SparseFillEmptyRows
========================



对稀疏张量按行进行补全操作。当某一行在输入稀疏表示中不存在非零元素时，
使用给定的 **default_value** 为该行补充一个元素，并生成新的稀疏表示结果。
同时可选地输出反向索引映射关系。

该算子常用于保证稀疏张量在行维度上的完备性。

.. math::

    \text{if row } r \text{ is empty:} \quad
    (r, 0, \dots) \rightarrow default\_value

输入：
    - **indices_ptr** - 输入稀疏索引数组地址，大小为 ``N × rank``。
    - **values_ptr** - 输入稀疏值数组地址。
    - **params** - 参数打包成数组。
        - **N** - 输入稀疏元素个数。
        - **rank** - 稀疏张量的秩（索引维度）。
        - **dense_rows** - 稠密行数。
        - **default_value** - 用于填充空行的默认值，传指针
        - **scratch_ptr** - 中间缓冲区，用于存放前缀和信息。
        - **filled_count** - 计数数组。
    - **core_mask** - 核掩码（仅共享存储版本需要）。
输出：
    - **output_y_indices_ptr** - 输出稀疏索引数组地址。
    - **output_y_values_ptr** - 输出稀疏值数组地址。
    - **output_reverse_index_map_ptr** - 反向索引映射输出地址。

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

.. note::
    - FT78NE 支持fp, dp, int8, int16, int32, cplx64, cplx128
    - MT7004 支持hp, fp, int16, int32, cplx64

**共享存储版本:**

.. c:function:: void i8_sparse_fill_empty_rows_s(int *indices_ptr, int8_t *values_ptr, int *output_y_indices_ptr, int8_t *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params, int core_mask)
.. c:function:: void i16_sparse_fill_empty_rows_s(int *indices_ptr, int16_t *values_ptr, int *output_y_indices_ptr, int16_t *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params, int core_mask)
.. c:function:: void i32_sparse_fill_empty_rows_s(int *indices_ptr, int32_t *values_ptr, int *output_y_indices_ptr, int32_t *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params, int core_mask)
.. c:function:: void hp_sparse_fill_empty_rows_s(int *indices_ptr, half *values_ptr, int *output_y_indices_ptr, half *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params, int core_mask)
.. c:function:: void fp_sparse_fill_empty_rows_s(int *indices_ptr, float *values_ptr, int *output_y_indices_ptr, float *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params, int core_mask)
.. c:function:: void dp_sparse_fill_empty_rows_s(int *indices_ptr, double *values_ptr, int *output_y_indices_ptr, double *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params, int core_mask)
.. c:function:: void c64_sparse_fill_empty_rows_s(int *indices_ptr, float *values_ptr, int *output_y_indices_ptr, float *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params, int core_mask)
.. c:function:: void c128_sparse_fill_empty_rows_s(int *indices_ptr, double *values_ptr, int *output_y_indices_ptr, double *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params, int core_mask)

**C调用示例：**

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

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

    int main(int argc, char* argv[]) {
        int *indices_vec = (int *) 0x81000000; //索引数组
        int *sparse_values = (int *)0x82000000; //值数组
        int *scratch = (int *)0x83000000; //scratch数组
        int *output_indices = (int *)0x84000000; //输出索引数组
        int *output_values = (int *)0x85000000; //输出值数组
        int *output_reverse_index_map = (int *)0x86000000; //输出反向索引映射数组
        int *filled_count = (int *)0x87000000; //填充计数数组

        int dims[] = {128, 8, 4};
        int rank = 3;
        int dense_rows = 128; //dims的第一个维度，即稠密行的数量
        int N = 120; 
        int default_value = 0;

        srand(seed++);

        int i;
        for (i = 0; i < N; i++) {
            indices_vec[i * rank] = rand() % dims[0];
            indices_vec[i * rank + 1] = rand() % dims[1];
            indices_vec[i * rank + 2] = rand() % dims[2];
            sparse_values[i] = rand() % 100;
        }

        compute_scratch(N, rank, dense_rows, indices_vec, scratch);
        
        //
        long long params[11];
        params[0] = (long long)N;
        params[1] = (long long)rank;
        params[2] = (long long)dense_rows;
        params[3] = (long long)&default_value;
        params[4] = (long long)scratch;
        params[5] = (long long)filled_count;

        int core_mask = 0b1111;
        i32_sparse_fill_empty_rows_s(indices_vec, sparse_values, output_indices, output_values, output_reverse_index_map, params, core_mask);

        return 0;
    }


**私有存储版本:**

.. c:function:: void i8_sparse_fill_empty_rows_p(int *indices_ptr, int8_t *values_ptr, int *output_y_indices_ptr, int8_t *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params)
.. c:function:: void i16_sparse_fill_empty_rows_p(int *indices_ptr, int16_t *values_ptr, int *output_y_indices_ptr, int16_t *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params)
.. c:function:: void i32_sparse_fill_empty_rows_p(int *indices_ptr, int32_t *values_ptr, int *output_y_indices_ptr, int32_t *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params)
.. c:function:: void hp_sparse_fill_empty_rows_p(int *indices_ptr, half *values_ptr, int *output_y_indices_ptr, half *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params)
.. c:function:: void fp_sparse_fill_empty_rows_p(int *indices_ptr, float *values_ptr, int *output_y_indices_ptr, float *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params)
.. c:function:: void dp_sparse_fill_empty_rows_p(int *indices_ptr, double *values_ptr, int *output_y_indices_ptr, double *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params)
.. c:function:: void c64_sparse_fill_empty_rows_p(int *indices_ptr, float *values_ptr, int *output_y_indices_ptr, float *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params)
.. c:function:: void c128_sparse_fill_empty_rows_p(int *indices_ptr, double *values_ptr, int *output_y_indices_ptr, double *output_y_values_ptr, int *output_reverse_index_map_ptr, long long *params)

**C调用示例：**

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

    //FT04示例
    #include <stdio.h>
    #include <sparsefillemptyrows.h>

    int main(int argc, char* argv[]) {
        int *indices_vec = (int *) 0x10010000; //索引数组
        int *sparse_values = (int *)0x10018000; //值数组
        int *scratch = (int *)0x10020000; //scratch数组
        int *output_indices = (int *)0x10028000; //输出索引数组
        int *output_values = (int *)0x10030000; //输出值数组
        int *output_reverse_index_map = (int *)0x10038000; //输出反向索引映射数组
        int *filled_count = (int *)0x100580000; //填充计数数组

        int dims[] = {128, 8, 4};
        int rank = 3;
        int dense_rows = 128; //dims的第一个维度，即稠密行的数量
        int N = 120; 
        int default_value = 0;

        srand(seed++);

        int i;
        for (i = 0; i < N; i++) {
            indices_vec[i * rank] = rand() % dims[0];
            indices_vec[i * rank + 1] = rand() % dims[1];
            indices_vec[i * rank + 2] = rand() % dims[2];
            sparse_values[i] = rand() % 100;
        }

        compute_scratch(N, rank, dense_rows, indices_vec, scratch);
        
        //
        long long params[11];
        params[0] = (long long)N;
        params[1] = (long long)rank;
        params[2] = (long long)dense_rows;
        params[3] = (long long)&default_value;
        params[4] = (long long)scratch;
        params[5] = (long long)filled_count;

        i32_sparse_fill_empty_rows_p(indices_vec, sparse_values, output_indices, output_values, output_reverse_index_map, params);

        return 0;
    }
