o
    ۷i                  	   @   s   U d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	 ddl
mZ er+ddlmZ e	eZG dd	 d	eZG d
d deedZi Zeeef ed< 	ddededB deegef fddZdS )a  Diffusion attention backend registry.

This module provides an enum-based registry for diffusion attention backends,
similar to vLLM's AttentionBackendEnum. Each backend registers its class path,
and platforms can override or extend backends using register_backend().
    )Callable)EnumEnumMeta)TYPE_CHECKING)init_logger)resolve_obj_by_qualname)AttentionBackendc                       s*   e Zd ZdZdeddf fddZ  ZS )_DiffusionBackendEnumMetazMMetaclass for DiffusionAttentionBackendEnum to provide better error messages.namereturnDiffusionAttentionBackendEnumc                    sL   zt  |W S  ty%   t| j }d|}td| d| dw )z0Get backend by name with helpful error messages.z, z&Unknown diffusion attention backend: 'z'. Valid options are: N)super__getitem__KeyErrorlist__members__keysjoin
ValueError)clsr
   membersvalid_backends	__class__ e/home/ubuntu/vllm_env/lib/python3.10/site-packages/vllm_omni/diffusion/attention/backends/registry.pyr      s   
z%_DiffusionBackendEnumMeta.__getitem__)__name__
__module____qualname____doc__strr   __classcell__r   r   r   r   r	      s    r	   c                   @   sR   e Zd ZdZdZdZdZddedefdd	Z	dddZ
defddZdddZdS )r   a;  Enumeration of all supported diffusion attention backends.

    The enum value is the default class path, but this can be overridden
    at runtime using register_backend().

    To get the actual backend class (respecting overrides), use:
        backend.get_class()

    Example:
        # Get backend class
        backend = DiffusionAttentionBackendEnum.FLASH_ATTN
        backend_cls = backend.get_class()

        # Register custom backend
        @register_diffusion_backend(DiffusionAttentionBackendEnum.CUSTOM)
        class MyCustomBackend:
            ...
    zGvllm_omni.diffusion.attention.backends.flash_attn.FlashAttentionBackendz7vllm_omni.diffusion.attention.backends.sdpa.SDPABackendzEvllm_omni.diffusion.attention.backends.sage_attn.SageAttentionBackendTinclude_classnamer   c                 C   sD   t | | j}|std| j d| j d|s |ddd }|S )zGet the class path for this backend (respects overrides).

        Returns:
            The fully qualified class path string

        Raises:
            ValueError: If backend has empty path and is not registered
        zBackend z] must be registered before use. Use register_diffusion_backend(DiffusionAttentionBackendEnum.z, 'your.module.YourClass').   r   )_DIFFUSION_ATTN_OVERRIDESgetvaluer   r
   rsplit)selfr"   pathr   r   r   get_path?   s   	
z&DiffusionAttentionBackendEnum.get_pathtype[AttentionBackend]c                 C   s   t |  S )zGet the backend class (respects overrides).

        Returns:
            The backend class

        Raises:
            ImportError: If the backend class cannot be imported
            ValueError: If backend has empty path and is not registered
        )r   r+   r)   r   r   r   	get_classS   s   
z'DiffusionAttentionBackendEnum.get_classc                 C   s   | t v S )zCheck if this backend has been overridden.

        Returns:
            True if the backend has a registered override
        )r%   r-   r   r   r   is_overridden_   s   z+DiffusionAttentionBackendEnum.is_overriddenNc                 C   s   t | d dS )z>Clear any override for this backend, reverting to the default.N)r%   popr-   r   r   r   clear_overrideg   s   z,DiffusionAttentionBackendEnum.clear_override)T)r   r,   )r   N)r   r   r   r   
FLASH_ATTN
TORCH_SDPA	SAGE_ATTNboolr    r+   r.   r/   r1   r   r   r   r   r   &   s    
r   )	metaclassr%   Nbackend
class_pathr   c                    s2   dt dt f fdd}|dur|t < dd S |S )a  Register or override a diffusion backend implementation.

    Args:
        backend: The DiffusionAttentionBackendEnum member to register
        class_path: Optional class path. If not provided and used as
            decorator, will be auto-generated from the class.

    Returns:
        Decorator function if class_path is None, otherwise a no-op

    Examples:
        # Override an existing backend
        @register_diffusion_backend(DiffusionAttentionBackendEnum.FLASH_ATTN)
        class MyCustomFlashAttn:
            ...

        # Override an existing backend (e.g., ASCEND_ATTN)
        @register_diffusion_backend(DiffusionAttentionBackendEnum.ASCEND_ATTN)
        class CustomAscendAttentionBackend:
            ...

        # Direct registration
        register_diffusion_backend(
            DiffusionAttentionBackendEnum.CUSTOM,
            "my.module.MyCustomBackend"
        )
    r   r   c                    s   | j  d| j t < | S )Nr#   )r   r   r%   )r   r7   r   r   	decorator   s   z-register_diffusion_backend.<locals>.decoratorNc                 S   s   | S Nr   )xr   r   r   <lambda>   s    z,register_diffusion_backend.<locals>.<lambda>)typer%   )r7   r8   r:   r   r9   r   register_diffusion_backendp   s
    r?   r;   )r   collections.abcr   enumr   r   typingr   vllm.loggerr   vllm.utils.import_utilsr   /vllm_omni.diffusion.attention.backends.abstractr   r   loggerr	   r   r%   dictr    __annotations__r>   r?   r   r   r   r   <module>   s(   G