Stridedslice
=================

对输入张量进行步长切片（Strided Slice）操作。该算子根据起始位置（begins）、结束位置（ends）和步长（strides）从输入张量中提取子张量。该算子不区分数据类型，适用于所有数据类型。

算法支持三种运行模式：
1. **全拷贝模式**（soft_copy_mode = 1）：当输出是输入的连续子区域时，使用内存拷贝。
2. **快速运行模式**（fast_run = 1）：优化的快速路径，适用于特定场景。
3. **普通模式**：逐块拷贝模式，适用于一般情况。

对于每个维度 `i`，输出张量的索引范围由 `begins[i]`、`ends[i]` 和 `strides[i]` 决定：

.. math::

    \text{output\_shape}[i] = \left\lceil \frac{\text{ends}[i] - \text{begins}[i]}{\text{strides}[i]} \right\rceil

输入：
    - **input** - 输入数据指针（void*）。
    - **in_shape** - 输入张量的形状数组（int*），大小为 `in_shape_size`。
    - **out_shape** - 输出张量的形状数组（int*），大小为 `out_shape_size`。
    - **in_shape_size** - 输入张量的维度数（int）。
    - **out_shape_size** - 输出张量的维度数（int）。
    - **begins** - 起始位置数组（int*），每个维度切片开始的位置。
    - **ends** - 结束位置数组（int*），每个维度切片结束的位置。
    - **strides** - 步长数组（int*），每个维度的步长。
    - **data_type_bytes** - 数据类型所占字节数（int）。
    - **soft_copy_mode** - 全拷贝模式标志（int），1 表示启用，0 表示不启用。
    - **fast_run** - 快速运行模式标志（int），1 表示启用，0 表示不启用。
    - **split_axis** - 策略2：分割轴（int），当输入和输出张量只有1个维度不同时使用。
    - **inner_size** - 策略2：内部大小（int）。
    - **outer** - 策略2：外部大小（int）。
    - **parallel_on_outer** - 策略2：是否在外层并行（int）。
    - **parallel_on_split_axis** - 策略2：是否在分割轴并行（int）。
    - **cal_num_per_thread** - 策略2：每个线程的计算数量（int）。
    - **caled_num** - 策略2：已计算数量（int）。
    - **temp_space** - 临时空间指针（void*）。
    - **inner** - 策略2：内部大小（int），与 `inner_size` 类似。

输出：
    - **output** - 输出数据指针（void*）。

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

.. note::
    - FT78NE 支持fp32, int8, int16, int32, fp64, cplx64, cplx128
    - MT7004 支持fp16, fp32, int16, int32, cplx64
    - 该算子不区分数据类型，适用于所有数据类型
    - 算子会根据 `soft_copy_mode` 和 `fast_run` 标志自动选择最优的执行路径
    - 策略2相关参数用于优化特定场景（输入和输出张量只有1个维度不同）

**共享存储版本:**

.. c:function:: void stridedslice(void* input, void* output, int* in_shape, int* out_shape, int in_shape_size, int out_shape_size, int* begins, int* ends, int* strides, int data_type_bytes, int soft_copy_mode, int fast_run, int split_axis, int inner_size, int outer, int parallel_on_outer, int parallel_on_split_axis, int cal_num_per_thread, int caled_num, void* temp_space, int inner, int core_mask)

**C调用示例：**

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

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

    int main(int argc, char* argv[]) {
        // 假设在DDR空间
        // 输入张量形状 [2, 3, 4, 5]
        int in_shape[] = {2, 3, 4, 5};
        int in_shape_size = 4;
        
        // 输出张量形状 [1, 2, 2, 3]
        // 从 [0, 1, 1, 2] 开始，到 [2, 3, 4, 5] 结束，步长为 [1, 1, 2, 1]
        int out_shape[] = {1, 2, 2, 3};
        int out_shape_size = 4;
        
        // 切片参数
        int begins[] = {0, 1, 1, 2};  // 每个维度的起始位置
        int ends[] = {2, 3, 4, 5};     // 每个维度的结束位置
        int strides[] = {1, 1, 2, 1};  // 每个维度的步长
        
        // 数据类型：float32，占4字节
        int data_type_bytes = 4;
        
        // 输入输出数据指针
        float *input = (float *)0xA0000000;
        float *output = (float *)0xB0000000;
        
        // 运行模式
        int soft_copy_mode = 0;  // 不启用全拷贝模式
        int fast_run = 0;         // 不启用快速运行模式
        
        // 策略2参数（不使用时可设为0）
        int split_axis = 0;
        int inner_size = 0;
        int outer = 0;
        int parallel_on_outer = 0;
        int parallel_on_split_axis = 0;
        int cal_num_per_thread = 0;
        int caled_num = 0;
        int inner = 0;
        
        // 临时空间
        void *temp_space = (void *)0xC0000000;
        
        // 核掩码
        
        stridedslice(input, output, in_shape, out_shape, in_shape_size, out_shape_size,
                       begins, ends, strides, data_type_bytes, soft_copy_mode, fast_run,
                       split_axis, inner_size, outer, parallel_on_outer, parallel_on_split_axis,
                       cal_num_per_thread, caled_num, temp_space, inner);
        
        return 0;
    }

**私有存储版本:**

.. c:function:: void stridedslice(void* input, void* output, int* in_shape, int* out_shape, int in_shape_size, int out_shape_size, int* begins, int* ends, int* strides, int data_type_bytes, int soft_copy_mode, int fast_run, int split_axis, int inner_size, int outer, int parallel_on_outer, int parallel_on_split_axis, int cal_num_per_thread, int caled_num, void* temp_space, int inner)

**C调用示例：**

.. code-block:: c
    :linenos:
    :emphasize-lines: 37-40

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

    int main(int argc, char* argv[]) {
        // 假设在L2空间
        int in_shape[] = {2, 3, 4, 5};
        int in_shape_size = 4;
        
        int out_shape[] = {1, 2, 2, 3};
        int out_shape_size = 4;
        
        int begins[] = {0, 1, 1, 2};
        int ends[] = {2, 3, 4, 5};
        int strides[] = {1, 1, 2, 1};
        
        int data_type_bytes = 4;
        
        float *input = (float *)0x10000000;
        float *output = (float *)0x10010000;
        
        int soft_copy_mode = 0;
        int fast_run = 0;
        
        // 策略2参数（不使用）
        int split_axis = 0;
        int inner_size = 0;
        int outer = 0;
        int parallel_on_outer = 0;
        int parallel_on_split_axis = 0;
        int cal_num_per_thread = 0;
        int caled_num = 0;
        int inner = 0;
        
        void *temp_space = (void *)0x10020000;
        
        stridedslice(input, output, in_shape, out_shape, in_shape_size, out_shape_size,
                      begins, ends, strides, data_type_bytes, soft_copy_mode, fast_run,
                      split_axis, inner_size, outer, parallel_on_outer, parallel_on_split_axis,
                      cal_num_per_thread, caled_num, temp_space, inner);
        
        return 0;
    }


