(self)
| 174 | self.assertTrue(mx.allclose(w, w_hat, rtol=1e-5, atol=1e-5)) |
| 175 | |
| 176 | def test_qqmv(self): |
| 177 | key = mx.random.key(0) |
| 178 | k1, k2 = mx.random.split(key) |
| 179 | tests = product( |
| 180 | [256, 512, 67], # M |
| 181 | [64, 256], # N |
| 182 | ) |
| 183 | modes = ["nvfp4", "mxfp8"] |
| 184 | for M, N in tests: |
| 185 | for mode in modes: |
| 186 | with self.subTest(shape=(M, N), mode=mode): |
| 187 | x_shape = (1, N) |
| 188 | w_shape = (M, N) |
| 189 | |
| 190 | x = mx.random.normal(shape=x_shape, key=k1) |
| 191 | x_hat = mx.dequantize( |
| 192 | *mx.quantize(x, mode=mode), mode=mode, dtype=mx.float32 |
| 193 | ) |
| 194 | |
| 195 | w = mx.random.normal(shape=w_shape, key=k2) |
| 196 | w_q, scales = mx.quantize(w, mode=mode) |
| 197 | w_hat = mx.dequantize(w_q, scales, mode=mode, dtype=mx.float32) |
| 198 | y_q = mx.qqmm( |
| 199 | x, |
| 200 | w_q, |
| 201 | scales, |
| 202 | mode=mode, |
| 203 | ) |
| 204 | y_hat = x_hat @ mx.swapaxes(w_hat, -1, -2) |
| 205 | self.assertEqual(y_q.shape, y_hat.shape) |
| 206 | self.assertLess((y_q - y_hat).abs().max(), 1e-3) |
| 207 | |
| 208 | def test_qmm(self): |
| 209 | key = mx.random.key(0) |
nothing calls this directly
no test coverage detected