| 46 | } // namespace |
| 47 | |
| 48 | TEST(TestGoptGtrans, ExtractOprLeaves) { |
| 49 | HostTensorGenerator<> gen; |
| 50 | auto graph = ComputingGraph::make(); |
| 51 | graph->options().graph_opt_level = 0; |
| 52 | auto v = [&](int idx) { |
| 53 | auto hv = gen({1}); |
| 54 | return opr::Host2DeviceCopy::make(*graph, hv).rename(ssprintf("v%d", idx)); |
| 55 | }; |
| 56 | auto v0 = v(0), v1 = v(1), v2 = v(2), v3 = v(3), v4 = v(4), v5 = v(5), v6 = v(6); |
| 57 | |
| 58 | using Mode = opr::Elemwise::Mode; |
| 59 | auto vt = opr::Elemwise::make( |
| 60 | {(v0 + v1) - (v2 - v3), |
| 61 | opr::Elemwise::make({v0, v5, v6}, Mode::FUSE_MUL_ADD3), v4 / v3 * v5}, |
| 62 | Mode::COND_LEQ_MOV); |
| 63 | |
| 64 | std::unordered_set<Mode, enumhash> allowed_modes; |
| 65 | for (size_t i = 0; i < megdnn::param::Elemwise::MODE_NR_MEMBER; ++i) { |
| 66 | allowed_modes.insert(static_cast<Mode>(i)); |
| 67 | } |
| 68 | auto pred = [&](cg::OperatorNodeBase* opr) -> bool { |
| 69 | auto elem = gopt::try_cast_as_op<opr::Elemwise>(opr); |
| 70 | if (elem) |
| 71 | return allowed_modes.count(elem->param().mode); |
| 72 | return false; |
| 73 | }; |
| 74 | auto chain = gopt::extract_opr_leaves(vt.node(), pred); |
| 75 | |
| 76 | SymbolVarArray chain_expect = {v0, v1, v2, v3, v0, v5, v6, v5, v4, v3}; |
| 77 | ASSERT_EQ(chain_expect.size(), chain.size()); |
| 78 | for (size_t i = 0; i < chain.size(); ++i) { |
| 79 | ASSERT_EQ(chain_expect[i].node(), chain[i]); |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | TEST(TestGoptGtrans, BinaryTrans20Elem) { |
| 84 | run_binary_trans20_test( |