o
    i7                     @   s  U d Z ddlmZ ddlmZmZm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 e s6ed	ddlZdd
lmZ ddlmZ ddlmZ eeZe	ddZdddeddfddZG dd deZG dd dZG dd dZi Z e!eef e"d< de!eef fddZ#dededB fdd Z$	d+d!edddefd"d#Z%eddd$d%ed&edB dddefd'd(Z&e	d+ddd$d%edB d&edB dddeegef fd)d(Z&	d+ddd$d%eeB dB d&edB dddeeegef B fd*d(Z&dS ),a  
vLLM Helion kernel registration with pre-tuned config selection.

This module leverages Helion's internal config selection infrastructure to use
pre-tuned configs instead of runtime autotuning.

How Helion Normally Works
-------------------------
For each kernel invocation, Helion:
1. Computes a cache key from input arguments
2. Looks up the key in its internal compilation cache
3. On cache miss, runs autotuning to find the best config
4. Compiles and caches the kernel with that config

How We Override It
------------------
We override two Helion hooks to use pre-tuned configs:

1. **key**: We provide a key function (derived from config_picker) that
   computes cache keys matching our pre-tuned config keys. This ensures Helion's
   internal cache uses keys that correspond to configs we've prepared.

2. **autotuner_fn**: We provide PresetConfigSearch which, instead of autotuning,
   simply returns the pre-tuned config for the computed key. On cache miss,
   Helion calls our autotuner which returns the author-prepared config.

Both hooks use the same config_picker logic to ensure the cache key computed
by key matches the config returned by the autotuner.

Key Classes
-----------
- HelionKernelWrapper: Wraps raw kernel + config_picker, creates configured ops
- ConfiguredHelionKernel: Platform-specific kernel registered as PyTorch custom op
- PresetConfigSearch: Custom autotuner that returns pre-tuned configs
    )Callable)AnycastoverloadN)Library)init_logger)
has_helion)direct_register_custom_opzTregister module requires helion to be installed. Install it with: pip install helion)BaseAutotuner)Config)default_autotuner_fnvllm_helionFRAGMENThelion_settingshelion.Settings | Noneop_namereturnc                 C   sl   | du rdS |   }d|v r%|d dur%|d tur%td| d| d|ddu r4td| dS dS )	zBValidate that helion_settings doesn't contain conflicting options.Nautotuner_fnzHelionKernelWrapper for 'za' uses a custom autotuner via config picker. Remove 'autotuner_fn' from helion_settings and use @z .register_config_picker instead.static_shapesTzKernel '%s' has static_shapes=True in helion_settings. Most vLLM ops require dynamic shapes for variable batch sizes and sequence lengths. Consider removing this setting.)to_dictr   
ValueErrorgetloggerwarning)r   r   settings_dict r   R/home/ubuntu/vllm_env/lib/python3.10/site-packages/vllm/kernels/helion/register.pyvalidate_helion_settingsA   s"   r   c                   @   sT   e Zd ZdZdeedf deeedf gef fddZddd	e	d
efddZ
dS )PresetConfigSearchzJCustom autotuner that uses a preset config selector instead of autotuning.args.config_selectorc                 C   s   || _ || _d S N)r   r    )selfr   r    r   r   r   __init__c   s   
zPresetConfigSearch.__init__F)
skip_cacher$   r   c                C   s   |  | jS r!   )r    r   )r"   r$   r   r   r   autotunek   s   zPresetConfigSearch.autotuneN)__name__
__module____qualname____doc__tupler   r   r   r#   boolr%   r   r   r   r   r   `   s    

r   c                	   @   s   e Zd ZdZ	ddedeeedf ee gedB f dB deddfd	d
Z	dd Z
dd Zdd ZdddZdedef fddZdS )ConfiguredHelionKernelz8A configured Helion kernel bound to a specific platform.Nr   config_picker.raw_kernel_funcr   r   c                 C   s&   || _ || _|| _|| _|  | _d S r!   )r   r-   r.   r   _create_decorated_kernel_decorated_kernel)r"   r   r-   r.   r   r   r   r   r#   r   s
   zConfiguredHelionKernel.__init__c                 O   s   | j |i |S r!   )r0   )r"   r   kwargsr   r   r   __call__   s   zConfiguredHelionKernel.__call__c                    sB    j du rtd j d j d j dusJ  fdd}|S )z
        Create a key computer function derived from the config picker.

        The returned function receives kernel arguments unpacked (*args) to match
        Helion's key signature (called as self._key_fn(*args)).
        N(No config picker registered for kernel ''. Use @(.register_config_picker to register one.c                     sZ   t  j }ttttdf t t gtd B f  j}|| |}|r$|S d jv r+dS d S )N.default)	listconfigskeysr   r   r*   r   strr-   )r   config_keysr-   selected_keyr"   r   r   key_computer   s   "
zAConfiguredHelionKernel._create_key_computer.<locals>.key_computer)r-   RuntimeErrorr   )r"   r>   r   r=   r   _create_key_computer   s   

z+ConfiguredHelionKernel._create_key_computerc                        fdd}|S )Nc              	      sj    |  }|d u rt dj dtj  |jvr0t d| dj dtj  j| S )Nz(Config picker returned None for kernel 'z' with available config keys: z+Config picker returned invalid config key 'z' for kernel 'z'. Available keys: )r   r   r7   r8   r9   )r   selected_config_keyr>   r"   r   r   r       s$   


zGConfiguredHelionKernel._create_config_selector.<locals>.config_selectorr   )r"   r>   r    r   rC   r   _create_config_selector   s   z.ConfiguredHelionKernel._create_config_selectorr   c                 C   s^   ddl m} ddlm} | | _| }|| j| j| _| js-t	d| j d| j dd S )Nr   )ConfigManager)get_canonical_gpu_namez!No configs available for kernel 'z' on platform '')
"vllm.kernels.helion.config_managerrE   vllm.kernels.helion.utilsrF   platformget_instanceget_platform_configsr   r8   r   )r"   rE   rF   config_managerr   r   r   _load_platform_configs   s   
z-ConfiguredHelionKernel._load_platform_configsc                    s   |    |  }| | i }| jr|| j  |ddur%d|d<  fdd|d< ||d< td| j	| j
 tjd	i || jS )
Nr   TFc                    s
   t | S r!   )r   )_r   r    r   r   <lambda>   s    zAConfiguredHelionKernel._create_decorated_kernel.<locals>.<lambda>r   keyzACreating decorated kernel %s with custom autotuner on platform %sr   )rN   r@   rD   r   updater   r   r   debugr   rJ   helionkernelr.   )r"   r>   kernel_kwargsr   rP   r   r/      s    
z/ConfiguredHelionKernel._create_decorated_kernelr!   )r   N)r&   r'   r(   r)   r:   r   r*   r   r7   r#   r2   r@   rD   rN   r/   r   r   r   r   r,   o   s"    "

r,   c                	   @   s   e Zd ZdZ	ddedededdfdd	Zd
d Zdeee	df e
e gedB f deee	df e
e gedB f fddZde	fddZdS )HelionKernelWrapperzKWrapper for Helion kernels that creates config-specific PyTorch custom ops.Nr.   r   	fake_implr   r   c                 C   s,   t || || _|| _|| _|| _d | _d S r!   )r   r.   r   
_fake_implr   _config_picker)r"   r.   r   rY   r   r   r   r   r#      s   
zHelionKernelWrapper.__init__c                 O   s   |   }||i |S r!   )get_configured_op)r"   r   r1   configured_opr   r   r   r2      s   zHelionKernelWrapper.__call__picker_func.r   c                 C   s
   || _ |S r!   )r[   )r"   r^   r   r   r   register_config_picker   s   z*HelionKernelWrapper.register_config_pickerc                 C   s   | j d usJ d| j d| j dttjj| jr)td| j ttjj| jS t	| j| j | j
| jd}td| j t| j|jd | jtd ttjj| jS )Nr3   r4   r5   z%Op vllm_helion::%s already registered)r   r-   r.   r   zRegistering op: vllm_helion::%s)r   op_funcmutates_argsrY   
target_lib)r[   r   hasattrtorchopsr   r   rT   getattrr,   r.   r   infor	   r0   rZ   vllm_helion_lib)r"   configured_kernelr   r   r   r\      s.   
	z%HelionKernelWrapper.get_configured_opr!   )r&   r'   r(   r)   r   r:   r#   r2   r*   r   r7   r_   r\   r   r   r   r   rX      s&    

rX   _REGISTERED_KERNELSc                   C   s   t  S r!   )rj   copyr   r   r   r   get_registered_kernels   s   rl   kernel_namec                 C   s
   t | S r!   )rj   r   )rm   r   r   r   get_kernel_by_name$  s   
rn   kernel_funcc                    rA   )Nc                     sb   i } r|    tjdi |}|| }|j }||}|| i |ddd iS )N	_launcherc                  _      d S r!   r   )akwr   r   r   rQ   8  s    z=infer_fake_impl.<locals>.helion_fake_kernel.<locals>.<lambda>r   )rS   r   rU   rV   bindconfig_specdefault_configcompile_config)r   r1   rW   temp_decorated_kernelboundrv   compiled_runnerr   ro   r   r   helion_fake_kernel,  s   


z+infer_fake_impl.<locals>.helion_fake_kernelr   )ro   r   r|   r   r{   r   infer_fake_impl(  s   r}   )rY   r   op_name_or_funcrY   c                C   rq   r!   r   r~   rY   r   r   r   r   register_kernelC     r   c                C   rq   r!   r   r   r   r   r   r   L  r   c                   s8   dt dtf fdd}trtts|S |S )z
    Decorator to register a Helion kernel function as a HelionKernelWrapper.

    Wraps the raw kernel function in a HelionKernelWrapper and registers it
    in the global kernel registry. Auto-generates fake_impl if not provided.
    ro   r   c                    s   t trnd }|r|n| j}|tv rtd| d }|d u r.t| }td| j t| ||d}|t|< t	d| j |S )NzHelion kernel 'zV' is already registered. Use a different op_name or check for duplicate registrations.z/Auto-generated fake_impl for Helion kernel '%s')r.   r   rY   r   z4Registered Helion kernel '%s' as HelionKernelWrapper)

isinstancer:   r&   rj   r   r}   r   rT   rX   rg   )ro   r   final_op_namefinal_fake_implkernel_wrapperrY   r   r~   r   r   	decoratorb  s2   

z"register_kernel.<locals>.decorator)r   rX   callabler   r:   )r~   rY   r   r   r   r   r   r   U  s   "r!   )'r)   collections.abcr   typingr   r   r   rd   torch.libraryr   vllm.loggerr   vllm.utils.import_utilsr   vllm.utils.torch_utilsr	   ImportErrorrU   helion.autotuner.base_searchr
   helion.runtime.configr   helion.runtime.settingsr   r&   r   rh   r:   r   r   r,   rX   rj   dict__annotations__rl   rn   r}   r   r   r   r   r   <module>   s   $

p>
	
