U
    9%e                     @   s2  U d dl Z d dlZd dlZd dlmZmZmZmZmZm	Z	m
Z
mZmZmZ d dlmZ d dlZd dlZ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 d dlmZ d dlmZ d d	lm Z  zzd dl!Z!d dl"Z"d d
l#m$Z% e&d d dl'Zd dl(Zd dl)Zd dl*Zd dl+Zd dl,Zd dl-m.Z. d dl/m0Z0m1Z1 dZ2W n e3k
rZ   dZ2Y nX dddddgZ4e5dddZ6e
e7 dddZ8e7dddZ9dd Z:e7ddd Z;e<e=Z>G d!d" d"eZ?ej@jAdd#d$d%ZBej@jAdd&d'd(ZCee7d)f dd*d+ZDej@jAeed)f d#d,d-ZEej@jAed#d.d/ZFej@jAee7d)f d#d0d1ZGee7d)f ee7d)f d2d3d4ZHeejId)f ed5 d6d7d8ZJeejId)f ed5 eejId)f d9d:d;ZKeejId<d=d>ZLd?ee7d)f eejId)f ed5 ee7d)f eejId)f ed5 e5eejId)f d@	dAdBZMd?ee7d)f eejId)f ed5 ee7d)f eejId)f ed5 e5eejId)f d@	dCdDZNG dEdF dFZOe jPG dGdH dHZQee7ee7ee7ef f f ZReeSd< e jPddIeddJG dKd dZTeddJG dLd dZUeddJddMej@jAe	eeTee7ef f  dNdOdZVdS )P    N)
AnyDictFinalListMappingOptionalSequenceSetTupleUnion)	TypeAlias)
FakeTensor)compatibility)FakeTensorProp)OperatorSupport)CALLABLE_NODE_OPS)_pytree)_pybind_stateZ
onnxscript)fx_onnx_interpreter)_TORCH_DTYPE_TO_NUMPY_DTYPE(_TORCH_DTYPE_TO_ONNX_TENSOR_ELEMENT_TYPETFis_onnxrt_backend_supportedtorch_compile_backendOrtExecutionProviderOrtBackendOptions
OrtBackend)returnc                   C   s   t S )a)  Returns ``True`` if ONNX Runtime dependencies are installed and usable
    to support TorchDynamo backend integration; ``False`` otherwise.

    Example::

        # xdoctest: +REQUIRES(env:TORCH_DOCTEST_ONNX)
        >>> import torch
        >>> if torch.onnx.is_onnxrt_backend_supported():
        ...     @torch.compile(backend="onnxrt")
        ...     def f(x):
        ...             return x * x
        ...     print(f(torch.randn(10)))
        ... else:
        ...     print("pip install onnx onnxscript-preview onnxruntime")
        ...
    )_SUPPORT_ONNXRT r   r   _/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/torch/onnx/_internal/onnxruntime.pyr   C   s    c                   C   s   dgS )NCPUExecutionProviderr   r   r   r   r   _infer_default_epsW   s    r!   namec                 C   s   t j rt jj|  dS )zIf PyTorch is installed with CUDA support, this starts NVTX range.

    Check torch.cuda.nvtx.range_push's document for more details.
    N)torchcudais_availablenvtxZ
range_pushr"   r   r   r   _nvtx_range_push]   s    
r(   c                   C   s   t j rt jj  dS )zIf PyTorch is installed with CUDA support, this terminates NVTX range.

    Check torch.cuda.nvtx.range_pop's document for more details.
    N)r$   r%   r&   r'   Z	range_popr   r   r   r   _nvtx_range_popf   s    
r)   Zdevice_typec                 C   sF   | dkrt j S | dkr$t j S | dkr6t j S td|  d S )Nr%   cpuZortzUnsupported device type: )ORTC	OrtDevicer%   r+   Znpu
ValueErrorr*   r   r   r   _get_ort_device_typeo   s    


r/   c                       sZ   e Zd ZdZee eeef d fddZe	ee
jjf e
jjed fddZ  ZS )OrtOperatorSupporta0  Operator support for ONNXRuntime backend.

    It has two-level of support decision. One is via support_dict and the other one
    is via extra_support_dict. The logic of using support_dict is implemented in
    OrtOperatorSupport and extra_support_dict is used by OperatorSupport.is_node_supported.
    )support_dictextra_support_dictc                    s   t  | || _d S N)super__init___onnx_support_dict)selfr1   r2   	__class__r   r   r5      s    zOrtOperatorSupport.__init__)
submodulesnoder   c                    s   |j tkrdS |j dkr>|j| jkr>td|jt|j dS td|jt|j t ||r|td|jt|j dS td|jt|j dS )NFZcall_functionz0support_dict supports node.target: %s (type: %s)Tz7support_dict doesn't support node.target: %s (type: %s)z6extra_support_dict supports node.target: %s (type: %s)z>extra_support_dict doesn't supports node.target: %s (type: %s))	opr   targetr6   loggerwarningtyper4   is_node_supported)r7   r:   r;   r8   r   r   rA      s6    
z$OrtOperatorSupport.is_node_supported)__name__
__module____qualname____doc__r	   r   r   strr5   r   r$   nnModulefxNodeboolrA   __classcell__r   r   r8   r   r0      s    	 r0   graph_moduler   c                 C   sh   | j }g }d}|jD ].}|jdkr,|| |dkr|jdkr|}q|dkrPdS |D ]}|| qTdS )z
    In torch.fx.Graph, placehoder is a special assignment node. If it's not
    executed in the beginning, it could overwrite values computed by upstream
    nodes.
    Nplaceholder)graphnodesr<   appendprepend)rN   rP   placeholdersZfirst_not_placeholderr;   rO   r   r   r   _move_placeholder_to_front   s    


rU   )	fx_moduler   c                 C   s  | j jD ]}t|jtjjr|jjtjj	j
krd}d}d}d}d|jkr^|jd tjkr^d}d|jkr|jd |jd jd jkrd}d|jkrd}|jD ]}|dkrd}qt|jd	kr|r|r|r|rd|jd i|_tjj	jj|_qtd
dd |jD  d|j q|   d S )NTlayoutFdevicer   valdtype)rW   rX   rZ      zaaten._to_copy must be replaced with other ONNX-supported aten ops.                          args=c                 S   s   g | ]
}|j qS r   )meta).0argr   r   r   
<listcomp>   s     z,_replace_to_copy_with_to.<locals>.<listcomp>z	, kwargs=)rP   rQ   
isinstancer=   r$   Z_opsZ
OpOverloadZoverloadpacketZopsatenZ_to_copykwargsZstridedargsr\   rX   lentorZ   RuntimeErrorZ	recompile)rV   r;   Zis_default_layoutZis_on_same_deviceZis_castZare_kwargs_supportedkwargr   r   r   _replace_to_copy_with_to   sR    


rh   .c                  G   sP   g }| D ]>}t |dr|j}|jdkr2|d q|jdkr|d qt|S )zBReturn the first valid device (i.e., GPU or CPU) in argument list.rX   r%   CUDAExecutionProviderr+   r    )hasattrrX   r@   rR   tuple)rc   epsr^   rX   r   r   r   _infer_ep_from_device   s    


rm   c                 C   sX   g }| j jD ]B}|jdkrt|drDd|jkrDt|jd tjsDt|	| qt
|S )NrO   r\   rY   )rP   rQ   r<   rj   r\   r`   r$   TensorAssertionErrorrR   rk   )rN   rT   r;   r   r   r   _extract_graph_module_inputs  s    
rp   c                 C   s2   | j jD ]}|jdkr|jd   S qtddS )zHCollect "val" fields from outputs metadata in this torch.fx.GraphModule.outputr   z2No output node found in this torch.fx.GraphModule.N)rP   rQ   r<   rc   r.   )rN   r;   r   r   r   _extract_graph_module_outputs  s    
rr   c                 C   s(   t t| \}}dd |D }t| S )z[Return the all valid devices (i.e., GPU or CPU) among outputs of this torch.fx.GraphModule.c                 S   s*   g | ]"}t |d rd|jkr|jd qS )r\   rY   rj   r\   )r]   Z
output_argr   r   r   r_      s   
 
z/_infer_ep_from_graph_module.<locals>.<listcomp>)r   Ztree_flattenrr   rm   )rN   Zflattened_output_args_Zselected_output_argsr   r   r   _infer_ep_from_graph_module  s    ru   )rl   r   c                 C   s*   t tddd}t| }tt||ddS )z:Sort execution providers in eps based on pre-set priority.)epr   c                 S   s   | dkrdS | dkrdS dS )Nr       ri   r[   r   r   )rv   r   r   r   get_execution_provider_priority-  s
    z2_sort_eps.<locals>.get_execution_provider_priorityT)keyreverse)rF   intsetrk   sorted)rl   rx   Z
unique_epsr   r   r   	_sort_eps*  s    r~   zORTC.OrtDevice.)valuesr   c                    sH   t fddD stdttddd t fddD }|S )Nc                 3   s   | ]}|j  d  j kV  qdS )r   N)rX   r]   value)r   r   r   	<genexpr>=  s    z$_get_onnx_devices.<locals>.<genexpr>z&All values must be on the same device.)	device_idr   c                 S   s   | pdS )Nr   r   )r   r   r   r   _device_id_or_zeroA  s    z-_get_onnx_devices.<locals>._device_id_or_zeroc                 3   s2   | ]*}t t|jjt j  |jjV  qd S r3   )r,   r-   r/   rX   r@   Zdefault_memoryindexr   )r   r   r   r   D  s   

)allro   r{   rk   )r   devicesr   )r   r   r   _get_onnx_devices<  s    
r   )tensorsr   r   c                 C   sn   t  }|t|  g }g }g }| D ]0}|t|j  ||  ||  q&|	| |||| |S r3   )
r,   OrtValueVectorZreserverd   rR   r   rZ   sizeZdata_ptrpush_back_batch)r   r   Z	ortvaluesZdtypesZshapesZ	data_ptrstensorr   r   r   !_get_ortvalues_from_torch_tensorsO  s    r   )r   r   c                 C   s*   | j rtdtj|  | j| jd}|S )Nz#sparse tensor is not yet supported.)rZ   rX   )Z	is_sparser.   r$   emptyr   rZ   rX   )r   outr   r   r   _to_real_tensor`  s    r   onnxruntime.InferenceSession)	sessinput_namesinputsinput_devicesoutput_namesoutputsoutput_devicespreallocate_outputr   c                 C   s   t d tdd |D }t  t d t||}|rTtdd |D }	t|	|}
nt }
t  t d t }|dd | 	|||||
| t  |r|	S t d	 tj
jj|
}	t  |	S d S )
N
contiguousc                 s   s   | ]}|  V  qd S r3   )r   )r]   ar   r   r   r   r  s     z8_run_onnx_session_with_ortvaluevector.<locals>.<genexpr>r   c                 s   s$   | ]}t |trt|n|V  qd S r3   )r`   r   r   )r]   tr   r   r   r   }  s    run_with_ortvaluevectorZ'disable_synchronize_execution_providers1zafter run_with_ortvaluevector)r(   rk   r)   r   r,   r   onnxruntimeZ
RunOptionsZadd_run_config_entryr   ZtrainingZ	ortmodule_utilsZ_ortvalues_to_torch_tensor)r   r   r   r   r   r   r   r   Z
ort_inputspth_outputsort_outputsZrun_optionsr   r   r   %_run_onnx_session_with_ortvaluevectorg  s@    

     
r   c                 C   s<   dd t ||D }| ||}	tdd t |	|D }
|
S )Nc                 S   s&   i | ]\}}|t j|  qS r   )r   ZOrtValueZortvalue_from_numpyr+   numpy)r]   r#   r   r   r   r   
<dictcomp>  s    z0_run_onnx_session_with_fetch.<locals>.<dictcomp>c                 s   s$   | ]\}}t ||jV  qd S r3   )r$   Z
from_numpyre   rX   )r]   r   r   r   r   r   r     s   z/_run_onnx_session_with_fetch.<locals>.<genexpr>)ziprunrk   )r   r   r   r   r   r   r   r   feedr   r   r   r   r   _run_onnx_session_with_fetch  s    
r   c                   @   sh   e Zd ZdZdeedf ed eedf ed ed ed eeejdf ejf dddZ	d	d
 Z
dS )OrtExecutionInfoPerSessionzWInformation required to execute torch.fx.GraphModule using onnxruntime.InferenceSessionr   .)zonnx.ValueInfoProto.r   sessionr   input_value_infosr   output_value_infosr   r   example_outputsc	           	      C   s4   || _ || _|| _|| _|| _|| _|| _|| _d S r3   r   )	r7   r   r   r   r   r   r   r   r   r   r   r   r5     s    z#OrtExecutionInfoPerSession.__init__c                 G   s   t |t | jkrdS t|| jD ]\}}t|tjs< dS t|j }||jj	j
krZ dS t|j|jj	jjD ]D\}}t|tr|j|ksn|jrqnqnt|tjr|jrqnqn  dS qnq"dS NFT)rd   r   r   r`   r$   rn   r   rZ   r@   Ztensor_typeZ	elem_typeshapedimr{   Z	dim_valueZ	dim_paramZSymInt)r7   rc   r^   Z
value_infoZ
onnx_dtyper   Zonnx_dimr   r   r   is_supported  s&    

z'OrtExecutionInfoPerSession.is_supportedN)rB   rC   rD   rE   r
   rF   r   r$   rn   r5   r   r   r   r   r   r     s   

!r   c                   @   s:   e Zd Zdd ZejjdddZejjedddZ	d	S )
"OrtExecutionInfoForAllGraphModulesc                 C   s
   i | _ d S r3   )execution_info_per_graph_module)r7   r   r   r   r5     s    z+OrtExecutionInfoForAllGraphModules.__init__rN   c                 G   s8   || j krd S | j | }|D ]}|j| r|  S qd S r3   )r   r   )r7   rN   rc   
candidates	candidater   r   r   &search_reusable_session_execution_info  s    



zIOrtExecutionInfoForAllGraphModules.search_reusable_session_execution_info)rN   infoc                 C   s,   || j kr|g| j |< n| j | | d S r3   )r   rR   )r7   rN   r   r   r   r   cache_session_execution_info  s    
z?OrtExecutionInfoForAllGraphModules.cache_session_execution_infoN)
rB   rC   rD   r5   r$   rI   GraphModuler   r   r   r   r   r   r   r     s    r   )frozen)Zis_backward_compatiblec                   @   s~   e Zd ZU dZdZeee  ed< dZ	e
ed< dZeee  ed< dZe
ed< dZe
ed	< dZed
 ed< dZed ed< dS )r   aJ  Options for constructing an ``OrtBackend``, the ONNX Runtime
    backend (``"onnxrt"``) for ``torch.compile``.

    Example::

        >>> @torch.compile(
        ...     backend="onnxrt",
        ...     options=torch.onnx._OrtBackendOptions(...),
        ... )
        ... def ort_function(x):
        ...     return x ** x
    Npreferred_execution_providersTinfer_execution_providersdefault_execution_providersFr   use_aot_autogradztorch.onnx.ExportOptionsexport_optionszonnxruntime.SessionOptionsort_session_options)rB   rC   rD   rE   r   r   r   r   __annotations__r   rK   r   r   r   r   r   r   r   r   r   r     s   

c                   @   s   e Zd ZU dZdee dddZejj	e
eeeeef f  dddZejj	d	d
dZejj	ejj	dddZejj	ejj	dddZdZeed< g Zeed   ed< edeeeeeef f  d dddZedd Zedd ZdS )r   a	  A backend compiles (sub-)graphs in torch.fx.GraphModule to onnxruntime.InferenceSession calls.

    The compiler entry point is OrtBackend.compile, which
        1. partitions the original graph into supported sub-graphs (type: torch.fx.GrpahModule) and unsupported
           sub-graphs.
        2. For each supported sub-graph, it replaces its _wrapped_call function with _ort_accelerated_call.
        3. Inside _ort_accelerated_call, it creates onnxruntime.InferenceSession and calls it to execute the sub-graph.
    Noptionsc                 C   s   |d krt  n|| _tjjj| jjd kr4tj n| jj| _	tjjj
j| j	j}d d d}t||| _i | _t | _d| _d| _ttdrtnt| _d S )N)getattrz_operator.getitemFr   r   )r   _optionsr$   onnx	_internalZexporterZResolvedExportOptionsr   ZExportOptions_resolved_onnx_exporter_optionsrI   decomposition_tableZ'_create_onnx_supports_op_overload_tableonnx_registryr0   _supported_ops_partitioner_cacher   _all_ort_execution_info_assert_allclose_to_baselineexecution_countrj   r,   r   r   r   )r7   r   r1   r2   r   r   r   r5   ^  s,    

zOrtBackend.__init__rM   c                 G   s   t  }| jjr0t|  }r |}nt| }r0|}g }| jjp>g t|| jjpPt D ]T}t	|t
rl|i f}n"t	|t r|d d kr|d i f}|d k	rT||krT|| qT|S )Nr[   r   )rk   r   r   rm   ru   r   r~   r   r!   r`   rF   rR   )r7   rN   rc   Zinferred_epsZeps_from_argsZeps_from_graph_moduleZselected_epsrv   r   r   r   _select_eps  s$    


zOrtBackend._select_epsr   c              
   O   s  | j j|f| }|r>|j}|j}|j}|j}|j}	|j}
ntj	j
jj| jj| }| jjrd| _t|}dd }t||}
n>zt|j||}
W n( tk
r   td| d| _ Y nX tj| jjd}tj	j
jj| jj| }|j|| jj| jjd}|j | jj!j"d}t#j$|% | j&j'| j(|f| d}t)d	d
 |j*j+D }t)dd
 |j*j,D }t-|}t.|
t)rt-|
}	n
t-|
f}	t/||t)dd
 |j*j+D |t)dd
 |j*j,D ||	|
d}| j 0|| |  j1d7  _1t.|
tj2}|r|
fn|
}t.|t)st3t4dd
 |D s.t3t5d | |||||||	| j&j}t6  | j7rtj8j9j:|f|ddi}|r|fn|}t;||D ]\}}tj<=|| q|r|d S |S )a  This function replaces GraphModule._wrapped_call in compiled model.

        The _wrapped_call is the underlying implementation of forward method. Replacing
        it means we delegate the computation to _ort_acclerated_call and therefore
        onnxruntime.InferenceSession.
        Fc                 S   s&   t | drd| jkr| jd S | S d S )Nr\   rY   rs   )r   r   r   r   maybe_map_to_meta_val  s    
z>OrtBackend._ort_acclerated_call.<locals>.maybe_map_to_meta_valzFakeTensorProb failed for %s)diagnostic_context)Zfx_graph_moduleonnxfunction_dispatcherop_level_debug)opset_version)Zpath_or_bytesZsess_options	providersc                 s   s   | ]}|j V  qd S r3   r"   r]   inputr   r   r   r   1  s     z2OrtBackend._ort_acclerated_call.<locals>.<genexpr>c                 s   s   | ]}|j V  qd S r3   r"   r]   rq   r   r   r   r   2  s     c                 s   s   | ]
}|V  qd S r3   r   r   r   r   r   r   ?  s     c                 s   s   | ]
}|V  qd S r3   r   r   r   r   r   r   A  s     r   r[   c                 s   s   | ]}t |tjV  qd S r3   )r`   r$   rn   )r]   elemr   r   r   r   U  s     Z$run_onnx_session_with_ortvaluevectorexecutorra   r   )>r   r   r   r   r   r   r   r   r$   r   r   rI   ZpassesZMovePlaceholderToFrontr   r   r   dynamic_shapesr   rr   r   Ztree_mapr   	propagate	Exceptionr>   r?   r   ZFxOnnxInterpreterZInsertTypePromotionr   r   Zto_model_protor   r   r   ZInferenceSessionZSerializeToStringr   r   r   rk   rP   r   rq   r   r`   r   r   r   rn   ro   r   r(   r)   r   Z_primsr   executer   testingZassert_close)r7   rN   rc   rb   Z!cached_execution_info_per_sessionZonnx_sessionr   r   r   r   Zprim_outputsZextracted_outputsr   Zfx_interpreterZexportedZ
onnx_modelZexecution_info_per_sessionZis_single_tensor_outputZnormalized_prim_outputsZonnx_outputsZbaseline_outputsZnormalized_baseline_ouptutsZonnx_outputZbaseline_outputr   r   r   _ort_acclerated_call  s    

   

 
 zOrtBackend._ort_acclerated_callc           	      C   s   ddl m} || jkr"| j| }nd|}t| ||| jdd}| }|| j|< |jjD ],}|jdkrXd|j	krXt
||j	}| j|_qX|S )Nr   )CapabilityBasedPartitionerT)Zallows_single_node_partitionZcall_moduleZfused_)Z!torch.fx.passes.infra.partitionerr   r   rh   r   Zpartition_and_fuserP   rQ   r<   r#   r   r   Z_wrapped_call)	r7   rN   rc   r   Zpartitioned_prim_graph_moduleZprim_graph_moduleZpartitionerr;   Zfused_moduler   r   r   compiler  s"    


zOrtBackend.compilec                 C   sF   | j jr:ddlm} ddlm} || j|| jjd||S | ||S )zIf ``OrtBackendOptions.use_aot_autograd`` is ``True``, the `auto_autograd` compiler
        will be invoked, wrapping this ``OrtBackend`` instance's ``compile`` method. Otherwise,
        the ``compile`` method is invoked directly.r   )#min_cut_rematerialization_partition)aot_autograd)Zfw_compilerZpartition_fnZdecompositions)	r   r   Zfunctorch.compiler   Ztorch._dynamo.backends.commonr   r   r   r   )r7   rN   rc   r   r   r   r   r   __call__  s     zOrtBackend.__call__   %_OrtBackend__instance_cache_max_count_OrtBackend__instance_cache)r   r   c                    s   t t dddt t s(t f  p$i  t fddtjD d}|dkrttjtjk sztdtj dt d	t d
tjt  } |S )a  Returns a possibly cached instance of an ``OrtBackend``. If an existing
        backend was created previously through this function with the same options,
        it will be returned. Otherwise a new backend will be created, cached, and
        returned.

        Note: if ``options`` sets ``ort_session_options``, a new ``OrtBackend``
        will always be returned, since ``onnxruntime.SessionOptions`` cannot
        participate in caching.r   bc                 S   s   | j |j ks<| j|jks<| j|jks<| j|jks<| j|jkr@dS | jd k	sT|jd k	rXdS | j|jkrhdS | jd k	r|jd k	r| jj|jjko| jj|jjko| jj	|jj	ko| jj
|jj
ko| jj|jjkS dS r   )r   r   r   r   r   r   r   r   r   Zdiagnostic_optionsr   Zfake_contextr   r   r   r   reusable  s<    




z<OrtBackend.get_cached_instance_for_options.<locals>.reusablec                 3   s   | ]}|j  r|V  qd S r3   )r   )r]   r   r   r   r   r   r     s      z=OrtBackend.get_cached_instance_for_options.<locals>.<genexpr>NzNo more than z instances of z allowed. Please instantiate `z` explicitly to pass to `torch.compile`. See https://github.com/pytorch/pytorch/pull/107973#discussion_r1306144795 for discussion.)	r   r`   nextr   r   rd   r   ro   rR   )r   backendr   r   r   get_cached_instance_for_options  s    $
	z*OrtBackend.get_cached_instance_for_optionsc                   C   s   t j  d S r3   )r   r   clearr   r   r   r   clear_cached_instances  s    z!OrtBackend.clear_cached_instancesc                   C   s
   t tjS r3   )rk   r   r   r   r   r   r   get_cached_instances  s    zOrtBackend.get_cached_instances)N)N)rB   rC   rD   rE   r   r   r5   r$   rI   r   r   r
   rF   r   r   r   r   r   r   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r   r   S  s.   
	L! ): F
r   )rN   r   c                C   s   t || |S r3   )r   r   )rN   rc   r   r   r   r   r     s    )Wdataclasses	importlibloggingtypingr   r   r   r   r   r   r   r	   r
   r   Ztyping_extensionsr   r$   Ztorch._CZ
torch._opsZtorch._prims.executorZtorch.fxZtorch._subclasses.fake_tensorr   Ztorch.fx._compatibilityr   Z torch.fx.passes.fake_tensor_propr   Z torch.fx.passes.operator_supportr   Ztorch.fx.passes.tools_commonr   Ztorch.utilsr   r   r   Zonnxruntime.capir   r,   import_moduleZ
torch.onnxZtorch.onnx._internalZ torch.onnx._internal.diagnosticsZtorch.onnx._internal.exporterZ+torch.onnx._internal.fx.decomposition_tableZtorch.onnx._internal.fx.passesZtorch.onnx._internal.fxr   Z"torch.onnx._internal.fx.type_utilsr   r   r   ImportError__all__rK   r   rF   r!   r(   r)   r/   	getLoggerrB   r>   r0   rI   r   rU   rh   rm   rp   rr   ru   r~   rn   r   r   r   r   r   r   	dataclassr   r   r   r   r   r   r   r   r   r   <module>   s    0

			
7-

  

2

;!$
9   @