Use PyTorch's SVD which can utilize GPU acceleration
(input_matrix, rank, n_iter=10)
| 2 | |
| 3 | |
| 4 | def get_svd_grad(input_matrix, rank, n_iter=10): |
| 5 | """Use PyTorch's SVD which can utilize GPU acceleration""" |
| 6 | |
| 7 | # Handle meta tensors |
| 8 | if hasattr(input_matrix, 'is_meta') and input_matrix.is_meta: |
| 9 | input_matrix = input_matrix.to('cpu') |
| 10 | input_matrix = input_matrix.clone().detach() |
| 11 | |
| 12 | # Convert to torch tensor if not already |
| 13 | if not torch.is_tensor(input_matrix): |
| 14 | input_matrix = torch.from_numpy(input_matrix) |
| 15 | |
| 16 | # Move to GPU |
| 17 | device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') |
| 18 | input_matrix = input_matrix.to(device) |
| 19 | |
| 20 | # Temporarily convert to float32 for SVD |
| 21 | input_matrix_float = input_matrix.to(torch.float32) |
| 22 | |
| 23 | # Create random tensor in same dtype |
| 24 | torch.manual_seed(42) # for reproducibility |
| 25 | size = input_matrix.size(1) |
| 26 | R = torch.randn(size, rank, device=device, dtype=torch.float32) |
| 27 | |
| 28 | # Compute SVD with controlled dtypes |
| 29 | U, s, V = torch.svd_lowrank(input_matrix_float, q=rank, niter=n_iter) |
| 30 | |
| 31 | # Convert results back to bfloat16 |
| 32 | U = U.to(torch.bfloat16) |
| 33 | s = s.to(torch.bfloat16) |
| 34 | V = V.to(torch.bfloat16) |
| 35 | diag_s = torch.diag(s) |
| 36 | |
| 37 | # remove intermediate tensors from memory |
| 38 | del input_matrix, input_matrix_float, R |
| 39 | |
| 40 | return U, diag_s, V.T |
| 41 | |
| 42 | |
| 43 |
no outgoing calls
no test coverage detected