TBH, I don’t have much idea how it really works. I just know that if I operate on Variables and avoid inplace operations, then backprop works.
Some pointers…

The Module class has nothing to do with building the computation graph.
If I do a*b then python calls a.__mul__(b) which must be somehow defined on the Variable class though I haven’t found where.
Operations like torch.matmul also work on Variables, so they might provide clues.

Be aware that Variables and Tensors are being merged in the current master branch, so if you are digging around in the source code, you might find it easier to stick to the v0.3.1 branch