Q1 + Q2: if you don’t call .clone() or manually make a deepcopy, pytorch tries to use the same storage if possible. So the answer to both questions: usually the same storage will be used.
Q3: for instances of torch.nn.Module the changes are made in the self variable (python uses something similar to call by reference) and you wouldn’t have to reassign it at all. After this operation the self variable is returned to ensure a proper API. Since net and gnet are references to the same internal variable, changing one of them will also change the other one.
Q4:
If the model is just on the device you want it to push to, the .to() operations becomes a no-OP (just like changing the dtype or calling .cuda() or .cpu() directly.
So yes: usually the method you suggested is the way to go and usually CPU and GPU should cover nearly the same operations (if you don’t use very experimental ones) if you use only torch functions.