warp.tile_matmul#
- warp.tile_matmul(
- a: Tile[Float, tuple[int, int]],
- b: Tile[Float, tuple[int, int]],
- out: Tile[Float, tuple[int, int]],
- alpha: Float = 1.0,
- beta: Float = 1.0,
- precision: str = 'default',
Accumulate the matrix product
a @ binto an existing tile.Computes
out = alpha * a @ b + beta * out, updatingoutin place.outis read only whenbetais nonzero, so it must be initialized before the call unlessbetais zero. Use thewp.tile_matmul(a, b)overload to obtain a freshly computed tile instead.outmust not aliasaorb: the operands are read whileoutis being written, so overlapping tiles give undefined results. Passing the same tile as bothaandbis fine.This is a cooperative operation, so every thread in the block must call it.
a,b, andoutmay independently usefloat16,float32, orfloat64. Accumulation uses the dtype ofout. Currently,aandbmay also usebfloat16when backward compilation is disabled with the module optionenable_backward=False. Apart from theM,N, andKextents having to agree, the shapes are unconstrained, but large tiles may exhaust shared memory or fail to compile the cuBLASDx kernel.Tile data is migrated to shared memory when necessary.
On CUDA devices, Warp uses cuBLASDx when it is built with libmathdx and
warp.config.enable_mathdx_gemm(or theenable_mathdx_gemmmodule option) isTrue, unless an operand’s strides cannot be expressed as a cuBLASDx leading dimension. Otherwise, and on the CPU, it uses a scalar GEMM, which is slower than cuBLASDx on CUDA devices.Passing
beta=0cuts gradient flow to the previous contents ofout. The scalaralphaandbetaarguments do not receive gradients.- Parameters:
a – A tile with
shape=(M, K).b – A tile with
shape=(K, N).out – A tile with
shape=(M, N)that the product is accumulated into. Must be initialized unlessbetais zero.alpha – Scaling factor applied to the product
a @ b.beta – Scaling factor applied to the incoming contents of
out.precision – Compute precision, specified as the string literal
"default"or"tf32"."default"uses the tile data type."tf32"uses TF32 input precision withfloat32accumulation, without changing tile storage. The adjoint products use the same precision. Tensor Core use depends on the GEMM configuration. Honored by the cuBLASDx GEMM on CUDA compile targets of compute capability 8.0 or higher. On the CPU, on older CUDA compile targets, or when MathDx GEMM is unavailable or disabled (seewarp.config.enable_mathdx_gemm), Warp computes infloat32and logs a warning when the module is compiled. The same fallback applies when operand strides cannot be represented by cuBLASDx leading dimensions.
- Raises:
TypeError – If
precision="tf32"is used with tiles other thanfloat32fora,b, andout.ValueError – If
precisionis not the string literal"default"or"tf32".
Example
@wp.kernel def gemm(a: wp.array2d[float], b: wp.array2d[float], out: wp.array2d[float]): # beta defaults to 1, so initialize the accumulator before adding the products out_tile = wp.tile_zeros(shape=(4, 8), dtype=float) # accumulate the partial products over two slices of the shared dimension for k in range(2): a_tile = wp.tile_load(a, shape=(4, 3), offset=(0, k * 3)) b_tile = wp.tile_load(b, shape=(3, 8), offset=(k * 3, 0)) wp.tile_matmul(a_tile, b_tile, out_tile) wp.tile_store(out, out_tile) a = wp.array(np.arange(24, dtype=np.float32).reshape(4, 6)) b = wp.array(np.arange(48, dtype=np.float32).reshape(6, 8)) out = wp.zeros((4, 8), dtype=float) # one full warp cooperates on the 32 output entries wp.launch_tiled(gemm, dim=1, inputs=[a, b], outputs=[out], block_dim=32) print(out.numpy())
[[ 440. 455. 470. 485. 500. 515. 530. 545.] [1160. 1211. 1262. 1313. 1364. 1415. 1466. 1517.] [1880. 1967. 2054. 2141. 2228. 2315. 2402. 2489.] [2600. 2723. 2846. 2969. 3092. 3215. 3338. 3461.]]
- warp.tile_matmul(
- a: Tile[Float, tuple[int, int]],
- b: Tile[Float, tuple[int, int]],
- alpha: Float = 1.0,
- precision: str = 'default',
Compute the matrix product
a @ b.Unlike the accumulating form
wp.tile_matmul(a, b, out), no tile is read for the result, so nothing has to be initialized.The product is accumulated in
a’s dtype, soamay not bebfloat16. Unlikewp.tile_matmul(a, b, out), whereout’s dtype sets the accumulation dtype, the result dtype cannot be chosen independently ofa. Backend selection matcheswp.tile_matmul(a, b, out); see that overload for details and a usage example.This is a cooperative operation, so every thread in the block must call it.
- Parameters:
a – A tile with
shape=(M, K).b – A tile with
shape=(K, N).alpha – Scaling factor applied to the product
a @ b. It does not receive a gradient.precision – Compute precision, specified as the string literal
"default"or"tf32"."default"uses the tile data type."tf32"uses TF32 input precision withfloat32accumulation, without changing tile storage. The adjoint products use the same precision. Tensor Core use depends on the GEMM configuration. Honored by the cuBLASDx GEMM on CUDA compile targets of compute capability 8.0 or higher. On the CPU, on older CUDA compile targets, or when MathDx GEMM is unavailable or disabled (seewarp.config.enable_mathdx_gemm), Warp computes infloat32and logs a warning when the module is compiled. The same fallback applies when operand strides cannot be represented by cuBLASDx leading dimensions.
- Returns:
A new tile in shared memory with
shape=(M, N)and the same dtype asa, holdingalpha * a @ b.- Raises:
TypeError – If
precision="tf32"is used with tiles other thanfloat32foraandb.ValueError – If
precisionis not the string literal"default"or"tf32".