-
Notifications
You must be signed in to change notification settings - Fork 0
/
grad.hpp
194 lines (157 loc) · 6.82 KB
/
grad.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
631: ERROR: test_check_grad_ignore_x (test_matmul_op.TestMatMulOp_dimX_1_dim_Y_1_transX_False_transY_False)
631: ----------------------------------------------------------------------
631: Traceback (most recent call last):
631: File "../test_matmul_op.py", line 108, in test_check_grad_ignore_x
631: ['Y'], 'Out', max_relative_error=1e-3, no_grad_set=set("X"))
631: File "../op_test.py", line 920, in check_grad
631: user_defined_grads)
631: File "../op_test.py", line 965, in check_grad_with_place
631: output_names, no_grad_set)
631: File "../op_test.py", line 1044, in _get_gradient
631: executor.run(prog, feed_dict, fetch_list, return_numpy=False)))
631: File "/nvm/dyshape/ngraph-paddle/build/python/paddle/fluid/executor.py", line 739, in run
631: six.reraise(*sys.exc_info())
631: File "/nvm/dyshape/ngraph-paddle/build/python/paddle/fluid/executor.py", line 734, in run
631: use_program_cache=use_program_cache)
631: File "/nvm/dyshape/ngraph-paddle/build/python/paddle/fluid/executor.py", line 781, in _run_impl
631: use_program_cache=use_program_cache)
631: File "/nvm/dyshape/ngraph-paddle/build/python/paddle/fluid/executor.py", line 858, in _run_program
631: fetch_var_name)
631: IndexError: deque::_M_range_check: __n (which is 1)>= this->size() (which is 1)
163│ void Node::set_arguments(const OutputVector& arguments)
164│ {
165│ // Add this node as a user of each argument.
166│ size_t i = 0;
167│ for (auto& output : arguments)
168│ {
169│ auto output_node = output.get_node();
170├> auto& output_descriptor = output_node->get_outputs().at(output.get_index());
171│ m_inputs.emplace_back(this, i++, output_descriptor);
172│ }
173│ }
174│
(gdb) print output.get_index()
$1 = 1
(gdb) p output_descriptor
$2 = (ngraph::descriptor::Output &) @0x5ffff9210: <error reading variable>
(gdb) p output_node->get_outputs()
$3 = std::deque with 1 elements = {{m_node = 0x4252ec0, m_index = 0, m_tensor = std::shared_ptr (count 1, weak 0) 0x4263570, m_inputs = std::vector of length 1, capacity 1 = {0x4282be0}}}
(gdb)
if (is_dy)
{
std::shared_ptr<ngraph::Node> dy_t = std::make_shared<ngraph::op::GetOutputElement>(fused_op, 1); <=== here
auto dy_scale = ElementwiseScalar<ngraph::op::Multiply>(1 / alpha, dy_t);
paddle::platform::SetOutputNode(op, "Y@GRAD", fused_op, ngb_node_map);
}
#############################################################
void BuildMatMulGradDynamic(
const std::shared_ptr<paddle::framework::OperatorBase>& op,
std::shared_ptr<
std::unordered_map<std::string, std::shared_ptr<ngraph::Node>>>
ngb_node_map)
{
std::cout << "NGRAPH_CUSTOM_MATMUL_BACKWARD" << std::endl;
auto op_attrs = paddle::framework::AttrReader(op->Attrs());
std::cout << "***** BuildMatMulGradNodeDynamic ***** " << std::endl;
auto dout = paddle::platform::GetInputNode(op, "Out@GRAD", ngb_node_map);
auto y = paddle::platform::GetInputNode(op, "Y", ngb_node_map);
auto x = paddle::platform::GetInputNode(op, "X", ngb_node_map);
bool is_dx = paddle::platform::HasOutput(op, "X@GRAD") ? true : false;
bool is_dy = paddle::platform::HasOutput(op, "Y@GRAD") ? true : false;
bool transpose_x = op_attrs.Get<bool>("transpose_X");
bool transpose_y = op_attrs.Get<bool>("transpose_Y");
float alpha = op_attrs.Get<float>("alpha");
// check if fused_op[0] ... fused_op[1]
auto fused_op = std::make_shared<ngraph::op::MatMulPdBackward>( x, y, dout, is_dx, is_dy, transpose_x, transpose_y);
if (is_dx)
{
std::shared_ptr<ngraph::Node> dx_t = std::make_shared<ngraph::op::GetOutputElement>(fused_op, 0);
auto dx_scale = ElementwiseScalar<ngraph::op::Multiply>(1 / alpha, dx_t);
paddle::platform::SetOutputNode(op, "X@GRAD", fused_op, ngb_node_map);
}
if (is_dy)
{
std::shared_ptr<ngraph::Node> dy_t = std::make_shared<ngraph::op::GetOutputElement>(fused_op, 1);
auto dy_scale = ElementwiseScalar<ngraph::op::Multiply>(1 / alpha, dy_t);
paddle::platform::SetOutputNode(op, "Y@GRAD", fused_op, ngb_node_map);
}
}
// ################################
constexpr NodeTypeInfo op::MatMulPdBackward::type_info;
op::MatMulPdBackward::MatMulPdBackward(
std::shared_ptr<ngraph::Node> A,
std::shared_ptr<ngraph::Node> B,
std::shared_ptr<ngraph::Node> OutGrad,
bool is_X,
bool is_Y,
bool transpose_a,
bool transpose_b ) : FusedOp(OutputVector{A, B, OutGrad}),
m_A{A}, m_B{B}, m_is_X{is_X}, m_is_Y(is_Y),
m_transpose_a{transpose_a}, m_transpose_b{transpose_b}
{
constructor_validate_and_infer_types();
}
............
}
NodeVector op::MatMulPdBackward::decompose_op() const
{
auto x = input_value(0).get_node_shared_ptr();
auto y = input_value(1).get_node_shared_ptr();
auto dout = input_value(2).get_node_shared_ptr();
// auto& dout = OutGrad;
// auto& x = m_A;
// auto& y = m_B;
auto dout_shape = dout->get_shape();
auto x_shape = x->get_shape();
auto y_shape = y->get_shape();
size_t nx = x_shape.size();
size_t ny = y_shape.size();
size_t ndout = dout_shape.size();
std::shared_ptr<ngraph::Node> x2, y2;
std::shared_ptr<ngraph::Node> dout2;
x2 = helper_transposeAndFlat3D(x, false);
y2 = helper_transposeAndFlat3D(y, false, false);
dout2 = helper_transposeAndFlat3D(dout, false);
auto x2_shape = x2->get_shape();
auto y2_shape = y2->get_shape();
if (nx >= 3 || ny >= 3) {
std::shared_ptr<ngraph::Node> dout_temp;
if (ndout == 2) {
dout_temp = std::make_shared<ngraph::op::Reshape>(
dout, ngraph::AxisVector{0, 1},
ngraph::Shape{dout_shape[0], dout_shape[1], 1});
if (ny < 3) {
dout2 = dout_temp;
} else {
dout2 = helper_transposeAndFlat3D(dout_temp, true);
}
}
x2 = helper_broadcast3D(x2, y_shape[0]);
y2 = helper_broadcast3D(y2, x_shape[0]);
} else {
dout2 = helper_transposeAndFlat3D(dout, false, nx == 1 && m_transpose_a == false);
}
if (m_transpose_b == false) {
y2 = helper_transposeAndFlat3D(y2, true);
}
if (m_transpose_a == false) {
x2 = helper_transposeAndFlat3D(x2, true);
}
auto dx = helper_dotOp(dout2, y2);
auto dy = helper_dotOp(x2, dout2);
if (m_transpose_a == true) {
dx = helper_transposeAndFlat3D(dx, true);
}
if (m_transpose_b == true) {
dy = helper_transposeAndFlat3D(dy, true);
}
if (nx < 3 && ny >= 3) {
dx = std::make_shared<ngraph::op::Sum>(dx, ngraph::AxisSet{0});
}
if (ny < 3 && nx >= 3) {
dy = std::make_shared<ngraph::op::Sum>(dy, ngraph::AxisSet{0});
}
auto dx_t = helper_reshapeToOriginal(dx, x_shape);
auto dy_t = helper_reshapeToOriginal(dy, y_shape);
return NodeVector{ dx_t, dy_t, dout };
}