This creates a rather large computational graph indeed.
self.M*x though could be computed a single time and then reused in the loop, that will reduce it quire a bit !
Also even though your use case is more complex, remember that using .expand() and then doing one single multiplucation (possibly with a sum as well) will be much more efficient in terms of memory and runtime. expand does not use any extra memory and the computational graph will be substantially smaller and thus the memory required to store the intermediary results will be reduced as well.