o
    Ti:                     @   sH  d dl Z d dlZd dlZd dlZd dlmZmZ d dlZd dl	Z	ddl
mZ dd Zdd Zd	d
 Zdd Zdd Zdd Zdd Zg fddZdefddZdefddZdd ZdefddZdd  Zg fd!d"Zg fd#d$Zd%efd&d'Zd8d%efd(d)Zd9defd,d-Zdefd.d/Zd0e d1e!fd2d3Z"d:d4d5Z#d:d6d7Z$dS );    N)GRADIENT_ACCUMULATION_STEPSTRAIN_MICRO_BATCH_SIZE_PER_GPU   )loggerc                 C   s   t j| sdS t| 4}|D ](}dD ]#}||}|dkr6||t| d  d    W  d    S qqW d    d S 1 sCw   Y  d S )Nstderr.log does not exist)ErrorerrorERRORz: )ospathexistsopenfindlenlstripfilenameflinesidx r   N/home/ubuntu/.local/lib/python3.10/site-packages/deepspeed/autotuning/utils.pysearch_error   s    

 
r   c                 C   sp   t j| sdS t| "}|D ]}d}||}|dkr% W d    dS qW d    dS 1 s1w   Y  dS )Nr   KeyboardInterruptr
   TF)r   r   r   r   r   r   r   r   r   was_interruptted   s   


r   c                 C   s   t | ts	t| S td| }|D ];}|dd }|dkr q||v s.J d| d| t || tr>| ||| } qt|dksHJ d|| } q| S )	Nz\$[\w]+$ 	nvme_pathzunknown var key: z, in    z-unable to replace multiple non-string matches)
isinstancestrrefindallreplacelowerr   )valuereplace_dictmatchesvarvar_keyr   r   r   find_replace_str)   s   

r,   c                 C   s   t | tr=|  D ]1\}}t |trt||| |< t |tr0tt|D ]}t|| |||< q$t |tr:t|| q	d S t | trVtt| D ]}tt| | || |< qHd S d S N)	r!   dictitemsr"   r,   listranger   find_replace)targetr(   keyr'   ir   r   r   r2   ;   s    





r2   c                 C   s   t | ts| gS | S r-   )r!   r0   )valr   r   r   get_listJ   s   
r7   c                    s   |  D ]?\}t|tjjrt i | < q vr$| < qt  ts2  g <    fddt	|D  q S )Nc                 3   s     | ]}|  vr|V  qd S r-   r   ).0r5   dkr   r   	<genexpr>[   s    zcombine_dict.<locals>.<genexpr>)
r/   r!   collectionsabcMappingcombine_dictgetr0   extendr7   )r:   uvr   r9   r   r@   Q   s   
$r@   c                 C   s@   | |v r	|| = dS |  D ]\}}t|tjjrt| | qdS )zDeletes a key from a dictionary if it exists.

    Args:
        t (string): target key to delete
        d (dict): dictionary to delete from
    N)r/   r!   r=   r>   r?   del_if_exists)tr:   r;   rD   r   r   r   rE   _   s   
rE   c                 C   sj   |dur3|  D ]*\}}||vr2|du rt||  qt|tjjr.t| |i ||| |< q|| |< q| S )a  Replaces values in dict d with values in dict u.

    Args:
        d (dict): the target dict to overwrite
        u (dict): the dict containing the values to overwrite the target dict

    Returns:
        dict d with values overwritten by the corresponding ones in dict u.
    N)r/   rE   r!   r=   r>   r?   r(   rA   )r:   rC   ignored_keysr;   rD   r   r   r   r(   n   s   

r(   r:   c                 C   s:   || v r| | S |   D ]}t|trt||  S qd S r-   )valuesr!   r.   get_val_by_key)r:   r;   rD   r   r   r   rI      s   
rI   c                 C   s8   || v r|| |< |   D ]}t|trt||| qd S r-   )rH   r!   r.   set_val_by_key)r:   r;   vvrD   r   r   r   rJ      s   
rJ   c           	      C   s   t j| std d S t| dX}t }| D ]F}|	 }|dkr&qz|
 \}}|
d\}}t|}W n tyL } ztd |d }~ww ||v r]td td||||< qW d    |S 1 smw   Y  |S )NzNUnable to find hostfile, will proceed with training with local resources only.rr   =zEHostfile is not formatted correctly, unable to proceed with training.zCHostfile contains duplicate hosts, unable to proceed with training.zhost {} is already defined)r   r   isfiler   warningr   r=   OrderedDict	readlinesstripsplitint
ValueErrorr   format)	hostfile_pathfdresource_poolr   hostnameslots_
slot_counterrr   r   r   fetch_hostfile   s6   




r_   configc                 C   s   dt fdd}| di }|sdS |d}d}|dkrdS |d	kr/||d
r.||dr.dS n%|dkrRddg}|di d|v rDd}|di d|v rQd}ndS |r]| ds]dS dS )Nr`   c                 S   s   | d u rdS t | |S NF)boolrA   )r`   r4   r   r   r   is_False   s   z$validate_ds_config.<locals>.is_Falsezero_optimizationTstageFr    r   cpu_offloadcpu_offload_params   cpunvmeoffload_optimizerdeviceoffload_param	optimizer)r.   rA   )r`   rc   config_zerore   offloadoffload_devicesr   r   r   validate_ds_config   s.   
rr   c                 C   s$   dd | D }t |}dd |D S )aF   Removes duplicate dictionaries from a list. Uses list comprehension and the json library to sort and stringify each dictionary and the set data type to ensure unique values. Works with nested data structures.

    Args:
        l (list): a list of (nested) data structures.

    Returns:
        A list of unique values.
    c                 S   s   g | ]	}t j|d dqS )T)	sort_keys)jsondumps)r8   r:   r   r   r   
<listcomp>   s    z%remove_dupe_dicts.<locals>.<listcomp>c                 S   s   g | ]}t |qS r   )rt   loads)r8   r   r   r   r   rv      s    )set)llist_of_stringsr   r   r   remove_dupe_dicts   s   	r{   c                    s6   |r|D ]}dt dtf fdd  | | qdS dS )z Prunes the input configurations

    Args:
        configs (dict): A configuration dictionary.
        ignored_keys (list, optional): the keys of the sections to delete. Defaults to [].

    Returns:
        A configuration dictionary.
    r:   r;   c                    s8   || v r	| |= d S |   D ]}t|tr || qd S r-   )rH   r!   r.   )r:   r;   ddfind_del_keyr   r   r~      s   


z"prune_config.<locals>.find_del_keyN)r.   r"   )r`   rG   r;   r   r}   r   prune_config   s   
r   c                 C   s*   g }| D ]}t || || qt|S )a   Prunes the input list of configurations

    Args:
        configs (list): A list of configuration dictionaries.
        ignored_keys (list, optional): the keys of the sections to delete. Defaults to [].

    Returns:
        A list of valid and unique configuration dictionaries.
    )r   appendr{   )configsrG   pruned_listr`   r   r   r   prune_configs   s
   

r   tuning_spacec                 C   sR   g }|   D ] \}}t|tr|t| t|tr&t|dkr&|| q|S )zOutputs the list of tunable parameters in the tuning space dict.

    Args:
        tuning_space (dict): a configuration dictionary containing tunable parameters as lists of values.

    Returns:
        A list of strings
    r    )r/   r!   r.   rB   get_tuning_keysr0   r   r   )r   tuning_keysr4   r6   r   r   r   r     s   	

r   c                    sd   dt f fdd g }i }|D ]}| |i ||< t||  q | D ]}t|| || q#|S )z Splits the tuning space dictionary to result in all combinations of values.

    Args:
        tuning_space (dict): the tuning space where tunable parameters are lists of values.
    r:   c                 3   sd    |   |  }}|D ]
}t|ts|g}q fdd|D }tj| D ]
}tt||V  q%d S )Nc                 3   s*    | ]}t |tr |nt|V  qd S r-   )r!   r.   r7   )r8   rD   gen_combinationsr   r   r<   ,  s   ( z<get_all_configs.<locals>.gen_combinations.<locals>.<genexpr>)keysrH   r!   r0   	itertoolsproductr.   zip)r:   r   rH   rD   values_choicescombr   r   r   r   '  s   
z)get_all_configs.<locals>.gen_combinations)r.   rA   rE   r(   r   )r   ignore_keysall_configsignored_key_valsikcr   r   r   get_all_configs   s   	
r   r   Fc                    sn   t |vr	|t  t|vr|t |  dd ddtf fdd  | ||d}||d	kr4| S d
 S )a   Generates a name from the acronyms of the tuning keys in the config dict. TRAIN_MICRO_BATCH_SIZE_PER_GPU is always included in the tuning keys.
    Args:
        config (dict): the config dict used to generate the name
        tuning_keys (list, optional):  the tuning keys used to generate the name. Defaults to None.
        prefix (str, optional): a string added to the beginning of the name. Defaults to None.
    c                 S   s   d}| d u rdS |   D ]?\}}dtdd |d}t|ts't|tr7|dkr7||d| d 7 }qt|trB|r@dnd	}|| | d7 }q|S )
Nr   None_c                 S      | d S Nr   r   r   r   r   r   <lambda>M      z:canonical_name.<locals>.get_offload_name.<locals>.<lambda>r\   (#  {:.1e}TF)	r/   joinmaprS   r!   rT   floatrV   rb   )offload_configcnamer4   r6   r   r   r   get_offload_nameH  s   
z(canonical_name.<locals>.get_offload_nameNFr`   c                    sB  d}|r| d u r
|S |   D ]\}}|dkrq|dkr(|d7 }|s'||7 }q|dkr9|d7 }|s8||7 }qt|trO |||d}|dkrO||d 7 }|rV||vrVqdtd	d
 |d}|st|tsot|tr|dkr||d| d 7 }qt|t	r|rdnd}|| | d7 }q||d 7 }q|d d S )Nr   arg_mappingsrm   op_rk   oo_omit_valr\   c                 S   r   r   r   r   r   r   r   r   p  r   z:canonical_name.<locals>.get_name_by_keys.<locals>.<lambda>r   r   r   r   r
   )
r/   r!   r.   r   r   rS   rT   r   rV   rb   )r`   r   r   r   r4   r6   nkey_strget_name_by_keysr   r   r   r   V  s>   

z(canonical_name.<locals>.get_name_by_keysr   r   expra   )r   r   r   sortr.   )r`   r   prefixr   namer   r   r   canonical_name;  s   

(r   c                 C   sr   | sd S t | }| D ])\}}t|tr%|dkr|||< nt|||< t|tr6t|dkr6|d ||< q|S )Nrn   r   )copydeepcopyr/   r!   r.   get_first_configr0   r   )r`   cfgr4   r6   r   r   r   r     s   


r   expsexps_dirc              	   C   sn   g }| D ]0}|d }t j|| d}t|d}t|| || W d    n1 s/w   Y  q|S )Nr   z.jsonw)r   r   r   r   rt   dumpr   )r   r   	exp_pathsr   exp_nameexp_pathrX   r   r   r   write_experiments  s   r   c                 C   sL  |d u rV| d dkrt t| d |d | S | d dkr*t t| d |d | S | d dkr=t t| d	 |d
 | S | d dkrPt t| d |d | S t | d S |dkrgt t| d |d | S |d| krzt t| d |d | S |d| krt t| d	 |d | S |d| krt t| d |d | S t | d S )Nl    J)r   l        z T ʚ;i   @z G@B i    M  i   K r   GMKi   r"   roundr   postfixunits	precisionr   r   r   memory_to_string  s&   r   c                 C   s  |d u rC| d dkrt t| d |d | S | d dkr*t t| d |d | S | d dkr=t t| d |d | S t | d S |d	| krVt t| d |d | S |d
| krit t| d |d | S |d| kr|t t| d |d | S t | d S )Nr   r   z Br   r   r   r   r   Br   r   r   r   r   r   r   number_to_string  s   r   r-   )Nr   F)r   Nr   )%r#   collections.abcr=   r   rt   deepspeed.runtime.constantsr   r   r   r   utilsr   r   r   r,   r2   r7   r@   rE   r(   r.   rI   rJ   r_   rr   r{   r   r   r   r   r   r   r0   r"   r   r   r   r   r   r   r   <module>   s<   	!H
