Q1: The function torch.addr_ is what I was looking for because it adds the outer product of two vectors completely in-place without allocating any extra memory.
As a side note, since the matrices are in row-major order in PyTorch, accessing the columns the way I do in my question above is slower than accessing the rows.