o
    Zh.                     @   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Zd dl	m
Z
mZmZmZmZmZmZmZ d dlmZ d dlmZ d dlmZ d dlmZ G d	d
 d
ZG dd deZG dd dZG dd deZdS )    N)partial)AnyCallableOptional)	AHContext
AHMetadataAHOperationChoice
CHOICE_COLFeedbackFEEDBACK_COLget_metadata_str_from_log)LearnedHeuristicController)ChoiceCaller)	cache_dir)get_gpu_shared_memoryc                   @   s>   e Zd ZdZdeegef ddfddZdedefdd	ZdS )
LocalFeedbacka7  
    To be able to collect data for a choice, a function providing feedback given a choice has to be provided.
    LocalFeedback can be used when AutoHeuristic should immediately run the function to collect feedback for each choice
    (see pad_mm.py, where the autotuning happens locally, for an example).
    feedback_fnreturnNc                 C   s
   || _ d S Nr   )selfr    r   Z/var/www/auris/lib/python3.10/site-packages/torch/_inductor/autoheuristic/autoheuristic.py__init__       
zLocalFeedback.__init__choicec                 C   s
   |  |S r   r   r   r   r   r   r   __call__#   r   zLocalFeedback.__call__)	__name__
__module____qualname____doc__r   r	   r   r   r   r   r   r   r   r      s    r   c                   @   s   e Zd ZdZdS )InconsistentMetadataz
    Exception that is thrown when AutoHeuristic tries to log data to a file where the metadata stored in the file does
    not match the metadata it would store if the file didn't exist.
    N)r   r    r!   r"   r   r   r   r   r#   '   s    r#   c                   @   s  e Zd ZU dZeeef ed< 		d"deg ef de	e de
e deded	e
e	e  d
e
eeegef  ddfddZdefddZdefddZ	d#dede
e	e  de
e	e  fddZdedefddZedefddZdefddZdefddZdededdfd d!ZdS )$AutoHeuristica  
    AutoHeuristic is a framework that allows one to collect data, learn a heuristic (i.e. a regression tree) and
    generate the heuristic to code. This class allows one to collect data. The collected data can then be used to train
    a heuristic (see torchgen/autoheuristic/).
    collected_feedbackNfallbackchoicesfeedbackcontextnameaugment_contextpreconditionr   c           
      C   s   || _ || _|| _|| _|| _i | _|| _tt t	j
 | j| j| _|| _|  s,dS t	jjjdkr9|  | _nt	jjj| _t	jj| jr]| jdur_| jD ]}| |}	| ||	 qOdS dS dS )a  
        Initializes an instance of the AutoHeuristic class.

        Args:
            fallback: A callable that returns a Choice when the heuristic is unsure which choice to make, or
            AutoHeuristic is in data collection mode.
            choices: A list of possible choices the heuristic can make.
            feedback: An instance of LocalFeedback that provides feedback for a given choice.
            context: Context to store with each choice and feedback.
            name: A string that identifies the heuristic.
            augment_context: An optional list of AHOperation instances that augment the context.
            precondition: A callable that returns a boolean indicating whether AutoHeuristic should run.
        NDEFAULT)r&   r'   r(   r)   r*   r%   r+   r   r   torchcudaZget_device_capabilitymetadatar,   satisfies_precondition	_inductorconfigZautoheuristic_log_pathget_default_log_pathlog_pathcollect_autoheuristic	save_data)
r   r&   r'   r(   r)   r*   r+   r,   r   feedback_valr   r   r   r   7   s6   


zAutoHeuristic.__init__c                 C   s   | j d u p|  | j| jS r   )r,   r0   r)   r   r   r   r   r1   k   s   z$AutoHeuristic.satisfies_preconditionc                 C   st   |   s|  S tjj| jr6| jdur| j	| j t
| j| j}| }|| jvr0|  S |dur6|S |  S )a  
        Returns the chosen option based on the value of autoheuristic_use.
        If self.name is one of the comma separated strings in autoheuristic_use,
        it queries a learned heuristic to make a decision. Otherwise, it returns the fallback option.
        N)r1   r&   r.   r2   r3   use_autoheuristicr*   r+   r)   apply_operationsr   r0   Zget_decisionr'   )r   
controllerZdecisionr   r   r   
get_choicep   s   

zAutoHeuristic.get_choicetop_kalways_includedc                 C   s   |   sd S tjj| jr@| jd ur| j| j t	| j
| j}||}|d u r,d S |d ur>|D ]}||vr=|| q2|S d S r   )r1   r.   r2   r3   r:   r*   r+   r)   r;   r   r0   Zget_decisions_rankedappend)r   r>   r?   r<   r'   r   r   r   r   get_top_k_choices   s&   


zAutoHeuristic.get_top_k_choicesr   c                 C   s   | j |d S r   )r%   getr   r   r   r   get_collected_feedback   s   z$AutoHeuristic.get_collected_feedbackc                  C   s   t j dd} | S )N _)r.   r/   Zget_device_namereplace)device_namer   r   r   get_device_identifier   s   z#AutoHeuristic.get_device_identifierc                 C   s<   |   }t  d| d}tj|dd || j d7 }|S )Nz/autoheuristic//T)exist_okz.txt)rH   r   osmakedirsr*   )r   rG   pathr   r   r   r4      s
   z"AutoHeuristic.get_default_log_pathc                 C   s2   | j  }| j \}}||d< ||d< t|S )NZnumerical_featuresZcategorical_features)r0   to_dictr)   Z&get_numerical_and_categorical_featuresjsondumps)r   metadata_dictZnum_featuresZcat_featuresr   r   r   serialize_metadata   s   

z AutoHeuristic.serialize_metadatar8   c                 C   s   || j |< | j}g }tj|}|r$|  }t| j}||kr#tdn||   | j	
 }|d t d t }	||	 d}
| j	 }|
|d | d t| 7 }
||
 t|d}|d|d  W d    d S 1 stw   Y  d S )Nz/Given metadata does not match existing metadata, a
)r%   r5   rK   rM   existsrR   r   r#   r@   r)   Zget_feature_names_csvr
   r   Zget_feature_values_csvstropenwritejoin)r   r   r8   r5   linesZ
log_existsr0   Zexisting_metadataZfeature_headerheaderlineZfeature_valuesfr   r   r   r7      s.   





"zAutoHeuristic.save_dataNNr   )r   r    r!   r"   dictr	   r   __annotations__r   listr   r   r   rX   r   r   boolr   r1   r=   intrA   r   rC   staticmethodrH   r4   rR   r7   r   r   r   r   r$   .   sL   
 	

	
4



r$   c                       s   e Zd ZdZ		ddeg ee f dee dee de	de
deee  d	eeee	gef  d
df fddZdee dee d
dfddZd
ee fddZ	ddedeee
  d
eee  fddZ  ZS )AutoHeuristicSelectAlgorithmz
    AutoHeuristicSelectAlgorithm is a subclass of AutoHeuristic that allows one to collect data and learn a heuristic
    when one wants to use AutoHeuristic for kernel choice selection.
    Nr&   r'   input_nodesr)   r*   r+   r,   r   c              	      s   || _ i | _|D ]	}|| j| < qt| j }	dtf fdd}
t |
|	d|||| tj	j
| jrB|  rD| || dS dS dS )a<  
        The arguments choices, input_nodes and name have to match the ones used in the call to
        autotune_select_algorithm(), e.g. if the following call is made
        autotune_select_algorithm(name, choices, input_nodes, layout), the same name, choices and input_nodes
        have to be used here.
        r   c                     s     } | d u r	dS |   S )NZunsure)autoheuristic_id)Zfallback_choicer&   r   r   fallback_str   s   z;AutoHeuristicSelectAlgorithm.__init__.<locals>.fallback_strN)rh   choicestr2choiceri   rc   keysrX   superr   r.   r2   r3   r6   r*   r1   register_global_feedback)r   r&   r'   rh   r)   r*   r+   r,   r   choices_strrk   	__class__rj   r   r      s*   z%AutoHeuristicSelectAlgorithm.__init__c                    s   ddl m}m m dtdtdtttf dtdtt	 dtt d	d
f fdd} |}j
||}t|||}|| d
S )zk
        Registers a callback in select_algorithm, which is called with the timing of each choice.
        r   )add_feedback_savercreate_inputs_keycreate_precompile_keyah_inputs_keyah_precompile_keytimingsr*   rh   r'   r   Nc           
         sR    |}|| kr
d S |||}||krd S |  D ]\}}	| |	 qd S r   )itemsr7   ri   )
rv   rw   rx   r*   rh   r'   Zcurrent_inputs_keyZcurrent_precompile_keyr   timert   ru   r   r   r   store_global_feedback  s   zTAutoHeuristicSelectAlgorithm.register_global_feedback.<locals>.store_global_feedback)Z torch._inductor.select_algorithmrs   rt   ru   rX   ra   r   floatrc   r   r*   r   )r   rh   r'   rs   r|   Z
inputs_keyZprecompile_keyZfeedback_saverr   r{   r   ro     s(   
z5AutoHeuristicSelectAlgorithm.register_global_feedbackc                 C   s   |   }| j|d S r   )r=   rl   rB   r   r   r   r   get_choice_caller1  s   z.AutoHeuristicSelectAlgorithm.get_choice_callerr>   r?   c                    s*     ||}|d u rd S  fdd|D S )Nc                    s   g | ]} j | qS r   )rl   ).0r   r9   r   r   
<listcomp>;  s    zIAutoHeuristicSelectAlgorithm.get_top_k_choices_caller.<locals>.<listcomp>)rA   )r   r>   r?   r'   r   r9   r   get_top_k_choices_caller5  s   z5AutoHeuristicSelectAlgorithm.get_top_k_choices_callerr`   r   )r   r    r!   r"   r   r   r   rc   r   r   rX   r   r   rd   r   ro   r~   re   r   __classcell__r   r   rq   r   rg      sJ    
	-
%

rg   )rO   rK   	functoolsr   typingr   r   r   r.   Z1torch._inductor.autoheuristic.autoheuristic_utilsr   r   r   r	   r
   r   r   r   Z:torch._inductor.autoheuristic.learned_heuristic_controllerr   Ztorch._inductor.irr   Z%torch._inductor.runtime.runtime_utilsr   Ztorch._inductor.utilsr   r   	Exceptionr#   r$   rg   r   r   r   r   <module>   s    (
 ,