ó
    Eñi_ ã                   óp  • S SK r S SKrS SKrS SKrS SKJrJrJr  S SKJ	r	  S SK
JrJr  S SKJr  S SKJrJrJrJrJr  S SKrS SKJr  S SKJs  Js  Jr  S SKJr  S SKJ r   S SK!J"r"  S S	K#J$r$J%r%J&r&J'r'J(r(J)r)J*r*  S S
K+J,r,  S SK-J.r.J/r/  S SK0J1r1J2r2  S SK3J4r4J5r5  S SK6J7r7J8r8J9r9  S SK:J;r;J<r<  S SK=J>r>  \(       a  S SK?J@r@  \R‚                  " \B5      rC\ " S S5      5       rDS\E\F\4   S\\G\F\4      4S jrH\ " S S5      5       rI " S S\5      rJ " S S\5      rKS\DS\E\F\4   S\LS \LS!\LS\M\E\F\4      4S" jrNS#\S\L4S$ jrOS\DS\E\F\4   S\I4S% jrPS\DS&\IS \LS\M\E\F\4      4S' jrQS(\%S)\E\F\4   S*\R¤                  S-  S\E\F\4   4S+ jrSS(\%S&\S*\R¤                  S-  S\4S, jrTS\DS-\FS)\E\F\4   S\E\F\4   4S. jrU    ShS/\E\F\4   S0\R¬                  S1\LS2\R®                  R°                  S-  S3\LS*\R¤                  S-  S\E\F\4   4S4 jjrYS\DS5\E\F\E\F\4   4   S6\M\F   S\E\F\4   4S7 jrZS8\FS9\M\R¶                     S6\M\F   S:\\R¸                     S;\/S\R¶                  4S< jr]S8\FS=\M\R¶                     S6\M\F   S\R¶                  4S> jr^S8\FS?\M\   S6\M\F   S\4S@ jr_ SiSA\E\F\4   S0\R¬                  S2\R®                  R°                  SB\M\E\F\4      \\RÀ                     -  S-  SC\LSD\LS\E\F\4   4SE jjra SjS0\R¬                  SB\M\E\F\4      \\RÀ                     -  S-  S\E\b\RÀ                  4   4SF jjrcS0\R<                  R¬                  S\E\.\F4   4SG jrd    SkS2\R®                  R°                  S0\R¬                  S-  SD\LSH\E\RÀ                  \M\F   4   S-  SI\E\.\F4   S-  S\E\b\F-  \RÀ                  4   4SJ jjre    SkS2\R®                  R°                  S0\R¬                  S-  SD\LSH\E\RÀ                  \M\F   4   S-  SI\E\.\F4   S-  S\E\RÀ                  \b\F-  4   4SK jjrf SjS0\R¬                  SB\M\E\F\4      \\RÀ                     -  S-  S\E\RÀ                  \b4   4SL jjrgSM\M\K   SN\E\K\F\b-  4   SO\E\F\b-  \RÀ                  4   S*\R¤                  S-  SS4
SP jrh SiS/\E\F\4   S*\R¤                  S-  SO\E\b\F-  \RÀ                  4   SH\E\RÀ                  \M\F   4   SQ\E\F\D4   SR\LS\G\M\K   \E\K\b\F-  4   4   4SS jjriST\E\F\4   SO\E\b\F-  \RÀ                  4   SH\E\RÀ                  \M\F   4   S\M\E\F\4      4SU jrjS/\E\F\4   S\L4SV jrk\ " SW SX5      5       rlS(\%SY\E\F\4   S\M\E\F\l4      4SZ jrmS\DS[\M\E\F\l4      SY\E\F\4   S\\E\F\E\F\4   4   S\G\RÜ                  S-  \E\F\M\R¶                  S-     4   4   4
S] jroS\DS\\E\F\E\F\4   4   S8\FS \LS\LS!\LSS4S^ jrpS\DS[\M\E\F\l4      SY\E\F\4   S \LS\LS!\LS\E\F\E\F\4   4   4S_ jrqS\DSY\E\F\4   S \LS\LS!\LS\E\F\4   4S` jrr SlSa\M\K   SN\E\K\b\F-  4   SQ\E\F\D4   S/\E\F\b-  \4   S\LS \LS!\LS\E\F\4   4Sb jjrs SlSa\M\K   SN\E\K\b\F-  4   SQ\E\F\D4   S/\E\F\b-  \4   S\LS \LS!\LS\E\F\4   4Sc jjrt\Rê                  " 5         SmS0\R¬                  S2\R®                  R°                  S/\E\F\4   SB\M\E\F\4      \\RÀ                     -  S-  S3\LS \LS*\R¤                  S-  SC\LS1\LS!\LS\E\F\4   4Sd jj5       rvS0\R¬                  S\E\F\D4   4Se jrw\S(\%Sf\8SS4Sg j5       rxg)né    N)ÚIterableÚIteratorÚSequence)Ú	ExitStack)Ú	dataclassÚfield)Úchain)ÚAnyÚcastÚ
NamedTupleÚno_type_checkÚTYPE_CHECKING)Ú_gather_state_dict)Ú_get_pg_default_device)Ú_apply_to_modulesÚ
_FSDPStateÚ._get_module_fsdp_state_if_fully_sharded_moduleÚ_get_param_to_fqnsÚ_module_handleÚ!_named_parameters_with_duplicatesÚclean_tensor_name)ÚSimpleProfiler)ÚFlatParameterÚFlatParamHandle)Ú_ext_chunk_dtensorÚ_ext_chunk_tensor)Ú
_lazy_initÚ%_reset_flat_param_grad_info_if_needed)ÚShardingStrategyÚStateDictSettingsÚStateDictType)ÚDTensorÚ	Replicate)Útree_map_only)ÚShardedTensorc                   óN   • \ rS rSr% \\S'   \\S'   \\\	4   \S'   \
\   \S'   Srg)ÚFSDPParamInfoé5   ÚstateÚhandleÚparam_indicesÚparam_requires_grad© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r   Ú__annotations__r   ÚdictÚstrÚintÚlistÚboolÚ__static_attributes__r-   ó    Ú`/home/mande/repo/quber/.venv/lib/python3.13/site-packages/torch/distributed/fsdp/_optim_utils.pyr'   r'   5   s&   ‡ àÓØÓØ˜˜S˜‘>Ó!Ø˜d™Ö#r9   r'   Ú
dictionaryÚreturnc              #   ó`   #   • [        U R                  5       5      nU H  nX U   4v •  M     g 7f©N)ÚsortedÚkeys)r;   r@   Úks      r:   Úsorted_itemsrB   =   s-   é € Ü�*—/‘/Ó#Ó$€DÛˆØ˜A‘ÐÔò ùs   ‚,.c                   ó¢   • \ rS rSr% Sr\" \S9r\\\	R                  4   \S'   \" \S9r\\\	R                  4   \S'   \" \S9r\\\4   \S'   Srg)	Ú_ConsolidatedOptimStateéC   a4  
This holds the consolidated optimizer state on the target rank. Positive-
dimension tensor state is communicated across ranks, while zero-dimension
tensor state and non-tensor state is taken directly from the target rank.

PyTorch version 1.12 moved to using zero-dimension tensors for scalar
values, but user implemented optimizers may still use float (i.e. a
non-tensor). Thus, we support both and handle them identically.

Attributes:
    tensor_state (Dict[str, torch.Tensor]): Mapping from positive-dimension
        tensor state name to the unsharded flat tensor representing the
        state.
    zero_dim_tensor_state (Dict[str, torch.Tensor]): Mapping from zero-
        dimension tensor state name to its value.
    non_tensor_state (Dict[str, Any]): Mapping from non-tensor state
        name to its value.
)Údefault_factoryÚtensor_stateÚzero_dim_tensor_stateÚnon_tensor_stater-   N)r.   r/   r0   r1   Ú__doc__r   r3   rG   r4   ÚtorchÚTensorr2   rH   rI   r
   r8   r-   r9   r:   rD   rD   C   s\   ‡ ññ& -2À$Ñ,G€L�$�s˜EŸL™LÐ(Ñ)ÓGÙ5:È4Ñ5PÐ˜4  U§\¡\Ð 1Ñ2ÓPÙ',¸TÑ'BÐ�d˜3 ˜8‘nÖBr9   rD   c                   óV   • \ rS rSr% Sr\R                  \S'   \R                  \S'   Sr	g)Ú_PosDimTensorInfoé]   ac  
Metadata for positive-dimension tensors used internally for
:meth:`scatter_full_optim_state_dict`.

Attributes:
    shape (torch.Size): Sharded tensor shape (which is equal to the
        unsharded tensor shape if the tensor is optimizer state for a
        non-FSDP parameter and is hence not sharded).
    dtype (torch.dtype): Data type of the tensor.
ÚshapeÚdtyper-   N)
r.   r/   r0   r1   rJ   rK   ÚSizer2   rQ   r8   r-   r9   r:   rN   rN   ]   s   ‡ ñ	ð �:‰:ÓØ�;‰;Ör9   rN   c                   ó8   • \ rS rSr% Sr\\S4   \S'   \\S'   Sr	g)Ú_OptimStateKeyém   zÛ
This represents an optimizer state key that may be used commonly across
ranks. It is based on the unflattened parameter names rather than parameter
IDs to make it independent of each rank's own optimizer construction.
.Úunflat_param_namesÚis_fsdp_managedr-   N)
r.   r/   r0   r1   rJ   Útupler4   r2   r7   r8   r-   r9   r:   rT   rT   m   s   ‡ ñð ˜c 3˜h™Ó'ØÖr9   rT   Úfsdp_param_infoÚflat_param_stateÚto_saveÚshard_stateÚcpu_offloadc                 óN  • U(       a  U(       d  [        S5      e[        U U5      nU(       ax  [        U UU5      nU Hc  nU(       d  M  [        UR	                  5       5       H:  nXx   n	[        U	[        R                  5      (       d  M(  U	R                  5       Xx'   M<     Me     U$ / $ )a  
Unflattens the optimizer state, consisting of the "state" part and the
"param_groups" part. Unflattening the "state" part involves consolidating
the state on the target rank and remapping from flattened to unflattened
parameter IDs, and the "param_groups" part only involves remapping from
flattened to unflattened parameter IDs.

Args:
    fsdp_param_info (FSDPParamInfo): The FSDP state, the handle, and a
        mapping from FQN to original parameter index.
    flat_param_state (Dict[str, Any]): Entry for the flat parameter in the
        "state" part of the optimizer state dict.
    to_save (bool): Whether to save the state on this rank.

Returns:
    List[Dict[str, Any]]: A :class:`list` holding the entries in the
    "state" part of the optimizer state dict corresponding to the
    unflattened parameters comprising the flat parameter if on the target
    rank or an empty :class:`list` otherwise. The final optimizer state
    dict will need to map these entries using the proper unflattened
    parameter IDs.
z7If ``shard_state`` is True, ``to_save`` has to be True.)	ÚAssertionErrorÚ_communicate_optim_stateÚ#_unflatten_communicated_optim_stater6   r@   Ú
isinstancerK   rL   Úcpu)
rY   rZ   r[   r\   r]   Úconsolidated_stateÚunflat_param_stateÚoptim_stateÚkeyr)   s
             r:   Ú_unflatten_optim_staterh   x   sŸ   € ö: ž7ÜÐVÓWÐWÜ1ØØóÐö Ü@ØØØó
Ðó
 .ˆKçˆ{Ü × 0Ñ 0Ó 2Ö3�CØ'Ñ,�EÜ% e¬U¯\©\×:Ñ:Ù Ø',§y¡y£{�KÓ$ó	 4ñ .ð "Ð!àˆ	r9   Úxc                 ób   • [         R                  " U 5      =(       a    U R                  5       S:H  $ ©Nr   )rK   Ú	is_tensorÚdim)ri   s    r:   Ú_is_zero_dim_tensorrn   ®   s    € Ü�?Š?˜1Ó×. !§%¡%£'¨Q¡,Ð.r9   c                 ó  • U R                   nU R                  R                  n[        5       nUR                  UR
                  UR                  pvn[        U5       GH¡  u  p‰[        R                  " U	5      (       GaH  U	R                  5       S:”  Ga3  UR                  S:X  d  UR                  [        R                  :X  a  X•U'   Mk  UR                  c  [!        S5      eU	R"                  R$                  UR                  R$                  :w  a  U	R'                  UR                  5      n	UR(                  R+                  5       n
U	R,                  " U
6 n[.        R0                  " X¹UR2                  S9  UR4                  R7                  5         [9        [:        R<                  UR>                  5      RA                  5       nUSU XX'   GMj  [C        U	5      (       a#  U	RE                  5       RG                  5       Xh'   GM�  X—U'   GM¤     U$ )aÞ  
Communicates the optimizer state for a flat parameter across ranks. All
ranks will hold the entire non-sharded optimizer state on GPU.

If ``N`` is the number of tensor optimizer states in the optimizer state
dict, then the communication complexity is 0 if ``N = 0`` and ``N + 1``
otherwise (where the plus 1 comes from all-gathering the padding per rank).

Args:
    fsdp_param_info (FSDPParamInfo): The FSDP state, the handle, and a
        mapping from FQN to original parameter index.
    flat_param_state (Dict[str, Any]): The entry in the "state" part of the
        optimizer state dict corresponding to the flat parameter.

Returns:
    ConsolidatedOptimState: Consolidated optimizer state for the target
    flat parameter.
r   é   Nz'compute_device has not been initialized©Úgroup)$r)   r*   Ú
flat_paramrD   rG   rH   rI   rB   rK   rl   rm   Ú
world_sizeÚsharding_strategyr   ÚNO_SHARDÚcompute_devicer_   ÚdeviceÚtypeÚtoÚ_full_param_paddedÚsizeÚ	new_zerosÚdistÚall_gather_into_tensorÚprocess_groupÚ_device_handleÚsynchronizer   ÚnnÚ	ParameterÚ_unpadded_unsharded_sizeÚnumelrn   ÚdetachÚclone)rY   rZ   Ú
fsdp_staters   r)   rG   rH   rI   Ú
state_nameÚvalueÚbuffer_sizeÚtensor_bufferÚunpadded_numels                r:   r`   r`   ²   s¯  € ð, !×&Ñ&€JØ ×'Ñ'×2Ñ2€JÜ#Ó%€Eà×ÑØ×#Ñ#Ø×Ñð *:€Lô *Ð*:×;Ñˆ
ä�?Š?˜5×!Ò! e§i¡i£k°A¤oð
 ×%Ñ%¨Ó*Ø×/Ñ/Ô3C×3LÑ3LÓLà+0˜ZÑ(ÙØ×(Ñ(Ñ0Ü$Ð%NÓOÐOØ�|‰|× Ñ  J×$=Ñ$=×$BÑ$BÓBØŸ™ ×!:Ñ!:Ó;�ð %×7Ñ7×<Ñ<Ó>ˆKØ!ŸOšO¨[Ð9ˆMÜ×'Ò'Ø¨J×,DÑ,Dòð ×%Ñ%×1Ñ1Ô3Ü!Ü—‘˜j×AÑAóç‰e‹gð ð (5°_°nÐ'EˆLÔ$ô # 5×)Ñ)Ø49·L±L³N×4HÑ4HÓ4JÐ%Ô1à/4 Ô,ñE <ðF €Lr9   r)   c           
      óÖ  • U R                   nU R                  nUR                  n/ n0 nUR                  nUR                  UR
                  UR                  pºn	[        U5       GH�  n0 n[        U	5       GH&  u  pïXç;   nU(       d  UR                  U5      nUX~'   OX~   n[        U5      nU(       aå  UR                  n[        USS5      (       aR  UR                  c  [        SUR                   35      e[        UUR                   UR                  UR"                  5      nOuUR$                  c  [        SUR$                   35      e['        UUR                   UR(                  UR*                  R-                  5       UR$                  UR"                  5      nUXÞ'   GM)     UR/                  [        U
5      5        UR/                  [        U5      5        UR1                  U5        GM„     U$ )aÎ  
Unflattens the communicated optimizer state (given by ``tensor_state``,
``non_tensor_state``, and ``zero_dim_tensor_state``) for a single flat
parameter. This should only be called on the target rank.

Args:
    fsdp_param_info (FSDPParamInfo): The FSDP state, the handle, and a
        mapping from FQN to original parameter index.
    state (_ConsolidatedOptimState): Consolidated optimizer state.

Returns:
    List[Dict[str, Any]]: A :class:`list` holding the entries in the
    "state" part of the optimizer state dict corresponding to the
    unflattened parameters comprising the flat parameter. The final
    optimizer state dict will need to map these entries using the proper
    unflattened parameter IDs.
Ú_use_dtensorFú*Expected _device_mesh to be not None, got ú+Expected process_group to be not None, got )r)   r*   rs   Ú_num_paramsrG   rH   rI   ÚrangerB   Ú_get_unflat_viewsÚnextÚ_optim_state_dict_configÚgetattrÚ_device_meshr_   r   ÚrankÚ_fsdp_extensionr€   r   rt   r�   Údevice_countÚupdateÚappend)rY   r)   r\   r‰   r*   rs   re   Úflat_param_viewsÚnum_unflat_paramsrG   rH   rI   Ú_Úunflat_state_paramrŠ   Úflat_tensorÚviews_generatedÚviewsrf   Ú
osd_configs                       r:   ra   ra   ÷   sí  € ð, !×&Ñ&€JØ×#Ñ#€FØ×"Ñ"€JØ/1ÐØ,.ÐØ"×.Ñ.Ðà×ÑØ×#Ñ#Ø×Ñð *:€Lô Ð$×%ˆØÐä'3°L×'AÑ#ˆJØ(Ñ<ˆOÞ"Ø×0Ñ0°Ó=�Ø/4Ð Ò,à(Ñ4�ÜBFÀuÃ+ˆKÞØ'×@Ñ@�
Ü˜: ~°u×=Ñ=Ø!×.Ñ.Ñ6Ü,ØHÈ×I`ÑI`ÐHaÐbóð ô #5Ø#Ø"Ÿ™Ø"×/Ñ/Ø"×2Ñ2ó	#‘Kð "×/Ñ/Ñ7Ü,ØIÈ*×JbÑJbÐIcÐdóð ô #4Ø#Ø"Ÿ™Ø"×-Ñ-Ø"×1Ñ1×>Ñ>Ó@Ø"×0Ñ0Ø"×2Ñ2ó#�Kð .9ÐÔ*ñE (BðJ 	×!Ñ!¤,Ð/DÓ"EÔFà×!Ñ!¤,Ð/?Ó"@ÔAØ×!Ñ!Ð"4×5ñW &ðX Ðr9   r‰   rf   rr   c                 óè   • S /n[         R                  " U5      S:X  a  [        [        R                  S U5      US'   [         R
                  " USUS9  [         R                  " U5      S:X  a  U$ US   $ )Nr   c                 óŠ   • U R                  5       S:X  a  U R                  5       $ [        U R                  U R                  5      $ rk   )rm   rc   rN   rP   rQ   )Úvs    r:   Ú<lambda>Ú,_broadcast_processed_state.<locals>.<lambda>Q  s.   €  §¡£¨A£�a—e‘e“gÐVÔ3DÀQÇWÁWÈaÏgÉgÓ3VÐVr9   ©Úsrcrr   )r~   Úget_rankr$   rK   rL   Úbroadcast_object_list)r‰   rf   rr   Úobjectss       r:   Ú_broadcast_processed_stater±   H  sl   € ð
 ˜€GÜ‡}‚}�UÓ˜qÓ Ü"Ü�L‰LÙVØó
ˆ�‰
ô
 	×Ò˜w¨A°UÒ;Ü‡}‚}�UÓ˜qÓ ØÐà�q‰zÐr9   c                 ó:  • [         R                  " U5      S:X  aQ  [        U[        R                  5      (       a  UR                  5       S:X  a  U$ UR                  U R                  5      nO™[        U[        R                  5      (       a/  UR                  5       S:w  a  [        SUR                   S35      eU$ [        U[        5      (       d  U$ [        R                  " UR                  UR                  U R                  S9n[         R                  " USUS9  U$ )Nr   z\For non-zero ranks, a tensor state should have zero dimension, but got the state with shape Ú.©rQ   rx   r¬   )r~   r®   rb   rK   rL   rm   rz   rw   r_   rP   rN   ÚzerosrQ   Ú	broadcast)r‰   r)   rr   Útensors       r:   Ú_broadcast_stater¸   [  sâ   € ô ‡}‚}�UÓ˜qÓ Ü˜%¤§¡×.Ñ.°%·)±)³+ÀÓ2BØˆLØ—‘˜*×3Ñ3Ó4‰ä�eœUŸ\™\×*Ñ*Ø�y‰y‹{˜aÓÜ$ð4Ø49·K±K°=ÀðCóð ð ˆLÜ˜EÔ#4×5Ñ5ØˆLÜ—’Ø�K‰K˜uŸ{™{°:×3LÑ3Lñ
ˆô 	‡N‚N�6˜q¨Ò.Ø€Mr9   Úfqnc                 óH  • U(       d  0 $ U R                   nU R                  R                  nU R                  U   nUR                  U   n[        X#R                  UR                  S9nUR                  (       d  0 $ 0 nUR                  nUR                  n	UR                  5        Hy  u  p«[        R                  " U5      (       aU  UR                  5       S:”  aA  UR                  [         R"                  :w  a#  UR%                  5       X‰S-    R'                  5       nX·U
'   M{     U$ )zŒ
Shard the optimizer state for the original parameter with the name ``fqn``.
This API should only be used when ``use_orig_params`` is True.
©Úpgrx   r   rp   )r)   r*   rs   r+   Ú_shard_param_infosr   r€   rw   Úin_shardÚintra_param_start_idxÚintra_param_end_idxÚitemsrK   rl   rm   ru   r   rv   Úflattenrˆ   )rY   r¹   rf   r‰   rs   Ú	param_idxÚshard_param_infoÚnew_optim_stater¿   rÀ   rŠ   r‹   s               r:   Ú_shard_orig_param_staterÆ   s  s  € ö Øˆ	Ø ×&Ñ&€JØ ×'Ñ'×2Ñ2€JØ×-Ñ-¨cÑ2€IØ!×4Ñ4°YÑ?ÐÜ$Ø×0Ñ0¸×9RÑ9Rñ€Kð ×$×$Øˆ	à&(€OØ,×BÑBÐØ*×>Ñ>ÐØ(×.Ñ.Ö0Ñˆ
ä�OŠO˜E×"Ñ"Ø—	‘	“˜a“Ø×,Ñ,Ô0@×0IÑ0IÓIà—M‘M“OØ%Øñ)ð÷ ‰e‹gð ð ',˜
Ó#ñ 1ð Ðr9   Úoptim_state_dictÚmodelÚuse_orig_paramsÚoptimÚ
rank0_onlyc           	      óZ  • [         R                  " 5         U nSU;  a  U(       d  [        S5      e[        U5      n[	        U5      n[        [        UR                  5       5      5      R                  n	U(       a
  [        X–US9n0 n
US   n[        UR                  5       5      nUR                  5        GHF  u  pÞUS   nXû;  a  M  UR                  U5        U(       a9  U H.  nX¿   (       d  M  X¿    H  n[        X›U   U   US9X¿   U'   M     M0     US   nXø;   Ga  X�   nU(       aG  [         R                  " [         R                   R"                  5         [%        UUX¿   5      nSSS5        O['        UUU5      n[)        [+        U5      S5      nW(       a  UU
U'   OíU(       a�  [-        U5      S:w  a  [/        SU S	35      eUb_  UR                  R1                  US5      nUb  [2        R4                  " U5      U
U'   OŒ[6        R8                  " S
U SU	R:                   S	3SS9  Oe[=        SU S35      e[-        U5      S:w  a  [/        S[-        U5       35      e[)        [+        U5      S5      n[2        R2                  " X¿   5      U
U'   U(       d  GMá  U H_  nX¿   (       d  M  [?        X¿   R                  5       5       H2  u  nnU	R:                  S:”  a  X¿   U	 M  URA                  5       X¿   U'   M4     Ma     GMI     U HY  nUU   n[C        U[D        RF                  5      (       a  U(       a  U(       a  [        U	UUS9n[2        R2                  " U5      U
U'   M[     [         RH                  " S5        SU;   a  [2        R4                  " US   5      nU
US.$ SU
0$ ! , (       d  f       GN/= f)a{  
Flattens the full optimizer state dict, still keying by unflattened parameter
names.

If ``use_orig_params`` is True, each rank will have all FSDP-managed
parameters but some of these parameters may be empty due to the sharding.
For a regular optim.Optimizer, states for those empty parameters will
not be initialized. So, when aggregating the FQNs across ranks, no assert
will be raised on a rank even if it does not have all the states -- it is
valid and FSDP know how to aggregate them. However, FSDP has to ignore
handling those parameters that are not managed by FSDP and do not exist on
the local rank -- it is managed by other parallelism and FSDP does not
know ho to handle/aggregate them.

Note that ``_flatten_tensor_optim_state`` does not need ``optim`` to
flatten/shard the state. However, NamedOptimizer and KeyedOptimizer require
all the states even if the corresponding parameters are empty. To this end,
``optim`` will be used to get the initial state of the empty parameters.
``optim`` should only be non-None if the ``optim` is KeyedOptimizer or
NamedOptimizer.

Returns:
    Dict[str, Any]: The flattened optimizer state dict.
r)   zO`optim_state_dict` must have the keys "state"to be a valid optimizer state dictrq   r   NTrp   z5use_orig_params is True but there are multiple FQNs, r³   zoptim_state[z] is not on ranké   ©Ú
stacklevelzThe state of z8 is empty. This should happen when use_orig_params=True.zExpected len(fqns) == 1, got Fz,FSDP _flatten_optim_state_dict() profiling: Úparam_groups©r)   rÐ   )%r   ÚresetÚ
ValueErrorr   Ú_get_fqn_to_fsdp_param_infor–   ÚiterÚvaluesr)   r±   Úsetr@   rÁ   Údifference_updater¸   ÚprofileÚTypeÚ
RESHARDINGrÆ   Ú_flatten_optim_staterT   rX   Úlenr_   ÚgetÚcopyÚdeepcopyÚwarningsÚwarnrš   ÚRuntimeErrorr6   rc   rb   rK   rL   Údump_and_reset)rÇ   rÈ   rÉ   rÊ   rË   rr   Ú
unflat_osdÚparam_to_fqnsÚfqn_to_fsdp_param_infor‰   Úflat_osd_stateÚunflat_osd_stateÚall_state_keysÚparamÚfqnsr¹   rŠ   rY   Ú
flat_staterg   r)   Úparam_stateÚ
user_stateÚflat_osd_param_groupss                           r:   Ú_flatten_optim_state_dictrñ   ™  sž  € ô@ ×ÒÔà!€JØ�jÓ ®Üð1ó
ð 	
ô ' uÓ-€MÜ8¸Ó?ÐÜ”dÐ1×8Ñ8Ó:Ó;Ó<×BÑB€Jö Ü/°
ÈeÑTˆ
ð 79€NØ! 'Ñ*ÐÜÐ)×.Ñ.Ó0Ó1€Nà$×*Ñ*×,‰ˆØ�1‰gˆØÓ&ÙØ×(Ñ(¨Ô.æÛ�Ø'×,ÙØ"2Ô"7�JÜ8HØ"°SÑ$9¸*Ñ$EÈUñ9Ð$Ñ)¨*Ó5ó #8ñ ð �q‘'ˆCØÔ(Ø4Ñ9ˆOÞÜ#×+Ò+¬N×,?Ñ,?×,JÑ,JÕKÜ!8Ø'ØØ(Ñ-ó"�J÷ LÐKô 2Ø#Ø$Øó�
ô
 !¤ t£¨dÓ3ˆCö Ø&0�˜sÒ#Þ Ü�t“9 “>Ü(ØOÐPTÈvÐUVÐWóð ð Ñ$Ø!ŸK™KŸO™O¨E°4Ó8�EØÑ(Ü.2¯mªm¸EÓ.B˜ sÒ+ä ŸšØ*¨3¨%Ð/?À
ÇÁÐ?PÐPQÐRØ'(òøô #Ø# C 5ð ),ð ,óð ô
 �4‹y˜A‹~Ü$Ð'DÄSÈÃYÀKÐ%PÓQÐQÜ ¤ t£¨eÓ4ˆCÜ"&§)¢)Ð,<Ñ,AÓ"BˆN˜3Ñç‰:Û�Ø'×,ÙÜ/3Ð4DÑ4I×4OÑ4OÓ4QÖ/RÑ+�J Ø!—‘¨Ó*à,Ñ1°*Ò=ð =H¿O¹OÓ<MÐ(Ñ-¨jÓ9ó 0Sô ñ -óX ˆØ% cÑ*ˆ
Ü�j¤%§,¡,×/Ñ/¶JÆ?Ü)¨*°jÈÑNˆJÜ"Ÿiši¨
Ó3ˆ�sÓñ	 ô ×!Ò!Ð"PÔQð ˜Ó#Ü $§¢¨j¸Ñ.HÓ IÐØ'Ð9NÑOÐOà˜Ð(Ð(÷Q LÖKús   ÅNÎ
N*	ré   rV   c           	      ó>  • U R                   nU R                  nUR                  n[        U5      nUS::  a  [	        S5      eUR
                  n[        U5      nXh:w  a  [	        SU SU 35      eU V	s/ s H  n	[        X‘;   5      PM     n
n	[        U
5      (       d  0 $ U V	s/ s H+  n	X‘;   a!  [        X   UR                  UR                  S9OSPM-     nn	SnU HQ  nUc  M  Uc  [        UR                  5       5      nM&  U[        UR                  5       5      :w  d  ME  [        SU 35      e   Uc  [	        SU 35      e0 nU GH¼  nU Vs/ s H  nUb  Xß   OSPM     nnU Vs/ s H
  nUc  M  UPM     nnU(       d  SXï'   MA  S	=n=nnU Hb  nU[        R                  " U5      =(       a    UR!                  5       S:„  -  nU[#        U5      -  nU[        R                  " U5      (       + -  nMd     U Vs1 s H  n[%        U5      iM     nn[        U5      S
:w  d  U(       d"  U(       d  U(       d  [        SU SU SU 35      eU(       av  ['        UUUUU5      nUR(                  S
:w  aN  UR*                  [,        R.                  :w  a0  [0        R2                  " UUR4                  UR(                  5      u  nnOUnUXï'   GM  U(       a  [7        UUU5      Xï'   GM˜  U(       d  [	        SU 35      e[9        UUU5      Xï'   GM¿     U$ s  sn	f s  sn	f s  snf s  snf s  snf )a3  
Flattens the optimizer state in ``full_optim_state_dict`` for a single
flat parameter in ``fsdp_param_info`` corresponding to the unflattened
parameter names in ``unflat_param_names``.

Args:
    fsdp_param_info (FSDPParamInfo): The FSDP state, the handle, and a
        mapping from FQN to original parameter index.
    unflat_osd_state (Dict[str, Dict[str, Any]]): The "state" part of the
        optimizer state dict corresponding to the unflattened parameters.
    unflat_param_names (List[str]): A :class:`list` of unflattened
        parameter names corresponding to the flat parameter ``flat_param``.

Returns:
    Dict[str, Any]: A :class:`dict` mapping state names to their values for
    a particular flat parameter. The sharded optimizer state dict's "state"
    part will map a key to this returned value.
r   zNExpects at least one unflattened parameter corresponding to the flat parameterzExpects z shapes but got r»   Nz@Differing optimizer state names for the unflattened parameters: z)Expected state_names to be not None, got Trp   z*Differing optimizer state types for state z	, values z", and unflattened parameter names z)Expected are_non_tensors to be True, got )r)   r*   rs   rÝ   r_   Ú_shapesr7   Úanyr   r€   rw   r×   r@   rÓ   rK   rl   rm   rn   ry   Ú_flatten_tensor_optim_statert   ru   r   rv   r   Ú
_get_shardrš   Ú$_flatten_zero_dim_tensor_optim_stateÚ_flatten_non_tensor_optim_state)rY   ré   rV   r‰   r*   rs   r    Úunflat_param_shapesÚnum_unflat_param_shapesÚunflat_param_nameÚ	has_stateÚunflat_param_statesÚstate_namesre   rí   rŠ   Ústate_valuesr©   Únon_none_state_valuesÚare_pos_dim_tensorsÚare_zero_dim_tensorsÚare_non_tensorsÚtypesr£   Úsharded_flat_tensorr¡   s                             r:   rÜ   rÜ   +  sÀ  € ð. !×&Ñ&€JØ×#Ñ#€FØ×"Ñ"€JÜÐ.Ó/ÐØ˜AÓÜØ\ó
ð 	
ð %×,Ñ,ÐÜ!Ð"5Ó6ÐØÓ3ÜØÐ(Ð)Ð)9Ð:QÐ9RÐSó
ð 	
ñ "4óâ!3Ðô 	ÐÑ2Ö3Ù!3ð ð ô ˆy�>‰>Øˆ	ñ "4ó	ò "4Ðð Ó0ô 	ØÑ/Ø×'Ñ'Ø×,Ñ,ò	
ð ò	ñ "4ð ð 	ð €Kã1ÐØÑ%ÙØÑÜÐ0×5Ñ5Ó7Ó8ŠKàœcÐ"4×"9Ñ"9Ó";Ó<Õ<Ü ð#Ø#5Ð"6ð8óð ñ 2ð ÑÜÐHÈÈÐVÓWÐWð 24€JÜ!ˆ
ñ ':ó
â&9Ð"ð /AÑ.LÐÒ*ÐRVÒVÙ&9ð 	ð 
ñ -9Ó JªL q¸A§©LÐÐ Jæ$Ø%)ˆJÑ"ÙØGKÐKÐÐKÐ2°_Û&ˆAØ¤5§?¢?°1Ó#5×#E¸!¿%¹%»'ÀA¹+ÑEÐØ Ô$7¸Ó$:Ñ:Ð Ø¤5§?¢?°1Ó#5Ô5Ñ5ŠOñ 'ñ #8Ó8Ò"7˜Q”�a–Ñ"7ˆÐ8Üˆu‹:˜‹?ÞÖ#7¾?äØ<¸Z¸Lð IØ/Ð0ð 1Ø+Ð,ð.óð ö
 Ü5ØØØ"Ø#ØóˆKð ×%Ñ%¨Ó*Ø×0Ñ0Ô4D×4MÑ4MÓMä)8×)CÒ)CØØ—O‘OØ×)Ñ)ó*Ñ&Ð#¡Qð '2Ð#Ø%8ˆJÔ"Þ!Ü%IØØØ"ó&ˆJÔ"ö #Ü$Ø?ÀÐ?PÐQóð ô &EØØØ"ó&ˆJÔ"ñs "ð~ ÐùòMùò	ùò<
ùò !Kùò 9s$   Á2LÂ!2LÅLÅ$LÅ/LÇ6LrŠ   Úpos_dim_tensorsrù   r*   c                 ó~  • UR                   nU Vs/ s H	  ofc  M  UPM     nnU Vs1 s H  ofR                  iM     nn[        U5      S:w  a  [        SU SU  SU 35      e[	        [        U5      5      n	[        X5       HR  u  p«U
c  [        U5      S:X  a  [        S5      eU
c  M'  U
R                  U:w  d  M9  [        SU
R                   SU 35      e   [        R                  " S	5      n[        X5       VVs/ s HW  u  pÛUb%  [        R                  " UR                  U5      5      O)[        R                  " [        R                  " UU	US
95      PMY     nnnUR                  XäR                  5      nUR                  nUR                  U:w  a  [!        SUR                   SU 35      eU$ s  snf s  snf s  snnf )aÕ  
Flattens the positive-dimension tensor optimizer state given by the values
``tensors`` for the state ``state_name`` for a single flat parameter
from ``handle`` corresponding to the unflattened parameter names
``unflat_param_names`` and unflatted parameter shapes
``unflat_param_shapes``. This flattens each unflattened parameter's tensor
state into one tensor.

NOTE: We use zero tensors for any unflattened parameters without state
since some value is required to fill those entries. This assumes that the
zero tensor is mathematically equivalent to having no state, which is true
for Adam's "exp_avg" and "exp_avg_sq" but may not be true for all
optimizers.

Args:
    state_name (str): Optimizer state name.
    pos_dim_tensors (List[torch.Tensor]): Positive-dimension tensor
        optimizer state values for the unflattened parameters corresponding
        to the single flat parameter.
    unflat_param_names (List[str]): A :class:`list` of unflattened
        parameter names corresponding to the single flat parameter.
    unflat_param_shapes (List[torch.Size]): Unflattened parameter shapes
        corresponding to the single flat parameter.
    handle (FlatParamHandle): The flat parameter's handle.

Returns:
    torch.Tensor: A flat tensor containing the optimizer state
    corresponding to ``state_name`` constructed by concatenating the
    unflattened parameter tensor states in ``pos_dim_tensors`` (using zero
    tensors for any unflattened parameters without the state).
rp   z‹All unflattened parameters comprising a single flat parameter must have positive-dimension tensor state with the same dtype but got dtypes ú for state ú! and unflattened parameter names r   z6Flattening a zero-dimension parameter is not supportedzBTensor optimizer state does not have same shape as its parameter: Ú rc   )r|   rQ   rx   ztensor optim state: z flat parameter: )rs   rQ   rÝ   rÓ   r–   rÕ   ÚziprP   rK   rx   rÂ   rz   rµ   Úflatten_tensorsÚ_aligned_numelr…   r_   )rŠ   r  rV   rù   r*   rs   ÚtÚnon_none_tensorsÚdtypesrQ   r·   rP   Ú
cpu_deviceÚstate_valueÚtensors_to_flattenr£   Úflat_param_shapes                    r:   rõ   rõ   »  sÞ  € ðL ×"Ñ"€JÙ#2ÓD¢?˜aŸ¡?ÐÐDá/Ó0Ò/˜!�gŒgÑ/€FÐ0Ü
ˆ6ƒ{�aÓÜð)à)/¨°¸J¸<ð H+Ø+=Ð*>ð@ó
ð 	
ô ”�f“Ó€Eä˜_ÖB‰ˆØ‰>œc %›j¨A›oÜÐUÓVÐVØÓ F§L¡L°EÕ$9ÜðØ$Ÿl™l˜^¨1¨U¨Gð5óð ñ	 Cô —’˜eÓ$€Jô #& oÔ"Kôò #LÑˆKð Ñ"ô 	�Š�k—n‘n ZÓ0Ô1ä�]Š]Ü�KŠKØØØ!ñó
ò	
ñ #Lð ñ ð ×(Ñ(Ð);×=RÑ=RÓS€KØ!×:Ñ:ÐØ×ÑÐ,Ó,ÜØ" ;×#4Ñ#4Ð"5Ð5FÐGWÐFXÐYó
ð 	
ð ÐùòW Eùâ0ùó.s   ‘F/›F/§F4Ã:AF9Úzero_dim_tensorsc           
      ó  • U Vs/ s H	  o3c  M  UPM     nnU Vs1 s H  o3b  UR                  5       OSiM     nnU Vs1 s H  o3b  UR                  OSiM     nn[        U5      [        U5      :w  d  [        U5      S:w  d  [        U5      S:w  a  [        SU SU SU  SU 35      e[	        [        U5      5      n[	        [        U5      5      n[        R                  " Xx[        R                  " S5      S9$ s  snf s  snf s  snf )	a,  
Flattens the zero-dimension tensor optimizer state given by the values
``zero_dim_tensors`` for the state ``state_name`` for a single flat
parameter corresponding to the unflattened parameter names
``unflat_param_names`` by enforcing that all tensors are the same and using
that common value.

NOTE: The requirement that the tensors are the same across all unflattened
parameters comprising the flat parameter is needed to maintain the
invariant that FSDP performs the same computation as its non-sharded
equivalent. This means that none of the unflattened parameters can be
missing this state since imposing a value may differ from having no value.
For example, for Adam's "step", no value means maximum bias correction,
while having some positive value means less bias correction.

Args:
    state_name (str): Optimizer state name.
    zero_dim_tensors (List[torch.Tensor]): Zero-dimension optimizer state
        for the unflattened parameters corresponding to the single
        flat parameter.
    unflat_param_names (List[str]): A :class:`list` of unflattened
        parameter names corresponding to the single flat parameter.

Returns:
    torch.Tensor: A zero-dimensional tensor giving the value of the state
    ``state_name`` for all unflattened parameters corresponding to the
    names ``unflat_param_names``.
Nrp   ú‚All unflattened parameters comprising a single flat parameter must have scalar state with the same value and dtype but got values z and dtypes r  r	  rc   r´   )	ÚitemrQ   rÝ   rÓ   r–   rÕ   rK   r·   rx   )	rŠ   r  rV   r  r  Ú
values_setr  r‹   rQ   s	            r:   r÷   r÷     s  € ñB $4ÓEÒ#3˜aŸÑ#3ÐÐEá?OÓPÒ?O¸!™m�!—&‘&”(°Ò5Ñ?O€JÐPÙ:JÓKÒ:J°Q™ˆa�gŠg¨DÒ0Ñ:J€FÐKäÐÓ¤Ð%5Ó!6Ó6Üˆz‹?˜aÓÜˆv‹;˜!Óäðà(˜\¨°f°X¸[ØˆlÐ;Ø!Ð"ð	$ó
ð 	
ô ”�jÓ!Ó"€EÜ”�f“Ó€EÜ�<Š<˜´5·<²<ÀÓ3FÑGÐGùò% FùâPùÚKs   …C9�C9›C>¿DÚnon_tensorsc                 óð   • U Vs/ s H	  o3c  M  UPM     nn[        U5      n[        U5      [        U5      :w  d  [        U5      S:w  a  [        SU SU  SU 35      e[        [	        U5      5      nU$ s  snf )a@  
Flattens the non-tensor optimizer state given by the values ``non_tensors``
for the state ``state_name`` for a single flat parameter corresponding
to the unflattened parameter names ``unflat_param_names`` by enforcing that
all values are the same and using that common value.

See the note in :func:`_flatten_zero_dim_tensor_optim_state`.

Args:
    state_name (str): Optimizer state name.
    non_tensors (List[Any]): Non-tensor optimizer state for the unflattened
        parameters corresponding to the single flat parameter.
    unflat_param_names (List[str]): A :class:`list` of unflattened
        parameter names corresponding to the single flat parameter.

Returns:
    Any: A non-tensor giving the value of the state ``state_name`` for all
    unflattened parameters corresponding to the names
    ``unflat_param_names``.
rp   r  r  z" and  unflattened parameter names )r×   rÝ   rÓ   r–   rÕ   )rŠ   r  rV   ÚntÚnon_none_non_tensorsÚnon_tensor_setÚ
non_tensors          r:   rø   rø   F  s�   € ñ2 *5ÓGª 2ŸB©ÐÐGä˜Ó%€NÜ
ÐÓ ¤C¨Ó$4Ó4¼¸NÓ8KÈqÓ8PÜðà,Ð-¨[¸¸ð E+Ø+=Ð*>ð@ó
ð 	
ô ”d˜>Ó*Ó+€JØÐùò Hs
   …A3�A3Úsharded_osdÚoptim_inputÚusing_optim_inputÚis_named_optimizerc           
      ól  • [        U5      n[        U5      n[        [        [        R
                  [        [        -  4   U(       a  [        X5      O[        X!XVU5      5      n[        U5      [        U5      :”  a#  [        S[        U5       S[        U5       35      e0 n	0 n
UR                  5        H*  u  p¼X¸;  a  M  X‹   nXÙ[        U5      '   U H  nXÚU'   M	     M,     U S   n0 nUR                  5        HM  u  nn[        U[        5      (       a  UUU'   M"  U	R                  UR                   UR                   5      nUUU'   MO     SU ;   a`  / nU S    HP  n["        R$                  " U5      n['        US    Vs1 s H  nX®   iM	     sn5      nUUS'   UR)                  U5        MR     UUS.$ SU0$ s  snf )a  
Rekeys the optimizer state dict from unflattened parameter names to flat
parameter IDs according to the calling rank's ``optim``, which may be
different across ranks. In particular, the unflattened parameter names are
represented as :class:`_OptimStateKey` s.
z<Expected len(param_to_param_key) <= len(param_to_fqns), got z > r)   rÐ   ÚparamsrÑ   )r   Ú_get_flat_param_to_fqnr   r3   rƒ   r„   r5   r4   Ú'_get_param_to_param_id_from_optim_inputÚ_get_param_to_param_keyrÝ   r_   rÁ   rX   rb   rÞ   rV   rß   rà   r?   rž   )r   rÈ   rÊ   r!  r"  r#  ræ   Úflat_param_to_fqnÚparam_to_param_keyÚ$unflat_param_names_to_flat_param_keyÚ#unflat_param_name_to_flat_param_keyrë   rV   Úflat_param_keyrû   Úsharded_osd_stateÚrekeyed_osd_staterg   rî   Úrekeyed_osd_param_groupsÚunflat_param_groupÚflat_param_groupÚflat_param_keyss                          r:   Ú_rekey_sharded_optim_state_dictr4  m  s  € ô ' uÓ-€MÜ.¨uÓ5ÐÜ8<ÜŒR�\‰\œ3¤™9Ð$Ñ%ö !ô 4°EÔGä(ØÐ0ÐARóó	9Ðô ÐÓ¤ ]Ó!3Ó3ÜØJÌ3ÐOaÓKbÐJcÐcfÔgjÐkxÓgyÐfzÐ{ó
ð 	
ð 	ð )ð ACÐ'Ø%2×%8Ñ%8Ö%:Ñ!ˆØÓ*áØ+Ñ2ˆØJX¬UÐ3EÓ-FÑGÛ!3ÐØESÐ0AÓBó "4ñ &;ð $ GÑ,ÐØ.0ÐØ-×3Ñ3Ö5Ñˆˆ[Ü�cœ3×ÑØ%0Ð˜cÑ"ÙØ=×AÑAØ×"Ñ" C×$:Ñ$:ó
ˆð -8Ð˜.Ó)ñ 6ð ˜Ó$Ø9;Ð Ø"-¨nÔ"=ÐÜ#Ÿ}š}Ð-?Ó@ÐÜ$ð .@ÀÒ-Ióâ-IÐ)ð 8ÔJÙ-IñóˆOð *9Ð˜XÑ&Ø$×+Ñ+Ð,<Ö=ñ #>ð +Ð<TÑUÐUàÐ*Ð+Ð+ùòs   Å9F1
c                 ó¸  • Uc"  [        [        U R                  5       5      5      $  [        [        [
        R                     [	        U5      5      n[        U5      S:X  a  [        S5      eSnSnU H3  nU[        U[        R                  5      -  nU[        U[         5      -  nM5     U(       d  U(       d  [        S5      eU(       a  [        [        U5      5      $ U(       d  [        SU 35      e/ nU H.  nSU;   n	U	(       d  [        S	5      eUR                  US   5        M0     [        [        U5      5      $ ! [         a  n[        SU 35      UeSnAff = f)
a  
Constructs a mapping from parameter IDs to parameters. This may be used
both for models with ``FlatParameter`` s and without.

NOTE: This method is only preserved for backward compatibility. The method
:meth:`_get_param_key_to_param` is the preferred code path that does not
rely on ``optim_input``.

NOTE: We critically assume that, whether the optimizer input is a list of
parameters or a list of parameter groups, :class:`torch.optim.Optimizer`
enumerates the parameter IDs in order. In other words, for a parameter list
input, the parameter IDs should be in that list order, and for a parameter
groups input, the parameter IDs should be in order within each parameter
group and in order across parameter groups.

Args:
    model (nn.Module): Model whose parameters are passed into the
        optimizer.
    optim_input (Optional[Union[List[Dict[str, Any]],
    Iterable[nn.Parameter]]]): Input passed into the optimizer
        representing either a :class:`list` of parameter groups or an
        iterable of parameters; if ``None``, then this method assumes the
        input was ``model.parameters()``. (Default: ``None``)

Returns:
    List[nn.Parameter]: Mapping from parameter IDs to parameters,
    where the parameter ID is implicitly the index in the :class:`list`.
NzCOptimizer input should be an iterable of Tensors or dicts, but got r   z#Optimizer input should not be emptyTz9Optimizer input should be an iterable of Tensors or dictsz#Expected all_dicts to be True, got r%  zNA parameter group should map "params" to a list of the parameters in the group)r3   Ú	enumerateÚ
parametersr   r6   rƒ   r„   Ú	TypeErrorrÝ   rÓ   rb   rK   rL   r_   Úextend)
rÈ   r!  r%  ÚeÚall_tensorsÚ	all_dictsrë   Úparam_id_to_paramÚparam_groupÚhas_params_keys
             r:   Ú'_get_param_id_to_param_from_optim_inputr@  º  s_  € ðD ÑÜ”I˜e×.Ñ.Ó0Ó1Ó2Ð2ðô ”dœ2Ÿ<™<Ñ(¬$¨{Ó*;Ó<ˆô ˆ6ƒ{�aÓÜÐ>Ó?Ð?ð €KØ€IÛˆØ”z %¬¯©Ó6Ñ6ˆØ”Z ¤tÓ,Ñ,Š	ñ ö žyÜÐSÓTÐTÞÜ”I˜fÓ%Ó&Ð&ÞÜÐBÀ9À+ÐNÓOÐOØ,.ÐÛˆØ! [Ñ0ˆÞÜ Ø`óð ð
 	× Ñ  ¨XÑ!6Ö7ñ ô ”	Ð+Ó,Ó-Ð-øô= ó ÜðØ"�mð%ó
ð ð	ûðús   §*D; Ä;
EÅEÅEc                 óx   • S nS n0 n[        U UU[        U 5       VVs/ s H  u  pEUPM	     snnU5      $ s  snnf )aÙ  
Constructs a mapping from ``FlatParameter`` to a cleaned (devoid of prefixes
from wrappers) fully qualified name (FQN). Note that this FQN is "non-canonical"
because ``FlatParameter``  s do not come from the original module but are
registered only after FSDP has been applied. This function returns the FSDP-given
name for the ``FlatParameter`` (usually module._flat_param) as opposed to the
canonical FQNs returned for ``FlatParameter`` s in ``_common_utils._get_param_to_fqns(...)``).

Consequently, this function will only return a non-empty mapping if FSDP was
applied with ``use_orig_params=False`` as, otherwise, the original parameters
are used within the module and there would be no ``FlatParameter`` s in the module.

c                 óz   • [        U SS9 H-  u  pE[        U[        5      (       d  M  [        X-   5      nXcU'   M/     g )NF)Úrecurse)r   rb   r   r   )ÚmoduleÚprefixÚ
tree_levelr)  Ú
param_namerë   r¹   s          r:   Ú	module_fnÚ)_get_flat_param_to_fqn.<locals>.module_fn  s@   € Ü!BØ˜Eô"
ÑˆJô ˜e¤]×3Ñ3ÙÜ# FÑ$7Ó8ˆCØ'*˜eÓ$ò"
r9   c                 ó   • U $ r>   r-   )r)  s    r:   Ú	return_fnÚ)_get_flat_param_to_fqn.<locals>.return_fn  ó   € Ø Ð r9   ©r   r   )rÈ   rH  rK  Úflat_param_to_fqn_retr¹   r¡   s         r:   r&  r&    sN   € ò+ò!ð 79ÐÜØØØÜ<¸UÔCÔDÒC‘�‹ÑCÒDØóð ùó 	Eó   Ÿ6ræ   r)  c                 ód  • 0 nU(       aC  Ub  Uc  [        S5      eUc  [        SU 35      e[        U5       H  u  pgXe[        U5      '   M     0 nSn	U R                   H“  n
U(       at  U
S    Hi  nUc  [        SU 35      eX´;   a  XK   nOBUc  [        SU 35      e[	        X;   5      S:w  a  [        S	[	        X;   5       35      eX;   S   n XV   nX¸U'   Mk     M~  U
S    H  nX¸U	'   U	S-  n	M     M•     U$ ! [
         a/  n[        S
U S[        UR                  5       5       S35      UeSnAff = f)zã
Constructs a mapping from parameter keys to parameters. For the regular
optimizers, the keys are parameter IDs. For NamedOptimizer, the keys
are FQNs. This API may be used both for models with ``FlatParameter`` s and
without.
NzDThe optimizer is a NamedOptimizer, `param_to_fqns` must not be None.z#Expected model to be not None, got r   r%  z/Expected flat_param_to_fqn to be not None, got z+Expected param_to_fqns to be not None, got rp   z-Expected len(param_to_fqns[param]) == 1, got zCan't find z from r³   )r_   r   r   rÐ   rÝ   ÚKeyErrorr6   r@   )rÊ   rÈ   r#  ræ   r)  Úclean_fqn_to_curr_fqnrg   r¡   Úparam_key_to_paramÚpidr>  rë   r:  s                r:   Ú_get_param_key_to_paramrV  (  s¦  € ð -/ÐÞØÑ Ð$5Ñ$=Ü ØVóð ð ‰=Ü Ð#FÀuÀgÐ!NÓOÐOÜ7¸Ö>‰FˆCØ<?Ô"3°CÓ"8Ó9ñ ?ð 9;ÐØ
€CØ×)Ô)ˆÞØ$ XÔ.�Ø$Ñ,Ü(ØIÐJ[ÐI\Ð]óð ð Ó-à+Ñ2‘Cà$Ñ,Ü,ØIÈ-ÈÐYóð ô ˜=Ñ/Ó0°AÓ5Ü,ØKÌCÐP]ÑPdÓLeÐKfÐgóð ð (Ñ.¨qÑ1�CðØ/Ñ4�Cð
 +0 3Ó'ó3 /ð6 % XÔ.�Ø*/ 3Ñ'Ø�q‘’ó /ñ; *ðB Ðøô  ó Ü"Ø% c U¨&´Ð6K×6PÑ6PÓ6RÓ1SÐ0TÐTUÐVóàðûðús   ÃC6Ã6
D/Ä *D*Ä*D/c                 ór   • [        XX#U5      nUR                  5        VVs0 s H  u  pgXv_M	     snn$ s  snnf )zË
Constructs the inverse mapping of :func:`_get_param_key_to_param`. This API
only supports the case where `optim` is a regular optimizer, not NamedOptimizer.
So the parameter keys will be parameter ids.
)rV  rÁ   )rÊ   rÈ   r#  ræ   r)  r=  Úparam_idrë   s           r:   r(  r(  f  sB   € ô 0ØÐ(Ð9JóÐð 4E×3JÑ3JÔ3LÔMÒ3L¡ ˆEŠOÑ3LÒMÐMùÓMs   ¡3c                 ón   • [        X5      nUR                  5        VVs0 s H  u  p4XC_M	     snn$ s  snnf )zRConstructs the inverse mapping of :func:`_get_param_id_to_param_from_optim_input`.)r@  rÁ   )rÈ   r!  r=  rX  rë   s        r:   r'  r'  x  s7   € ô
 @ÀÓSÐØ3D×3JÑ3JÔ3LÔMÒ3L¡ ˆEŠOÑ3LÒMÐMùÓMs   Ÿ1Úr0_optim_state_keysÚoptim_state_key_to_param_keyrT  c           	      óú  • / nU  HV  nXQ;  a  UR                  U5        M  X   n[        U[        5      (       d  M6  US:¼  a  U[        U5      :  a  MM  [	        S5      e   [        U5      n[        R                  " [        U5      /[        R                  US9n[        R                  " XƒS9  UR                  5       S:”  a²  [        [        R                  " U5      5       V	s/ s H  n	S PM     n
n	[        R                  " X¤US9  Sn[        U
5       HR  u  pÍ[!        ["        [$           U5      n[        U5      S:”  d  M-  USU SU Vs/ s H  oîR&                  PM     sn 3-  nMT     [)        U5      eg s  sn	f s  snf )Nr   z+Check the `param_key_to_param` constructionr´   rq   z”FSDP currently requires each rank to have at least the optimizer states needed by rank 0's optimizer but some ranks are missing some of those statesz
Rank z' is missing states for the parameters: )rž   rb   r5   rÝ   r_   r   rK   r·   Úint32r~   Ú
all_reducer  r”   Úget_world_sizeÚall_gather_objectr6  r   r6   rT   rV   rã   )rZ  r[  rT  rr   Úmissing_keysÚr0_optim_state_keyÚ	param_keyrx   Únum_missingr¡   Úobj_listÚ	error_msgrš   r@   rg   s                  r:   Ú_check_missing_keys_on_rankrg  �  sg  € ð *,€LÛ1ÐØÓAð ×ÑÐ 2Ô3ÙØ0ÑDˆ	Ü�i¤×%Ó%Ø “N y´3Ð7IÓ3JÕ'JÜ$Ð%RÓSÐSñ 2ô $ EÓ*€FÜ—,’,¤ LÓ 1Ð2¼%¿+¹+ÈfÑU€KÜ‡O‚O�KÒ-Ø×ÑÓ˜AÓÜ"'¬×(;Ò(;¸EÓ(BÔ"CÓDÒ"C˜Q“DÑ"CˆÐDÜ×Ò˜x¸UÒCð/ð 	ô
 $ HÖ-‰JˆDÜœœ^Ñ,¨dÓ3ˆDÜ�4‹y˜1�}ØØ˜d˜VÐ#JÙ:>Ó?º$°3×.Ô.¹$Ñ?Ð@ðBñ’	ñ .ô ˜9Ó%Ð%ð ùÚDùò @s   Ã!E3ÅE8rç   Ú
merge_keysc           
      ó0  • [         R                  " U5      n0 n/ nUR                  5        H›  u  pšX�S   ;  a  M  X:   n[        U
[        5      nU(       a4  US   U;  a+  [        SUS    S[        UR                  5       5       35      eUS   U;   n[        [        U5      US9nUS:X  d  U(       a  UR                  U5        X—U'   M�     U(       as  [        [         R                  " U5      5       Vs/ s H  n/ PM     nn[         R                  " XøUS9  / [        R                  " U5      Qn[!        [#        U5      5      nX‡4$ US:X  a  U/OS/n[         R$                  " USUS9  US   c  [        S	US    35      eUS   n['        UUUU5        X‡4$ s  snf )
a,  
Construct the local mapping between the ``_OptimStateKey`` and parameter keys
and all the ``_OptimStateKey`` across ranks. If ``merge_keys`` is False, rank0
must contain all the ``_OptimStateKey``, an exception will be raised otherwise.
Note that ``merge_keys`` should equal to ``use_orig_params``.
r)   r   z	Expected z, to be in fqn_to_fsdp_param_info, got keys: )rV   rW   rq   Nr¬   z-Expected key_obj_list[0] to be not None, got )r~   r®   rÁ   rb   r   r_   r6   r@   rT   rX   rž   r”   r_  r`  r	   Úfrom_iterabler?   r×   r¯   rg  )rÇ   rr   rT  ræ   rç   rh  rš   r[  Úall_optim_state_keysrc  rë   rì   rW   Úoptim_state_keyr¡   Úall_keysÚmerge_all_optim_state_keysÚkey_obj_lists                     r:   Ú_map_param_key_to_optim_keysrp  ª  sÙ  € ô �=Š=˜Ó€DØDFÐ Ø13Ðà.×4Ñ4Ö6Ñˆ	ð ¨WÑ5Ó5ÙØÑ#ˆÜ$ U¬MÓ:ˆÞØ�A‰wÐ4Ó4Ü$Ø  Q¡˜yÐ(TÔUYÐZp×ZuÑZuÓZwÓUxÐTyÐzóð ð ˜q™'Ð%;Ñ;ˆÜ(Ü$ T›{Ø+ñ
ˆð �1‹9ž
Ø ×'Ñ'¨Ô8Ø8A _Ó5ñ' 7ö* äœd×1Ò1°%Ó8Ô9ó0
Ú9�1‹BÑ9ð 	ð 0
ô 	×Ò˜xÀUÒKØ%E¤u×':Ò':¸8Ó'DÐ%EÐ"Ü%¤cÐ*DÓ&EÓFÐð$  Ð=Ð=ð '+¨a£iÐ!Ñ"°d°Vð 	ô 	×"Ò" <°Q¸eÒDØ˜‰?Ñ"Ü Ø?ÀÈQÁÐ?PÐQóð ð  ,¨A™ÐÜ#Ø Ø(ØØô		
ð  Ð=Ð=ùò/0
s   Ã2FÚ
state_dictc                 ó  • / nU S    Hp  n[         R                  " U5      nUS    Vs/ s H  nX   PM	     nnU Vs/ s H  o‚U   PM	     n	n/ [        R                  " U	5      QUS'   UR	                  U5        Mr     U$ s  snf s  snf )NrÐ   r%  )rß   rà   r	   rj  rž   )
rq  rT  ræ   rÐ   r2  r1  r-  Úparam_group_paramsrë   Únested_unflat_param_namess
             r:   Ú_unflatten_param_groupsru  ì  sº   € ð
 *,€LØ& ~Ô6ÐÜ!Ÿ]š]Ð+;Ó<Ðð #3°8Ò"<ó
â"<�ð Ô.Ù"<ð 	ð 
ñ
 /Aó%
Ú.@ U˜%Ô Ñ.@ð 	"ð %
ð(
Ü× Ò Ð!:Ó;ð(
Ð˜8Ñ$ð 	×ÑÐ.Ö/ñ 7ð Ðùò
ùò%
s
   ¨A>¼Bc                 óÖ   • U R                  S5      nU(       d  g [        [        UR                  5       5      5      n[        U[        5      $ ! [         a  n[	        U 5      UeSnAff = f)zö
Returns whether the state_dict is from a NamedOptimizer.
This function checks that the keys in the state_dict['state'] are strings
(which usually are FQNs) versus integers (which usually refer to param_ids
from a vanilla torch.optim.Optimizer).
r)   FN)rÞ   r–   rÕ   r@   Ú	Exceptionrb   r4   )rÇ   r)   rg   r:  s       r:   Ú_is_named_optimizerrx    se   € ð × Ñ  Ó)€EÞð ð1Ü”4˜Ÿ
™
›Ó%Ó&ˆô �cœ3ÓÐøô ó 1ÜÐ(Ó)¨qÐ0ûð1ús   ›"A Á
A(ÁA#Á#A(c                   óf   • \ rS rSr% \\\4   \S'   \\\R                  4   \S'   \\\
4   \S'   Srg)Ú	StateInfoi  ÚtensorsÚscalar_tensorsr  r-   N)r.   r/   r0   r1   r3   r4   rN   r2   rK   rL   r
   r8   r-   r9   r:   rz  rz    s7   ‡ ð �#Ð(Ð(Ñ)Ó)Ø˜˜eŸl™lÐ*Ñ+Ó+Ø�c˜3�h‘Ör9   rz  Úinput_statesc                 ó0  • 0 n[        U R                  5       Vs/ s H  n0 PM     nnUR                  5        Hµ  u  pV[        0 0 0 5      n[	        U5       H�  u  p‰[
        R                  " U	5      (       ab  U	R                  5       S:X  a  U	R                  5       UR                  U'   MS  [        U	R                  U	R                  5      UR                  U'   M‚  X—R                  U'   M’     XrU'   M·     [        R                   " UUU R"                  S9  U$ s  snf )z•
Given the ``input_states``, allgather StateInfo for each state. The function
uses all_gather_object to gather StateInfo so no GPU tensors are sent.
r   rq   )r”   rt   rÁ   rz  rB   rK   rl   rm   rc   r|  rN   rP   rQ   r{  r  r~   r`  r€   )
r‰   r}  Úprocessed_state_dictr¡   Úgathered_state_infor¹   rf   Úprocessed_staterŠ   r‹   s
             r:   Ú_allgather_state_infor‚    s  € ð 24Ðä˜*×/Ñ/Ô0ó7Ú0ˆq‹Ñ0ð ð 7ð )×.Ñ.Ö0Ñˆä# B¨¨BÓ/ˆÜ!-¨kÖ!:ÑˆJÜ�Š˜u×%Ñ%Ø—9‘9“; !Ó#àAFÇÁÃ�O×2Ñ2°:Ó>ä:KØŸ™ U§[¡[ó;�O×+Ñ+¨JÓ7ð ;@×+Ñ+¨JÓ7ñ ";ð %4˜SÓ!ñ 1ô 	×ÒØØØ×&Ñ&òð
 Ðùò17s   šDr€  Úoutput_statesc                 ó¶  • 0 nUR                  5        GH¯  u  pVU Vs/ s H  owU   PM	     nn[        U V	V
s1 s H  o™R                    H  oªiM     M     sn
n	5      n[        5       nSnU GHa  n/ n[        5       n[	        U5       H®  u  nnUR                  S5        UR                  R                  US5      nUb\  UR                  R                  5       US'   U(       d  UR                  nO+UUR                  :w  a  [        SU SUR                   35      eUS   S:X  d  M�  UR                  U5        M°     U(       a  UU:X  d  [        SU SU 35      eUnXä;  a  U R                   Vs/ s H  nSPM     snXN'   X%   R                  US5      nUb%  UR                  U R                  R                  5      nUXN   U R                  U   '   GMd     [	        U5       Hâ  u  nnUU;   a  M  UR                   R                  5        HA  u  nnUR                  US5      nUb!  UU:X  d  [        SU S	U S
U S3SU 3-   5      eUUU'   MC     UR"                  R                  5        HW  u  nnUR                  US5      nUb7  [$        R&                  " UU5      (       d  [        SU S	U S
U S3SU 3-   5      eUUU'   MY     Mä     GM²     WU4$ s  snf s  sn
n	f s  snf )a  
Given the ``gathered_state_info`` and ``input_states``, the API converted
the StateInfo into the original state if the state is not a non-scalar
tensor. For a multi-dimensional tensor, the local state will be stored in
``state_buffer`` in a correct order for later allgather purpose.
Nr   éÿÿÿÿz"Expected dtype == info.dtype, got ú != z?Expected empty_ranks to be empty or equal to _empty_ranks, got z vs zRank z has different values for z: r³   z Other ranks: )rÁ   r?   r{  r×   r6  rž   rÞ   rP   r†   rQ   r_   Úaddr+   rz   r)   rw   r  r|  rK   Úequal)rY   r€  r}  rƒ  Ústate_buffersr¹   Úgathered_stateÚsÚ
state_infor)   ÚnÚall_tensor_statesÚempty_ranksrQ   rŠ   ÚnumelsÚ_empty_ranksrš   Úobject_stateÚinfor¡   Úlocal_stateÚnameÚnon_tensor_valueÚcurr_non_tensor_valueÚscalar_tensor_valueÚcurr_scalar_tensor_values                              r:   Ú_convert_all_state_inforš  B  s7  € ð ;=€Mà,×2Ñ2×4ÑˆÙ&9Ó:Ò&9 ˜”fÑ&9ˆ
Ð:Ü"±:Ô#U²:¨%Ç}Å}À!¢AÁ}¡A±:Ò#UÓVÐÜ #£ˆØ$(ˆô ,ˆJØˆFÜ%(£UˆLÜ&/°
Ö&;Ñ"��lØ—‘˜aÔ Ø#×+Ñ+×/Ñ/°
¸DÓA�ØÑ#Ø!%§¡×!1Ñ!1Ó!3�F˜2‘JÞ Ø $§
¡
™à  D§J¡JÓ.Ü"0Ø"DÀUÀGÈ4ÐPT×PZÑPZÈ|Ð \ó#ð ð ˜"‘: •?Ø ×$Ñ$ TÖ*ñ '<ö $ {°lÓ'BÜ$ØUÐVaÐUbÐbfÐgsÐftÐuóð ð 'ˆKØÓ.à"1×"?Ò"?ó-Ú"?˜Q“DÑ"?ñ-�Ñ)ð 'Ñ+×/Ñ/°
¸DÓAˆKð Ñ&Ø)Ÿn™n¨_×-BÑ-B×-QÑ-QÓR�ØLWˆMÑ% o×&CÑ&CÀCÑ&HÔIñC ,ôL #,¨JÖ"7ÑˆD�,Ø�{Ó"ÙØ*6×*BÑ*B×*HÑ*HÖ*JÑ&�Ð&Ø(6×(:Ñ(:¸4ÀÓ(FÐ%à)Ñ1Ø,Ð0@Ó@ä(Ø ˜vÐ%?À¸vÀRÐHXÐGYÐYZÐ[Ø*Ð+@Ð*AÐBñCóð ð (8�˜tÓ$ñ +Kð .:×-HÑ-H×-NÑ-NÖ-PÑ)�Ð)Ø+9×+=Ñ+=¸dÀDÓ+IÐ(à,Ñ4Ü—{’{Ð#6Ð8P×QÑQä(Ø ˜vÐ%?À¸vÀRÐH[ÐG\Ð\]Ð^Ø*Ð+CÐ*DÐEñFóð ð (;�˜tÓ$ó .Qô #8ñ[  5ðP �-ÐÐùòO ;ùÛ#Uùò:-s   �K·KÅ+Kc           	      óî  • U(       d  gU R                   R                  nU R                  nUR                  5        GH”  u  p‰X’   n
U R                  U   n[        U
[        5      (       aÅ  U
R                  S   nU[        5       :w  a‰  UR                  nU
R                  [        5       4S9  [        UR                  U   5      nXí==   U
R                  R                  S5      -  ss'   [        R                   " U5      nU
R#                  U5      n
O=U
R#                  UR                  U   5      n
OU
R#                  UR                  U   5      n
U(       aæ  UR$                  n['        USS5      (       aR  UR(                  c  [+        SUR(                   35      e[-        U
UR.                  UR(                  UR0                  5      n
OºUR2                  c  [+        SUR2                   35      e[5        U
UR.                  UR6                  UR8                  R;                  5       UR2                  UR0                  5      n
ODU(       d=  [<        R>                  " S5         U
RA                  5       RC                  5       n
SSS5        U(       aG  [<        R>                  " [<        RD                  RF                  5         U
RI                  5       n
SSS5        X©U'   GM—     g! , (       d  f       Nf= f! , (       d  f       N)= f)	a  
Given a output state dict, ``output_states``, which the keys are FQNs to the
original parameters (not FlatParameters nor parameter ID), and the values
are gathered states, unflatten the states to the original dimensions.

This function performs the unflattening process in-place.
Nr   )Ú
placementsr�   Fr‘   r’   rˆ   )%r*   rs   r)   rÁ   r+   rb   r"   rœ  r#   rm   Úredistributer6   ró   Údevice_meshr|   rK   rR   Úreshaper—   r˜   r™   r_   r   rš   r›   r€   r   rt   r�   rœ   r   rÙ   r‡   rˆ   rÚ   ÚD2Hrc   )rY   rƒ  rŠ   r\   r[   r]   rs   r‰   r¹   rŠ  r‹   rÃ   Ú	placementÚplacement_dimÚreshape_sizer¦   s                   r:   Ú_unflatten_orig_param_statesr¤  œ  sz  € ö ØØ ×'Ñ'×2Ñ2€JØ ×&Ñ&€JØ,×2Ñ2×4ÑˆØÑ*ˆØ#×1Ñ1°#Ñ6ˆ	ô �eœW×%Ñ%Ø×(Ñ(¨Ñ+ˆIð œI›KÓ'Ø )§¡�Ø×"Ñ"¬y«{¨nÐ"Ñ=Ü# J×$6Ñ$6°yÑ$AÓB�ØÓ+¨u×/@Ñ/@×/EÑ/EÀaÓ/HÑHÓ+Ü$Ÿzšz¨,Ó7�ØŸ™ lÓ3‘ð Ÿ™ j×&8Ñ&8¸Ñ&CÓD‘ð —M‘M *×"4Ñ"4°YÑ"?Ó@ˆEæØ#×<Ñ<ˆJÜ�z >°5×9Ñ9Ø×*Ñ*Ñ2Ü(ØDÀZ×E\ÑE\ÐD]Ð^óð ô +ØØ—O‘OØ×+Ñ+Ø×.Ñ.ó	‘ð ×+Ñ+Ñ3Ü(ØEÀj×F^ÑF^ÐE_Ð`óð ô *ØØ—O‘OØ×)Ñ)Ø×-Ñ-×:Ñ:Ó<Ø×,Ñ,Ø×.Ñ.ó‘ö Ü×'Ò'¨Õ0ØŸ™›×,Ñ,Ó.�÷ 1ö Ü×'Ò'¬×(;Ñ(;×(?Ñ(?Õ@ØŸ	™	›�÷ Aà%*�zÔ"òq  5÷d 1Õ0ú÷ AÕ@ús   ÉKÊ2K&Ë
K#	Ë&
K4	c                 óª
  • U R                   nUR                  S:X  a_  [        R                  " 5       [        R                  R
                  :X  a.  [        R                  SUR                  R                  5       5        U Vs0 s H  ow0 _M     nn[        XX(5      u  pš[        U
5      S:X  a  U$ U R                  R                  5        VVs/ s H	  u  p{Xx;   PM     nnnU R                  R                  n[         R"                  " [$        R&                  X–R(                  S9nU" UR*                  5      nUR                  R-                  5         U
R                  5        GHÕ  u  nn/ nUR                  UR.                  R1                  5       -  nUUR.                  R1                  5       -   S-
  nSu  nn[3        UR4                  UR6                  5       GH  u  nnU(       + =(       a%    U R8                  U   (       + =(       a
    UU   (       + nU(       d  U(       a’  UUU-   S-
  nnUUs=::  a  U::  a  O  OUU:¼  a  UU-
  S-   OUU-
  S-   nOCUUs=::  a  U::  a  O  OUU::  a  UU-
  S-   OUU-
  S-   nOUUs=:  a  Us=::  a  U:  a  O  OUnOSnU(       a  UR;                  U" U5      5        U(       d7  UU   b,  UR;                  [=        [$        R>                  UU   5      5        US-  nUU-  nGM      UR.                  R1                  5       [A        S U 5       5      -
  nURB                  U:w  aJ  [E        SURB                   S	U S
UR.                  R1                  5        SUR4                   SU SU S35      eUS:”  a  UR;                  U" U5      5        [$        RF                  " U5      nUR1                  5       URH                  -  UR1                  5       :w  a  [E        S5      eUR                  R-                  5         [J        RL                  " [J        RN                  RP                  5         [        RR                  " UUURT                  S9  UR                  R-                  5         SSS5        USURV                  R1                  5        nU R                  n U RY                  U5      n![        U!5      [        U R                  5      :w  a  [E        S5      eU R                  R                  5        H*  u  p{U R8                  U   (       d  Xx;   d  M   U!U   X‡   U'   M,     [[        U UUUUU5        GMØ     AU$ s  snf s  snnf ! , (       d  f       Nà= f)zš
Given the ``gathered_state_info`` and ``input_states``, the API allgathers
all tensor states and restore non-tensor states from ``gathered_state_info``.
r   z@Memory Summary before calling to _allgather_orig_param_states %sr´   rp   )r   r   Nc              3   ó@   #   • U  H  oR                  5       v •  M     g 7fr>   )r†   )Ú.0r  s     r:   Ú	<genexpr>Ú/_allgather_orig_param_states.<locals>.<genexpr>[  s   é € Ð1¢=˜a—‘—	�	¢=ùs   ‚zLManually calculated _sharded_numel_padded is incorrect. _shard_numel_padded=z, shard_numel_padded=z, _sharded_size.numel=z, _numels_with_padding=z, begin=z, end=Ú,zËThe size of local shard times the world size should equal to the gathered tensor size. The inconsistency may be from a bug of FlatParameter's metadata or the reconstruction logic in optimizer state dict.rq   zˆThe number of parameters from FlatParameter is not consistent to the number of states used by optimizer state dict reconstruction logic.).r)   rš   r~   Úget_debug_levelÚ
DebugLevelÚDETAILÚloggerr“  r�   Úmemory_summaryrš  rÝ   r+   rÁ   r*   rs   Ú	functoolsÚpartialrK   Úemptyrw   Ú_padded_unsharded_sizer‚   Ú_sharded_sizer†   r  Ú_numels_with_paddingÚ_is_padding_maskr,   rž   r   rL   ÚsumÚ_shard_numel_paddedr_   Úcatrt   r   rÙ   rÚ   Ú	ALLGATHERr   r€   r…   Ú_get_unflat_views_alignedr¤  )"rY   r€  r}  r\   r[   r]   r‰   r¹   rƒ  rQ   r‰  ÚidxÚhas_state_paramsrs   Ú
empty_funcÚgathered_tensorrŠ   ÚbuffersÚlocal_buffersÚbeginÚendÚ
mem_offsetrÃ   r†   Ú
is_paddingÚfrozen_and_no_stateÚpadding_beginÚpadding_endÚpadding_lenÚshard_numel_paddedÚlocal_shardÚunpadded_tensorÚflat_param_handleÚorig_statess"                                     r:   Ú_allgather_orig_param_statesrÏ  ê  s2  € ð !×&Ñ&€JØ‡�˜!Ó¤× 4Ò 4Ó 6¼$¿/¹/×:PÑ:PÓ PÜ�‰ØNØ×%Ñ%×4Ñ4Ó6ô	
ñ
 DPÓ/PÂ<¸C°R²Á<€MÐ/Pä2Ø¨lóÑ€Eô ˆ=Ó˜QÓØÐð .=×-JÑ-J×-PÑ-PÔ-Rô$Ú-R¡ ˆÔÑ-Rð ñ $ð !×'Ñ'×2Ñ2€JÜ×"Ò"Ü�‰˜5×)BÑ)Bñ€Jñ ! ×!BÑ!BÓC€Oà×Ñ×)Ñ)Ô+Ø,×2Ñ2×4Ñˆ
�GØ,.ˆØ—‘ *×":Ñ":×"@Ñ"@Ó"BÑBˆà�j×.Ñ.×4Ñ4Ó6Ñ6¸Ñ:ˆà $Ñˆ
�IÜ!$Ø×+Ñ+¨Z×-HÑ-H÷"
ÑˆE�:ð '1¤.÷ #Ø#×7Ñ7¸	ÑBÔB÷ 4Ø(¨Ñ3Ô3ð  ö
 Ö0ð
 .8¸ÀeÑ9KÈaÑ9O˜{�Ø  EÕ8¨[Ö8ð
  +Ó-ð $ eÑ+¨aÒ/à  5™[¨1™_ñ  ð
 # cÕ8¨[Ö8ð
 ! MÓ1ð ˜mÑ+¨aÒ/à  5™[¨1™_ñ  ð
 ˜]Õ?¨kÕ?¸CÖ?ð #(‘Kà"#�KÞØ!×(Ñ(©°KÓ)@ÔAæð ˜9Ñ%Ñ1Ø!×(Ñ(¬¬e¯l©l¸GÀIÑ<NÓ)OÔPØ˜Q‘�	à˜%Ñ‹Jñq"
ðt (×5Ñ5×;Ñ;Ó=ÜÑ1¡=Ó1Ó1ñ
Ðð ×)Ñ)Ð-?Ó?Ü ð'Ø'1×'EÑ'EÐ&Fð G&Ø&8Ð%9ð :'Ø'1×'?Ñ'?×'EÑ'EÓ'GÐ&Hð I(Ø(2×(GÑ(GÐ'Hð IØ˜˜v c U¨!ð-óð ð  Ó!à× Ñ ¡Ð,>Ó!?Ô@Ü—i’i Ó.ˆØ×ÑÓ ×!6Ñ!6Ñ6¸/×:OÑ:OÓ:QÓQÜ ðóð ð 	×!Ñ!×-Ñ-Ô/Ü×#Ò#¤N×$7Ñ$7×$AÑ$AÕBÜ×'Ò'Ø °J×4LÑ4Lòð ×%Ñ%×1Ñ1Ô3÷ Cð *Ð*W¨J×,OÑ,O×,UÑ,UÓ,WÐXˆØ+×2Ñ2ÐØ'×AÑAÀ/ÓRˆÜˆ{Óœs ?×#@Ñ#@ÓAÓAÜ ðóð ð
 (×5Ñ5×;Ñ;Ö=‰HˆCØ×2Ñ2°3×7¸3Õ;OØ1<¸SÑ1A�Ñ" :Ó.ñ >ô 	%ØØØØØØ÷	
ñ]  5ðn 	ØÐùòi 0Qùó$÷Z CÕBús   Â T9Ã
T>Ð/;UÕ
U	c                 ó  • U R                   nUR                  S:X  d  UR                  [        R                  :X  a  U(       a  U$ 0 $ [
        R                  " [
        R                  R                  5         [
        R                  " [
        R                  R                  5         [        XQ5      nSSS5        [        U WUUUU5      nSSS5        U(       a�  U R                  R                  5        Hm  u  p‰UW;   a  M  U R                  U	   (       d  M#  [        U S[!        U R                  R#                  5       5       S[!        UR#                  5       5       S35      e   W$ 0 $ ! , (       d  f       N¼= f! , (       d  f       Nµ= f)a#  
Given a optimizer state dict, ``input_states``, which the keys are FQNs to the
original parameters (not FlatParameters nor parameter ID), gather all the
states and unflatten them to the original dimensions. Note that all the
params referred by the ``input_states`` must be managed by FSDP.
rp   NzB is not in the output state. The FSDPParamInfo has the param keys z, while the output_states has the param keys r³   )r)   rt   ru   r   rv   r   rÙ   rÚ   rÛ   ÚALLGATHER_OBJr‚  rÏ  r+   rÁ   r,   rã   r?   r@   )
rY   r}  r\   r[   r]   r‰   r€  rƒ  rg   r¼  s
             r:   Ú_gather_all_orig_param_staterÒ  ”  sU  € ð !×&Ñ&€Jà×Ñ Ó"Ø×'Ñ'Ô+;×+DÑ+DÓDæ&ˆ|Ð.¨BÐ.ä	×	Ò	¤× 3Ñ 3× >Ñ >Õ	?Ü×#Ò#¤N×$7Ñ$7×$EÑ$EÕFÜ"7¸
Ó"QÐ÷ Gä4ØØØØØØó
ˆ÷ 
@ö Ø'×5Ñ5×;Ñ;Ö=‰HˆCØ�mÓ#ÙØ"×6Ñ6°s×;ÙäØ�%ð 8ä˜/×7Ñ7×<Ñ<Ó>Ó?Ð@ð A8ä˜-×,Ñ,Ó.Ó/Ð0°ð	3óð ñ >ð Ðàˆ	÷5 GÕFú÷ 
@Õ	?ús$   Á4/E6Â#E%Â/E6Å%
E3	Å/E6Å6
Frk  c                 ón  • 0 n0 nU  GH‹  n	UR                  U	5      n
U
c  U	R                  (       d  M+  U	R                  (       a]  U	R                  S   nUR                  U5      nUc  Ma  U
c  0 OX:   n[        U5      U;  a  0 U[        U5      '   XØ[        U5         U'   M™  U(       d  M¢  [	        U	R                  5      S:w  a!  [        S[	        U	R                  5       35      eU	R                  S   n[        R                  " S5         [        [        [        -  U
5      n
[        R                  " X:   5      X~'   U(       aI  [        X~   5       H8  u  nn[        R                  " U5      (       d  M#  UR                  5       X~   U'   M:     S S S 5        GMŽ     UR!                  5        H÷  n[#        [%        UR'                  5       5      5      nX+   n[	        UR(                  5      S::  a  [        S5      eUR*                  R-                  5        Hn  u  nnUU;   a  M  UR(                  U   (       d  M$  [/        U S[1        UR*                  R'                  5       5       S[1        UR'                  5       5       S35      e   UR3                  [5        UUUUU5      5        Mù     U$ ! , (       d  f       GM­  = f)	Nr   rp   ú;Expected len(optim_state_key.unflat_param_names) == 1, got Únone_fsdp_managed_copyzgWith use_orig_params, FSDPParamInfo should have requires_grad information. However, the length is zero.zE is not in the optimizer state. The FSDPParamInfo has the param keys z( while the optimizer has the param keys r³   )rÞ   rW   rV   ÚidrÝ   r_   r   rÙ   r   r4   r5   rß   rB   rK   rl   rc   rÖ   r–   rÕ   r@   r,   r+   rÁ   rã   r?   r�   rÒ  )rk  r[  rç   rÇ   r[   r\   r]   Úfsdp_osd_stateÚ
all_statesrl  rc  r¹   rY   r)   rû   rŠ   r‹   Ú_all_statesrg   r¼  s                       r:   Ú_convert_state_with_orig_paramsrÚ  Æ  s¦  € ð &(€Nð
 -/€Jô 0ˆØ&B×&FÑ&FÀÓ&Wˆ	àÑ _×%D×%DÙà×*×*Ø!×4Ñ4°QÑ7ˆCØ4×8Ñ8¸Ó=ˆOØÑ&ñ Ø#Ñ+‘BÐ1AÑ1LˆEÜ�/Ó"¨*Ó4Ø24�
œ2˜oÓ.Ñ/Ø38”r˜/Ó*Ñ+¨CÓ0çˆWÜ�?×5Ñ5Ó6¸!Ó;Ü$ØQÔRUÐVe×VxÑVxÓRyÐQzÐ{óð ð !0× BÑ BÀ1Ñ EÐÜ×'Ò'Ð(@ÕAÜ ¤¤s¡¨IÓ6�	Ü48·I²IØ$Ñ/ó5�Ñ1ö Ü-9Ø&Ñ9ö.Ñ)˜
 Eô  %Ÿš¨u×5Ñ5Ù$ØHMÏ	É	Ë˜Ñ9¸*ÓEñ.÷ BÒAñ9 0ðV "×(Ñ(Ö*ˆÜ”4˜×(Ñ(Ó*Ó+Ó,ˆØ0Ñ5ˆÜˆ×2Ñ2Ó3°qÓ8Ü ð<óð ð (×5Ñ5×;Ñ;Ö=‰HˆC�Ø�kÓ!ÙØ"×6Ñ6°s×;ÙÜØ�%ð 8ä˜/×7Ñ7×<Ñ<Ó>Ó?Ð@ð A4ä˜+×*Ñ*Ó,Ó-Ð.¨að	1óð ñ >ð 	×ÑÜ(ØØØØØóö	
ñ) +ð< Ð÷[ B×Aús   ÄBJ$Ê$
J4	c           	      óN  • 0 nU  GH›  nUR                  U5      n	U	c  [        SU SU	 35      eUR                  (       a£  UR                  S   n
X*   n[	        UX9   UUU5      nU(       av  [        U5      [        UR                  5      :w  a-  [        S[        U5       S[        UR                  5       35      eUR                  [        UR                  U5      5        MÛ  MÝ  U(       d  Mæ  [        UR                  5      S:w  a!  [        S[        UR                  5       35      eUR                  S   n[        R                  " X9   5      X}'   U(       d  GMS  [        X}   5       H7  u  pï[        R                  " U5      (       d  M"  UR                  5       X}   U'   M9     GMž     U$ )NzQIf use_orig_params is False, we must be able to find the corresponding param id. r
  r   zKExpected len(unflat_state) == len(optim_state_key.unflat_param_names), got r†  rp   rÔ  )rÞ   r_   rW   rV   rh   rÝ   r�   r  rß   rB   rK   rl   rc   )rk  r[  rç   rÇ   r[   r\   r]   r×  rl  rc  r¹   rY   Úunflat_staterû   rŠ   r‹   s                   r:   Ú_convert_state_with_flat_paramsrÝ  #  sÀ  € ð &(€Nô 0ˆØ&B×&FÑ&FÀÓ&Wˆ	àÑÜ ð+Ø+:Ð*;¸1¸Y¸KðIóð ð
 ×*×*ð "×4Ñ4°QÑ7ˆCØ4Ñ9ˆOÜ1ØØ Ñ+ØØØóˆLö Ü�|Ó$¬¨O×,NÑ,NÓ(OÓOÜ(ðÜ" <Ó0Ð1°´c¸/×:\Ñ:\Ó6]Ð5^ð`óð ð ×%Ñ%ÜØ'×:Ñ:Ø$óöñ ÷ ˆWÜ�?×5Ñ5Ó6¸!Ó;Ü$ØQÔRUÐVe×VxÑVxÓRyÐQzÐ{óð ð !0× BÑ BÀ1Ñ EÐÜ04·	²	Ð:JÑ:UÓ0VˆNÑ-ß‰{Ü)5Ø"Ñ5ö*Ñ%�Jô !Ÿ?š?¨5×1Ñ1Ù ØDIÇIÁIÃK�NÑ5°jÓAô*ñU 0ðb Ðr9   c
                 óB  • [         R                  " 5         [        5       n
U
R                  [         R                  " [         R
                  R                  5      5        [        [        R                  " U 5      5        U(       + =(       d"    [        R                  " U5      S:H  =(       d    Un[         R                  " S5         [        U 5      n[        U 5      n[        U5      n[        [         ["        [$        -  [&        R(                  4   U(       a  [+        X5      O[-        XXìU5      5      n[/        U 5      nSSS5        [         R                  " S5         [1        UUWWWUS9u  nnSSS5        [         R                  " S5         U(       a  [2        O[4        nU" WWWUS   UUU	5      nSSS5        U(       d  0 $ SW0n[7        WR9                  5       5      nUS   R;                  5        H<  u  nnUU;   a  M  UU;   a  M  UW;   a  M  [<        R>                  " SU S	3S
S9  UUU'   M>     SU;   a  [A        UWW5      US'   U
RC                  5         [         RD                  " S5        U$ ! , (       d  f       GN9= f! , (       d  f       GN= f! , (       d  f       Né= f)av	  
Consolidates the optimizer state and returns it as a :class:`dict`
following the convention of :meth:`torch.optim.Optimizer.state_dict`,
i.e. with keys ``"state"`` and ``"param_groups"``.
The flat parameters in ``FSDP`` modules contained in ``model`` are mapped
back to their unflattened parameters.

Parameter keys are not well-defined. For a regular optimizer, the optimizer
state_dict contains a mapping from parameter IDs to parameter states.
Parameter IDs are the order of parameters in ``optim.param_groups()`` across
all the groups. This API also allows user to pass ``optim_input`` for the
mapping between parameters and parameter IDs. Using ``optim_input`` is being
deprecated.

If the optimizer is a ``NamedOptimizer``, the optimizer state_dict does not
contain parameter IDs mapping but a mapping from parameter FQNs to parameter
states. This API finds the mapping from FQNs to parameters if the optimizer
is a ``NamedOptimizer``.

If ``use_orig_params`` is True, each rank will have all FSDP-managed
parameters but some of these parameters may be empty due to the sharding.
For a regular optim.Optimizer, states for those empty parameters will
not be initialized. So, when aggregating the FQNs across ranks, no assert
will be raised on a rank even if it does not have all the states -- it is
valid and FSDP knows how to aggregate them. However, FSDP has to ignore
handling those parameters that are not managed by FSDP and do not exist on
the local rank -- those are managed by other parallelisms and FSDP does not
know how to handle/aggregate them.

Args:
    model (nn.Module): Root module (which may or may not be a
        :class:`FullyShardedDataParallel` instance) whose parameters
        were passed into the optimizer ``optim``.
    optim (torch.optim.Optimizer): Optimizer for ``model`` 's
        parameters.
    rank0_only (bool): If ``True``, saves the populated :class:`dict`
        only on rank 0; if ``False``, saves it on all ranks. (Default:
        ``True``)
    shard_state (bool): If ``True``, shard and distribute all
        non-zero-dimension states.

Returns:
    Dict[str, Any]: A :class:`dict` containing the optimizer state for
    ``model`` 's original unflattened parameters and including keys
    "state" and "param_groups" following the convention of
    :meth:`torch.optim.Optimizer.state_dict`. If ``rank0_only=False``,
    then nonzero ranks return an empty :class:`dict`.
r   ÚpreprocessingNÚpreprocessing_with_comm)rh  Ústate_convertingr)   zFound a optim state, aK  , that FSDP cannot process. FSDP will directly copy everything to the returned state_dict. In most cases, this is a user-defined state that is not associated with any particular parameter. Another possible case is this state is managed by TorchRec. Otherwise, there may  be a mismatched assumption of optim_state_dict of this mode.rÍ   rÎ   rÐ   z$FSDP _optim_state_dict() profiling: )#r   rÒ   r   Úenter_contextrÙ   rÚ   ÚALLr   Útraversal_utilsÚ_get_fsdp_handlesr~   r®   r   r&  rx  r   r3   r5   r4   rƒ   r„   r@  rV  rÔ   rp  rÚ  rÝ  r×   rÖ   rÁ   rá   râ   ru  Úcloserä   )rÈ   rÊ   rÇ   r!  rË   r\   rr   r"  rÉ   r]   Úcmr[   ræ   r)  r#  rT  rç   rk  r[  Ú
convert_fnr×  Úfsdp_osdÚflat_param_fqnsrg   r‹   s                            r:   Ú_optim_state_dictrë  c  sp  € ôz ×ÒÔÜ	‹€BØ×Ñ”^×+Ò+¬N×,?Ñ,?×,CÑ,CÓDÔEÜ)¬/×*KÒ*KÈEÓ*RÔSØŒn×H¤§¢¨eÓ 4¸Ñ 9×H¸[€Gä	×	Ò	 Õ	0Ü*¨5Ó1ˆÜ2°5Ó9ÐÜ0Ð1AÓBÐä!Ü””s‘œBŸL™LÐ(Ñ)ö %ô 8¸ÔKä,ØÐ"4ÐEVóó	
Ðô "=¸UÓ!CÐ÷ 
1ô" 
×	Ò	Ð 9Õ	:ô )ØØØØØ"Ø&ñ
ñ	
Ø Ø(÷ 
;ô 
×	Ò	Ð 2Õ	3ö õ ,ä0ð 	ñ
 $Ø Ø(Ø"Ø˜WÑ%ØØØó
ˆ÷ 
4ö$ Øˆ	à '¨Ð8€HäÐ+×2Ñ2Ó4Ó5€OØ& wÑ/×5Ñ5Ö7‰
ˆˆUØ�.Ó ÙØ�/Ó!ÙØÐ$Ó$Ùô 	�ŠØ# C 5ð )Lð Lð ò	
ð $ˆ�sÓñ' 8ð* Ð)Ó)Ü#:ØÐ0°-ó$
ˆ�Ñ ð ‡H�H„JÜ×!Ò!Ð"HÔIà€O÷g 
1Ö	0ú÷" 
;Ö	:ú÷ 
4Õ	3ús%   ÃA8I,ÅI>Æ%JÉ,
I;É>
JÊ
Jc                 óx   • S nS n0 n[        U UU[        U 5       VVs/ s H  u  pEUPM	     snnU5      $ s  snnf )aä  
Construct the mapping from a param's fqn to its corresponding ``FSDPParamInfo``
if the param is managed by FSDP. Shared parameters, or original parameters that
are shared across multiple nn.Modules, are required to belong to one and only
one FSDP instance and thus correspond to one ``FlatParameter``. Within the one
``FlatParameter``, ``FlatParameter._fqns`` only stores the first FQN of a shared
parameter. Thus, the keys in the mapping are guaranteed to map to unique parameters.
c                 óè  • [        U 5      nUc  g [        X@5        [        X@5      nU(       d  g UR                  n[	        XE0 / 5      n[        UR                  5       H“  u  p‰[        X-   5      n
X£;   a)  X:   R                  R                  ULa  [        SU
 35      eXsU
'   X‡R                  U
'   UR                  c  Ma  UR                  R                  UR                  U   R                  5        M•     g )NzDExpected fqn_to_param_info[fqn].handle.flat_param is flat_param for )r   r   r   rs   r'   r6  Ú_fqnsr   r*   r_   r+   Ú_paramsr,   rž   Úrequires_grad)rD  rE  rF  Úfqn_to_param_infor‰   r*   rs   rY   r¼  Ú	local_fqnr¹   s              r:   rH  Ú._get_fqn_to_fsdp_param_info.<locals>.module_fn  sî   € ÜCÀFÓKˆ
ØÑØÜ�:Ô&Ü 
Ó3ˆÞØØ×&Ñ&ˆ
Ü'¨
¸BÀÓCˆô (¨
×(8Ñ(8Ö9‰NˆCÜ# FÑ$6Ó7ˆCØÓ'Ø$Ñ)×0Ñ0×;Ñ;À:ÒMÜ(Ø^Ð_bÐ^cÐdóð ð &5˜cÑ"Ø14×)Ñ)¨#Ñ.Ø×!Ñ!Ó-Ø×3Ñ3×:Ñ:Ø×&Ñ& sÑ+×9Ñ9öò :r9   c                 ó   • U $ r>   r-   )rñ  s    r:   rK  Ú._get_fqn_to_fsdp_param_info.<locals>.return_fn   rM  r9   rN  )rÈ   rH  rK  rñ  r¹   r¡   s         r:   rÔ   rÔ   ü  sP   € òò4!ð 35Ðô ØØØÜ<¸UÔCÔDÒC‘�‹ÑCÒDØóð ùó 	ErP  Ústate_dict_settingsc                 ó¦   • [        U SS 5      (       a?  UR                  nU[        R                  :X  a  [	        SSS5      eSUR
                  l        g g )Nr™   z'Found state_dict_type LOCAL_STATE_DICT.z3DeviceMesh is not compatible with LOCAL_STATE_DICT.zKPlease set state_dict_type to SHARDED_STATE_DICT to get DTensor state_dict.T)r˜   Ústate_dict_typer!   ÚLOCAL_STATE_DICTrã   Úoptim_state_dict_configr�   )r‰   rö  rø  s      r:   Ú_set_optim_use_dtensorrû  0  sZ   € ô ˆz˜>¨4×0Ñ0Ø-×=Ñ=ˆØœm×<Ñ<Ó<ÜØ9ØEØ]óð ð HLÐ×7Ñ7ÕDð 1r9   )FNFN)Fr>   )NFNN)T)FT)yrß   r°  Úloggingrá   Úcollections.abcr   r   r   Ú
contextlibr   Údataclassesr   r   Ú	itertoolsr	   Útypingr
   r   r   r   r   rK   Útorch.distributedÚdistributedr~   Ú'torch.distributed.fsdp._traversal_utilsÚfsdpÚ_traversal_utilsrä  Útorch.nnrƒ   Ú#torch.distributed._state_dict_utilsr   Ú"torch.distributed.distributed_c10dr   Ú$torch.distributed.fsdp._common_utilsr   r   r   r   r   r   r   Ú#torch.distributed.fsdp._debug_utilsr   Ú"torch.distributed.fsdp._flat_paramr   r   Ú'torch.distributed.fsdp._fsdp_extensionsr   r   Ú%torch.distributed.fsdp._runtime_utilsr   r   Útorch.distributed.fsdp.apir   r    r!   Útorch.distributed.tensorr"   r#   Útorch.utils._pytreer$   Ú'torch.distributed._shard.sharded_tensorr%   Ú	getLoggerr.   r®  r'   r3   r4   rX   rB   rD   rN   rT   r7   r6   rh   rn   r`   ra   ÚProcessGroupr±   r¸   rÆ   ÚModulerÊ   Ú	Optimizerrñ   rÜ   rL   rR   rõ   r÷   rø   r„   r4  r5   r@  r&  rV  r(  r'  rg  rp  ru  rx  rz  r‚  rQ   rš  r¤  rÏ  rÒ  rÚ  rÝ  Úno_gradrë  rÔ   rû  r-   r9   r:   Ú<module>r     s¬  ðã Û Û Û ß 8Ñ 8Ý  ß (Ý ß FÕ Fã Ý  ß AÓ AÝ Ý BÝ E÷÷ ñ õ ?ß M÷÷÷ñ ÷
 8Ý -ö ÝEð 
×	Ò	˜8Ó	$€ð ÷$ð $ó ð$ð˜T # s (™^ð °¸¸sÀC¸x¹Ñ0Iô ð ÷Cð Có ðCô2˜
ô ô �Zô ð3Ø"ð3à˜3 ˜8‘nð3ð ð3ð ð	3ð
 ð3ð 
ˆ$ˆs�Cˆx‰.Ñô3ðl/˜3ð / 4ô /ðBØ"ðBà˜3 ˜8‘nðBð ôBðJNØ"ðNà"ðNð ðNð 
ˆ$ˆs�Cˆx‰.Ñô	NðbØðà�c˜3�h‘ðð ×Ñ˜tÑ#ðð 
ˆ#ˆsˆ(�^ô	ð&ØðØ#&ðØ/3×/@Ñ/@À4Ñ/Gðàôð0#Ø"ð#à	ð#ð �c˜3�h‘ð#ð 
ˆ#ˆsˆ(�^ô	#ðR "Ø*.ØØ&*ñO)Ø˜3 ˜8‘nðO)à�9‰9ðO)ð ðO)ð �;‰;× Ñ  4Ñ'ð	O)ð
 ðO)ð ×Ñ˜tÑ#ðO)ð 
ˆ#ˆsˆ(�^õO)ðdMØ"ðMà˜3  S¨# X¡Ð.Ñ/ðMð ˜S™	ðMð 
ˆ#ˆsˆ(�^ô	Mð`RØðRà˜%Ÿ,™,Ñ'ðRð ˜S™	ðRð " %§*¡*Ñ-ð	Rð
 ðRð ‡\�\ôRðj3HØð3Hà˜5Ÿ<™<Ñ(ð3Hð ˜S™	ð3Hð ‡\�\ô	3Hðl$Øð$à�c‘ð$ð ˜S™	ð$ð 	ô	$ðZ  %ñJ,Ø�c˜3�h‘ðJ,à�9‰9ðJ,ð �;‰;× Ñ ðJ,ð �d˜3 ˜8‘nÑ%¨°·±Ñ(>Ñ>ÀÑEð	J,ð
 ðJ,ð ðJ,ð 
ˆ#ˆsˆ(�^õJ,ð^ IMñF.Ø�9‰9ðF.à�d˜3 ˜8‘nÑ%¨°·±Ñ(>Ñ>ÀÑEðF.ð 
ˆ#ˆr�|‰|Ð
ÑõF.ðR" %§(¡(§/¡/ð "°d¸=È#Ð;MÑ6Nô "ðN #Ø$Ø:>Ø9=ñ;Ø�;‰;× Ñ ð;à�9‰9�tÑð;ð ð;ð ˜Ÿ™ d¨3¡iÐ/Ñ0°4Ñ7ð	;ð
 ˜M¨3Ð.Ñ/°$Ñ6ð;ð 
ˆ#�‰)�R—\‘\Ð
!Ñ"õ;ð@ #Ø$Ø:>Ø9=ñNØ�;‰;× Ñ ðNà�9‰9�tÑðNð ðNð ˜Ÿ™ d¨3¡iÐ/Ñ0°4Ñ7ð	Nð
 ˜M¨3Ð.Ñ/°$Ñ6ðNð 
ˆ"�,‰,˜˜c™	Ð
!Ñ"õNð( IMñNØ�9‰9ðNà�d˜3 ˜8‘nÑ%¨°·±Ñ(>Ñ>ÀÑEðNð 
ˆ"�,‰,˜Ð
ÑõNð&&Ø˜nÑ-ð&&à"& ~°s¸S±yÐ'@Ñ"Að&&ð ˜S 3™Y¨¯©Ð4Ñ5ð&&ð ×Ñ˜tÑ#ð	&&ð
 
ô&&ð^ ñ?>Ø˜3 ˜8‘nð?>à×Ñ˜tÑ#ð?>ð ˜S 3™Y¨¯©Ð4Ñ5ð?>ð ˜Ÿ™ d¨3¡iÐ/Ñ0ð	?>ð
 !  mÐ!3Ñ4ð?>ð ð?>ð ˆ4�Ñ  n°c¸C±iÐ&?Ñ!@Ð@ÑAõ?>ðDØ�S˜#�X‘ðà˜S 3™Y¨¯©Ð4Ñ5ðð ˜Ÿ™ d¨3¡iÐ/Ñ0ðð 
ˆ$ˆs�Cˆx‰.Ñô	ð, ¨$¨s°C¨x©.ð  ¸Tô  ð& ÷ ð  ó ð ð"Øð"à�s˜C�x‘.ð"ð 
ˆ$ˆs�Iˆ~Ñ
Ñô"ðJW Ø"ðW à˜d 3¨	 >Ñ2Ñ3ðW ð �s˜C�x‘.ðW ð ˜˜T # s (™^Ð+Ñ,ð	W ð
 ˆ5�;‰;˜Ñ˜t C¨¨e¯l©l¸TÑ.AÑ)BÐ$BÑCÐCÑDôW ðtK+Ø"ðK+à˜˜T # s (™^Ð+Ñ,ðK+ð ðK+ð ð	K+ð
 ðK+ð ðK+ð 
ôK+ð\gØ"ðgà˜d 3¨	 >Ñ2Ñ3ðgð �s˜C�x‘.ðgð ð	gð
 ðgð ðgð 
ˆ#ˆt�C˜�H‰~Ð
ÑôgðT/Ø"ð/à�s˜C�x‘.ð/ð ð/ð ð	/ð
 ð/ð 
ˆ#ˆsˆ(�^ô/ðr ñZØ˜~Ñ.ðZà"& ~°s¸S±yÐ'@Ñ"AðZð !  mÐ!3Ñ4ðZð ˜3 ™9 c˜>Ñ*ð	Zð
 ðZð ðZð ðZð 
ˆ#ˆsˆ(�^õZðH ñ=Ø˜~Ñ.ð=à"& ~°s¸S±yÐ'@Ñ"Að=ð !  mÐ!3Ñ4ð=ð ˜3 ™9 c˜>Ñ*ð	=ð
 ð=ð ð=ð ð=ð 
ˆ#ˆsˆ(�^õ=ð@ ‡‚ƒð "ØñUØ�9‰9ðUà�;‰;× Ñ ðUð ˜3 ˜8‘nðUð �d˜3 ˜8‘nÑ%¨°·±Ñ(>Ñ>ÀÑEð	Uð
 ðUð ðUð ×Ñ˜tÑ#ðUð ðUð ðUð ðUð 
ˆ#ˆsˆ(�^ôUó ðUðp1 r§y¡yð 1°T¸#¸}Ð:LÑ5Mô 1ðh ðLØðLà*ðLð 
óLó ñLr9   