# ReverseSequence — MindSpore Signal+ 使用手册 alpha 文档

# ReverseSequence

对输入序列进行部分反转。

输入：

  - src - 需反转数据的地址

  - seq_lengths - 指定反转长度，为一维向量。

  - param - 算子计算所需参数的结构体。其各成员见下述。

  - core_mask - 核掩码。

ReverseSequenceParameter定义：

     1typedef struct ReverseSequenceParameter {
     2    int* shape_; // 输入和输出张量的形状
     3    int* strides_; // 一个记录张量每一维步长的数组
     4    int seq_dim_; // 指定反转的维度
     5    int batch_dim_; // 指定切片维度
     6    int ndim_; // 输入和输出张量的维度
     7    int type_size_; // 输入和输出张量数据类型的长度
     8    int copy_elem_num_; // 在inner_count循环中一次应被拷贝的元素数目
     9    int outer_stride_; // 外层元素间的步长
    10    int outer_count_; // 外层元素数
    11    int inner_stride_; // 内层元素间的步长
    12    int inner_count_; // 内层元素数
    13} ReverseSequenceParameter;

输出：

  - dst - 输出地址。

支持平台：

  `FT78NE` `MT7004`

备注

- FT78NE 支持int8, int16, int32, fp32, fp64, cplx64, cplx128

- MT7004 支持fp16, fp32, int16, int32, cplx64

共享/私有存储版本:

void anytype_reverse_sequence_anycore(void *src, void *dst, int *seq_lengths, ReverseSequenceParameter *param, int core_mask)

各种数据类型、私有及共享空间版本均使用该函数。对于不同数据类型，改变param中的type_size_参数即可。

C调用示例：

     1void Resize(ReverseSequenceParameter* param) {
     2    param->strides_ = (int*)0xA8020000;
     3    ComputeStrides(param->shape_, param->strides_, param->ndim_);
     4    int less_dim = param->batch_dim_ > param->seq_dim_ ? param->seq_dim_ : param->batch_dim_;
     5    int greater_dim = param->batch_dim_ < param->seq_dim_ ? param->seq_dim_ : param->batch_dim_;
     6    // calculate the size of elements should be copied at one time
     7    param->copy_elem_num_ = CountElementAfterDim(param->shape_, greater_dim, param->ndim_);
     8    // calculate the number of elements before the less axis and the stride
     9    param->outer_count_ = CountElementBeforeDim(param->shape_, less_dim);
    10    param->outer_stride_ = param->shape_[less_dim] * CountElementAfterDim(param->shape_, less_dim, param->ndim_);
    11    // calculate the number of elements between the less axis and the greater axis and the stride
    12    param->inner_count_ = 1;
    13    int i;
    14    for (i = less_dim + 1; i < greater_dim; i++) {
    15        param->inner_count_ *= param->shape_[i];
    16    }
    17    param->inner_stride_ = param->shape_[greater_dim] * CountElementAfterDim(param->shape_, greater_dim, param->ndim_);
    18}
    19
    20void TestReverseSequenceFp32(int* shape, int* orig_seq_lengths, int seq_dim, int batch_dim, int ndim, int core_mask) {
    21    int core_id = get_core_id();
    22    int core_num = GetCoreNum(core_mask);
    23    int logic_core_id = GetLogicCoreId(core_mask, core_id);
    24    float* input_data = (float*)0x88000000; // 测试私有空间时地址设置在私有空间内即可
    25    float* output_data = (float*)0x98000000;
    26    float* check = (float*)0xB8000000;
    27    int* seq_lengths = (int*)0xC8000000;
    28    ReverseSequenceParameter* param = (ReverseSequenceParameter*)0xA8000000;
    29    int i;
    30    if (logic_core_id == 0) {
    31        param->shape_ = (int*)0xA8010000;
    32        memcpy(param->shape_, shape, sizeof(int) * ndim);
    33        memcpy(seq_lengths, orig_seq_lengths, sizeof(int) * shape[batch_dim]);
    34        param->batch_dim_ = batch_dim;
    35        param->seq_dim_ = seq_dim;
    36        param->ndim_ = ndim;
    37        param->type_size_ = sizeof(float);
    38        Resize(param);
    39    }
    40    sys_bar(0, core_num); // 初始化参数完成后进行同步
    41    anytype_reverse_sequence_anycore(input_data, output_data, seq_lengths, param, core_mask);
    42}
    43
    44void main(){
    45    int shape[3] = {3, 4, 10};
    46    int seq_lengths[3] = {1, 2, 3};
    47    int ndim = 3;
    48    int seq_dim = 1;
    49    int batch_dim = 0;
    50    int core_mask = 0b1111; // 测试单核时核掩码设置为0b0001即可
    51    TestReverseSequenceFp32(shape, seq_lengths, seq_dim, batch_dim, ndim, core_mask);
    52}