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

# Sparsetodense

将稀疏张量转换为密集张量。该算子根据稀疏索引和值，将稀疏元素填充到密集张量的对应位置。支持标量值模式（所有位置使用相同的值）和向量值模式（每个索引对应不同的值）。

对于每个稀疏元素，根据其索引计算在密集张量中的线性位置，根据 is_scalar 标志，将对应的稀疏值写入密集张量的对应位置

\[\begin{split}\text{output}[\text{index}] = \begin{cases} \text{sparse\_values}[0], & \text{if } \text{is\_scalar} = 1 \\ \text{sparse\_values}[i], & \text{if } \text{is\_scalar} = 0 \end{cases}\end{split}\]

输入：

  - indices_vec - 稀疏张量的索引数组，大小为 sparse_length * 4，每4个连续的int值表示一个稀疏元素在4维密集张量中的位置坐标 [dim0, dim1, dim2, dim3]。

  - sparse_values - 稀疏张量的值数组。如果 is_scalar = 1，只需要 sparse_values[0] 有效；如果 is_scalar = 0，需要 sparse_length 个值。

  - output_strides - 输出密集张量的步长数组，大小为4，用于将多维索引转换为线性索引。output_strides[0], output_strides[1], output_strides[2] 对应前3维的步长，第4维的步长为1。

  - sparse_length - 稀疏张量中非零元素的数量。

  - is_scalar - 是否为标量值标志。1 表示所有稀疏元素使用相同的值（sparse_values[0]），0 表示每个索引对应不同的值。

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

输出：

  - output - 输出密集张量的数据数组。输出数组的大小由 output_strides 和最大索引值确定。未在 indices_vec 中指定的位置保持原值（调用前需要初始化）。

支持平台：

  `FT78NE` `MT7004`

备注

- FT78NE 支持fp32, int8, int16, int32, fp64, cplx64, cplx128

- MT7004 支持fp16, fp32, int16, int32, cplx64

共享存储版本:

void i8_sparsetodense_s(int *indices_vec, int8_t *sparse_values, int8_t *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)

void i16_sparsetodense_s(int *indices_vec, int16_t *sparse_values, int16_t *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)

void i32_sparsetodense_s(int *indices_vec, int32_t *sparse_values, int32_t *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)

void hp_sparsetodense_s(int *indices_vec, half *sparse_values, half *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)

void fp_sparsetodense_s(int *indices_vec, float *sparse_values, float *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)

void dp_sparsetodense_s(int *indices_vec, double *sparse_values, double *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)

void c64_sparsetodense_s(int *indices_vec, float *sparse_values, float *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)

void c128_sparsetodense_s(int *indices_vec, double *sparse_values, double *output, int *output_strides, int sparse_length, int is_scalar, int core_mask)

C调用示例（向量值模式）：

     1//FT78NE示例
     2#include <stdio.h>
     3#include <sparsetodense.h>
     4
     5int main(int argc, char* argv[]) {
     6    // 假设在DDR空间
     7    // 输出密集张量形状 [2, 3, 4, 5]
     8    int output_shape[] = {2, 3, 4, 5};
     9
    10    // 计算步长：stride0 = 3*4*5 = 60, stride1 = 4*5 = 20, stride2 = 5, stride3 = 1
    11    int output_strides[4];
    12    output_strides[0] = 3 * 4 * 5;  // 60
    13    output_strides[1] = 4 * 5;      // 20
    14    output_strides[2] = 5;          // 5
    15    output_strides[3] = 1;          // 第4维步长为1（未使用）
    16
    17    // 稀疏元素：3个非零元素
    18    int sparse_length = 3;
    19
    20    // 索引：[[0,0,0,0], [0,1,2,3], [1,2,3,4]]
    21    int *indices_vec = (int *)0xA0000000;
    22    indices_vec[0] = 0; indices_vec[1] = 0; indices_vec[2] = 0; indices_vec[3] = 0;  // 位置(0,0,0,0)
    23    indices_vec[4] = 0; indices_vec[5] = 1; indices_vec[6] = 2; indices_vec[7] = 3;  // 位置(0,1,2,3)
    24    indices_vec[8] = 1; indices_vec[9] = 2; indices_vec[10] = 3; indices_vec[11] = 4; // 位置(1,2,3,4)
    25
    26    // 稀疏值：每个索引对应不同的值
    27    float *sparse_values = (float *)0xA1000000;
    28    sparse_values[0] = 1.0f;
    29    sparse_values[1] = 2.0f;
    30    sparse_values[2] = 3.0f;
    31
    32    // 输出密集张量（需要预先初始化为0或默认值）
    33    float *output = (float *)0xB0000000;
    34    int output_size = 2 * 3 * 4 * 5;  // 120
    35    memset(output, 0, output_size * sizeof(float));
    36
    37    int is_scalar = 0;  // 向量值模式
    38    int core_mask = 0xff;
    39
    40    fp_sparsetodense_s(indices_vec, sparse_values, output, output_strides,
    41                      sparse_length, is_scalar, core_mask);
    42
    43    return 0;
    44}

C调用示例（标量值模式）：

     1//FT78NE示例
     2#include <stdio.h>
     3#include <sparsetodense.h>
     4
     5int main(int argc, char* argv[]) {
     6    // 假设在DDR空间
     7    int output_strides[4];
     8    output_strides[0] = 3 * 4 * 5;  // 60
     9    output_strides[1] = 4 * 5;       // 20
    10    output_strides[2] = 5;           // 5
    11    output_strides[3] = 1;
    12
    13    int sparse_length = 3;
    14
    15    // 索引：[[0,0,0,0], [0,1,2,3], [1,2,3,4]]
    16    int *indices_vec = (int *)0xA0000000;
    17    indices_vec[0] = 0; indices_vec[1] = 0; indices_vec[2] = 0; indices_vec[3] = 0;
    18    indices_vec[4] = 0; indices_vec[5] = 1; indices_vec[6] = 2; indices_vec[7] = 3;
    19    indices_vec[8] = 1; indices_vec[9] = 2; indices_vec[10] = 3; indices_vec[11] = 4;
    20
    21    // 所有位置使用相同的值
    22    float *sparse_values = (float *)0xA1000000;
    23    sparse_values[0] = 5.0f;  // 只有这个值会被使用
    24
    25    float *output = (float *)0xB0000000;
    26    int output_size = 2 * 3 * 4 * 5;
    27    memset(output, 0, output_size * sizeof(float));
    28
    29    int is_scalar = 1;  // 标量值模式
    30    int core_mask = 0xff;
    31
    32    fp_sparsetodense_s(indices_vec, sparse_values, output, output_strides,
    33                      sparse_length, is_scalar, core_mask);
    34
    35    return 0;
    36}

私有存储版本:

void i8_sparsetodense_p(int *indices_vec, int8_t *sparse_values, int8_t *output, int *output_strides, int sparse_length, int is_scalar)

void i16_sparsetodense_p(int *indices_vec, int16_t *sparse_values, int16_t *output, int *output_strides, int sparse_length, int is_scalar)

void i32_sparsetodense_p(int *indices_vec, int32_t *sparse_values, int32_t *output, int *output_strides, int sparse_length, int is_scalar)

void hp_sparsetodense_p(int *indices_vec, half *sparse_values, half *output, int *output_strides, int sparse_length, int is_scalar)

void fp_sparsetodense_p(int *indices_vec, float *sparse_values, float *output, int *output_strides, int sparse_length, int is_scalar)

void dp_sparsetodense_p(int *indices_vec, double *sparse_values, double *output, int *output_strides, int sparse_length, int is_scalar)

void c64_sparsetodense_p(int *indices_vec, float *sparse_values, float *output, int *output_strides, int sparse_length, int is_scalar)

void c128_sparsetodense_p(int *indices_vec, double *sparse_values, double *output, int *output_strides, int sparse_length, int is_scalar)

C调用示例（私有存储版本）：

     1//FT78NE示例
     2#include <stdio.h>
     3#include <sparsetodense.h>
     4
     5int main(int argc, char* argv[]) {
     6    // 假设在L2空间
     7    int output_strides[4];
     8    output_strides[0] = 3 * 4 * 5;  // 60
     9    output_strides[1] = 4 * 5;      // 20
    10    output_strides[2] = 5;          // 5
    11    output_strides[3] = 1;
    12
    13    int sparse_length = 3;
    14
    15    int *indices_vec = (int *)0x10000000;
    16    indices_vec[0] = 0; indices_vec[1] = 0; indices_vec[2] = 0; indices_vec[3] = 0;
    17    indices_vec[4] = 0; indices_vec[5] = 1; indices_vec[6] = 2; indices_vec[7] = 3;
    18    indices_vec[8] = 1; indices_vec[9] = 2; indices_vec[10] = 3; indices_vec[11] = 4;
    19
    20    float *sparse_values = (float *)0x10001000;
    21    sparse_values[0] = 1.0f;
    22    sparse_values[1] = 2.0f;
    23    sparse_values[2] = 3.0f;
    24
    25    float *output = (float *)0x10002000;
    26    int output_size = 2 * 3 * 4 * 5;
    27    memset(output, 0, output_size * sizeof(float));
    28
    29    int is_scalar = 0;
    30
    31    fp_sparsetodense_p(indices_vec, sparse_values, output, output_strides,
    32                      sparse_length, is_scalar);
    33
    34    return 0;
    35}