# L2norm — MindSpore Signal+ 使用手册 alpha 文档

# L2norm

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

\[ \begin{align}\begin{aligned}S = \sqrt{\sum_{i=0}^{N-1} Input_i^2}\\\text{temp}_i = \frac{Input_i}{S}\\\begin{split}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}\end{split}\end{aligned}\end{align} \]

输入：

  - Input - 输入数据地址。

  - sqrt_sum - 输入向量的 L2 范数（模），需要预先计算好。

  - length - 计算长度。

  - is_relu - 是否进行 ReLU 操作的标志（0或1）。

  - is_relu6 - 是否进行 ReLU6 操作的标志（0或1）。

  - core_mask - 核掩码（仅共享存储版本需要）。

输出：

  - Output - 计算结果地址。

支持平台：

  `FT78NE` `MT7004`

备注

- FT78NE 支持fp32

- MT7004 支持fp16, fp32

共享存储版本:

void hp_l2norm_s(half *Input, half *output, half sqrt_sum, int length, int is_relu, int is_relu6, int core_mask)

void fp_l2norm_s(float *Input, float *output, float sqrt_sum, int length, int is_relu, int is_relu6, int core_mask)

C调用示例：

     1//FT78NE示例
     2#include <stdio.h>
     3#include <math.h>
     4#include <l2norm.h> // 假设头文件名为 l2norm.h
     5
     6int main(int argc, char* argv[]) {
     7    float *input = (float *)0xA0000000;   //input在DDR空间
     8    float *output = (float *)0xC0000000;
     9    int length = 1024;
    10    int core_mask = 0xff;
    11    // 伪代码：用户需要自行计算L2范数
    12    float sum_of_squares = 0.0f;
    13    for(int i=0; i<length; i++) sum_of_squares += input[i] * input[i];
    14    float l2_norm_val = sqrtf(sum_of_squares);
    15
    16    fp_l2norm_s(input, output, l2_norm_val, length, 0, 0, core_mask);
    17    return 0;
    18}

私有存储版本:

void hp_l2norm_p(half *Input, half *output, half sqrt_sum, int length, int is_relu, int is_relu6)

void fp_l2norm_p(float *Input, float *output, float sqrt_sum, int length, int is_relu, int is_relu6)

C调用示例：

     1//FT78NE示例
     2#include <stdio.h>
     3#include <math.h>
     4#include <l2norm.h> // 假设头文件名为 l2norm.h
     5
     6int main(int argc, char* argv[]) {
     7    float *input = (float *)0x10000000;   //input在L2空间
     8    float *output = (float *)0x10002000;
     9    int length = 1024;
    10    // 伪代码：用户需要自行计算L2范数
    11    float sum_of_squares = 0.0f;
    12    for(int i=0; i<length; i++) sum_of_squares += input[i] * input[i];
    13    float l2_norm_val = sqrtf(sum_of_squares);
    14
    15    fp_l2norm_p(input, output, l2_norm_val, length, 0, 0);
    16    return 0;
    17}