| 6 | using namespace mgb; |
| 7 | |
| 8 | TEST(TestReformatEmitter, Basic) { |
| 9 | constexpr size_t N = 12, C = 64, H = 7, W = 7; |
| 10 | HostTensorGenerator<> gen; |
| 11 | using NamedTensorShape = megdnn::NamedTensorShape; |
| 12 | auto src = |
| 13 | NamedTensorShape::make_named_tensor_shape(NamedTensorShape::Format::NCHW32); |
| 14 | auto dest = |
| 15 | NamedTensorShape::make_named_tensor_shape(NamedTensorShape::Format::NCHW4); |
| 16 | auto&& tuple = gopt::ReformatEmitter(src, dest).emit(); |
| 17 | auto reformat = std::get<0>(tuple); |
| 18 | auto checker = std::get<1>(tuple); |
| 19 | |
| 20 | auto graph = ComputingGraph::make(); |
| 21 | graph->options().graph_opt_level = 0; |
| 22 | |
| 23 | auto nchw32_to_nchw4 = [](VarNode* in) { |
| 24 | auto x = SymbolVar(in); |
| 25 | auto xshp = opr::GetVarShape::make(x); |
| 26 | auto cv = [&x](int v) { return x.make_scalar(v); }; |
| 27 | auto sub = [&xshp, &cv](int idx) { |
| 28 | return opr::IndexAt::make(xshp, {{0, cv(idx)}}); |
| 29 | }; |
| 30 | auto tshp0 = opr::Concat::make( |
| 31 | {sub(0), sub(1), sub(2), sub(3), cv(8), sub(4) / 8}, 0), |
| 32 | tshp1 = opr::Concat::make( |
| 33 | {sub(0), sub(1) * 8, sub(2), sub(3), sub(4) / 8}, 0); |
| 34 | auto y0 = opr::Reshape::make(x, tshp0); |
| 35 | auto y1 = opr::Dimshuffle::make(y0, {0, 1, 4, 2, 3, 5}); |
| 36 | auto y2 = opr::Reshape::make(y1, tshp1); |
| 37 | return y2.node(); |
| 38 | }; |
| 39 | |
| 40 | auto mkvar = [&](const char* name, const TensorShape& shp) { |
| 41 | return opr::Host2DeviceCopy::make(*graph, gen(shp)).rename(name); |
| 42 | }; |
| 43 | auto x = mkvar("x", {N, C / 32, H, W, 32}); |
| 44 | EXPECT_TRUE(checker({x.node()})); |
| 45 | auto x_ = mkvar("x", {N, H, W, C}); |
| 46 | EXPECT_FALSE(checker({x_.node()})); |
| 47 | auto y1 = SymbolVar(reformat({x.node()})); |
| 48 | size_t nr_shapeof = 0; |
| 49 | size_t nr_reshape = 0; |
| 50 | cg::DepOprIter{[&nr_shapeof, &nr_reshape](cg::OperatorNodeBase* o) { |
| 51 | if (o->same_type<opr::GetVarShape>()) |
| 52 | nr_shapeof++; |
| 53 | if (o->same_type<opr::Reshape>()) |
| 54 | nr_reshape++; |
| 55 | }}.add(y1.node()->owner_opr()); |
| 56 | ASSERT_EQ(nr_shapeof, 1); |
| 57 | ASSERT_EQ(nr_reshape, 2); |
| 58 | auto y2 = SymbolVar(nchw32_to_nchw4(x.node())); |
| 59 | HostTensorND t1, t2; |
| 60 | auto func1 = graph->compile({make_callback_copy(y1, t1)}); |
| 61 | func1->execute(); |
| 62 | auto func2 = graph->compile({make_callback_copy(y2, t2)}); |
| 63 | func2->execute(); |
| 64 | MGB_ASSERT_TENSOR_EQ(t1, t2); |
| 65 | } |
nothing calls this directly
no test coverage detected