
    ~Wh                     J    d Z ddlZddlmc mZ ddlmZ g dZ	d Z
d Zd ZdS )z(Keras Utilities for DTensor related API.    N)dtensor_api)alphabetabias	depthwise
embeddingsgammakernelmoving_meanmoving_variance	pointwise	recurrentc                 Z      fd}t           j        j                             |          S )a  A decorator for injecting layout information to layer.__init__.

    Layout will be a new param for any of the weights for all the keras layers.
    Adding the param to all the __init__ method will be a big/duplicated work.

    This decorator is design to reduce and code duplication and make it easy to
    add/remove the dtensor feature if needed.

    Sample usage:
    ```python
    class Dense(tf.keras.layer.Layer):

      @allow_initializer_layout
      def __init__(self, units,
                   kernel_initializer='zeros',
                   bias_initializer='zeros',
                   **kwargs):
         super().__init__(**kwargs)

    d = Dense(units=8, kernel_layout=layout1, bias_layout=layout2)
    d.kernel_layout == layout1
    d.bias_layout == layout2
    ```

    By adding this annotation, it will:

    1. Filter out the kwargs based on some keywords, eg if the
      'kernel_initialzer' appears in method signature, then it will try to pop
      the 'kernel_layout' if it presents. Same for "bias" and
      "recurrent_kernel", etc. This will make sure the layout related param is
      not passed to `BaseLayer.__init__`, which will raise error about unexpect
      keyword args.
    2. Set the self.kernel/bias_layout attribute after the `__init__` method is
       called. Keras framework will use those fields to create weights down the
       stream.

    Args:
      init_method: the `__init__` method of the Keras layer to annotate.

    Returns:
      the annotated __init__ method.
    c                    t          j                  }i }t          D ]1}|dz   |j        v r#|                    |dz   d           }|r|||dz   <   2 | g|R i | |                                D ]\  }}t          | ||           d S )N_initializer_layout)inspect	signatureKERAS_VARIABLE_NAMES
parameterspopitemssetattr)	layer_instanceargskwargsr   layout_argsvariable_namelayoutlayout_param_nameinit_methods	           Y/var/www/html/movieo_spanner_bot/venv/lib/python3.11/site-packages/keras/dtensor/utils.py_wrap_functionz0allow_initializer_layout.<locals>._wrap_functionU   s    %k22	 2 	D 	DM~-1EEEMI$=tDD D=CK	 9:N4T444V444 *5):):)<)< 	? 	?%vN$5v>>>>	? 	?    targetdecorator_functf__internal__	decoratormake_decoratorr!   r#   s   ` r"   allow_initializer_layoutr.   )   sF    X? ? ? ? ?$ ?$33> 4   r$   c                 Z      fd}t           j        j                             |          S )a  Inject DTensor mesh information to an object.

    This is useful for keras object like `Metric` and `Optimizer` which need
    DTensor mesh to create the weights, but doesn't want to change the current
    public API interface.

    This is for temporary usage and eventually the mesh/layout information will
    be public arguments in the `__init__` method.

    Sample usage:
    ```python
    class Accuracy(tf.keras.metrics.Metric):

      @inject_mesh
      def __init__(self, name='accuracy', dtype=None):
         super().__init__(**kwargs)

      acc = Accuracy(mesh=mesh)
      assert acc._mesh == mesh
    ```

    Args:
      init_method: the `__init__` method of the Keras class to annotate.

    Returns:
      the annotated __init__ method.
    c                 ^    |                     dd           }||| _         | g|R i | d S )Nmesh)r   _mesh)instancer   r   r1   r!   s       r"   r#   z#inject_mesh.<locals>._wrap_function   sK    zz&$'' !HNH.t...v.....r$   r%   r(   r-   s   ` r"   inject_meshr4   l   sE    :/ / / / / ?$33> 4   r$   c                     |rNt          j        |j                  5   | |i |}t          j        ||          cddd           S # 1 swxY w Y    | |i |S )a  Invoke the function with inputs and relayout the result.

    Args:
      fn: the function to invoke.
      layout: if not None, the output of the fn will be relayout with this.
      *args: positional arguments to be called with fn.
      **kwargs: keyword arguments to be called with fn.

    Returns:
      The output of fn, with potential relayout with the layout specified.
    N)dtensorrun_onr1   relayout)fnr   r   r   results        r"   call_with_layoutr;      s      4^FK(( 	4 	4R(((F#FF33	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 2tvs   AA
A
)__doc__r   tensorflow.compat.v2compatv2r)   keras.dtensorr   r6   r   r.   r4   r;    r$   r"   <module>rB      s    / .  ! ! ! ! ! ! ! ! ! 0 0 0 0 0 0
   @ @ @F( ( (V    r$   