725 lines
36 KiB
C++
725 lines
36 KiB
C++
//
|
|
// StridedSliceTest.cpp
|
|
// MNNTests
|
|
//
|
|
// Created by MNN on 2020/1/20.
|
|
// Copyright © 2018, Alibaba Group Holding Limited
|
|
//
|
|
|
|
#include <MNN/expr/Expr.hpp>
|
|
#include <MNN/expr/ExprCreator.hpp>
|
|
#include "MNNTestSuite.h"
|
|
#include "TestUtils.h"
|
|
|
|
using namespace MNN::Express;
|
|
class StridedSliceTest : public MNNTestCase {
|
|
public:
|
|
virtual ~StridedSliceTest() = default;
|
|
virtual bool run(int precision) {
|
|
auto input = _Input({1, 3, 2, 3}, NCHW);
|
|
auto begin = _Input({4}, NCHW);
|
|
auto end = _Input({4}, NCHW);
|
|
auto strided = _Input({4}, NCHW);
|
|
const float input_data[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
memcpy(input->writeMap<float>(), input_data, 18 * sizeof(float));
|
|
const int begin_data[] = {0, 0, 0, 0};
|
|
memcpy(begin->writeMap<int>(), begin_data, 4 * sizeof(int));
|
|
const int end_data[] = {1, 2, 2, 3};
|
|
memcpy(end->writeMap<int>(), end_data, 4 * sizeof(int));
|
|
const int stride_data[] = {1, 1, 1, 1};
|
|
memcpy(strided->writeMap<int>(), stride_data, 4 * sizeof(int));
|
|
// 1. all mask = 0
|
|
auto output_1 = _StridedSlice(input, begin, end, strided, 0, 0, 0, 0, 0);
|
|
const std::vector<int> expectedShape_1 = {1, 2, 2, 3};
|
|
const std::vector<float> expectedOutput_1 = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};
|
|
if (!checkVector<int>(output_1->getInfo()->dim.data(), expectedShape_1.data(), expectedShape_1.size(), 0) ||
|
|
!checkVector<float>(output_1->readMap<float>(), expectedOutput_1.data(), expectedOutput_1.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice (all mask=0) test failed!\n");
|
|
return false;
|
|
}
|
|
// 2. ellipsisMask = 2
|
|
auto output_2 = _StridedSlice(input, begin, end, strided, 0, 0, 2, 0, 0);
|
|
const std::vector<int> expectedShape_2 = {1, 3, 2, 3};
|
|
const std::vector<float> expectedOutput_2 = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
if (!checkVector<int>(output_2->getInfo()->dim.data(), expectedShape_2.data(), expectedShape_2.size(), 0) ||
|
|
!checkVector<float>(output_2->readMap<float>(), expectedOutput_2.data(), expectedOutput_2.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice (ellipsisMask=2) test failed!\n");
|
|
return false;
|
|
}
|
|
// 3. newAxisMask = 2
|
|
auto output_3 = _StridedSlice(input, begin, end, strided, 0, 0, 0, 2, 0);
|
|
const std::vector<int> expectedShape_3 = {1, 1, 2, 2, 3};
|
|
const std::vector<float> expectedOutput_3 = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4};
|
|
if (!checkVector<int>(output_3->getInfo()->dim.data(), expectedShape_3.data(), expectedShape_3.size(), 0) ||
|
|
!checkVector<float>(output_3->readMap<float>(), expectedOutput_3.data(), expectedOutput_3.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice (newAxisMask=2) test failed!\n");
|
|
return false;
|
|
}
|
|
// 4. shrinkAxisMask = 2
|
|
auto output_4 = _StridedSlice(input, begin, end, strided, 0, 0, 0, 0, 2);
|
|
const std::vector<int> expectedShape_4 = {1, 2, 3};
|
|
const std::vector<float> expectedOutput_4 = {1, 1, 1, 2, 2, 2};
|
|
if (!checkVector<int>(output_4->getInfo()->dim.data(), expectedShape_4.data(), expectedShape_4.size(), 0) ||
|
|
!checkVector<float>(output_4->readMap<float>(), expectedOutput_4.data(), expectedOutput_4.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice (shrinkAxisMask=2) test failed!\n");
|
|
return false;
|
|
}
|
|
// 5. ellipsisMask = 2, shrinkAxisMask = 8(0b01000)
|
|
auto output_5 = _StridedSlice(input, begin, end, strided, 0, 0, 2, 0, 8);
|
|
const std::vector<int> expectedShape_5 = {1, 3, 2};
|
|
const std::vector<float> expectedOutput_5 = {1, 2, 3, 4, 5, 6};
|
|
if (!checkVector<int>(output_5->getInfo()->dim.data(), expectedShape_5.data(), expectedShape_5.size(), 0) ||
|
|
!checkVector<float>(output_5->readMap<float>(), expectedOutput_5.data(), expectedOutput_5.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice (ellipsisMask=2, shrinkAxisMask=8) test failed!\n");
|
|
return false;
|
|
}
|
|
// 6. beginMask = 9, endMask = 15
|
|
const int begin_data6[] = {0, 1, 1, 0};
|
|
memcpy(begin->writeMap<int>(), begin_data6, 4 * sizeof(int));
|
|
const int end_data6[] = {0, 0, 0, 0};
|
|
memcpy(end->writeMap<int>(), end_data6, 4 * sizeof(int));
|
|
const int stride_data6[] = {1, 1, 1, 1};
|
|
memcpy(strided->writeMap<int>(), stride_data6, 4 * sizeof(int));
|
|
auto output_6 = _StridedSlice(input, begin, end, strided, 9, 15, 0, 0, 0);
|
|
const std::vector<int> expectedShape_6 = {1, 2, 1, 3};
|
|
const std::vector<float> expectedOutput_6 = {4, 4, 4, 6, 6, 6};
|
|
if (!checkVector<int>(output_6->getInfo()->dim.data(), expectedShape_6.data(), expectedShape_6.size(), 0) ||
|
|
!checkVector<float>(output_6->readMap<float>(), expectedOutput_6.data(), expectedOutput_6.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice (beginMask=9, endMask=15) test failed!\n");
|
|
return false;
|
|
}
|
|
// 7. dim = 2, stride = -1
|
|
const int begin_data7[] = {0, 0, 0, 0};
|
|
memcpy(begin->writeMap<int>(), begin_data7, 4 * sizeof(int));
|
|
const int end_data7[] = {1, 3, 2, 3};
|
|
memcpy(end->writeMap<int>(), end_data7, 4 * sizeof(int));
|
|
const int stride_data7[] = {1, 1, -1, 1};
|
|
memcpy(strided->writeMap<int>(), stride_data7, 4 * sizeof(int));
|
|
auto output_7 = _StridedSlice(input, begin, end, strided, 4, 4, 0, 0, 0);
|
|
const std::vector<int> expectedShape_7 = {1, 3, 2, 3};
|
|
const std::vector<float> expectedOutput_7 = {2, 2, 2, 1, 1, 1, 4, 4, 4, 3, 3, 3, 6, 6, 6, 5, 5, 5};
|
|
if (!checkVector<int>(output_7->getInfo()->dim.data(), expectedShape_7.data(), expectedShape_7.size(), 0) ||
|
|
!checkVector<float>(output_7->readMap<float>(), expectedOutput_7.data(), expectedOutput_7.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice dim=2, stride=-1 test failed!\n");
|
|
return false;
|
|
}
|
|
// 8. dim = 3, stride = -1
|
|
auto input8 = _Input({1, 2, 2, 4}, NCHW);
|
|
const float input_data8[] = { 0, 1, 2, 3, 4, 5, 6, 7,
|
|
8, 9, 10, 11, 12, 13, 14, 15 };
|
|
memcpy(input8->writeMap<float>(), input_data8, 16 * sizeof(float));
|
|
const int begin_data8[] = {0, 0, 0, 0};
|
|
memcpy(begin->writeMap<int>(), begin_data8, 4 * sizeof(int));
|
|
const int end_data8[] = {0, 0, 0, 0};
|
|
memcpy(end->writeMap<int>(), end_data8, 4 * sizeof(int));
|
|
const int stride_data8[] = {1, 1, 1, -1};
|
|
memcpy(strided->writeMap<int>(), stride_data8, 4 * sizeof(int));
|
|
auto output_8 = _StridedSlice(input8, begin, end, strided, 15, 15, 0, 0, 0);
|
|
const std::vector<int> expectedShape_8 = {1,2,2,4};
|
|
const std::vector<float> expectedOutput_8 = {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12};
|
|
auto info = output_8->getInfo();
|
|
if (!checkVector<int>(output_8->getInfo()->dim.data(), expectedShape_8.data(), expectedShape_8.size(), 0) ||
|
|
!checkVector<float>(output_8->readMap<float>(), expectedOutput_8.data(), expectedOutput_8.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice dim = 3, stride=-1 test failed!\n");
|
|
return false;
|
|
}
|
|
// 9. dim = 0
|
|
input = _Input({2, 1, 3, 3}, NCHW);
|
|
begin = _Input({1}, NCHW);
|
|
end = _Input({1}, NCHW);
|
|
strided = _Input({1}, NCHW);
|
|
const float input_data_[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
memcpy(input->writeMap<float>(), input_data_, 18 * sizeof(float));
|
|
const int begin_data10[] = {1};
|
|
memcpy(begin->writeMap<int>(), begin_data10, 1 * sizeof(int));
|
|
const int end_data10[] = {2};
|
|
memcpy(end->writeMap<int>(), end_data10, 1 * sizeof(int));
|
|
const int stride_data10[] = {1};
|
|
memcpy(strided->writeMap<int>(), stride_data10, 1 * sizeof(int));
|
|
auto output_10 = _StridedSlice(input, begin, end, strided, 0, 0, 0, 0, 1);
|
|
const std::vector<int> expectedShape_10 = {1, 3, 3};
|
|
const std::vector<float> expectedOutput_10 = {4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
if (!checkVector<int>(output_10->getInfo()->dim.data(), expectedShape_10.data(), expectedShape_10.size(), 0) ||
|
|
!checkVector<float>(output_10->readMap<float>(), expectedOutput_10.data(), expectedOutput_10.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice dim=0, stride=1 test failed!\n");
|
|
return false;
|
|
}
|
|
// 11. dim = 0, zero shape
|
|
input = _Input({0, 1}, NCHW);
|
|
begin = _Input({2}, NCHW);
|
|
end = _Input({2}, NCHW);
|
|
strided = _Input({2}, NCHW);
|
|
input->writeMap<int>();
|
|
const int begin_data11[] = {0, 0};
|
|
memcpy(begin->writeMap<int>(), begin_data11, 2 * sizeof(int));
|
|
const int end_data11[] = {1, 1};
|
|
memcpy(end->writeMap<int>(), end_data11, 2 * sizeof(int));
|
|
const int stride_data11[] = {1, 1};
|
|
memcpy(strided->writeMap<int>(), stride_data11, 2 * sizeof(int));
|
|
auto output_11 = _StridedSlice(input, begin, end, strided, 0, 0, 0, 0, 3);
|
|
const std::vector<int> expectedShape_11 = {};
|
|
const std::vector<float> expectedOutput_11 = {0.0f};
|
|
if ((!output_11->getInfo()->dim.empty()) ||
|
|
!checkVector<float>(output_11->readMap<float>(), expectedOutput_11.data(), expectedOutput_11.size(), 0.01)) {
|
|
MNN_ERROR("stridedslice dim=0, stride=1 test failed!\n");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
MNNTestSuiteRegister(StridedSliceTest, "op/stridedslice");
|
|
|
|
class SplitC4Test : public MNNTestCase {
|
|
public:
|
|
virtual ~SplitC4Test() = default;
|
|
virtual bool run(int precision) {
|
|
int N = 1; int C = 32; int W = 3; int H = 4;
|
|
auto x = _Input({N, C, H, W}, NCHW, halide_type_of<int>());
|
|
auto xPtr = x->writeMap<int>();
|
|
for (int x=0; x<N; ++x) {
|
|
for (int y=0; y<C; ++y) {
|
|
for (int z=0; z<H; ++z) {
|
|
for (int w=0; w<W; ++w) {
|
|
auto pos = x * C * H * W + y * H * W + z * W + w;
|
|
xPtr[pos] = pos;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
x = _Convert(x, NC4HW4);
|
|
x.fix(VARP::CONSTANT);
|
|
|
|
auto y = _Split(x, {2}, 1)[1];
|
|
auto yInfo = y->getInfo();
|
|
if (yInfo->dim[0] != N || yInfo->dim[1] != C/2 || yInfo->dim[2] != H || yInfo->dim[3] != W) {
|
|
FUNC_PRINT(1);
|
|
return false;
|
|
}
|
|
y = _Add(y, _Scalar<int>(0));
|
|
y = _Convert(y, NCHW);
|
|
{
|
|
auto yPtr = y->readMap<int>();
|
|
for (int x=0; x<N; ++x) {
|
|
for (int y=0; y<C/2; ++y) {
|
|
for (int z=0; z<H; ++z) {
|
|
for (int w=0; w<W; ++w) {
|
|
auto pos = x * C/2 * H * W + y * H * W + z * W + w;
|
|
auto value = x * C * H * W + (y+C/2) * H * W + z * W + w;
|
|
if (yPtr[pos] != value) {
|
|
FUNC_PRINT(1);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (1 == N) {
|
|
auto y2 = _RasterRaw({x}, {C/2*H*W, 0, 0, 1, 0, 0, 0, 1, 1, 1, C/2*H*W}, {N, C/2, H, W}, halide_type_of<int>(), NC4HW4);
|
|
y2 = _Add(y2, _Scalar<int>(0));
|
|
y2 = _Convert(y2, NCHW);
|
|
auto yPtr = y2->readMap<int>();
|
|
for (int x=0; x<N; ++x) {
|
|
for (int y=0; y<C/2; ++y) {
|
|
for (int z=0; z<H; ++z) {
|
|
for (int w=0; w<W; ++w) {
|
|
auto pos = x * C/2 * H * W + y * H * W + z * W + w;
|
|
auto value = x * C * H * W + (y+C/2) * H * W + z * W + w;
|
|
if (yPtr[pos] != value) {
|
|
FUNC_PRINT(1);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
MNNTestSuiteRegister(SplitC4Test, "op/splitc4");
|
|
|
|
class StrideSliceWriteTest: public MNNTestCase {
|
|
virtual bool run(int precision) {
|
|
|
|
// Test Case: 1D Input
|
|
{
|
|
// 1. Input data
|
|
auto input = _Input({20}, NCHW);
|
|
auto begin = _Input({1}, NCHW);
|
|
auto end = _Input({1}, NCHW);
|
|
auto strided = _Input({1}, NCHW);
|
|
auto write = _Input({5}, NCHW);
|
|
auto size = 20;
|
|
const float inputData[] = {
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
|
|
};
|
|
memcpy(input->writeMap<float>(), inputData, size * sizeof(float));
|
|
|
|
// 2. (Slicing Parameters)
|
|
// Slice on Dim 0: from index 2 to 15 with stride 3
|
|
// This will select indices: 2, 5, 8, 11, 14
|
|
const int beginData[] = {2};
|
|
memcpy(begin->writeMap<int>(), beginData, 1 * sizeof(int));
|
|
const int endData[] = {15};
|
|
memcpy(end->writeMap<int>(), endData, 1 * sizeof(int));
|
|
const int strideData[] = {3};
|
|
memcpy(strided->writeMap<int>(), strideData, 1 * sizeof(int));
|
|
|
|
// 3. Write Tensor
|
|
// write element size = 5 ( (15-2)/3 rounded up )
|
|
const float writeData[] = {99, 99, 99, 99, 99};
|
|
memcpy(write->writeMap<float>(), writeData, 5 * sizeof(float));
|
|
|
|
auto output = _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
|
|
// 4. Expected Result
|
|
const std::vector<int> expectedShape = {20};
|
|
const std::vector<float> expectedOutput = {
|
|
0, 1, 99, 3, 4, 99, 6, 7, 99, 9, 10, 99, 12, 13, 99, 15, 16, 17, 18, 19
|
|
};
|
|
// Indices 2, 5, 8, 11, 14 have been replaced by 99.
|
|
|
|
// 5. validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite shape test0 error\n");
|
|
return false;
|
|
}
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test0 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Test Case: 2D Input
|
|
{
|
|
// 1. input data
|
|
auto input = _Input({6, 8}, NCHW);
|
|
auto begin = _Input({2}, NCHW);
|
|
auto end = _Input({2}, NCHW);
|
|
auto strided = _Input({2}, NCHW);
|
|
auto write = _Input({12}, NCHW);
|
|
auto size = 48;
|
|
const float inputData[] = {
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
10, 10, 10, 10, 10, 10, 10, 10,
|
|
20, 20, 20, 20, 20, 20, 20, 20,
|
|
30, 30, 30, 30, 30, 30, 30, 30,
|
|
40, 40, 40, 40, 40, 40, 40, 40,
|
|
50, 50, 50, 50, 50, 50, 50, 50
|
|
};
|
|
memcpy(input->writeMap<float>(), inputData, size * sizeof(float));
|
|
|
|
// 2. Slicing Parameters
|
|
// Slice on Dim 0 (rows): from index 1 to 6 with stride 2 -> selects rows 1, 3, 5
|
|
// Slice on Dim 1 (cols): from index 0 to 8 with stride 2 -> selects cols 0, 2, 4, 6
|
|
const int beginData[] = {1, 0};
|
|
memcpy(begin->writeMap<int>(), beginData, 2 * sizeof(int));
|
|
const int endData[] = {6, 8};
|
|
memcpy(end->writeMap<int>(), endData, 2 * sizeof(int));
|
|
const int strideData[] = {2, 2};
|
|
memcpy(strided->writeMap<int>(), strideData, 2 * sizeof(int));
|
|
|
|
// 3. Write Tensor
|
|
// write element size = 3 (rows) * 4 (cols) = 12
|
|
const float writeData[] = {
|
|
77, 77, 77, 77,
|
|
77, 77, 77, 77,
|
|
77, 77, 77, 77
|
|
};
|
|
memcpy(write->writeMap<float>(), writeData, 12 * sizeof(float));
|
|
|
|
auto output = _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
|
|
// 4. Expected Result
|
|
const std::vector<int> expectedShape = {6, 8};
|
|
const std::vector<float> expectedOutput = {
|
|
0, 0, 0, 0, 0, 0, 0, 0, // row 0: unchanged
|
|
77, 10, 77, 10, 77, 10, 77, 10, // row 1: selected cols replaced
|
|
20, 20, 20, 20, 20, 20, 20, 20, // row 2: unchanged
|
|
77, 30, 77, 30, 77, 30, 77, 30, // row 3: selected cols replaced
|
|
40, 40, 40, 40, 40, 40, 40, 40, // row 4: unchanged
|
|
77, 50, 77, 50, 77, 50, 77, 50 // row 5: selected cols replaced
|
|
};
|
|
|
|
// 5. validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite shape test0 error\n");
|
|
return false;
|
|
}
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test0 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Test Case: 3D Input
|
|
{
|
|
auto input = _Input({4, 5, 6}, NCHW);
|
|
auto begin = _Input({3}, NCHW);
|
|
auto end = _Input({3}, NCHW);
|
|
auto strided = _Input({3}, NCHW);
|
|
auto write = _Input({20}, NCHW);
|
|
auto size = 120;
|
|
|
|
// 1. Input data
|
|
const float inputData[] = {
|
|
// Plane 0
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
// Plane 1
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
// Plane 2
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
// Plane 3
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
|
|
};
|
|
memcpy(input->writeMap<float>(), inputData, size * sizeof(float));
|
|
|
|
// 2. Slicing Parameters
|
|
// Slice on Dim 0: from index 1 to 4 with stride 2 -> selects planes 1, 3
|
|
// Slice on Dim 1: from index 0 to 5 with stride 1 -> selects all 5 rows
|
|
// Slice on Dim 2: from index 2 to 6 with stride 3 -> selects columns 2, 5
|
|
const int beginData[] = {1, 0, 2};
|
|
memcpy(begin->writeMap<int>(), beginData, 3 * sizeof(int));
|
|
const int endData[] = {4, 5, 6};
|
|
memcpy(end->writeMap<int>(), endData, 3 * sizeof(int));
|
|
const int strideData[] = {2, 1, 3};
|
|
memcpy(strided->writeMap<int>(), strideData, 3 * sizeof(int));
|
|
|
|
// 3. Write Tensor
|
|
// 2 (dim0) * 5 (dim1) * 2 (dim2) = 20
|
|
const float writeData[] = {
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8
|
|
};
|
|
memcpy(write->writeMap<float>(), writeData, 20 * sizeof(float));
|
|
|
|
auto output = _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
|
|
// 4. Expected Result
|
|
const std::vector<int> expectedShape = {4, 5, 6};
|
|
const std::vector<float> expectedOutput = {
|
|
// Plane 0 - remain the same
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
// Plane 1 - write the new element
|
|
2, 2, 8, 2, 2, 8, 2, 2, 8, 2, 2, 8, 2, 2, 8, 2, 2, 8, 2, 2, 8, 2, 2, 8, 2, 2, 8, 2, 2, 8,
|
|
// Plane 2 - remain the same
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
// Plane 3 - write the new element
|
|
4, 4, 8, 4, 4, 8, 4, 4, 8, 4, 4, 8, 4, 4, 8, 4, 4, 8, 4, 4, 8, 4, 4, 8, 4, 4, 8, 4, 4, 8
|
|
};
|
|
|
|
// 5. validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite shape test0 error\n");
|
|
return false;
|
|
}
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test0 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
{
|
|
auto input = _Input({2, 3, 2, 12}, NCHW);
|
|
auto begin = _Input({4}, NCHW);
|
|
auto end = _Input({4}, NCHW);
|
|
auto strided = _Input({4}, NCHW);
|
|
auto write = _Input({20}, NCHW);
|
|
|
|
// initialize
|
|
auto size = input->getInfo()->size;
|
|
const float inputData[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
|
|
memcpy(input->writeMap<float>(), inputData, size * sizeof(float));
|
|
const int beginData[] = {0, 1, 0, 2};
|
|
memcpy(begin->writeMap<int>(), beginData, 4 * sizeof(int));
|
|
const int endData[] = {2, 3, 2, 12};
|
|
memcpy(end->writeMap<int>(), endData, 4 * sizeof(int));
|
|
const int strideData[] = {1, 1, 2, 2};
|
|
memcpy(strided->writeMap<int>(), strideData, 4 * sizeof(int));
|
|
const float writeData[] = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
|
|
memcpy(write->writeMap<float>(), writeData, 20 * sizeof(float));
|
|
auto output= _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
const std::vector<int> expectedShape = {2, 3, 2, 12};
|
|
const std::vector<float> expectedOutput = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
3, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
5, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5,
|
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
3, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
5, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5,
|
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
|
|
|
|
// validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite shape test0 error\n");
|
|
return false;
|
|
}
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test0 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
{
|
|
auto input = _Input({1, 3, 2, 12}, NCHW);
|
|
auto begin = _Input({4}, NCHW);
|
|
auto end = _Input({4}, NCHW);
|
|
auto strided = _Input({4}, NCHW);
|
|
auto write = _Input({12}, NCHW);
|
|
|
|
// initialize
|
|
auto size = input->getInfo()->size;
|
|
const float inputData[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
|
|
memcpy(input->writeMap<float>(), inputData, size * sizeof(float));
|
|
const int beginData[] = {0, 1, 0, 2};
|
|
memcpy(begin->writeMap<int>(), beginData, 4 * sizeof(int));
|
|
const int endData[] = {1, 3, 2, 12};
|
|
memcpy(end->writeMap<int>(), endData, 4 * sizeof(int));
|
|
const int strideData[] = {1, 1, 2, 2};
|
|
memcpy(strided->writeMap<int>(), strideData, 4 * sizeof(int));
|
|
const float writeData[] = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
|
|
memcpy(write->writeMap<float>(), writeData, 12 * sizeof(float));
|
|
auto output= _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
const std::vector<int> expectedShape = {1, 3, 2, 12};
|
|
const std::vector<float> expectedOutput = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
3, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
5, 5, 9, 5, 9, 5, 9, 5, 9, 5, 9, 5,
|
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
|
|
|
|
// validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite shape test1 error\n");
|
|
return false;
|
|
}
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test1 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
{
|
|
int originSize = 300;
|
|
int sliceSize = 250;
|
|
INTS originShape = {3, originSize, originSize};
|
|
INTS sliceShape = {3, sliceSize, sliceSize};
|
|
auto input = _Input(sliceShape, NCHW, halide_type_of<float>());
|
|
auto src = _Input(originShape, NCHW, halide_type_of<float>());
|
|
// initialize 0
|
|
memset(src->writeMap<float>(), 0, src->getInfo()->size * sizeof(float));
|
|
// initialize 1
|
|
for (int i = 0; i < input->getInfo()->size; ++i) {
|
|
input->writeMap<float>()[i] = 1.f;
|
|
}
|
|
|
|
// slice write
|
|
std::vector<int> begin = {0,0,0};
|
|
std::vector<int> stride = {1,1,1};
|
|
VARP startVar = _Const(begin.data(), {(int)begin.size()}, Dimensionformat::NCHW, halide_type_of<int>());
|
|
VARP endVar = _Const(sliceShape.data(), {(int)sliceShape.size()}, Dimensionformat::NCHW, halide_type_of<int>());
|
|
VARP strideVar = _Const(stride.data(), {(int)stride.size()}, Dimensionformat::NCHW, halide_type_of<int>());
|
|
auto dst = _StridedSliceWrite(src, startVar, endVar, strideVar, input, 0, 0, 0, 0, 0);
|
|
|
|
// validate
|
|
if (_ReduceSum(input)->readMap<float>()[0] != _ReduceSum(dst)->readMap<float>()[0]) {
|
|
MNN_PRINT("StrideSliceWrite test2 Error\n");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto input = _Input({1, 3, 2, 3}, NCHW);
|
|
auto begin = _Input({4}, NCHW);
|
|
auto end = _Input({4}, NCHW);
|
|
auto strided = _Input({4}, NCHW);
|
|
auto write = _Input({3}, NCHW);
|
|
|
|
// initialize
|
|
const float inputData[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
memcpy(input->writeMap<float>(), inputData, 18 * sizeof(float));
|
|
const int beginData[] = {0, 1, 0, 0};
|
|
memcpy(begin->writeMap<int>(), beginData, 4 * sizeof(int));
|
|
const int endData[] = {1, 3, 2, 3};
|
|
memcpy(end->writeMap<int>(), endData, 4 * sizeof(int));
|
|
const int strideData[] = {1, 1, 2, 2};
|
|
memcpy(strided->writeMap<int>(), strideData, 4 * sizeof(int));
|
|
const float writeData[] = {9, 9, 9};
|
|
memcpy(write->writeMap<float>(), writeData, 3 * sizeof(float));
|
|
auto output= _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
const std::vector<int> expectedShape = {1, 3, 2, 3};
|
|
const std::vector<float> expectedOutput = {1, 1, 1, 2, 2, 2, 9, 3, 9, 4, 4, 4, 9, 5, 9, 6, 6, 6};
|
|
|
|
// validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite test3 shape error\n");
|
|
return false;
|
|
}
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test3 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto input = _Input({1, 3, 2, 3}, NCHW);
|
|
auto begin = _Input({4}, NCHW);
|
|
auto end = _Input({4}, NCHW);
|
|
auto strided = _Input({4}, NCHW);
|
|
auto write = _Input({3}, NCHW);
|
|
|
|
// initialize
|
|
const float inputData[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
memcpy(input->writeMap<float>(), inputData, 18 * sizeof(float));
|
|
const int beginData[] = {0, 1, 0, 0};
|
|
memcpy(begin->writeMap<int>(), beginData, 4 * sizeof(int));
|
|
const int endData[] = {1, 3, 2, 3};
|
|
memcpy(end->writeMap<int>(), endData, 4 * sizeof(int));
|
|
const int strideData[] = {1, 1, 2, 1};
|
|
memcpy(strided->writeMap<int>(), strideData, 4 * sizeof(int));
|
|
const float writeData[] = {9, 9, 9};
|
|
memcpy(write->writeMap<float>(), writeData, 3 * sizeof(float));
|
|
auto output= _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
const std::vector<int> expectedShape = {1, 3, 2, 3};
|
|
const std::vector<float> expectedOutput = {1, 1, 1, 2, 2, 2, 9, 9, 9, 4, 4, 4, 9, 9, 9, 6, 6, 6};
|
|
|
|
// validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite test4 shape error\n");
|
|
return false;
|
|
}
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test4 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto input = _Input({1, 3, 2, 3}, NCHW);
|
|
auto begin = _Input({4}, NCHW);
|
|
auto end = _Input({4}, NCHW);
|
|
auto strided = _Input({4}, NCHW);
|
|
auto write = _Input({3}, NCHW);
|
|
|
|
// initialize
|
|
const float inputData[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
memcpy(input->writeMap<float>(), inputData, 18 * sizeof(float));
|
|
const int beginData[] = {0, 1, 0, 0};
|
|
memcpy(begin->writeMap<int>(), beginData, 4 * sizeof(int));
|
|
const int endData[] = {1, 3, 2, 3};
|
|
memcpy(end->writeMap<int>(), endData, 4 * sizeof(int));
|
|
const int strideData[] = {1, 1, 1, 1};
|
|
memcpy(strided->writeMap<int>(), strideData, 4 * sizeof(int));
|
|
const float writeData[] = {9, 9, 9};
|
|
memcpy(write->writeMap<float>(), writeData, 3 * sizeof(float));
|
|
auto output= _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
const std::vector<int> expectedShape = {1, 3, 2, 3};
|
|
const std::vector<float> expectedOutput = {1, 1, 1, 2, 2, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
|
|
|
|
// validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite test5 shape error\n");
|
|
return false;
|
|
}
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test5 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
{
|
|
auto input = _Input({1, 3, 2, 3}, NCHW);
|
|
auto begin = _Input({4}, NCHW);
|
|
auto end = _Input({4}, NCHW);
|
|
auto strided = _Input({4}, NCHW);
|
|
auto write = _Input({3}, NCHW);
|
|
|
|
// initialize
|
|
const float inputData[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
memcpy(input->writeMap<float>(), inputData, 18 * sizeof(float));
|
|
const int beginData[] = {0, 1, 0, 0};
|
|
memcpy(begin->writeMap<int>(), beginData, 4 * sizeof(int));
|
|
const int endData[] = {1, 2, 2, 3};
|
|
memcpy(end->writeMap<int>(), endData, 4 * sizeof(int));
|
|
const int strideData[] = {1, 1, 1, 1};
|
|
memcpy(strided->writeMap<int>(), strideData, 4 * sizeof(int));
|
|
const float writeData[] = {9, 9, 9};
|
|
memcpy(write->writeMap<float>(), writeData, 3 * sizeof(float));
|
|
auto output= _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
const std::vector<int> expectedShape = {1, 3, 2, 3};
|
|
const std::vector<float> expectedOutput = {1, 1, 1, 2, 2, 2, 9, 9, 9, 9, 9, 9, 5, 5, 5, 6, 6, 6};
|
|
|
|
// validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite test6 shape error\n");
|
|
return false;
|
|
}
|
|
auto ptr = output->readMap<float>();
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test6 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
auto input = _Input({1, 3, 2, 3}, NCHW);
|
|
auto begin = _Input({4}, NCHW);
|
|
auto end = _Input({4}, NCHW);
|
|
auto strided = _Input({4}, NCHW);
|
|
auto write = _Input({3}, NCHW);
|
|
|
|
// initialize
|
|
const float inputData[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
|
|
memcpy(input->writeMap<float>(), inputData, 18 * sizeof(float));
|
|
const int beginData[] = {0, 0, 0, 0};
|
|
memcpy(begin->writeMap<int>(), beginData, 4 * sizeof(int));
|
|
const int endData[] = {1, 2, 2, 3};
|
|
memcpy(end->writeMap<int>(), endData, 4 * sizeof(int));
|
|
const int strideData[] = {1, 1, 1, 1};
|
|
memcpy(strided->writeMap<int>(), strideData, 4 * sizeof(int));
|
|
const float writeData[] = {9, 9, 9};
|
|
memcpy(write->writeMap<float>(), writeData, 3 * sizeof(float));
|
|
auto output= _StridedSliceWrite(input, begin, end, strided, write, 0, 0, 0, 0, 0);
|
|
const std::vector<int> expectedShape = {1, 3, 2, 3};
|
|
const std::vector<float> expectedOutput = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5, 5, 6, 6, 6};
|
|
|
|
// validate
|
|
if (!checkVector<int>(output->getInfo()->dim.data(), expectedShape.data(), expectedShape.size(), 0)) {
|
|
MNN_PRINT("StrideSliceWrite test7 shape error\n");
|
|
return false;
|
|
}
|
|
auto ptr = output->readMap<float>();
|
|
if (!checkVector<float>(output->readMap<float>(), expectedOutput.data(), expectedOutput.size(), 0.01)) {
|
|
MNN_PRINT("StrideSliceWrite test7 result error\n");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
{
|
|
{
|
|
// For strideslicewrite shape compute
|
|
auto tinput = _Input({1, 3, 2, 3}, NCHW);
|
|
auto tbegin = _Input({4}, NCHW);
|
|
auto tend = _Input({4}, NCHW);
|
|
auto tstrided = _Input({4}, NCHW);
|
|
auto twrite = _Input({3}, NCHW);
|
|
auto toutput= _StridedSliceWrite(tinput, tbegin, tend, tstrided, twrite, 0, 0, 0, 0, 0);
|
|
auto info = toutput->getInfo();
|
|
if (nullptr == info) {
|
|
FUNC_PRINT(1);
|
|
return false;
|
|
}
|
|
if (info->dim != tinput->getInfo()->dim) {
|
|
MNN_PRINT("StrideSliceWrite test8 shape error\n");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
MNNTestSuiteRegister(StrideSliceWriteTest, "op/strideSliceWrite");
|