FlattenGrad
=================

Flatten 算子的反向传播算子，用于将一维梯度按照原始输入张量的形状还原。  
该算子不进行数值计算，仅依据原始形状信息对梯度数据进行内存拷贝与重解释，元素顺序保持不变。

.. math::

    \text{grad\_input} = \text{reshape}(\text{grad\_output}, \text{origin\_shape})

输入：
    - **input** - 上游梯度（Flatten 输出对应的梯度）地址。
    - **origin_shape** - 原始输入张量的形状数组。
    - **origin_ndim** - 原始输入张量的维度数。
    - **core_mask** - 核掩码（仅适用于共享存储版本）。

输出：
    - **output** - 还原形状后的梯度数据地址。

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

.. note::
    - FT78NE 支持 fp32
    - MT7004 支持 fp16, fp32
    - 该算子仅进行内存拷贝，不涉及数值运算
    - 输出元素总数等于 origin_shape 各维度之积

**共享存储版本:**

.. c:function:: void fp_flatten_grad_s(float* input, float* output, int* origin_shape, int origin_ndim, int core_mask)
.. c:function:: void hp_flatten_grad_s(half* input, half* output, int* origin_shape, int origin_ndim, int core_mask)

**C调用示例：**

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

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

    int main(int argc, char* argv[]) {
        float *grad_flat = (float *)0xA0000000;   // 梯度在 DDR
        float *grad_out  = (float *)0xC0000000;

        int origin_shape[2] = {32, 128};
        int origin_ndim = 2;
        int core_mask = 0xff;

        fp_flatten_grad_s(grad_flat, grad_out, origin_shape, origin_ndim, core_mask);
        return 0;
    }


**私有存储版本:**

.. c:function:: void fp_flatten_grad_p(float* input, float* output, int* origin_shape, int origin_ndim)
.. c:function:: void hp_flatten_grad_p(half* input, half* output, int* origin_shape, int origin_ndim)

**C调用示例：**

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

    // MT7004 示例
    #include <stdio.h>
    #include <flattengrad.h>

    int main(int argc, char* argv[]) {
        half *grad_flat = (half *)0x10810000;   // 梯度在 L2
        half *grad_out  = (half *)0x10820000;

        int origin_shape[3] = {1, 3, 224 * 224};
        int origin_ndim = 3;

        hp_flatten_grad_p(grad_flat, grad_out, origin_shape, origin_ndim);
        return 0;
    }
