

'''simple docstring'''


import gc
import threading
import time

import psutil
import torch




class      a      :






						"""simple docstring"""




						def __init__(				self       :   Optional[int]	):



								'''simple docstring'''



								snake_case__    :							Union[str, Any]							    =	psutil.Process()
								snake_case__    :							int							    =	False







						def    __magic_name__				(				self       :   Dict	):



								'''simple docstring'''



								snake_case__    :							Union[str, Any]							    =	-1

								while True:
										snake_case__    :							str							    =	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    __magic_name__				(				self       :   int	):



								'''simple docstring'''



								snake_case__    :							Union[str, Any]							    =	True
								snake_case__    :							Optional[int]							    =	threading.Thread(target=self.peak_monitor	)
								snake_case__    :							List[str]							    =	True
								self.thread.start()







						def    __magic_name__				(				self       :   Optional[int]	):



								'''simple docstring'''



								snake_case__    :							int							    =	False
								self.thread.join()
								return self.cpu_memory_peak





lowerCAmelCase__    :							List[str]					    =    PeakCPUMemory()




def 						_a							(					):

		"""simple docstring"""

		snake_case__    :							Optional[Any]							    =	{'''time''': time.time()}

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

		# CPU mem
		snake_case__    :							Optional[Any]							    =	psutil.Process().memory_info().rss
		cpu_peak_tracker.start()

		# GPU mem
		for i in range(torch.cuda.device_count()  ):
				snake_case__    :							Tuple							    =	torch.cuda.memory_allocated(__snake_case  )
		torch.cuda.reset_peak_memory_stats()

		return measures




def 						_a							(					__lowerCAmelCase		:   Any  ):

		"""simple docstring"""

		snake_case__    :							Optional[Any]							    =	{'''time''': time.time() - start_measures['''time''']}

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

		# CPU mem
		snake_case__    :							Union[str, Any]							    =	(psutil.Process().memory_info().rss - start_measures['''cpu''']) / 2**20
		snake_case__    :							int							    =	(cpu_peak_tracker.stop() - start_measures['''cpu''']) / 2**20

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

		return measures





def 						_a							(					__lowerCAmelCase		:   Dict ,				__lowerCAmelCase		:   Optional[int]  ):

		"""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(__snake_case  )]:.2f}MiB"""  )
				snake_case__    :							Union[str, Any]							    =	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'''

from __future__ import annotations



def snake_case_      (					__snake_case  :							list[int | str])			->					None:
   create_state_space_tree(__snake_case	,   []	,   0	,   [0 for i in range(len(__snake_case))])



def snake_case_      (					__snake_case  :							list[int | str]	,   __snake_case  :							list[int | str]	,   __snake_case  :							int	,   __snake_case  :							list[int]	,   )			->					None:

   if index == len(__snake_case):
      print(__snake_case)
      return

   for i in range(len(__snake_case)):
      if not index_used[i]:
         current_sequence.append(sequence[i])
         lowerCAmelCase_			=      True
         create_state_space_tree(__snake_case	,   __snake_case	,   index + 1	,   __snake_case)
         current_sequence.pop()
         lowerCAmelCase_			=      False
A_     :						list[int | str]    							=[3, 1, 2, 4]
generate_all_permutations(sequence)

A_     :						list[int | str]    							=["A", "B", "C"]






generate_all_permutations(sequence_a)





