
    VhY                     *   d dl Z d dlmZ d dlmZ d dlmZ d dlmZm	Z	m
Z
mZ d dlZd dlmZ d dlmZ d dlmZmZ d d	lmZmZmZmZmZmZmZmZmZ d d
lmZm Z  ejB                  jD                  Z"de#fdZ$ G d de jJ                        Z& G d d      Z'y)    N)Sequence)	lru_cache)chain)CallablecastOptionalUnion)
OpOverload)FakeTensorMode)DTensorSpec
TensorMeta)	OpInfoOpSchema
OpStrategyOutputShardingOutputSpecTypePlacementStrategyRuntimeSchemaInfoStrategyTypeTupleStrategy)%compute_local_shape_and_global_offsetcompute_local_stridereturnc                 @    | yt        | t              syt        |       S )Nr      )
isinstancer   len)objs    W/home/dcms/DCMS/lib/python3.12/site-packages/torch/distributed/tensor/_sharding_prop.py_lengthr        s     
{c8$s8O    c                   .    e Zd ZdeddfdZdefdZd Zy)LocalLRUCacheuser_functionr   Nc                 0     t        d       |      | _        y N)r   cache)selfr$   s     r   __init__zLocalLRUCache.__init__)   s    $Yt_]3
r!   c                 &     | j                   |i |S r&   )r'   )r(   argskwargss      r   __call__zLocalLRUCache.__call__,   s    tzz4*6**r!   c                 6    | j                   j                         S r&   )r'   
cache_infor(   s    r   r/   zLocalLRUCache.cache_info/   s    zz$$&&r!   )__name__
__module____qualname__r   r)   objectr-   r/    r!   r   r#   r#   (   s&    4h 44 4+6 +'r!   r#   c                   J   e Zd ZddZ	 ddedeegef   dee	   fdZ
	 ddedeegef   dee	   fd	Zd
ededeeee      f   fdZed
ededeeee      f   fd       Zdedededeeee      f   ddfdZd
edefdZdeddfdZd
edefdZdedefdZdedededefdZy)ShardingPropagatorr   Nc                 D   i | _         i | _        i | _        t        | j                        | _        t        j                  j                  dt        j                  j                  dt        j                  j                  dt        j                  j                  dt        j                  j                  dt        j                  j                  dt        j                  j                  dt        j                  j                  dt        j                   j                  di	| _        y )Nr   )r      )op_to_rulesop_strategy_funcsop_to_schema_infor#    propagate_op_sharding_non_cachedpropagate_op_shardingaten	new_emptydefaultnew_fullnew_ones	new_zerosnew_empty_stridedexpandreshapeview_unsafe_viewop_to_shape_and_stride_idxr0   s    r   r)   zShardingPropagator.__init__4   s    SU  	 GI%211&
" NN""AMM!!1MM!!1NN""A""**FKKLL  !IIq%%q
 	'r!   op_overload	rule_funcschema_infoc                 F    || j                   |<   ||| j                  |<   yy)zG
        Register a sharding propagation rule for an operator.
        N)r:   r<   )r(   rK   rL   rM   s       r   register_sharding_prop_rulez.ShardingPropagator.register_sharding_prop_ruleR   s/     )2%"2=D"";/ #r!   strategy_funcc                 F    || j                   |<   ||| j                  |<   yy)zI
        Register a sharding strategy generator for an operator.
        N)r;   r<   )r(   rK   rP   rM   s       r   register_op_strategyz'ShardingPropagator.register_op_strategy_   s/     /<{+"2=D"";/ #r!   	op_schemac                    |j                   t        j                  j                  k(  ryt	               5  |j                         }|j                         } |j                   |i |}ddd       t        t        j                        r0t        |j                  |j                         |j                        S t        |t        t        f      rg }|D ]m  }t        |t        j                        r@|j!                  t        |j                  |j                         |j                               ]|j!                  d       o t        |t              rt        |      S |S y# 1 sw Y   xY w)z{
        Propagate the tensor metadata, it could either return a TensorMeta
        or a list/tuple of TensorMetas
        N)shapestridedtype)opr?   equalrA   r   gen_fake_argsgen_fake_kwargsr   torchTensorr   rU   rV   rW   tuplelistappend)r(   rS   	fake_argsfake_kwargsfake_outtensor_meta_listfake_out_items          r   !_propagate_tensor_meta_non_cachedz4ShardingPropagator._propagate_tensor_meta_non_cachedl   s@    <<4::---  	?!//1I#335K#y||Y>+>H	?
 h-nnX__->hnn  5$-0;=!) 
2mU\\:$++""/"5"5#0#7#7#9"/"5"5 %++D1
2 h. &' & =	? 	?s   3E  E)c                 $    | j                  |      S r&   )rf   )r(   rS   s     r   _propagate_tensor_metaz)ShardingPropagator._propagate_tensor_meta   s     55i@@r!   rX   output_specsoutput_tensor_metac           
         t        |t              rbt        |t              sJt        |t        t        f      st        d      t        d|j                          dt        |       d      ||_        yt        |t        t        f      rt        |t        t        f      rt        |      t        |      k7  r5t        d|j                          dt        |       dt        |       d      t        |      D ]  \  }}t        |t              s||   }t        |t              s\|t        j                  j                  k(  r|dk(  r|t        |t              sJ d||<   ht        d	| d
|j                          d      ||_         yy)zQ
        Wrap the output_specs with the tensor metadata from the output.
        zGShardingPropagator error: output does not have an associated TensorMetazFor the op zM, `output_specs` has 1 output which does not equal the number of op outputs: .z, `output_specs` has z7 outputs which does not equal the number of op outputs r   Nz!ShardingPropagator error: output z of z' does not have an associated TensorMeta)r   r   r   r^   r_   
ValueErrornamer   tensor_metar    	enumerater?   convolution_backwardrA   )r(   rX   ri   rj   ispecoutput_tensor_meta_is          r   _wrap_output_spec_tensor_metaz0ShardingPropagator._wrap_output_spec_tensor_meta   s    lK00*=!"4udmD$%  !!"'') ---01C-D,EQH 
 (:L$udm405$-@CE'(E) !!"''),A#lBSAT U,,34F,G+HK  %\2 <4dK0+=a+@(%&:JG $";";"C"CC !Q 4 <#-lD#AA#A.2LO$","CA3d2779+ VI !I# 
 (<D$1< 5r!   c                 $   dt         dt         ffd|j                  D cg c]
  } |       }}|j                  j                         D ci c]  \  }}| |       }}}t	        |j
                  t        |      |      S c c}w c c}}w )z
        wrap a op_schema that contains DTensorSpec to another op_schema that contains
        OpStrategy/TupleStrategy, the returned op_schema is then used for sharding
        strategy propagation on pytorch operators.
        rs   r   c                 v   t        | t              rt        t        |       g      S t        | t        t
        f      rwt        |       dkD  rit        | d   t              rV| D cg c]
  } |       }}t        t        t           |      }t        t        | t
              rt        |            S |      S | S c c}w )Nr   )r   r   r   r   r_   r^   r   r   r   r   r   )rs   stuple_strategyspec_to_strategys      r   rz   zCShardingPropagator._wrap_with_op_strategy.<locals>.spec_to_strategy   s    $,!#4T#:";<<4$/IMtAw4 @D!D!"21"5!D!D!%h|&<n!M$-7e-DE.) JX   "Es   "B6)rX   args_schemakwargs_schema)r4   r{   r|   itemsr   rX   r^   )r(   rS   rr   args_op_strategykvkwargs_op_strategyrz   s          @r   _wrap_with_op_strategyz)ShardingPropagator._wrap_with_op_strategy   s    	6 	f 	" :C9N9NOA,Q/OO 09/F/F/L/L/N
'+q!A""
 
 ||./,
 	
 P
s   BBop_infoc                     |j                   j                  r#| j                  |j                         }||_        y t        t        | j                  |j                               }||_        y r&   )schemahas_symintsr=   r   r   r>   output_sharding)r(   r   r   s      r   	propagatezShardingPropagator.propagate   sY    
 >>%%"CCGNNSO
 #2 # : :7>> JO #2r!   c           
         |j                   t        j                  j                  u rt	        d|      S | j                  |      }|j                   | j                  v r| j                  |      } | j                  |j                      |      }t        |t              rP| j                  |      }d}g }|j                  t        |j                  t              sJ t        |j                        D ]r  \  }}	|j                  |j                   n|j                  |   }
|j#                  |
j%                  |	j&                               |	j(                  |
j(                  k7  sqd}t d}|r1t+        |j                   t-        |      i       }|j/                  |       |j                   | j0                  v rmt        |j                   t              sJ |j                   j3                         r7|xs |}t        |t4              sJ | j7                  |||j                         }d}|j9                         r|j                  }t        |t              rt-        t;        t=        |j                   j>                  j@                              D cg c].  }t        |jB                  |j(                  |j&                        0 c}      }n|jE                         r|j                  }nd}t	        |||      }n3t        |tF              rg }g }|jH                  D ]Q  }t        |t              sJ | j                  |      }|j#                  |       |j#                  |j                          S d}g }d}|jJ                  D ]S  }|rt        |tL        t,        f      rt        |d   t              rg }t        |      D ]`  \  }}||   jO                  |      }|j%                  |j&                        }|j(                  |j(                  k7  rd}|j#                  |       b |j#                  t        |t,              rt-        |      n|       |dz  }t        |t              rb|d   jO                  |      }|j%                  |j&                        }|j(                  |j(                  k7  rd}|j#                  |       |dz  }C|j#                  |       V d}|r*t+        |j                   t-        |      |jP                        }t	        |t-        |      nd||      }ntS        d      | jU                  |j                   |j                   |       |S |j                   | jV                  v r| jV                  |j                      }	  ||      }|j                   E|j^                  t]        d	| d       ||j^                        }|j                   |_        d|_0        | jU                  |j                   |j                   |       |S tY        d|j                    d      c c}w # tX        $ r}|d}~wtZ        $ r}t]        d	| d
|       |d}~ww xY w)zM
        Propagate the sharding for an operator given the op_schema.
        NFT)mesh
placementsro   )needs_redistributer   r   zUnsupported op strategy typez"Sharding propagation failed on op z	.
Error: !z	Operator z. does not have a sharding strategy registered.)1rX   r?   _local_scalar_denserA   r   rf   r;   r   r   r   _select_strategyinput_specsri   r   rp   	args_specoutput_specr`   shallow_copy_with_tensor_metaro   r   r   r^   !_inplace_rewrap_schema_suggestionrJ   
is_shardedr   _adjust_shape_and_stride_argsreturn_type_tuple_tensor_likeranger   _schemareturnsr   return_type_tensorr   childsr{   r_   
input_specr|   rm   ru   r:   NotImplementedError	ExceptionRuntimeErrorredistribute_schemar   )r(   rS   out_tensor_metastrategy_schemaop_strategyoutput_strategyr   expected_input_specsidxr   desired_specsuggestion_schemar   ri   _r   selected_strategiesout_spec_liststrategyselected_strategysuggestion_argstensor_or_list_tensor_arg_idxargexpected_input_spec_listarg_specexpected_input_specsharding_prop_funcepropagation_ress                                r   r=   z3ShardingPropagator.propagate_op_sharding_non_cached  s]    <<433;;;!$	22@@K<<4111"99)DO ?$00>OK+z2"&"7"7"D &+":<$
 #..6%o&B&BKPPP'01D1D'E 2OC +66> (33,88= !
 )//$BB&22
 ",,0G0GG-1*2 %)!%(0!e,@&A2)% &GG	R <<4#B#BB%o&A&A;OOO '22==?!2!?i)/:FFF,0,N,N+V_5P5P-) .2* ::< 4C3O3OL!,<', */s9<<3G3G3O3O/P)Q	 %& !,)5):):/;/F/F0<0H0H!"	( 113#2#?#?L#'L"0 %'9#
 K7 @B#35 + 2 2 HH%h
;;;(,(=(=h(G%'../@A!(():)F)FG	H &+"0201-$00 (4C&sT5M:&s1v{;FH0-6s^ QMC2Ec2J2U2U =3/ !4 Q Q$,$8$8!" 0
  (226I6T6TT59 24;;<OPQ (..)#u5 "":;!9
 6:5#C5.A!.D.O.O9/+ 0MM # ,
 >>-@-K-KK15.'../BC5:5'..s3Q(4T %)!%(0!eO&<i>U>U)% #1,;,GE-(T%'9# !!?@@ ..o99? #"\\T---!%!1!1),,!?"4Y"? **2"66>&<YKqI  '9';;'O 3B2M2MO/9=O6 ..o99? #"%ILL>)WX [	R '  "8:aSQs*   3X<X 	Y
%X''Y
3YY
r   c                 \   t        |j                        dk(  r|j                  d   S g }|j                  D ]N  }|j                  J d       t        t	        j
                  |j                              }|j                  |       P |j                  |j                  t        |               S )Nr   r   z)must set redistribute cost each strategy!)	r   
strategiesredistribute_costsumr   from_iterabler`   indexmin)r(   r   strategy_costsstrtgr   s        r   r   z#ShardingPropagator._select_strategy  s    x""#q(&&q))&((( 	5E**6 ;6 !$E$7$78O8O$P Q!!"34	5 "">#7#7N8K#LMMr!   r   r   rs   c                    | j                   |j                     }t        |t              r|\  }}n|}d }t	        |j
                        }t        |j                  |j                  |j                        \  ||<   }|r.t        |j                  |j                  |j                        ||<   t        |j                  t        |      |j                        S r&   )rJ   rX   r   r^   r_   r{   r   rU   r   r   r   rV   r   r|   )	r(   r   r   rs   shape_stride_idx	shape_idx
stride_idxexpected_input_schemar   s	            r   r   z0ShardingPropagator._adjust_shape_and_stride_args  s      ::699E&.$4!Iz(IJ $V%7%7 8 /T!!499doo/
+i(!
 0D&&		4??1!*- 		5)>#?AUAUVVr!   )r   Nr&   )r1   r2   r3   r)   r
   r   r   r   r   r   rO   r   rR   r	   r   r   rf   r   rh   r   ru   r   r   r   r=   r   r   r   r   r   r5   r!   r   r7   r7   3   s   
D 48	>> XJ67> /0	>" 48	>>  
L 89> /0	>+!+	tZ(:*>!??	@+Z A!A	tZ(:*>!??	@A A
:<:< %:< "$
HXj=Q4R"RS	:<
 
:<x"
 "
X "
H2 2D 2Z( Z~ ZxN N8I N W#W W 	W
 
Wr!   r7   )(	threadingcollections.abcr   	functoolsr   	itertoolsr   typingr   r   r   r	   r\   
torch._opsr
   torch._subclassesr   &torch.distributed.tensor._dtensor_specr   r   #torch.distributed.tensor._op_schemar   r   r   r   r   r   r   r   r   torch.distributed.tensor._utilsr   r   opsr?   intr    localr#   r7   r5   r!   r   <module>r      sp     $   2 2  ! , J
 
 
 yy~~C 'IOO '_W _Wr!   