


from manim import *







class 	snake_case_       (lowerCamelCase_				):
					def 			lowerCamelCase__(				self       :Optional[Any]				) ->   Optional[Any]:
												a__					=					Rectangle(height=0.5      ,width=0.5				)
												a__					=					Rectangle(height=0.46      ,width=0.46				).set_stroke(width=0				)

												a__					=					Rectangle(height=0.25      ,width=0.25				)

												a__					=					[mem.copy() for i in range(6				)]
												a__					=					[mem.copy() for i in range(6				)]
												a__					=					VGroup(*__snake_case				).arrange(__snake_case      ,buff=0				)
												a__					=					VGroup(*__snake_case				).arrange(__snake_case      ,buff=0				)
												a__					=					VGroup(__snake_case      ,__snake_case				).arrange(__snake_case      ,buff=0				)
												a__					=					Text('CPU'      ,font_size=24				)
												a__					=					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				)

												a__					=					[mem.copy() for i in range(4				)]
												a__					=					VGroup(*__snake_case				).arrange(__snake_case      ,buff=0				)
												a__					=					Text('GPU'      ,font_size=24				)
												a__					=					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				)

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

												a__					=					Text('Model'      ,font_size=24				)
												a__					=					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				)

												a__					=					[]
												a__					=					[]

												for i, rect in enumerate(__snake_case				):
																			a__					=					fill.copy().set_fill(__snake_case      ,opacity=0.8				)
																			target.move_to(__snake_case				)
																			model_arr.append(__snake_case				)

																			a__					=					Rectangle(height=0.46      ,width=0.46				).set_stroke(width=0.0				).set_fill(__snake_case      ,opacity=0.8				)
																			cpu_target.move_to(cpu_left_col_base[i]				)
																			model_cpu_arr.append(__snake_case				)

												self.add(*__snake_case      ,*__snake_case				)

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

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

												a__					=					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				)

												a__					=					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				)

												a__					=					MarkupText(
												    F'Now watch as an input is passed through the model\nand how the memory is utilized and handled.'      ,font_size=24      ,)
												step_a.move_to([2, 2, 0]				)

												self.play(Write(__snake_case				)				)

												a__					=					Square(0.3				)
												input.set_fill(__snake_case      ,opacity=1.0				)
												input.set_stroke(width=0.0				)
												input.next_to(model_base[0]      ,__snake_case      ,buff=0.5				)

												self.play(Write(__snake_case				)				)

												input.generate_target()
												input.target.next_to(model_arr[0]      ,direction=__snake_case      ,buff=0.02				)
												self.play(MoveToTarget(__snake_case				)				)

												self.play(FadeOut(__snake_case				)				)

												a__					=					Arrow(start=__snake_case      ,end=__snake_case      ,color=__snake_case      ,buff=0.5				)
												a.next_to(model_arr[0].get_left()      ,__snake_case      ,buff=0.2				)

												model_cpu_arr[0].generate_target()
												model_cpu_arr[0].target.move_to(gpu_rect[0]				)

												a__					=					MarkupText(
												    F'As the input reaches a layer, the hook triggers\nand weights are moved from the CPU\nto the GPU and back.'      ,font_size=24      ,)
												step_a.move_to([2, 2, 0]				)

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

												a__					=					{'run_time': 1, 'fade_in': True, 'fade_out': True, 'buff': 0.02}

												self.play(
												    Write(__snake_case				)      ,Circumscribe(model_arr[0]      ,color=__snake_case      ,**__snake_case				)      ,Circumscribe(model_cpu_arr[0]      ,color=__snake_case      ,**__snake_case				)      ,Circumscribe(gpu_rect[0]      ,color=__snake_case      ,**__snake_case				)      ,)
												self.play(MoveToTarget(model_cpu_arr[0]				)				)

												a__					=					a.copy()
												for i in range(6				):
																			a_c.next_to(model_arr[i].get_right() + 0.02      ,__snake_case      ,buff=0.2				)

																			input.generate_target()
																			input.target.move_to(model_arr[i].get_right() + 0.02				)

																			a__					=					AnimationGroup(
																			    FadeOut(__snake_case      ,run_time=0.5				)      ,MoveToTarget(__snake_case      ,run_time=0.5				)      ,FadeIn(__snake_case      ,run_time=0.5				)      ,lag_ratio=0.2				)

																			self.play(__snake_case				)

																			model_cpu_arr[i].generate_target()
																			model_cpu_arr[i].target.move_to(cpu_left_col_base[i]				)

																			if i < 5:
																										model_cpu_arr[i + 1].generate_target()
																										model_cpu_arr[i + 1].target.move_to(gpu_rect[0]				)
																										if i >= 1:
																																	a__					=					0.7

																										self.play(
																										    Circumscribe(model_arr[i]      ,**__snake_case				)      ,Circumscribe(cpu_left_col_base[i]      ,**__snake_case				)      ,Circumscribe(cpu_left_col_base[i + 1]      ,color=__snake_case      ,**__snake_case				)      ,Circumscribe(gpu_rect[0]      ,color=__snake_case      ,**__snake_case				)      ,Circumscribe(model_arr[i + 1]      ,color=__snake_case      ,**__snake_case				)      ,)
																										if i < 1:
																																	self.play(
																																	    MoveToTarget(model_cpu_arr[i]				)      ,MoveToTarget(model_cpu_arr[i + 1]				)      ,)
																										else:
																																	self.play(
																																	    MoveToTarget(model_cpu_arr[i]      ,run_time=0.7				)      ,MoveToTarget(model_cpu_arr[i + 1]      ,run_time=0.7				)      ,)
																			else:
																										model_cpu_arr[i].generate_target()
																										model_cpu_arr[i].target.move_to(cpu_left_col_base[-1]				)
																										input.generate_target()
																										input.target.next_to(model_arr[-1].get_right()      ,RIGHT + 0.02      ,buff=0.2				)

																										self.play(
																										    Circumscribe(model_arr[-1]      ,color=__snake_case      ,**__snake_case				)      ,Circumscribe(cpu_left_col_base[-1]      ,color=__snake_case      ,**__snake_case				)      ,Circumscribe(gpu_rect[0]      ,color=__snake_case      ,**__snake_case				)      ,)

																										self.play(MoveToTarget(model_cpu_arr[i]				)				)

																			a__					=					a_c
																			a__					=					a_c.copy()

												input.generate_target()
												input.target.next_to(model_base[-1]      ,RIGHT + 0.02      ,buff=0.5				)
												self.play(
												    FadeOut(__snake_case				)      ,FadeOut(__snake_case      ,run_time=0.5				)      ,)

												a__					=					MarkupText(F'Inference on a model too large for GPU memory\nis successfully completed.'      ,font_size=24				)
												step_a.move_to([2, 2, 0]				)

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

												self.wait()








from math import ceil, sqrt






def 							__lowercase       (			__lowerCAmelCase							:    int = 1_0_0_0_0_0_0       ):
							a__					=					0

							for outer_width in range(3 ,   (limit // 4) + 2       ):
														if outer_width**2 > limit:
																					a__					=					max(ceil(sqrt(outer_width**2 - limit       )       ) ,   1       )
														else:
																					a__					=					1
														if (outer_width - hole_width_lower_bound) % 2:
																					hole_width_lower_bound += 1

														answer += (outer_width - hole_width_lower_bound - 2) // 2 + 1

							return answer


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




