L2norm
=================



对输入向量进行 L2 归一化，并可选择性地应用 ReLU 或 ReLU6 激活函数。该算子首先用输入向量的 L2 范数（即欧几里得长度）去除向量中的每个元素，然后应用激活函数。

.. math::

    S = \sqrt{\sum_{i=0}^{N-1} Input_i^2}

    \text{temp}_i = \frac{Input_i}{S}

    output_i = \begin{cases}
        \min(6, \max(0, \text{temp}_i)), & \text{if } \text{is\_relu6} = 1 \\
        \max(0, \text{temp}_i), & \text{if } \text{is\_relu} = 1 \\
        \text{temp}_i, & \text{otherwise}
    \end{cases}

输入：
    - **Input** - 输入数据地址。
    - **sqrt_sum** - 输入向量的 L2 范数（模），需要预先计算好。
    - **length** - 计算长度。
    - **is_relu** - 是否进行 ReLU 操作的标志（0或1）。
    - **is_relu6** - 是否进行 ReLU6 操作的标志（0或1）。
    - **core_mask** - 核掩码（仅共享存储版本需要）。

输出：
    - **Output** - 计算结果地址。

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

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

**共享存储版本:**

.. c:function:: void hp_l2norm_s(half* Input, half* output, half sqrt_sum, int length, int is_relu, int is_relu6, int core_mask)
.. c:function:: void fp_l2norm_s(float* Input, float* output, float sqrt_sum, int length, int is_relu, int is_relu6, int core_mask)

**C调用示例：**

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

    //FT78NE示例
    #include <stdio.h>
    #include <math.h>
    #include <l2norm.h> // 假设头文件名为 l2norm.h

    int main(int argc, char* argv[]) {
        float *input = (float *)0xA0000000;   //input在DDR空间
        float *output = (float *)0xC0000000;
        int length = 1024;
        int core_mask = 0xff;
        // 伪代码：用户需要自行计算L2范数
        float sum_of_squares = 0.0f;
        for(int i=0; i<length; i++) sum_of_squares += input[i] * input[i];
        float l2_norm_val = sqrtf(sum_of_squares);

        fp_l2norm_s(input, output, l2_norm_val, length, 0, 0, core_mask);
        return 0;
    }


**私有存储版本:**

.. c:function:: void hp_l2norm_p(half* Input, half* output, half sqrt_sum, int length, int is_relu, int is_relu6)
.. c:function:: void fp_l2norm_p(float* Input, float* output, float sqrt_sum, int length, int is_relu, int is_relu6)
    
**C调用示例：**

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

    //FT78NE示例
    #include <stdio.h>
    #include <math.h>
    #include <l2norm.h> // 假设头文件名为 l2norm.h

    int main(int argc, char* argv[]) {
        float *input = (float *)0x10000000;   //input在L2空间
        float *output = (float *)0x10002000;
        int length = 1024;
        // 伪代码：用户需要自行计算L2范数
        float sum_of_squares = 0.0f;
        for(int i=0; i<length; i++) sum_of_squares += input[i] * input[i];
        float l2_norm_val = sqrtf(sum_of_squares);

        fp_l2norm_p(input, output, l2_norm_val, length, 0, 0);
        return 0;
    }