
    3j+                         S SK r S SKrS SKJrJr  S SKJr  S SKJr  S SK	J
r
  S SKrSSKJrJrJr  SSKJrJrJr  \ R(                  " S	5      r " S
 S5      r\" 5       rg)    N)CallableMapping)contextmanager)cached_property)Any   )FunctionConstraintsValidationResultvalidate_function_call)BackendNotFoundErrorBackendNotImplementedErrorNoCapableBackendErrorzcomfy_kitchen.dispatchc            	       |   \ rS rSrS r\S\\\4   S-  4S j5       rS\	S\
\	\4   4S jrS	\	S
\	S\S-  4S jrS\	S\	4S jrS	\	4S jrS	\	4S jrS\\	   4S jrS	\	S\4S jrS\
4S jrS	\	S
\	S\\	\4   S\4S jr SS
\	S\\	\4   S-  S\	4S jjr  SS
\	S\	S-  S\\	\4   S-  S\4S jjr\S	\	4S j5       rSrg)BackendRegistry   c                     0 U l         0 U l        0 U l        / SQU l        [	        5       U l        0 U l        [        R                  " 5       U l	        [        R                  " 5       U l        g )N)cudatritoneager)	_backends_capabilities_constraints	_priorityset	_disabled_unavailable	threadingLock_locklocal_thread_local)selfs    P/home/wildlama/miniconda3/lib/python3.13/site-packages/comfy_kitchen/registry.py__init__BackendRegistry.__init__   sN    4^^%
&__.    returnNc                    [         R                  R                  5       (       aT   [         R                  R                  [         R                  R	                  5       5      nUR
                  UR                  4$ g ! [         a     g f = fN)torchr   is_availableget_device_propertiescurrent_devicemajorminor	Exception)r"   propss     r#   _compute_capability#BackendRegistry._compute_capability   sg    ::""$$

889R9R9TUU[[11   s   AA9 9
BBnamecapabilitiesc                 @   U R                      X R                  U'   [        UR                  5       5      U R                  U'   UR                  5        H  u  pEXPR                  X4'   M     U R                  R                  US5        SSS5        g! , (       d  f       g= f)zRegister 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"   r4   moduler5   	func_nameconstraintss         r#   registerBackendRegistry.register)   s|     ZZ#)NN4 '*<+<+<+>'?Dt$*6*<*<*>&	7B!!4"34 +?!!$- ZZs   A9B
Bbackend_namer;   c                 :    U R                   R                  X45      $ )z5Get constraints for a specific backend/function pair.)r   get)r"   r?   r;   s      r#   get_constraintsBackendRegistry.get_constraints=   s       $$l%>??r&   reasonc                 l    U R                      X R                  U'   SSS5        g! , (       d  f       g= f)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"   r4   rD   s      r#   mark_unavailable BackendRegistry.mark_unavailableC   s#     ZZ&,d# ZZs   %
3c                     U R                      U R                  R                  U5        SSS5        g! , (       d  f       g= f)zPManually disable a backend.

Args:
    backend_name: Name of backend to disable
N)r   r   addr"   r?   s     r#   disableBackendRegistry.disableM   s'     ZZNN|, ZZ	   2
A c                     U R                      U R                  R                  U5        SSS5        g! , (       d  f       g= f)z\Re-enable a previously disabled backend.

Args:
    backend_name: Name of backend to enable
N)r   r   discardrJ   s     r#   enableBackendRegistry.enableV   s'     ZZNN""<0 ZZrM   priority_listc                 p    U R                      [        U5      U l        SSS5        g! , (       d  f       g= f)zhSet backend selection priority order.

Args:
    priority_list: List of backend names in priority order
N)r   listr   )r"   rR   s     r#   set_priorityBackendRegistry.set_priority_   s!     ZZ!-0DN ZZs   '
5c                 H    XR                   ;   =(       a    XR                  ;  $ )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   rJ   s     r#   r+   BackendRegistry.is_availableh   s     ~~-T,nn2TTr&   c           
         0 n[        U R                  5      [        U R                  R                  5       5      -  [        U R                  R                  5       5      -  nU H`  nX0R                  ;   X0R
                  ;   U R                  R                  U5      [        U R                  R                  U/ 5      5      S.X'   Mb     U$ )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_reasonr5   )	r   r   r   r7   r   r   rA   sortedr   )r"   resultall_backend_namesr4   s       r#   list_backendsBackendRegistry.list_backendss   s     #dnn&9&9&;"<<s4CTCTCYCYC[?\\ 	 &D!^^3 NN2&*&7&7&;&;D&A &t'9'9'='=dB'G H	FL & r&   kwargsc                    U R                  U5      (       d1  [        R                  " SU R                  R	                  US5      5      $ X R
                  R	                  U[        5       5      ;  a  [        R                  " SS5      $ U R                  R	                  X45      nUc  [        R                  " 5       $ [        UUU R                  S9$ )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 implemented)compute_capability)r+   r
   failr   rA   r   r   r   okr   r2   )r"   r?   r;   rb   r<   s        r#   validate_backend_for_call)BackendRegistry.validate_backend_for_call   s    "   ..#((!!%%lOD 
 ..22<GG#((9JKK''++\,EF#&&((%#77
 	
r&   c                 V   0 n[        U5      n[        U R                  SS5      nU(       a  U R                  U5      (       d  SX5'   OXR                  R                  U[        5       5      ;  a  SX5'   OxU(       aY  U R                  XQU5      nUR                  (       a  [        R                  SXQ5        U$ UR                   SUR                   3X5'   O[        R                  SXQ5        U$ U R                   H  nU R                  U5      (       d  M  XR                  R                  U[        5       5      ;  a  MD  U(       aB  U R                  XqU5      nUR                  (       d  UR                   SUR                   3X7'   M  [        R                  SXq5        Us  $    [        X5      e)a0  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_overrideNre   rg   z%Backend %s selected for %s (override): zBackend %s selected for %s)boolgetattrr!   r+   r   rA   r   rk   successloggerdebugfailed_paramfailure_reasonr   r   )r"   r;   rb   failuresvalidateoverrider^   r?   s           r#   get_capable_backend#BackendRegistry.get_capable_backend   sr   " $&< 4--/A4H$$X..%4""4"4"8"835"II%6"77VT>>LL!H(^#O(.(;(;'<Bv?T?T>U%V"DhZ !NNL$$\22 2 2 6 6|SU KK77QWX~~060C0C/DBvG\G\F]-^H*LL5|O + $I88r&   backendc                 8   U(       a  X R                   ;  a%  [        X R                  R                  US5      5      eX R                  ;   a  [        US5      eXR
                  R                  U[        5       5      ;  a  [        X!5      eU(       aI  U R                  X!U5      nUR                  (       d&  [        XUR                   SUR                   305      e[        U R                   U   U5      $ U R                  X5      n[        U R                   U   U5      $ )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 registeredr[   ro   )r   r   r   rA   r   r   r   r   rk   rr   r   ru   rv   rq   rz   )r"   r;   r|   rb   r^   selected_backends         r#   get_implementation"BackendRegistry.get_implementation   s    * nn,*74E4E4I4I'Sc4dee..(*7J?? 2 2 6 6w FF0DD77FS~~/	H[H[G\\^_e_t_t^uEv;wxx4>>'2I>>33IFt~~&67CCr&   c              #     #    U R                  U5      (       dP  XR                  ;   a  U R                  U   n[        X5      eXR                  ;   a  [        US5      e[        US5      e[	        U R
                  SS5      nXR
                  l         Sv   Uc  [        U R
                  S5        gX0R
                  l        g! Uc  [        U R
                  S5        f X0R
                  l        f = f7f)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()
r[   r~   rn   N)r+   r   r   r   rq   r!   rn   delattr)r"   r?   rD   previouss       r#   use_backendBackendRegistry.use_backend  s        ..000**<8*<@@/*<DD*<9IJJ 4--/A4H.:+	? **,>?6>""3 **,>?6>""3s   BC/C  +C/ ,C,,C/)r   r   r   r   r   r   r!   r   r)   )NN) __name__
__module____qualname____firstlineno__r$   r   tupleintr2   strdictr	   r=   rB   rF   rK   rP   rT   rU   rp   r+   r`   r   r   r
   rk   rz   r   r   r   r   __static_attributes__ r&   r#   r   r      s   / U38_t%;  .. 3 334	.(@@,/@	t	#@-S -# --C -13 11$s) 1	U 	U 	Ut :"
"
 "
 S!	"

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