@@ -182,9 +182,11 @@ Graph::Graph(const ProgramDesc &program) : program_(program) {
182
182
}
183
183
184
184
/* *
185
- * We only handle write after read(WAR), since it should not have a write
186
- * after write in program. If there are write after write operators, we need
187
- * prune them.
185
+ * We should handle write after read(WAR) and write after write(WAW) here.
186
+ * Because some of the operators of the program can be executed parallelly.
187
+ * So, to make the program running in the right order, we should add the
188
+ * dependence of WAR and WAW.
189
+ *
188
190
*
189
191
* https://en.wikipedia.org/wiki/Hazard_(computer_architecture)#Write_after_read_(WAR)
190
192
*/
@@ -201,6 +203,19 @@ Graph::Graph(const ProgramDesc &program) : program_(program) {
201
203
(*it_new)->inputs .empty () ? nullptr : (*it_new)->inputs [0 ];
202
204
const auto &read_ops = (*it_old)->outputs ;
203
205
206
+ PADDLE_ENFORCE (write_op, " The write_op should not be empty." );
207
+
208
+ // Add write after write dependence
209
+ ir::Node *upstream_op =
210
+ (*it_old)->inputs .empty () ? nullptr : (*it_old)->inputs [0 ];
211
+ if (upstream_op) {
212
+ ir::Node *dep_var = CreateControlDepVar ();
213
+ write_op->inputs .push_back (dep_var);
214
+ upstream_op->outputs .push_back (dep_var);
215
+ dep_var->outputs .push_back (write_op);
216
+ dep_var->inputs .push_back (upstream_op);
217
+ }
218
+
204
219
for (auto *read_op : read_ops) {
205
220
// Manually add a dependency var from read_op to write_op;
206
221
if (read_op == write_op) {
0 commit comments