EmbeddingLookup
=================

传入一个矩阵和一组索引，根据给定的索引提取对应的行（向量），若此行不曾被标记为“已正则化”，则对此行进行正则化处理，将结果拼接输出，若已经正则化过则直接输出。

.. math::

   \forall k \in [1, ids\_size], \quad
   \begin{cases}
   \text{if } \textbf{is\_regulated}[i\_k] = 0, &
     \begin{cases}
        \displaystyle X_{i\_k} \leftarrow
        X_{i\_k} \cdot \frac{\text{max\_norm}}
        {\sum_{j=1}^{layer\_size\_} X_{i\_k, j}} \\[10pt]
        \textbf{is\_regulated}[i\_k] \leftarrow 1
     \end{cases} \\[12pt]
   \text{输出向量 } Y_k \leftarrow X_{i\_k}
   \end{cases}

输入：
    - **input_data** - 输入矩阵数据地址。
    - **ids** - 输入索引的存储地址。
    - **max_norm** - 最大范数约束。
    - **is_regulated** - 记录矩阵行是否被正则化的标志数组。
    - **ids_size_** - 输入索引个数。
    - **layer_size_** - 输入矩阵的列数。
    - **layer_num_** - 输入矩阵的行数。
    - **core_mask(int, 可选)** - 核掩码（仅适用于共享存储版本）。
    
输出：
    - **output** - 结果输出地址。

支持平台：
    ``FT78NE``
    ``MT7004``

.. note::
    - FT78NE 支持fp32
    - MT7004 支持fp16, fp32

**共享存储版本：**

.. c:function:: void hp_embeddinglookup_s(half* input_data,int* ids, half* output, half max_norm_, bool* is_regulated, int ids_size_, int layer_size_, int layer_num_ , int core_mask)
.. c:function:: void fp_embeddinglookup_s(float* input_data,int* ids, float* output, float max_norm_, bool* is_regulated, int ids_size_, int layer_size_, int layer_num_ , int core_mask)


    **C调用示例：**

    .. code-block:: c
        :linenos:
        :emphasize-lines: 16

        //FT78NE示例
        #include <stdio.h>
        #include <embeddinglookup.h>

        int main(int argc, char* argv[]) {
            float *input_data = (float *)0xA0000000;   //input在DDR空间
            float *output_data = (float *)0xA0872c00;
            int layer_size = 4;//列
            int layer_num = 5;//行
            float max_norm = 4.5;
            int ids[]={0,1,3};
            int ids_size  = 3;//提取三行
            bool *output = (bool *)0xC0000000;
            bool is_regulated_[5] = {0};//layer_num
            int core_mask = 0xff;
            fp_embeddinglookup_s(input_data, ids, output_data, max_norm, is_regulated_, ids_size, layer_size, layer_num, core_mask);
            return 0;
        }


**私有存储版本：**

.. c:function:: void hp_embeddinglookup_p(half* Input0, half* Input1, bool* output,int length)
.. c:function:: void fp_embeddinglookup_p(float* Input0, float* Input1, bool* output,int length)


    **C调用示例：**

    .. code-block:: c
        :linenos:
        :emphasize-lines: 15

        //FT78NE示例
        #include <stdio.h>
        #include <embeddinglookup.h>

        int main(int argc, char* argv[]) {
            float *input_data = (float *)0x10810000;   //input在DDR空间
            float *output_data = (float *)0x10820000;
            int layer_size = 4;//列
            int layer_num = 5;//行
            float max_norm = 4.5;
            int ids[]={0,1,3};
            int ids_size  = 3;//提取三行
            bool *output = (bool *)0xC0000000;
            bool is_regulated_[5] = {0};//layer_num
            fp_embeddinglookup_s(input_data, ids, output_data, max_norm, is_regulated_, ids_size, layer_size, layer_num);
            return 0;
        }