



"""simple docstring"""


from __future__ import annotations







class       A_			:



						"""simple docstring"""






						def __init__(					self :Optional[int]   ,  lowercase_ :list[list[int]]					)				->			Tuple:
												UpperCAmelCase             = TypeError(
												    'Matrices must be formed from a list of zero or more lists containing at '
												    'least one and the same number of values, each of which must be of type '
												    'int or float.'					)
												if len(lowercase_					) != 0:
																		UpperCAmelCase             = len(rows[0]					)
																		if cols == 0:
																								raise error
																		for row in rows:
																								if len(lowercase_					) != cols:
																														raise error
																								for value in row:
																														if not isinstance(lowercase_   ,  (int, float)					):
																																				raise error
																		UpperCAmelCase             = rows
												else:
																		UpperCAmelCase             = []






						def 	UpperCAmelCase__     (					self :Union[str, Any]					)				->			list[list[int]]:
												return [[row[i] for row in self.rows] for i in range(len(self.rows[0]					)					)]






						@property
						def 	UpperCAmelCase__     (					self :Optional[int]					)				->			int:
												return len(self.rows					)






						@property
						def 	UpperCAmelCase__     (					self :Dict					)				->			int:
												return len(self.rows[0]					)






						@property
						def 	UpperCAmelCase__     (					self :Tuple					)				->			tuple[int, int]:
												return (self.num_rows, self.num_columns)






						@property
						def 	UpperCAmelCase__     (					self :List[Any]					)				->			bool:
												return self.order[0] == self.order[1]






						def 	UpperCAmelCase__     (					self :Optional[int]					)				->			Matrix:
												UpperCAmelCase             = [
												    [0 if column_num != row_num else 1 for column_num in range(self.num_rows					)]
												    for row_num in range(self.num_rows					)
												]
												return Matrix(lowercase_					)






						def 	UpperCAmelCase__     (					self :Tuple					)				->			int:
												if not self.is_square:
																		return 0
												if self.order == (0, 0):
																		return 1
												if self.order == (1, 1):
																		return int(self.rows[0][0]					)
												if self.order == (2, 2):
																		return int(
																		    (self.rows[0][0] * self.rows[1][1])
																		    - (self.rows[0][1] * self.rows[1][0])					)
												else:
																		return sum(
																		    self.rows[0][column] * self.cofactors().rows[0][column]
																		    for column in range(self.num_columns					)					)






						def 	UpperCAmelCase__     (					self :Optional[Any]					)				->			bool:
												return bool(self.determinant()					)






						def 	UpperCAmelCase__     (					self :int   ,  lowercase_ :int   ,  lowercase_ :int					)				->			int:
												UpperCAmelCase             = [
												    [
												        self.rows[other_row][other_column]
												        for other_column in range(self.num_columns					)
												        if other_column != column
												    ]
												    for other_row in range(self.num_rows					)
												    if other_row != row
												]
												return Matrix(lowercase_					).determinant()






						def 	UpperCAmelCase__     (					self :List[str]   ,  lowercase_ :int   ,  lowercase_ :int					)				->			int:
												if (row + column) % 2 == 0:
																		return self.get_minor(lowercase_   ,  lowercase_					)
												return -1 * self.get_minor(lowercase_   ,  lowercase_					)






						def 	UpperCAmelCase__     (					self :str					)				->			Matrix:
												return Matrix(
												    [
												        [self.get_minor(lowercase_   ,  lowercase_					) for column in range(self.num_columns					)]
												        for row in range(self.num_rows					)
												    ]					)






						def 	UpperCAmelCase__     (					self :int					)				->			Matrix:
												return Matrix(
												    [
												        [
												            self.minors().rows[row][column]
												            if (row + column) % 2 == 0
												            else self.minors().rows[row][column] * -1
												            for column in range(self.minors().num_columns					)
												        ]
												        for row in range(self.minors().num_rows					)
												    ]					)






						def 	UpperCAmelCase__     (					self :Optional[int]					)				->			Matrix:
												UpperCAmelCase             = [
												    [self.cofactors().rows[column][row] for column in range(self.num_columns					)]
												    for row in range(self.num_rows					)
												]
												return Matrix(lowercase_					)






						def 	UpperCAmelCase__     (					self :Dict					)				->			Matrix:
												UpperCAmelCase             = self.determinant()
												if not determinant:
																		raise TypeError('Only matrices with a non-zero determinant have an inverse'					)
												return self.adjugate() * (1 / determinant)






						def __repr__(					self :str					)				->			str:
												return str(self.rows					)






						def __str__(					self :List[Any]					)				->			str:
												if self.num_rows == 0:
																		return "[]"
												if self.num_rows == 1:
																		return "[[" + ". ".join(str(self.rows[0]					)					) + "]]"
												return (
												    "["
												    + "\n ".join(
												        [
												            '[' + '. '.join([str(lowercase_					) for value in row]					) + '.]'
												            for row in self.rows
												        ]					)
												    + "]"
												)






						def 	UpperCAmelCase__     (					self :int   ,  lowercase_ :list[int]   ,  lowercase_ :int | None = None					)				->			None:
												UpperCAmelCase             = TypeError('Row must be a list containing all ints and/or floats'					)
												if not isinstance(lowercase_   ,  lowercase_					):
																		raise type_error
												for value in row:
																		if not isinstance(lowercase_   ,  (int, float)					):
																								raise type_error
												if len(lowercase_					) != self.num_columns:
																		raise ValueError(
																		    'Row must be equal in length to the other rows in the matrix'					)
												if position is None:
																		self.rows.append(lowercase_					)
												else:
																		UpperCAmelCase             = self.rows[0:position] + [row] + self.rows[position:]






						def 	UpperCAmelCase__     (					self :Optional[int]   ,  lowercase_ :list[int]   ,  lowercase_ :int | None = None					)				->			None:
												UpperCAmelCase             = TypeError(
												    'Column must be a list containing all ints and/or floats'					)
												if not isinstance(lowercase_   ,  lowercase_					):
																		raise type_error
												for value in column:
																		if not isinstance(lowercase_   ,  (int, float)					):
																								raise type_error
												if len(lowercase_					) != self.num_rows:
																		raise ValueError(
																		    'Column must be equal in length to the other columns in the matrix'					)
												if position is None:
																		UpperCAmelCase             = [self.rows[i] + [column[i]] for i in range(self.num_rows					)]
												else:
																		UpperCAmelCase             = [
																		    self.rows[i][0:position] + [column[i]] + self.rows[i][position:]
																		    for i in range(self.num_rows					)
																		]






						def __eq__(					self :Any   ,  lowercase_ :object					)				->			bool:
												if not isinstance(lowercase_   ,  lowercase_					):
																		return NotImplemented
												return self.rows == other.rows






						def __ne__(					self :Optional[Any]   ,  lowercase_ :object					)				->			bool:
												return not self == other






						def __neg__(					self :Tuple					)				->			Matrix:
												return self * -1






						def __add__(					self :Any   ,  lowercase_ :Matrix					)				->			Matrix:
												if self.order != other.order:
																		raise ValueError('Addition requires matrices of the same order'					)
												return Matrix(
												    [
												        [self.rows[i][j] + other.rows[i][j] for j in range(self.num_columns					)]
												        for i in range(self.num_rows					)
												    ]					)






						def __sub__(					self :Any   ,  lowercase_ :Matrix					)				->			Matrix:
												if self.order != other.order:
																		raise ValueError('Subtraction requires matrices of the same order'					)
												return Matrix(
												    [
												        [self.rows[i][j] - other.rows[i][j] for j in range(self.num_columns					)]
												        for i in range(self.num_rows					)
												    ]					)






						def __mul__(					self :Dict   ,  lowercase_ :Matrix | int | float					)				->			Matrix:
												if isinstance(lowercase_   ,  (int, float)					):
																		return Matrix(
																		    [[int(element * other					) for element in row] for row in self.rows]					)
												elif isinstance(lowercase_   ,  lowercase_					):
																		if self.num_columns != other.num_rows:
																								raise ValueError(
																								    'The number of columns in the first matrix must '
																								    'be equal to the number of rows in the second'					)
																		return Matrix(
																		    [
																		        [Matrix.dot_product(lowercase_   ,  lowercase_					) for column in other.columns()]
																		        for row in self.rows
																		    ]					)
												else:
																		raise TypeError(
																		    'A Matrix can only be multiplied by an int, float, or another matrix'					)






						def __pow__(					self :List[Any]   ,  lowercase_ :int					)				->			Matrix:
												if not isinstance(lowercase_   ,  lowercase_					):
																		raise TypeError('A Matrix can only be raised to the power of an int'					)
												if not self.is_square:
																		raise ValueError('Only square matrices can be raised to a power'					)
												if other == 0:
																		return self.identity()
												if other < 0:
																		if self.is_invertable():
																								return self.inverse() ** (-other)
																		raise ValueError(
																		    'Only invertable matrices can be raised to a negative power'					)
												UpperCAmelCase             = self
												for _ in range(other - 1					):
																		result *= self
												return result






						@classmethod
						def 	UpperCAmelCase__     (					cls :Optional[Any]   ,  lowercase_ :list[int]   ,  lowercase_ :list[int]					)				->			int:
												return sum(row[i] * column[i] for i in range(len(lowercase_					)					)					)


if __name__ == "__main__":
				import doctest

				doctest.testmod()








from manim import *






class 	__magic_name__    (			lowerCAmelCase_      ):





			def 		__magic_name__    (		self					)   -> Any:




						'''simple docstring'''
						__a        =Rectangle(height=0.5					,  width=0.5					)
						__a        =Rectangle(height=0.25					,  width=0.25					)
						__a        =Rectangle(height=0.46					,  width=0.46					).set_stroke(width=0					)

						__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        =[]
						__a        =[]

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

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

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

						__a        =Text('Loaded Checkpoint'					,  font_size=24					)
						__a        =Group(__snake_case					,  __snake_case					).arrange(__snake_case					,  buff=0.5					,  aligned_edge=__snake_case					)
						checkpoint.move_to([3, 0.5, 0]					)

						self.add(__snake_case					)

						__a        =[]
						__a        =[]

						for i, rect in enumerate(__snake_case					):
									__a        =fill.copy().set_fill(__snake_case					,  opacity=0.7					)
									target.move_to(__snake_case					)
									ckpt_arr.append(__snake_case					)

									__a        =target.copy()
									if i < 5:
												cpu_target.move_to(cpu_left_col_base[i + 1]					)
									else:
												cpu_target.move_to(cpu_right_col_base[i - 5]					)
									ckpt_cpu_arr.append(__snake_case					)
						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'Based on the passed in configuration, weights are stored in\na variety of np.memmaps on disk or to a particular device.'					,  font_size=24					,  )
						step_a.move_to([2, 2, 0]					)

						__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.0, -1.25, 0]					)
						self.play(Write(__snake_case					,  run_time=3					)					,  Write(__snake_case					,  run_time=1					)					,  Create(__snake_case					,  run_time=1					)					)

						__a        =[]
						for i, rect in enumerate(__snake_case					):
									__a        =rect.copy()
									target.generate_target()
									target.target.move_to(disk_left_col_base[i]					).scale(0.5					)
									animations.append(MoveToTarget(__snake_case					,  run_time=1.5					)					)
						self.play(*__snake_case					)

						self.play(FadeOut(__snake_case					)					)

						__a        =MarkupText(f'Then, the checkpoint is removed from memory\nthrough garbage collection.'					,  font_size=24					)
						step_a.move_to([2, 2, 0]					)

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

						self.play(
						    FadeOut(__snake_case					,  __snake_case					,  *__snake_case					,  *__snake_case					)					,  )

						self.wait()






