MCPcopy Create free account
hub / github.com/pytorch/pytorch / gen_do_gradient

Function gen_do_gradient

caffe2/python/control_ops_grad.py:11–166  ·  view source on GitHub ↗

Generates gradient Do operator, given forward Do op and a list of gradient blobs corresponding to forward op's outputs Returns a gradient op and a list of blobs corresponding to input gradients

(op, g_output)

Source from the content-addressed store, hash-verified

9
10
11def gen_do_gradient(op, g_output):
12 """
13 Generates gradient Do operator, given forward Do op and a list
14 of gradient blobs corresponding to forward op's outputs
15 Returns a gradient op and a list of blobs corresponding to input gradients
16 """
17 from caffe2.python.core import BlobReference
18 subnet, outer_to_inner_map, inner_to_outer_map, workspace_blob_name = \
19 _do_op_sanity_check_and_process(op)
20
21 assert len(g_output) == len(op.output), \
22 "Different number of gradient blobs and Do op outputs"
23
24 grad_ops, deduped_g_output = dedupe_g_output(op, g_output)
25 g_output = deduped_g_output
26
27 # From the outer net point of view:
28 # Do is an operator that has some number of inputs and outputs;
29 # we have to generate a gradient operator that writes into
30 # corresponding input gradient blobs and has access to inputs, outputs
31 # and gradient output blobs
32 # From the inner net point of view:
33 # Do is an operator with a subnet and blob bindings,
34 # we need to forward Do's output blob gradients into inner workspace,
35 # use them to run backward pass generation and forward Do's input blob
36 # gradients back into outer workspace
37
38 op_output = [str(o) for o in op.output]
39 op_output = op_output[:-1] # remove workspace pointer blob
40 op_input = [str(i) for i in op.input]
41 op_input = op_input[:-1] # remove workspace pointer blob
42
43 ordered_inner_output_blob_names = [outer_to_inner_map[o] for o in op_output]
44
45 backward_pass_initial_grad_map = {}
46 initial_grad_map = {}
47 for inner_output_name, outer_grad_output_name in \
48 zip(ordered_inner_output_blob_names, g_output):
49 # link inner_output_name to corresponding inner_grad_output_name for
50 # backward pass generation;
51 if outer_grad_output_name:
52 inner_grad_output_name = inner_output_name + "/_DO_OPERATOR_INNER_GRAD_"
53 backward_pass_initial_grad_map[BlobReference(inner_output_name)] = \
54 BlobReference(inner_grad_output_name)
55 initial_grad_map[inner_grad_output_name] = str(outer_grad_output_name)
56 assert len(initial_grad_map) > 0, "Empty initial gradient map for Do op"
57
58 inner_grad_ops, inner_grad_names_map = _gen_subgradient_pass(
59 subnet, backward_pass_initial_grad_map)
60
61 if len(inner_grad_ops) == 0:
62 return [], []
63
64 grad_copy_ops = []
65 g_input = []
66 new_op_outputs = []
67 new_blob_bindings = {}
68 for outer_input_name in op_input:

Callers

nothing calls this directly

Calls 10

BlobReferenceClass · 0.90
dedupe_g_outputFunction · 0.85
_gen_subgradient_passFunction · 0.85
_prepare_blob_copy_opFunction · 0.85
_prepare_gradient_do_opFunction · 0.85
appendMethod · 0.45
getMethod · 0.45
addMethod · 0.45
updateMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…