Ë
    g^(hS ã                   óT  — d dl Z d dlZd dlZd dlZd dlmZmZmZ d dlm	Z	 d dl
mZmZ d dlmZ d dlmZmZmZmZmZmZmZ d dlZd dlmZ d dlmc mc mZ d dlm Z  d dl!m"Z" d dl#m$Z$ d d	l%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z, d d
l-m.Z. d dl/m0Z0m1Z1 d dl2m3Z3m4Z4 d dl5m6Z6m7Z7 d dl8m9Z9m:Z:m;Z; d dl<m=Z=m>Z> d dl?m@Z@ erd dlAmBZB  ej†                  eD«      ZEe G d„ d«      «       ZFdeGeHef   deeIeHef      fd„ZJe G d„ d«      «       ZK G d„ de«      ZL G d„ de«      ZMdeFdeGeHef   deNd eNd!eNdeOeGeHef      fd"„ZPd#edeNfd$„ZQdeFdeGeHef   deKfd%„ZRdeFd&eKd eNdeOeGeHef      fd'„ZSd(e'd)eGeHef   d*eej¨                     deGeHef   fd+„ZUd(e'd&ed*eej¨                     defd,„ZVdeFd-eHd)eGeHef   deGeHef   fd.„ZW	 	 	 	 dhd/eGeHef   d0e j°                  d1eNd2eej²                  j´                     d3eNd*eej¨                     deGeHef   fd4„Z[deFd5eGeHeGeHef   f   d6eOeH   deGeHef   fd7„Z\d8eHd9eOejº                     d6eOeH   d:eej¼                     d;e1dejº                  fd<„Z_d8eHd=eOejº                     d6eOeH   dejº                  fd>„Z`d8eHd?eOe   d6eOeH   defd@„Za	 didAeGeHef   d0e j°                  d2ej²                  j´                  dBeeeOeGeHef      ee jÄ                     f      dCeNdDeNdeGeHef   fdE„Zc	 djd0e j°                  dBeeeOeGeHef      ee jÄ                     f      deGede jÄ                  f   fdF„Zed0ej@                  j°                  deGe0eHf   fdG„Zf	 	 	 	 dkd2ej²                  j´                  d0ee j°                     dDeNdHeeGe jÄ                  eOeH   f      dIeeGe0eHf      deGeedeHf   e jÄ                  f   fdJ„Zg	 	 	 	 dkd2ej²                  j´                  d0ee j°                     dDeNdHeeGe jÄ                  eOeH   f      dIeeGe0eHf      deGe jÄ                  eedeHf   f   fdK„Zh	 djd0e j°                  dBeeeOeGeHef      ee jÄ                     f      deGe jÄ                  edf   fdL„ZidMeOeM   dNeGeMeeHedf   f   dOeGeeHedf   e jÄ                  f   d*eej¨                     ddf
dP„Zj	 did/eGeHef   d*eej¨                     dOeGeedeHf   e jÄ                  f   dHeGe jÄ                  eOeH   f   dQeGeHeFf   dReNdeIeOeM   eGeMeedeHf   f   f   fdS„ZkdTeGeHef   dOeGeedeHf   e jÄ                  f   dHeGe jÄ                  eOeH   f   deOeGeHef      fdU„Zld/eGeHef   deNfdV„Zme G dW„ dX«      «       Znd(e'dYeGeHef   deOeGeHenf      fdZ„ZodeFd[eOeGeHenf      dYeGeHef   d\eGeHeGeHef   f   deIeejà                     eGeHeOeejº                        f   f   f
d]„ZqdeFd\eGeHeGeHef   f   d8eHd eNdeNd!eNddfd^„ZrdeFd[eOeGeHenf      dYeGeHef   d eNdeNd!eNdeGeHeGeHef   f   fd_„ZsdeFdYeGeHef   d eNdeNd!eNdeGeHef   fd`„Zt	 dldaeOeM   dNeGeMeedeHf   f   dQeGeHeFf   d/eGeeHedf   ef   deNd eNd!eNdeGeHef   fdb„Zu	 dldaeOeM   dNeGeMeedeHf   f   dQeGeHeFf   d/eGeeHedf   ef   deNd eNd!eNdeGeHef   fdc„Zv ejî                  «       	 	 dmd0e j°                  d2ej²                  j´                  d/eGeHef   dBeeeOeGeHef      ee jÄ                     f      d3eNd eNd*eej¨                     dCeNd1eNd!eNdeGeHef   fdd„«       Zxd0e j°                  deGeHeFf   fde„Zyed(e'dfe:ddfdg„«       Zzy)né    N)ÚIterableÚIteratorÚSequence)Ú	ExitStack)Ú	dataclassÚfield)Úchain)ÚAnyÚcastÚ
NamedTupleÚno_type_checkÚOptionalÚTYPE_CHECKINGÚUnion)Ú_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                   óF   — e Zd ZU eed<   eed<   eeef   ed<   e	e
   ed<   y)ÚFSDPParamInfoÚstateÚhandleÚparam_indicesÚparam_requires_gradN)Ú__name__Ú
__module__Ú__qualname__r   Ú__annotations__r   ÚdictÚstrÚintÚlistÚbool© ó    úa/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/distributed/fsdp/_optim_utils.pyr)   r)   5   s&   … àÓØÓØ˜˜S˜‘>Ó!Ø˜d™Ô#r8   r)   Ú
dictionaryÚreturnc              #   ó^   K  — t        | j                  «       «      }|D ]  }|| |   f–— Œ y ­w©N)ÚsortedÚkeys)r:   r?   Úks      r9   Úsorted_itemsrA   =   s5   è ø€ Ü�*—/‘/Ó#Ó$€DØò ˆØ�˜A‘ÐÓñùs   ‚+-c                   ó¬   — e Zd ZU dZ ee¬«      Zeeej                  f   e
d<    ee¬«      Zeeej                  f   e
d<    ee¬«      Zeeef   e
d<   y)Ú_ConsolidatedOptimStateap  
    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_stateN)r.   r/   r0   Ú__doc__r   r2   rE   r3   ÚtorchÚTensorr1   rF   rG   r
   r7   r8   r9   rC   rC   C   s\   … ññ& -2À$Ô,G€L�$�s˜EŸL™LÐ(Ñ)ÓGÙ5:È4Ô5PÐ˜4  U§\¡\Ð 1Ñ2ÓPÙ',¸TÔ'BÐ�d˜3 ˜8‘nÔBr8   rC   c                   óN   — e Zd ZU dZej
                  ed<   ej                  ed<   y)Ú_PosDimTensorInfoaƒ  
    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ÚdtypeN)r.   r/   r0   rH   rI   ÚSizer1   rN   r7   r8   r9   rL   rL   ]   s   … ñ	ð �:‰:ÓØ�;‰;Ôr8   rL   c                   ó0   — e Zd ZU dZeedf   ed<   eed<   y)Ú_OptimStateKeyzë
    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_managedN)r.   r/   r0   rH   Útupler3   r1   r6   r7   r8   r9   rQ   rQ   m   s   … ñð ˜c 3˜h™Ó'ØÔr8   rQ   Úfsdp_param_infoÚflat_param_stateÚto_saveÚshard_stateÚcpu_offloadc                 ó  — |r	|sJ d«       ‚t        | |«      }|rjt        | ||«      }|D ]V  }|sŒt        |j                  «       «      D ]5  }||   }	t	        |	t
        j                  «      sŒ#|	j                  «       ||<   Œ7 ŒX |S g S )aO  
    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.)Ú_communicate_optim_stateÚ#_unflatten_communicated_optim_stater5   r?   Ú
isinstancerI   rJ   Úcpu)
rU   rV   rW   rX   rY   Úconsolidated_stateÚunflat_param_stateÚoptim_stateÚkeyr*   s
             r9   Ú_unflatten_optim_staterc   x   s®   € ñ: ™gð ØAóÐ%ô 2ØØóÐñ Ü@ØØØó
Ðð
 .ò 	3ˆKâÜ × 0Ñ 0Ó 2Ó3ò 3�CØ'¨Ñ,�EÜ% e¬U¯\©\Ô:Ø Ø',§y¡y£{�K Ò$ñ	3ð	3ð "Ð!àˆ	r8   Úxc                 óV   — t        j                  | «      xr | j                  «       dk(  S ©Nr   )rI   Ú	is_tensorÚdim)rd   s    r9   Ú_is_zero_dim_tensorri   ¯   s    € Ü�?‰?˜1ÓÒ. !§%¡%£'¨Q¡,Ð.r8   c                 óæ  — | j                   }| j                  j                  }t        «       }|j                  |j
                  |j                  }}}t        |«      D �]‘  \  }}	t        j                  |	«      �rB|	j                  «       dkD  �r.|j                  dk(  s|j                  t        j                  k(  r|	||<   Œc|j                  €J d«       ‚|	j                   j"                  |j                  j"                  k7  r|	j%                  |j                  «      }	|j&                  j)                  «       }
 |	j*                  |
Ž }t-        j.                  ||	|j0                  ¬«       |j2                  j5                  «        t7        t8        j:                  |j<                  «      j?                  «       }|d| ||<   �Œ_tA        |	«      r#|	jC                  «       jE                  «       ||<   �Œ�|	||<   �Œ” |S )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_paramrC   rE   rF   rG   rA   rI   rg   rh   Ú
world_sizeÚsharding_strategyr!   ÚNO_SHARDÚcompute_deviceÚdeviceÚtypeÚtoÚ_full_param_paddedÚsizeÚ	new_zerosÚdistÚall_gather_into_tensorÚprocess_groupÚ_device_handleÚsynchronizer   ÚnnÚ	ParameterÚ_unpadded_unsharded_sizeÚnumelri   ÚdetachÚclone)rU   rV   Ú
fsdp_statern   r*   rE   rF   rG   Ú
state_nameÚvalueÚbuffer_sizeÚtensor_bufferÚunpadded_numels                r9   r[   r[   ³   sÆ  € ð, !×&Ñ&€JØ ×'Ñ'×2Ñ2€JÜ#Ó%€Eà×ÑØ×#Ñ#Ø×Ñð *:Ð'€Lô *Ð*:Ó;ó #5Ñˆ
�Eä�?‰?˜5Õ! e§i¡i£k°A£oð
 ×%Ñ%¨Ò*Ø×/Ñ/Ô3C×3LÑ3LÒLà+0�˜ZÑ(ØØ×,Ñ,Ð8ð Ø9óÐ8ð �|‰|× Ñ  J×$=Ñ$=×$BÑ$BÒBØŸ™ ×!:Ñ!:Ó;�ð %×7Ñ7×<Ñ<Ó>ˆKØ+˜EŸO™O¨[Ð9ˆMÜ×'Ñ'Ø˜u¨J×,DÑ,Dõð ×%Ñ%×1Ñ1Ô3Ü!Ü—‘˜j×AÑAóç‰e‹gð ð (5°_°nÐ'EˆL˜Ó$ô # 5Ô)Ø49·L±L³N×4HÑ4HÓ4JÐ% jÓ1à/4Ð  Ó,ðG#5ðH €Lr8   r*   c           
      óR  — | j                   }| j                  }|j                  }g }i }|j                  }|j                  |j
                  |j                  }}
}	t        |«      D �]?  }i }t        |	«      D ]ë  \  }}||v }|s|j                  |«      }|||<   n||   }t        |«      }|r²|j                  }t        |dd«      r;|j                  €J ‚t        ||j                  |j                  |j                   «      }n^|j"                  €J ‚t%        ||j                  |j&                  |j(                  j+                  «       |j"                  |j                   «      }|||<   Œí t        |
«      D ]
  \  }}|||<   Œ t        |«      D ]
  \  }}|||<   Œ |j-                  |«       �ŒB |S )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)r*   r+   rn   Ú_num_paramsrE   rF   rG   ÚrangerA   Ú_get_unflat_viewsÚnextÚ_optim_state_dict_configÚgetattrÚ_device_meshr   ÚrankÚ_fsdp_extensionr{   r   ro   r|   Údevice_countÚappend)rU   r*   rX   r„   r+   rn   r`   Úflat_param_viewsÚnum_unflat_paramsrE   rF   rG   Ú_Úunflat_state_paramr…   Úflat_tensorÚviews_generatedÚviewsra   Ú
osd_configÚzero_dim_tensorÚ
non_tensors                         r9   r\   r\   ù   sï  € ð, !×&Ñ&€JØ×#Ñ#€FØ×"Ñ"€JØ/1ÐØ,.ÐØ"×.Ñ.Ðà×ÑØ×#Ñ#Ø×Ñð *:Ð'€Lô Ð$Ó%ó '6ˆØÐä'3°LÓ'Aò 	9Ñ#ˆJ˜Ø(Ð,<Ð<ˆOÙ"Ø×0Ñ0°Ó=�Ø/4Ð  Ò,à(¨Ñ4�ÜGKÈEÃ{ˆKÙØ'×@Ñ@�
Ü˜: ~°uÔ=Ø%×2Ñ2Ð>Ð>Ð>Ü"4Ø#Ø"Ÿ™Ø"×/Ñ/Ø"×2Ñ2ó	#‘Kð &×3Ñ3Ð?Ð?Ð?Ü"3Ø#Ø"Ÿ™Ø"×-Ñ-Ø"×1Ñ1×>Ñ>Ó@Ø"×0Ñ0Ø"×2Ñ2ó#�Kð .9Ð˜zÒ*ð9	9ô> ,8Ð8MÓ+Nò 	=Ñ'ˆJ˜Ø-<Ð˜zÒ*ð	=ô '3Ð3CÓ&Dò 	8Ñ"ˆJ˜
Ø-7Ð˜zÒ*ð	8à×!Ñ!Ð"4Ö5ðO'6ðP Ðr8   r„   ra   rm   c                 óä   — d g}t        j                  |«      dk(  rt        t        j                  d„ |«      |d<   t        j
                  |d|¬«       t        j                  |«      dk(  r|S |d   S )Nr   c                 óˆ   — | j                  «       dk(  r| j                  «       S t        | j                  | j                  «      S rf   )rh   r^   rL   rM   rN   )Úvs    r9   ú<lambda>z,_broadcast_processed_state.<locals>.<lambda>O  s,   €  §¡£¨A¢�a—e‘e“g€ Ô3DÀQÇWÁWÈaÏgÉgÓ3V€ r8   ©Úsrcrm   )ry   Úget_rankr&   rI   rJ   Úbroadcast_object_list)r„   ra   rm   Úobjectss       r9   Ú_broadcast_processed_staterª   F  sl   € ð
 ˜€GÜ‡}�}�UÓ˜qÒ Ü"Ü�L‰LÙVØó
ˆ�‰
ô
 	×Ñ˜w¨A°UÕ;Ü‡}�}�UÓ˜qÒ ØÐà�q‰zÐr8   c                 óø  — t        j                  |«      dk(  rKt        |t        j                  «      r|j                  «       dk(  r|S |j                  | j                  «      }n~t        |t        j                  «      r|j                  «       dk(  sJ d«       ‚|S t        |t        «      s|S t        j                  |j                  |j                  | j                  ¬«      }t        j                  |d|¬«       |S )Nr   zlFor non-zero ranks, a tensor state should have zero dimension, but got the state with shape {state.shape()}.©rN   rs   r¥   )ry   r§   r]   rI   rJ   rh   ru   rr   rL   ÚzerosrM   rN   Ú	broadcast)r„   r*   rm   Útensors       r9   Ú_broadcast_stater°   Y  sÉ   € ô ‡}�}�UÓ˜qÒ Ü˜%¤§¡Ô.°%·)±)³+ÀÒ2BØˆLØ—‘˜*×3Ñ3Ó4‰ä�eœUŸ\™\Ô*Ø—9‘9“; !Ò#ð ð@óÐ#ð ˆLÜ˜EÔ#4Ô5ØˆLÜ—‘Ø�K‰K˜uŸ{™{°:×3LÑ3Lô
ˆô 	‡N�N�6˜q¨Õ.Ø€Mr8   Úfqnc                 ó.  — |si S | j                   }| j                  j                  }| j                  |   }|j                  |   }t        ||j                  |j                  ¬«      }|j                  si S i }|j                  }|j                  }	|j                  «       D ]s  \  }
}t        j                  |«      rT|j                  «       dkD  rA|j                  t         j"                  k7  r$|j%                  «       ||	dz    j'                  «       }|||
<   Œu |S )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.
    ©Úpgrs   r   rk   )r*   r+   rn   r,   Ú_shard_param_infosr   r{   rr   Úin_shardÚintra_param_start_idxÚintra_param_end_idxÚitemsrI   rg   rh   rp   r!   rq   Úflattenrƒ   )rU   r±   ra   r„   rn   Ú	param_idxÚshard_param_infoÚnew_optim_stater·   r¸   r…   r†   s               r9   Ú_shard_orig_param_stater¾   p  s  € ñ Øˆ	Ø ×&Ñ&€JØ ×'Ñ'×2Ñ2€JØ×-Ñ-¨cÑ2€IØ!×4Ñ4°YÑ?ÐÜ$Ø˜
×0Ñ0¸×9RÑ9Rô€Kð ×$Ò$Øˆ	à&(€OØ,×BÑBÐØ*×>Ñ>ÐØ(×.Ñ.Ó0ò 
,Ñˆ
�Eä�O‰O˜EÔ"Ø—	‘	“˜a’Ø×,Ñ,Ô0@×0IÑ0IÒIà—M‘M“OØ%Ð(;Øñ)ð÷ ‰e‹gð ð ',ˆ˜
Ò#ð
,ð Ðr8   Úoptim_state_dictÚmodelÚuse_orig_paramsÚoptimÚ
rank0_onlyc                 ó¨  — t        j                  «        | }d|vr|st        d«      ‚t        |«      }t	        |«      }t        t        |j                  «       «      «      j                  }	|rt        |	||¬«      }i }
|d   }t        |j                  «       «      }|j                  «       D �]  \  }}|d   }||vrŒ|j                  |«       |rD|D ]:  }||   sŒ	||   j                  «       D ]  }t        |	||   |   |¬«      ||   |<   Œ Œ< |d   }||v �r||   }|rGt        j                  t         j                   j"                  «      5  t%        ||||   «      }ddd«       nt'        |||«      }t)        t+        |«      d«      }r||
|<   nÊ|ryt-        |«      dk(  sJ d|› d	�«       ‚|�­|j                  j/                  |d«      }|�t1        j2                  |«      |
|<   nvt5        j6                  d
|› d|	j8                  › d	�«       nOt;        d|› d�«      ‚t-        |«      dk(  sJ ‚t)        t+        |«      d«      }t1        j0                  ||   «      |
|<   |s�Œ³|D ]X  }||   sŒ	t=        ||   j                  «       «      D ]1  \  }}|	j8                  dkD  r||   |= Œ|j?                  «       ||   |<   Œ3 ŒZ �Œ |D ]K  }||   }tA        |tB        jD                  «      r|r|rt        |	||¬«      }t1        j0                  |«      |
|<   ŒM t        jF                  d«       d|v rt1        j2                  |d   «      }|
|dœS d|
iS # 1 sw Y   �ŒßxY w)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 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 dictrl   r   NTrk   z5use_orig_params is True but there are multiple FQNs, ú.zoptim_state[z] is not on rankzThe state of z8 is empty. This should happen when use_orig_params=True.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_staterQ   rT   ÚlenÚgetÚcopyÚdeepcopyÚwarningsÚwarnr“   ÚRuntimeErrorr5   r^   r]   rI   rJ   Údump_and_reset)r¿   rÀ   rÁ   rÂ   rÃ   rm   Ú
unflat_osdÚparam_to_fqnsÚfqn_to_fsdp_param_infor„   Úflat_osd_stateÚunflat_osd_stateÚall_state_keysÚparamÚfqnsr±   r…   rU   Ú
flat_staterb   r*   Úparam_stateÚ
user_stateÚflat_osd_param_groupss                           r9   Ú_flatten_optim_state_dictrç   –  s×  € ô@ ×ÑÔà!€JØ�jÑ ©Üð1ó
ð 	
ô ' uÓ-€MÜ8¸Ó?ÐÜ”dÐ1×8Ñ8Ó:Ó;Ó<×BÑB€Jñ Ü/°
¸JÈeÔTˆ
ð =?€NØ! 'Ñ*ÐÜÐ)×.Ñ.Ó0Ó1€Nà$×*Ñ*Ó,ó FN‰ˆˆtØ�1‰gˆØÐ&Ñ&ØØ×(Ñ(¨Ô.áØò �Ø'¨Ò,ØØ"2°3Ñ"7×"<Ñ"<Ó">ò �JÜ8HØ"Ð$4°SÑ$9¸*Ñ$EÈUô9Ð$ SÑ)¨*Ò5ñðð �q‘'ˆCØÐ(Ò(Ø4°SÑ9ˆOÙÜ#×+Ñ+¬N×,?Ñ,?×,JÑ,JÓKñ Ü!8Ø'ØØ(¨Ñ-ó"�J÷ð ô 2Ø#Ø$Øó�
ô
 !¤ t£¨dÓ3ˆCñ Ø&0�˜sÒ#Ù Ü˜4“y A’~ð ØKÈDÈ6ÐQRÐSó�~ð Ð$Ø!ŸK™KŸO™O¨E°4Ó8�EØÐ(Ü.2¯m©m¸EÓ.B˜ sÒ+ä Ÿ™Ø*¨3¨%Ð/?À
ÇÁÐ?PÐPQÐRõô
 #Ø# C 5ð ),ð ,óð ô
 �t“9 ’>Ð!�>Ü ¤ t£¨eÓ4ˆCÜ"&§)¡)Ð,<¸SÑ,AÓ"BˆN˜3ÑãØò 
N�Ø'¨Ò,ØÜ/3Ð4DÀSÑ4I×4OÑ4OÓ4QÓ/Rò NÑ+�J Ø!—‘¨Ò*à,¨SÑ1°*Ñ=ð =H¿O¹OÓ<MÐ(¨Ñ-¨jÒ9ñNò
NðyFNðR ò 4ˆØ% cÑ*ˆ
Ü�j¤%§,¡,Ô/±JÁ?Ü)¨*°jÈÔNˆJÜ"Ÿi™i¨
Ó3ˆ�sÒð	4ô ×!Ñ!Ð"PÔQð ˜Ñ#Ü $§¡¨j¸Ñ.HÓ IÐØ'Ð9NÑOÐOà˜Ð(Ð(÷Kñ ús   ÅMÍM	rß   rR   c           	      ó\  — | j                   }| j                  }|j                  }t        |«      }|dkD  sJ d«       ‚|j                  }t        |«      }||k(  sJ d|› d|› �«       ‚|D �	cg c]  }	t        |	|v «      ‘Œ }
}	t        |
«      si S |D �	cg c]-  }	|	|v r%t        ||	   |j                  |j                  ¬«      nd‘Œ/ }}	d}|D ]K  }|€Œ|€t        |j                  «       «      }Œ"|t        |j                  «       «      k7  sŒ?t        d|› �«      ‚ |€J ‚i }|D �]q  }|D �cg c]  }|�||   nd‘Œ }}|D �cg c]  }|€Œ|‘Œ	 }}|sd||<   Œ4dx}x}}|D ]V  }|t        j                  |«      xr |j                  «       dkD  z  }|t!        |«      z  }|t        j                  |«       z  }ŒX |D �ch c]  }t#        |«      ’Œ }}t        |«      d	k7  s|s|s|st        d
|› d|› d|› �«      ‚|rst%        |||||«      }|j&                  d	k7  rL|j(                  t*        j,                  k7  r/t/        j0                  ||j2                  |j&                  «      \  }}n|}|||<   �ŒJ|rt5        |||«      ||<   �Œ^|sJ ‚t7        |||«      ||<   �Œt |S c c}	w c c}	w c c}w c c}w c c}w )ao  
    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: Trk   z*Differing optimizer state types for state z	, values z", and unflattened parameter names )r*   r+   rn   rÓ   Ú_shapesr6   Úanyr   r{   rr   rÍ   r?   rÉ   rI   rg   rh   ri   rt   Ú_flatten_tensor_optim_statero   rp   r!   rq   r   Ú
_get_shardr“   Ú$_flatten_zero_dim_tensor_optim_stateÚ_flatten_non_tensor_optim_state)rU   rß   rR   r„   r+   rn   r˜   Úunflat_param_shapesÚnum_unflat_param_shapesÚunflat_param_nameÚ	has_stateÚunflat_param_statesÚstate_namesr`   rã   r…   Ústate_valuesr£   Únon_none_state_valuesÚare_pos_dim_tensorsÚare_zero_dim_tensorsÚare_non_tensorsÚtypesr›   Úsharded_flat_tensorr™   s                             r9   rÒ   rÒ   %  s±  € ð. !×&Ñ&€JØ×#Ñ#€FØ×"Ñ"€JÜÐ.Ó/ÐØ˜qÒ ð ØXóÐ ð %×,Ñ,ÐÜ!Ð"5Ó6ÐØÐ 7Ò7ð Ø
Ð$Ð%Ð%5Ð6MÐ5NÐOóÐ7ð "4öàô 	ÐÐ"2Ð2Õ3ð€Ið ô ˆyŒ>Øˆ	ð "4ö	ð ð Ð 0Ñ0ô 	ØÐ.Ñ/Ø×'Ñ'Ø×,Ñ,õ	
ð ñ	ð	Ðð 	ð €KØ1ò 
ÐØÐ%ØØÐÜÐ0×5Ñ5Ó7Ó8‰KàœcÐ"4×"9Ñ"9Ó";Ó<Ó<Ü ð#Ø#5Ð"6ð8óð ð
ð Ð"Ð"Ð"ð 57€JØ!ó :ˆ
ð ':ö
à"ð /AÐ.LÐ˜zÒ*ÐRVÑVð
ˆð 
ð -9Ö J q¸A¹M¢Ð JÐÐ Já$Ø%)ˆJ�zÑ"ØØGKÐKÐÐKÐ2°_Ø&ò 	6ˆAØ¤5§?¡?°1Ó#5Ò#E¸!¿%¹%»'ÀA¹+ÑEÐØ Ô$7¸Ó$:Ñ:Ð Ø¤5§?¡?°1Ó#5Ð5Ñ5‰Oð	6ð #8Ö8˜Q”�a•Ð8ˆÐ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�zÓ"Ù!Ü%IØØØ"ó&ˆJ�zÓ"ñ #Ð"�?Ü%DØØØ"ó&ˆJ�zÓ"ðm:ðx ÐùòCùò	ùò8
ùò !Kùò 9s$   Á)JÂ2JÄ&JÄ<J$ÅJ$Æ7J)r…   Úpos_dim_tensorsrï   r+   c                 óX  — |j                   }|D �cg c]  }|€Œ|‘Œ	 }}|D �ch c]  }|j                  ’Œ }}t        |«      dk7  rt        d|› d| › d|› �«      ‚t	        t        |«      «      }	t        ||«      D ]M  \  }
}|
€t        |«      dk(  rt        d«      ‚|
€Œ$|
j                  |k7  sŒ4t        d|
j                  › d|› �«      ‚ t        j                  d	«      }t        ||«      D ��cg c]V  \  }}|�$t        j                  |j                  |«      «      n*t        j                  t        j                  ||	|¬
«      «      ‘ŒX }}}|j                  ||j                  «      }|j                  }|j                  |k(  sJ d|j                  › d|› �«       ‚|S c c}w c c}w c c}}w )aA  
    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).
    rk   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: ú r^   )rw   rN   rs   ztensor optim state: z flat parameter: )rn   rN   rÓ   rÉ   r�   rË   ÚziprM   rI   rs   rº   ru   r­   Úflatten_tensorsÚ_aligned_numelr€   )r…   rü   rR   rï   r+   rn   ÚtÚnon_none_tensorsÚdtypesrN   r¯   rM   Ú
cpu_deviceÚstate_valueÚtensors_to_flattenr›   Úflat_param_shapes                    r9   rë   rë   ®  sé  € ðL ×"Ñ"€JØ#2ÖD˜a°a±mšÐDÐÐDà/Ö0˜!ˆa�g‹gÐ0€FÐ0Ü
ˆ6ƒ{�aÒÜð)à)/¨°¸J¸<ð H+Ø+=Ð*>ð@ó
ð 	
ô ”�f“Ó€Eä˜_Ð.AÓBò ‰ˆ�Øˆ>œc %›j¨AšoÜÐUÓVÐVØÑ F§L¡L°EÓ$9ÜðØ$Ÿl™l˜^¨1¨U¨Gð5óð ð	ô —‘˜eÓ$€Jô #& oÐ7JÓ"K÷ñ ˆK˜ð Ð"ô 	�‰�k—n‘n ZÓ0Ô1ä�]‰]Ü�K‰KØØØ!ôó
ñ	
ðÐñ ð ×(Ñ(Ð);¸V×=RÑ=RÓS€KØ!×:Ñ:ÐØ×ÑÐ 0Ò0ð Ø
˜{×0Ñ0Ð1Ð1BÐCSÐBTÐUóÐ0ð ÐùòU Eùâ0ùó.s   ‘F™F£F!Ã.AF&Úzero_dim_tensorsc           
      óú  — |D �cg c]  }|€Œ|‘Œ	 }}|D �ch c]  }|�|j                  «       nd’Œ }}|D �ch c]  }|�|j                  nd’Œ }}t        |«      t        |«      k7  st        |«      dk7  st        |«      dk7  rt        d|› d|› d| › d|› �«      ‚t	        t        |«      «      }t	        t        |«      «      }t        j                  ||t        j                  d«      ¬«      S c c}w c c}w c c}w )	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``.
    Nrk   ú‚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ÿ   r^   r¬   )	ÚitemrN   rÓ   rÉ   r�   rË   rI   r¯   rs   )	r…   r  rR   r  r  Ú
values_setr  r†   rN   s	            r9   rí   rí     s  € ðB $4ÖE˜a°q±}šÐEÐÐEà?OÖP¸!˜a˜m�!—&‘&”(°Ñ5ÐP€JÐPØ:JÖK°Q˜˜ˆa�gŠg¨DÑ0ÐK€FÐKäÐÓ¤Ð%5Ó!6Ò6Üˆz‹?˜aÒÜˆv‹;˜!Òäðà(˜\¨°f°X¸[ØˆlÐ;Ø!Ð"ð	$ó
ð 	
ô ”�jÓ!Ó"€EÜ”�f“Ó€EÜ�<‰<˜ U´5·<±<ÀÓ3FÔGÐGùò% FùâPùÚKs   …C.�C.—C3¸C8Únon_tensorsc                 óä   — |D �cg c]  }|€Œ|‘Œ	 }}t        |«      }t        |«      t        |«      k7  st        |«      dk7  rt        d|› d| › d|› �«      ‚t        t	        |«      «      }|S c c}w )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``.
    rk   r  rþ   z" and  unflattened parameter names )rÍ   rÓ   rÉ   r�   rË   )r…   r  rR   ÚntÚnon_none_non_tensorsÚnon_tensor_setr    s          r9   rî   rî   8  s’   € ð2 *5ÖG 2¸¹šBÐGÐÐGä˜Ó%€NÜ
ÐÓ ¤C¨Ó$4Ò4¼¸NÓ8KÈqÒ8PÜðà,Ð-¨[¸¸ð E+Ø+=Ð*>ð@ó
ð 	
ô ”d˜>Ó*Ó+€JØÐùò Hs
   …A-�A-Úsharded_osdÚoptim_inputÚusing_optim_inputÚis_named_optimizerc           
      ó  — t        |«      }t        |«      }t        t        t        j
                  t        t        t        f   f   |rt        ||«      nt        |||||«      «      }t        |«      t        |«      k  sJ ‚i }	i }
|j                  «       D ])  \  }}||vrŒ||   }||	t        |«      <   |D ]  }||
|<   Œ	 Œ+ | d   }i }|j                  «       D ]F  \  }}t        |t        «      r|||<   Œ|	j                  |j                   |j                   «      }|||<   ŒH d| v r[g }| d   D ]L  }t#        j$                  |«      }t'        |d   D �ch c]  }|
|   ’Œ	 c}«      }||d<   |j)                  |«       ŒN ||dœS d|iS c c}w )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.
    r*   rÆ   ÚparamsrÇ   )r   Ú_get_flat_param_to_fqnr   r2   r~   r   r   r4   r3   Ú'_get_param_to_param_id_from_optim_inputÚ_get_param_to_param_keyrÓ   r¹   rT   r]   rÔ   rR   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á   rR   Úflat_param_keyrñ   Úsharded_osd_stateÚrekeyed_osd_staterb   rä   Úrekeyed_osd_param_groupsÚunflat_param_groupÚflat_param_groupÚflat_param_keyss                          r9   Ú_rekey_sharded_optim_state_dictr)  _  s  € ô& ' uÓ-€MÜ.¨uÓ5ÐÜ>BÜŒR�\‰\œ5¤¤c ™?Ð*Ñ+ñ !ô 4°E¸;ÔGä(Ø�uÐ0°-ÐARóó	?Ðô Ð!Ó"¤c¨-Ó&8Ò8Ð8Ð8ð 	ð )ð
 	ð (ð &3×%8Ñ%8Ó%:ò TÑ!ˆÐ!ØÐ*Ñ*àØ+¨EÑ2ˆØJXÐ,¬UÐ3EÓ-FÑGØ!3ò 	TÐØESÐ/Ð0AÒBñ	TðTð $ GÑ,ÐØ46ÐØ-×3Ñ3Ó5ò 8Ñˆˆ[Ü�cœ3ÔØ%0Ð˜cÑ"ØØ=×AÑAØ×"Ñ" C×$:Ñ$:ó
ˆð -8Ð˜.Ò)ð8ð ˜Ñ$Ø9;Ð Ø"-¨nÑ"=ò 		>ÐÜ#Ÿ}™}Ð-?Ó@ÐÜ$ð .@ÀÑ-Iöà)ð 8Ð8IÓJòóˆOð *9Ð˜XÑ&Ø$×+Ñ+Ð,<Õ=ð		>ð +Ð<TÑUÐUàÐ*Ð+Ð+ùòs   ÅF
c                 óV  — |€"t        t        | j                  «       «      «      S 	 t        t        t
        j                     t	        |«      «      }t        |«      dk(  rt        d«      ‚d}d}|D ]2  }|t        |t        j                  «      z  }|t        |t         «      z  }Œ4 |s|st        d«      ‚|rt        t        |«      «      S |sJ ‚g }|D ]#  }d|v }	|	sJ d«       ‚|j                  |d   «       Œ% t        t        |«      «      S # t        $ r}t        d|› �«      |‚d}~ww xY w)	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 dictsr  zNA parameter group should map "params" to a list of the parameters in the group)r2   Ú	enumerateÚ
parametersr   r5   r~   r   Ú	TypeErrorrÓ   rÉ   r]   rI   rJ   Úextend)
rÀ   r  r  ÚeÚall_tensorsÚ	all_dictsrá   Úparam_id_to_paramÚparam_groupÚhas_params_keys
             r9   Ú'_get_param_id_to_param_from_optim_inputr5  ¯  sZ  € ðN ÐÜ”I˜e×.Ñ.Ó0Ó1Ó2Ð2ðÜ”dœ2Ÿ<™<Ñ(¬$¨{Ó*;Ó<ˆô ˆ6ƒ{�aÒÜÐ>Ó?Ð?ð €KØ€IØò -ˆØ”z %¬¯©Ó6Ñ6ˆØ”Z ¤tÓ,Ñ,‰	ð-ñ ™yÜÐSÓTÐTÙÜ”I˜fÓ%Ó&Ð&ÙÐˆ9Ø,.ÐØò 8ˆØ! [Ð0ˆÙð 	
ð&ó	
ˆ~ð 	× Ñ  ¨XÑ!6Õ7ð8ô ”	Ð+Ó,Ó-Ð-øô; ò ÜðØ"�mð%ó
ð ð	ûðús   ¦*D Ä	D(ÄD#Ä#D(c                 ót   — d„ }d„ }i }t        | ||t        | «      D ��cg c]  \  }}|‘Œ	 c}}|«      S c c}}w )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                 óv   — t        | d¬«      D ])  \  }}t        |t        «      sŒt        ||z   «      }|||<   Œ+ y )NF)Úrecurse)r   r]   r   r   )ÚmoduleÚprefixÚ
tree_levelr  Ú
param_namerá   r±   s          r9   Ú	module_fnz)_get_flat_param_to_fqn.<locals>.module_fn	  sI   € Ü!BØ˜Eô"
ò 	+ÑˆJ˜ô ˜e¤]Ô3ØÜ# F¨ZÑ$7Ó8ˆCØ'*Ð˜eÒ$ñ	+r8   c                 ó   — | S r=   r7   )r  s    r9   Ú	return_fnz)_get_flat_param_to_fqn.<locals>.return_fn  ó   € Ø Ð r8   ©r   r   )rÀ   r=  r?  Úflat_param_to_fqn_retr±   r™   s         r9   r  r  ú  sJ   € ò+ò!ð 79ÐÜØØØÜ<¸UÓC×D‘��aŠÓDØóð ùó 	Eó   Ÿ4rÜ   r  c                 óÀ  — i }|r0|�|€J d«       ‚|€J ‚t        |«      D ]  \  }}||t        |«      <   Œ i }d}	| j                  D ][  }
|rC|
d   D ]:  }|€J ‚||v r||   }n|€J ‚t        ||   «      dk(  sJ ‚||   d   }	 ||   }|||<   Œ< ŒH|
d   D ]  }|||	<   |	dz  }	Œ Œ] |S # t        $ r/}t	        d|› dt        |j                  «       «      › d�«      |‚d}~ww xY w)	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.r   r  rk   zCan't find z from rÅ   )r   r   rÆ   rÓ   ÚKeyErrorr5   r?   )rÂ   rÀ   r  rÜ   r  Úclean_fqn_to_curr_fqnrb   r™   Úparam_key_to_paramÚpidr3  rá   r/  s                r9   Ú_get_param_key_to_paramrI    s�  € ð -/ÐÙØÐ(Ð->Ð-Jð 	
ØRó	
ÐJð Ð Ð Ð Ü7¸Ó>ò 	@‰FˆC�Ø<?Ð!Ô"3°CÓ"8Ò9ð	@ð ?AÐØ
€CØ×)Ñ)ò ˆÙØ$ XÑ.ò 0�Ø(Ð4Ð4Ð4ØÐ-Ñ-à+¨EÑ2‘Cà(Ð4Ð4Ð4ä˜}¨UÑ3Ó4¸Ò9Ð9Ð9Ø'¨Ñ.¨qÑ1�CðØ/°Ñ4�Cð
 +0Ð" 3Ò'ñ!0ð$ % XÑ.ò �Ø*/Ð" 3Ñ'Ø�q‘‘ñð)ð0 Ðøô  ò Ü"Ø% c U¨&´Ð6K×6PÑ6PÓ6RÓ1SÐ0TÐTUÐVóàðûðús   Â B%Â%	CÂ.*CÃCc                 ót   — t        | ||||«      }|j                  «       D ��ci c]  \  }}||“Œ
 c}}S c c}}w )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.
    )rI  r¹   )rÂ   rÀ   r  rÜ   r  r2  Úparam_idrá   s           r9   r  r  R  sD   € ô 0ØˆuÐ(¨-Ð9JóÐð 4E×3JÑ3JÓ3L×M¡ ¨%ˆE�8‰OÓMÐMùÓMs   £4c                 ón   — t        | |«      }|j                  «       D ��ci c]  \  }}||“Œ
 c}}S c c}}w )zRConstructs the inverse mapping of :func:`_get_param_id_to_param_from_optim_input`.)r5  r¹   )rÀ   r  r2  rK  rá   s        r9   r  r  d  s7   € ô @ÀÀ{ÓSÐØ3D×3JÑ3JÓ3L×M¡ ¨%ˆE�8‰OÓMÐMùÓMs    1Úr0_optim_state_keysÚoptim_state_key_to_param_keyrG  c           	      óØ  — g }| D ]H  }||vr|j                  |«       Œ||   }t        |t        «      sŒ/|dk\  r|t        |«      k  rŒCJ d«       ‚ t	        |«      }t        j                  t        |«      gt
        j                  |¬«      }t        j                  ||¬«       |j                  «       dkD  r¬t        t        j                  |«      «      D �	cg c]  }	d ‘Œ }
}	t        j                  |
||¬«       d}t        |
«      D ]N  \  }}t        t         t"           |«      }t        |«      dkD  sŒ,|d|› d|D �cg c]  }|j$                  ‘Œ c}› �z  }ŒP t'        |«      ‚y c c}	w c c}w )Nr   z+Check the `param_key_to_param` constructionr¬   rl   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–   r]   r4   rÓ   r   rI   r¯   Úint32ry   Ú
all_reducer  r�   Úget_world_sizeÚall_gather_objectr+  r   r5   rQ   rR   rÙ   )rM  rN  rG  rm   Úmissing_keysÚr0_optim_state_keyÚ	param_keyrs   Únum_missingr™   Úobj_listÚ	error_msgr“   r?   rb   s                  r9   Ú_check_missing_keys_on_rankrZ  r  sy  € ð *,€LØ1ò 
ÐØÐ%AÑAð ×ÑÐ 2Ô3ØØ0Ð1CÑDˆ	Ü�i¤Õ%Ø ’> i´#Ð6HÓ2IÓ&Ið Ø=óÐIð
ô $ EÓ*€FÜ—,‘,¤ LÓ 1Ð2¼%¿+¹+ÈfÔU€KÜ‡O�O�K uÕ-Ø×ÑÓ˜AÒÜ"'¬×(;Ñ(;¸EÓ(BÓ"CÖD˜Q’DÐDˆÐDÜ×Ñ˜x¨¸UÕCð/ð 	ô
 $ HÓ-ò 	‰JˆD�$Üœœ^Ñ,¨dÓ3ˆDÜ�4‹y˜1‹}ØØ˜d˜VÐ#JØ:>Ö?°3˜×.Ó.Ò?Ð@ðBñ‘	ð	ô ˜9Ó%Ð%ð ùÚDùò @s   Ã	E"Ä:E'rÝ   Ú
merge_keysc                 óÞ  — t        j                  |«      }i }g }|j                  «       D ]ˆ  \  }	}
|	| d   vrŒ||
   }t        |
t        «      }|r*|d   |v s#J |d   t        |j                  «       «      f«       ‚|d   |v }t        t        |«      |¬«      }|dk(  s|r|j                  |«       |	||<   ŒŠ |rrt        t        j                  |«      «      D �cg c]  }g ‘Œ }}t        j                  |||¬«       g t        j                  |«      ¢}t        t!        |«      «      }||fS |dk(  r|gndg}t        j"                  |d|¬«       |d   €J ‚|d   }t%        ||||«       ||fS c c}w )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   )rR   rS   rl   Nr¥   )ry   r§   r¹   r]   r   r5   r?   rQ   rT   r–   r�   rR  rS  r	   Úfrom_iterabler>   rÍ   r¨   rZ  )r¿   rm   rG  rÜ   rÝ   r[  r“   rN  Úall_optim_state_keysrV  rá   râ   rS   Úoptim_state_keyr™   Úall_keysÚmerge_all_optim_state_keysÚkey_obj_lists                     r9   Ú_map_param_key_to_optim_keysrc  œ  sÐ  € ô �=‰=˜Ó€DØJLÐ Ø13Ðà.×4Ñ4Ó6ò BÑˆ	�5ð Ð,¨WÑ5Ñ5ØØ˜UÑ#ˆÜ$ U¬MÓ:ˆÙØ˜‘7Ð4Ñ4ð Ø�Q‘ÜÐ+×0Ñ0Ó2Ó3ð7ó Ð4ð ˜q™'Ð%;Ð;ˆÜ(Ü$ T›{Ø+ô
ˆð �1Š9™
Ø ×'Ñ'¨Ô8Ø8AÐ$ _Ò5ð'Bñ* äœd×1Ñ1°%Ó8Ó9ö0
ØŠBð0
ˆð 0
ô 	×Ñ˜xÐ)=ÀUÕKØ%E¤u×':Ñ':¸8Ó'DÐ%EÐ"Ü%¤cÐ*DÓ&EÓFÐð  Ð!=Ð=Ð=ð '+¨a¢iÐ!Ñ"°d°Vð 	ô 	×"Ñ" <°Q¸eÕDØ˜A‰Ð*Ð*Ð*Ø+¨A™ÐÜ#Ø Ø(ØØô		
ð  Ð!=Ð=Ð=ùò)0
s   Ã	E*Ú
state_dictc                 ó   — g }| d   D ]i  }t        j                  |«      }|d   D �cg c]  }||   ‘Œ	 }}|D �cg c]  }||   ‘Œ	 }	}g t        j                  |	«      ¢|d<   |j	                  |«       Œk |S c c}w c c}w )NrÆ   r  )rÕ   rÖ   r	   r]  r–   )
rd  rG  rÜ   rÆ   r'  r&  r"  Úparam_group_paramsrá   Únested_unflat_param_namess
             r9   Ú_unflatten_param_groupsrh  Û  s¿   € ð
 *,€LØ& ~Ñ6ò 0ÐÜ!Ÿ]™]Ð+;Ó<Ðð #3°8Ñ"<ö
àð ˜~Ó.ð
Ðð 
ð
 /Aö%
Ø%*ˆM˜%Ó ð%
Ð!ð %
ð(
Ü× Ñ Ð!:Ó;ð(
Ð˜8Ñ$ð 	×ÑÐ.Õ/ð0ð Ðùò
ùò%
s
   §A6¹A;c                 óÌ   — | j                  dd«      }|sy	 t        t        |j                  «       «      «      }t        |t        «      S # t        $ r}t	        | «      |‚d}~ww xY w)a
  
    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*   NF)rÔ   r�   rË   r?   Ú	Exceptionr]   r3   )r¿   r*   rb   r/  s       r9   Ú_is_named_optimizerrk  ñ  sg   € ð × Ñ  ¨$Ó/€EÙð ð1Ü”4˜Ÿ
™
›Ó%Ó&ˆô �cœ3ÓÐøô ò 1ÜÐ(Ó)¨qÐ0ûð1ús   —"A	 Á		A#ÁAÁA#c                   ó^   — e Zd ZU eeef   ed<   eeej                  f   ed<   eee	f   ed<   y)Ú	StateInfoÚtensorsÚscalar_tensorsr  N)
r.   r/   r0   r2   r3   rL   r1   rI   rJ   r
   r7   r8   r9   rm  rm    s7   … ð �#Ð(Ð(Ñ)Ó)Ø˜˜eŸl™lÐ*Ñ+Ó+Ø�c˜3�h‘Ôr8   rm  Úinput_statesc                 ó  — i }t        | j                  «      D �cg c]  }i ‘Œ }}|j                  «       D ]­  \  }}t        i i i «      }t	        |«      D ]ˆ  \  }}	t        j                  |	«      r_|	j                  «       dk(  r|	j                  «       |j                  |<   ŒLt        |	j                  |	j                  «      |j                  |<   Œz|	|j                  |<   ŒŠ |||<   Œ¯ t        j                   ||| j"                  ¬«       |S c c}w )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   rl   )r�   ro   r¹   rm  rA   rI   rg   rh   r^   ro  rL   rM   rN   rn  r  ry   rS  r{   )
r„   rp  Úprocessed_state_dictr™   Úgathered_state_infor±   ra   Úprocessed_stater…   r†   s
             r9   Ú_allgather_state_inforu    s  € ð 24Ðä˜*×/Ñ/Ó0ö7ØŠð7Ðð 7ð )×.Ñ.Ó0ò 4Ñˆˆ[ä# B¨¨BÓ/ˆÜ!-¨kÓ!:ò 
	@ÑˆJ˜Ü�‰˜uÔ%Ø—9‘9“; !Ò#àAFÇÁÃ�O×2Ñ2°:Ò>ä:KØŸ™ U§[¡[ó;�O×+Ñ+¨JÒ7ð ;@�×+Ñ+¨JÒ7ð
	@ð %4Ð˜SÒ!ð4ô 	×ÑØØØ×&Ñ&õð
 Ðùò17s   š	D	rs  Úoutput_statesc                 ó  — i }|j                  «       D �]`  \  }}|D �cg c]  }||   ‘Œ	 }}t        |D �	�
ch c]#  }	|	j                  j                  «       D ]  }
|
’Œ Œ% c}
}	«      }t	        «       }d}|D �]%  }g }t	        «       }t        |«      D ]‹  \  }}|j                  d«       |j                  j                  |d«      }|�=|j                  j                  «       |d<   |s|j                  }n||j                  k(  sJ ‚|d   dk(  sŒ{|j                  |«       Œ� |r||k(  sJ ‚|}||vr| j                  D �cg c]  }d‘Œ c}||<   ||   j                  |d«      }|�%|j                  | j                  j                  «      }|||   | j                  |   <   �Œ( t        |«      D ]É  \  }}||v rŒ|j                   j                  «       D ]:  \  }}|j                  |d«      }|�||k(  sJ d|› d|› d|› d�d|› �z   «       ‚|||<   Œ< |j"                  j                  «       D ]K  \  }}|j                  |d«      }|�-t%        j&                  ||«      sJ d|› d|› d|› d�d|› �z   «       ‚|||<   ŒM ŒË �Œc |fS c c}w c c}
}	w c c}w )	a1  
    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Rank z has different values for z: rÅ   z Other ranks: )r¹   r>   rn  r?   rÍ   r+  r–   rÔ   rM   r�   rN   Úaddr,   ru   r*   rr   r  ro  rI   Úequal)rU   rs  rp  rv  Ústate_buffersr±   Úgathered_stateÚsÚ
state_infor*   ÚnÚall_tensor_statesÚempty_ranksrN   r…   ÚnumelsÚ_empty_ranksr“   Úobject_stateÚinfor™   Úlocal_stateÚnameÚnon_tensor_valueÚcurr_non_tensor_valueÚscalar_tensor_valueÚcurr_scalar_tensor_values                              r9   Ú_convert_all_state_inforŒ  1  s1  € ð >@€Mà,×2Ñ2Ó4ó ?;Ñˆˆ^Ø&9Ö: �a˜“fÐ:ˆ
Ð:Ü"Ø&×E�5°·±×0BÑ0BÓ0DÒE¨1ŠQÐEˆQÓEó
Ðô !$£ˆØ'+ˆð ,ó 	XˆJØˆFÜ%(£UˆLÜ&/°
Ó&;ò 
+Ñ"��lØ—‘˜aÔ Ø#×+Ñ+×/Ñ/°
¸DÓA�ØÐ#Ø!%§¡×!1Ñ!1Ó!3�F˜2‘JÙ Ø $§
¡
™à$¨¯
©
Ò2Ð2Ð2Ø˜"‘: “?Ø ×$Ñ$ TÕ*ð
+ñ # k°\Ò&AÐAÐAØ&ˆKØ Ñ.à"1×"?Ñ"?ö-Ø’Dò-�˜jÑ)ð ' sÑ+×/Ñ/°
¸DÓAˆKð Ð&Ø)Ÿn™n¨_×-BÑ-B×-QÑ-QÓR�ØLWˆM˜*Ñ% o×&CÑ&CÀCÑ&HÓIð7	Xô@ #,¨JÓ"7ò 	;ÑˆD�,Ø�{Ñ"ØØ*6×*BÑ*B×*HÑ*HÓ*Jò 	8Ñ&�Ð&Ø(6×(:Ñ(:¸4ÀÓ(FÐ%à)Ð1Ø,Ð0@Ò@ðð ˜D˜6Ð!;¸D¸6ÀÐDTÐCUÐUVÐWØ&Ð'<Ð&=Ð>ñ?ó	ðAð (8�˜tÒ$ð	8ð .:×-HÑ-H×-NÑ-NÓ-Pò ;Ñ)�Ð)Ø+9×+=Ñ+=¸dÀDÓ+IÐ(Ø/Ð7¼5¿;¹;Ø'Ð)Aô<ð ð ˜D˜6Ð!;¸D¸6ÀÐDWÐCXÐXYÐZØ&Ð'?Ð&@ÐAñBóð ð (;�˜tÒ$ñ;ò	;ðS?;ðB �-ÐÐùòA ;ùãEùò0-s   žI;¶(J Ä:	Jc           	      óD  — |sy| j                   j                  }| j                  }|j                  «       D �]O  \  }}	|	|   }
| j                  |   }t        |
t        «      rÇ|
j                  d   }|t        «       k7  rŒ|j                  }|
j                  t        «       f¬«       t        |j                  |   «      }||xx   |
j                  j                  d«      z  cc<   t        j                   |«      }|
j#                  |«      }
n=|
j#                  |j                  |   «      }
n|
j#                  |j                  |   «      }
|r³|j$                  }t'        |dd«      r;|j(                  €J ‚t+        |
|j,                  |j(                  |j.                  «      }
n�|j0                  €J ‚t3        |
|j,                  |j4                  |j6                  j9                  «       |j0                  |j.                  «      }
n>|s<t;        j<                  d«      5  |
j?                  «       jA                  «       }
ddd«       |rFt;        j<                  t:        jB                  jD                  «      5  |
jG                  «       }
ddd«       |
|	|<   �ŒR y# 1 sw Y   ŒZxY w# 1 sw Y   ŒxY w)a,  
    Given a output state dict, ``output_states``, which the keys are FQNs to the
    original parameters (not FlatParameters nor parmeter 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+   rn   r*   r¹   r,   r]   r$   rŽ  r%   rh   Úredistributer5   ré   Údevice_meshrw   rI   rO   Úreshaper�   r‘   r’   r   r“   r”   r{   r   ro   r|   r•   r   rÏ   r‚   rƒ   rÐ   ÚD2Hr^   )rU   rv  r…   rX   rW   rY   rn   r„   r±   r|  r†   r»   Ú	placementÚplacement_dimÚreshape_sizerž   s                   r9   Ú_unflatten_orig_param_statesr–  „  sY  € ñ ØØ ×'Ñ'×2Ñ2€JØ ×&Ñ&€JØ,×2Ñ2Ó4ó 2+Ñˆˆ^Ø˜zÑ*ˆØ#×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Ø!×.Ñ.Ð:Ð:Ð:Ü*ØØ—O‘OØ×+Ñ+Ø×.Ñ.ó	‘ð "×/Ñ/Ð;Ð;Ð;Ü)ØØ—O‘OØ×)Ñ)Ø×-Ñ-×:Ñ:Ó<Ø×,Ñ,Ø×.Ñ.ó‘ñ Ü×'Ñ'¨Ó0ñ /ØŸ™›×,Ñ,Ó.�÷/ñ Ü×'Ñ'¬×(;Ñ(;×(?Ñ(?Ó@ñ $ØŸ	™	›�÷$à%*ˆ�zÓ"ñe2+÷X/ð /ú÷$ð $ús   ÈJ
É(JÊ
J	ÊJ	c                 ó
  — | j                   }|j                  dk(  r]t        j                  «       t        j                  j
                  k(  r.t        j                  d|j                  j                  «       «       |j                  «       D �ci c]  }|i “Œ }}t        | |||«      \  }	}
t        |
«      dk(  r|S | j                  j                  «       D ��cg c]  \  }}||v rdnd‘Œ }}}| j                  j                   }t#        j$                  t&        j(                  |	|j*                  ¬«      } ||j,                  «      }|j                  j/                  «        |
j                  «       D �]…  \  }}g }|j                  |j0                  j3                  «       z  }||j0                  j3                  «       z   dz
  }d\  }}t5        |j6                  |j8                  «      D ]ç  \  }}| xr | j:                  |    xr ||    }|s|r„|||z   dz
  }}||cxk  r|k  rn n||k\  r||z
  dz   n||z
  dz   }n=||cxk  r|k  rn n||k  r||z
  dz   n||z
  dz   }n||cxk  r|cxk  r|k  rn n|}nd}|r|j=                   ||«      «       |s6||   �,|j=                  t?        t&        j@                  ||   «      «       |dz  }||z  }Œé |j0                  j3                  «       tC        d	„ |D «       «      z
  }|jD                  |k(  sFJ d
|jD                  › d|› d|j0                  j3                  «       › d|j6                  › d|› d|› d�«       ‚|dkD  r|j=                   ||«      «       t'        jF                  |«      }|j3                  «       |jH                  z  |j3                  «       k(  sJ d«       ‚|j                  j/                  «        tK        jL                  tJ        jN                  jP                  «      5  t        jR                  |||jT                  ¬«       |j                  j/                  «        ddd«       |d|jV                  j3                  «        }| j                  } | jY                  |«      }!t        |!«      t        | j                  «      k(  sJ d«       ‚| j                  j                  «       D ]$  \  }}| j:                  |   s||v sŒ|!|   ||   |<   Œ& t[        | |||||«       �Œˆ ~|S c c}w c c}}w # 1 sw Y   ŒÍxY w)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 %sTFr¬   rk   )r   r   Nc              3   ó<   K  — | ]  }|j                  «       –— Œ y ­wr=   )r�   )Ú.0r  s     r9   ú	<genexpr>z/_allgather_orig_param_states.<locals>.<genexpr>>  s   è ø€ Ò1˜a�—‘—	Ñ1ù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.rl   zˆThe number of parameters from FlatParameter is not consistent to the number of states used by optimizer state dict reconstruction logic.).r*   r“   ry   Úget_debug_levelÚ
DebugLevelÚDETAILÚloggerr…  r|   Úmemory_summaryr?   rŒ  rÓ   r,   r¹   r+   rn   Ú	functoolsÚpartialrI   Úemptyrr   Ú_padded_unsharded_sizer}   Ú_sharded_sizer�   r  Ú_numels_with_paddingÚ_is_padding_maskr-   r–   r   rJ   ÚsumÚ_shard_numel_paddedÚcatro   r   rÏ   rÐ   Ú	ALLGATHERrz   r{   r€   Ú_get_unflat_views_alignedr–  )"rU   rs  rp  rX   rW   rY   r„   r±   rv  rN   r{  ÚidxÚhas_state_paramsrn   Ú
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"                                     r9   Ú_allgather_orig_param_statesrÀ  Ì  so  € ð !×&Ñ&€JØ‡�˜!Ò¤× 4Ñ 4Ó 6¼$¿/¹/×:PÑ:PÒ PÜ�‰ØNØ×%Ñ%×4Ñ4Ó6ô	
ð
 DP×CTÑCTÓCVÖ/W¸C°°R±Ð/W€MÐ/Wä2ØÐ,¨l¸MóÑ€Eˆ=ô ˆ=Ó˜QÒØÐð (×5Ñ5×;Ñ;Ó=÷$áˆC�ð �}Ñ$‰¨%Ñ/ð$Ðñ $ð !×'Ñ'×2Ñ2€JÜ×"Ñ"Ü�‰˜5¨×)BÑ)Bô€Jñ ! ×!BÑ!BÓC€Oà×Ñ×)Ñ)Ô+Ø,×2Ñ2Ó4ó r
Ñˆ
�GØ,.ˆØ—‘ *×":Ñ":×"@Ñ"@Ó"BÑBˆà�j×.Ñ.×4Ñ4Ó6Ñ6¸Ñ:ˆà $Ñˆ
�IÜ!$Ø×+Ñ+¨Z×-HÑ-Hó"
ò 8	 Ñˆ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8	 ðt (×5Ñ5×;Ñ;Ó=ÜÑ1 =Ô1Ó1ñ
Ðð ×-Ñ-Ð1CÒCð 	
ð#Ø#-×#AÑ#AÐ"Bð C"Ø"4Ð!5ð 6#Ø#-×#;Ñ#;×#AÑ#AÓ#CÐ"Dð E$Ø$.×$CÑ$CÐ#Dð EØ�G˜6 #  að)ó	
ÐCð  Ò!à× Ñ ¡Ð,>Ó!?Ô@Ü—i‘i Ó.ˆØ× Ñ Ó" Z×%:Ñ%:Ñ:¸o×>SÑ>SÓ>UÒUð 	
ðó	
ÐUð 	×!Ñ!×-Ñ-Ô/Ü×#Ñ#¤N×$7Ñ$7×$AÑ$AÓBñ 	4Ü×'Ñ'Ø °J×4LÑ4Lõð ×%Ñ%×1Ñ1Ô3÷	4ð *Ð*W¨J×,OÑ,O×,UÑ,UÓ,WÐXˆØ+×2Ñ2ÐØ'×AÑAÀ/ÓRˆÜ�;Ó¤3 ×'DÑ'DÓ#EÒEð 	
ðó	
ÐEð
 (×5Ñ5×;Ñ;Ó=ò 	B‰HˆC�Ø×2Ñ2°3Ò7¸3À-Ò;OØ1<¸SÑ1A�˜cÑ" :Ò.ð	Bô 	%ØØØØØØö	
ðWr
ðh 	ØÐùòe 0Xùó$÷X	4ð 	4ús   Â
S8ÃS=Ï:=TÔT	c                 óÎ  — | j                   }|j                  dk(  s|j                  t        j                  k(  r|r|S i S t        j                  t
        j                  j                  «      5  t        j                  t
        j                  j                  «      5  t        ||«      }ddd«       t        | ||||«      }ddd«       |r„| j                  j                  «       D ]e  \  }}	|v rŒ| j                  |	   sŒt        |› dt!        | j                  j#                  «       «      › dt!        |j#                  «       «      › d�«      ‚ S i S # 1 sw Y   Œ©xY w# 1 sw Y   Œ�xY w)a6  
    Given a optimizer state dict, ``input_states``, which the keys are FQNs to the
    original parameters (not FlatParameters nor parmeter 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.
    rk   NzB is not in the output state. The FSDPParamInfo has the param keys z, while the output_states has the param keys rÅ   )r*   ro   rp   r!   rq   r   rÏ   rÐ   rÑ   ÚALLGATHER_OBJru  rÀ  r,   r¹   r-   rÙ   r>   r?   )
rU   rp  rX   rW   rY   r„   rs  rv  rb   r­  s
             r9   Ú_gather_all_orig_param_staterÃ  t  sl  € ð !×&Ñ&€Jà×Ñ Ò"Ø×'Ñ'Ô+;×+DÑ+DÒDá&ˆ|Ð.¨BÐ.ä	×	Ñ	¤× 3Ñ 3× >Ñ >Ó	?ñ 

Ü×#Ñ#¤N×$7Ñ$7×$EÑ$EÓFñ 	RÜ"7¸
ÀLÓ"QÐ÷	Rä4ØØØØØØó
ˆ÷

ñ Ø'×5Ñ5×;Ñ;Ó=ò 	‰HˆC�Ø�mÑ#ØØ"×6Ñ6°sÒ;ØäØ�%ð 8ä˜/×7Ñ7×<Ñ<Ó>Ó?Ð@ð A8ä˜-×,Ñ,Ó.Ó/Ð0°ð	3óð ð	ð Ðàˆ	÷5	Rð 	Rú÷

ð 

ús$   Á,.EÂEÂ'EÅE	ÅEÅE$r^  c                 óÊ  — i }i }| D �]P  }	|j                  |	d «      }
|
€|	j                  sŒ%|	j                  rZ|	j                  d   }|j                  |d «      }|€ŒU|
€i n||
   }t        |«      |vri |t        |«      <   ||t        |«         |<   Œ‹|sŒŽt	        |	j                  «      dk(  sJ ‚|	j                  d   }t        j                  d«      5  t        t        t        t        f   |
«      }
t        j                  ||
   «      ||<   |rBt        ||   «      D ]1  \  }}t        j                  |«      sŒ|j                  «       ||   |<   Œ3 d d d «       �ŒS |j!                  «       D ]è  }t#        t%        |j'                  «       «      «      }||   }t	        |j(                  «      dkD  sJ d«       ‚|j*                  j-                  «       D ]e  \  }}||v rŒ|j(                  |   sŒt/        |› dt1        |j*                  j'                  «       «      › dt1        |j'                  «       «      › d�«      ‚ |j3                  t5        |||||«      «       Œê |S # 1 sw Y   �Œ[xY w)Nr   rk   Ú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Ô   rS   rR   ÚidrÓ   r   rÏ   r   r   r3   r4   rÕ   rA   rI   rg   r^   rÌ   r�   rË   r?   r-   r,   r¹   rÙ   r>   ÚupdaterÃ  )r^  rN  rÝ   r¿   rW   rX   rY   Úfsdp_osd_stateÚ
all_statesr_  rV  r±   rU   r*   rñ   r…   r†   Ú_all_statesrb   r­  s                       r9   Ú_convert_state_with_orig_paramsrË  ¦  sÂ  € ð &(€Nð
 -/€Jð 0ó &TˆØ+G×+KÑ+KØ˜Tó,
ˆ	ð Ð _×%DÒ%DØà×*Ò*Ø!×4Ñ4°QÑ7ˆCØ4×8Ñ8¸¸dÓCˆOØÐ&ð Ø#Ð+‘BÐ1AÀ)Ñ1LˆEÜ�/Ó"¨*Ñ4Ø24�
œ2˜oÓ.Ñ/Ø38ˆJ”r˜/Ó*Ñ+¨CÒ0âÜ�×9Ñ9Ó:¸aÒ?Ð?Ð?Ø /× BÑ BÀ1Ñ EÐÜ×'Ñ'Ð(@ÓAñ TÜ ¤¤s¬C x¡°)Ó<�	Ü48·I±IØ$ YÑ/ó5�Ð0Ñ1ñ Ü-9Ø&Ð'8Ñ9ó.ò TÑ)˜
 Eô  %Ÿ™¨uÔ5Ø$ØHMÏ	É	Ë˜Ð'8Ñ9¸*ÒEðT÷Tñ Tð7&TðT "×(Ñ(Ó*ò 
ˆÜ”4˜×(Ñ(Ó*Ó+Ó,ˆØ0°Ñ5ˆÜ�?×6Ñ6Ó7¸!Ò;ð 	
ð8ó	
Ð;ð (×5Ñ5×;Ñ;Ó=ò 	‰HˆC�Ø�kÑ!ØØ"×6Ñ6°sÒ;ØÜØ�%ð 8ä˜/×7Ñ7×<Ñ<Ó>Ó?Ð@ð A4ä˜+×*Ñ*Ó,Ó-Ð.¨að	1óð ð	ð 	×ÑÜ(ØØØØØóõ	
ð'
ð: Ð÷YTñ Tús   ÃA=IÉI"	c                 ón  — i }| D �],  }|j                  |d «      }	|	€J d|› d|	› �«       ‚|j                  rp|j                  d   }
||
   }t        |||	   |||«      }|sŒZt	        |«      t	        |j                  «      k(  sJ ‚t        |j                  |«      D ]
  \  }}|||<   Œ Œ¡|sŒ¤t	        |j                  «      dk(  sJ ‚|j                  d   }t        j                  ||	   «      ||<   |sŒët        ||   «      D ]1  \  }}t        j                  |«      sŒ|j                  «       ||   |<   Œ3 �Œ/ |S )NzQIf use_orig_params is False, we must be able to find the corresponding param id. r   r   rk   )rÔ   rS   rR   rc   rÓ   r  rÕ   rA   rI   rg   r^   )r^  rN  rÝ   r¿   rW   rX   rY   rÈ  r_  rV  r±   rU   Úunflat_staterñ   r`   r…   r†   s                    r9   Ú_convert_state_with_flat_paramsrÎ    s�  € ð &(€Nð 0ó (PˆØ+G×+KÑ+KØ˜Tó,
ˆ	ð Ð$ð 	
ð'Ø'6Ð&7°q¸¸ðEó	
Ð$ð
 ×*Ò*ð "×4Ñ4°QÑ7ˆCØ4°SÑ9ˆOÜ1ØØ  Ñ+ØØØóˆLò Ü˜<Ó(¬C°×0RÑ0RÓ,SÒSÐSÐSÜ=@Ø#×6Ñ6Ø ó>ò KÑ9Ð%Ð'9ð 9K�NÐ#4Ò5ñ	Kò
 Ü�×9Ñ9Ó:¸aÒ?Ð?Ð?Ø /× BÑ BÀ1Ñ EÐÜ04·	±	Ð:JÈ9Ñ:UÓ0VˆNÐ,Ñ-ÚÜ)5Ø"Ð#4Ñ5ó*ò PÑ%�J ô !Ÿ?™?¨5Ô1Ø ØDIÇIÁIÃK�NÐ#4Ñ5°jÒAòPðG(PðT Ðr8   c
                 óÖ  — t        j                  «        t        «       }
|
j                  t        j                  t         j
                  j                  «      «       t        t        j                  | «      «       | xs t        j                  |«      dk(  xs |}t        j                  d«      5  t        | «      }t        | «      }t        |«      }t        t         t"        t$        t&        f   t(        j*                  f   |rt-        | |«      nt/        || |||«      «      }t1        | «      }ddd«       t        j                  d«      5  t3        |||¬«      \  }}ddd«       t        j                  d«      5  |rt4        nt6        } ||d   |||	«      }ddd«       |si S di}t9        j;                  «       «      }|d   j=                  «       D ]2  \  }}||v rŒ||v rŒ|v rŒt?        j@                  d|› d	�«       |||<   Œ4 d
|v rtC        |«      |d
<   |
jE                  «        t        jF                  d«       |S # 1 sw Y   �ŒxY w# 1 sw Y   Œ÷xY w# 1 sw Y   ŒÆxY w)a
  
    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)r[  Ú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Æ   z$FSDP _optim_state_dict() profiling: )$r   rÈ   r   Úenter_contextrÏ   rÐ   ÚALLr    Útraversal_utilsÚ_get_fsdp_handlesry   r§   r   r  rk  r   r2   r   r4   r3   r~   r   r5  rI  rÊ   rc  rË  rÎ  rÍ   rÌ   r¹   r×   rØ   rh  ÚcloserÚ   )rÀ   rÂ   r¿   r  rÃ   rX   rm   r  rÁ   rY   ÚcmrW   rÜ   r  r  rG  rÝ   r^  rN  Ú
convert_fnrÈ  Úfsdp_osdÚflat_param_fqnsrb   r†   s                            r9   Ú_optim_state_dictrÜ  :  s“  € ôD ×ÑÔÜ	‹€BØ×Ñ”^×+Ñ+¬N×,?Ñ,?×,CÑ,CÓDÔEÜ)¬/×*KÑ*KÈEÓ*RÔSØˆnÒH¤§¡¨eÓ 4¸Ñ 9ÒH¸[€Gä	×	Ñ	 Ó	0ñ DÜ*¨5Ó1ˆÜ2°5Ó9ÐÜ0Ð1AÓBÐä!Ü””sœC�x‘¤"§,¡,Ð.Ñ/ñ %ô 8¸¸{ÔKä,Ø˜5Ð"4°mÐEVóó	
Ðô "=¸UÓ!CÐ÷Dô" 
×	Ñ	Ð 9Ó	:ñ 
ô )ØØØØØ"Ø&ô
ñ	
Ø Ø(÷
ô 
×	Ñ	Ð 2Ó	3ñ 
ñ õ ,ä0ð 	ñ
 $Ø Ø(Ø"Ø˜WÑ%ØØØó
ˆ÷
ñ$ Øˆ	à '¨Ð8€HäÐ+×2Ñ2Ó4Ó5€OØ& wÑ/×5Ñ5Ó7ò $‰
ˆˆUØ�.Ñ ØØ�/Ñ!ØØÐ$Ñ$Øô 	�‰Ø# C 5ð )Lð Lô	
ð $ˆ�sÒð%$ð( Ð)Ñ)Ü#:ØÐ0°-ó$
ˆ�Ñ ð ‡H�H„JÜ×!Ñ!Ð"HÔIà€O÷eDñ Dú÷"
ð 
ú÷
ð 
ús%   Â/A<IÅIÅ: IÉIÉIÉI(c                 ót   — d„ }d„ }i }t        | ||t        | «      D ��cg c]  \  }}|‘Œ	 c}}|«      S c c}}w )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                 óÒ  — t        | «      }|€y t        || «       t        || «      }|sy |j                  }t	        ||i g «      }t        |j                  «      D ]Œ  \  }}	t        ||	z   «      }
|
|v r"||
   j                  j                  |u sJ |
«       ‚|||
<   ||j                  |
<   |j                  €Œ[|j                  j                  |j                  |   j                  «       ŒŽ y r=   )r   r   r   rn   r)   r+  Ú_fqnsr   r+   r,   Ú_paramsr-   r–   Úrequires_grad)r9  r:  r;  Úfqn_to_param_infor„   r+   rn   rU   r­  Ú	local_fqnr±   s              r9   r=  z._get_fqn_to_fsdp_param_info.<locals>.module_fná  s÷   € ÜCÀFÓKˆ
ØÐØÜ�:˜vÔ&Ü 
¨FÓ3ˆÙØØ×&Ñ&ˆ
Ü'¨
°F¸BÀÓCˆô (¨
×(8Ñ(8Ó9ò 		‰NˆC�Ü# F¨YÑ$6Ó7ˆCØÐ'Ñ'Ø(¨Ñ-×4Ñ4×?Ñ?À:ÑMÐRÈsÓRÐMØ%4Ð˜cÑ"Ø14ˆO×)Ñ)¨#Ñ.Ø×!Ñ!Ñ-Ø×3Ñ3×:Ñ:Ø×&Ñ& sÑ+×9Ñ9õñ		r8   c                 ó   — | S r=   r7   )râ  s    r9   r?  z._get_fqn_to_fsdp_param_info.<locals>.return_fnø  r@  r8   rA  )rÀ   r=  r?  râ  r±   r™   s         r9   rÊ   rÊ   ×  sL   € òò.!ð 35Ðô ØØØÜ<¸UÓC×D‘��aŠÓDØóð ùó 	ErC  Ústate_dict_settingsc                 óš   — t        | dd «      r>|j                  }|t        j                  k(  rt	        ddd«      ‚d|j
                  _        y y )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      r9   Ú_set_optim_use_dtensorrê    sW   € ô ˆz˜>¨4Ô0Ø-×=Ñ=ˆØœm×<Ñ<Ò<ÜØ9ØEØ]óð ð HLÐ×7Ñ7ÕDð 1r8   )FNFN)Fr=   )NFNN)T)FT){rÕ   r¡  Úloggingr×   Úcollections.abcr   r   r   Ú
contextlibr   Údataclassesr   r   Ú	itertoolsr	   Útypingr
   r   r   r   r   r   r   rI   Útorch.distributedÚdistributedry   Ú'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)   r2   r3   rT   rA   rC   rL   rQ   r6   r5   rc   ri   r[   r\   ÚProcessGrouprª   r°   r¾   ÚModulerÂ   Ú	Optimizerrç   rÒ   rJ   rO   rë   rí   rî   r   r)  r4   r5  r  rI  r  r  rZ  rc  rh  rk  rm  ru  rN   rŒ  r–  rÀ  rÃ  rË  rÎ  Úno_gradrÜ  rÊ   rê  r7   r8   r9   ú<module>r     s  ðã Û Û Û ß 8Ñ 8Ý  ß (Ý ß W× WÑ Wã Ý  ß AÓ AÝ Ý BÝ E÷÷ ñ õ ?ß M÷÷÷ñ ÷
 8Ý -ñ ÝEð 
ˆ×	Ñ	˜8Ó	$€ð ÷$ð $ó ð$ð˜T # s (™^ð °¸¸sÀC¸x¹Ñ0Ió ð ÷Cð Có ðCô2˜
ô ô �Zô ð4Ø"ð4à˜3 ˜8‘nð4ð ð4ð ð	4ð
 ð4ð 
ˆ$ˆs�Cˆx‰.Ñó4ðn/˜3ð / 4ó /ðCØ"ðCà˜3 ˜8‘nðCð óCðLJØ"ðJà"ðJð ðJð 
ˆ$ˆs�Cˆx‰.Ñó	JðZØðà�c˜3�h‘ðð �D×%Ñ%Ñ&ðð 
ˆ#ˆsˆ(�^ó	ð&ØðØ#&ðØ/7¸×8IÑ8IÑ/Jðàóð.#Ø"ð#à	ð#ð �c˜3�h‘ð#ð 
ˆ#ˆsˆ(�^ó	#ðR "Ø-1ØØ)-ñL)Ø˜3 ˜8‘nðL)à�9‰9ðL)ð ðL)ð �E—K‘K×)Ñ)Ñ*ð	L)ð
 ðL)ð �D×%Ñ%Ñ&ðL)ð 
ˆ#ˆsˆ(�^óL)ð^FØ"ðFà˜3  S¨# X¡Ð.Ñ/ðFð ˜S™	ðFð 
ˆ#ˆsˆ(�^ó	FðRQØðQà˜%Ÿ,™,Ñ'ðQð ˜S™	ðQð " %§*¡*Ñ-ð	Qð
 ðQð ‡\�\óQðh3HØð3Hà˜5Ÿ<™<Ñ(ð3Hð ˜S™	ð3Hð ‡\�\ó	3Hðl$Øð$à�c‘ð$ð ˜S™	ð$ð 	ó	$ðd  %ñM,Ø�c˜3�h‘ðM,à�9‰9ðM,ð �;‰;× Ñ ðM,ð ØØ��c˜3�h‘Ñ Ø�R—\‘\Ñ"ð$ñ	
ñð	M,ð ðM,ð ðM,ð 
ˆ#ˆsˆ(�^óM,ðn 	ñH.Ø�9‰9ðH.àØØ��c˜3�h‘Ñ Ø�R—\‘\Ñ"ð$ñ	
ñðH.ð 
ˆ#ˆr�|‰|Ð
ÑóH.ðV" %§(¡(§/¡/ð "°d¸=È#Ð;MÑ6Nó "ðN "&Ø$Ø=AØ<@ñ0Ø�;‰;× Ñ ð0à�B—I‘IÑð0ð ð0ð ˜D §¡¨t°C©yÐ!8Ñ9Ñ:ð	0ð
    ]°CÐ%7Ñ 8Ñ9ð0ð 
ˆ%��S�‰/˜2Ÿ<™<Ð
'Ñ(ó0ðj "&Ø$Ø=AØ<@ñNØ�;‰;× Ñ ðNà�B—I‘IÑðNð ðNð ˜D §¡¨t°C©yÐ!8Ñ9Ñ:ð	Nð
    ]°CÐ%7Ñ 8Ñ9ðNð 
ˆ"�,‰,˜˜c 3˜h™Ð
'Ñ(óNð2 	ñNØ�9‰9ðNàØØ��c˜3�h‘Ñ Ø�R—\‘\Ñ"ð$ñ	
ñðNð 
ˆ"�,‰,˜Ð
ÑóNð'&Ø˜nÑ-ð'&à"& ~°u¸SÀ#¸X±Ð'FÑ"Gð'&ð ˜U 3¨ 8™_¨b¯l©lÐ:Ñ;ð'&ð �D×%Ñ%Ñ&ð	'&ð
 
ó'&ð` ñ<>Ø˜3 ˜8‘nð<>à�D×%Ñ%Ñ&ð<>ð ˜U 3¨ 8™_¨b¯l©lÐ:Ñ;ð<>ð ˜Ÿ™ d¨3¡iÐ/Ñ0ð	<>ð
 !  mÐ!3Ñ4ð<>ð ð<>ð ˆ4�Ñ  n°e¸CÀ¸H±oÐ&EÑ!FÐFÑGó<>ð~Ø�S˜#�X‘ðà˜U 3¨ 8™_¨b¯l©lÐ:Ñ;ðð ˜Ÿ™ d¨3¡iÐ/Ñ0ðð 
ˆ$ˆs�Cˆx‰.Ñó	ð, ¨$¨s°C¨x©.ð  ¸Tó  ð& ÷ ð  ó ð ð"Øð"à�s˜C�x‘.ð"ð 
ˆ$ˆs�Iˆ~Ñ
Ñó"ðJP Ø"ðP à˜d 3¨	 >Ñ2Ñ3ðP ð �s˜C�x‘.ðP ð ˜˜T # s (™^Ð+Ñ,ð	P ð
 ˆ8�E—K‘KÑ  $ s¨D°¸%¿,¹,Ñ1GÑ,HÐ'HÑ"IÐIÑJóP ðfE+Ø"ðE+à˜˜T # s (™^Ð+Ñ,ðE+ð ðE+ð ð	E+ð
 ðE+ð ðE+ð 
óE+ðPeØ"ðeà˜d 3¨	 >Ñ2Ñ3ðeð �s˜C�x‘.ðeð ð	eð
 ðeð ðeð 
ˆ#ˆt�C˜�H‰~Ð
ÑóeðP/Ø"ð/à�s˜C�x‘.ð/ð ð/ð ð	/ð
 ð/ð 
ˆ#ˆsˆ(�^ó/ðr ñXØ˜~Ñ.ðXà"& ~°u¸SÀ#¸X±Ð'FÑ"GðXð !  mÐ!3Ñ4ðXð ˜5  c ™?¨CÐ/Ñ0ð	Xð
 ðXð ðXð ðXð 
ˆ#ˆsˆ(�^óXðD ñ6Ø˜~Ñ.ð6à"& ~°u¸SÀ#¸X±Ð'FÑ"Gð6ð !  mÐ!3Ñ4ð6ð ˜5  c ™?¨CÐ/Ñ0ð	6ð
 ð6ð ð6ð ð6ð 
ˆ#ˆsˆ(�^ó6ðr €‡�ƒð "ØñYØ�9‰9ðYà�;‰;× Ñ ðYð ˜3 ˜8‘nðYð ØØ��c˜3�h‘Ñ Ø�R—\‘\Ñ"ð$ñ	
ñð	Yð ðYð ðYð �D×%Ñ%Ñ&ðYð ðYð ðYð ðYð  
ˆ#ˆsˆ(�^ò!Yó ðYðx. r§y¡yð .°T¸#¸}Ð:LÑ5Mó .ðb ðLØðLà*ðLð 
òLó ñLr8   