I realize that one thing that was not clear is that the compute_f_loss() actually computes a loss that is a function of the output of f and of g. Essentially, the output of g is fed into f.
The problem with detaching the outputs of f and g before feeding them into the loss is that I need the gradient of calculate_f_loss() with respect to f.parameters() and then I need the 2nd order gradient with respect to g.parameters(). If I detached the outputs of f and g, then calculate_f_loss().backward() would not populate the .grad fields of f.parameters() or g.parameters().