
    qi                     P   d dl mZ d dlZd dlZd dlZd dlZd dlmZmZm	Z	 d dl
mZ d dlZ ed          Z e	d          Zdeeef         deeef         fdZ ej        d	
           G d d                      Zdej        dej        j        deegef         dej        fdZdS )    )CallableN)Any	ParamSpecTypeVarPRmethreturnc                     t          j                   rt           j        t          j                  st          d          t	          j         j                  \  dt          j        dt          j
        dt          j        dt          f fd}t          j        |g|R i |t          j                   dt          j
        dt          j        dt          ffd            }|S )a  A higher-order function to JIT-compile `nnx.Module` methods, freezing the module's state in the process.

    Why not `nnx.jit`? For some reason, naively applying `nnx.jit` to `nnx.Module` methods, bound or unbound, uses much
    more memory than necessary. I'm guessing it has something to do with the fact that it must keep track of module
    mutations. Also, `nnx.jit` has some inherent overhead compared to a standard `jax.jit`, since every call must
    traverse the NNX module graph. See https://github.com/google/flax/discussions/4224 for details.

    `module_jit` is an alternative that avoids these issues by freezing the module's state. The function returned by
    `module_jit` acts exactly like the original method, except that the state of the module is frozen to whatever it was
    when `module_jit` was called. Mutations to the module within `meth` are still allowed, but they will be discarded
    after the method call completes.
    z=module_jit must only be used on bound methods of nnx.Modules.stateargskwargsr
   c                 P    t          j        |           } j        |g|R i |S N)nnxmerge__func__)r   r   r   modulegraphdefr	   s       8/home/robot-lab/Pi0.5_yam/src/openpi/shared/nnx_utils.pyfunzmodule_jit.<locals>.fun!   s6    8U++t}V5d555f555    c                       g| R i |S r    )r   r   	jitted_fnr   s     r   wrapperzmodule_jit.<locals>.wrapper'   s#    y0000000r   )inspectismethod
isinstance__self__r   Module
ValueErrorsplitStater   r   r   r   jaxjit	functoolswraps)r	   jit_args
jit_kwargsr   r   r   r   r   s   `    @@@r   
module_jitr+      s    T"" Zz$-'L'L ZXYYYi..OHe639 6QV 6qx 6A 6 6 6 6 6 6 6 5h555*55I_T1qv 1 1a 1 1 1 1 1 1 1 Nr   T)frozenc                   j    e Zd ZU dZeej        z  ed<   dZeed<   d Z	de
j        j        dedefd	Zd
S )	PathRegexzNNX Filter that matches paths using a regex.

    By default, paths are joined with a `/` separator. This can be overridden by setting the `sep` argument.
    pattern/sepc                     t          | j        t          j                  s5t                              | dt          j        | j                             d S d S )Nr/   )r   r/   rePatternobject__setattr__compile)selfs    r   __post_init__zPathRegex.__post_init__8   sO    $,
33 	JtY
4<0H0HIIIII	J 	Jr   pathxr
   c                     | j                             d |D                       }t          | j        t          j                  sJ | j                            |          d uS )Nc              3   4   K   | ]}t          |          V  d S r   )str).0r;   s     r   	<genexpr>z%PathRegex.__call__.<locals>.<genexpr>=   s(      #9#9qCFF#9#9#9#9#9#9r   )r1   joinr   r/   r3   r4   	fullmatch)r8   r:   r;   joined_paths       r   __call__zPathRegex.__call__<   sY    hmm#9#9D#9#9#999$,
33333|%%k22$>>r   N)__name__
__module____qualname____doc__r>   r3   r4   __annotations__r1   r9   r   	filterlib	PathPartsr   boolrD   r   r   r   r.   r.   .   s          
 2:CNNNJ J J?S]4 ? ? ? ? ? ? ? ?r   r.   r   filterfnc                     t          |                     |                                                    |                     fd          S )zBApply a function to the leaves of the state that match the filter.c                 &    | v r |          n|S r   r   )kvfiltered_keysrN   s     r   <lambda>zstate_map.<locals>.<lambda>E   s    1+=+=""Q%%%1 r   )setrM   
flat_statemap)r   rM   rN   rS   s     `@r   	state_maprX   B   sH    V,,7799::M99DDDDDEEEr   )collections.abcr   dataclassesr'   r   r3   typingr   r   r   flax.nnxr   r%   r   r   r+   	dataclassr.   r$   rJ   FilterrX   r   r   r   <module>r_      sf   $ $ $ $ $ $          				 * * * * * * * * * *       



IcNNGCLLXad^ !Q$    > d###? ? ? ? ? ? ? $#?&FSY F(< F(C5RU:BV F[^[d F F F F F Fr   