| 20 | using ResultChecker = thin_function<void()>; |
| 21 | |
| 22 | void run_test(CompNode cn, const PluginMaker& plugin_maker) { |
| 23 | // use a predefiend seed because we have hard-coded the expected outputs |
| 24 | HostTensorGenerator<> gen{0.f, 1.f, /*seed*/ 23}; |
| 25 | std::shared_ptr<HostTensorND> host_x; |
| 26 | |
| 27 | auto make_expect = [&host_x]() { |
| 28 | HostTensorND ret{host_x->comp_node(), host_x->dtype()}; |
| 29 | auto x = host_x->ptr<float>(), p = ret.resize(host_x->shape()).ptr<float>(); |
| 30 | auto shp1 = host_x->shape(1); |
| 31 | for (size_t i = 0, it = host_x->shape().total_nr_elems(); i < it; ++i) { |
| 32 | p[i] = (x[i] >= 0.f ? x[i] : 0.f) * (x[i % shp1] + 2.f); |
| 33 | } |
| 34 | return ret; |
| 35 | }; |
| 36 | for (size_t record : {0, 1, 2}) { |
| 37 | host_x = gen({2, 3}, cn); |
| 38 | auto graph = ComputingGraph::make(); |
| 39 | graph->options().var_sanity_check_first_run = false; |
| 40 | graph->options().comp_node_seq_record_level = record; |
| 41 | graph->options().graph_opt_level = 0; |
| 42 | auto plug = plugin_maker(graph.get(), record); |
| 43 | |
| 44 | // make a non-contiguous value, also introduce some shape dependencies |
| 45 | auto sub_brd = [](SymbolVar x) { |
| 46 | using S = opr::Subtensor; |
| 47 | auto zero = x.make_scalar(0), one = x.make_scalar(1), xshp = x.symshape(); |
| 48 | return S::make(x, {S::AxisIndexer::make_interval(0, zero, one, None)}) |
| 49 | .broadcast(xshp); |
| 50 | }; |
| 51 | |
| 52 | // write in primitive oprs to ensure stable opr ordering across |
| 53 | // compilers |
| 54 | auto x = opr::Host2DeviceCopy::make_no_fwd(*graph, host_x), |
| 55 | two = x.make_scalar_dt(2), sub = sub_brd(x) + two, xrelu = opr::relu(x), |
| 56 | y = xrelu * sub; |
| 57 | |
| 58 | // set stable names so the test can be used when opr naming is disabled |
| 59 | auto cb_rename = [](cg::OperatorNodeBase* opr) { |
| 60 | opr->name(ssprintf("opr%zu", opr->id())); |
| 61 | for (auto i : opr->output()) { |
| 62 | i->name(ssprintf("var%zu", i->id())); |
| 63 | } |
| 64 | }; |
| 65 | cg::DepOprIter{cb_rename}.add(y); |
| 66 | |
| 67 | HostTensorND host_y; |
| 68 | auto func = graph->compile({make_callback_copy(y, host_y)}); |
| 69 | if (record == 2) { |
| 70 | ComputingGraph::assert_destroy(graph); |
| 71 | } |
| 72 | func->execute(); |
| 73 | plug->flush_lazy(); |
| 74 | MGB_ASSERT_TENSOR_EQ(make_expect(), host_y); |
| 75 | |
| 76 | if (record == 2) { |
| 77 | host_x->copy_from(*gen(host_x->shape(), cn)); |
| 78 | } else { |
| 79 | // change ptr |
no test coverage detected