U
    ªÊ¹jÑz  ã                   @   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mZ d dlmZm	Z	m
Z
mZ d dlZdcdd„Zdddd„Zded	d
„Zdd„ Zdd„ Zdd„ Zdd„ Zdfdd„Zg Ze
d ed< dd„ Zdd„ Zdd„ ZeZdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Z d)d*„ Z!d+d,„ Z"d-d.„ fd/d0„Z#d1d2„ Z$d3d4„ Z%d5d6„ Z&d7d8„ Z'd9d:„ Z(d;d<„ Z)d=d>„ Z*d?d@„ Z+G dAdB„ dBe,ƒZ-G dCdD„ dDƒZ.dEdF„ Z/dGdH„ Z0dIdJ„ Z1dKdL„ Z2dMdN„ Z3e4dOœdPdQ„Z5dgee6e6e4dRœdSdT„Z7dUdV„ Z8dWdX„ Z9G dYdZ„ dZƒZ:d[d\„ Z;d]d^„ Z<e =d_¡e,d`œdadb„ƒZ>dS )hé    N)Údefaultdict)ÚAnyÚDefaultDictÚListÚOptionalFc           	      K   sÚ   t d||ƒ}|dkr&| jd | jj S t|tƒr8t|ƒ}|t| ƒkrH| S | jr¸|js\t	dƒ‚|j 
dd¡}|d |j }tj | ¡ ||¡}|d }tj | ¡ ||¡}||||  ¡ ƒS |jrÆt	dƒ‚||  ¡ ƒ | |¡S )	a©  Returns the type if `dtype` is not provided, else casts this object to
    the specified type.

    If this is already of the correct type, no copy is performed and the
    original object is returned.

    Args:
        dtype (type or string): The desired type
        non_blocking (bool): If ``True``, and the source is in pinned memory
            and destination is on the GPU or vice versa, the copy is performed
            asynchronously with respect to the host. Otherwise, the argument
            has no effect.
        **kwargs: For compatibility, may contain the key ``async`` in place of
            the ``non_blocking`` argument. The ``async`` arg is deprecated.
    ÚtypeNÚ.z)Cannot cast sparse tensor to dense tensorz.sparseÚ z.LongTensorz)Cannot cast dense tensor to sparse tensor)Ú_get_async_or_non_blockingÚ
__module__Ú	__class__Ú__name__Ú
isinstanceÚstrÚ_import_dotted_namer   Ú	is_sparseÚRuntimeErrorÚreplaceÚtorchÚTensorÚ_valuesÚ_indicesÚsizeÚcopy_)	ÚselfÚdtypeÚnon_blockingÚkwargsZnew_module_nameZnew_values_type_nameÚ
new_valuesZnew_indices_type_nameZnew_indices© r   úK/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/_utils.pyÚ_type   s,    
 ÿr!   c              
   K   s´   t d||ƒ}ttddƒ}|dk	s(tdƒ‚| jrP|dkr>| ¡ }|  ¡ |kr\| S n|dkr\d}| |¡�D | jrvtdƒ‚tj	|  
¡ t d¡d�}| | |¡ |W  5 Q R £ S Q R X dS )aS  Returns a copy of this object in HPU memory.

    If this object is already in HPU memory and on the correct device, then
    no copy is performed and the original object is returned.

    Args:
        device (int): The destination HPU id. Defaults to the current device.
        non_blocking (bool): If ``True`` and the source is in pinned memory,
            the copy will be asynchronous with respect to the host. Otherwise,
            the argument has no effect.
        **kwargs: For compatibility, may contain the key ``async`` in place of
            the ``non_blocking`` argument.
    ÚhpuNzHPU device module is not loadedéÿÿÿÿz/sparse storage is not supported for HPU tensors©Údevice)r
   Úgetattrr   ÚAssertionErrorZis_hpuÚcurrent_deviceÚ
get_devicer%   r   ÚUntypedStorager   r   )r   r%   r   r   r"   Úuntyped_storager   r   r    Ú_hpu4   s    r,   c              
   K   sî   t d||ƒ}| jr6|dkr$tj ¡ }|  ¡ |krB| S n|dkrBd}tj |¡�– | jr¬ttjj	| j
jƒ}tj | ¡ ||¡}tj | ¡ ||¡}||||  ¡ ƒW  5 Q R £ S tj|  ¡ t d¡d�}| | |¡ |W  5 Q R £ S W 5 Q R X dS )aU  Returns a copy of this object in CUDA memory.

    If this object is already in CUDA memory and on the correct device, then
    no copy is performed and the original object is returned.

    Args:
        device (int): The destination GPU id. Defaults to the current device.
        non_blocking (bool): If ``True`` and the source is in pinned memory,
            the copy will be asynchronous with respect to the host. Otherwise,
            the argument has no effect.
        **kwargs: For compatibility, may contain the key ``async`` in place of
            the ``non_blocking`` argument.
    ÚcudaNr#   r$   )r
   Zis_cudar   r-   r(   r)   r%   r   r&   Úsparser   r   r   r   r   r   r*   r   )r   r%   r   r   Únew_typeÚindicesÚvaluesr+   r   r   r    Ú_cudaT   s(    
 ÿr2   c                 C   sR   |s|S t |ƒdksd|kr@d}t| ¡ ƒ ¡ }t| | |¡ƒ‚t d¡ |d S )zþReturn the non-blocking flag given the function name and kwargs.

    Args:
        function_name (str): the name of the function being used.
        non_blocking (bool): the default value.
        **kwargs (dict): the kwargs passed to the function.
    é   Úasyncz,{}() got an unexpected keyword argument '{}'z)'async' is deprecated; use 'non_blocking')ÚlenÚlistÚkeysÚpopÚ	TypeErrorÚformatÚwarningsÚwarn)Zfunction_namer   r   ÚmessageÚargumentr   r   r    r
   y   s    
r
   c                 C   s(   t jg | j| jjd�}| | j|||¡S ©N©r   r%   )r   Útensorr   Z_untyped_storager%   Úset_)ÚstorageÚstorage_offsetr   ÚstrideÚtr   r   r    Ú_rebuild_tensor²   s    rG   c                 C   s   t | tjƒst‚tj | ¡S ©N)r   r   r   r'   Ú_CZ_get_tensor_metadata©rA   r   r   r    Úget_tensor_metadata¸   s    rK   c                 C   s0   t |tƒst‚t | tjƒst‚tj | |¡ d S rH   )r   Údictr'   r   r   rI   Z_set_tensor_metadata)rA   Úmetadatar   r   r    Úset_tensor_metadataÀ   s    rN   c                 C   s,   t | |||ƒ}||_|r"t||ƒ ||_|S rH   )rG   Úrequires_gradrN   Ú_backward_hooks)rC   rD   r   rE   rO   Úbackward_hooksrM   rA   r   r   r    Ú_rebuild_tensor_v2Ç   s    
rR   ztorch.TensorÚ_sparse_tensors_to_validatec                  C   sÎ   z¾t D ]´} | jtjkr8t |  ¡ |  ¡ |  ¡ |  	¡ ¡ q| jtj
tjtjtjhkr¨| jtj
tjhkrx|  ¡ |  ¡  }}n|  ¡ |  ¡  }}t |||  ¡ |  ¡ | j¡ qtd| j› d�ƒ‚qW 5 t  ¡  X d S )Nz,_validate_loaded_sparse_tensors for layout `ú`)rS   ÚclearÚlayoutr   Ú
sparse_cooZ _validate_sparse_coo_tensor_argsr   r   r   Úis_coalescedÚ
sparse_csrÚ
sparse_cscÚ
sparse_bsrÚ
sparse_bscZcrow_indicesZcol_indicesZccol_indicesZrow_indicesZ'_validate_sparse_compressed_tensor_argsr1   ÚNotImplementedError)rF   Úcompressed_indicesÚplain_indicesr   r   r    Ú_validate_loaded_sparse_tensorsã   sB       ÿüþþ    ÿÿ
r`   c           	      C   s®   | t jkrTt|ƒdkr&|\}}}d}n|\}}}}t j|||d|d�}t |¡ |S | t jt jt jt j	hkrœ|\}}}}t j
||||| dd�}t |¡ |S td| › �ƒ‚dS )zÖ
    Rebuilds a sparse tensor from its sparse storage representation.

    Args:
        layout (str): The sparse storage layout of the tensor.
        data (tuple): The tensor's sparse storage representation.
    é   NF)Úcheck_invariantsrX   )rV   rb   z$rebuilding sparse tensor for layout )r   rW   r5   Zsparse_coo_tensorrS   ÚappendrY   rZ   r[   r\   Zsparse_compressed_tensorr]   )	rV   Údatar0   r1   r   rX   Úresultr^   r_   r   r   r    Ú_rebuild_sparse_tensor  s@    

    ÿ
üú
rf   c                 C   s   t  | ¡j||d�}||_|S r?   )r   Z
from_numpyÚtorO   )rd   r   r%   rO   rA   r   r   r    Ú!_rebuild_device_tensor_from_numpy2  s    rh   c                 C   s   t j||| d|d�S )NÚmeta)r   r%   rO   )r   Zempty_strided)r   r   rE   rO   r   r   r    Ú_rebuild_meta_tensor_no_storage<  s        ÿrj   c              	   C   s   t jj| ||||||d�S )N)ÚstridesrD   rV   r%   rO   )r   r   Z_make_wrapper_subclass)Úclsr   r   rE   rD   rV   r%   rO   r   r   r    Ú_rebuild_wrapper_subclassB  s    ùrm   c                 C   s  |d }|t jkr6|\}}	}
t j||	|
| j| jd�}nº|t jt jfkrâ|\}}}}t|ƒtkrÆt|ƒtkrÆ|t jkržt j	|t j
| jd�}t j	|t j| jd�}n(t j	|t j| jd�}t j	|t j| jd�}t j||||| j| jd�}ntd|› �ƒ‚| | |||¡ ||_||_|S )Nr   )ÚscaleÚ
zero_pointr   r%   r@   )ÚscalesÚzero_pointsÚaxisr   r%   z0Can't deserialize quantized tensor with qscheme )r   Zper_tensor_affineZ_empty_affine_quantizedr   r%   Zper_channel_affineZ per_channel_affine_float_qparamsr   r6   rA   ÚdoubleÚlongÚfloatZ#_empty_per_channel_affine_quantizedr   rB   rO   rP   )rC   rD   r   rE   Zquantizer_paramsrO   rQ   ZqschemeÚ_rn   ro   rA   rp   rq   rr   r   r   r    Ú_rebuild_qtensorR  sN    	

û
  ÿ  ÿú	rw   c                 C   s   t j | |¡}||_|S rH   )r   ÚnnÚ	ParameterrP   )rd   rO   rQ   Úparamr   r   r    Ú_rebuild_parameter…  s    r{   c                 C   s"   t j | |¡}||_t||ƒ}|S rH   )r   rx   ry   rP   Ú_set_obj_state)rd   rO   rQ   Ústaterz   r   r   r    Ú_rebuild_parameter_with_state�  s    
r~   c                    sL   t ˆ dd ƒ}|r|ƒ }n0t ˆ j¡}|rBˆ j‡ fdd„|D ƒf}nˆ j}|S )NÚ__getstate__c                    s"   i | ]}t ˆ |ƒr|tˆ |ƒ“qS r   )Úhasattrr&   )Ú.0Úname©Úobjr   r    Ú
<dictcomp>ª  s   
þ z"_get_obj_state.<locals>.<dictcomp>)r&   ÚcopyregÚ
_slotnamesr   Ú__dict__)r„   Zgetstate_fnr}   Zslots_to_saver   rƒ   r    Ú_get_obj_state›  s    
þþ	r‰   c                 C   s†   t |tƒr6t|ƒdks$td|› �ƒ‚|d }|d }n|}d }|r`| ¡ D ]\}}t| ||ƒ qJ|r‚| ¡ D ]\}}t| ||ƒ ql| S )Né   zInvalid serialized state: r   r3   )r   Útupler5   r   ÚitemsÚsetattr)r„   r}   Z
dict_stateZslots_stateÚkÚvr   r   r    r|   ¶  s    

r|   c                 C   s6   |   d¡}t|d ƒ}|dd … D ]}t||ƒ}q"|S )Nr   r   r3   )ÚsplitÚ
__import__r&   )r‚   Ú
componentsr„   Ú	componentr   r   r    r   Ì  s
    
r   c                 C   s   | | S rH   r   )ÚxÚyr   r   r    Ú<lambda>Õ  ó    r–   c                 c   sP   t | ƒ}zt|ƒ}W n tk
r*   Y dS X |V  |D ]}|||ƒ}|V  q6dS )zReturn running totalsN)ÚiterÚnextÚStopIteration)ÚiterableÚfnÚitÚtotalÚelementr   r   r    Ú_accumulateÕ  s    
r    c                 C   s   t jj | ¡S )a¢  Flatten dense tensors into a contiguous 1D buffer. Assume tensors are of
    same dense type.

    Since inputs are dense, the resulting tensor will be a concatenated 1D
    buffer. Element-wise operation on this buffer will be equivalent to
    operating individually.

    Args:
        tensors (Iterable[Tensor]): dense tensors to flatten.

    Returns:
        A contiguous 1D buffer containing input tensors.
    ©r   rI   Ú_nnZflatten_dense_tensors)Útensorsr   r   r    Ú_flatten_dense_tensorsä  s    r¤   c                 C   s8   t jj dd„ | D ƒ¡}t jj dd„ | D ƒ¡}||fS )ab  Flatten sparse tensors into two contiguous 1D buffers, one of indices and
    one of values. Assume tensors are of same sparse type.

    Args:
        tensors (Iterable[Tensor]): sparse tensors to flatten.

    Returns:
        A tuple of two contiguous 1D buffers, one containing input tensors'
        indices and the other containing the values.
    c                 S   s   g | ]}t j |¡‘qS r   ©r   r   r   ©r�   rF   r   r   r    Ú
<listcomp>  s     z+_flatten_sparse_tensors.<locals>.<listcomp>c                 S   s   g | ]}t j |¡‘qS r   ©r   r   r   r¦   r   r   r    r§     s     r¡   )r£   Úflat_indicesÚflat_valuesr   r   r    Ú_flatten_sparse_tensorsõ  s    ÿÿr«   c                 C   s   t jj | |¡S )a®  View a flat buffer using the sizes of tensors. Assume that tensors are of
    same dense type, and that flat is given by _flatten_dense_tensors.

    Args:
        flat (Tensor): flattened dense tensors to unflatten.
        tensors (Iterable[Tensor]): dense tensors whose sizes will be used to
          unflatten flat.

    Returns:
        Unflattened dense tensors with sizes same as tensors and values from
        flat.
    )r   rI   r¢   Úunflatten_dense_tensors)Úflatr£   r   r   r    Ú_unflatten_dense_tensors	  s    r®   c           
   	   C   sx   | \}}t jj |dd„ |D ƒ¡}t jj |dd„ |D ƒ¡}g }t|||ƒD ]"\}}}	| | ||	| ¡ ¡¡ qLt|ƒS )a  View flat buffer (containing indices and values) using the sizes of
    tensors. Assume that tensors are of same sparse type, and that flat is given
    by _flatten_sparse_tensors.

    Args:
        flat (tuple(Tensor, Tensor)): flattened indices and values of sparse
          tensors to unflatten.
        tensors (Iterable[Tensor]): sparse tensors whose sizes will be used to
          unflatten flat.

    Returns:
        Unflattened sparse tensors with sizes same as tensors and values from
        flat.
    c                 S   s   g | ]}t j |¡‘qS r   r¥   r¦   r   r   r    r§   *  s     z-_unflatten_sparse_tensors.<locals>.<listcomp>c                 S   s   g | ]}t j |¡‘qS r   r¨   r¦   r   r   r    r§   -  s     )	r   rI   r¢   r¬   Úziprc   Únewr   r‹   )
r­   r£   r©   rª   r0   r1   ÚoutputsrF   Úir�   r   r   r    Ú_unflatten_sparse_tensors  s     ÿ ÿr³   c                    sL   t tƒ}| D ]}|| ¡   |¡ qdd„ | ¡ D ƒ‰ t‡ fdd„|D ƒƒS )a  Assume that tensors are of same order as ordered_tensors within their
    types, e.g., from _take_tensors. Reorder them to be of same order as
    ordered_tensors.

    Args:
        tensors (Iterable[Tensor]): tensors to be reordered. They should be of
          the same order as ordered_tensors within their own types.
        ordered_tensors (Iterable[Tensor]): tensors whose order will be the
          reference.

    Returns:
        Ordered tuple of tensors with contents from tensors and order of
        ordered_tensors.
    c                 S   s   i | ]\}}|t |ƒ“qS r   )r˜   )r�   rF   Zcollr   r   r    r…   G  s      z'_reorder_tensors_as.<locals>.<dictcomp>c                 3   s   | ]}t ˆ | ¡  ƒV  qd S rH   )r™   r   )r�   rA   ©Z
type_dict_r   r    Ú	<genexpr>H  s     z&_reorder_tensors_as.<locals>.<genexpr>)r   r6   r   rc   rŒ   r‹   )r£   Zordered_tensorsZ	type_dictrA   r   r´   r    Ú_reorder_tensors_as5  s
    r¶   c                 c   sò   t dd„ ƒ}| D ]¸}| ¡ }|jr\tj |¡}tj |¡}| ¡ | ¡  | ¡ | ¡   }n| ¡ | ¡  }|| }|d | |krª|d dkrª|d V  g dg }||< |d  	|¡ |d  |7  < q| 
¡ D ]\}	}
t|	ƒdkrÒ|	V  qÒdS )aÕ  Group tensors into chunks. This generator yields a chunk at each time,
    each containing tensors of same type up to certain byte limit in total size.

    Args:
        tensors (Sequence): A sequence of tensors to be separated into chunks.
        size_limit (int): The limit of each chunk in bytes.

    Yields:
        Blocks of tensors of same type and within size_limit. The yielded
        tensors are only ordered as the original sequence within its types.
    c                   S   s   g dgS )Nr   r   r   r   r   r    r–   W  r—   z_take_tensors.<locals>.<lambda>r3   r   N)r   r   r   r   r   r   r   ZnumelZelement_sizerc   r1   r5   )r£   Z
size_limitZbuf_dictrA   rF   r0   r1   r   Zbuf_and_sizeÚbufrv   r   r   r    Ú_take_tensorsK  s(    ÿÿ
r¸   c                    s   ‡ ‡fdd„}|S )Nc                    s   t ˆ ƒ| _ˆ| jd< | S )NÚreturn)rL   Ú__annotations__)Zfun©r   Úretr   r    Údecq  s    

zannotate.<locals>.decr   )r¼   r   r½   r   r»   r    Úannotatep  s    r¾   c              	   C   s‚   t j | ¡}|d krt| ƒ}g }t jjddd��H | dd„ |D ƒ¡ | dd„ | ¡ D ƒ¡ |› dd |¡› d�}W 5 Q R X |S )	Nr   )Ú	thresholdZ	edgeitemsc                 s   s   | ]}t |ƒV  qd S rH   ©Úrepr)r�   Úar   r   r    rµ   €  s     zrender_call.<locals>.<genexpr>c                 s   s$   | ]\}}|› d t |ƒ› �V  qdS )ú=NrÀ   )r�   rŽ   r�   r   r   r    rµ   �  s     ú(z, ú))	r   Z	overridesÚresolve_namer   Z_tensor_strZprintoptionsÚextendrŒ   Újoin)rœ   Úargsr   Zstr_fnZstr_argsÚrr   r   r    Úrender_cally  s     rË   c                   @   s   e Zd ZdZdd„ ZdS )ÚKeyErrorMessagez(str subclass that returns itself in reprc                 C   s   | S rH   r   )r   r   r   r    Ú__repr__’  s    zKeyErrorMessage.__repr__N)r   r   Ú__qualname__Ú__doc__rÍ   r   r   r   r    rÌ   �  s   rÌ   c                   @   s"   e Zd ZdZddd„Zdd„ ZdS )	ÚExceptionWrapperz?Wraps an exception plus traceback to communicate across threadsNúin backgroundc                 C   s6   |d krt  ¡ }|d | _d tj|Ž ¡| _|| _d S )Nr   r	   )ÚsysÚexc_infoÚexc_typerÈ   Ú	tracebackÚformat_exceptionÚexc_msgÚwhere)r   rÓ   rØ   r   r   r    Ú__init__™  s
    
zExceptionWrapper.__init__c                 C   s‚   d| j j› d| j› d| j› �}| j tkr2t|ƒ}nt| j ddƒrL| j |d�‚z|   |¡}W n tk
rx   t|ƒd‚Y nX |‚dS )z4Reraises the wrapped exception in the current threadzCaught ú z.
Original r=   N)r=   )	rÔ   r   rØ   r×   ÚKeyErrorrÌ   r&   r9   r   )r   ÚmsgÚ	exceptionr   r   r    Úreraise¢  s    

zExceptionWrapper.reraise)NrÑ   )r   r   rÎ   rÏ   rÙ   rÞ   r   r   r   r    rÐ   –  s   
	rÐ   c                  C   sP   t j ¡ rdS tt dƒr&t j ¡ r&dS t j ¡ } tt | d ƒ}|rL| ¡ rL| S d S ©Nr-   Úxpu)r   r-   Zis_availabler€   rà   rI   Ú_get_privateuse1_backend_namer&   )Zcustom_backend_nameZcustom_device_modr   r   r    Ú_get_available_device_type¹  s    

râ   c                 C   sZ   t ƒ }|r | ¡ dkr | tjƒS |r:| ¡ dkr:| tjƒS |tj ¡ krV| tt|ƒƒS d S rß   )râ   Úlowerr   r-   rà   rI   rá   r&   )Z
get_memberÚdevice_typer   r   r    Ú_get_device_attrÆ  s    

rå   c                   C   s   t dd„ ƒS )Nc                 S   s   |   ¡ S rH   )r(   ©Úmr   r   r    r–   Ô  r—   z+_get_current_device_index.<locals>.<lambda>©rå   r   r   r   r    Ú_get_current_device_indexÒ  s    ré   c                   C   s   t dd„ ƒS )Nc                 S   s   t t|  ¡ ƒƒS rH   )r6   ÚrangeÚdevice_countræ   r   r   r    r–   Ù  r—   z)_get_all_device_indices.<locals>.<lambda>rè   r   r   r   r    Ú_get_all_device_indices×  s    rì   c                 C   s   dd„ | D ƒS )Nc                    s   g | ]‰ t ‡ fd d„ƒ‘qS )c                    s
   |   ˆ ¡S rH   )Zget_device_propertiesræ   ©r²   r   r    r–   Þ  r—   z4_get_devices_properties.<locals>.<listcomp>.<lambda>rè   )r�   r   rí   r    r§   Þ  s     z+_get_devices_properties.<locals>.<listcomp>r   )Z
device_idsr   r   r    Ú_get_devices_propertiesÜ  s    rî   )r¹   c                   C   s   t j ¡ dkrt j ¡ S dS )zÈChecks if there are CUDA devices available and
    returns the device index of the current default CUDA device.
    Returns -1 in case there are no CUDA devices available.
    Arguments: ``None``
    r   r#   )r   r-   rë   r(   r   r   r   r    Úget_current_device_indexá  s    
rï   )r%   ÚoptionalÚ	allow_cpur¹   c                 C   sš   t | tƒrt | ¡} d}t | tjƒrT|s@| jdkr@td| › �ƒ‚| jdkrNdn| j}t | tƒrb| }|dkr–|rˆtj 	¡ r€t
ƒ }q–tƒ }ntd| › �ƒ‚|S )a'  Gets the device index from :attr:`device`, which can be a torch.device
    object, a Python integer, or ``None``.

    If :attr:`device` is a torch.device object, returns the device index if it
    has index. Note that for a device without a specified index,
    i.e., ``torch.device('xxx')``, this will return the current default
    device of that type if :attr:`optional` is ``True``. If :attr:`allow_cpu` is ``True``,
    CPU devices will be accepted and ``-1`` will be returned in this case.

    If :attr:`device` is a Python integer, it is returned as is.

    If :attr:`device` is ``None``, this will return the current default
    device of the supported runtime platform if :attr:`optional` is ``True``.
    i.e., the current default CUDA device will be returned if CUDA runtime is supported.
    NÚcpuz$Expected a non cpu device, but got: r#   zFExpected a torch.device with a specified index or an integer, but got:)r   r   r   r%   r   Ú
ValueErrorÚindexÚintZjitZis_scriptingrï   ré   )r%   rð   rñ   Z
device_idxr   r   r    Ú_get_device_indexì  s$    



ÿrö   c                 C   s$   t | tjjƒs |  ¡ r t | ¡S | S )zÀ
    Returns a real view of a tensor if complex dtype else just the tensor
    need to check if a UninitializedParameter because otherwise checking is_complex is an error for a LazyModule
    )r   r   rx   ZUninitializedParameterÚ
is_complexZview_as_realrJ   r   r   r    Ú_handle_complex  s    ÿþürø   c                 C   sl   t | tjƒstdt| ƒ› �ƒ‚| jr4t | ¡jd? S | jrJt | ¡jd? S | tj	krXdS t 
| ¡jd? S dS )z8
    Returns the element size for a dtype, in bytes
    zexpected torch.dtype, but got rŠ   ra   r3   N)r   r   r   r   r   r÷   ZfinfoÚbitsZis_floating_pointÚboolZiinfo)r   r   r   r    Ú_element_size&  s    
rû   c                   @   s    e Zd Zddd„Zddd„ZdS )Ú_ClassPropertyDescriptorNc                 C   s
   || _ d S rH   )Úfget)r   rý   Úfsetr   r   r    rÙ   9  s    z!_ClassPropertyDescriptor.__init__c                 C   s    |d krt |ƒ}| j ||¡ƒ S rH   )r   rý   Ú__get__)r   ÚinstanceÚownerr   r   r    rÿ   <  s    z _ClassPropertyDescriptor.__get__)N)N)r   r   rÎ   rÙ   rÿ   r   r   r   r    rü   8  s   
rü   c                 C   s   t | ttfƒst| ƒ} t| ƒS rH   )r   ÚclassmethodÚstaticmethodrü   )Úfuncr   r   r    ÚclasspropertyB  s    r  c                   C   s   dS )NFr   r   r   r   r    Úis_compilingI  s    r  rŠ   )rä   c                 C   s.   t t| d ƒ}|d kr*td| › d| › d�ƒ‚|S )NzDevice 'z<' does not have a corresponding module registered as 'torch.z'.)r&   r   r   )rä   Zdevice_moduler   r   r    Ú_get_device_moduleM  s    ÿr  )NF)NF)NF)N)FF)?r†   Ú	functoolsrÒ   rÕ   r;   Úcollectionsr   Útypingr   r   r   r   r   r!   r,   r2   r
   rG   rK   rN   rR   rS   rº   r`   rf   rh   Z_rebuild_xla_tensorrj   rm   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ü   r  r  Ú	lru_cacher  r   r   r   r    Ú<module>   s|    
(
 
%9 ÿ
%*3
	%	#   ÿ  þ-
