o
    5ti}p                     @   s   d dl Z d dlZd dlZd dl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 d dlmZ d dlmZmZ d dlmZmZ d d	lmZ ee   ZeeZG d
d dZ de!e"e"f de"fddZ#dd Z$de!ddfddZ%	dde"ee"e!B eB  B de dB fddZ&dS )    N)Mapping)partial)Path)DictListOptionalUnion)utils)ConfigurableGroupGroupConfig)ConfigurableTaskTask)get_subtask_listc                   @   s  e Zd ZdZ				dDdedB deeB dB dededB ddf
d	d
Z		dEdeeB dB dedeeef fddZ	e
dd Ze
dd Ze
dd Ze
dd Ze
dd Z	dFdefddZdee dee fddZdedefddZdedefdd Zdedefd!d"Zdedefd#d$Zdedefd%d&Zd'edefd(d)Zd'edefd*d+Zd'edefd,d-Zdefd.d/Zd0d1 Zd2d3 ZdGd4d5Zd6d7 Z			dHd8eeB dB d9edB d:edB defd;d<Z dGdeeB dB defd=d>Z!d'efd?d@Z"dAefdBdCZ#dS )ITaskManagerzpTaskManager indexes all tasks from the default `lm_eval/tasks/`
    and an optional directory if provided.

    NT	verbosityinclude_pathinclude_defaultsmetadatareturnc                    s   |d ur	t | | _| _ j||d _tt j  _	t fdd j	D  _
t fdd j	D  _t fdd j	D  _tt _d S )N)r   r   c                    "   g | ]} j | d  dkr|qS )typegroup_task_index.0xself J/home/ubuntu/.local/lib/python3.10/site-packages/lm_eval/tasks/__init__.py
<listcomp>,      " z(TaskManager.__init__.<locals>.<listcomp>c                    s"   g | ]} j | d  dv r|qS )r   )taskpython_taskr   r   r   r   r    r!   /   s
    c                    r   )r   tagr   r   r   r   r    r!   6   r"   )r	   setup_loggingr   r   initialize_tasksr   sortedlistkeys
_all_tasks_all_groups_all_subtasks	_all_tagscollectionsdefaultdicttask_group_map)r   r   r   r   r   r   r   r    __init__   s(   

zTaskManager.__init__c                 C   sn   |rt jt jtd g}ng }|dur#t|tr|g}|| i }|D ]}| |}i ||}q'|S )a  Creates a dictionary of tasks indexes.

        :param include_path: Union[str, List] = None
            An additional path to be searched for tasks recursively.
            Can provide more than one such path as a list.
        :param include_defaults: bool = True
            If set to false, default tasks (those in lm_eval/tasks/) are not indexed.
        return
            Dictionary of task names as key and task metadata
        /N)	ospathdirnameabspath__file__
isinstancestrextend_get_task_and_group)r   r   r   	all_paths
task_indextask_dirtasksr   r   r    r'   ;   s   


zTaskManager.initialize_tasksc                 C      | j S N)r+   r   r   r   r    	all_tasksZ      zTaskManager.all_tasksc                 C   rA   rB   )r,   r   r   r   r    
all_groups^   rD   zTaskManager.all_groupsc                 C   rA   rB   )r-   r   r   r   r    all_subtasksb   rD   zTaskManager.all_subtasksc                 C   rA   rB   )r.   r   r   r   r    all_tagsf   rD   zTaskManager.all_tagsc                 C   rA   rB   r   r   r   r   r    r>   j   rD   zTaskManager.task_indexc                 C   s  ddl m} dd }| }ddg|_g }| jD ]}| j| d }	|	dkr'd	}	n||	}	|||	g q||_| }
d
g|
_dd | jD |
_| }g d|_g }| jD ]R}| j| d }	d}|	dkrt	j
|	dd}d|v rr|d }n d|v r|	dd d |d  }t	j
|dd}d|v r|d }|	dkrd	}	n||	}	|||	|g qS||_d}|r|| d 7 }|r||
 d 7 }|r|| d 7 }|S )Nr   )MarkdownTableWriterc                 S   s   d| v rd|  dd  S | S )Nzlm_eval/tasks/)split)r5   r   r   r    sanitize_paths   s   z1TaskManager.list_all_tasks.<locals>.sanitize_pathGroupConfig Location	yaml_pathrI   z---Tagc                 S   s   g | ]}|gqS r   r   )r   tr   r   r    r!      s    z.TaskManager.list_all_tasks.<locals>.<listcomp>)r   rM   zOutput Type simplemodeoutput_typeincluder3   
z

)pytablewriterrH   headersrE   r>   appendvalue_matrixrG   rF   r	   load_yaml_configrJ   dumps)r   list_groups	list_tagslist_subtasksrH   rK   group_table	gt_valuesgr5   	tag_tablesubtask_table	st_valuesrP   rU   configr   include_configresultr   r   r    list_all_tasksn   sV   




zTaskManager.list_all_tasks	task_listc                 C   s   t || jS rB   )r	   pattern_matchrC   )r   rk   r   r   r    match_tasks   s   zTaskManager.match_tasksnamec                 C   s   || j v rdS dS )NTF)rC   r   rn   r   r   r    _name_is_registered   s   
zTaskManager._name_is_registeredc                 C   $   |  |r| j| d dkrdS dS )Nr   r#   TFrp   r>   ro   r   r   r    _name_is_task      zTaskManager._name_is_taskc                 C   rq   )Nr   r%   TFrr   ro   r   r   r    _name_is_tag   rt   zTaskManager._name_is_tagc                 C   rq   )Nr   r   TFrr   ro   r   r   r    _name_is_group      
zTaskManager._name_is_groupc                 C   rq   )Nr   r$   TFrr   ro   r   r   r    _name_is_python_task   rw   z TaskManager._name_is_python_taskrg   c                 C      d|v rt |d trdS dS Nr#   TFr9   r:   r   rg   r   r   r    _config_is_task      zTaskManager._config_is_taskc                 C   ry   rz   )r9   r)   r|   r   r   r    _config_is_group   r~   zTaskManager._config_is_groupc                 C   s   d|v rdS dS )NclassTFr   r|   r   r   r    _config_is_python_task   s   z"TaskManager._config_is_python_taskc                 C   s   || j vrt| j | d S )NrN   )r>   
ValueErrorro   r   r   r    _get_yaml_path      
zTaskManager._get_yaml_pathc                 C   s2   || j vrt| |}|dkri S tj|ddS )NrI   fullrS   )r>   r   r   r	   r\   )r   rn   rN   r   r   r    _get_config   s   

zTaskManager._get_configc                 C   s   |  |rt| j| d S )Nr#   )rs   r   r>   ro   r   r   r    _get_tasklist   r   zTaskManager._get_tasklistc                 C   s0   d|v rd|v r|d ur|d |krd |d< |S )Ngroup_aliasr   r   )r   rg   r   r   r   r    _process_alias   s   zTaskManager._process_aliasc                 C   s$   t |dd }|rdt|jv S dS )Nr2   rg   F)getattrinspect	signature
parameters)r   clsconstructorr   r   r     _class_has_config_in_constructor   s   z,TaskManager._class_has_config_in_constructorname_or_configparent_nameupdate_configc              	      s  fdd}dt dtttt f ffdd}	 ddt dt dtt t f fdd	}t|tr|d ur8d
|i|}nW|sB|rM|}|||dS 	|}|dkrh|}	||	\}	}||	\}
}n'
|rtjt|t rw|nd d}t tjt|t| S t||dd}
t|t r.|r"|d
 |d uri ||} r }	||	|\}	}||	\}
}nl
 r߈	 }tj|d}t tjt|t| S  r }|d urttt fddj| }|dkr  d|  j|   i ||}n|}|| dS ||\}	}||	\}
}tj|
|d}|
t tjt|t| iS )Nc                    s   d| v ri t jd d| didd| }  | r; | d r)| d | d}n| d  }t|tr7||j_||iS  j	d urL| 
di  j	B | d< n| 
di | d< t| d}||iS )NrV   r   )rN   yaml_configrT   r   rg   r   )r	   r\   popr   r   r9   r   rg   r#   r   get)rg   r#   task_objectr   r   r    
_load_task	  s,   




z>TaskManager._load_individual_task_or_group.<locals>._load_taskrg   r   c                    sv    j d ur| di  j B | d< t| d}g }|jd D ]}t|tr1 |r1| | q|	| q||fS )Nr   r   r#   )
r   r   r
   rg   r9   r:   ru   r;   r   rZ   )rg   
group_namesubtask_listr#   r   r   r    "_get_group_and_subtask_from_config$  s   

zVTaskManager._load_individual_task_or_group.<locals>._get_group_and_subtask_from_configr   c                 S   sL   |d ur
i | |} dd |   D }t|sd }dd |   D }||fS )Nc                 S   s   i | ]\}}|t vr||qS r   GROUP_ONLY_KEYSr   kvr   r   r    
<dictcomp>7      z]TaskManager._load_individual_task_or_group.<locals>._process_group_config.<locals>.<dictcomp>c                 S   s   i | ]\}}|t v r||qS r   r   r   r   r   r    r   =  s    )itemsbool)rg   r   _update_configgroup_configr   r   r    _process_group_config2  s   zITaskManager._load_individual_task_or_group.<locals>._process_group_configr#   r#   rI   )r   )r   r#   r   c                    s
   |   S rB   )
startswith)r   )rn   r   r    <lambda>     
 z<TaskManager._load_individual_task_or_group.<locals>.<lambda>r   -)r   r   rB   )dicttupler
   r)   r:   r9   rs   rx   r   r   ru   r   _load_individual_task_or_groupr/   ChainMapmapreversedr}   r   rv   rp   lenfilterr1   rZ   )r   r   r   r   r   r   r   task_configr   r   r   fnbase_task_confignum_duplicater   )rn   r   r    r     s   

















z*TaskManager._load_individual_task_or_groupc                    s0   t |tr|g}ttjt fdd| }|S )zLoads a dictionary of task objects from a list

        :param task_list: Union[str, list] = None
            Single string or list of string of task names to be loaded

        :return
            Dictionary of task objects
        c                    s
     | S rB   r   r   r   r   r    r     r   z0TaskManager.load_task_or_group.<locals>.<lambda>)r9   r:   r   r/   r   r   )r   rk   all_loaded_tasksr   r   r    load_task_or_group  s   
	
zTaskManager.load_task_or_groupc                 C   s
   |  |S rB   r   r|   r   r   r    load_config  s   
zTaskManager.load_configr?   c              
      sV  dd }d}ddg t  }t|D ]\}}} fdd|D |dd< |  |  |D ]x}|d	rtj||}	tj	|	d
d}
| 
|
r\|
d }d|	d||< ||
||| q/| |
rldd|	d||
d < q/| |
r|
d }||v rtd| d|| d  d|	  q/d|	d||< ||
||| q/td| d| d q/q|S )a  Creates a dictionary of tasks index with the following metadata,
        - `type`, that can be either `task`, `python_task`, `group` or `tags`.
            `task` refer to regular task configs, `python_task` are special
            yaml files that only consists of `task` and `class` parameters.
            `group` are group configs. `tags` are labels that can be assigned
            to tasks to assist in sorting and calling tasks of certain themes.
        - `yaml_path`, path to the yaml file. If the entry is a `group` that
            was configured through a task config, the yaml_path will be -1
            and all subtasks will be listed in `task` (see below)
        - `task`, reserved for entries with `type` as `group`. This will list
            all subtasks. When a group config is created (as opposed to task
            config having `group` parameter set), this will be set to -1 to
            avoid recursive indexing. The whole list of subtasks will be loaded
            at evaluation.

        :param task_dir: str
            A directory to check for tasks

        :return
            Dictionary of task names as key and task metadata
        c                 S   s   d| v r@| d }t |tr|g}|D ]/}||vr"d|gdd||< q|| d dkr6td| d  d S || d | qd S d S )Nr%   rI   r   r#   rN   r   z	The tag 'zl' is already registered as a group, this tag will not be registered. This may affect tasks you want to call.r#   )r9   r:   eval_loggerinforZ   )rg   r#   tasks_and_groups
print_info	attr_listr%   r   r   r    _populate_tags_and_groups  s$   

zBTaskManager._get_task_and_group.<locals>._populate_tags_and_groupsT__pycache__z.ipynb_checkpointsc                    s   g | ]}| vr|qS r   r   )r   dignore_dirsr   r    r!     s    z3TaskManager._get_task_and_group.<locals>.<listcomp>Nz.yamlrR   rS   r#   r$   )r   rN   r   rI   r   zDuplicate task name 'z"' found. Already registered from: rN   z. Skipping duplicate from: zFile z in z could not be loaded)r/   r0   r4   walksortendswithr5   joinr	   r\   r   r   r}   r   warningdebug)r   r?   r   r   r   rootdirs	file_listfrN   rg   r#   r   r   r    r<     s`   






7zTaskManager._get_task_and_group)NNTN)NT)TTTrB   )NNN)$__name__
__module____qualname____doc__r:   r)   r   r   r2   r'   propertyrC   rE   rF   rG   r>   rj   rm   rp   rs   ru   rv   rx   r}   r   r   r   r   r   r   r   r   r   r   r   r<   r   r   r   r    r      s    

"








B	
	


 r   r   r   c                 C   s8   d| v r| d S d| v rdj di | S dj di | S )Nr#   dataset_namez{dataset_path}_{dataset_name}z{dataset_path}r   )format)r   r   r   r    get_task_name_from_config+  s
   r   c                 C   s.   t | dr
| jd S t | dr| jS t| jS )Nrg   r#   EVAL_HARNESS_NAME)hasattr_configr   r   r   )r   r   r   r    get_task_name_from_object4  s   

r   	task_dictc                    st   g   D ]	\}}| qfddD   fdd D }t dkr8tdt  d| dd	S )
a  helper function solely used in validating get_task_dict output.
    Takes the output of lm_eval.evaluator_utils.get_subtask_list and
    returns a list of all leaf subtasks contained within, and errors if any such leaf subtasks are
    "oversubscribed" to several disjoint groups.
    c                    s   h | ]}  |d kr|qS )   )count)r   	task_name)subtask_namesr   r    	<setcomp>K  r   z$_check_duplicates.<locals>.<setcomp>c                    s*   g | ]}t t|  d kr|qS )r   )r   setintersection)r   r   )duplicate_tasksr   r   r    r!   P  s
    z%_check_duplicates.<locals>.<listcomp>r   zjFound 1 or more tasks while trying to call get_task_dict() that were members of more than 1 called group: z. Offending groups: zW. Please call groups which overlap their constituent tasks in separate evaluation runs.N)r   r;   r*   r   r   r)   )r   keyvaluecompeting_groupsr   )r   r   r   r    _check_duplicatesA  s   
r   task_name_listtask_managerc                 C   s  i }i }i }t | tr| g} nt | tr"tdd | D s!tdn
tdt|  ddd | D }dd | D }t|dkrL|d	u rGt }||}|D ]!}t |t	r`i ||j
|d
}qNt |troi |t||i}qNt| t| sti |||}tt| dtfdd}	td | D ]\}
}t |
tr2td|
j  t |t	r'tt| }t |tr| D ]R\}}t |trtd|j  | D ]\}}t |tr|	||dd qt| d|  qqt |trt |tr|	||dd qtd| d|  qqt|
 d|  qt|
 d|  qt |
trFt |trF|	|
|dd qt|
 d|  q|S )a  Creates a dictionary of task objects from either a name of task, config, or prepared Task object.

    :param task_name_list: List[Union[str, Dict, Task]]
        Name of model or LM object, see lm_eval.models.get_model
    :param task_manager: TaskManager = None
        A TaskManager object that stores indexed tasks. If not set,
        task_manager will load one. This should be set by the user
        if there are additional paths that want to be included
        via `include_path`

    :return
        Dictionary of task objects
    c                 S   s   g | ]
}t |tttfqS r   )r9   r:   r   r   r   r#   r   r   r    r!   u  s    z!get_task_dict.<locals>.<listcomp>zfExpected all list items to be of types 'str', 'dict', or 'Task', but at least one entry did not match.z(Expected a 'str' or 'list' but received .c                 S   s   g | ]	}t |tr|qS r   r{   r   r   r   r    r!   ~  s    c                 S   s   g | ]	}t |ts|qS r   r{   r   r   r   r    r!     s
    
r   Nr   indentc                 S   sn   |j |  d }t|}ttj}z||}W n ty"   |}Y nw d| }t| d|  d| d d S )NrN     zTask: z ())r>   r   r8   parentrelative_tor   r   r   )r   r   r   rN   lm_eval_tasks_pathdisplay_pathpadr   r   r    pretty_print_task  s   
 z(get_task_dict.<locals>.pretty_print_taskzSelected tasks:zGroup: z  Subgroup:    )r   z: r   r   )r9   r:   r)   all	TypeErrorr   r   r   r   r   r   r   r   r   r*   
isdisjointr   r   r   intr   r   r   r
   r   nextiterr   )r   r   task_name_from_string_dicttask_name_from_config_dicttask_name_from_object_dictstring_task_name_listothers_task_name_listtask_elementfinal_task_dictr   r   r   	first_keysubgroupr   r   configurable_taskr   r   r    get_task_dict\  s   









r
  rB   )'r/   r   loggingr4   collections.abcr   	functoolsr   pathlibr   typingr   r   r   r   lm_evalr	   lm_eval.api.groupr
   r   lm_eval.api.taskr   r   lm_eval.evaluator_utilsr   r)   to_dictr*   r   	getLoggerr   r   r   r   r:   r   r   r   r
  r   r   r   r    <module>   s8    
    	