o
     i                  	   @   s   d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZm	Z	m
Z
mZmZ d dlZedddgZded	ed
ee fddZd
e	eege	egef f fddZde
eef ded
efddZ	dde	dedeeej  d
efddZdS )    N)
namedtuple)fields)AnyCallableDictListOptionalItemconstructorconfigrootbase_modulereturnc                 C   sj   g }t | D ]+}|dr2|ds2|d |d }|tjvr2d||g}t	| |
| q|S )N).pyz.pyc_r   .)oslistdirendswith
startswithfindsysmodulesjoin	importlibimport_moduleappend)r   r   r   filemodulemodule_name r    B/home/ubuntu/.local/lib/python3.10/site-packages/xformers/utils.pyimport_all_modules   s   


r"   c                    s"   |fdt dtf fdd}|S )Nnamer   c                    s    fdd}|S )zRegisters a subclass.

        This decorator allows xFormers to instantiate a given subclass
        from a configuration file, even if the class itself is not part of the
        xFormers library.c                    sp    v rt dt| st d| jj| jv r(t d| jt| d < | j | S )Nz#Cannot register duplicate item ({})z,Item ({}: {}) must extend the base class: {}z3Cannot register item with duplicate class name ({}))r
   r   )
ValueErrorformat
issubclass__name__r	   add)cls)class_registryr   r#   name_registryreference_classr    r!   register_cls+   s"   


zCget_registry_decorator.<locals>.register_item.<locals>.register_clsr    )r#   r   r-   r*   r+   r,   )r   r#   r!   register_item$   s   z-get_registry_decorator.<locals>.register_item)strr   )r*   r+   r,   default_configr/   r    r.   r!   get_registry_decorator!   s   r2   supersetconfig_classc                    sX   t tdd t|  fdd|  D } D ]}|| vr$d||< q|di |S )zaGiven a superset of the inputs and a reference config class,
    return exactly the needed configc                 S   s   | j S )N)r#   )xr    r    r!   <lambda>I   s    z*generate_matching_config.<locals>.<lambda>c                    s   i | ]\}}| v r||qS r    r    ).0kvfield_namesr    r!   
<dictcomp>J   s    z,generate_matching_config.<locals>.<dictcomp>Nr    )listmapr   itemskeys)r3   r4   subsetr8   r    r:   r!   generate_matching_configD   s   rB      fnrepgrad_to_nonec                 C   s  t j t j krtd|   |dur&|D ]}|  |d d|_qt j }t j	| |   W d   n1 s?w   Y  t j
  t jjdd}t jjdd}|  |  |  t j
  ||}tdt|| }t j }t j	| t|D ]}	|dur|D ]}d|_q|   qW d   n1 sw   Y  t j
  g }
d}t|D ]+}	t jjdd}t jjdd}|  |  |  t j
  |
||| g7 }
qt t |
 S )a  
    Benchmark the runtime of the provided function.
    Args:
        fn: Function to benchmark
        rep: Repetition time (in ms)
        grad_to_none: Reset the gradient of the provided tensor to None
    Returns:
        Benchmarked runtime in ms
    zQCannot capture graph in default stream. Please use side stream in benchmark code.NT)enable_timing   
   )torchcudacurrent_streamdefault_streamRuntimeErrordetach_requires_grad_grad	CUDAGraphgraphsynchronizeEventrecordreplayelapsed_timemaxintrangemeantensoritem)rD   rE   rF   r5   gstart_event	end_eventestimate_msn_repeatiret	n_retriesr    r    r!   do_bench_cudagraphU   sX   







rg   )rC   N)r   r   r   collectionsr   dataclassesr   typingr   r   r   r   r   rJ   r	   r0   r"   r2   rB   rZ   Tensorfloatrg   r    r    r    r!   <module>   s.   
#