a
    ==ic                     @   sf   d dl mZ d dlmZ d dlmZ d dlZd dlm	Z	 d dl
Z
e
eZdd ZG dd	 d	eZdS )
    )schema)
ModelLayer)	viewitemsN)defaultdictc                    s   t t}d | D ]}|jjd }t|drt|jdrt|jjdrt|jjjt	r|jjj
 D ]$\}}||  fdd|D  qb |7  q| rt	|S d S )Nr   metadatafeature_specsfeature_to_indexc                    s   g | ]} | qS  r	   ).0vi	start_posr	   l/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/caffe2/python/layers/concat.py
<listcomp>       z5get_concatenated_feature_to_index.<locals>.<listcomp>)r   listZdtypeshapehasattrr   r   
isinstancer   dictitemsextendkeys)Zblobs_to_concatZconcat_feature_to_indexZscalarZnum_dimskvr	   r   r   !get_concatenated_feature_to_index   s    


r   c                       s*   e Zd ZdZd	 fdd	Zdd Z  ZS )
Concata  
    Construct Concat layer
    Assume that first dimension is batch,

    Example:

        embedding_dim = 64
        input_record = self.new_record(schema.Struct(
            ('input1', schema.Scalar((np.float32, (embedding_dim, )))),
            ('input2', schema.Scalar((np.float32, (embedding_dim, )))),
            ('input3', schema.Scalar((np.float32, (embedding_dim, )))),
        ))

        output = self.model.Concat(input_record)
        self.assertEqual(
            schema.Scalar((np.float32, ((len(input_record.fields) * embedding_dim, )))),
            output
        )

        # Note that in Concat layer we assume first dimension is batch.
        # so input is B * embedding_dim
        # add_axis=1 make it B * 1 * embedding_dim
        # Concat on axis=1 make it B * N * embedding_dim

        output = self.model.Concat(input_record, axis=1, add_axis=1)
        self.assertEqual(
            schema.Scalar((np.float32, ((len(input_record.fields), embedding_dim)))),
            output
        )
       r   concatc                    s  t t| j|||fi | || _|| _|dkr@|dkr@J dt|tjsZJ d|g }t	|j
D ]d\}}	t|	tjsJ d||	t|	 j}
|r|
|d d t|
|ksJ d||
 qhtdt|  |dkrt|d | dg| _d S d}|D ]D}
||
|d  7 }d|
|d < |
|d ksJ d	|
|d q|d }|||d < td
t|  ttj|f| d| _|j
 }t|}|rtjtj|dd}| j| d S )Nr   r   zIt's not allowed to add axis=0z8Incorrect input type. Expected Struct, but received: {0}z9Incorrect input type for {}. Expected Scalar, but got: {}z:Concat expects that limited dimensions of the input tensorzConcat Layer input shapes: outputz0Shapes {0} and {1} are not compatible for ConcatzConcat Layer output_dims: )r   )r   )superr   __init__axisadd_axisr   r   Structformatr   fieldsZScalarr   
field_typer   insertlenappendloggerinfostrZfrom_blob_listZget_next_blob_referenceoutput_schemanpfloat32valuesr   MetadataZFeatureSpecZset_metadata)selfmodelinput_recordr"   r#   namekwargsZshapes
field_namer'   r   Z
concat_dimZoutput_dimsZrecord_to_concatZconcated_feature_to_indexr   	__class__r	   r   r!   C   sv    


zConcat.__init__c                 C   s<   |j | j | j d | j d d g| j| jd d S )Nr   Z_concat_dims)r"   r#   )r   r5   Zfield_blobsr.   r"   r#   )r3   netr	   r	   r   add_ops   s    zConcat.add_ops)r   r   r   )__name__
__module____qualname____doc__r!   r<   __classcell__r	   r	   r9   r   r   #   s
     =r   )Zcaffe2.pythonr   Zcaffe2.python.layers.layersr   Zfuture.utilsr   numpyr/   collectionsr   logging	getLoggerr=   r+   r   r   r	   r	   r	   r   <module>   s   
