o
    bi}<                     @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ edG dd deZdS )    N)backend)dtype_policies)tree)keras_export)any_symbolic_tensors)is_nnx_enabled)Node)KerasSaveable)python_utils)traceback_utils)	auto_namezkeras.Operationc                       s   e Zd Zd&ddZejdd Zdd Zdd	 Zd
d Z	dd Z
 fddZejdd Zedd Zdd Zedd Zedd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Z  ZS )'	OperationNc                 C   sV   |d u r
t | jj}t|trd|v r td| dt| d|| _g | _g | _	d S )N/zRArgument `name` must be a string and cannot contain character `/`. Received: name=z
 (of type ))
r   	__class____name__
isinstancestr
ValueErrortypename_inbound_nodes_outbound_nodes)selfr    r   K/home/ubuntu/.local/lib/python3.10/site-packages/keras/src/ops/operation.py__init__   s   
zOperation.__init__c                 O   sh  t  r[t||r| j}n;t| dd d ur9t| dd d ur+| j| jg|R i |}n| j| jg|R i |}nt| dd d urE| j}n| j}t j|| j	j
 dd}||i |S t||rh| j|i |S t| dd d urt| dd d ur| j| jg|R i ||i |S | j| jg|R i ||i |S t| dd d ur| j|i |S | j|i |S )N_remat_modequantization_modez.call())object_name)r   is_traceback_filtering_enabledr   symbolic_callgetattrrematerialized_callquantized_callcall!inject_argument_info_in_tracebackr   r   )r   argskwargscall_fnr   r   r   __call__    sd   

zOperation.__call__c                 O   s$   | j |i |}t| |||d |S )N)	operation	call_argscall_kwargsoutputs)compute_output_specr   )r   r'   r(   r.   r   r   r   r!   O   s
   zOperation.symbolic_callc                 O      t NNotImplementedErrorr   r'   r(   r   r   r   r%   ]      zOperation.callc                 O   r0   r1   r2   r4   r   r   r   r$   `   r5   zOperation.quantized_callc                 O   sz   zt j| jg|R i |W S  ty< } z"|d| j d| jj d| jj d| jj d| 
}||jd d }~ww )Nz;Could not automatically infer the output shape / dtype of 'z' (of type z). Either the `z<.call()` method is incorrect, or you need to implement the `zM.compute_output_spec() / compute_output_shape()` method. Error encountered:

)	r   r/   r%   	Exceptionr   r   r   with_traceback__traceback__)r   r'   r(   enew_er   r   r   r/   c   s&   	zOperation.compute_output_specc                    s  t t| | }t dkr5t r5ddlm} z|j t	|d< W n t
y4   |j t	|d< Y nw d}t| j}t| j z|jdg|R i |}W n ty\   d}Y nw |rrt fd	d
|j D rrd}d|_|r|  |j}|| ji O }| jd  |dd  jdur| j}t|dkrd}d|_ttt t!t"df}	zt#$|}
|
D ]}t%||	sd} nqW n ty   d}Y nw zd|_&|rddl'm(} |j)di ||_*nd|_*d|_&W |S  t+y   Y |S w )aJ  We override __new__ to saving serializable constructor arguments.

        These arguments are used to auto-generate an object serialization
        config, which enables user-created subclasses to be serializable
        out of the box in most cases without forcing the user
        to manually implement `get_config()`.
        jaxr   )nnx_pytree__state_object__stateTNFc                    s,   g | ]\}}| j d  kr|jtjjkqS )r   )r'   kindinspect	ParameterPOSITIONAL_ONLY).0r   paramargspecr   r   
<listcomp>   s
    z%Operation.__new__.<locals>.<listcomp>r   )serialization_libr   ),superr   __new__r   r   flaxr<   	pytreelibPytreeStatevarsAttributeErrorobjectObjectStater@   	signaturer   getfullargspecbind	TypeErrorany
parametersitems_auto_config_error_argsapply_defaults	argumentspopvarkwr'   varargslenr   intfloatboolr   r   flattenr   _lockkeras.src.savingrH   SerializableDict_auto_configRecursionError)clsr'   r(   instancer<   auto_configrR   bound_parametersr^   supported_typesflat_arg_valuesvaluerH   r   rE   r   rJ   r   sx   
	



zOperation.__new__c                 C   s   d| j i}t| js|S t| dddur@|| jj t	| j
j}d|v }d|v o3|d jtjjk}|s>|s>|dd |S d}t| ddrWttd| jj d	| ttd| jj d
| )zReturns the config of the object.

        An object config is a Python dictionary (serializable)
        containing the information needed to re-instantiate it.
        r   rg   Nr(   a  
            class CustomLayer(keras.layers.Layer):
                def __init__(self, arg1, arg2, **kwargs):
                    super().__init__(**kwargs)
                    self.arg1 = arg1
                    self.arg2 = arg2

                def get_config(self):
                    config = super().get_config()
                    config.update({
                        "arg1": self.arg1,
                        "arg2": self.arg2,
                    })
                    return config
            rY   Fz
            Object a   was created by passing
            positional only or variadic positional arguments (e.g.,
            `*args`) to `__init__()`, which is not supported by the
            automatic config generation. Please remove all positional
            only and variadic arguments from `__init__()`
            or override `get_config()` and `from_config()` to make
            the object serializatble.

            Example:

            a   was created by passing
            non-serializable argument values in `__init__()`,
            and therefore the object must override `get_config()` in
            order to be serializable. Please implement `get_config()`.

            Example:

            )r   r
   
is_default
get_configr"   updaterg   configr@   rR   r   rW   r?   rA   VAR_KEYWORDr\   r3   textwrapdedentr   r   )r   rt   init_paramsinit_has_nameinit_has_kwargsexample_strr   r   r   rr      sD   zOperation.get_configc              
   C   s   d|v r(t |d tr(| }t|d }t |tjs$|jdu r$|j}||d< z| di |W S  tyJ } zt	d| j
 d| d| d}~ww )a  Creates an operation from its config.

        This method is the reverse of `get_config`, capable of instantiating the
        same operation from the config dictionary.

        Note: If you override this method, you might receive a serialized dtype
        config, which is a `dict`. You can deserialize it as follows:

        ```python
        if "dtype" in config and isinstance(config["dtype"], dict):
            policy = dtype_policies.deserialize(config["dtype"])
        ```

        Args:
            config: A Python dictionary, typically the output of `get_config`.

        Returns:
            An operation instance.
        dtypeNz Error when deserializing class 'z' using config=z.

Exception encountered: r   )r   dictcopyr   deserializeDTypePolicyMapr   r   r6   rU   r   )ri   rt   policyr9   r   r   r   from_config  s(   


zOperation.from_configc                 C   s   d| j  dS )Nz<Operation name=>)r   r   r   r   r   __repr__D  s   zOperation.__repr__c                 C      |  dddS )zRetrieves the input tensor(s) of a symbolic operation.

        Only returns the tensor(s) corresponding to the *first time*
        the operation was called.

        Returns:
            Input tensor or list of input tensors.
        r   input_tensorsinput_get_node_attribute_at_indexr   r   r   r   r   G     
zOperation.inputc                 C   r   )zRetrieves the output tensor(s) of a layer.

        Only returns the tensor(s) corresponding to the *first time*
        the operation was called.

        Returns:
            Output tensor or list of output tensors.
        r   output_tensorsoutputr   r   r   r   r   r   S  r   zOperation.outputc                 C   s   | j std| j d| dt| j |ks'td| d| dt| j  dt| j | |}t|tr>t|dkr>|d	 S |S )
a  Private utility to retrieves an attribute (e.g. inputs) from a node.

        This is used to implement the properties:
        - output
        - input

        Args:
            node_index: Integer index of the node from which
                to retrieve the attribute.
            attr: Exact node attribute name.
            attr_name: Human-readable attribute name, for error messages.

        Returns:
            The operation's attribute `attr` at the node of index `node_index`.
        z
The layer z/ has never been called and thus has no defined .zAsked to get z	 at node z, but the operation has only z inbound nodes.   r   )r   rO   r   r_   r   r"   r   list)r   
node_indexattr	attr_namevaluesr   r   r   r   _  s$   
z&Operation._get_node_attribute_at_indexc                 C      dS )Nr   r   r   r   r   r   	_obj_type  r5   zOperation._obj_typec                 C   r   )5Can be overridden for per backend post build actions.Nr   r   r   r   r   _post_build     zOperation._post_buildc                 C   s   ||fS )r   r   )r   r   ro   r   r   r   _setattr_hook  s   zOperation._setattr_hookc                 C   r   )z5Can be overridden for per backend post track actions.Nr   r   variabler   r   r   _post_track_variable  r   zOperation._post_track_variablec                 C   r   )z7Can be overridden for per backend post untrack actions.Nr   r   r   r   r   _post_untrack_variable  r   z Operation._post_untrack_variabler1   )r   
__module____qualname__r   r   filter_tracebackr*   r!   r%   r$   r/   rJ   r
   defaultrr   classmethodr   r   propertyr   r   r   r   r   r   r   r   __classcell__r   r   rp   r   r      s0    

.[
L
)

!r   )r@   rv   	keras.srcr   r   r   keras.src.api_exportr   %keras.src.backend.common.keras_tensorr   keras.src.backend.configr   keras.src.ops.noder   keras.src.saving.keras_saveabler	   keras.src.utilsr
   r   keras.src.utils.namingr   r   r   r   r   r   <module>   s    