
    }YhF?                        d dl Z d dlZd dl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          ej                  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Optional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      y/var/www/tools.fuzzalab.pt/emblema-extractor/venv/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                       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__C   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__H   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   <lambda>z,TensorChunkSpec.from_tuple.<locals>.<lambda>Z       ,, r   r   )r,   args_chunk_specs     r   
from_tuplezTensorChunkSpec.from_tupleK   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   r/   r0   s    r   r2   z+TensorChunkSpec.from_dict.<locals>.<lambda>l   r3   r   r   )r,   kwargs_chunk_specs     r   	from_dictzTensorChunkSpec.from_dict^   s%     *,,
 
 ! r   N)r   r   r   r   r   int__annotations__r)   r+   staticmethodtupler5   dictstrr9   r   r   r   r	   r	   9   s          # # # NNN
 
 

4 4 4 #s(O   \$ !cN! ! ! \! ! !r   r	   c                       e Zd ZdS )
_ReplicateNr   r   r   r   rA   rA   r   r   r   rA   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 ]F!i }|                                D ]\  }}!fd|D             }|||<   |                    |           Gg }|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: c                      g | ]
}|         S r   r   ).0v_flat	chunk_idxs     r   
<listcomp>z'_shard_dict_of_args.<locals>.<listcomp>   s    DDDfy 1DDDr   )lenlistkeysitemsr   append
ValueErrorziprA   
isinstancetorchTensorr	   sizer"   loggerwarningRuntimeErrortensor_split_debug_mask_minibatches
zeros_likeslicendim	TypeErrorranger   )"	args_dictr4   
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_argskeyarg_single_chunk
args_splitchunkper_chunk_argsarg_specrF   s"                                    @r   _shard_dict_of_argsr}   v   s   ( !I OLy>>S11111nd9>>#3#344nnPTUdUiUiUkUkPlPlnn 211 ")) 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DDDDDDD.JsOO:&&&& J * *9~~U++++$'y$A$A 	@ 	@ JS#"0h"?"?N3.))))r   args.kwargschunksr4   r8   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          |                     d |D             }||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           
      z    g | ]7t          fd t          t                              D                       8S )c              3   (   K   | ]}|         V  d S r   r   )rD   irv   s     r   	<genexpr>z;split_args_kwargs_into_chunks.<locals>.<listcomp>.<genexpr>W  s'      <<jm<<<<<<r   )r=   r\   rH   )rD   rv   s    @r   rG   z1split_args_kwargs_into_chunks.<locals>.<listcomp>V  sT        	<<<<U3z??%;%;<<<<<  r   )r	   DEFAULT_CHUNK_DIMrH   r>   fromkeysr}   	enumeraterU   )	r~   r   r   r4   r8   args_split_dictra   kwargs_splitry   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
 |##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   )rD   rF   arg_idxchunks_flatteneds     r   rG   z merge_chunks.<locals>.<listcomp>  s3        !+G4  r      devicemeta)sectionsr1   r0   )r   r	   r   rH   rM   rL   r   rO   r\   rW   shaperP   rV   emptyr"   rN   rR   rY   rZ   catr   r   r   r   )r   rg   spec_flattenedflatten_specchunk0_flatrz   chunk_flattenedri   args_flattenedrd   partial_valuesoverall_shapevalmeta_chunksvalues_to_catchunk_start_idxpartial_value
meta_chunkchunk_end_idxrt   slicedreduced_valrF   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operatortypingr   r   rP   torch.fx.noder   torch.utils._pytreer   r   __all__	getLoggerr   rS   rW   r   r   tensoraddsum_reducerr   r	   rA   r}   r=   r>   r?   r:   rI   r
   r   r   r   r   <module>r      sQ                      ' ' ' ' ' ' < < < < < < < <   
	8	$	$
   # # # # # # # #$	 	 	 	 	> 	 	 	 l<5<,,hl;;  5! 5! 5! 5! 5! 5! 5! 5!r	 	 	 	 	 	 	 	| | |F >B>Bf$ f$
S/f$T#s(^$f$ f$ eOS$89:	f$
  S/%9 :;f$ 4;T
"#f$ f$ f$ f$Rw8Iw8 w8 w8 w8 w8 w8r   