Concat
=================

在指定维度（axis）上连接一组张量。所有输入张量除了连接维度外，其他维度的形状必须完全相同。

.. math::

   output = \text{Concat}(input_0, input_1, \dots, input_{n-1}, \text{axis})

输入：
    - **inputs** - 包含所有输入张量起始地址的数组指针。
    - **input_shapes** - 包含所有输入张量形状（shape）的数组指针。
    - **num_inputs** - 输入张量的数量。
    - **axis** - 连接操作所在的维度索引。
    - **input_ndim** - 输入张量的维度（秩）。
    - **core_mask(int, 可选)** - 核掩码（仅适用于共享存储版本）。

输出：
    - **output** - 计算结果存储地址。

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

.. note::
    - FT78NE 支持 int8, int16, int32, fp32, fp64, cplx64, cplx128
    - MT7004 支持 fp16, fp32, int16, int32, cplx64
    - 所有输入张量的维度 `input_ndim` 必须一致。
    - 除 `axis` 指定的维度外，所有输入张量的 `shape[i]` 必须相等。

**共享存储版本:**

.. c:function:: void i8_concat_s(int8_t* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, int8_t* output, int core_mask)
.. c:function:: void i16_concat_s(int16_t* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, int16_t* output, int core_mask)
.. c:function:: void i32_concat_s(int32_t* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, int32_t* output, int core_mask)
.. c:function:: void hp_concat_s(half* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, half* output, int core_mask)
.. c:function:: void fp_concat_s(float* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, float* output, int core_mask)
.. c:function:: void dp_concat_s(double* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, double* output, int core_mask)
.. c:function:: void c64_concat_s(float* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, float* output, int core_mask)
.. c:function:: void c128_concat_s(double* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, double* output, int core_mask)

    **C调用示例：**

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

        // FT78NE 示例（共享存储）
        #include <stdio.h>
        #include "78NE/utils.h"

        int main() {
            int shape0[] = { 4, 10, 8, 12 };
            int shape1[] = { 4, 5, 8, 12 };
            int shape2[] = { 4, 15, 8, 12 };
            int* input_shapes[] = { shape0, shape1, shape2 };
            
            float *input0 = (float *)0xA0000000;
            float *input1 = (float *)0xA2000000;
            float *input2 = (float *)0xA4000000;
            float *inputs[] = { input0, input1, input2 };
            float *output = (float *)0xB0000000;

            int num_inputs = 3;
            int axis = 1;
            int input_ndim = 4;
            int core_mask = 0b1011;

            fp_concat_s(inputs, input_shapes, num_inputs, axis, input_ndim, output, core_mask);
            return 0;
        }


**私有存储版本:**

.. c:function:: void i8_concat_p(int8_t* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, int8_t* output)
.. c:function:: void i16_concat_p(int16_t* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, int16_t* output)
.. c:function:: void i32_concat_p(int32_t* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, int32_t* output)
.. c:function:: void hp_concat_p(half* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, half* output)
.. c:function:: void fp_concat_p(float* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, float* output)
.. c:function:: void dp_concat_p(double* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, double* output)
.. c:function:: void c64_concat_p(float* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, float* output)
.. c:function:: void c128_concat_p(double* inputs[], int* input_shapes[], int num_inputs, int axis, int input_ndim, double* output)

    **C调用示例：**

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

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

        int main() {
            int shape0[] = { 2, 3, 4, 5 };
            int shape1[] = { 2, 2, 4, 5 };
            int* input_shapes[] = { shape0, shape1 };

            float *input0 = (float *)0x10810000;
            float *input1 = (float *)0x10820000; 
            float *inputs[] = { input0, input1 };
            float *output = (float *)0x10830000;

            int num_inputs = 2;
            int axis = 1;
            int input_ndim = 4;

            fp_concat_p(inputs, input_shapes, num_inputs, axis, input_ndim, output);
            return 0;
        }