
    Vh                         d dl Z d dlmZmZmZ d dlZd dlmZmZ e	edf   Z
eeeef   ge	edf   f   Zg dZdedefdZd	ej"                  j$                  deeef   fd
Zdee   deeef   fdZdedefdZy)    N)AnyCallableUnion)tree_flatten_with_pathtree_map.)normalize_source_namemodule_to_nested_dicttrack_dynamism_across_examplesclone_and_convert_to_metanamereturnc                 0    t        j                  dd|       S )Nz\.([a-zA-Z_][a-zA-Z0-9_]*)z['\1'])resub)r   s    O/home/dcms/DCMS/lib/python3.12/site-packages/torch/fx/experimental/_dynamism.pyr   r      s    66/DAA    modulec                 D   i }i |d<   i |d<   t        |       D ]  }|j                  d      rt        t        | |            r+t        | |      }t	        |t
        j                  j                        r\t	        |t        t        t
        j                  f      st        |      t        us|||<    | j                  d      D ]  \  }}||d   |<    | j                  d      D ]  \  }}||d   |<    | j                         D ]  \  }}t!        |      |d   |<    |S )ziRecursively converts an nn.Module into a nested dictionary with explicit 'parameters' and 'modules' keys._parameters_modules_F)recurse)dir
startswithcallablegetattr
isinstancetorchnnModuleintfloatTensortypeboolnamed_parametersnamed_buffersnamed_childrenr	   )r   	self_dict	attr_name
attr_valuer   parambuffer	submodules           r   r	   r	      s2    "I!ImIj[ 2	##C('&):T1U 3Jz588??;zC+EF$D0'1	)$2 ..u.= /e).	- &/,,U,; 0f)/	- &0 "002 Gi&;I&F	*d#G r   example_inputsc                    i }| D ]m  }d|v r8t        |d   t        j                  j                        rt	        |d         |d<   t        |      \  }}|D ]  \  }}t        |t        t        t        j                  f      s-t        |t        j                        rt        |j                        }d}n|f}d}||vr0t        t        |            D cg c]  }t                c}|f||<   nV||   \  }	}
|
|k7  r	 t        |	      t        |      k  r1|	j                  t                      t        |	      t        |      k  r1t        |      D ]  \  }}||   d   |   j!                  |       !  p i }|j#                         D ]U  \  }\  }	}t        d |	D              }ddj%                  d |D              z   }|d   j&                  }||vri ||<   |||   |<   W |S c c}w )	a  
    This function analyzes a list of example inputs to determine the dynamism of their shapes.
    It tracks whether the dimensions of tensors or non-tensor values change across
    different examples. The function returns a dictionary where each key represents
    a path to a value in the input examples, and the corresponding value is a tuple
    indicating which dimensions are dynamic (i.e., change across examples). This
    helps in understanding how the structure of data varies across different instances.
    selfTFr   c              3   8   K   | ]  }t        |      d kD    yw)   N)len).0ss     r   	<genexpr>z1track_dynamism_across_examples.<locals>.<genexpr>[   s     7#a&1*7s   L c              3   4   K   | ]  }t        |         y w)N)str)r5   ks     r   r7   z1track_dynamism_across_examples.<locals>.<genexpr>\   s     >3q6(>s   )r   r   r   r    r	   r   r!   r"   r#   tupleshaperanger4   setappend	enumerateadditemsjoinkey)r/   trackingexleaves_with_pathsr   key_pathvaluer>   	is_tensordim_setsflagidimoutput
_is_tensor	final_dynkey_strrF   s                     r   r
   r
   4   s    <>H 2R<Jr&z588??C.r&z:BvJ5b910 	2OHeec5%,,%?@%.16u{{1C 	!	x'6;CJ6G&Hsu&H)%T"!)(!3$9$(mc%j0OOCE* (mc%j0#E* 23"1%a(,,S12#	2	20  F,4NN,< )((8Z7h77	>X>>>qkoofF3K(sG) M% 'Is   G"example_inputc                 :    dt         dt         fd}t        ||       S )z
    This function takes a list of example inputs and for each tensor, clones it and converts it to device=meta.
    For non-tensor values, it keeps the reference. It uses pytree to handle nested structures recursively.
    rK   r   c                 z    t        | t        j                        r | j                         j	                  d      S | S )Nmeta)device)r   r   r#   cloneto)rK   s    r   transform_fnz/clone_and_convert_to_meta.<locals>.transform_fnj   s/    eU\\*;;=##6#22r   )r   r   )rU   r\   s     r   r   r   d   s$    C C 
 L-00r   )r   typingr   r   r   r   torch.utils._pytreer   r   r=   KeyPathr!   r"   NonTensorShapeFn__all__r;   r   r   r    dictr	   listr
   r    r   r   <module>re      s    	 ' '  @ S/U3:./sCx@A B B B
%((// d38n 8-I-	#s(^-`1S 1S 1r   