Checks if the gradient operators can be correctly carried out.
(
self, grad_op_input, g_output, fwd_op_idx, locally_generated_blobs)
| 554 | self.ssa.append(OpSSA(op, in_versions, out_versions)) |
| 555 | |
| 556 | def CheckGradientOperatorInput( |
| 557 | self, grad_op_input, g_output, fwd_op_idx, locally_generated_blobs): |
| 558 | """Checks if the gradient operators can be correctly carried out.""" |
| 559 | forward_op, in_versions, out_versions = self.ssa[fwd_op_idx] |
| 560 | original_index = GetIndexFromGradientList(g_output, grad_op_input) |
| 561 | |
| 562 | # Functions to generate debug help for version-mismatches |
| 563 | def versionMismatchInfoOut(name): |
| 564 | s = "DEBUG HELP:\n" |
| 565 | s += "Maybe you use same output blob twice for different ops?\n" |
| 566 | s += "== Version history of blob [{}]\n".format(name) |
| 567 | for (op, vers) in self.out_version_history[name]: |
| 568 | s += "Version (out) {} <-- {}".format(vers, op) |
| 569 | s += "\n" |
| 570 | return s |
| 571 | |
| 572 | def versionMismatchInfoIn(name): |
| 573 | s = "DEBUG HELP:\n" |
| 574 | s += "Maybe the blob was overwritten by another op?\n" |
| 575 | s += "== Version history of blob [{}]\n".format(name) |
| 576 | for (op, vers) in self.in_version_history[name]: |
| 577 | s += "version (in) {} <-- {}".format(vers, op) |
| 578 | s += "\n" |
| 579 | return s |
| 580 | |
| 581 | # If it is a dense or sparse gradient name, it should match the |
| 582 | # version of the corresponding output. |
| 583 | if original_index is not None: |
| 584 | original_name = forward_op.output[original_index] |
| 585 | if (out_versions[original_name] != |
| 586 | self.gradient_frontier[original_name]): |
| 587 | raise RuntimeError( |
| 588 | 'Gradient name "%s" is expected to correspond ' |
| 589 | 'to version %d of "%s", but currently we have ' |
| 590 | 'version %d.\n\n' % ( |
| 591 | grad_op_input, out_versions[original_name], |
| 592 | original_name, |
| 593 | self.gradient_frontier[original_name]) + |
| 594 | versionMismatchInfoOut(original_name)) |
| 595 | # If it is an output name, the current version should match the |
| 596 | # version when the operator was run. |
| 597 | elif grad_op_input in out_versions: |
| 598 | if self.frontier[grad_op_input] != out_versions[grad_op_input]: |
| 599 | raise RuntimeError( |
| 600 | 'Gradient operator needs output "%s" at version' |
| 601 | ' %d, but currently we have version %d.\n\n' % ( |
| 602 | grad_op_input, out_versions[grad_op_input], |
| 603 | self.frontier[grad_op_input] |
| 604 | ) + versionMismatchInfoOut(grad_op_input) |
| 605 | ) |
| 606 | # If it is an input name, the current version should match the |
| 607 | # version when the operator was run. |
| 608 | elif grad_op_input in in_versions: |
| 609 | if (self.frontier[grad_op_input] != in_versions[grad_op_input]): |
| 610 | raise RuntimeError( |
| 611 | 'Gradient operator needs input "%s" at version ' |
| 612 | '%d, but currently we have version %d.\n\n' % ( |
| 613 | grad_op_input, in_versions[grad_op_input], |
no test coverage detected