

from __future__ import annotations

from collections import deque






class        A_		:
							def __init__(		self		:			Any   ,SCREAMING_SNAKE_CASE__		:			Any):
								__lowerCamelCase				:				Dict					       = []
								self.adlist.append(
								    {'value': '', 'next_states': [], 'fail_state': 0, 'output': []})

								for keyword in keywords:
									self.add_keyword(lowerCAmelCase__)
								self.set_fail_transitions()
							def     lowerCAmelCase     (		self		:			str   ,SCREAMING_SNAKE_CASE__		:			Tuple   ,SCREAMING_SNAKE_CASE__		:			str):


								for state in self.adlist[current_state]["next_states"]:
									if char == self.adlist[state]["value"]:
										return state
								return None
							def     lowerCAmelCase     (		self		:			Optional[Any]   ,SCREAMING_SNAKE_CASE__		:			List[Any]):
								__lowerCamelCase				:				List[Any]					       = 0
								for character in keyword:
									__lowerCamelCase				:				int					       = self.find_next_state(lowerCAmelCase__   ,lowerCAmelCase__)
									if next_state is None:
										self.adlist.append(
										    {
										        'value': character,
										        'next_states': [],
										        'fail_state': 0,
										        'output': [],
										    })
										self.adlist[current_state]["next_states"].append(len(self.adlist) - 1)
										__lowerCamelCase				:				Tuple					       = len(self.adlist) - 1
									else:
										__lowerCamelCase				:				Tuple					       = next_state
								self.adlist[current_state]["output"].append(lowerCAmelCase__)
							def     lowerCAmelCase     (		self		:			Any):
								__lowerCamelCase				:				Any					       = deque()
								for node in self.adlist[0]["next_states"]:
									q.append(lowerCAmelCase__)
									__lowerCamelCase				:				Tuple					       = 0
								while q:
									__lowerCamelCase				:				List[Any]					       = q.popleft()
									for child in self.adlist[r]["next_states"]:
										q.append(lowerCAmelCase__)
										__lowerCamelCase				:				List[Any]					       = self.adlist[r]['fail_state']
										while (
										    self.find_next_state(lowerCAmelCase__   ,self.adlist[child]['value']) is None
										    and state != 0
										):
											__lowerCamelCase				:				int					       = self.adlist[state]['fail_state']
										__lowerCamelCase				:				List[Any]					       = self.find_next_state(
										    lowerCAmelCase__   ,self.adlist[child]['value'])
										if self.adlist[child]["fail_state"] is None:
											__lowerCamelCase				:				str					       = 0
										__lowerCamelCase				:				str					       = (
										    self.adlist[child]['output']
										    + self.adlist[self.adlist[child]['fail_state']]['output']
										)


							def     lowerCAmelCase     (		self		:			List[str]   ,SCREAMING_SNAKE_CASE__		:			Union[str, Any]):
								__lowerCamelCase				:				Optional[Any]					       = {}  # returns a dict with keywords and list of its occurrences
								__lowerCamelCase				:				Optional[int]					       = 0
								for i in range(len(lowerCAmelCase__)):
									while (
									    self.find_next_state(lowerCAmelCase__   ,string[i]) is None
									    and current_state != 0
									):
										__lowerCamelCase				:				Optional[int]					       = self.adlist[current_state]['fail_state']
									__lowerCamelCase				:				Dict					       = self.find_next_state(lowerCAmelCase__   ,string[i])
									if next_state is None:
										__lowerCamelCase				:				Any					       = 0
									else:
										__lowerCamelCase				:				List[Any]					       = next_state
										for key in self.adlist[current_state]["output"]:
											if key not in result:
												__lowerCamelCase				:				List[Any]					       = []
											result[key].append(i - len(lowerCAmelCase__) + 1)
								return result


if __name__ == "__main__":
					import doctest

					doctest.testmod()





import gc
import threading
import time

import psutil
import torch




class    _UpperCamelCase      :


			"""simple docstring"""






			def __init__(   self						)     ->					str:

							'''simple docstring'''


							__lowercase 			=							psutil.Process()
							__lowercase 			=							False





			def        _SCREAMING_SNAKE_CASE			(   self						)     ->					str:

							'''simple docstring'''


							__lowercase 			=							-1

							while True:
											__lowercase 			=							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        _SCREAMING_SNAKE_CASE			(   self						)     ->					int:

							'''simple docstring'''


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





			def        _SCREAMING_SNAKE_CASE			(   self						)     ->					str:

							'''simple docstring'''


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


__a  :     List[str]       =  PeakCPUMemory()





def 				UpperCAmelCase						(    ):







				"""simple docstring"""



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

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

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

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

				return measures





def 				UpperCAmelCase						(    lowercase							):







				"""simple docstring"""



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

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

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

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

				return measures





def 				UpperCAmelCase						(    lowercase							,			lowercase							):







				"""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"							)
								__lowercase 			=							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"							)