As we go backward through the computation graph, we can compute de/dc without knowing anything about dc/da or dc/db as e = g(c, d) comes after a and b.
Yes, that is the critical part. In order for autograd to work, every supported op must have a backward function (or more than one depending on the number of inputs) defined for this purpose. The function doesn’t store b necessarily, it just knows that the derivative is the other input. If we rewrite c = f(a, b) for a moment to be output = f(input, weight), there are definitions for “how to compute input gradient given output gradient and weight” and “how to compute weight gradient given output gradient and input.” While this grad_fn itself doesn’t store the values, we will need to pass them to grad_fn to compute the gradients.