U
    ‰dç  ã                   @   sp   d dl m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„ Z
dd„ Zdd„ Zdd„ ZdS )é    )ÚOrderedDictc                 C   s   |   ¡ rtdƒ‚d S )NzzNYI: Named tensors don't support serialization. Please drop names via `tensor = tensor.rename(None)` before serialization.)Ú	has_namesÚRuntimeError©Útensor© r   ú@/tmp/pip-unpacked-wheel-ua33x9lu/torch/_namedtensor_internals.pyÚcheck_serializing_named_tensor
   s    ÿr	   c                 C   s   t dd„ t| jƒD ƒƒS )zkReturns a map of { dim: dim_name } where dim is a name if the dim is named
    and the dim index otherwise.c                 S   s$   g | ]\}}|d kr|n||f‘qS ©Nr   )Ú.0ÚidxÚnamer   r   r   Ú
<listcomp>   s   ÿz!build_dim_map.<locals>.<listcomp>)r   Ú	enumerateÚnamesr   r   r   r   Úbuild_dim_map   s    ÿr   c                 C   sT   t | tƒr|  ¡ } t| dƒs8t | tƒs8td t| ƒ¡ƒ‚t| ƒdkrLtdƒ‚t	| Ž S )NÚ__iter__zDExpected namedshape to be OrderedDict or iterable of tuples, got: {}r   z!Expected namedshape to non-empty.)
Ú
isinstancer   ÚitemsÚhasattrÚtupler   ÚformatÚtypeÚlenÚzip)Z
namedshaper   r   r   Úunzip_namedshape   s    
ÿÿr   c                 C   s   | rdS dS d S )NZrename_Úrenamer   )Úinplacer   r   r   Únamer_api_name$   s    r   c                 C   s   | t kp| dkS )Nz...)ÚEllipsis)Úitemr   r   r   Úis_ellipsis+   s    r!   c                 C   sF   dd„ t | ƒD ƒ}t|ƒdkr.td || ¡ƒ‚t|ƒdkrB|d S d S )Nc                 S   s   g | ]\}}t |ƒr|‘qS r   )r!   )r   Úir   r   r   r   r   /   s      z)single_ellipsis_index.<locals>.<listcomp>é   zb{}: More than one Ellipsis ('...') found in names ({}). This function supports up to one Ellipsis.é   r   )r   r   r   r   )r   Úfn_nameZellipsis_indicesr   r   r   Úsingle_ellipsis_index.   s     þr&   c                 C   s   || t |ƒ| … S r
   )r   )Znumel_pre_globZnumel_post_globr   r   r   r   Úexpand_single_ellipsis8   s    r'   c                 C   s8   t | t|ƒ|  d |ƒ}|d | … | || d d …  S )Nr$   )r'   r   )Úellipsis_idxr   Útensor_namesZglobbed_namesr   r   r   Úreplace_ellipsis_by_position<   s    r*   c                 C   s"   t | |ƒ}|dkr| S t|| |ƒS )zX
    Expands ... inside `names` to be equal to a list of names from `tensor_names`.
    N)r&   r*   )r   r)   r%   r(   r   r   r   Úresolve_ellipsisA   s    
r+   c                 C   s>   t |ƒdkr$|d d kr$|  d |¡S |  t|| jt|ƒƒ|¡S )Nr$   r   )r   Ú_update_namesr+   r   r   )r   r   r   r   r   r   Úupdate_names_with_listK   s     ÿr-   c                 C   sd   t | ƒ}| ¡ D ]>}|| }|| ¡ kr2|||< qtdj||| jt|ƒdƒ‚q|  t| ¡ ƒ|¡S )Nzq{api_name}: Tried to rename dim '{old_dim}' to dim {new_dim} in Tensor[{dims}] but dim '{old_dim}' does not exist)Úold_dimÚnew_dimZdimsÚapi_name)	r   Úkeysr   r   r   r   r,   r   Úvalues)r   Ú
rename_mapr   Zdim_mapr.   r/   r   r   r   Úupdate_names_with_mappingT   s    
  ý
r4   c                 C   s`   t |ƒdk}t|ƒ}|r0|r0tdjt|ƒdƒ‚|sD|sDt| ||ƒS |rTt| ||ƒS t| ||ƒS )až  There are two usages:

    tensor.rename(*names) returns a view on tensor with named dims `names`.
    `names` must be of length `tensor.dim()`; otherwise, if '...' is in `names`,
    then it is expanded greedily to be equal to the corresponding names from
    `tensor.names`.

    For example,
    ```
    >>> x = torch.empty(2, 3, 5, 7, names=('N', 'C', 'H', 'W'))
    >>> x.rename('...', 'height', 'width').names
    ('N', 'C', 'height', 'width')

    >>> x.rename('batch', '...', 'width').names
    ('batch', 'C', 'H', 'width')
    ```

    tensor.rename(**rename_map) returns a view on tensor that has rename dims
        as specified in the mapping `rename_map`.

    For example,
    ```
    >>> x = torch.empty(2, 3, 5, 7, names=('N', 'C', 'H', 'W'))
    >>> x.rename(W='width', H='height').names
    ('N', 'C', 'height', 'width')
    ```

    Finally, tensor.rename has an in-place version called tensor.rename_.
    r   z´{api_name}: This function takes either positional args or keyword args, but not both. Use tensor.{api_name}(*names) to name dims and tensor.{api_name}(**rename_map) to rename dims.)r0   )r   Úboolr   r   r   r-   r4   )r   r   r3   r   r   Zhas_rename_pairsr   r   r   Úupdate_namesb   s    ýr6   N)Úcollectionsr   r	   r   r   r   r!   r&   r'   r*   r+   r-   r4   r6   r   r   r   r   Ú<module>   s   	

	