



import sys
from collections.abc import Mapping

import numpy as np
import pyarrow as pa

from .. import config
from ..utils.py_utils import map_nested
from .formatting import TensorFormatter




class  snake_case__						(	TensorFormatter[Mapping, np.ndarray, Mapping]					):






     """simple docstring"""


     def __init__(	self  :  str,			_snake_case  :  List[str]=None,			**_snake_case  :  Any )       ->List[Any]:
            super().__init__(features=_snake_case )
            snake_case__							:     Dict            =     np_array_kwargs






     def        lowercase_       (	self  :  Union[str, Any],			_snake_case  :  Any )       ->List[Any]:
            if isinstance(_snake_case,			_snake_case ):
                   if column and all(
                       isinstance(_snake_case,			np.ndarray ) and x.shape == column[0].shape and x.dtype == column[0].dtype for x in column ):
                          return np.stack(_snake_case )
                   else:
                          # don't use np.array(column, dtype=object)
                          # since it fails in certain cases
                          # see https://stackoverflow.com/q/51005699
                          snake_case__							:     List[str]            =     np.empty(len(_snake_case ),			dtype=_snake_case )
                          snake_case__							:     Dict            =     column
                          return out
            return column






     def        lowercase_       (	self  :  List[str],			_snake_case  :  List[str] )       ->List[str]:
            if isinstance(_snake_case,			(str, bytes, type(_snake_case )) ):
                   return value
            elif isinstance(_snake_case,			(np.character, np.ndarray) ) and np.issubdtype(value.dtype,			np.character ):
                   return value
            elif isinstance(_snake_case,			np.number ):
                   return value

            snake_case__							:     List[Any]            =     {}

            if isinstance(_snake_case,			np.ndarray ) and np.issubdtype(value.dtype,			np.integer ):
                   snake_case__							:     int            =     {'dtype': np.intaa}
            elif isinstance(_snake_case,			np.ndarray ) and np.issubdtype(value.dtype,			np.floating ):
                   snake_case__							:     Dict            =     {'dtype': np.floataa}
            elif config.PIL_AVAILABLE and "PIL" in sys.modules:
                   import PIL.Image

                   if isinstance(_snake_case,			PIL.Image.Image ):
                          return np.asarray(_snake_case,			**self.np_array_kwargs )

            return np.asarray(_snake_case,			**{**default_dtype, **self.np_array_kwargs} )






     def        lowercase_       (	self  :  List[str],			_snake_case  :  List[Any] )       ->Union[str, Any]:
            # support for torch, tf, jax etc.
            if config.TORCH_AVAILABLE and "torch" in sys.modules:
                   import torch

                   if isinstance(_snake_case,			torch.Tensor ):
                          return self._tensorize(data_struct.detach().cpu().numpy()[()] )
            if hasattr(_snake_case,			'__array__' ) and not isinstance(_snake_case,			(np.ndarray, np.character, np.number) ):
                   snake_case__							:     Tuple            =     data_struct.__array__()
            # support for nested types like struct of list of struct
            if isinstance(_snake_case,			np.ndarray ):
                   if data_struct.dtype == object:
                          return self._consolidate([self.recursive_tensorize(_snake_case ) for substruct in data_struct] )
            if isinstance(_snake_case,			(list, tuple) ):
                   return self._consolidate([self.recursive_tensorize(_snake_case ) for substruct in data_struct] )
            return self._tensorize(_snake_case )






     def        lowercase_       (	self  :  List[Any],			_snake_case  :  dict )       ->Any:
            return map_nested(self._recursive_tensorize,			_snake_case,			map_list=_snake_case )






     def        lowercase_       (	self  :  Dict,			_snake_case  :  pa.Table )       ->Mapping:
            snake_case__							:     Dict            =     self.numpy_arrow_extractor().extract_row(_snake_case )
            snake_case__							:     Tuple            =     self.python_features_decoder.decode_row(_snake_case )
            return self.recursive_tensorize(_snake_case )






     def        lowercase_       (	self  :  Dict,			_snake_case  :  pa.Table )       ->np.ndarray:
            snake_case__							:     Tuple            =     self.numpy_arrow_extractor().extract_column(_snake_case )
            snake_case__							:     List[Any]            =     self.python_features_decoder.decode_column(_snake_case,			pa_table.column_names[0] )
            snake_case__							:     str            =     self.recursive_tensorize(_snake_case )
            snake_case__							:     List[str]            =     self._consolidate(_snake_case )
            return column






     def        lowercase_       (	self  :  Optional[int],			_snake_case  :  pa.Table )       ->Mapping:
            snake_case__							:     Union[str, Any]            =     self.numpy_arrow_extractor().extract_batch(_snake_case )
            snake_case__							:     Dict            =     self.python_features_decoder.decode_batch(_snake_case )
            snake_case__							:     Dict            =     self.recursive_tensorize(_snake_case )
            for column_name in batch:
                   snake_case__							:     List[Any]            =     self._consolidate(batch[column_name] )
            return batch











from manim import *




class  snake_case__						(	lowerCAmelCase_					):






     """simple docstring"""


     def        lowercase_       (	self  :  List[Any] )       ->Dict:
            snake_case__							:     str            =     Rectangle(height=0.5,			width=0.5 )
            snake_case__							:     str            =     Rectangle(height=0.4_6,			width=0.4_6 ).set_stroke(width=0 )
            snake_case__							:     List[Any]            =     Rectangle(height=0.2_5,			width=0.2_5 )

            snake_case__							:     Any            =     [mem.copy() for i in range(6 )]
            snake_case__							:     Optional[Any]            =     [mem.copy() for i in range(6 )]
            snake_case__							:     int            =     VGroup(*_snake_case ).arrange(_snake_case,			buff=0 )
            snake_case__							:     Optional[int]            =     VGroup(*_snake_case ).arrange(_snake_case,			buff=0 )
            snake_case__							:     Any            =     VGroup(_snake_case,			_snake_case ).arrange(_snake_case,			buff=0 )
            snake_case__							:     Optional[Any]            =     Text('CPU',			font_size=2_4 )
            snake_case__							:     str            =     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__							:     Optional[int]            =     [mem.copy() for i in range(4 )]
            snake_case__							:     int            =     VGroup(*_snake_case ).arrange(_snake_case,			buff=0 )
            snake_case__							:     str            =     Text('GPU',			font_size=2_4 )
            snake_case__							:     List[Any]            =     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__							:     Optional[int]            =     [mem.copy() for i in range(6 )]
            snake_case__							:     Union[str, Any]            =     VGroup(*_snake_case ).arrange(_snake_case,			buff=0 )

            snake_case__							:     int            =     Text('Model',			font_size=2_4 )
            snake_case__							:     List[Any]            =     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__							:     Any            =     []
            snake_case__							:     Optional[int]            =     []

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

                   snake_case__							:     Union[str, Any]            =     Rectangle(height=0.4_6 / 4,			width=0.4_6 / 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.0_2,			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__							:     Optional[Any]            =     [meta_mem.copy() for i in range(6 )]
            snake_case__							:     List[Any]            =     [meta_mem.copy() for i in range(6 )]
            snake_case__							:     Dict            =     VGroup(*_snake_case ).arrange(_snake_case,			buff=0 )
            snake_case__							:     Tuple            =     VGroup(*_snake_case ).arrange(_snake_case,			buff=0 )
            snake_case__							:     int            =     VGroup(_snake_case,			_snake_case ).arrange(_snake_case,			buff=0 )
            snake_case__							:     Union[str, Any]            =     Text('Disk',			font_size=2_4 )
            snake_case__							:     int            =     Group(_snake_case,			_snake_case ).arrange(_snake_case,			buff=0.5,			aligned_edge=_snake_case )
            disk.move_to([-4.0, -1.2_5, 0] )
            self.add(_snake_case,			_snake_case )

            snake_case__							:     str            =     []

            for i in range(6 ):
                   snake_case__							:     str            =     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__							:     int            =     Square(side_length=2.2 )
            key.move_to([-5, 2, 0] )

            snake_case__							:     int            =     MarkupText(
                F'''<b>Key:</b>\n\n<span fgcolor=\'{YELLOW}\'>●</span> Empty Model''',			font_size=1_8,			)

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

            self.add(_snake_case,			_snake_case )

            snake_case__							:     Optional[int]            =     MarkupText(
                F'''<span fgcolor=\'{BLUE}\'>●</span> Checkpoint''',			font_size=1_8,			)

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

            snake_case__							:     Optional[int]            =     MarkupText(F'''The offloaded weights are all sent to the CPU.''',			font_size=2_4 )
            step_a.move_to([2, 2, 0] )

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

            for i in range(6 ):
                   snake_case__							:     int            =     cpu_disk_arr[i]
                   snake_case__							:     Optional[Any]            =     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__							:     Optional[Any]            =     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=2_4,			)
            step_a.move_to([2, 2, 0] )

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

            snake_case__							:     str            =     []
            snake_case__							:     Optional[Any]            =     []
            for i in range(6 ):
                   snake_case__							:     List[Any]            =     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()






