forked from mindspore-Ecosystem/mindspore
support neg stride
support different shape length and begins length
This commit is contained in:
parent
9a5e074c48
commit
a8866026d9
|
@ -22,14 +22,22 @@ void PadStridedSliceParameterTo4D(StridedSliceParameter *param) {
|
||||||
int32_t ends[DIMENSION_4D];
|
int32_t ends[DIMENSION_4D];
|
||||||
int32_t strides[DIMENSION_4D];
|
int32_t strides[DIMENSION_4D];
|
||||||
int32_t input_shape[DIMENSION_4D];
|
int32_t input_shape[DIMENSION_4D];
|
||||||
for (int32_t i = 0; i < param->num_axes_; ++i) {
|
int32_t i;
|
||||||
|
for (i = 0; i < param->num_axes_; ++i) {
|
||||||
begins[i] = param->begins_[i];
|
begins[i] = param->begins_[i];
|
||||||
ends[i] = param->ends_[i];
|
ends[i] = MSMIN(param->ends_[i], param->in_shape_[i]);
|
||||||
strides[i] = param->strides_[i];
|
strides[i] = param->strides_[i];
|
||||||
input_shape[i] = param->in_shape_[i];
|
input_shape[i] = param->in_shape_[i];
|
||||||
}
|
}
|
||||||
int32_t real_index = param->num_axes_ - 1;
|
for (i = param->num_axes_; i < param->in_shape_length_; ++i) {
|
||||||
for (int32_t i = DIMENSION_4D - 1; i >= 0; --i) {
|
input_shape[i] = param->in_shape_[i];
|
||||||
|
begins[i] = 0;
|
||||||
|
ends[i] = param->in_shape_[i];
|
||||||
|
strides[i] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t real_index = param->in_shape_length_ - 1;
|
||||||
|
for (i = DIMENSION_4D - 1; i >= 0; --i) {
|
||||||
if (real_index >= 0) {
|
if (real_index >= 0) {
|
||||||
param->begins_[i] = begins[real_index];
|
param->begins_[i] = begins[real_index];
|
||||||
param->ends_[i] = ends[real_index];
|
param->ends_[i] = ends[real_index];
|
||||||
|
@ -43,8 +51,23 @@ void PadStridedSliceParameterTo4D(StridedSliceParameter *param) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
param->num_axes_ = DIMENSION_4D;
|
param->num_axes_ = DIMENSION_4D;
|
||||||
|
param->in_shape_length_ = DIMENSION_4D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChangeNegToPositive(StridedSliceParameter *param) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < DIMENSION_4D; ++i) {
|
||||||
|
if (param->begins_[i] < 0) {
|
||||||
|
param->begins_[i] += param->in_shape_[i];
|
||||||
|
}
|
||||||
|
if (param->ends_[i] < 0) {
|
||||||
|
param->ends_[i] += param->in_shape_[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool LoopContinue(int stride, int i, int end) { return stride > 0 ? i < end : i > end; }
|
||||||
|
|
||||||
int DoStridedSlice(const void *in_data, void *out_data, StridedSliceParameter *param) {
|
int DoStridedSlice(const void *in_data, void *out_data, StridedSliceParameter *param) {
|
||||||
if (in_data == NULL || out_data == NULL || param == NULL) {
|
if (in_data == NULL || out_data == NULL || param == NULL) {
|
||||||
return NNACL_NULL_PTR;
|
return NNACL_NULL_PTR;
|
||||||
|
@ -61,16 +84,18 @@ int DoStridedSlice(const void *in_data, void *out_data, StridedSliceParameter *p
|
||||||
if (param->num_axes_ < DIMENSION_4D) {
|
if (param->num_axes_ < DIMENSION_4D) {
|
||||||
PadStridedSliceParameterTo4D(param);
|
PadStridedSliceParameterTo4D(param);
|
||||||
}
|
}
|
||||||
|
ChangeNegToPositive(param);
|
||||||
|
|
||||||
size_t dim_offset[DIMENSION_4D - 1];
|
size_t dim_offset[DIMENSION_4D - 1];
|
||||||
dim_offset[2] = in_shape[3];
|
dim_offset[2] = in_shape[3];
|
||||||
dim_offset[1] = dim_offset[2] * in_shape[2];
|
dim_offset[1] = dim_offset[2] * in_shape[2];
|
||||||
dim_offset[0] = dim_offset[1] * in_shape[1];
|
dim_offset[0] = dim_offset[1] * in_shape[1];
|
||||||
size_t out_offset = 0;
|
size_t out_offset = 0;
|
||||||
for (int32_t dim0 = begins[0]; dim0 < ends[0]; dim0 += strides[0]) {
|
int32_t dim0, dim1, dim2, dim3;
|
||||||
for (int32_t dim1 = begins[1]; dim1 < ends[1]; dim1 += strides[1]) {
|
for (dim0 = begins[0]; LoopContinue(strides[0], dim0, ends[0]); dim0 += strides[0]) {
|
||||||
for (int32_t dim2 = begins[2]; dim2 < ends[2]; dim2 += strides[2]) {
|
for (dim1 = begins[1]; LoopContinue(strides[1], dim1, ends[1]); dim1 += strides[1]) {
|
||||||
for (int32_t dim3 = begins[3]; dim3 < ends[3]; dim3 += strides[3]) {
|
for (dim2 = begins[2]; LoopContinue(strides[2], dim2, ends[2]); dim2 += strides[2]) {
|
||||||
|
for (dim3 = begins[3]; LoopContinue(strides[3], dim3, ends[3]); dim3 += strides[3]) {
|
||||||
int32_t in_offset = dim0 * dim_offset[0] + dim1 * dim_offset[1] + dim2 * dim_offset[2] + dim3;
|
int32_t in_offset = dim0 * dim_offset[0] + dim1 * dim_offset[1] + dim2 * dim_offset[2] + dim3;
|
||||||
if (param->data_type == kDataTypeFloat) {
|
if (param->data_type == kDataTypeFloat) {
|
||||||
*((float *)out_data + out_offset) = *((float *)in_data + in_offset);
|
*((float *)out_data + out_offset) = *((float *)in_data + in_offset);
|
||||||
|
|
|
@ -25,6 +25,7 @@ typedef struct StridedSliceParameter {
|
||||||
int strides_[8];
|
int strides_[8];
|
||||||
int isScale;
|
int isScale;
|
||||||
int num_axes_;
|
int num_axes_;
|
||||||
|
int in_shape_length_;
|
||||||
int in_shape_[8];
|
int in_shape_[8];
|
||||||
LiteDataType data_type;
|
LiteDataType data_type;
|
||||||
} StridedSliceParameter;
|
} StridedSliceParameter;
|
||||||
|
|
|
@ -44,6 +44,11 @@ int StridedSliceCPUKernel::ReSize() {
|
||||||
MS_ASSERT(input);
|
MS_ASSERT(input);
|
||||||
MS_ASSERT(parameter);
|
MS_ASSERT(parameter);
|
||||||
parameter->data_type = input->data_type() == kNumberTypeInt8 ? kDataTypeInt8 : kDataTypeFloat;
|
parameter->data_type = input->data_type() == kNumberTypeInt8 ? kDataTypeInt8 : kDataTypeFloat;
|
||||||
|
auto input_shape = input->shape();
|
||||||
|
for (size_t i = 0; i < input_shape.size(); ++i) {
|
||||||
|
parameter->in_shape_[i] = input_shape[i];
|
||||||
|
}
|
||||||
|
parameter->in_shape_length_ = static_cast<int>(input_shape.size());
|
||||||
return RET_OK;
|
return RET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,434 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include "utils/log_adapter.h"
|
||||||
|
#include "common/common_test.h"
|
||||||
|
#include "mindspore/lite/src/common/utils.h"
|
||||||
|
#include "nnacl/strided_slice.h"
|
||||||
|
#include "mindspore/lite/src/kernel_registry.h"
|
||||||
|
#include "mindspore/lite/src/lite_kernel.h"
|
||||||
|
|
||||||
|
namespace mindspore {
|
||||||
|
class TestStridedSliceFp32 : public mindspore::CommonTest {
|
||||||
|
public:
|
||||||
|
TestStridedSliceFp32() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void InitStridedSliceParam(StridedSliceParameter *param, const std::vector<int> &in_shape,
|
||||||
|
const std::vector<int> &begins, const std::vector<int> &ends,
|
||||||
|
const std::vector<int> &strides, const int begins_length, const int in_shape_length) {
|
||||||
|
for (auto i = 0; i < begins_length; i++) {
|
||||||
|
param->in_shape_[i] = in_shape[i];
|
||||||
|
param->begins_[i] = begins[i];
|
||||||
|
param->ends_[i] = ends[i];
|
||||||
|
param->strides_[i] = strides[i];
|
||||||
|
}
|
||||||
|
param->num_axes_ = begins_length;
|
||||||
|
param->in_shape_length_ = in_shape_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestStridedSliceFp32, StridedSlice1) {
|
||||||
|
// prepare stage
|
||||||
|
auto strided_slice_param = new StridedSliceParameter();
|
||||||
|
std::vector<int> in_shape{1, 2, 4};
|
||||||
|
std::vector<int> begins{0, 0, 0};
|
||||||
|
std::vector<int> ends{1, 2, 4};
|
||||||
|
std::vector<int> strides{1, 2, 2};
|
||||||
|
int length = 3;
|
||||||
|
int in_shape_length = 3;
|
||||||
|
InitStridedSliceParam(strided_slice_param, in_shape, begins, ends, strides, length, in_shape_length);
|
||||||
|
|
||||||
|
float input_data[8] = {0.2390374, 0.92039955, 0.05051243, 0.49574447, 0.8355223, 0.02647042, 0.08811307, 0.4566604};
|
||||||
|
|
||||||
|
float correct[2] = {0.2390374, 0.05051243};
|
||||||
|
|
||||||
|
float output_data[2];
|
||||||
|
|
||||||
|
// runtime part
|
||||||
|
printf("Calculating runtime cost...\n");
|
||||||
|
uint64_t time_avg = 0;
|
||||||
|
|
||||||
|
// warm up loop
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
DoStridedSlice(input_data, output_data, strided_slice_param);
|
||||||
|
}
|
||||||
|
|
||||||
|
int loop_count = 100;
|
||||||
|
auto time_start = mindspore::lite::GetTimeUs();
|
||||||
|
for (int i = 0; i < loop_count; i++) {
|
||||||
|
DoStridedSlice(input_data, output_data, strided_slice_param);
|
||||||
|
}
|
||||||
|
auto time_end = mindspore::lite::GetTimeUs();
|
||||||
|
auto cost = time_end - time_start;
|
||||||
|
time_avg = cost / loop_count;
|
||||||
|
printf("single thread running time : %f ms\n", time_avg / 1000.0f);
|
||||||
|
|
||||||
|
printf("==================output data=================\n");
|
||||||
|
std::cout << output_data[0] << " , " << output_data[1];
|
||||||
|
std::cout << std::endl;
|
||||||
|
printf("==================corret data=================\n");
|
||||||
|
std::cout << correct[0] << " , " << correct[1];
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
CompareOutputData(output_data, correct, 2, 0.00001);
|
||||||
|
|
||||||
|
delete strided_slice_param;
|
||||||
|
MS_LOG(INFO) << "Teststrided_sliceFp32 passed";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestStridedSliceFp32, StridedSlice2) {
|
||||||
|
// prepare stage
|
||||||
|
auto strided_slice_param = new StridedSliceParameter();
|
||||||
|
std::vector<int> in_shape{1, 3, 3};
|
||||||
|
std::vector<int> begins{0, 0, 0};
|
||||||
|
std::vector<int> ends{2, 4, 4};
|
||||||
|
std::vector<int> strides{1, 1, 1};
|
||||||
|
int length = 3;
|
||||||
|
int in_shape_length = 3;
|
||||||
|
InitStridedSliceParam(strided_slice_param, in_shape, begins, ends, strides, length, in_shape_length);
|
||||||
|
|
||||||
|
float input_data[9] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f};
|
||||||
|
|
||||||
|
float correct[9] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f};
|
||||||
|
|
||||||
|
float output_data[9];
|
||||||
|
|
||||||
|
// runtime part
|
||||||
|
DoStridedSlice(input_data, output_data, strided_slice_param);
|
||||||
|
|
||||||
|
CompareOutputData(output_data, correct, 9, 0.00001);
|
||||||
|
|
||||||
|
delete strided_slice_param;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestStridedSliceFp32, StridedSlice3) {
|
||||||
|
// prepare stage
|
||||||
|
auto strided_slice_param = new StridedSliceParameter();
|
||||||
|
std::vector<int> in_shape{1, 2, 4};
|
||||||
|
std::vector<int> begins{0, 0, 0};
|
||||||
|
std::vector<int> ends{1, 2, 4};
|
||||||
|
std::vector<int> strides{1, 2, 2};
|
||||||
|
int length = 3;
|
||||||
|
int in_shape_length = 3;
|
||||||
|
InitStridedSliceParam(strided_slice_param, in_shape, begins, ends, strides, length, in_shape_length);
|
||||||
|
|
||||||
|
// int input_shape[3] = {1, 2, 4};
|
||||||
|
std::vector<int> input_shape = {1, 2, 4};
|
||||||
|
float input_data[8] = {0.2390374, 0.92039955, 0.05051243, 0.49574447, 0.8355223, 0.02647042, 0.08811307, 0.4566604};
|
||||||
|
|
||||||
|
float correct[2] = {0.2390374, 0.05051243};
|
||||||
|
float output_data[2];
|
||||||
|
// int out_shape[3] = {1, 1, 2};
|
||||||
|
std::vector<int> output_shape = {1, 1, 2};
|
||||||
|
|
||||||
|
lite::Tensor input_tensor;
|
||||||
|
input_tensor.SetData(input_data);
|
||||||
|
input_tensor.set_shape(input_shape);
|
||||||
|
std::vector<lite::Tensor *> inputs_tensor(1);
|
||||||
|
inputs_tensor[0] = &input_tensor;
|
||||||
|
|
||||||
|
std::vector<lite::Tensor *> outputs_tensor;
|
||||||
|
lite::Tensor output_tensor;
|
||||||
|
outputs_tensor.push_back(&output_tensor);
|
||||||
|
output_tensor.SetData(output_data);
|
||||||
|
output_tensor.set_data_type(input_tensor.data_type());
|
||||||
|
output_tensor.set_shape(output_shape);
|
||||||
|
|
||||||
|
lite::Context *ctx = new lite::Context();
|
||||||
|
ctx->thread_num_ = 2;
|
||||||
|
strided_slice_param->op_parameter_.type_ = schema::PrimitiveType_StridedSlice;
|
||||||
|
kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeFloat32, schema::PrimitiveType_StridedSlice};
|
||||||
|
auto creator = lite::KernelRegistry::GetInstance()->GetCreator(desc);
|
||||||
|
ASSERT_NE(creator, nullptr);
|
||||||
|
kernel::LiteKernel *kernel =
|
||||||
|
creator(inputs_tensor, outputs_tensor, reinterpret_cast<OpParameter *>(strided_slice_param), ctx, desc, nullptr);
|
||||||
|
ASSERT_NE(kernel, nullptr);
|
||||||
|
kernel->Run();
|
||||||
|
delete ctx;
|
||||||
|
|
||||||
|
CompareOutputData(output_data, correct, 2, 0.000001);
|
||||||
|
input_tensor.SetData(nullptr);
|
||||||
|
output_tensor.SetData(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestStridedSliceFp32, StridedSlice4) {
|
||||||
|
// prepare stage
|
||||||
|
auto strided_slice_param = new StridedSliceParameter();
|
||||||
|
std::vector<int> in_shape{5, 5};
|
||||||
|
std::vector<int> begins{-5, -3};
|
||||||
|
std::vector<int> ends{-1, -1};
|
||||||
|
std::vector<int> strides{2, 1};
|
||||||
|
int length = 2;
|
||||||
|
int in_shape_length = 2;
|
||||||
|
InitStridedSliceParam(strided_slice_param, in_shape, begins, ends, strides, length, in_shape_length);
|
||||||
|
|
||||||
|
std::vector<int> input_shape = {5, 5};
|
||||||
|
float input_data[25] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
|
||||||
|
13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0};
|
||||||
|
|
||||||
|
float correct[4] = {2.0, 3.0, 12.0, 13.0};
|
||||||
|
float output_data[4];
|
||||||
|
std::vector<int> output_shape = {2, 2};
|
||||||
|
|
||||||
|
lite::Tensor input_tensor;
|
||||||
|
input_tensor.SetData(input_data);
|
||||||
|
input_tensor.set_shape(input_shape);
|
||||||
|
std::vector<lite::Tensor *> inputs_tensor(1);
|
||||||
|
inputs_tensor[0] = &input_tensor;
|
||||||
|
|
||||||
|
std::vector<lite::Tensor *> outputs_tensor;
|
||||||
|
lite::Tensor output_tensor;
|
||||||
|
outputs_tensor.push_back(&output_tensor);
|
||||||
|
output_tensor.SetData(output_data);
|
||||||
|
output_tensor.set_data_type(input_tensor.data_type());
|
||||||
|
output_tensor.set_shape(output_shape);
|
||||||
|
|
||||||
|
lite::Context *ctx = new lite::Context();
|
||||||
|
ctx->thread_num_ = 2;
|
||||||
|
strided_slice_param->op_parameter_.type_ = schema::PrimitiveType_StridedSlice;
|
||||||
|
kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeFloat32, schema::PrimitiveType_StridedSlice};
|
||||||
|
auto creator = lite::KernelRegistry::GetInstance()->GetCreator(desc);
|
||||||
|
ASSERT_NE(creator, nullptr);
|
||||||
|
kernel::LiteKernel *kernel =
|
||||||
|
creator(inputs_tensor, outputs_tensor, reinterpret_cast<OpParameter *>(strided_slice_param), ctx, desc, nullptr);
|
||||||
|
ASSERT_NE(kernel, nullptr);
|
||||||
|
kernel->Run();
|
||||||
|
delete ctx;
|
||||||
|
|
||||||
|
CompareOutputData(output_data, correct, 4, 0.000001);
|
||||||
|
input_tensor.SetData(nullptr);
|
||||||
|
output_tensor.SetData(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestStridedSliceFp32, StridedSlice5) {
|
||||||
|
// prepare stage
|
||||||
|
auto strided_slice_param = new StridedSliceParameter();
|
||||||
|
std::vector<int> in_shape{5, 5, 5};
|
||||||
|
std::vector<int> begins{1, -1, 1};
|
||||||
|
std::vector<int> ends{4, -3, 3};
|
||||||
|
std::vector<int> strides{1, -1, 1};
|
||||||
|
int length = 3;
|
||||||
|
int in_shape_length = 3;
|
||||||
|
InitStridedSliceParam(strided_slice_param, in_shape, begins, ends, strides, length, in_shape_length);
|
||||||
|
|
||||||
|
std::vector<int> input_shape = {5, 5, 5};
|
||||||
|
float input_data[125] = {
|
||||||
|
0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
|
||||||
|
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
|
||||||
|
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
|
||||||
|
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
|
||||||
|
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
|
||||||
|
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0,
|
||||||
|
96.0, 97.0, 98.0, 99.0, 100.0, 101.0, 102.0, 103.0, 104.0, 105.0, 106.0, 107.0, 108.0, 109.0, 110.0, 111.0,
|
||||||
|
112.0, 113.0, 114.0, 115.0, 116.0, 117.0, 118.0, 119.0, 120.0, 121.0, 122.0, 123.0, 124.0};
|
||||||
|
|
||||||
|
float correct[12] = {46.0, 47.0, 41.0, 42.0, 71.0, 72.0, 66.0, 67.0, 96.0, 97.0, 91.0, 92.0};
|
||||||
|
float output_data[12];
|
||||||
|
std::vector<int> output_shape = {3, 2, 2};
|
||||||
|
|
||||||
|
lite::Tensor input_tensor;
|
||||||
|
input_tensor.SetData(input_data);
|
||||||
|
input_tensor.set_shape(input_shape);
|
||||||
|
std::vector<lite::Tensor *> inputs_tensor(1);
|
||||||
|
inputs_tensor[0] = &input_tensor;
|
||||||
|
|
||||||
|
std::vector<lite::Tensor *> outputs_tensor;
|
||||||
|
lite::Tensor output_tensor;
|
||||||
|
outputs_tensor.push_back(&output_tensor);
|
||||||
|
output_tensor.SetData(output_data);
|
||||||
|
output_tensor.set_data_type(input_tensor.data_type());
|
||||||
|
output_tensor.set_shape(output_shape);
|
||||||
|
|
||||||
|
lite::Context *ctx = new lite::Context();
|
||||||
|
ctx->thread_num_ = 2;
|
||||||
|
strided_slice_param->op_parameter_.type_ = schema::PrimitiveType_StridedSlice;
|
||||||
|
kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeFloat32, schema::PrimitiveType_StridedSlice};
|
||||||
|
auto creator = lite::KernelRegistry::GetInstance()->GetCreator(desc);
|
||||||
|
ASSERT_NE(creator, nullptr);
|
||||||
|
kernel::LiteKernel *kernel =
|
||||||
|
creator(inputs_tensor, outputs_tensor, reinterpret_cast<OpParameter *>(strided_slice_param), ctx, desc, nullptr);
|
||||||
|
ASSERT_NE(kernel, nullptr);
|
||||||
|
kernel->Run();
|
||||||
|
delete ctx;
|
||||||
|
|
||||||
|
CompareOutputData(output_data, correct, 12, 0.000001);
|
||||||
|
input_tensor.SetData(nullptr);
|
||||||
|
output_tensor.SetData(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestStridedSliceFp32, StridedSlice6) {
|
||||||
|
// prepare stage
|
||||||
|
auto strided_slice_param = new StridedSliceParameter();
|
||||||
|
std::vector<int> in_shape{5, 5, 5};
|
||||||
|
std::vector<int> begins{-5, -3, 1};
|
||||||
|
std::vector<int> ends{-1, -1, 3};
|
||||||
|
std::vector<int> strides{2, 1, 1};
|
||||||
|
int length = 3;
|
||||||
|
int in_shape_length = 3;
|
||||||
|
InitStridedSliceParam(strided_slice_param, in_shape, begins, ends, strides, length, in_shape_length);
|
||||||
|
|
||||||
|
std::vector<int> input_shape = {5, 5, 5};
|
||||||
|
float input_data[125] = {
|
||||||
|
0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
|
||||||
|
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
|
||||||
|
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
|
||||||
|
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
|
||||||
|
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
|
||||||
|
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0,
|
||||||
|
96.0, 97.0, 98.0, 99.0, 100.0, 101.0, 102.0, 103.0, 104.0, 105.0, 106.0, 107.0, 108.0, 109.0, 110.0, 111.0,
|
||||||
|
112.0, 113.0, 114.0, 115.0, 116.0, 117.0, 118.0, 119.0, 120.0, 121.0, 122.0, 123.0, 124.0};
|
||||||
|
|
||||||
|
float correct[8] = {11.0, 12.0, 16.0, 17.0, 61.0, 62.0, 66.0, 67.0};
|
||||||
|
float output_data[8];
|
||||||
|
std::vector<int> output_shape = {2, 2, 2};
|
||||||
|
|
||||||
|
lite::Tensor input_tensor;
|
||||||
|
input_tensor.SetData(input_data);
|
||||||
|
input_tensor.set_shape(input_shape);
|
||||||
|
std::vector<lite::Tensor *> inputs_tensor(1);
|
||||||
|
inputs_tensor[0] = &input_tensor;
|
||||||
|
|
||||||
|
std::vector<lite::Tensor *> outputs_tensor;
|
||||||
|
lite::Tensor output_tensor;
|
||||||
|
outputs_tensor.push_back(&output_tensor);
|
||||||
|
output_tensor.SetData(output_data);
|
||||||
|
output_tensor.set_data_type(input_tensor.data_type());
|
||||||
|
output_tensor.set_shape(output_shape);
|
||||||
|
|
||||||
|
lite::Context *ctx = new lite::Context();
|
||||||
|
ctx->thread_num_ = 2;
|
||||||
|
strided_slice_param->op_parameter_.type_ = schema::PrimitiveType_StridedSlice;
|
||||||
|
kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeFloat32, schema::PrimitiveType_StridedSlice};
|
||||||
|
auto creator = lite::KernelRegistry::GetInstance()->GetCreator(desc);
|
||||||
|
ASSERT_NE(creator, nullptr);
|
||||||
|
kernel::LiteKernel *kernel =
|
||||||
|
creator(inputs_tensor, outputs_tensor, reinterpret_cast<OpParameter *>(strided_slice_param), ctx, desc, nullptr);
|
||||||
|
ASSERT_NE(kernel, nullptr);
|
||||||
|
kernel->Run();
|
||||||
|
delete ctx;
|
||||||
|
|
||||||
|
CompareOutputData(output_data, correct, 8, 0.000001);
|
||||||
|
input_tensor.SetData(nullptr);
|
||||||
|
output_tensor.SetData(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestStridedSliceFp32, StridedSlice7) {
|
||||||
|
// prepare stage
|
||||||
|
auto strided_slice_param = new StridedSliceParameter();
|
||||||
|
std::vector<int> in_shape{2, 3};
|
||||||
|
std::vector<int> begins{-1, 1};
|
||||||
|
std::vector<int> ends{2, 2};
|
||||||
|
std::vector<int> strides{1, 1};
|
||||||
|
int length = 2;
|
||||||
|
int in_shape_length = 2;
|
||||||
|
InitStridedSliceParam(strided_slice_param, in_shape, begins, ends, strides, length, in_shape_length);
|
||||||
|
|
||||||
|
std::vector<int> input_shape = {2, 3};
|
||||||
|
float input_data[6] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
|
||||||
|
|
||||||
|
float correct[1] = {4.0};
|
||||||
|
float output_data[1];
|
||||||
|
std::vector<int> output_shape = {1, 1};
|
||||||
|
|
||||||
|
lite::Tensor input_tensor;
|
||||||
|
input_tensor.SetData(input_data);
|
||||||
|
input_tensor.set_shape(input_shape);
|
||||||
|
std::vector<lite::Tensor *> inputs_tensor(1);
|
||||||
|
inputs_tensor[0] = &input_tensor;
|
||||||
|
|
||||||
|
std::vector<lite::Tensor *> outputs_tensor;
|
||||||
|
lite::Tensor output_tensor;
|
||||||
|
outputs_tensor.push_back(&output_tensor);
|
||||||
|
output_tensor.SetData(output_data);
|
||||||
|
output_tensor.set_data_type(input_tensor.data_type());
|
||||||
|
output_tensor.set_shape(output_shape);
|
||||||
|
|
||||||
|
lite::Context *ctx = new lite::Context();
|
||||||
|
ctx->thread_num_ = 2;
|
||||||
|
strided_slice_param->op_parameter_.type_ = schema::PrimitiveType_StridedSlice;
|
||||||
|
kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeFloat32, schema::PrimitiveType_StridedSlice};
|
||||||
|
auto creator = lite::KernelRegistry::GetInstance()->GetCreator(desc);
|
||||||
|
ASSERT_NE(creator, nullptr);
|
||||||
|
kernel::LiteKernel *kernel =
|
||||||
|
creator(inputs_tensor, outputs_tensor, reinterpret_cast<OpParameter *>(strided_slice_param), ctx, desc, nullptr);
|
||||||
|
ASSERT_NE(kernel, nullptr);
|
||||||
|
kernel->Run();
|
||||||
|
delete ctx;
|
||||||
|
|
||||||
|
CompareOutputData(output_data, correct, 1, 0.000001);
|
||||||
|
input_tensor.SetData(nullptr);
|
||||||
|
output_tensor.SetData(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestStridedSliceFp32, StridedSlice8) {
|
||||||
|
// prepare stage
|
||||||
|
auto strided_slice_param = new StridedSliceParameter();
|
||||||
|
std::vector<int> in_shape{5, 5, 5};
|
||||||
|
std::vector<int> begins{-2, -3};
|
||||||
|
std::vector<int> ends{-1, -2};
|
||||||
|
std::vector<int> strides{1, 1};
|
||||||
|
int length = 2;
|
||||||
|
int in_shape_length = 3;
|
||||||
|
InitStridedSliceParam(strided_slice_param, in_shape, begins, ends, strides, length, in_shape_length);
|
||||||
|
|
||||||
|
std::vector<int> input_shape = {5, 5, 5};
|
||||||
|
float input_data[125] = {
|
||||||
|
0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
|
||||||
|
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
|
||||||
|
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
|
||||||
|
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
|
||||||
|
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
|
||||||
|
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0,
|
||||||
|
96.0, 97.0, 98.0, 99.0, 100.0, 101.0, 102.0, 103.0, 104.0, 105.0, 106.0, 107.0, 108.0, 109.0, 110.0, 111.0,
|
||||||
|
112.0, 113.0, 114.0, 115.0, 116.0, 117.0, 118.0, 119.0, 120.0, 121.0, 122.0, 123.0, 124.0};
|
||||||
|
|
||||||
|
float correct[5] = {85.0, 86.0, 87.0, 88.0, 89.0};
|
||||||
|
float output_data[5];
|
||||||
|
std::vector<int> output_shape = {1, 1, 5};
|
||||||
|
|
||||||
|
lite::Tensor input_tensor;
|
||||||
|
input_tensor.SetData(input_data);
|
||||||
|
input_tensor.set_shape(input_shape);
|
||||||
|
std::vector<lite::Tensor *> inputs_tensor(1);
|
||||||
|
inputs_tensor[0] = &input_tensor;
|
||||||
|
|
||||||
|
std::vector<lite::Tensor *> outputs_tensor;
|
||||||
|
lite::Tensor output_tensor;
|
||||||
|
outputs_tensor.push_back(&output_tensor);
|
||||||
|
output_tensor.SetData(output_data);
|
||||||
|
output_tensor.set_data_type(input_tensor.data_type());
|
||||||
|
output_tensor.set_shape(output_shape);
|
||||||
|
|
||||||
|
lite::Context *ctx = new lite::Context();
|
||||||
|
ctx->thread_num_ = 2;
|
||||||
|
strided_slice_param->op_parameter_.type_ = schema::PrimitiveType_StridedSlice;
|
||||||
|
kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeFloat32, schema::PrimitiveType_StridedSlice};
|
||||||
|
auto creator = lite::KernelRegistry::GetInstance()->GetCreator(desc);
|
||||||
|
ASSERT_NE(creator, nullptr);
|
||||||
|
kernel::LiteKernel *kernel =
|
||||||
|
creator(inputs_tensor, outputs_tensor, reinterpret_cast<OpParameter *>(strided_slice_param), ctx, desc, nullptr);
|
||||||
|
ASSERT_NE(kernel, nullptr);
|
||||||
|
kernel->Run();
|
||||||
|
delete ctx;
|
||||||
|
|
||||||
|
CompareOutputData(output_data, correct, 5, 0.000001);
|
||||||
|
input_tensor.SetData(nullptr);
|
||||||
|
output_tensor.SetData(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mindspore
|
Loading…
Reference in New Issue