
    ^j                     ^   U d Z 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	m
Z
 ddlZddlmZ  ej                  e      Z G d de
      Zeej"                  eej&                     gef   Zi Zeeedz  f   ed	<   i Zeeef   ed
<   daeez  ed<   	 	 	 ddedz  dedz  dee   dede	f   fdZ ej8                  ed      Z ej8                  ed      Zdeez  defdZddee   fdZ ejB                  d d       Z"ejB                  d d       Z#dede$fdZ%deez  dz  ddfdZ&deez  fdZ'y)!a  
This module implements TorchDynamo's backend registry system for managing compiler backends.

The registry provides a centralized way to register, discover and manage different compiler
backends that can be used with torch.compile(). It handles:

- Backend registration and discovery through decorators and entry points
- Lazy loading of backend implementations
- Lookup and validation of backend names
- Categorization of backends using tags (debug, experimental, etc.)

Key components:
- CompilerFn: Type for backend compiler functions that transform FX graphs
- _BACKENDS: Registry mapping backend names to entry points
- _COMPILER_FNS: Registry mapping backend names to loaded compiler functions

Example usage:
    @register_backend
    def my_compiler(fx_graph, example_inputs):
        # Transform FX graph into optimized implementation
        return compiled_fn

    # Use registered backend
    torch.compile(model, backend="my_compiler")

The registry also supports discovering backends through setuptools entry points
in the "torch_dynamo_backends" group. Example:
```
setup.py
---
from setuptools import setup

setup(
    name='my_torch_backend',
    version='0.1',
    packages=['my_torch_backend'],
    entry_points={
        'torch_dynamo_backends': [
            # name = path to entry point of backend implementation
            'my_compiler = my_torch_backend.compiler:my_compiler_function',
        ],
    },
)
```
```
my_torch_backend/compiler.py
---
def my_compiler_function(fx_graph, example_inputs):
    # Transform FX graph into optimized implementation
    return compiled_fn
```
Using `my_compiler` backend:
```
import torch

model = ...  # Your PyTorch model
optimized_model = torch.compile(model, backend="my_compiler")
```
    N)CallableSequence)
EntryPoint)AnyProtocol)fxc                   N    e Zd Zdej                  deej                  df   fdZy)
CompiledFnargsreturn.c                      y )N )selfr   s     j/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/torch/_dynamo/backends/registry.py__call__zCompiledFn.__call__K   s        N)__name__
__module____qualname__torchTensortupler   r   r   r   r
   r
   J   s!    LellLuU\\35F/GLr   r
   	_BACKENDS_COMPILER_FNSinductor_default_backendcompiler_fnnametagsr   .c                 &   | t        j                  t        ||      S t        |       st	        dt        |              |xs | j                  }|t        v rt	        d|       | t        vr	dt        |<   | t        |<   t        |      | _
        | S )a  
    Decorator to add a given compiler to the registry to allow calling
    `torch.compile` with string shorthand.  Note: for projects not
    imported by default, it might be easier to pass a function directly
    as a backend and not use a string.

    Args:
        compiler_fn: Callable taking a FX graph and fake tensor inputs
        name: Optional name, defaults to `compiler_fn.__name__`
        tags: Optional set of string tags to categorize backend with
    N)r   r   z"compiler_fn must be callable, got zduplicate name: )	functoolspartialregister_backendcallableAssertionErrortyper   r   r   r   _tags)r   r   r   s      r   r#   r#   U   s        !14HHK A${BSATUVV';''D}/v677)#	$%M$dKr   )debug)r   )experimentalc                     t        | t              r`| t        vr
t                | t        vrddlm}  ||       | t        vr&t        |    }|t        |j                         |        t        |    } | S )z#Expand backend strings to functions   )InvalidBackend)r   )r   r   )	
isinstancestrr   _lazy_importexcr,   r   r#   load)r   r,   entry_points      r   lookup_backendr3   z   sj    +s#i'Ni', k22m+#K0K& [-=-=-?kR#K0r   c                     t                t        | xs d      }t        D cg c].  }|t        vs"|j	                  t        |   j
                        s|0 }}t        |      S c c}w )za
    Return valid strings that can be passed to:

        torch.compile(..., backend="name")
    r   )r/   setr   r   intersectionr'   sorted)exclude_tagsexclude_tags_setr   backendss       r   list_backendsr;      sk     N<-2. }$,,]4-@-F-FG 	H  (s   3A"c                  f    ddl m}  ddlm}  ||        ddlm} |t        d      t                y )Nr+   )r:   )import_submodule)dynamo_minifier_backendz&dynamo_minifier_backend failed to load) r:   utilsr=   repro.after_dynamor>   r%   _discover_entrypoint_backends)r:   r=   r>   s      r   r/   r/      s+    (X<&EFF!#r   c                      ddl m}  d} | |      }|j                  D ci c]  }|||   
 }}|D ]  }||   t        |<    y c c}w )Nr   )entry_pointstorch_dynamo_backends)group)importlib.metadatarD   namesr   )rD   
group_nameepsr   eps_dictbackend_names         r   rB   rB      sX     0(J
Z
(C,/II6Dc$i6H6  9"*<"8	,9 7s   Ac                     t                | t        j                         v ryt        | d      r| j                  }|t
        v s|t        v ryt        | d      r | j                  t        j                         v S y)z
    Check if the given compiler function is a registered backend.
    Custom backends (user-provided callables not in the registry) return False.
    Tcompiler_namer   F)r/   r   valueshasattrrN   r   r   )r   rN   s     r   _is_registered_backendrQ      sq     N m**,, {O,#11I%-)G {M*&&-*>*>*@@@r   backendc                 v    | da yt        | t              s"t        |       st	        dt        |              | a y)zSet the default backend used by torch.compile when no backend is explicitly specified.

    Pass None to reset to the default ("inductor").
    Nr   z*backend must be a string or callable, got )r   r-   r.   r$   	TypeErrorr&   )rR   s    r   set_default_backendrU      s@     %gs#HW,=DT']OTUUr   c                      t         S )z5Return the current default backend for torch.compile.)r   r   r   r   get_default_backendrW      s    r   )NNr   ))r(   r)   )r   N)(__doc__r!   loggingcollections.abcr   r   rG   r   typingr   r   r   r   	getLoggerr   logr
   GraphModulelistr   
CompilerFnr   dictr.   __annotations__r   r   r#   r"   register_debug_backendregister_experimental_backendr3   r;   cacher/   rB   boolrQ   rU   rW   r   r   r   <module>rg      s  :x   . )     g!M M r~~tELL'9:JFG
*,	4Z$&&' ,')tCO$ )%/ #
" / &*d"
* 3- c3h	> +**+;*M  1	 1 1,! 
j 0 Z &T#Y $ $ $ 	9 	9
 t 4z!1D!8 T S:- r   