

from manim import *


class       SCREAMING_SNAKE_CASE__					(__snake_case     ):





    def       snake_case_				(      self):
         lowercase__    :   Optional[Any]      =       Rectangle(height=0.5						,   width=0.5)
         lowercase__    :   Optional[int]      =       Rectangle(height=0.25						,   width=0.25)
         lowercase__    :   List[Any]      =       Rectangle(height=0.46						,   width=0.46).set_stroke(width=0)

         lowercase__    :   Optional[Any]      =       [mem.copy() for i in range(6)]
         lowercase__    :   Optional[Any]      =       [mem.copy() for i in range(6)]
         lowercase__    :   Any      =       VGroup(*a).arrange(a						,   buff=0)
         lowercase__    :   Tuple      =       VGroup(*a).arrange(a						,   buff=0)
         lowercase__    :   List[str]      =       VGroup(a						,   a).arrange(a						,   buff=0)
         lowercase__    :   List[str]      =       Text('CPU'						,   font_size=24)
         lowercase__    :   List[str]      =       Group(a						,   a).arrange(a						,   buff=0.5						,   aligned_edge=a)
         cpu.move_to([-2.5, -0.5, 0])
         self.add(a)

         lowercase__    :   Optional[Any]      =       [mem.copy() for i in range(4)]
         lowercase__    :   Any      =       VGroup(*a).arrange(a						,   buff=0)
         lowercase__    :   Optional[int]      =       Text('GPU'						,   font_size=24)
         lowercase__    :   Optional[int]      =       Group(a						,   a).arrange(a						,   buff=0.5						,   aligned_edge=a)
         gpu.move_to([-1, -1, 0])
         self.add(a)

         lowercase__    :   Optional[int]      =       [mem.copy() for i in range(6)]
         lowercase__    :   List[str]      =       VGroup(*a).arrange(a						,   buff=0)

         lowercase__    :   Tuple      =       Text('Model'						,   font_size=24)
         lowercase__    :   Any      =       Group(a						,   a).arrange(a						,   buff=0.5						,   aligned_edge=a)
         model.move_to([3, -1.0, 0])
         self.add(a)

         lowercase__    :   Tuple      =       []
         lowercase__    :   Any      =       []
         lowercase__    :   Dict      =       []

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

              lowercase__    :   Dict      =       Rectangle(height=0.46 / 4						,   width=0.46 / 3).set_stroke(width=0.0).set_fill(a						,   opacity=0.7)

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

         self.add(*a						,   *a						,   *a)

         lowercase__    :   List[str]      =       [mem.copy() for i in range(6)]
         lowercase__    :   Optional[Any]      =       VGroup(*a).arrange(a						,   buff=0)

         lowercase__    :   int      =       Text('Loaded Checkpoint'						,   font_size=24)
         lowercase__    :   Optional[int]      =       Group(a						,   a).arrange(a						,   buff=0.5						,   aligned_edge=a)
         checkpoint.move_to([3, 0.5, 0])

         self.add(a)

         lowercase__    :   str      =       []
         lowercase__    :   str      =       []

         for i, rect in enumerate(a):
              lowercase__    :   Optional[Any]      =       fill.copy().set_fill(a						,   opacity=0.7)
              target.move_to(a)
              ckpt_arr.append(a)

              lowercase__    :   str      =       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(a)
         self.add(*a						,   *a)

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

         lowercase__    :   Any      =       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(a						,   a)

         lowercase__    :   List[Any]      =       MarkupText(
             f"""<span fgcolor='{BLUE}'>●</span> Checkpoint"""						,   font_size=18						,   )

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

         lowercase__    :   int      =       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])

         lowercase__    :   List[Any]      =       [meta_mem.copy() for i in range(6)]
         lowercase__    :   Optional[int]      =       [meta_mem.copy() for i in range(6)]
         lowercase__    :   Dict      =       VGroup(*a).arrange(a						,   buff=0)
         lowercase__    :   List[Any]      =       VGroup(*a).arrange(a						,   buff=0)
         lowercase__    :   List[str]      =       VGroup(a						,   a).arrange(a						,   buff=0)
         lowercase__    :   Optional[int]      =       Text('Disk'						,   font_size=24)
         lowercase__    :   Tuple      =       Group(a						,   a).arrange(a						,   buff=0.5						,   aligned_edge=a)
         disk.move_to([-4.0, -1.25, 0])
         self.play(Write(a						,   run_time=3)						,   Write(a						,   run_time=1)						,   Create(a						,   run_time=1))

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

         self.play(FadeOut(a))

         lowercase__    :   Optional[Any]      =       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(a						,   run_time=3))

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

         self.wait()




from __future__ import annotations

from collections.abc import Callable
from typing import Generic, TypeVar

snake_case_			  = TypeVar('''T''')
snake_case_			  = TypeVar('''U''')


class       SCREAMING_SNAKE_CASE__					(Generic[T, U]     ):





    def __init__(      self						,   a						,   a):
         lowercase__    :   List[Any]      =       key
         lowercase__    :   List[Any]      =       val
         lowercase__    :   DoubleLinkedListNode[T, U] | None      =       None
         lowercase__    :   DoubleLinkedListNode[T, U] | None      =       None





    def __repr__(      self):
         return (
             f"""Node: key: {self.key}, val: {self.val}, """
             f"""has next: {bool(self.next)}, has prev: {bool(self.prev)}"""
         )



class       SCREAMING_SNAKE_CASE__					(Generic[T, U]     ):





    def __init__(      self):
         lowercase__    :   DoubleLinkedListNode[T, U]      =       DoubleLinkedListNode(a						,   a)
         lowercase__    :   DoubleLinkedListNode[T, U]      =       DoubleLinkedListNode(a						,   a)
         lowercase__      , lowercase__    :   Union[str, Any]      =       self.rear, self.head





    def __repr__(      self):
         lowercase__    :   Any      =       ['DoubleLinkedList']
         lowercase__    :   List[str]      =       self.head
         while node.next is not None:
              rep.append(str(a))
              lowercase__    :   Tuple      =       node.next
         rep.append(str(self.rear))
         return ",\n    ".join(a)





    def       snake_case_				(      self						,   a):
         lowercase__    :   Optional[Any]      =       self.rear.prev

         # All nodes other than self.head are guaranteed to have non-None previous
         assert previous is not None

         lowercase__    :   Dict      =       node
         lowercase__    :   int      =       previous
         lowercase__    :   Union[str, Any]      =       node
         lowercase__    :   Optional[int]      =       self.rear





    def       snake_case_				(      self						,   a):

         if node.prev is None or node.next is None:
              return None

         lowercase__    :   Union[str, Any]      =       node.next
         lowercase__    :   Tuple      =       node.prev
         lowercase__    :   Union[str, Any]      =       None
         lowercase__    :   List[Any]      =       None
         return node



class       SCREAMING_SNAKE_CASE__					(Generic[T, U]     ):
    __lowerCamelCase						:       dict[Callable[[T], U], LRUCache[T, U]]														=     {}





    def __init__(      self						,   a):
         lowercase__    :   DoubleLinkedList[T, U]      =       DoubleLinkedList()
         lowercase__    :   Optional[Any]      =       capacity
         lowercase__    :   Union[str, Any]      =       0
         lowercase__    :   Tuple      =       0
         lowercase__    :   int      =       0
         lowercase__    :   dict[T, DoubleLinkedListNode[T, U]]      =       {}





    def __repr__(      self):
         return (
             f"""CacheInfo(hits={self.hits}, misses={self.miss}, """
             f"""capacity={self.capacity}, current size={self.num_keys})"""
         )





    def __contains__(      self						,   a):
         return key in self.cache





    def       snake_case_				(      self						,   a):
         # Note: pythonic interface would throw KeyError rather than return None

         if key in self.cache:
              self.hits += 1
              lowercase__    :   DoubleLinkedListNode[T, U]      =       self.cache[key]
              lowercase__    :   str      =       self.list.remove(self.cache[key])
              assert node == value_node

              # node is guaranteed not None because it is in self.cache
              assert node is not None
              self.list.add(a)
              return node.val
         self.miss += 1
         return None





    def       snake_case_				(      self						,   a						,   a):

         if key not in self.cache:
              if self.num_keys >= self.capacity:
                   # delete first node (oldest) when over capacity
                   lowercase__    :   Optional[int]      =       self.list.head.next

                   # guaranteed to have a non-None first node when num_keys > 0
                   # explain to type checker via assertions
                   assert first_node is not None
                   assert first_node.key is not None
                   assert (
                       self.list.remove(a) is not None
                   )  # node guaranteed to be in list assert node.key is not None

                   del self.cache[first_node.key]
                   self.num_keys -= 1
              lowercase__    :   Optional[Any]      =       DoubleLinkedListNode(a						,   a)
              self.list.add(self.cache[key])
              self.num_keys += 1

         else:
              # bump node to the end of the list, update value
              lowercase__    :   Any      =       self.list.remove(self.cache[key])
              assert node is not None  # node guaranteed to be in list
              lowercase__    :   Union[str, Any]      =       value
              self.list.add(a)





    @classmethod
    def       snake_case_				(      cls						,   a = 128):

         def cache_decorator_inner(a) -> Callable[..., U]:
              def cache_decorator_wrapper(*a) -> U:
                   if func not in cls.decorator_function_to_instance_map:
                        lowercase__    :   Dict      =       LRUCache(a)

                   lowercase__    :   str      =       cls.decorator_function_to_instance_map[func].get(args[0])
                   if result is None:
                        lowercase__    :   str      =       func(*a)
                        cls.decorator_function_to_instance_map[func].put(args[0]						,   a)
                   return result

              def cache_info() -> LRUCache[T, U]:
                   return cls.decorator_function_to_instance_map[func]

              setattr(a						,   'cache_info'						,   a)  # noqa: B010

              return cache_decorator_wrapper

         return cache_decorator_inner


if __name__ == "__main__":
       import doctest

       doctest.testmod()

