PadFusion
=================
通过指定的填充模式和大小对输入张量进行填充，支持常数填充、反射填充和对称填充三种模式。

输入：
    - **input** - 输入张量地址。
    - **input_shape** - 输入张量形状数组（不超过4维，不足时从前往后补1）。
    - **output_shape** - 输出张量形状数组（不超过4维，不足时从前往后补1）。
    - **paddings** - 填充大小数组（长度为 (2 × 输入张量维数)，不足时从前往后补1）。
    - **padding_mode** - 填充模式：Constant=0, Reflect=1, Symmetric=2。
    - **constant_value** - 常量填充时的填充值（仅Constant模式使用）。
    - **core_mask(int, 可选)** - 核掩码（仅适用于共享存储版本）。

输出：
    - **output** - 输出数据地址。
    - **formated_input_shape** - 格式化后的输入形状数组地址。
    - **formated_output_shape** - 格式化后的输出形状数组地址。
    - **formated_paddings** - 格式化后的填充数组地址。
    - **in_strides** - 输入张量步长数组地址。
    - **out_strides** - 输出张量步长数组地址。

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

.. note::
    - FT78NE 支持的数据类型：int8, int16, int32, fp32, fp64, cplx64, cplx128
    - MT7004 支持的数据类型：fp16, fp32, int16, int32, cplx64

**填充模式说明：**
    - ``kConstant = 0`` - 常数填充，使用指定的 constant_value 进行填充
    - ``kReflect = 1`` - 反射填充，使用张量边缘的值(不包含边界值)填充输入张量。例如，向 [1, 2, 3, 4] 的两边分别填充2个元素，结果为 [3, 2, 1, 2, 3, 4, 3, 2]。
    - ``kSymmetric = 2`` - 对称填充，使用张量边缘的值(包含边界值)填充输入张量。例如，向 [1, 2, 3, 4] 的两边分别填充2个元素，结果为 [2, 1, 1, 2, 3, 4, 4, 3]。

**共享存储版本：**

.. c:function:: void i8_padfusion_s(long long* params, int core_mask)
.. c:function:: void i16_padfusion_s(long long* params, int core_mask)
.. c:function:: void i32_padfusion_s(long long* params, int core_mask)
.. c:function:: void fp_padfusion_s(long long* params, int core_mask)
.. c:function:: void dp_padfusion_s(long long* params, int core_mask)
.. c:function:: void c64_padfusion_s(long long* params, int core_mask)
.. c:function:: void c128_padfusion_s(long long* params, int core_mask)
.. c:function:: void hp_padfusion_s(long long* params, int core_mask)

**参数数组结构：**

.. code-block:: c
    :linenos:

    long long params[12];
    params[0] = (long long)input;                    // 输入数据地址
    params[1] = (long long)output;                   // 输出数据地址
    params[2] = (long long)input_shape;              // 输入形状数组
    params[3] = (long long)output_shape;             // 输出形状数组
    params[4] = (long long)paddings;                 // 填充数组
    params[5] = (long long)padding_mode;             // 填充模式
    params[6] = (long long)constant_value;           // 常数填充值的*地址*
    params[7] = (long long)formated_input_shape;     // 格式化输入形状
    params[8] = (long long)formated_output_shape;    // 格式化输出形状
    params[9] = (long long)formated_paddings;        // 格式化填充数组
    params[10] = (long long)in_strides;              // 输入步长数组
    params[11] = (long long)out_strides;             // 输出步长数组

**C调用示例：**

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

        // FT78NE 多核示例
        #include <stdio.h>
        #include <padfusion.h>

        int main(void) {
            srand(time(0));
            
            // 输入参数设置
            int input_shape[4] = {23, 31, 29, 28};
            int paddings[8] = {3, 2, 3, 2, 1, 2, 0, 2};
            int padding_mode = 2;  // kSymmetric
            double constant_value[2] = {1.0, 0.0};
            int core_mask = 0xff;

            // 内存分配（DDR空间）
            double* input = (double*)0x81000000;
            double* output = (double*)0x82000000;
            int* formated_input_shape = (int*)0x84000000;
            int* formated_output_shape = (int*)0x85000000;
            int* formated_paddings = (int*)0x86000000;
            int* in_strides = (int*)0x87000000;
            int* out_strides = (int*)0x88000000;
            int* output_shape = (int*)0x89000000;

            // 计算输出形状
            for (int i = 0; i < 4; ++i) {
                output_shape[i] = input_shape[i] + paddings[i * 2] + paddings[i * 2 + 1];
            }

            // 初始化input
            // ... 省略初始化input数据代码 ...

            // 准备参数数组
            long long params[12];
            params[0] = (long long)input;
            params[1] = (long long)output;
            params[2] = (long long)input_shape;
            params[3] = (long long)output_shape;
            params[4] = (long long)paddings;
            params[5] = (long long)padding_mode;
            params[6] = (long long)constant_value;
            params[7] = (long long)formated_input_shape;
            params[8] = (long long)formated_output_shape;
            params[9] = (long long)formated_paddings;
            params[10] = (long long)in_strides;
            params[11] = (long long)out_strides;

            // 执行 PadFusion 操作
            c128_padfusion_s(params, core_mask);
            return 0;
        }

**私有存储版本：**

.. c:function:: void i8_padfusion_p(long long* params)
.. c:function:: void i16_padfusion_p(long long* params)
.. c:function:: void i32_padfusion_p(long long* params)
.. c:function:: void fp_padfusion_p(long long* params)
.. c:function:: void dp_padfusion_p(long long* params)
.. c:function:: void c64_padfusion_p(long long* params)
.. c:function:: void c128_padfusion_p(long long* params)
.. c:function:: void hp_padfusion_p(long long* params)

**C调用示例：**

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

        // MT7004 单核示例
        #include <stdio.h>
        #include <padfusion.h>


        int main(void) {
            // 输入参数设置
            int input_shape[4] = {4, 8, 4, 8};
            int paddings[8] = {1, 1, 1, 1, 1, 1, 1, 1};
            int padding_mode = 0;  // kConstant
            float constant_value = 0.0f;

            // 内存分配（L2空间）
            float* input = (float*)0x10000000;
            float* output = (float*)0x10100000;
            int* output_shape = (int*)0x10200000;
            int* formated_input_shape = (int*)0x10300000;
            int* formated_output_shape = (int*)0x10400000;
            int* formated_paddings = (int*)0x10500000;
            int* in_strides = (int*)0x10600000;
            int* out_strides = (int*)0x10700000;

            // 计算输出形状
            for (int i = 0; i < 4; ++i) {
                output_shape[i] = input_shape[i] + paddings[i * 2] + paddings[i * 2 + 1];
            }

            // 初始化input
            // ... 省略初始化input数据代码 ...

            // 准备参数数组
            long long params[12];
            params[0] = (long long)input;
            params[1] = (long long)output;
            params[2] = (long long)input_shape;
            params[3] = (long long)output_shape;
            params[4] = (long long)paddings;
            params[5] = (long long)padding_mode;
            params[6] = (long long)&constant_value;
            params[7] = (long long)formated_input_shape;
            params[8] = (long long)formated_output_shape;
            params[9] = (long long)formated_paddings;
            params[10] = (long long)in_strides;
            params[11] = (long long)out_strides;

            // 执行 PadFusion 操作
            fp_padfusion_p(params);
            return 0;
        }