o
    ̳i!                     @   s   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
 d dlmZmZ d dlmZ d dlmZmZ ded	ed
dfddZde
eeef ef d
efddZded
efddZdede	e d
efddZdeeef ded
dfddZdS )    )	Namespace)import_module)
ModuleType)AnyDictListUnion)
DictConfig	OmegaConf)InstantiationError)
get_loggerlog_rank_zerorecipe_namecfgreturnNc                 C   s4   t d}tj|ddd}t|d|  d| d dS )z
    Logs the resolved config (merged YAML file and CLI overrides) to rank zero.

    Args:
        recipe_name (str): name of the recipe to display
        cfg (DictConfig): parsed config object
    DEBUGT)resolve	sort_keyszRunning z with resolved config:

)loggermsgN)r   r
   to_yamlr   )r   r   r   cfg_str r   K/home/ubuntu/.local/lib/python3.10/site-packages/torchtune/config/_utils.py
log_config   s
   
r   nodec                 C   s   t | s
t| tod| v S )N_component_)r
   is_dict
isinstancedict)r   r   r   r   _has_component!   s   r    pathc           
      C   s  | dkrt ddd | dD }|D ]}t|s$t d|  dd q|d	 }zt|}W n tyN } ztd|  d
t| d| d |d}~ww tdt|D ]}|| }zt||}W qV t	y } zud
|d| }t|trd
|d|d  }	zt|	}W W Y d}~qV ty } ztd|  d
t| d| d| d |d}~w ty } ztd|  d
t| |d}~ww td|  d
t| d| d| d |d}~ww |S )aY  
    Return an object by name or dotted path, importing as necessary.
    The base functionality relies on ``getattr()`` and handles all
    possible exceptions accordingly.

    Based on Hydra's `_locate` from Facebook Research:
    https://github.com/facebookresearch/hydra/blob/main/hydra/_internal/utils.py#L614

    Args:
        path (str): Dotted path of the object

    Returns:
        Any: The object

    Raises:
        InstantiationError: If there is an exception loading the
            object from the provided path
        ValueError: If a relative or invalid dotpath is passed in
     z
Empty pathc                 S   s   g | ]}|qS r   r   ).0partr   r   r   
<listcomp><   s    z,_get_component_from_path.<locals>.<listcomp>.zError loading 'z': invalid dotstring.z$
Relative imports are not supported.r   z':
z
Are you sure that module 'z' is installed?N   z
Are you sure that 'z' is importable from module 'z'?z' is an attribute of ')
ValueErrorsplitlenr   ImportErrorr   reprrangegetattrAttributeErrorjoinr   r   ModuleNotFoundError	Exception)
r!   partsr$   part0obj
exc_importmexc_attrparent_dotpathmodr   r   r   _get_component_from_path%   s|   


r;   	yaml_argscli_argsc           
   
   C   s   t | }g }|D ]w}|dr@|dd dd }d|v r%td| zt|| W n ttfy>   td| d	dw qz	|d\}}W n tyX   td
| dw ||v rgt|| rg|d7 }|dkrmd}d|v rud| }|| d|  qt	|}t
|}	t|	|S )a  
    Takes the direct output of argparse's parse_known_args which returns known
    args as a Namespace and unknown args as a dotlist (in our case, yaml args and
    cli args, respectively) and merges them into a single OmegaConf DictConfig.

    If a cli arg overrides a yaml arg with a _component_ field, the cli arg can
    be specified with the parent field directly, e.g., model=torchtune.models.lora_llama2_7b
    instead of model._component_=torchtune.models.lora_llama2_7b. Nested fields within the
    component should be specified with dot notation, e.g., model.lora_rank=16.

    Example:
        >>> config.yaml:
        >>>     a: 1
        >>>     b:
        >>>       _component_: torchtune.models.my_model
        >>>       c: 3

        >>> tune full_finetune --config config.yaml b=torchtune.models.other_model b.c=4
        >>> yaml_args, cli_args = parser.parse_known_args()
        >>> conf = _merge_yaml_and_cli_args(yaml_args, cli_args)
        >>> print(conf)
        >>> {"a": 1, "b": {"_component_": "torchtune.models.other_model", "c": 4}}

    Args:
        yaml_args (Namespace): Namespace containing args from yaml file, components
            should have _component_ fields
        cli_args (List[str]): List of key=value strings

    Returns:
        DictConfig: OmegaConf DictConfig containing merged args

    Raises:
        ValueError: If a cli override is not in the form of key=value
    ~r'   N=r   r   0Removing components from CLI is not supported: ~zCould not find key z in yaml config to removez=Command-line overrides must be in the form of key=value, got z._component_Nonez!!nullmax_filenamez!!str )vars
startswithr)   r(   _remove_key_by_dotpathKeyErrorr    appendr
   from_dotlistcreatemerge)
r<   r=   yaml_kwargscli_dotlistargdotpathkvcli_conf	yaml_confr   r   r   _merge_yaml_and_cli_argsp   sL   $



rS   nested_dictrN   c                    sb    d}dtttf dtddffdd dtttf dtt ddf fd	d
| | dS )z
    Removes a key specified by dotpath from a nested dict. Errors should handled by
    the calling function.

    Args:
        nested_dict (Dict[str, Any]): Dict to remove key from
        dotpath (str): dotpath of key to remove, e.g., "a.b.c"
    r&   dkeyr   Nc                    s$   t | | rtd  | |= d S )Nr@   )r    r(   )rU   rV   )rN   r   r   delete_non_component   s
   
z4_remove_key_by_dotpath.<locals>.delete_non_componentr!   c                    sZ   t |dkr | |d  d S | |d  |dd   | |d  s+ | |d  d S d S )Nr'   r   )r*   )rU   r!   )rW   recurse_and_deleter   r   rX      s   z2_remove_key_by_dotpath.<locals>.recurse_and_delete)r)   r   strr   r   )rT   rN   r!   r   )rW   rN   rX   r   rE      s   
	"(rE   )argparser   	importlibr   typesr   typingr   r   r   r   	omegaconfr	   r
   torchtune.config._errorsr   torchtune.utils._loggingr   r   rY   r   boolr    r;   rS   rE   r   r   r   r   <module>   s   "K"T