NonZero
=================



查找输入张量中 **非零元素的位置索引**。
该算子按线性顺序遍历输入张量，对于满足“非零”判定条件的元素，
计算其在各维度上的索引，并顺序写入输出索引张量。

对于浮点类型，非零的判定标准为：

.. math::

    |x| > \epsilon

其中 :math:`\epsilon` 为平台定义的极小阈值（如 ``FLOAT_EPS``），
用于避免数值误差导致的误判。

输入：
    - **input** - 输入数据地址，按一维连续内存存储。
    - **dim_strides** - 各维度步长数组，长度为 ``input_rank``，
      用于将线性索引映射为多维索引。
    - **shape** - 输入张量的形状数组，长度为 ``input_rank`` （当前实现中主要用于描述维度信息）。
    - **input_rank** - 输入张量的维度数。
    - **length** - 输入张量的元素总数。
    - **core_mask** - 核掩码（仅适用于共享存储版本）。

输出：
    - **output** - 非零元素索引输出地址，
      按 ``[non_zero_num, input_rank]`` 形式顺序存储。
    - **non_zero_num** - 非零元素个数指针，函数执行结束后保存最终非零元素数量。

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

.. note::
    - FT78NE 支持 ``fp32``、``fp64``、``int8``、``int16``、``int32``、``cplx64``、``cplx128`` 类型
    - MT7004 支持 ``fp16``、``fp32``、``int16``、``int32``、``cplx64`` 类型
    - 输出索引按照输入线性遍历顺序排列
    - ``non_zero_num`` 在调用前需初始化为 0

**共享存储版本:**

.. c:function:: void fp_nonzero_s(float* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask)
.. c:function:: void dp_nonzero_s(double* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask)
.. c:function:: void i8_nonzero_s(int8_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask)
.. c:function:: void i16_nonzero_s(int16_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask)
.. c:function:: void i32_nonzero_s(int32_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask)
.. c:function:: void c64_nonzero_s(cplx64* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask)
.. c:function:: void c128_nonzero_s(cplx128* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask)

**C调用示例：**

.. code-block:: c
    :linenos:
    :emphasize-lines: 18-20

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

    int main(int argc, char* argv[]) {
        float *input = (float *)0xA0000000;
        int *output = (int *)0xC0000000;
        int *non_zero_num = (int *)0xA1000000;
        int *dim_strides = (int *)0xA2000000;
        int *shape = (int *)0xA3000000;

        int input_rank = 3;
        int length = 1024;
        int core_mask = 0xff;

        non_zero_num[0] = 0;

        fp_nonzero_s(input, output, non_zero_num,
                     dim_strides, shape, input_rank,
                     length, core_mask);
        return 0;
    }


**私有存储版本:**

.. c:function:: void fp_nonzero_p(float* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length)
.. c:function:: void dp_nonzero_p(double* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length)
.. c:function:: void i8_nonzero_p(int8_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length)
.. c:function:: void i16_nonzero_p(int16_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length)
.. c:function:: void i32_nonzero_p(int32_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length)
.. c:function:: void c64_nonzero_p(cplx64* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length)
.. c:function:: void c128_nonzero_p(cplx128* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length)


**C调用示例：**

.. code-block:: c
    :linenos:
    :emphasize-lines: 17-18

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

    int main(int argc, char* argv[]) {
        float *input = (float *)0x10810000;   // L2 空间
        int *output = (int *)0x10820000;
        int *non_zero_num = (int *)0x10830000;
        int *dim_strides = (int *)0x10840000;
        int *shape = (int *)0x10850000;

        int input_rank = 3;
        int length = 1024;

        non_zero_num[0] = 0;

        fp_nonzero_p(input, output, non_zero_num,
                     dim_strides, shape, input_rank, length);
        return 0;
    }
