
    +j+                         d dl Z d dlZd dlmZmZ d dlmZ d dlmZ d dl	m
Z
 d dlZddlmZmZmZ ddlmZmZmZ  e j        d	          Z G d
 d          Z e            ZdS )    N)CallableMapping)contextmanager)cached_property)Any   )FunctionConstraintsValidationResultvalidate_function_call)BackendNotFoundErrorBackendNotImplementedErrorNoCapableBackendErrorzcomfy_kitchen.dispatchc            	          e Zd Zd Zedeeef         dz  fd            Zdede	ee
f         fdZded	ede
dz  fd
ZdedefdZdefdZdefdZdee         fdZdedefdZde	fdZded	edeeef         defdZ	 dd	edeeef         dz  defdZ	 	 dd	ededz  deeef         dz  defdZedefd            ZdS )BackendRegistryc                     i | _         i | _        i | _        g d| _        t	                      | _        i | _        t          j                    | _	        t          j
                    | _        d S )N)cudatritoneager)	_backends_capabilities_constraints	_priorityset	_disabled_unavailable	threadingLock_locklocal_thread_local)selfs    Y/home/wildlama/comfy/ComfyUI/.venv/lib/python3.11/site-packages/comfy_kitchen/registry.py__init__zBackendRegistry.__init__   s^    444^%%
&_..    returnNc                     t           j                                        r[	 t           j                            t           j                                                  }|j        |j        fS # t          $ r Y d S w xY wd S N)torchr   is_availableget_device_propertiescurrent_devicemajorminor	Exception)r!   propss     r"   _compute_capabilityz#BackendRegistry._compute_capability   sv    :""$$ 	
889R9R9T9TUUU[11   ttts   AA) )
A76A7namecapabilitiesc                 .   | j         5  || j        |<   t          |                                          | j        |<   |                                D ]\  }}|| j        ||f<   | j                            |d           ddd           dS # 1 swxY w Y   dS )a!  Register a backend with its capabilities and constraints.

        Args:
            name: Backend name (e.g., "cuda", "eager", "triton")
            module: The backend module containing implementations
            capabilities: Dict mapping function names to FunctionConstraints
        N)	r   r   r   keysr   itemsr   r   pop)r!   r1   moduler2   	func_nameconstraintss         r"   registerzBackendRegistry.register)   s     Z 	. 	.#)DN4 '*<+<+<+>+>'?'?Dt$*6*<*<*>*> C C&	;7B!4"344!!$---	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.s   A5B

BBbackend_namer8   c                 :    | j                             ||f          S )z5Get constraints for a specific backend/function pair.)r   get)r!   r;   r8   s      r"   get_constraintszBackendRegistry.get_constraints=   s       $$lI%>???r$   reasonc                 Z    | j         5  || j        |<   ddd           dS # 1 swxY w Y   dS )zMark a backend as unavailable with a reason.

        Args:
            name: Backend name
            reason: Why the backend is unavailable (e.g., "ImportError: ...")
        N)r   r   )r!   r1   r?   s      r"   mark_unavailablez BackendRegistry.mark_unavailableC   s}     Z 	- 	-&,Dd#	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-s    $$c                 z    | j         5  | j                            |           ddd           dS # 1 swxY w Y   dS )zhManually disable a backend.

        Args:
            backend_name: Name of backend to disable
        N)r   r   addr!   r;   s     r"   disablezBackendRegistry.disableM   s     Z 	- 	-N|,,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-   044c                 z    | j         5  | j                            |           ddd           dS # 1 swxY w Y   dS )ztRe-enable a previously disabled backend.

        Args:
            backend_name: Name of backend to enable
        N)r   r   discardrD   s     r"   enablezBackendRegistry.enableV   s     Z 	1 	1N""<000	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1rF   priority_listc                 n    | j         5  t          |          | _        ddd           dS # 1 swxY w Y   dS )zSet backend selection priority order.

        Args:
            priority_list: List of backend names in priority order
        N)r   listr   )r!   rJ   s     r"   set_priorityzBackendRegistry.set_priority_   s     Z 	1 	1!-00DN	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1s   *..c                 &    || j         v o|| j        vS )zCheck if backend is available and not disabled.

        Args:
            backend_name: Name of backend to check

        Returns:
            True if backend is registered and not disabled
        )r   r   rD   s     r"   r)   zBackendRegistry.is_availableh   s     t~-T,dn2TTr$   c           
         i }t          | j                  t          | j                                                  z  t          | j                                                  z  }|D ]X}|| j        v || j        v | j                            |          t          | j                            |g                     d||<   Y|S )a  Return dict of all backends with their status.

        Returns:
            Dict mapping backend names to status info:
            {
                "backend_name": {
                    "available": bool,
                    "disabled": bool,
                    "unavailable_reason": str or None,
                    "capabilities": list[str]
                }
            }
        )	availabledisabledunavailable_reasonr2   )	r   r   r   r4   r   r   r=   sortedr   )r!   resultall_backend_namesr1   s       r"   list_backendszBackendRegistry.list_backendss   s     #dn&9&9&;&;"<"<<s4CTCYCYC[C[?\?\\ 	 & 	 	D!T^3 DN2&*&7&;&;D&A&A &t'9'='=dB'G'G H H	 F4LL r$   kwargsc                    |                      |          s.t          j        d| j                            |d                    S || j                            |t                                vrt          j        dd          S | j                            ||f          }|t          j                    S t          ||| j
                  S )a<  Validate if a backend can handle a function call with given args.

        Args:
            backend_name: Name of backend to validate
            func_name: Function name
            kwargs: Keyword arguments for the function call

        Returns:
            ValidationResult with success/failure details
        __backend__not available__function__not implementedN)compute_capability)r)   r
   failr   r=   r   r   r   okr   r0   )r!   r;   r8   rW   r9   s        r"   validate_backend_for_callz)BackendRegistry.validate_backend_for_call   s    "   .. 	#(!%%lODD  
 D.22<GGGG#(9JKKK'++\9,EFF#&(((%#7
 
 
 	
r$   c                 &   i }t          |          }t          | j        dd          }|r|                     |          sd||<   n|| j                            |t                                vrd||<   nq|rQ|                     |||          }|j        rt          
                    d||           |S |j         d|j         ||<   nt          
                    d||           |S | j        D ]}|                     |          s|| j                            |t                                vrB|r3|                     |||          }|j        s|j         d|j         ||<   wt          
                    d||           |c S t          ||          )ap  Find the best backend that can handle a function call.

        Args:
            func_name: Function name
            kwargs: Keyword arguments for constraint validation (empty/None skips validation)

        Returns:
            Backend name that will handle the function

        Raises:
            NoCapableBackendError: If no backend can handle the call
        backend_overrideNrZ   r\   z%Backend %s selected for %s (override): zBackend %s selected for %s)boolgetattrr    r)   r   r=   r   r`   successloggerdebugfailed_paramfailure_reasonr   r   )r!   r8   rW   failuresvalidateoverriderT   r;   s           r"   get_capable_backendz#BackendRegistry.get_capable_backend   s   " $&<< 4-/A4HH 	 $$X..  %4""$"4"8"8355"I"III%6""  77)VTT> $LL!H(T]^^^#O(.(;%V%Vv?T%V%V""DhPYZZZ !N 	  	 L$$\22  2 6 6|SUU K KKK 77iQWXX~ 060C-^-^vG\-^-^H\*LL5|YOOO#Ix888r$   backendc                 (   |r|| j         vr)t          || j                            |d                    || j        v rt          |d          || j                            |t                                vrt          ||          |r?|                     |||          }|j	        s!t          |||j         d|j         i          t          | j         |         |          S |                     ||          }t          | j         |         |          S )a=  Get the best implementation for a function.

        Args:
            func_name: Name of the function to get
            backend: Explicit backend to use, or None for auto-select
            kwargs: Kwargs for constraint validation (empty/None skips validation)

        Returns:
            The function implementation

        Raises:
            BackendNotFoundError: If explicit backend is not available
            BackendNotImplementedError: If explicit backend doesn't implement function
            NoCapableBackendError: If no backend can handle the call
        not registeredrQ   rc   )r   r   r   r=   r   r   r   r   r`   rf   r   ri   rj   re   rn   )r!   r8   ro   rW   rT   selected_backends         r"   get_implementationz"BackendRegistry.get_implementation   s&   *  	?dn,,*7D4E4I4I'Sc4d4deee$.((*7J??? 2 6 6w F FFF0)DDD y77FSS~ y/	GH[EvEv_e_tEvEv;wxxx4>'2I>>>33IvFFt~&67CCCr$   c              #     K   |                      |          sO|| j        v r| j        |         }t          ||          || j        v rt          |d          t          |d          t	          | j        dd          }|| j        _        	 dV  |t          | j        d           dS || j        _        dS # |t          | j        d           n|| j        _        w xY w)zContext manager to temporarily use a specific backend.

        Args:
            backend_name: Name of backend to use in this context

        Example:
            with registry.use_backend("eager"):
                result = some_function()
        rQ   rq   rb   N)r)   r   r   r   re   r    rb   delattr)r!   r;   r?   previouss       r"   use_backendzBackendRegistry.use_backend  s        .. 	Kt000*<8*<@@@//*<DDD*<9IJJJ 4-/A4HH.:+	?EEE *,>?????6>"333 *,>????6>"3>>>>s   
B5 5&Cr'   )NN)__name__
__module____qualname__r#   r   tupleintr0   strdictr	   r:   r>   rA   rE   rI   rL   rM   rd   r)   rV   r   r   r
   r`   rn   r   rs   r   rw    r$   r"   r   r      s       / / / U38_t%;    _.. 3 334	. . . .(@@,/@	t	#@ @ @ @-S -# - - - --C - - - -13 1 1 1 11$s) 1 1 1 1	U 	U 	U 	U 	U 	Ut    :"
"
 "
 S!	"

 
"
 "
 "
 "
N ,059 5959 S!D(59 
	59 59 59 59t #+/	#D #D#D t#D S!D(	#D
 
#D #D #D #DJ ? ? ? ? ^? ? ?r$   r   )loggingr   collections.abcr   r   
contextlibr   	functoolsr   typingr   r(   r9   r	   r
   r   
exceptionsr   r   r   	getLoggerrg   r   registryr   r$   r"   <module>r      s        - - - - - - - - % % % % % % % % % % % %        V V V V V V V V V V          
	3	4	4\? \? \? \? \? \? \? \?~ ?r$   