o
    }oi0                     @   s   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	 dZ
zd dlmZmZmZ W n ey7   dZ
Y nw 	ddd	d
ddefddZddd
ddedefddZddd
ddefddZ		ddddddeee  deeeef  fddZdS )    N)is_dataclass)DictListOptional)loggingT)
DictConfig	OmegaConf	open_dictF	model_clsz#nemo.core.config.modelPT.NemoConfig
update_cfgr   drop_missing_subconfigsc                 C   sH  t std td t| st| tstdt|ts"t	|}t| r+t
| } t| |d|d} t| |d|d} t| |d|d} t| |d|d} t| |dd	} d
|jv rwd
| jvrwt|j |jd
 W d   n1 srw   Y  d|jv rd| jvrt|j |jd W d   n1 sw   Y  t| |}|S )a\  
    Helper class that updates the default values of a ModelPT config class with the values
    in a DictConfig that mirrors the structure of the config class.

    Assumes the `update_cfg` is a DictConfig (either generated manually, via hydra or instantiated via yaml/model.cfg).
    This update_cfg is then used to override the default values preset inside the ModelPT config class.

    If `drop_missing_subconfigs` is set, the certain sub-configs of the ModelPT config class will be removed, if
    they are not found in the mirrored `update_cfg`. The following sub-configs are subject to potential removal:
        -   `train_ds`
        -   `validation_ds`
        -   `test_ds`
        -   `optim` + nested `sched`.

    Args:
        model_cls: A subclass of NemoConfig, that details in entirety all of the parameters that constitute
            the NeMo Model.

        update_cfg: A DictConfig that mirrors the structure of the NemoConfig data class. Used to update the
            default values of the config class.

        drop_missing_subconfigs: Bool which determins whether to drop certain sub-configs from the NemoConfig
            class, if the corresponding sub-config is missing from `update_cfg`.

    Returns:
        A DictConfig with updated values that can be used to instantiate the NeMo Model along with supporting
        infrastructure.
    @This function requires Hydra/Omegaconf and it was not installed.   z@`model_cfg` must be a dataclass or a structured OmegaConf objecttrain_ds)subconfig_keyr   validation_dstest_dsoptim)r   targetNnemo_version)
_HAS_HYDRAr   errorexitr   
isinstancer   
ValueErrorr   create
structured_update_subconfig_add_subconfig_keysmodelr	   popmerge)r
   r   r   	model_cfg r#   K/home/ubuntu/.local/lib/python3.10/site-packages/nemo/utils/config_utils.pyupdate_model_config   sD   







r%   r"   r   c                 C   s   t std td t| jE ||jv r#|| jvr#|j| | j|< ||jvr=|| jv rE|rM| j| W d   | S W d   | S W d   | S W d   | S 1 sXw   Y  | S )a  
    Updates the NemoConfig DictConfig such that:
    1)  If the sub-config key exists in the `update_cfg`, but does not exist in ModelPT config:
        - Add the sub-config from update_cfg to ModelPT config

    2) If the sub-config key does not exist in `update_cfg`, but exists in ModelPT config:
        - Remove the sub-config from the ModelPT config; iff the `drop_missing_subconfigs` flag is set.

    Args:
        model_cfg: A DictConfig instantiated from the NemoConfig subclass.
        update_cfg: A DictConfig that mirrors the structure of `model_cfg`, used to update its default values.
        subconfig_key: A str key used to check and update the sub-config.
        drop_missing_subconfigs: A bool flag, whether to allow deletion of the NemoConfig sub-config,
            if its mirror sub-config does not exist in the `update_cfg`.

    Returns:
        The updated DictConfig for the NemoConfig
    r   r   N)r   r   r   r   r	   r   r    )r"   r   r   r   r#   r#   r$   r   n   s,   




r   c                 C   s   t std td t| j; ||jv rC|| jvr d| j|< t| j| }t|j| }t	||}|| j|< W d   | S W d   | S 1 sNw   Y  | S )a?  
    For certain sub-configs, the default values specified by the NemoConfig class is insufficient.
    In order to support every potential value in the merge between the `update_cfg`, it would require
    explicit definition of all possible cases.

    An example of such a case is Optimizers, and their equivalent Schedulers. All optimizers share a few basic
    details - such as name and lr, but almost all require additional parameters - such as weight decay.
    It is impractical to create a config for every single optimizer + every single scheduler combination.

    In such a case, we perform a dual merge. The Optim and Sched Dataclass contain the bare minimum essential
    components. The extra values are provided via update_cfg.

    In order to enable the merge, we first need to update the update sub-config to incorporate the keys,
    with dummy temporary values (merge update config with model config). This is done on a copy of the
    update sub-config, as the actual override values might be overriden by the NemoConfig defaults.

    Then we perform a merge of this temporary sub-config with the actual override config in a later step
    (merge model_cfg with original update_cfg, done outside this function).

    Args:
        model_cfg: A DictConfig instantiated from the NemoConfig subclass.
        update_cfg: A DictConfig that mirrors the structure of `model_cfg`, used to update its default values.
        subconfig_key: A str key used to check and update the sub-config.

    Returns:
        A ModelPT DictConfig with additional keys added to the sub-config.
    r   r   N)
r   r   r   r   r	   r   copydeepcopyr   r!   )r"   r   r   	subconfigupdate_subconfigr#   r#   r$   r      s$   





r   cls
class_typedatacls	dataclassignore_args
remap_argsc              	   C   s  t | j}tdi |j}|d t |}tdi |j}|dd t| }t| }|dury| D ]>\}}	||v r[|	| |
|	 td| d|	 d| j  ||v rx|	| |
|	 td| d|	 d|j  q:|durt|}|| }|| }td|  t||}
||
 }||
 }t|t|kst|dkst|dkrtd	| j d
|j d t|dkrtd	| j d|  t|rtd|j d|  d||fS dS )aG  
    Analyses the signature of a provided class and its respective data class,
    asserting that the dataclass signature matches the class __init__ signature.

    Note:
        This is not a value based check. This function only checks if all argument
        names exist on both class and dataclass and logs mismatches.

    Args:
        cls: Any class type - but not an instance of a class. Pass type(x) where x is an instance
            if class type is not easily available.
        datacls: A corresponding dataclass for the above class.
        ignore_args: (Optional) A list of string argument names which are forcibly ignored,
            even if mismatched in the signature. Useful when a dataclass is a superset of the
            arguments of a class.
        remap_args: (Optional) A dictionary, mapping an argument name that exists (in either the
            class or its dataclass), to another name. Useful when argument names are mismatched between
            a class and its dataclass due to indirect instantiation via a helper method.

    Returns:
        A tuple containing information about the analysis:
        1) A bool value which is True if the signatures matched exactly / after ignoring values.
            False otherwise.
        2) A set of arguments names that exist in the class, but *do not* exist in the dataclass.
            If exact signature match occurs, this will be None instead.
        3) A set of argument names that exist in the data class, but *do not* exist in the class itself.
            If exact signature match occurs, this will be None instead.
    self_target_Nz	Remapped z -> z in zRemoving ignored arguments - r   zClass z" arguments do not match Dataclass !z has additional arguments :
z
Dataclass F)TNNr#   )inspect	signature__init__dict
parametersr    setkeysitemsremoveaddr   info__name__intersectionlenr   )r*   r,   r.   r/   	class_sigclass_paramsdataclass_sigdataclass_paramsoriginal_argnew_argr?   
subset_clssubset_dataclsr#   r#   r$    assert_dataclass_signature_match   sF   "





(
rI   )T)NN)r&   r3   dataclassesr   typingr   r   r   
nemo.utilsr   r   	omegaconfr   r   r	   ModuleNotFoundErrorboolr%   strr   r   rI   r#   r#   r#   r$   <module>   sP   
P
'4
