| 321 | #if MGB_ENABLE_COND_EXEC |
| 322 | |
| 323 | TEST(TestCondExec, GoptRemoveConstMask) { |
| 324 | using MergeMode = opr::CondExecMerge::Mode; |
| 325 | HostTensorGenerator<> gen; |
| 326 | auto host_x = gen({2, 3}); |
| 327 | auto run = [&](MergeMode merge_mode, int const_mask, int pred_mask, |
| 328 | bool expect_change) -> HostTensorND { |
| 329 | auto host_pred0 = gen({1}), host_pred1 = gen({1}); |
| 330 | host_pred0->ptr<float>()[0] = pred_mask & 1; |
| 331 | host_pred1->ptr<float>()[0] = pred_mask >> 1; |
| 332 | auto graph = ComputingGraph::make(); |
| 333 | auto x = opr::Host2DeviceCopy::make(*graph, host_x); |
| 334 | auto make_mark = [x, &graph]( |
| 335 | bool const_pred, |
| 336 | const std::shared_ptr<HostTensorND>& host_pred) { |
| 337 | SymbolVar pred; |
| 338 | if (const_pred) { |
| 339 | pred = opr::ImmutableTensor::make(*graph, *host_pred); |
| 340 | } else { |
| 341 | pred = opr::Host2DeviceCopy::make(*graph, host_pred); |
| 342 | } |
| 343 | SymbolVar ppv, ret; |
| 344 | unpack_vector(opr::CondExecPred::make(pred, {pred.make_scalar_dt(1)}), ppv); |
| 345 | unpack_vector(opr::CondExecMark::make(ppv, {x}), ret); |
| 346 | return ret; |
| 347 | }; |
| 348 | SymbolVarArray merge_shp; |
| 349 | if (merge_mode == MergeMode::SUM) { |
| 350 | merge_shp.push_back(x.symshape()); |
| 351 | } |
| 352 | auto xmark0 = make_mark(const_mask & 1, host_pred0) + 1.2f, |
| 353 | xmark1 = make_mark(const_mask >> 1, host_pred1) * 2.3f, |
| 354 | y = opr::CondExecMerge::make( |
| 355 | {xmark0, xmark1}, {1, merge_mode}, merge_shp)[0]; |
| 356 | VarNodeArray y_opt_arr{y.node()}; |
| 357 | gopt::GraphOptimizer{} |
| 358 | .add_pass<gopt::CondExecConstPredicateFolding>() |
| 359 | .apply_inplace(y_opt_arr); |
| 360 | SymbolVar y_opt = y_opt_arr[0]; |
| 361 | if (expect_change) { |
| 362 | EXPECT_NE(y_opt.node(), y.node()); |
| 363 | } else { |
| 364 | EXPECT_EQ(y_opt, y); |
| 365 | } |
| 366 | HostTensorND host_y; |
| 367 | graph->options().graph_opt_level = 0; |
| 368 | auto func = graph->compile({make_callback_copy(y_opt, host_y)}); |
| 369 | func->execute(); |
| 370 | return host_y; |
| 371 | }; |
| 372 | |
| 373 | for (size_t mode_num = 0; mode_num < opr::CondExecMerge::Param::MODE_NR_MEMBER; |
| 374 | ++mode_num) { |
| 375 | auto mode = static_cast<MergeMode>(mode_num); |
| 376 | bool exact_one = |
| 377 | (mode == MergeMode::EXACT_ONE || |
| 378 | mode == MergeMode::EXACT_ONE_SAME_SHAPE); |
| 379 | for (int pmask = 0; pmask < 4; ++pmask) { |
| 380 | if (exact_one && (pmask & 1) + (pmask >> 1) != 1) { |
nothing calls this directly
no test coverage detected