But when you call the global_contrast.backward manually, you do get something non-zero?
Some other random thoughts on your code:

.data should not be needed for anything these days.
You would not get gradients for non-leaves (like c unless you do c.retain_grad() before the backward).  retain_graph is for when you want to call .backward a second time, not for keeping intermediate gradients.
calling the variable grad seems - let’s say - unconventional, but I know it’s just an example.

Best regards
Thomas