o
    ϯi                     @   s   d dl mZmZ d dlZd dlmZ 	 dedee fddZG dd dej	Z
G d	d
 d
ej	ZG dd dej	Zdee fddZdS )    )CallableListNmethodfeature_dimsc                 C   sr   | dkrt |S | dkrt|S | dkrt|dd S | dkr&t|dd S | dkr1t|d	d S td
|  d)a  
    Args:
        method (str): the fusion method to be constructed. Options:
            - 'concat'
            - 'temporal_concat'
            - 'max'
            - 'sum'
            - 'prod'

        feature_dims (List[int]): the first argument of all fusion layers. It holds a list
            of required feature_dims for each tensor input (where the tensor inputs are of
            shape (batch_size, seq_len, feature_dim)). The list order must corresponds to
            the tensor order passed to forward(...).
    concattemporal_concatmaxc                 S   s   t j| ddjS Nr   dim)torchr   valuesx r   N/home/ubuntu/.local/lib/python3.10/site-packages/pytorchvideo/layers/fusion.py<lambda>%   s    z#make_fusion_layer.<locals>.<lambda>sumc                 S      t j| ddS r	   )r   r   r   r   r   r   r   '       prodc                 S   r   r	   )r   r   r   r   r   r   r   )   r   zFusion z not available.)ConcatFusionTemporalConcatFusionReduceFusionNotImplementedError)r   r   r   r   r   make_fusion_layer   s   r   c                       P   e Zd ZdZdee f fddZedd Zdee	j
 de	j
fd	d
Z  ZS )r   z
    Concatenates all inputs by their last dimension. The resulting tensor last dim will be
    the sum of the last dimension of all input tensors.
    r   c                    s    t    t| t|| _d S N)super__init___verify_feature_dimr   _output_dimselfr   	__class__r   r   r   4   s   
zConcatFusion.__init__c                 C      | j S zC
        Last dimension size of forward(..) tensor output.
        r!   r#   r   r   r   
output_dim9      zConcatFusion.output_dim
input_listreturnc                 C      t j|ddS )a8  
        Args:
            input_list (List[torch.Tensor]): a list of tensors of shape
                (batch_size, seq_len, feature_dim).

        Returns:
            Tensor of shape (batch_size, seq_len, sum(feature_dims)) where sum(feature_dims)
                is the sum of all input feature_dims.
        r
   r   catr#   r,   r   r   r   forward@      
zConcatFusion.forward__name__
__module____qualname____doc__r   intr   propertyr*   r   Tensorr3   __classcell__r   r   r$   r   r   .   s    
"r   c                       r   )r   z[
    Concatenates all inputs by their temporal dimension which is assumed to be dim=1.
    r   c                    s2   t    t| t|| _| jt|ksJ d S r   )r   r   r    r   r!   minr"   r$   r   r   r   R   s   

zTemporalConcatFusion.__init__c                 C   r&   r'   r(   r)   r   r   r   r*   Z   r+   zTemporalConcatFusion.output_dimr,   r-   c                 C   r.   )a,  
        Args:
            input_list (List[torch.Tensor]): a list of tensors of shape
                (batch_size, seq_len, feature_dim)

        Returns:
            Tensor of shape (batch_size, sum(seq_len), feature_dim) where sum(seq_len) is
                the sum of all input tensors.
           r
   r0   r2   r   r   r   r3   a   r4   zTemporalConcatFusion.forwardr5   r   r   r$   r   r   M   s    
"r   c                       sb   e Zd ZdZdee deejgejf f fddZ	e
dd Zdeej d	ejfd
dZ  ZS )r   z
    Generic fusion method which takes a callable which takes the list of input tensors
    and expects a single tensor to be used. This class can be used to implement fusion
    methods like "sum", "max" and "prod".
    r   	reduce_fnc                    s8   t    t| || _t|| _| jt|ksJ d S r   )r   r   r    r@   r   r!   r>   )r#   r   r@   r$   r   r   r   u   s
   

zReduceFusion.__init__c                 C   r&   r'   r(   r)   r   r   r   r*      r+   zReduceFusion.output_dimr,   r-   c                 C   s   |  t|S )z
        Args:
            input_list (List[torch.Tensor]): a list of tensors of shape
                (batch_size, seq_len, feature_dim).

        Returns:
            Tensor of shape (batch_size, seq_len, feature_dim).
        )r@   r   stackr2   r   r   r   r3      s   	zReduceFusion.forward)r6   r7   r8   r9   r   r:   r   r   r<   r   r;   r*   r3   r=   r   r   r$   r   r   n   s    
"r   c                 C   s(   t | tsJ tdd | D sJ d S )Nc                 s   s    | ]}|d kV  qdS )r   Nr   ).0r   r   r   r   	<genexpr>   s    z&_verify_feature_dim.<locals>.<genexpr>)
isinstancelistall)r   r   r   r   r       s   r    )typingr   r   r   torch.nnnnstrr:   r   Moduler   r   r   r    r   r   r   r   <module>   s   !%