// // RasrerTest.cpp // MNNTests // // Created by MNN on 2021/12/23. // Copyright © 2018, Alibaba Group Holding Limited // #include #include #include "MNNTestSuite.h" #include "TestUtils.h" using namespace MNN::Express; class RasrerTest : public MNNTestCase { public: virtual ~RasrerTest() = default; bool _run(int precision, bool lazy) { auto input = _Input({2, 2}, NCHW); input->setName("input_tensor"); // set input data const float inpudata[] = {1, 2, 3, 4}; auto inputPtr = input->writeMap(); memcpy(inputPtr, inpudata, 4 * sizeof(float)); // transpose auto output = _Raster({input}, {0, 4, 1, 2, 0, 4, 2, 1, 1, 2, 2}, {2, 2}); const std::vector expectedOutput = {1, 3, 2, 4}; auto gotOutput = output->readMap(); if (!checkVector(gotOutput, expectedOutput.data(), 4, 0.01)) { MNN_ERROR("RasterTest transpose test failed!\n"); return false; } auto output0 = _Raster({input}, {2, 4, 2, 1, 0, 4, 2, 1, 1, 1, 2}, {2}); const std::vector expectedOutput0 = {3, 4}; auto gotOutput0 = output0->readMap(); if (!checkVector(gotOutput0, expectedOutput0.data(), 2, 0.01)) { MNN_ERROR("RasterTest slice test failed!\n"); return false; } return true; } virtual bool run(int precision) { ExecutorScope::Current()->lazyEval = false; auto res = _run(precision, false); if (!res) { FUNC_PRINT(1); return false; } ExecutorScope::Current()->lazyEval = true; ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_CONTENT); res = _run(precision, true); if (!res) { FUNC_PRINT(1); return false; } ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_FULL); res = _run(precision, true); return res; } }; MNNTestSuiteRegister(RasrerTest, "op/raster"); class BlitC4Test : public MNNTestCase { public: virtual ~BlitC4Test() = default; bool _run(int precision, bool lazy) { int w = 1; int h = 1; int n = 16; int c = 5; auto input0 = _Input({n, c, h, w}, NCHW); auto input1 = _Input({n, c, h, w}, NCHW); auto input2 = _Input({n, c, h, w}, NCHW); std::vector inputPtr = { input0->writeMap(), input1->writeMap(), input2->writeMap(), }; int p = (int)inputPtr.size(); std::vector outputData(n * c * h * w * p); float current = 0.0f; for (int pp=0; pp(), NC4HW4); output = _Convert(output, NCHW); output = _Reshape(output, {p, -1}); output = _Reverse(output, _Scalar(0)); auto outputPtr = output->readMap(); if (!checkVector(outputPtr, outputData.data(), n * c * h * w * p, 0.01f)) { MNN_ERROR("blitc4 test failed!\n"); return false; } return true; } virtual bool run(int precision) { ExecutorScope::Current()->lazyEval = false; auto res = _run(precision, false); if (!res) { FUNC_PRINT(1); return false; } ExecutorScope::Current()->lazyEval = true; ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_CONTENT); res = _run(precision, true); if (!res) { FUNC_PRINT(1); return false; } ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_FULL); res = _run(precision, true); return res; } }; MNNTestSuiteRegister(BlitC4Test, "op/blitc4"); class RasterC4ToNCHWRegionTest : public MNNTestCase { public: virtual ~RasterC4ToNCHWRegionTest() = default; bool _run(int precision, bool lazy) { const int n = 2; const int c = 4; auto input = _Input({n, c, 1, 1}, NCHW); auto inputPtr = input->writeMap(); for (int i = 0; i < n; ++i) { for (int j = 0; j < c; ++j) { inputPtr[i * c + j] = (float)(i * 10 + j); } } input = _Convert(input, NC4HW4); auto output = _RasterRaw({input}, { 0, c, 1, 1, 0, 1, n, 1, n, c, 1, }, {c, n, 1, 1}, halide_type_of(), NCHW); const std::vector expected = { 0.0f, 10.0f, 1.0f, 11.0f, 2.0f, 12.0f, 3.0f, 13.0f, }; auto outputPtr = output->readMap(); if (!checkVector(outputPtr, expected.data(), expected.size(), 0.01f)) { MNN_ERROR("raster c4 to nchw region test failed!\n"); return false; } return true; } virtual bool run(int precision) { ExecutorScope::Current()->lazyEval = false; auto res = _run(precision, false); if (!res) { FUNC_PRINT(1); return false; } ExecutorScope::Current()->lazyEval = true; ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_CONTENT); res = _run(precision, true); if (!res) { FUNC_PRINT(1); return false; } ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_FULL); res = _run(precision, true); return res; } }; MNNTestSuiteRegister(RasterC4ToNCHWRegionTest, "op/raster_c4_to_nchw_region"); class ReduceBlitTest : public MNNTestCase { public: virtual ~ReduceBlitTest() = default; bool _run(int precision, bool lazy) { int w = 1; int h = 1; int n = 16; int c = 5; auto input0 = _Input({n, c, h, w}, NCHW); auto inputPtr = input0->writeMap(); std::vector outputData(n * h * w); float current = 0.0f; auto dstptr = outputData.data(); for (int u=0; u(), NCHW); auto outputPtr = output->readMap(); if (!checkVector(outputPtr, outputData.data(), n * h * w, 0.01f)) { MNN_ERROR("reduce blit test failed!\n"); return false; } return true; } virtual bool run(int precision) { // TODO: Other Backend Support Reduce Blit auto type = getCurrentType(); if (type != MNN_FORWARD_CPU) { MNN_ERROR("Currently only cpu backend support reduce blit\n"); return true; } ExecutorScope::Current()->lazyEval = false; auto res = _run(precision, false); if (!res) { FUNC_PRINT(1); return false; } ExecutorScope::Current()->lazyEval = true; ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_CONTENT); res = _run(precision, true); if (!res) { FUNC_PRINT(1); return false; } ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_FULL); res = _run(precision, true); return res; } }; MNNTestSuiteRegister(ReduceBlitTest, "op/reduce_blit"); class ConcatSliceTest : public MNNTestCase { public: virtual ~ConcatSliceTest() = default; bool _run(int precision, bool lazy) { int n = 20; int c = 32; auto input0 = _Input({n, c}, NCHW, halide_type_of()); auto input1 = _Input({n, c}, NCHW, halide_type_of()); std::vector inputPtr = { input0->writeMap(), input1->writeMap(), }; for (int p=0; p output0(n*c); { // Split Compute auto o0 = _RasterRaw({input0, input1}, { 0, c, 1, 1, 0, c*2, 1, 1, n,c,1, 0, c, 1, 1, 32, c*2, 1, 1, n,c,1, }, {n, c*2}, halide_type_of(), NCHW); o0.fix(MNN::Express::VARP::CONSTANT); o0 = _RasterRaw({o0}, { 0, 0, n*c*2, 1, 0, 1, n*c, 1, 1,1,n*c }, {n, c}, halide_type_of(), NCHW); auto ptr = o0->readMap(); ::memcpy(output0.data(), ptr, n*c*sizeof(int)); } std::vector output1(n*c); { // Fuse Compute auto o0 = _RasterRaw({input0, input1}, { 0, c, 1, 1, 0, c*2, 1, 1, n,c,1, 0, c, 1, 1, 32, c*2, 1, 1, n,c,1, }, {n, c*2}, halide_type_of(), NCHW); o0 = _RasterRaw({o0}, { 0, 0, n*c*2, 1, 0, 1, n*c, 1, 1,1,n*c, }, {n, c}, halide_type_of(), NCHW); auto ptr = o0->readMap(); ::memcpy(output1.data(), ptr, n*c*sizeof(int)); } if (output0 != output1) { return false; } return true; } virtual bool run(int precision) { ExecutorScope::Current()->lazyEval = true; ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_FULL); auto res = _run(precision, true); return res; } }; MNNTestSuiteRegister(ConcatSliceTest, "op/concat_slice"); class TransposeC4Test : public MNNTestCase { public: virtual ~TransposeC4Test() = default; bool _run(int precision, bool lazy) { int n = 32; int c = 32; auto input = _Input({n, c, 1, 1}, NCHW, halide_type_of()); auto inputPtr = input->writeMap(); for (int i=0; i output0(n*c); { // Split Compute auto o0 = _RasterRaw({input}, { 0, 0, 1, 1, 0, 0, 1, 1, 1,1,n*c, }, {1, c, 1, n}, halide_type_of(), NC4HW4); o0.fix(MNN::Express::VARP::CONSTANT); o0 = _Convert(o0, NCHW); auto ptr = o0->readMap(); ::memcpy(output0.data(), ptr, n*c*sizeof(int)); } for (int i=0; ilazyEval = true; ExecutorScope::Current()->setLazyComputeMode(MNN::Express::Executor::LAZY_FULL); auto res = _run(precision, true); return res; } }; MNNTestSuiteRegister(TransposeC4Test, "op/transpose_c4");