The torch layer, checked against PyTorch 2.11
Silent errors in eager torch are fixed, the layers, optimizers, dtypes, linalg, fft and distributions ordinary training code uses are added, and eager torch's heavy loops run natively: about 4.8x faster, same bytes.
The commits lead with what was silently wrong. In-place arithmetic rebound a tensor to new storage, so the textbook w.data.add_(w.grad, alpha=-lr) left the weights unchanged; float32 means accumulated in float32, so the mean of a million 0.1s was 0.100958 (1f95d6f9). The -100 padding label indexed a real class and a reassigned BatchNorm buffer never reached state_dict (cfc8e990). A PyTorch Adam checkpoint drifted its bias correction (782cc0aa), and torch.compile training captured an eager op on a parameter as a new leaf whose gradient never reached it (7dd1db31). Each fix is checked against values PyTorch 2.11 generated, and each commit adds what training code reaches for: about 200 tensor functions, the common layers, 12 optimizers, 15 schedulers, torch.utils.data, float16 and bfloat16 (stored in two bytes by 61b960e5), torch.linalg and torch.distributions.
Speed came second and without changing a byte. 14a2ef71 turned the JIT on for zipp py and fb5ecc0a reverted it the same night, because once the tensor loops ran natively the JIT made training slower. b24c6b81 is that change: matmul, convolution, elementwise ops and reductions run as Rust natives that repeat the JavaScript's float64 operations in the same order, and 20,828 native-against-JavaScript cases differ in no byte. torch_matmul went from 319 to 8.4 ms and the geometric mean to 0.21× its time. 2481bb47 did the same for torch.linalg (a 64x64 eig from 218 s to 2.6 ms) and added complex tensors and torch.fft.