o
    ei                     @   sr  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
mZmZ ddlZddlmZ eeZG dd deZeejeej gef Zi Zeee
e f ed	< i Zeeef ed
< 			d!de
e de
e dee dede	f fddZejeddZejeddZdeeef defddZ d"dee fddZ!ej"d#ddZ#ej"d#ddZ$dede%fdd Z&dS )$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OptionalProtocolUnion)fxc                   @   s*   e Zd Zdejdeejdf fddZdS )
CompiledFnargsreturn.c                 G   s   d S )N )selfr   r   r   i/var/www/addictedbytheproject.nl/epg/venv/lib/python3.10/site-packages/torch/_dynamo/backends/registry.py__call__K   s    zCompiledFn.__call__N)__name__
__module____qualname__torchTensortupler   r   r   r   r   r
   J   s    "r
   	_BACKENDS_COMPILER_FNSr   compiler_fnnametagsr   .c                 C   sj   | du rt jt||dS t| sJ |p| j}|tvs"J 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duplicate name: )		functoolspartialregister_backendcallabler   r   r   r   _tags)r   r   r   r   r   r   r   T   s   

r   )debug)r   )experimentalc                 C   sj   t | tr3| tvrt  | tvrddlm} || d| tvr/t|  }|dur/t| | d t|  } | S )z#Expand backend strings to functions   )InvalidBackend)r   N)r   r   )	
isinstancestrr   _lazy_importexcr$   r   r   load)r   r$   entry_pointr   r   r   lookup_backendw   s   

r+   r!   r"   c                    s,   t   t| pd  fddtD }t|S )za
    Return valid strings that can be passed to:

        torch.compile(..., backend="name")
    r   c                    s(   g | ]}|t vs t | js|qS r   )r   intersectionr    .0r   exclude_tags_setr   r   
<listcomp>   s    z!list_backends.<locals>.<listcomp>)r'   setr   sorted)exclude_tagsbackendsr   r0   r   list_backends   s   
r7   c                  C   sB   ddl m}  ddlm} ||  ddlm} |d usJ t  d S )Nr#   )r6   )import_submodule)dynamo_minifier_backend) r6   utilsr8   repro.after_dynamor9   _discover_entrypoint_backends)r6   r8   r9   r   r   r   r'      s   
r'   c                     sH   ddl m}  d}| |d  fdd jD }|D ]}|| t|< qd S )Nr   )entry_pointstorch_dynamo_backends)groupc                    s   i | ]}| | qS r   r   r.   epsr   r   
<dictcomp>   s    z1_discover_entrypoint_backends.<locals>.<dictcomp>)importlib.metadatar>   namesr   )r>   
group_nameeps_dictbackend_namer   rA   r   r=      s   
r=   c                 C   sV   t   | t v rdS t| dr| j}|tv s|tv rdS t| dr)| jt v S dS )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hasattrrI   r   r   )r   rI   r   r   r   _is_registered_backend   s   

rL   )NNr   )r,   )r   N)'__doc__r   loggingcollections.abcr   r   rD   r   typingr   r   r   r   r   r	   	getLoggerr   logr
   GraphModulelistr   
CompilerFnr   dictr&   __annotations__r   r   r   register_debug_backendregister_experimental_backendr+   r7   cacher'   r=   boolrL   r   r   r   r   <module>   sH    <


