Flatten
=================

将多维输入张量按行优先（row-major）顺序展平成一维连续数组。  
该算子仅改变数据的形状，不改变数据内容与顺序，本质上是一次连续内存拷贝操作。

数学上可表示为：

.. math::

    \text{output} = \text{reshape}(\text{input}, [-1])

输入张量的所有元素按照原有存储顺序依次写入输出张量。

输入：
    - **input** - 输入数据地址。
    - **core_mask** - 核掩码（仅适用于共享存储版本）。
    - **param** - Flatten 参数结构体指针，包含形状与类型信息。

输出：
    - **output** - 展平后的输出数据地址。

FlattenParameter 结构体说明：

    - **shape_** - 输入张量各维度大小数组。
    - **ndim_** - 输入张量维度数。
    - **elem_cnt_** - 输入张量元素总数。
    - **type_size_** - 单个元素的字节数。

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

.. note::
    - FT78NE 支持 ``fp32``、``fp64``、``int8``、``int16``、``int32``、``cplx64``、``cplx128``
    - MT7004 支持 ``fp16``、``fp32``、``int16``、``int32``、``cplx64``
    - 该算子不涉及数值计算，仅进行内存搬运
    - 当 input 与 output 地址相同时，算子直接返回，不执行拷贝
    - 当 core_mask 对应的逻辑核无效时，算子直接返回

**共享存储版本:**

.. c:function:: void Flatten(const void* input, void* output, int core_mask, FlattenParameter* param)

**C调用示例：**

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

    // FT78NE 示例（共享存储）
    #include <stdio.h>
    #include <flatten.h>

    int main(int argc, char* argv[]) {
        float *input  = (float *)0xA0000000;   // DDR 空间
        float *output = (float *)0xC0000000;

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

        FlattenParameter param;
        param.shape_ = shape;
        param.ndim_ = 3;
        param.elem_cnt_ = 1 * 3 * 224 * 224;
        param.type_size_ = sizeof(float);

        int core_mask = 0xff;
        Flatten(input, output, core_mask, &param);

        return 0;
    }


**私有存储版本:**

该算子在私有存储模式下等价为单核内存拷贝操作，
直接调用 `Flatten` 且 core_mask 设置为单核即可。

**C调用示例：**

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

    // FT78NE 示例（私有存储）
    #include <stdio.h>
    #include <flatten.h>

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

        int shape[2] = {4, 256};

        FlattenParameter param;
        param.shape_ = shape;
        param.ndim_ = 2;
        param.elem_cnt_ = 4 * 256;
        param.type_size_ = sizeof(float);

        Flatten(input, output, 0x1, &param);

        return 0;
    }
