





'''simple docstring'''

import gc
import threading
import time

import psutil
import torch
class     __lowerCAmelCase					:






       """simple docstring"""





       def __init__(							self       :		Optional[int]					)   ->					List[Any]:

            '''simple docstring'''




            _UpperCamelCase       =	psutil.Process()
            _UpperCamelCase       =	False





       def snake_case__						(							self       :		str					)   ->					Any:

            '''simple docstring'''




            _UpperCamelCase       =	-1

            while True:
                 _UpperCamelCase       =	max(self.process.memory_info().rss	,			self.cpu_memory_peak					)

                 # can't sleep or will not catch the peak right (this comment is here on purpose)
                 if not self.peak_monitoring:
                      break





       def snake_case__						(							self       :		Tuple					)   ->					Any:

            '''simple docstring'''




            _UpperCamelCase       =	True
            _UpperCamelCase       =	threading.Thread(target=self.peak_monitor					)
            _UpperCamelCase       =	True
            self.thread.start()







       def snake_case__						(							self       :		Dict					)   ->					Any:

            '''simple docstring'''




            _UpperCamelCase       =	False
            self.thread.join()
            return self.cpu_memory_peak

lowercase__						:      Optional[Any]	=    PeakCPUMemory()







def  a__    (    )		->		int:





     """simple docstring"""

     _UpperCamelCase       =	{'''time''': time.time()}

     gc.collect()
     torch.cuda.empty_cache()

     # CPU mem
     _UpperCamelCase       =	psutil.Process().memory_info().rss
     cpu_peak_tracker.start()

     # GPU mem
     for i in range(torch.cuda.device_count()				):
          _UpperCamelCase       =	torch.cuda.memory_allocated(lowercase				)
     torch.cuda.reset_peak_memory_stats()

     return measures







def  a__    (    lowercase :					str				)		->		Optional[int]:





     """simple docstring"""

     _UpperCamelCase       =	{'''time''': time.time() - start_measures['''time''']}

     gc.collect()
     torch.cuda.empty_cache()

     # CPU mem
     _UpperCamelCase       =	(psutil.Process().memory_info().rss - start_measures['''cpu''']) / 2**20
     _UpperCamelCase       =	(cpu_peak_tracker.stop() - start_measures['''cpu''']) / 2**20

     # GPU mem
     for i in range(torch.cuda.device_count()				):
          _UpperCamelCase       =	(torch.cuda.memory_allocated(lowercase				) - start_measures[str(lowercase				)]) / 2**20
          _UpperCamelCase       =	(torch.cuda.max_memory_allocated(lowercase				) - start_measures[str(lowercase				)]) / 2**20

     return measures







def  a__    (    lowercase :					List[str], lowercase :					Dict				)		->		Union[str, Any]:





     """simple docstring"""

     print(F"""{description}:"""				)
     print(F"""- Time: {measures['time']:.2f}s"""				)
     for i in range(torch.cuda.device_count()				):
          print(F"""- GPU {i} allocated: {measures[str(lowercase				)]:.2f}MiB"""				)
          _UpperCamelCase       =	measures[F"""{i}-peak"""]
          print(F"""- GPU {i} peak: {peak:.2f}MiB"""				)
     print(F"""- CPU RAM allocated: {measures['cpu']:.2f}MiB"""				)
     print(F"""- CPU RAM peak: {measures['cpu-peak']:.2f}MiB"""				)










'''simple docstring'''

def  a__    (    lowercase :					int, lowercase :					int				)		->		int:





     """simple docstring"""

     return x if y == 0 else greatest_common_divisor(lowercase, x % y				)







def  a__    (    lowercase :					int, lowercase :					int				)		->		int:





     """simple docstring"""

     return (x * y) // greatest_common_divisor(lowercase, lowercase				)







def  a__    (    lowercase :					int = 20				)		->		int:





     """simple docstring"""

     _UpperCamelCase       =	1
     for i in range(1, n + 1				):
          _UpperCamelCase       =	lcm(lowercase, lowercase				)
     return g


if __name__ == "__main__":
   print(F"""{solution() = }""")



