MCPcopy Create free account
hub / github.com/MegEngine/MegEngine / TEST

Function TEST

imperative/src/test/backward_graph.cpp:81–146  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

79}
80
81TEST(TestImperative, BackwardGraphBasic) {
82 HostTensorGenerator<> gen;
83 SmallVector<HostTensorND> hvs;
84 SmallVector<TensorPtr> inputs;
85 for (size_t i = 0; i < 2; ++i) {
86 hvs.push_back(*gen({42}));
87 inputs.push_back(Tensor::make(hvs.back()));
88 }
89
90 using Param = opr::Elemwise::Param;
91 Param param{Param::Mode::MUL};
92 auto attr = OprAttr::make("Elemwise");
93 attr->cast_final_safe<OprAttr>().param.write_pod(param);
94
95 SmallVector<LogicalTensorDesc> input_descs;
96 for (auto&& i : inputs) {
97 input_descs.push_back({i->layout(), i->comp_node()});
98 }
99 auto result = OpDef::make_backward_graph(*attr, input_descs, {true, true}, {true});
100 auto&& save_for_backward = result.input_mask;
101 auto&& input_has_grad = result.output_mask;
102
103 for (size_t i = 0; i < inputs.size(); i++) {
104 input_descs[i].value = inputs[i]->dev_tensor();
105 }
106 auto [output_descs, validated] =
107 OpDef::infer_output_attrs_fallible(*attr, input_descs);
108 auto outputs =
109 OpDef::apply_on_physical_tensor(*attr, inputs, output_descs, validated);
110 inputs.push_back(outputs[0]);
111 hvs.push_back(*gen({42}));
112 inputs.push_back(Tensor::make(hvs.back()));
113 mgb_assert(save_for_backward.size() == inputs.size());
114 for (size_t i = 0; i < inputs.size(); ++i) {
115 if (!save_for_backward[i]) {
116 inputs[i].reset(); // drop unused tensor
117 }
118 }
119 SmallVector<TensorPtr> backward_graph_inputs;
120 for (auto&& i : inputs) {
121 if (i) {
122 backward_graph_inputs.push_back(i);
123 }
124 }
125 inputs.clear();
126 auto input_grads = result.graph.apply<TensorPtr>(
127 backward_graph_inputs, apply_shared_on_physical_tensor,
128 [&](auto&& x) { return x; });
129 mgb_assert(input_grads.size() == input_has_grad.size());
130 for (size_t i = 0; i < input_has_grad.size(); ++i) {
131 mgb_assert(input_has_grad[i] == static_cast<bool>(input_grads[i]));
132 }
133
134 SmallVector<HostTensorND> res;
135 for (auto&& i : input_grads) {
136 res.emplace_back();
137 res.back().copy_from(i->dev_tensor()).sync();
138 }

Callers

nothing calls this directly

Calls 15

TensorLayoutClass · 0.85
expand_gradsFunction · 0.85
backMethod · 0.80
emplace_backMethod · 0.80
genFunction · 0.50
makeFunction · 0.50
make_backward_graphFunction · 0.50
apply_on_physical_tensorFunction · 0.50
loadFunction · 0.50
push_backMethod · 0.45

Tested by

no test coverage detected