partial answers to your question, in case useful:

the derivatives are calculated when you call .backward() on your loss/objective function

optimizer.step() passes the derivatives to the optimizer, eg SGD, Adam etc, which then handles all the fancy momentum stuff and so on, and updates the weights
in the backward path, the derivatives are based on the forward path. However, I kind of suspect that if you have eg .int() in your forward path, this is theoretically non-differentiable, and you’d need to use some kind of REINFORCE algorithm or gumbel softmax or similar (I havent though through the assertion that .int() is non-differentiable for more than ~2-3 seconds, so take this with a wodge of salt)