o
    Ti!                     @   s   d Z ddlZddlZddlZddlmZ ddlmZmZm	Z	 ddl
mZ G dd deZdd	 ZG d
d deZG dd dejZG dd deZdd Zdd Zdd Zdd ZdS )z1
Collection of DeepSpeed configuration utilities
    N)reduce)	BaseModel
ConfigDictfield_serializer)loggerc                	       sh   e Zd ZdZd fdd	Zdd Zdd Zed	d	d	d	d
d	ddZe	dddde
jdefddZ  ZS )DeepSpeedConfigModela  
    This class should be used as a base for all DeepSpeed configs. It extends
    pydantic.BaseModel to allow for deprecated fields. To enable this feature,
    add deprecated=True to pydantic.Field:

    my_dep_field: int = Field(0, deprecated=True)

    Deprecated Field kwargs:
    - deprecated: [True|False], default False
        Enables / Disables deprecated fields
    - deprecated_msg: str, default ""
        Message to include with deprecation warning
    - new_param: str, default ""
        Name of the field replacing the deprecated field
    - set_new_param: [True|False], default True
        If new_param is provided, enables setting the value of that param with
        deprecated field value
    - new_param_fn: callable, default (lambda x: x)
        If new_param is provided and set_new_param is True, this function will
        modify the value of the deprecated field before placing that value in
        the new_param field

    Example:
        my_new_field is replacing a deprecated my_old_field. The expected type
        for my_new_field is int while the expected type for my_old_field is
        str. We want to maintain backward compatibility with our configs, so we
        define the fields with:

        class MyExampleConfig(DeepSpeedConfigModel):
            my_new_field: int = 0
            my_old_field: str = Field('0',
                                      deprecated=True,
                                      new_param='my_new_field',
                                      new_param_fn=(lambda x: int(x)))
    Fc                    s4   |sdd |  D }t jdi | |   d S )Nc                 S   s&   i | ]\}}|d ks|dkr||qS )autoreplace_method .0kvr
   r
   R/home/ubuntu/.local/lib/python3.10/site-packages/deepspeed/runtime/config_utils.py
<dictcomp>8   s   & z1DeepSpeedConfigModel.__init__.<locals>.<dictcomp>r
   )itemssuper__init___deprecated_fields_check)selfstrictdata	__class__r
   r   r   6   s   zDeepSpeedConfigModel.__init__c              
   C   s  | }|j }t|j| j}|ddd }|t||}|dd}|dd}||v rtd| d|r;d	| d
nd |rDd| nd  |r|ddrzt|| W n t	yn }	 zt
d| d |	d }	~	ww |d}
t|
dkrtt|
d d |}|j }|
d }||vsJ d| d| dz	t||| W d S  t	y }	 zt
d| d| d |	d }	~	ww d S d S d S )Nnew_param_fnc                 S   s   | S Nr
   )xr
   r
   r   <lambda>A   s    z@DeepSpeedConfigModel._process_deprecated_field.<locals>.<lambda>	new_param deprecated_msgzConfig parameter z is deprecatedz use z insteadz. set_new_paramTzTried removing deprecated 'z' from config.   z%Cannot provide deprecated parameter 'z' and replacing parameter 'z
' togetherzTried setting value for 'z' with value from deprecated '')model_fields_settypemodel_fieldsjson_schema_extragetgetattrr   warningdelattr	Exceptionerrorsplitlenr   setattr)r   	dep_fieldpydantic_config
fields_setkwargsr   param_value	new_fielddep_msgenew_param_nestednew_param_namer
   r
   r   _process_deprecated_field<   sL   

z.DeepSpeedConfigModel._process_deprecated_fieldc                 C   s:   | j }| D ]\}}|jr|jddr| | qd S )N
deprecatedF)r(   r   r)   r*   r=   )r   fields
field_name
field_infor
   r
   r   r   c   s   
z-DeepSpeedConfigModel._deprecated_fields_checkTforbidr
   )validate_defaultvalidate_assignmentuse_enum_valuespopulate_by_nameextraarbitrary_types_allowedprotected_namespacesdtype)check_fieldsreturnc                 C   s   t | S r   )str)rJ   r
   r
   r   serialize_torch_dtypes   s   z*DeepSpeedConfigModel.serialize_torch_dtype)F)__name__
__module____qualname____doc__r   r=   r   r   model_configr   torchrJ   rM   rN   __classcell__r
   r
   r   r   r      s     $'

r   c                 C   sN   || j v sJ d| d|  | j | rJ d| d| j | S )Nr%   z' is not a field in z7' is a required field and does not have a default value)r(   r*   is_requiredget_default)configr@   r
   r
   r   get_config_defaultx   s   
rY   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )pp_intz
    A wrapper for integers that will return a custom string or comma-formatted
    string of the integer. For example, print(pp_int(1e5)) will return
    "10,000". This is useful mainly for auto-generated documentation purposes.
    Nc                    s   t  | |}||_|S r   )r   __new__custom_print_str)clsvalr\   instr   r
   r   r[      s   zpp_int.__new__c                 C   s   | j r| j S | jdS )N,)r\   realr   r
   r
   r   __repr__   s   
zpp_int.__repr__r   )rO   rP   rQ   rR   r[   rc   rU   r
   r
   r   r   rZ      s    rZ   c                       s"   e Zd ZdZd fdd	Z  ZS )ScientificNotationEncodera  
    This class overrides ``json.dumps`` default formatter.

    This version keeps everything as normal except formats numbers bigger than 1e3 using scientific notation.

    Just pass ``cls=ScientificNotationEncoder`` to ``json.dumps`` to activate it

    Fr   c                    s   j d urj nd}d  | } d7  d  | t|tr%|r#dS dS t|ts/t|tr:|dkr7|dS | S t|tjjr\ fdd	| D }d
d	| d|  d S t|tjj
rut|tsudd	tj| dS d	t ||S )N    r#   truefalseg     @@r:   c                    s0   g | ]\}}d  d| dj | d qS )
"z": )level)
iterencoder   rk   prefixr   r
   r   
<listcomp>   s   0 z8ScientificNotationEncoder.iterencode.<locals>.<listcomp>{z, ri   }[]z
, )indent
isinstanceboolfloatintcollectionsabcMappingr   joinSequencerM   maprl   r   )r   o	_one_shotrk   rt   prefix_closer   r   rm   r   rl      s    
z$ScientificNotationEncoder.iterencode)Fr   )rO   rP   rQ   rR   rl   rU   r
   r
   r   r   rd      s    	rd   c                   @   s    e Zd ZdZdd Zdd ZdS )DeepSpeedConfigObjectz 
    For json serialization
    c                 C   s   | j S r   )__dict__rb   r
   r
   r   repr   s   zDeepSpeedConfigObject.reprc                 C   s   t j| jddtdS )NTre   )	sort_keysrt   r]   )jsondumpsr   rd   rb   r
   r
   r   rc      s   zDeepSpeedConfigObject.__repr__N)rO   rP   rQ   rR   r   rc   r
   r
   r
   r   r      s    r   c                 C      |  ||S r   r*   
param_dict
param_nameparam_default_valuer
   r
   r   get_scalar_param      r   c                 C   r   r   r   r   r
   r
   r   get_list_param   r   r   c                 C   r   r   r   r   r
   r
   r   get_dict_param   r   r   c                 C   sZ   t dd | D }t|t| kr+tdd | D }dd | D }td||S )zReject duplicate keys.c                 s   s    | ]	\}}||fV  qd S r   r
   r   r
   r
   r   	<genexpr>   s    z5dict_raise_error_on_duplicate_keys.<locals>.<genexpr>c                 S   s   g | ]}|d  qS )r   r
   )r   pairr
   r
   r   ro      s    z6dict_raise_error_on_duplicate_keys.<locals>.<listcomp>c                 S   s   g | ]
\}}|d kr|qS )r#   r
   )r   keyvaluer
   r
   r   ro      s    z&Duplicate keys in DeepSpeed config: {})dictr1   ry   Counterr   
ValueErrorformat)ordered_pairsdcounterkeysr
   r
   r   "dict_raise_error_on_duplicate_keys   s   r   )rR   ry   r   rT   	functoolsr   pydanticr   r   r   deepspeed.utilsr   r   rY   rx   rZ   JSONEncoderrd   objectr   r   r   r   r   r
   r
   r
   r   <module>   s    g