

"""simple docstring"""

from manim import *
class     A__      (      snake_case__     ):




	def 							a_		(   self  :	Dict	)					-> List[Any]:
						__snake_case          =	Rectangle(height=0.5      ,    width=0.5	)
						__snake_case          =	Rectangle(height=0.46      ,    width=0.46	).set_stroke(width=0	)
						__snake_case          =	Rectangle(height=0.25      ,    width=0.25	)

						__snake_case          =	[mem.copy() for i in range(6	)]
						__snake_case          =	[mem.copy() for i in range(6	)]
						__snake_case          =	VGroup(*__snake_case	).arrange(__snake_case      ,    buff=0	)
						__snake_case          =	VGroup(*__snake_case	).arrange(__snake_case      ,    buff=0	)
						__snake_case          =	VGroup(__snake_case      ,    __snake_case	).arrange(__snake_case      ,    buff=0	)
						__snake_case          =	Text("""CPU"""      ,    font_size=24	)
						__snake_case          =	Group(__snake_case      ,    __snake_case	).arrange(__snake_case      ,    buff=0.5      ,    aligned_edge=__snake_case	)
						cpu.move_to([-2.5, -0.5, 0]	)
						self.add(__snake_case	)

						__snake_case          =	[mem.copy() for i in range(4	)]
						__snake_case          =	VGroup(*__snake_case	).arrange(__snake_case      ,    buff=0	)
						__snake_case          =	Text("""GPU"""      ,    font_size=24	)
						__snake_case          =	Group(__snake_case      ,    __snake_case	).arrange(__snake_case      ,    buff=0.5      ,    aligned_edge=__snake_case	)
						gpu.move_to([-1, -1, 0]	)
						self.add(__snake_case	)

						__snake_case          =	[mem.copy() for i in range(6	)]
						__snake_case          =	VGroup(*__snake_case	).arrange(__snake_case      ,    buff=0	)

						__snake_case          =	Text("""Model"""      ,    font_size=24	)
						__snake_case          =	Group(__snake_case      ,    __snake_case	).arrange(__snake_case      ,    buff=0.5      ,    aligned_edge=__snake_case	)
						model.move_to([3, -1.0, 0]	)
						self.add(__snake_case	)

						__snake_case          =	[]
						__snake_case          =	[]

						for i, rect in enumerate(__snake_case	):
											rect.set_stroke(__snake_case	)

											__snake_case          =	Rectangle(height=0.46 / 4      ,    width=0.46 / 3	).set_stroke(width=0.0	).set_fill(__snake_case      ,    opacity=0.7	)

											if i == 0:
																cpu_target.next_to(cpu_left_col_base[0].get_corner(DOWN + LEFT	)      ,    buff=0.02      ,    direction=__snake_case	)
																cpu_target.set_x(cpu_target.get_x() + 0.1	)
											elif i == 3:
																cpu_target.next_to(model_cpu_arr[0]      ,    direction=__snake_case      ,    buff=0.0	)
											else:
																cpu_target.next_to(model_cpu_arr[i - 1]      ,    direction=__snake_case      ,    buff=0.0	)
											self.add(__snake_case	)
											model_cpu_arr.append(__snake_case	)

						self.add(*__snake_case      ,    *__snake_case	)

						__snake_case          =	[meta_mem.copy() for i in range(6	)]
						__snake_case          =	[meta_mem.copy() for i in range(6	)]
						__snake_case          =	VGroup(*__snake_case	).arrange(__snake_case      ,    buff=0	)
						__snake_case          =	VGroup(*__snake_case	).arrange(__snake_case      ,    buff=0	)
						__snake_case          =	VGroup(__snake_case      ,    __snake_case	).arrange(__snake_case      ,    buff=0	)
						__snake_case          =	Text("""Disk"""      ,    font_size=24	)
						__snake_case          =	Group(__snake_case      ,    __snake_case	).arrange(__snake_case      ,    buff=0.5      ,    aligned_edge=__snake_case	)
						disk.move_to([-4.0, -1.25, 0]	)
						self.add(__snake_case      ,    __snake_case	)

						__snake_case          =	[]

						for i in range(6	):
											__snake_case          =	fill.copy().set_fill(__snake_case      ,    opacity=0.8	)
											target.move_to(disk_left_col_base[i]	).scale(0.5	)
											cpu_disk_arr.append(__snake_case	)

						self.add(*__snake_case	)

						__snake_case          =	Square(side_length=2.2	)
						key.move_to([-5, 2, 0]	)

						__snake_case          =	MarkupText(
						    f'''<b>Key:</b>\n\n<span fgcolor=\'{YELLOW}\'>●</span> Empty Model'''      ,    font_size=18      ,    )

						key_text.move_to([-5, 2.4, 0]	)

						self.add(__snake_case      ,    __snake_case	)

						__snake_case          =	MarkupText(
						    f'''<span fgcolor=\'{BLUE}\'>●</span> Checkpoint'''      ,    font_size=18      ,    )

						blue_text.next_to(__snake_case      ,    DOWN * 2.4      ,    aligned_edge=key_text.get_left()	)
						self.add(__snake_case	)

						__snake_case          =	MarkupText(f'''The offloaded weights are all sent to the CPU.'''      ,    font_size=24	)
						step_a.move_to([2, 2, 0]	)

						self.play(Write(__snake_case      ,    run_time=3	)	)

						for i in range(6	):
											__snake_case          =	cpu_disk_arr[i]
											__snake_case          =	rect.copy().set_fill(__snake_case      ,    opacity=0.8	).scale(2.0	)
											cpa.generate_target()
											cpa.target.move_to(model_base[i]	)

											if i == 0:
																rect.set_fill(__snake_case      ,    opacity=0.8	)
																rect.generate_target()
																rect.target.move_to(cpu_left_col_base[0]	).scale(2.0	)

																self.remove(
																    *__snake_case      ,    *__snake_case      ,    )

											else:
																rect.generate_target()
																rect.target.move_to(cpu_left_col_base[i]	).scale(2.0	)
											self.play(MoveToTarget(__snake_case	)      ,    MoveToTarget(__snake_case	)      ,    model_base[i].animate.set_stroke(__snake_case	)	)
						self.play(FadeOut(__snake_case	)	)

						__snake_case          =	MarkupText(
						    f'''Finally, hooks are added to each weight in the model\nto transfer the weights from CPU to GPU\n\t\tand back when needed.'''      ,    font_size=24      ,    )
						step_a.move_to([2, 2, 0]	)

						self.play(Write(__snake_case      ,    run_time=3	)	)

						__snake_case          =	[]
						__snake_case          =	[]
						for i in range(6	):
											__snake_case          =	Arrow(start=__snake_case      ,    end=__snake_case      ,    color=__snake_case      ,    buff=0.5	)
											a.next_to(model_base[i].get_left()      ,    __snake_case      ,    buff=0.2	)
											arrows.append(__snake_case	)
											animations.append(Write(__snake_case	)	)
						self.play(*__snake_case	)
						self.wait()








"""simple docstring"""

import functools
from math import sqrt
from time import time




def       snake_case__	(       lowerCAmelCase   :		int				,					*lowerCAmelCase   :		str				,					**lowerCAmelCase   :		List[Any]		):
					__snake_case          =	time()
					__snake_case          =	func(*lowerCAmelCase				,					**lowerCAmelCase		)
					__snake_case          =	time()
					if int(end - start		) > 0:
										print(F'''{func.__name__} runtime: {(end - start):0.4f} s'''		)
					else:
										print(F'''{func.__name__} runtime: {(end - start) * 1_000:0.4f} ms'''		)
					return output




def       snake_case__	(       lowerCAmelCase   :		int		):
					if n < 0:
										raise Exception("""n is negative"""		)
					if n == 0:
										return [0]
					__snake_case          =	[0, 1]
					for _ in range(n - 1		):
										fib.append(fib[-1] + fib[-2]		)
					return fib




def       snake_case__	(       lowerCAmelCase   :		int		):

					def fib_recursive_term(lowerCAmelCase   :		int		) -> int:
										if i < 0:
															raise Exception("""n is negative"""		)
										if i < 2:
															return i
										return fib_recursive_term(i - 1		) + fib_recursive_term(i - 2		)

					if n < 0:
										raise Exception("""n is negative"""		)
					return [fib_recursive_term(lowerCAmelCase		) for i in range(n + 1		)]




def       snake_case__	(       lowerCAmelCase   :		int		):

					@functools.cache
					def fib_recursive_term(lowerCAmelCase   :		int		) -> int:
										if i < 0:
															raise Exception("""n is negative"""		)
										if i < 2:
															return i
										return fib_recursive_term(i - 1		) + fib_recursive_term(i - 2		)

					if n < 0:
										raise Exception("""n is negative"""		)
					return [fib_recursive_term(lowerCAmelCase		) for i in range(n + 1		)]




def       snake_case__	(       lowerCAmelCase   :		int		):
					if n < 0:
										raise Exception("""n is negative"""		)
					# Cache must be outside recursuive function
					# other it will reset every time it calls itself.
					__snake_case          =	{0: 0, 1: 1, 2: 1}  # Prefilled cache

					def rec_fn_memoized(lowerCAmelCase   :		int		) -> int:
										if num in cache:
															return cache[num]

										__snake_case          =	rec_fn_memoized(num - 1		) + rec_fn_memoized(num - 2		)
										__snake_case          =	value
										return value

					return [rec_fn_memoized(lowerCAmelCase		) for i in range(n + 1		)]




def       snake_case__	(       lowerCAmelCase   :		int		):
					if n < 0:
										raise Exception("""n is negative"""		)
					if n >= 1_475:
										raise Exception("""n is too large"""		)
					__snake_case          =	sqrt(5		)
					__snake_case          =	(1 + sqrt_a) / 2
					return [round(phi**i / sqrt_a		) for i in range(n + 1		)]


if __name__ == "__main__":
		UpperCamelCase__ :    Optional[Any] 					=							30
		time_func(fib_iterative, num)
		time_func(fib_recursive, num)  # Around 3s runtime
		time_func(fib_recursive_cached, num)  # Around 0ms runtime
		time_func(fib_memoization, num)
		time_func(fib_binet, num)


