U
    Mhy                     @   sT   d dl Z d dlZd dlZd dlmZmZ d dlZeddd ZG dd dZ	dS )    N)ListUnionc                  C   s>   z"dd l } dd l}ddl m} W dS  tk
r8   Y dS X d S )Nr   )torchTF)safetensorstransformersr   ImportError)r   r   Zsafetensors_torch r   Q/var/www/html/venv/lib/python3.8/site-packages/torch/onnx/_internal/fx/patcher.py has_safetensors_and_transformers   s    r
   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ONNXTorchPatcheraH  Context manager to temporarily patch PyTorch during FX-to-ONNX export.

    This class is a collection of "patches" required by FX-to-ONNX exporter.

    This context overrides several torch functions to support symbolic
    export of large scale models.

    torch.load:
        This function is patched to record the files PyTorch stores model
        parameters and buffers. Downstream FX-to-ONNX exporter can create
        initializers from these files.
    torch.fx._symbolic_trace._wrapped_methods_to_patch:
        This list is extended with (torch.Tensor, "__getitem__") so that
        weight[x, :, y] becomes exportable with torch.fx.symbolic_trace.
    safetensors.torch.load_file:
        This function is patched to allow safetensors to be loaded within
        FakeTensorMode. Remove after https://github.com/huggingface/safetensors/pull/318

    Search for ONNXTorchPatcher in test_fx_to_onnx_with_onnxruntime.py for
    example usage.

    TODO: Should this really be a global patcher? Can we make it a local patcher?
        A reason for splitting this into several patchers is to patch one part of the code
        as a collateral damage of patching another part of the code. For example, we
        for tracing model with torch._dynamo.export, we don't need to patch
        `torch.fx._symbolic_trace._wrapped_methods_to_patch`
    c                    sd   g _ fdd}tj_|_t r`dd l dd l}d fdd	} jj_	|_
|jj_d S )Nc                    s    j |   j| f||S )N)pathsappend
torch_load)fargskwargs)selfr   r	   torch_load_wrapper:   s    z5ONNXTorchPatcher.__init__.<locals>.torch_load_wrapperr   cpuc              	      s   j |  i } jj| d|db}| D ]R}tj }|sN||||< q,||}tj	t
|  j| d||< q,W 5 Q R X |S )Npt)Z	frameworkdevice)Zdtype)r   r   r   Z	safe_openkeysZ_guardsZdetect_fake_modeZ
get_tensorZ	get_sliceemptytuple	get_shapeZ	_getdtypeZ	get_dtype)filenamer   resultr   kZ	fake_modeZempty_tensorr   r   r   r	   safetensors_load_file_wrapperJ   s(      


z@ONNXTorchPatcher.__init__.<locals>.safetensors_load_file_wrapper)r   )r   r   loadr   r   r
   r   r   	load_filesafetensors_torch_load_file#safetensors_torch_load_file_wrappermodeling_utilssafe_load_file*transformers_modeling_utils_safe_load_file)r   r   r   r   r   r   r	   __init__6   s    
zONNXTorchPatcher.__init__c                 C   sz   | j t_tjjj| _ttjjj}tj	df|krB|
tj	df |tjj_t rvdd l}dd l}| j|j_| j|j_d S )N__getitem__r   )r   r   r    fx_symbolic_trace_wrapped_methods_to_patch2torch_fx__symbolic_trace__wrapped_methods_to_patchcopydeepcopyZTensorr   r
   r   r   r#   r!   r$   r%   )r   Zdesired_wrapped_methodsr   r   r   r   r	   	__enter__e   s    

zONNXTorchPatcher.__enter__c                 C   sB   | j t_| jtjj_t r>dd l}dd l	}| j
|j_| j|j_d S )Nr   )r   r   r    r,   r)   r*   r+   r
   r   r   r"   r!   r&   r$   r%   )r   exc_type	exc_value	tracebackr   r   r   r   r	   __exit__   s    
zONNXTorchPatcher.__exit__N)__name__
__module____qualname____doc__r'   r/   r3   r   r   r   r	   r      s   /r   )
r-   	functoolsiotypingr   r   r   	lru_cacher
   r   r   r   r   r	   <module>   s   
