| 1351 | namespace { |
| 1352 | |
| 1353 | void test_null_grad(bool dyn) { |
| 1354 | auto d = [dyn](SymbolVar var) -> SymbolVar { |
| 1355 | if (dyn) |
| 1356 | var = opr::MarkDynamicVar::make(var).node(); |
| 1357 | return var; |
| 1358 | }; |
| 1359 | |
| 1360 | auto zg = [](SymbolVar var) { |
| 1361 | return opr::SetGrad::make(var, opr::SetGrad::zero_grad); |
| 1362 | }; |
| 1363 | |
| 1364 | auto spow = [&](SymbolVar a, float p) { return opr::pow(d(a), a.make_scalar(p)); }; |
| 1365 | |
| 1366 | constexpr int LOOP_TIME = 1; |
| 1367 | HostTensorGenerator<dtype::Float32, RandomDistribution::UNIFORM> gen{1e-2, 1}; |
| 1368 | constexpr size_t SIZE0 = 23, SIZE1 = 32; |
| 1369 | auto host_x0 = gen({SIZE0}), host_x1 = gen({SIZE1}); |
| 1370 | |
| 1371 | auto graph = ComputingGraph::make(); |
| 1372 | auto outgraph_x0 = opr::Host2DeviceCopy::make(*graph, host_x0), |
| 1373 | outgraph_x1 = opr::Host2DeviceCopy::make(*graph, host_x1); |
| 1374 | |
| 1375 | auto desc_maker = [&](LoopDesc& desc) { |
| 1376 | auto x0a = desc.add_input_assignable(outgraph_x0).rename("x0a"), |
| 1377 | x0b = desc.add_input_assignable(outgraph_x0).rename("x0b"), |
| 1378 | |
| 1379 | // one value as multiple assignors |
| 1380 | val0 = (spow(x0a, 0.4) * spow(x0b, 0.5)).rename("val0"), |
| 1381 | |
| 1382 | x0c = desc.add_input_assignable(outgraph_x0).rename("x0c"), |
| 1383 | x0c1 = desc.add_input(outgraph_x0).rename("x0c1"), |
| 1384 | // assignee null grad |
| 1385 | val1 = (spow(zg(x0c), 0.5) * x0c1).rename("val1"), |
| 1386 | |
| 1387 | x0d = desc.add_input_assignable(outgraph_x0).rename("x0d"), |
| 1388 | // assignor null grad |
| 1389 | val2 = (spow(x0d, 0.6) * x0c1).rename("val2"), |
| 1390 | |
| 1391 | // null outgrad in par graph |
| 1392 | x1 = desc.add_input(outgraph_x1).rename("x1"), |
| 1393 | x1a = desc.add_input_assignable(outgraph_x1).rename("x1a"), |
| 1394 | val3 = (spow(x1a, 0.7) * x1).rename("val3"); |
| 1395 | |
| 1396 | desc.assign(x0a, val0); |
| 1397 | desc.assign(x0b, val0); |
| 1398 | desc.assign(x0c, val1); |
| 1399 | desc.assign(x0d, val2); |
| 1400 | desc.assign(x1a, val3); |
| 1401 | |
| 1402 | desc.add_output(val0, OutputMode::LAST); |
| 1403 | desc.add_output(val1, OutputMode::LAST); |
| 1404 | desc.add_output(zg(val2), OutputMode::LAST); |
| 1405 | desc.add_output(val3, OutputMode::LAST); |
| 1406 | |
| 1407 | desc.set_loop_condition(desc.get_counter_var() < LOOP_TIME - 1); |
| 1408 | }; |
| 1409 | |
| 1410 | auto y = opr::Loop::make(desc_maker); |
no test coverage detected