
    קg?                        d dl Z d dlmZmZmZmZmZ d dlZd dlm	Z	 d dl
mZmZ g dZ e j        e          Z	 dZ G d d          Z G d	 d
e          Z e ej        d          d           Zd Z G d d          Z G d d          Zd Z	 	 ddeedf         deeeef                  dedeeedf                  deeeef                  deee         ee         f         fdZdee         fdZdS )    N)AnyDictListOptionalTuplemap_aggregate)tree_flattentree_unflatten)TensorChunkSpecsplit_args_kwargs_into_chunksmerge_chunksFc                       e Zd ZdZd ZdS )_CustomReducera$  
    Custom reducer class that can be used to specify a custom operation that
    reduces losses of multiple microbatches into one value.

    Example:
    >>> # xdoctest: +SKIP
    >>> sum_reducer = _CustomReducer(
    >>>     torch.tensor(0.0),
    >>>     lambda a, b: a + b
    >>> )
    c                 "    || _         || _        d S N)
init_value	reduce_fn)selfr   r   s      c/var/www/html/ai-engine/env/lib/python3.11/site-packages/torch/distributed/pipelining/microbatch.py__init__z_CustomReducer.__init__(   s    $"    N)__name__
__module____qualname____doc__r    r   r   r   r      s-        
 
# # # # #r   r   c                       e Zd ZdS )_LossReducerNr   r   r   r   r   r   r   r   -           Dr   r   g        c                     | |z   S r   r   )abs     r   <lambda>r%   1   s
    1q5 r   c                       e Zd ZU dZd Zeed<   d Zd Ze	de
edf         fd            Ze	deeef         fd	            Zd
S )r   z2
    Class used to specify chunking of inputs
    c                     || _         d S r   	split_dim)r   r)   s     r   r   zTensorChunkSpec.__init__=   s    "r   r)   c                 J    | j         j         d| j         j         d| j         dS )N.())	__class__r   r   r)   r   s    r   __repr__zTensorChunkSpec.__repr__B   s/    ~(VV4>+BVVT^VVV	
r   c                     d| j          dS )NzTensorChunkSpec(r-   r(   r/   s    r   __str__zTensorChunkSpec.__str__G   s    3$.3333r   
chunk_dims.c                 (    t          | d           }|S )a  
        A helper for creating a tuple of `TensorChunkSpec` from a tuple of chunk
        dimensions (int's).
        Example:
            >>> # xdoctest: +SKIP
            >>> # There are three positional arguments to the model, and
            >>> # we are chunking them along dimension 0, 0 and 1, respectively
            >>> args_chunk_spec = TensorChunkSpec.from_tuple((0, 0, 1))
        c                      t          |           S r   r   dims    r   r%   z,TensorChunkSpec.from_tuple.<locals>.<lambda>Y       ,, r   r   )r3   args_chunk_specs     r   
from_tuplezTensorChunkSpec.from_tupleJ   s$     (,,
 
 r   c                 (    t          | d           }|S )a\  
        A helper for creating a dictionary of `TensorChunkSpec` from a
        dictionary of chunk dimensions (int's).
        Example:
            >>> # xdoctest: +SKIP
            >>> # Chunk dimension 0 for the "id" argument, 1 for the "mask" argument
            >>> kwargs_chunk_spec = TensorChunkSpec.from_dict({"id": 0, "mask": 1})
        c                      t          |           S r   r6   r7   s    r   r%   z+TensorChunkSpec.from_dict.<locals>.<lambda>k   r9   r   r   )r3   kwargs_chunk_specs     r   	from_dictzTensorChunkSpec.from_dict]   s%     *,,
 
 ! r   N)r   r   r   r   r   int__annotations__r0   r2   staticmethodr   r;   r   strr?   r   r   r   r   r   8   s          # # # NNN
 
 

4 4 4 #s(O   \$ !cN! ! ! \! ! !r   r   c                       e Zd ZdS )
_ReplicateNr    r   r   r   rE   rE   q   r!   r   rE   c                    i }g }|}d}t          |           t          |          k    sNJ dt          |                                            dt          |                                                       |                                 D ]\  }}t	          |          \  }	}
|                    |
           ||         }|J t	          |          \  }}t          |	          t          |          k    rt          d| d|           g }t          |	|          D ]\  }}|t          u st          |t          j                  s|                    |g|z             Ct          |t                    r}t          |t          j                  sJ | d            |                    |j                  }||k     rB|r't                              d| d	| d
| d           |}nt#          d| d| d| d          t          j        |||j                  }t&          rg }d}|D ]}t          j        |          }||                    |j                  z   }t+          ddd          g|j        z  }t+          ||          ||j        <   |||<   |                    |           ||                    |j                  z  }|                    |           n|                    |           d}t/          d|           |||<   g }t1          |          D ]Z}i }|                                D ],\  }}g }|D ]}|                    ||                    |||<   -|                    |           [g }|D ]y} i }!t          |          t          |           k    sJ t          |                                 |          D ]\  \  }}}"t3          ||"          |!|<   |                    |!           z|S )aW  
    Given a dictionary of args, and a dictionary of chunking specs, shard the
    args according to the chunking specs.

    Args:
        args_dict: Dictionary of args
        args_chunk_spec: Dictionary of chunking specs
        num_chunks: Number of chunks to shard the args into

    Returns:
        args_split: List of sharded args
    Tzargs_dict.keys() = z args_chunk_spec.keys() = NzArgument value z9 did not have the same number of values as as chunk spec z is not a tensorz%Tensor size on chunking dimension is z', downsizing the number of chunks from z to r+   zArg z% on chunking dimension has a size of z$, smaller than the number of chunks z. PiPPy cannot reduce the number of chunks because other arguments have bigger chunk-dimension sizes. Please adjust your num_chunks setting.r   FzUnrecognized chunk spec: )lenlistkeysitemsr
   append
ValueErrorziprE   
isinstancetorchTensorr   sizer)   loggerwarningRuntimeErrortensor_split_debug_mask_minibatches
zeros_likeslicendim	TypeErrorranger   )#	args_dictr:   
num_chunksargs_sharded_replicated	arg_specsreal_num_chunksfirst_tensorarg_keyargflatspec
chunk_specchunk_spec_flat_sharded_arg_flatvchunk_vv_split_dim_sizechunk_tensorsexpanded_chunkssplit_dim_idxchunk_tensornew_val	upper_idxslice_indiceschunks_flat	chunk_idx
chunk_argskeyarg_single_chunkv_flat
args_splitchunkper_chunk_argsarg_specs#                                      r   _shard_dict_of_argsr~   u   s   ( !I OLy>>S    mT).."2"233mmtTcThThTjTjOkOkmm   ")) I< I<!#&&
d$W-
%%%)*55t99O,,,,8# 8 8+58 8  
 dO44 8	G 8	GJAw*$$Jq%,,G,G$ ''o(=>>>>G_55 5G "!U\22JJq4J4J4JJJJ#$66'*;#<#< #o55#  hDT h hDNh hTdh h h   +;*E7 E EQa E EAKE E E   !& 2(9! ! + ;&(O$%M(5 N N"'"21"5"5$1L4E4EgFW4X4X$X	).tT4)@)@(AGL(P;@)9< <g&78 2>.'..w777%):):7;L)M)MM$++O<<<<$++M:::$ EG E EFFF+;(( K?++ ' '	
/5577 	/ 	/HC! ; ; ''y(9::::.JsOO:&&&& J * *9~~U++++$'y$A$A 	@ 	@ JS#"0h"?"?N3.))))r   args.kwargschunksr:   r>   returnc                   	 |i }|%t          t                    ft          |           z  }|-t                              |t          t                              }t          t          t          |                     t          t          |                    |          }t          |          }t          |||          }t          |          |k     rTt          |          }t          t          t          |                     t          t          |                    |          }t          |          t          |          k    r/t          dt          |           dt          |                     g }|D ]J	|                    t          	fdt          t          	                    D                                  K||fS )a  
    Given a sequence of args and kwargs, split them into a number of chunks
    according to  their respective chunking specs.

    Args:
        args: Tuple of args
        kwargs: Dict of kwargs
        chunks: Number of chunks to split the args and kwargs into
        args_chunk_spec: chunking specs for args, in same shape as args
        kwargs_chunk_spec: chunking specs for kwargs, in same shape as kwargs

    Returns:
        args_split: List of sharded args
        kwargs_split: List of sharded kwargs
    Nz;args and kwargs are split into different number of chunks: z, c              3   (   K   | ]}|         V  d S r   r   ).0irv   s     r   	<genexpr>z0split_args_kwargs_into_chunks.<locals>.<genexpr>Y  s'      NN!
1NNNNNNr   )r   DEFAULT_CHUNK_DIMrG   dictfromkeysr~   	enumeraterT   rK   tupler[   )
r   r   r   r:   r>   args_split_dictr`   kwargs_splitrz   rv   s
            @r   r   r      s   p ~ *+<==?#d))K  MM&/BS2T2TUU)Yt__Y''(( O
 /**O& L <?** l++-4!!?++,,
 
 ?s<0000;?##; ;'*<'8'8; ;
 
 	

 J% P P
%NNNNuS__7M7MNNNNNOOOO|##r   c                 ^   |t          |          \  }}n=t          | d                   \  }}t          t                    gt          |          z  }g | D ]^}t          |          \  }}t          |          t          |          k    rt	          d| d|                               |           _g }t          |          D ]T\  }	t          |	t                    rmfdt          t                              D             }
t          r
|
d         j
        }|
dd         D ]}|j
        |k    sJ t          j        t          j        |ddit          |
          |	j        	          }g }d}t          |
          t          |          k    sJ t          |
|          D ]s\  }}||                    |	j                  z   }t#          ddd          g|j        z  }t#          ||          ||	j        <   ||         }|                    |           |}tn|
}|                    t          j        ||	j        
                     t          |	t(                    r_|	j        }t          t                              D ]$}|	                    ||                            }%|                    |           d                  }t          dt                              D ]}|                  |k    sJ |                    |           Vt/          ||          S )z
    Given a list of chunks, merge them into a single value according to
    the chunk spec.

    Args:
        chunks: list of chunks
        chunk_spec: Chunking spec for the chunks

    Returns:
        value: Merged value
    Nr   zChunk z did not match chunk spec c                 ,    g | ]}|                  S r   r   )r   ru   arg_idxchunks_flatteneds     r   
<listcomp>z merge_chunks.<locals>.<listcomp>  s3        !+G4  r      devicemeta)sectionsr8   r7   )r
   r   r   rG   rL   rK   r   rN   r[   rV   shaperO   rU   emptyr)   rM   rQ   rX   rY   catr   r   r   r   )r   rf   spec_flattenedflatten_specchunk0_flatr{   chunk_flattenedrh   args_flattenedrc   partial_valuesoverall_shapevalmeta_chunksvalues_to_catchunk_start_idxpartial_value
meta_chunkchunk_end_idxrs   slicedreduced_valru   valuer   r   s                           @@r   r   r   ^  s   Z '3J'?'?$ %1$;$;!\)*;<<=K@P@PP  1 1)%003~#6#666SeSSzSSTTT0000
 N!.11 0) 0)c?++ /	)    !&s+;'<'<!=!=  N
 ' / .q 1 7)!""- 6 6C955555#0K>v>> 00   !#"#>**c+.>.>>>>>14^[1Q1Q 4 4-M:$3joocm6T6T$TM%*4t%<%<$=@R$RM38-3X3XM#-0*=9F!((000&3OO4 !/!!%)Ms}"M"M"MNNNN^,, 	).K"3'7#8#899  	!mm!1)!<W!E  !!+....$Q'0E"1c*:&;&;<< E E	'	27;uDDDDD!!%(((( .,777r   )NN)loggingtypingr   r   r   r   r   rO   torch.fx.noder	   torch.utils._pytreer
   r   __all__	getLoggerr   rR   rV   r   r   tensorsum_reducerr   r   rE   r~   rC   r@   r   r   r   r   r   <module>r      s\    3 3 3 3 3 3 3 3 3 3 3 3 3 3  ' ' ' ' ' ' < < < < < < < <   
	8	$	$
   # # # # # # # #$	 	 	 	 	> 	 	 	 l<5<,,.@.@AA  5! 5! 5! 5! 5! 5! 5! 5!r	 	 	 	 	 	 	 	~ ~ ~J >B>Be$ e$
S/e$T#s(^$e$ e$ eOS$89:	e$
  S/%9 :;e$ 4;T
"#e$ e$ e$ e$Pw8Iw8 w8 w8 w8 w8 w8r   