U
    5-e                     @   s  U 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Zd dl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 d dlmZ d dlmZ d dlm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'm(Z( dZ)e*dj+Z,e*dj+Z-e*dj+Z.dZ/dZ0dZ1e e2ej3ee!e4 f Z5e#e6d< ee eej7e2gej7f ej8e2ee2e2f f  Z9e#e6d< e eej:j;ej<f Z=e#e6d< dddddddddddd d!d"d#d$gZ>G d%d de?Z@ed&d ZAg ZBG d'd" d"eZCdaDeeC e6d(< eeC d)d*d#ZEd+d$ ZFeGd)d,d-ZHeIee=gee2 f ee=e2gee= f d.d/dZJdd1dZKd2d3 ZLd4d5 ZMd6d7 ZNd8d9 ZOd:d; ZPd<d= ZQd>d? ZRd@d ZSdAdB ZTdCd ZUdDdE ZVdFdG ZWdHdI ZXdJdK ZYdLdM ZZeJdNeLeR eJdOeMeT eJdPeOeW eJdQePeX eJdReQeZ eJdSeNeV e eej:j;ej<f dTdUdZ[dVd Z\dWd Z]dXd Z^dYdZ Z_G d[d\ d\Z`G d]d^ d^e`ZaG d_d` d`e`ZbG dadb dbe`Zcdcdd ZdG dedf dfe`ZeG dgdh dhe`ZfG didj dje`Zgdkdl ZheGd)dmdnZidodp ZjeGd)dqdrZkdd)dsdtZldudv Zme%e)d0dwfene5eeIeGeGddxdydZodd)dzd{Zpd|d} Zqddwdd~e5e9eeGeeG eeddd Zrdd Zsi es_te$%ejudd  dd Zve e4e2f e2dddZwdd ZxG dd! d!ZydddZzdd Z{dS )    N)closingcontextmanager)Enum   )_import_dotted_name)get_source_lines_and_file)Storage)#_get_dtype_from_pickle_storage_type)
AnyBinaryIOCallablecastDictOptionalTypeTupleUnionIO)	TypeAlias   z=lz=iz=hl   l|9QC
 i  ,	FILE_LIKEMAP_LOCATIONSTORAGESourceChangeWarningmkdtempregister_package%check_module_version_greater_or_equalvalidate_cuda_devicevalidate_hpu_devicelocation_tagdefault_restore_locationnormalize_storage_typestorage_to_tensor_typesaveloadStorageTypeLoadEndiannessget_default_load_endiannessset_default_load_endiannessc                   @   s   e Zd ZdS )r   N)__name__
__module____qualname__ r-   r-   T/var/www/html/Darija-Ai-Train/env/lib/python3.8/site-packages/torch/serialization.pyr   :   s   c               	   c   s$   t  } z
| V  W 5 t|  X d S N)tempfiler   shutilrmtreepathr-   r-   r.   r   >   s    
c                   @   s   e Zd ZdZdZdZdS )r'   r   r      N)r*   r+   r,   NATIVELITTLEBIGr-   r-   r-   r.   r'   I   s   _default_load_endianreturnc                   C   s   t S )a  
    Get fallback byte order for loading files

    If byteorder mark is not present in saved checkpoint,
    this byte order is used as fallback.
    By default, it's "native" byte order.

    Returns:
        default_load_endian: Optional[LoadEndianness]
    )r9   r-   r-   r-   r.   r(   P   s    c                 C   s"   t | ts| dk	rtd| adS )z
    Set fallback byte order for loading files

    If byteorder mark is not present in saved checkpoint,
    this byte order is used as fallback.
    By default, it's "native" byte order.

    Args:
        endianness: the new fallback byte order
    Nz=Invalid argument type in function set_default_load_endianness)
isinstancer'   	TypeErrorr9   )Z
endiannessr-   r-   r.   r)   ]   s    c                 C   s`   g }|   }| d}|dkrB|| t|dkr6qB| d}q| | ddddg}||kS )Nr             P   K      )tellreadappendlenseek)f
read_bytesstartbyteZlocal_header_magic_numberr-   r-   r.   _is_zipfilem   s    	


rM   )prioritytaggerdeserializerc                 C   s    | ||f}t | t   dS )a  
    Registers callables for tagging and deserializing storage objects with an associated priority.
    Tagging associates a device with a storage object at save time while deserializing moves a
    storage object to an appropriate device at load time. :attr:`tagger` and :attr:`deserializer`
    are run in the order given by their :attr:`priority` until a tagger/deserializer returns a
    value that is not `None`.

    To override the deserialization behavior for a device in the global registry, one can register a
    tagger with a higher priority than the existing tagger.

    This function can also be used to register a tagger and deserializer for new devices.

    Args:
        priority: Indicates the priority associated with the tagger and deserializer, where a lower
            value indicates higher priority.
        tagger: Callable that takes in a storage object and returns its tagged device as a string
            or None.
        deserializer: Callable that takes in storage object and a device string and returns a storage
            object on the appropriate device or None.

    Returns:
        `None`

    Example:
        >>> def ipu_tag(obj):
        >>>     if obj.device.type == 'ipu':
        >>>         return 'ipu'
        >>> def ipu_deserialize(obj, location):
        >>>     if location.startswith('ipu'):
        >>>         ipu = getattr(torch, "ipu", None)
        >>>         assert ipu is not None, "IPU device module is not loaded"
        >>>         assert torch.ipu.is_available(), "ipu is not available"
        >>>         return obj.ipu(location)
        >>> torch.serialization.register_package(11, ipu_tag, ipu_deserialize)
    N)_package_registryrF   sort)rN   rO   rP   Z
queue_elemr-   r-   r.   r      s    (

Tc              
      s   z2| j d t fddt|D }||k}W nb tk
r } zDd| j d| j  dt| }|rrt||nt	|d  d}W 5 d	}~X Y nX |S )
a  
    Check if a module's version satisfies requirements

    Usually, a module's version string will be like 'x.y.z', which would be represented
    as a tuple (x, y, z), but sometimes it could be an unexpected format. If the version
    string does not match the given tuple's format up to the length of the tuple, then
    error and exit or emit a warning.

    Args:
        module: the module to check the version of
        req_version_tuple: tuple (usually of ints) representing the required version
        error_if_malformed: whether we should exit if module version string is malformed

    Returns:
        requirement_is_met: bool
    .c                 3   s"   | ]\}}t | | V  qd S r/   )type).0idxZ	req_fieldZversion_strsr-   r.   	<genexpr>   s    z8check_module_version_greater_or_equal.<locals>.<genexpr>'z&' module version string is malformed 'z$' and cannot be compared with tuple z1, but continuing assuming that requirement is metTN)
__version__splittuple	enumerate	Exceptionr*   strRuntimeErrorwarningswarn)moduleZreq_version_tupleZerror_if_malformedZmodule_versionZrequirement_is_metemessager-   rW   r.   r      s    c                 C   s   | j jdkrdS d S NcpudevicerT   objr-   r-   r.   _cpu_tag   s    rl   c                 C   s    | j jdkrdt| j j S d S )Ncudazcuda:ri   rT   r_   indexrj   r-   r-   r.   	_cuda_tag   s    rp   c                 C   s    | j jdkrdt| j j S d S )Nhpuzhpu:rn   rj   r-   r-   r.   _hpu_tag   s    rr   c                 C   s   | j jdkrdS d S Nmpsrh   rj   r-   r-   r.   _mps_tag   s    ru   c                 C   s   | j jdkrdS d S )Nmetarh   rj   r-   r-   r.   	_meta_tag   s    rw   c                 C   s>   t j }| jj|kr:| jjd kr&|S |d t| jj S d S )N:)torch_C_get_privateuse1_backend_nameri   rT   ro   r_   )rk   backend_namer-   r-   r.   _privateuse1_tag   s
    
r}   c                 C   s   |dkr| S d S rf   r-   rk   locationr-   r-   r.   _cpu_deserialize   s    r   c                 C   sN   t jj| d}t j s"tdt j }||krJtd| d| d|S )NTzAttempting to deserialize object on a CUDA device but torch.cuda.is_available() is False. If you are running on a CPU-only machine, please use torch.load with map_location=torch.device('cpu') to map your storages to the CPU.z0Attempting to deserialize object on CUDA device z" but torch.cuda.device_count() is U. Please use torch.load with map_location to map your storages to an existing device.)ry   rm   _utils_get_device_indexis_availabler`   device_count)r   ri   r   r-   r-   r.   r      s    

c              
   C   sf   | drbt|}t| ddrXtj|& tj|  t|dW  5 Q R  S Q R X n
| |S d S )Nrm   _torch_load_uninitializedFri   )
startswithr   getattrry   rm   ri   UntypedStoragenbytes)rk   r   ri   r-   r-   r.   _cuda_deserialize  s    
,r   c                 C   sf   t tdd }|d k	std|jj| dd}| s<td| }||krbtd| d| d|S )	Nrq   HPU device module is not loadedT)optionalzAttempting to deserialize object on a HPU device but torch.hpu.is_available() is False. If you are running on a CPU-only machine, please use torch.load with map_location=torch.device('cpu') to map your storages to the CPU.z/Attempting to deserialize object on HPU device z! but torch.hpu.device_count() is r   )r   ry   AssertionErrorr   r   r   r`   r   )r   rq   ri   r   r-   r-   r.   r     s    c              
   C   s   t tdd }|d k	std|dr|t|}t | ddrr||& tj|  t|dW  5 Q R  S Q R X n
| |S d S )Nrq   r   r   Fr   )	r   ry   r   r   r   ri   r   r   rq   )rk   r   rq   ri   r-   r-   r.   _hpu_deserialize.  s    
,r   c                 C   s   | dr|  S d S rs   )r   rt   r~   r-   r-   r.   _mps_deserialize:  s    
r   c                 C   s   |dkrt j|  ddS d S )Nrv   r   )ry   r   r   r~   r-   r-   r.   _meta_deserialize?  s    r   c              
   C   s   t | }|jr|jnd}tt |s8td|  dtt |}t|drn| sntd|  d| dt|dr| }||krtd	|  d
| d| d| d	|S )Nr   zThe z device module is not registered. If you are running on a CPU-only machine, please use torch.load with map_location=torch.device('cpu') to map your storages to the CPU.r   z&Attempting to deserialize object on a z device but torch.z.is_available() is False. If you are running on a CPU-only machine, please use torch.load with map_location=torch.device('cpu') to map your storages to the CPU.r   z$Attempting to deserialize object on z device z but torch.z.device_count() is r   )	ry   ri   ro   hasattrr`   upperr   r   r   )r   r|   ri   device_indexZdevice_moduler   r-   r-   r.   _validate_privateuse1_deviceD  s    



&r   c              
   C   s`   t j }||r\t| |sDtd|  d| d| d| d	t||}t| ||S d S )Nz'Attempting to load the storages to the z' device but torch.storage._StorageBase.z!() or torch.storage.TypedStorage.zi() is not generated. Please use torch.utils.generate_methods_for_privateuse1_backend to generate storage.z() method first.)	ry   rz   r{   r   r   r`   r   r   r   )rk   r   r|   r   r-   r-   r.   _privateuse1_deserialize]  s    


&
r   
                  )storagec                 C   s:   t D ]\}}}|| }|r|  S qtdt|  d S )Nz-don't know how to determine data location of rQ   r`   ry   typename)r   _rO   r   r-   r-   r.   r    r  s    
c                 C   sL   t D ]$\}}}|| |}|d k	r|  S qtdt|  d | d d S )Nz+don't know how to restore data location of z (tagged with )r   )r   r   r   fnresultr-   r-   r.   r!   {  s    

c                 C   s   t t| jS r/   )r   ry   r*   )storage_typer-   r-   r.   r"     s    c                 C   s&   t | }t|j}t||jddS )Nr   Tensor)rT   r   r+   r   r*   replace)r   r   rc   r-   r-   r.   r#     s    
c                 C   s   t | ttjfS r/   )r<   r_   pathlibPath)name_or_bufferr-   r-   r.   _is_path  s    r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )_openerc                 C   s
   || _ d S r/   	file_like)selfr   r-   r-   r.   __init__  s    z_opener.__init__c                 C   s   | j S r/   r   r   r-   r-   r.   	__enter__  s    z_opener.__enter__c                 G   s   d S r/   r-   r   argsr-   r-   r.   __exit__  s    z_opener.__exit__N)r*   r+   r,   r   r   r   r-   r-   r-   r.   r     s   r   c                       s$   e Zd Z fddZdd Z  ZS )
_open_filec                    s   t  t|| d S r/   )superr   open)r   namemode	__class__r-   r.   r     s    z_open_file.__init__c                 G   s   | j   d S r/   )r   closer   r-   r-   r.   r     s    z_open_file.__exit__r*   r+   r,   r   r   __classcell__r-   r-   r   r.   r     s   r   c                       s   e Zd Z fddZ  ZS )_open_buffer_readerc                    s   t  | t| d S r/   )r   r   _check_seekable)r   bufferr   r-   r.   r     s    z_open_buffer_reader.__init__r*   r+   r,   r   r   r-   r-   r   r.   r     s   r   c                   @   s   e Zd Zdd ZdS )_open_buffer_writerc                 G   s   | j   d S r/   )r   flushr   r-   r-   r.   r     s    z_open_buffer_writer.__exit__N)r*   r+   r,   r   r-   r-   r-   r.   r     s   r   c                 C   sD   t | rt| |S d|kr"t| S d|kr2t| S td| d S )Nwrz$Expected 'r' or 'w' in mode but got )r   r   r   r   r`   )r   r   r-   r-   r.   _open_file_like  s    
r   c                       s"   e Zd Zdd fddZ  ZS )_open_zipfile_readerNr:   c                    s   t  tj| d S r/   )r   r   ry   rz   ZPyTorchFileReader)r   r   r   r-   r.   r     s    z_open_zipfile_reader.__init__r   r-   r-   r   r.   r     s   r   c                       s0   e Zd Zdd fddZddddZ  ZS )_open_zipfile_writer_fileNr:   c                    sx   d | _ t|| _z| jd W n< tk
r\   tj| jdd| _ t t	j
| j  Y nX t t	j
| j d S )Nasciir   )r   )file_streamr_   r   encodeUnicodeEncodeErrorioFileIOr   r   ry   rz   PyTorchFileWriterr   r   r   r-   r.   r     s    
z"_open_zipfile_writer_file.__init__c                 G   s"   | j   | jd k	r| j  d S r/   )r   write_end_of_filer   r   r   r-   r-   r.   r     s    

z"_open_zipfile_writer_file.__exit__r   r-   r-   r   r.   r     s   r   c                       s0   e Zd Zdd fddZddddZ  ZS )_open_zipfile_writer_bufferNr:   c                    sb   t t|dd sDdtt|d d}t|ds<t|t||| _t	 
tj| d S )Nwritez
Buffer of z<>z" has no callable attribute 'write')callabler   r_   rT   stripr   AttributeErrorr=   r   r   r   ry   rz   r   )r   r   msgr   r-   r.   r     s    
z$_open_zipfile_writer_buffer.__init__c                 G   s   | j   | j  d S r/   )r   r   r   r   r   r-   r-   r.   r     s    
z$_open_zipfile_writer_buffer.__exit__r   r-   r-   r   r.   r     s   	r   c                 C   s   t | rt}nt}|| S r/   )r   r   r   )r   	containerr-   r-   r.   _open_zipfile_writer  s    r   c                 C   s.   dg}z| j |kW S  tk
r(   Y dS X d S )NgzipF)r+   r   )rI   Zcompress_modulesr-   r-   r.   _is_compressed_file  s
    r   c                 C   sL   t | rdS z|  dkW S  tjk
r2   Y dS  tk
rF   Y dS X dS )z
    Checks if f is a file that should be read directly. It should be read
    directly if it is backed by a real file (has a fileno) and is not a
    a compressed file (e.g. gzip)
    Fr   N)r   filenor   UnsupportedOperationr   rI   r-   r-   r.   _should_read_directly  s    r   c              
   C   sX   dd }z|  |   W dS  tjtfk
rR } z|ddg| W 5 d }~X Y nX dS )Nc                 S   s>   | D ]0}|t |krt |d d d }t||q|d S )Nz7. You can only torch.load from a file that is seekable.z; Please pre-load the data into a buffer like io.BytesIO andz try to load from it instead.)r_   rT   )patternsrd   pr   r-   r-   r.   raise_err_msg	  s    
z&_check_seekable.<locals>.raise_err_msgTrH   rD   F)rH   rD   r   r   r   )rI   r   rd   r-   r-   r.   r     s    	 r   c                 C   sH   | dk	rD| j dkrDd}t| |dsDtdddd |D | jdS )	zChecks if using dill as the pickle module, and if so, checks if it is the correct version.
    If dill version is lower than 0.3.1, a ValueError is raised.

    Args:
        pickle_module: module used for pickling metadata and objects

    NZdill)r   r5   r   Fz\'torch' supports dill >= {}, but you have dill {}. Please upgrade dill or switch to 'pickle'rS   c                 S   s   g | ]}t |qS r-   )r_   )rU   numr-   r-   r.   
<listcomp>)  s     z'_check_dill_version.<locals>.<listcomp>)r*   r   
ValueErrorformatjoinrZ   )pickle_moduleZrequired_dill_versionr-   r-   r.   _check_dill_version  s    r   c                 C   s&   t | ttjfs"t| ds"tdd S )Nr   zOexpected 'f' to be string, path, or a file-like object with a 'write' attribute)r<   r_   osPathLiker   r   r   r-   r-   r.   _check_save_filelike.  s    r   F)rk   rI   r   pickle_protocol_use_new_zipfile_serialization_disable_byteorder_recordr;   c              	   C   sx   t jd t| t| |rPt| }t| |||| W 5 Q R  dS Q R X n$t|d}t| ||| W 5 Q R X dS )aP  save(obj, f, pickle_module=pickle, pickle_protocol=DEFAULT_PROTOCOL, _use_new_zipfile_serialization=True)

    Saves an object to a disk file.

    See also: :ref:`saving-loading-tensors`

    Args:
        obj: saved object
        f: a file-like object (has to implement write and flush) or a string or
           os.PathLike object containing a file name
        pickle_module: module used for pickling metadata and objects
        pickle_protocol: can be specified to override the default protocol

    .. note::
        A common PyTorch convention is to save tensors using .pt file extension.

    .. note::
        PyTorch preserves storage sharing across serialization. See
        :ref:`preserve-storage-sharing` for more details.

    .. note::
        The 1.6 release of PyTorch switched ``torch.save`` to use a new
        zipfile-based file format. ``torch.load`` still retains the ability to
        load files in the old format. If for any reason you want ``torch.save``
        to use the old format, pass the kwarg ``_use_new_zipfile_serialization=False``.

    Example:
        >>> # xdoctest: +SKIP("makes cwd dirty")
        >>> # Save to file
        >>> x = torch.tensor([0, 1, 2, 3, 4])
        >>> torch.save(x, 'tensor.pt')
        >>> # Save to io.BytesIO buffer
        >>> buffer = io.BytesIO()
        >>> torch.save(x, buffer)
    z
torch.saveNwb)	ry   rz   _log_api_usage_oncer   r   r   _saver   _legacy_save)rk   rI   r   r   r   r   opened_zipfileopened_filer-   r-   r.   r$   5  s    0
c              	      s   dd l m  i i i ttt d fdd}tttjdktt	t
tdd}|jt||d |jt||d |j|||d |j||d}||_||  t }|j|||d |  |D ],}| \}	}
|	|t|d	tj|
 qd S )
Nr   )rk   r;   c                    s  t | trt|  jr| kr"d S d| < d  }}zt| \}}}d|}W n( tk
rv   td| j	 d  Y nX d| ||fS t | t
jjst
| rt | t
jjr| j}| j}|  }tt
|}| j}	|  }
nFt | t
jr| }t
j}tt| }t
j}	| }
ntdt|  | dkrd| krX||  krdtdn|| < d}t|j}t|}|kr||	f|< |j|jk}|rt|j|| f}nd }d	||||
|f}|S d S )
NT 4Couldn't retrieve source code for container of type 3. It won't be checked for correctness upon loading.rc   ztype not recognized: r   SCannot save multiple tensors or storages that view the same data as different typesr   )r<   rT   
issubclassModuler   r   r^   ra   rb   r*   ry   r   TypedStorage
is_storage_untyped_storagedtype_pickle_storage_typer   _sizer   uint8r"   r   r=   data_ptrr`   r_   _cdatar    )rk   source_filesourceZsource_linesr   r   storage_dtypestorage_type_strr   r  storage_numeloffsetstorage_keyr   Zis_viewview_metadataresnnZserialized_container_typesserialized_storagesstorage_dtypesr-   r.   persistent_id}  sn    




z#_legacy_save.<locals>.persistent_idlittle)shortintlong)protocol_versionZlittle_endianZ
type_sizesprotocolT)Ztorch.nnr  r
   r   r   dictPROTOCOL_VERSIONsys	byteorder
SHORT_SIZEINT_SIZE	LONG_SIZEdumpMAGIC_NUMBERPicklerr  sortedkeysr   Z_write_filer   ry   r   _element_size)rk   rI   r   r   r  Zsys_infopicklerZserialized_storage_keyskeyr   r  r-   r  r.   r   r  s4    l

r   c                    s   i i  i  fdd}t  }|j||d}||_||  | }|d|t| |stj	dkrxt
dtj	 |dtj	ttj	 t D ]D}	d|	 }
|	 }|jjd	kr| }| }||
| | qd S )
Nc                    s   t | tjjst| rt | tjjrN| j}| j}|  }tt|}| 	 }n| }tj
}tt| }| }| dkr| kr||  krtdn|| <  |jtt }t|}||< d||||fS d S )Nr   r   r   )r<   ry   r   r   r   r   r  r  r   r  r  r"   rT   r   r  r`   
setdefaultr  r_   rG   r    )rk   r   r	  r
  r   r  r  r   Zid_mapr  r  r-   r.   r    s8    

z_save.<locals>.persistent_idr  data.pkl)r  bigUnknown endianness type: r  data/rg   )r   BytesIOr%  r  r#  getvalueZwrite_recordrG   r  r  r   r&  r'  ri   rT   rg   r   r  )rk   zip_filer   r   r   r  Zdata_bufr)  Z
data_valuer*  r   r   	num_bytesr-   r,  r.   r     s*    0


r   )weights_onlymmap)rI   map_locationr   r5  r6  pickle_load_argsr;   c                K   sZ  t jd d}tdd dkr(d}|r>|dk	rJtdn|dkrJt}|dkrVd	}t| d
|	 krrd|d
< t
| d}t|r| }d}	t| }
t|
rtdt || t jj||dW  5 Q R  W  5 Q R  S |rt| tstdtj| }t j| d	|}	|rz2t|
|tfd|	i|W W  5 Q R  W  5 Q R  S  tk
r } zt|t| dW 5 d}~X Y nX t|
||fd|	i|W  5 Q R  W  5 Q R  S Q R X |rtdd|r4zt||tf|W W  5 Q R  S  tk
r2 } zt|t| dW 5 d}~X Y nX t|||f|W  5 Q R  S Q R X dS )a  load(f, map_location=None, pickle_module=pickle, *, weights_only=False, mmap=None, **pickle_load_args)

    Loads an object saved with :func:`torch.save` from a file.

    :func:`torch.load` uses Python's unpickling facilities but treats storages,
    which underlie tensors, specially. They are first deserialized on the
    CPU and are then moved to the device they were saved from. If this fails
    (e.g. because the run time system doesn't have certain devices), an exception
    is raised. However, storages can be dynamically remapped to an alternative
    set of devices using the :attr:`map_location` argument.

    If :attr:`map_location` is a callable, it will be called once for each serialized
    storage with two arguments: storage and location. The storage argument
    will be the initial deserialization of the storage, residing on the CPU.
    Each serialized storage has a location tag associated with it which
    identifies the device it was saved from, and this tag is the second
    argument passed to :attr:`map_location`. The builtin location tags are ``'cpu'``
    for CPU tensors and ``'cuda:device_id'`` (e.g. ``'cuda:2'``) for CUDA tensors.
    :attr:`map_location` should return either ``None`` or a storage. If
    :attr:`map_location` returns a storage, it will be used as the final deserialized
    object, already moved to the right device. Otherwise, :func:`torch.load` will
    fall back to the default behavior, as if :attr:`map_location` wasn't specified.

    If :attr:`map_location` is a :class:`torch.device` object or a string containing
    a device tag, it indicates the location where all tensors should be loaded.

    Otherwise, if :attr:`map_location` is a dict, it will be used to remap location tags
    appearing in the file (keys), to ones that specify where to put the
    storages (values).

    User extensions can register their own location tags and tagging and
    deserialization methods using :func:`torch.serialization.register_package`.

    Args:
        f: a file-like object (has to implement :meth:`read`, :meth:`readline`, :meth:`tell`, and :meth:`seek`),
            or a string or os.PathLike object containing a file name
        map_location: a function, :class:`torch.device`, string or a dict specifying how to remap storage
            locations
        pickle_module: module used for unpickling metadata and objects (has to
            match the :attr:`pickle_module` used to serialize file)
        weights_only: Indicates whether unpickler should be restricted to
            loading only tensors, primitive types and dictionaries
        mmap: Indicates whether the file should be mmaped rather than loading all the storages into memory.
            Typically, tensor storages in the file will first be moved from disk to CPU memory, after which they
            are moved to the location that they were tagged with when saving, or specified by ``map_location``. This
            second step is a no-op if the final location is CPU. When the ``mmap`` flag is set, instead of copying the
            tensor storages from disk to CPU memory in the first step, ``f`` is mmaped.
        pickle_load_args: (Python 3 only) optional keyword arguments passed over to
            :func:`pickle_module.load` and :func:`pickle_module.Unpickler`, e.g.,
            :attr:`errors=...`.

    .. warning::
        :func:`torch.load()` unless `weights_only` parameter is set to `True`,
        uses ``pickle`` module implicitly, which is known to be insecure.
        It is possible to construct malicious pickle data which will execute arbitrary code
        during unpickling. Never load data that could have come from an untrusted
        source in an unsafe mode, or that could have been tampered with. **Only load data you trust**.

    .. note::
        When you call :func:`torch.load()` on a file which contains GPU tensors, those tensors
        will be loaded to GPU by default. You can call ``torch.load(.., map_location='cpu')``
        and then :meth:`load_state_dict` to avoid GPU RAM surge when loading a model checkpoint.

    .. note::
        By default, we decode byte strings as ``utf-8``.  This is to avoid a common error
        case ``UnicodeDecodeError: 'ascii' codec can't decode byte 0x...``
        when loading files saved by Python 2 in Python 3.  If this default
        is incorrect, you may use an extra :attr:`encoding` keyword argument to specify how
        these objects should be loaded, e.g., :attr:`encoding='latin1'` decodes them
        to strings using ``latin1`` encoding, and :attr:`encoding='bytes'` keeps them
        as byte arrays which can be decoded later with ``byte_array.decode(...)``.

    Example:
        >>> # xdoctest: +SKIP("undefined filepaths")
        >>> torch.load('tensors.pt')
        # Load all tensors onto the CPU
        >>> torch.load('tensors.pt', map_location=torch.device('cpu'))
        # Load all tensors onto the CPU, using a function
        >>> torch.load('tensors.pt', map_location=lambda storage, loc: storage)
        # Load all tensors onto GPU 1
        >>> torch.load('tensors.pt', map_location=lambda storage, loc: storage.cuda(1))
        # Map tensors from GPU 1 to GPU 0
        >>> torch.load('tensors.pt', map_location={'cuda:1': 'cuda:0'})
        # Load tensor from io.BytesIO object
        >>> with open('tensor.pt', 'rb') as f:
        ...     buffer = io.BytesIO(f.read())
        >>> torch.load(buffer)
        # Load a module with 'ascii' encoding for unpickling
        >>> torch.load('module.pt', encoding='ascii')
    z
torch.loadzWeights only load failed. Re-running `torch.load` with `weights_only` set to `False` will likely succeed, but it can result in arbitrary code execution.Do it only if you get the file from a trusted source. WeightsUnpickler error: ZTORCH_FORCE_WEIGHTS_ONLY_LOAD0)1yyestrueTNzDCan not safely load weights when explicit pickle_module is specifiedFencodingzutf-8rbz'torch.load' received a zip file that looks like a TorchScript archive dispatching to 'torch.jit.load' (call 'torch.jit.load' directly to silence this warning)r7  z9f must be a string filename in order to use mmap argumentoverall_storagez,mmap can only be used with files saved with zz`torch.save(_use_new_zipfile_serialization=True), please torch.save your checkpoint with this option in order to use mmap.) ry   rz   r   r   getenvlowerr`   pickler   r'  r   rM   rD   r   _is_torchscript_zipra   rb   UserWarningrH   Zjitr%   r<   r_   r   r4   getsizer   	from_file_load_weights_only_unpicklerUnpicklingError_legacy_load)rI   r7  r   r5  r6  r8  ZUNSAFE_MESSAGEr   Zorig_positionrA  r   sizerd   r-   r-   r.   r%   X  sz    h


( &$&c                 C   s:   t j}|s2tj D ]}t|tjr||t|< q||  S )z@Get layout extension object from its string representation.
    )_get_layoutcachery   __dict__valuesr<   layoutr_   )r   rO  vr-   r-   r.   rN  	  s    rN  c                 C   s   t t| ffS r/   )rN  r_   rj   r-   r-   r.   <lambda>  r>   rT  c              	      s  i t |G dd dj dd  fdd}i fdd}t|  t| }|r|  d	krz
|| W S  tjk
r   t| rt| j	 d
d | 
d	 Y nX t| dsdtj  krdk rn ntdt|  dj| f}|tkrtdj| f}|tkr2td| j| f}	 | f}
||
_|
 }j| f}|rv|  nd }|D ]J}|kst| }|j| ||tj|j |d k	r~|  }q~tj  |S )Nc                       s   e Zd Z fddZ  ZS )z&_legacy_load.<locals>.UnpicklerWrapperc                    sB   t |tkr4d|kr4z
t|W S  tk
r2   Y nX t ||S Nr   )rT   r_   r&   KeyErrorr   
find_classr   mod_namer   r   r-   r.   rW    s    
z1_legacy_load.<locals>.UnpicklerWrapper.find_classr*   r+   r,   rW  r   r-   r-   r   r.   UnpicklerWrapper  s   r[  c           
   	   S   sL  zd t| d }W n* tk
r@   td| j d  Y d S X ||krH| jr"| jd }tj|	d|	d||dd}d |}ztt
|dL}|dd	}|d |dkr|| n|t|ks| |krtW 5 Q R X d
| d | d }	W n" tk
r   d| d }	Y nX nd}	dt|  d|	 }	t|	t d S )Nr   r   r   r   z.patch
)Zlinetermza+r   zSaved a reverse patch to z. Run `patch -p0 < z` to revert your changes.z;Tried to save a patch, but couldn't create a writable file zD. Make sure it doesn't exist and your working directory is writable.zyou can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.zsource code of class 'z' has changed. )r   r   r^   ra   rb   r*   Zdump_patchesdifflibZunified_diffr[   r   rH   r   rG   rE   OSErrorry   r   r   )
container_typer  Zoriginal_sourceZcurrent_source	file_namedifflinesrI   	file_sizer   r-   r-   r.   _check_container_source'  sR    

 


z-_legacy_load.<locals>._check_container_sourcec                     s  i   fdd}t tj| dtjdf}t R}|jd|d ttj|ddd} j	| f}t
|D ]^}j	| f}|\}}}	|	j}
tttj| tj|
}||}tjj||
d	d
 |< qrj	| f}|D ]T\}}}} | }tj|j}|| }tjj|j||||   |jd	d
 |< qW 5 Q R X |jd|d ttj|ddd} j	| f}t
|D ]}j	| f}|\}}} | }td| d\}| d td| d| d| }td| d| d| }td| d\}tjg |jd|j|||}| |< qW 5 Q R X |d}|f}||_|	 }|W  5 Q R  W  5 Q R  S Q R X W 5 Q R X d S )Nc                    s6   t | tr*t| dd  r" |   | d S t|  S )Nr   r   )r<   r\   allr  )saved_id)rd  deserialized_objectsr-   r.   persistent_loadR  s
    
z:_legacy_load.<locals>.legacy_load.<locals>.persistent_loadzr:)fileobjr   r   Zstoragesr3   r?  r   TZwrap_storager  	_internalZtensorsz<ir?   <q   z<qr  rD  )r   tarfiler   
PAX_FORMATr   extractr   r4   r   r%   rangeZ_dtyper   r   ry   r   Z_new_with_filer   r(  r   r   r  r   structunpackrE   tensorset_extractfilerh  ) rI   rh  tarZtmpdirZnum_storagesir   r*  r   r   r  rk   Zstorage_viewsZtarget_cdataZ
root_cdatar  numelrootZelement_sizeoffset_bytesZnum_tensorsr   Z
storage_idZoriginal_tensor_typer   ndimZstridestorage_offsetrv  pickle_file	unpicklerr   )r[  rd  r8  r   restore_location)rg  r.   legacy_loadO  sl    



   
z!_legacy_load.<locals>.legacy_loadc                    sx  t | tstt| d }| dd  }|dkrNt|dd  rF |  |d S |dkrb|\}}}}}t|}|j}|tj| }	|krt	t
t|	}
d|
_tjj|
||dd}||< n*| }| dkrtjj|jj|dd}|d k	rZ|\}}}|tj| }|tj| }|krPtjj|j|||  |dd|< | }n|}|S td| d  d S )	Nr   r   rc   r   Trj  )ri   r  rk  zUnknown saved id type: )r<   r\   r   _maybe_decode_asciire  r  ry   r   r(  r   r   r   r   r   r   	_data_ptrr   ri   r`   )rf  r   datar   Zroot_keyr   r{  r  r  r   rk   typed_storageZview_keyr  Z	view_sizer}  Zview_size_bytesr  )rd  rg  r  r-   r.   rh    sT    






z%_legacy_load.<locals>.persistent_loadr   z9 is a zip archive (did you mean to use torch.jit.load()?)readinto)r5   rn  r   )r5   rn  r   ztorch.load does not work with file-like objects that do not implement readinto on Python 3.8.0 and 3.8.1. Received object of type "zH". Please update to Python 3.8.2 or newer to restore this functionality.z#Invalid magic number; corrupt file?zInvalid protocol version: )_get_restore_location	Unpicklerr   r   rD   rp  TarErrorrM   r`   r   rH   r   r  version_inforT   r%   r$  r  rh  r   r   Z_set_from_filery   r   r(  r  _validate_loaded_sparse_tensors)rI   r7  r   r8  r  rh  Zf_should_read_directlyZmagic_numberr  Z	_sys_infor  r   Zdeserialized_storage_keysr  r*  r  r-   )r[  rd  rg  r8  r   r  r.   rL    sb    
(A6

$

  

rL  )	bytes_strr;   c                 C   s   t | tr| dS | S )Nr   )r<   bytesdecode)r  r-   r-   r.   r    s    

r  c                    sl    d krt }nZt tr& fdd}nBt ttfrB fdd}n&t tjr\ fdd}n fdd}|S )Nc                    s     ||}t| |S r/   )getr!   r   r   r@  r-   r.   r    s    z/_get_restore_location.<locals>.restore_locationc                    s
   t |  S r/   r!   r  r@  r-   r.   r    s    c                    s   t | t S r/   )r!   r_   r  r@  r-   r.   r    s    c                    s     | |}|d krt | |}|S r/   r  )r   r   r   r@  r-   r.   r    s    

)r!   r<   r  r_   r  ry   ri   )r7  r  r-   r@  r.   r    s    
r  c                   @   s   e Zd Zdd Zdd ZdS )r&   c                 C   s   t || _d S r/   )r	   r  r   r-   r-   r.   r     s    zStorageType.__init__c                 C   s   d| j  dS )NzStorageType(dtype=r   ro  r   r-   r-   r.   __str__!  s    zStorageType.__str__N)r*   r+   r,   r   r  r-   r-   r-   r.   r&     s   r-  c                    s>  t |i d}d  |rB|  dkrtd   nDt tjksXt d kr^d n(t tjkrpd nt tj	kr~ntd|st d krt
jdkrtdt  fd	d
fdd}ddiG fddd|j}t|}	||	f|}
||
_|
 }tj  tjdd i |S )Nr  )   little   bigr/  r  r  zInvalid load endianness typer.  a  The default load endianness for checkpoints without a byteorder mark on big endian machines was changed from 'native' to 'little' endian, to avoid this behavior please use torch.serialization.set_default_load_endianness to set the desired default load endiannessc                    s   d| }d k	r. |}|||  }n||tj j} d k	rd  tjkrd|	|  tj
j||| dd}| dkr||< |S )Nr0  Trj  r   )Zget_record_offsetZget_storage_from_recordry   r   Z_typed_storager   r  r  r  byteswapr   r   r  )r  r{  r*  r   r   r  r   r  )byteorderdataloaded_storagesrA  r  r3  r-   r.   load_tensorG  s     


z_load.<locals>.load_tensorc           
         s   t | tstt| d }| dd  }|dks>td| d|\}}}}|tjkr\tj}n|j}|krt| }n"|tj	| }	 ||	|t|}|S )Nr   r   r   zBUnknown typename for persistent_load, expected 'storage' but got 'rY   )
r<   r\   r   r  ry   r   r  r  r   r(  )
rf  r   r  r   r*  r   r{  r  r  r   )r  r  r-   r.   rh  _  s    



z_load.<locals>.persistent_loadztorch.tensorztorch._tensorc                       s   e Zd Z fddZ  ZS )z_load.<locals>.UnpicklerWrapperc                    sN   t |tkr4d|kr4z
t|W S  tk
r2   Y nX ||}t ||S rU  )rT   r_   r&   rV  r  r   rW  rX  )r   load_module_mappingr-   r.   rW    s    
z*_load.<locals>.UnpicklerWrapper.find_classrZ  r-   )r  r   r.   r[  |  s   r[  ztorch.load.metadataserialization_id)r  Z
has_recordZ
get_recordr   r  r(   r'   r7   r8   r6   r  r  ra   rb   rF  r  r   r1  rh  r%   ry   r   r  rz   Z_log_api_usage_metadatar  )r3  r7  r   r  rA  r8  Zbyteordernamerh  r[  Z	data_filer  r   r-   )r  r  r  r  rA  r  r3  r.   rI  %  sR    


 
 
rI  c                 C   s   d|   kS )Nzconstants.pkl)Zget_all_records)r3  r-   r-   r.   rE    s    rE  )T)NN)r-  N)|r]  r   r   r1   rt  r  ry   rp  r0   ra   
contextlibr   r   enumr   r   r   Ztorch._sourcesr   Ztorch.typesr   Ztorch.storager	   typingr
   r   r   r   r   r   r   r   r   r   Ztyping_extensionsr   copyregrD  r   Ztorch._weights_only_unpicklerrJ  DEFAULT_PROTOCOLStructrM  r"  r!  r   r$  r  ZSTORAGE_KEY_SEPARATORr_   r   r  r   __annotations__r   ri   r   r   r   r   r   __all__Warningr   r   rQ   r'   r9   r(   r)   boolrM   r  r   r   rl   rp   rr   ru   rw   r}   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   objectr$   r   r   r%   rN  rO  rR  rL  r  r  r&   rI  rE  r-   r-   r-   r.   <module>   s    06
-
'	
	
	
= X   2 d
r