| 273 | |
| 274 | |
| 275 | def blockwise_bmm( |
| 276 | x_fp8_np: np.ndarray, |
| 277 | x_scale_np: np.ndarray, |
| 278 | w_np: np.ndarray, |
| 279 | w_scale_np: np.ndarray, |
| 280 | block_size: tuple[int, int], |
| 281 | dtype: str, |
| 282 | ): |
| 283 | o_np = np.zeros((x_fp8_np.shape[0], x_fp8_np.shape[1], w_np.shape[1]), dtype=dtype) |
| 284 | for j in range(w_scale_np.shape[1]): |
| 285 | for k in range(w_scale_np.shape[2]): |
| 286 | o_np[..., j * block_size[0] : min((j + 1) * block_size[0], w_np.shape[1])] += ( |
| 287 | np.matmul( |
| 288 | x_fp8_np[ |
| 289 | ..., k * block_size[1] : min((k + 1) * block_size[1], x_fp8_np.shape[2]) |
| 290 | ].astype(dtype), |
| 291 | w_np[ |
| 292 | ..., |
| 293 | j * block_size[0] : min((j + 1) * block_size[0], w_np.shape[1]), |
| 294 | k * block_size[1] : min((k + 1) * block_size[1], w_np.shape[2]), |
| 295 | ] |
| 296 | .transpose(0, 2, 1) |
| 297 | .astype(dtype), |
| 298 | ) |
| 299 | * x_scale_np[..., k : k + 1] |
| 300 | * w_scale_np[..., j : j + 1, k : k + 1] |
| 301 | ) |
| 302 | return o_np |
| 303 | |
| 304 | |
| 305 | @pytest.mark.skipif(not env.has_cutlass(), reason="need cutlass") |