o
    ߥi                     @   s   d dl Z d dl mZ d dlmZ d dlZd dlm  mZ z
d dl	m
Z
 dZW n ey2   dZY nw zd dlm  mZ W n eyI   dZY nw dZdd	 Zd
d Zdd Zdd Zdd ZddedefddZddedefddZdd ZdS )    N)abc)
accumulate)multi_tensor_l2normTF|c                    s0   t |drt|dkri S  fdd  |S )zu
    Apply some function to the sample. The f function will effect on the `Tensor` object, otherwise do nothing.
    __len__r   c                    s   t | r	| S t| tjr#t fdd|  D }| j|_|S t| tr3 fdd|  D S t| trA fdd| D S t| t	rQt	 fdd| D S t| t
r_ fdd	| D S | S )
Nc                 3   s     | ]\}}| |fV  qd S N .0keyvalue_applyr   d/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/models/multi_modal/ofa/generate/utils.py	<genexpr>(   s    
z2apply_to_sample.<locals>._apply.<locals>.<genexpr>c                    s   i | ]	\}}| |qS r   r   r	   r   r   r   
<dictcomp>-   s    z3apply_to_sample.<locals>._apply.<locals>.<dictcomp>c                    s   g | ]} |qS r   r   r
   xr   r   r   
<listcomp>/       z3apply_to_sample.<locals>._apply.<locals>.<listcomp>c                 3   s    | ]} |V  qd S r   r   r   r   r   r   r   1   s    c                    s   h | ]} |qS r   r   r   r   r   r   	<setcomp>3   r   z2apply_to_sample.<locals>._apply.<locals>.<setcomp>)torch	is_tensor
isinstancecollectionsOrderedDictitems__dict__dictlisttupleset)r   odr   fr   r   r   #   s"   




zapply_to_sample.<locals>._apply)hasattrlen)r$   sampler   r#   r   apply_to_sample   s   r(   c                    s`   t | tjr|  S t | ttfrt fdd| D S t | tjr. fdd|  D S | S )z,
    Puts each data field to the device
    c                 3   s    | ]}t | V  qd S r   move_to_device)r
   itemdevicer   r   r   A   s    z!move_to_device.<locals>.<genexpr>c                    s   i | ]
\}}|t | qS r   r)   r	   r,   r   r   r   C   s    
z"move_to_device.<locals>.<dictcomp>)	r   r   Tensortor   r    r   Mappingr   )batchr-   r   r,   r   r*   :   s   

r*   c                 C   s   | |  | S )z1
    Get the non pad value from input tensor
    )ne)tensorpadr   r   r   	strip_padK   s   r5   c                    s@   t | } fdd| D }tt|fddt|D }|S )aN  
    Get the token to word mapping. The token indicates the original token index, while word indicates the token index
    excluding the `exclude_list`.

    >>> import torch
    >>> all_tokens = torch.arange(4)
    >>> exclude_tokens = [1]
    >>> get_token_to_word_mapping(all_tokens, exclude_tokens) # {0: 1, 1: 1, 2: 2, 3: 3}
    c                    s   g | ]}t | vqS r   )int)r
   token)exclude_listr   r   r   ]   s    z-get_token_to_word_mapping.<locals>.<listcomp>c                    s   i | ]}| | qS r   r   )r
   i)word_idxr   r   r   _       z-get_token_to_word_mapping.<locals>.<dictcomp>)r&   r   r   range)tokensr8   n
word_starttoken_to_wordr   )r8   r:   r   get_token_to_word_mappingR   s
   
rA   c                 C   s   ||k||k@ j ddjdd}||k||kB j ddjdd}t|||g}t|||g}g }	t|dkrqt|t|k rq| | }
td|
dd|f< |
jdd\}}t||D ]\}}|	||  d ||  d f qY|	S )	O
    @deprecated
    There is no usage in this project, should be removed.
    Fas_tupledimr   z-infN   )	nonzerosqueezerA   r&   floatmaxzipappendr+   )attnsrc_senttgt_sentr4   eos	tgt_validsrc_invalidsrc_token_to_wordtgt_token_to_word	alignment
attn_valid_src_indicestgt_idxsrc_idxr   r   r   extract_hard_alignmentc   s6   r]   rG   
onnx_tracec                 C   (   |rt j|  |dS t j| |tjdS )z?
    softmax function. Using `torch.nn.functional.softmax`
    rF   rG   dtype)FsoftmaxrK   r   float32r   rG   r^   r   r   r   rc   {      rc   c                 C   r_   )zG
    log softmax function. Using `torch.nn.functional.log_softmax`
    rF   r`   )rb   log_softmaxrK   r   rd   re   r   r   r   rg      rf   rg   c           	      C   sb   ||kj dd}||kj ddjdd}g }t|dkr/t|dkr/| ||f }dd |D }|S )rB   FrC   rE   rF   r   c                 S   s   g | ]}d d |  D qS )c                 S   s   g | ]}d  |qS )z{:.6f})format)r
   pr   r   r   r      r;   z5extract_soft_alignment.<locals>.<listcomp>.<listcomp>)tolist)r
   	src_probsr   r   r   r      s    z*extract_soft_alignment.<locals>.<listcomp>)rI   rJ   r&   )	rO   rP   rQ   r4   rR   rS   	src_validrW   rX   r   r   r   extract_soft_alignment   s   rm   )F)r   r   	itertoolsr   r   torch.nn.functionalnn
functionalrb   amp_Cr   multi_tensor_l2norm_availableImportErrortorch_xla.core.xla_modelcore	xla_modelxmMANIFOLD_PATH_SEPr(   r*   r5   rA   r]   r6   boolrc   rg   rm   r   r   r   r   <module>   s2   

