Skip to content

Commit 38d0bbe

Browse files
weimin023github-actions[bot]
authored andcommitted
Automerge: [NVGPU] Add FP8 (e4m3/e5m2) support to nvgpu.mma.sync (#207342)
This PR is stacked on #207307 ## Description Add FP8 E4M3/E5M2 support for `nvgpu.mma.sync`, building on the NVVM-level support in #207307. This adds NVGPU verification and lowering support, registers the supported `m16n8k16`/`m16n8k32` MMA variants, and adds coverage for NVGPU lowering and NVVM verification. ## Test ```sh mlir-opt mlir/test/Conversion/NVGPUToNVVM/nvgpu-to-nvvm-fp8.mlir \ -convert-nvgpu-to-nvvm -split-input-file ``` Co-authored with Claude Sonnet 5 --------- Signed-off-by: weimin023 <tnwilly@gmail.com>
2 parents 1142778 + ed0ea83 commit 38d0bbe

3 files changed

Lines changed: 55 additions & 3 deletions

File tree

mlir/lib/Conversion/NVGPUToNVVM/NVGPUToNVVM.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,10 @@ static FailureOr<NVVM::MMATypes> getNvvmMmaType(Type t) {
330330
return NVVM::MMATypes::f64;
331331
if (elType.isF32())
332332
return NVVM::MMATypes::tf32;
333+
if (elType.isF8E4M3FN())
334+
return NVVM::MMATypes::e4m3;
335+
if (elType.isF8E5M2())
336+
return NVVM::MMATypes::e5m2;
333337
return failure();
334338
}
335339

mlir/lib/Dialect/NVGPU/IR/NVGPUDialect.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ static LogicalResult verifyMmaSyncOp(Operation *op,
184184
numElementA = 1;
185185
numElementB = 1;
186186
} else if (aType.isF32() || aType.isBF16() || aType.isF16() ||
187-
aType.isInteger(8) || aType.isInteger(4)) {
187+
aType.isInteger(8) || aType.isInteger(4) || aType.isF8E4M3FN() ||
188+
aType.isF8E5M2()) {
188189
// 8-by-8-128b fundamental tensor core tile size
189190
int operandBitwidth = aType.getIntOrFloatBitWidth();
190191
shapeK = 128 / operandBitwidth; // 128b wide shapeK
@@ -193,8 +194,8 @@ static LogicalResult verifyMmaSyncOp(Operation *op,
193194
numElementB = 32 / operandBitwidth; // 32b wide operand B
194195
} else {
195196
return op->emitError()
196-
<< "expected input data type (i4,i8,f16,bf16,tf32,f64) "
197-
"supported by "
197+
<< "expected input data type (i4,i8,f16,bf16,tf32,f64,"
198+
"f8E4M3FN,f8E5M2) supported by "
198199
<< op->getName();
199200
}
200201

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: mlir-opt %s -convert-nvgpu-to-nvvm -split-input-file | FileCheck %s
2+
3+
// CHECK-LABEL: @fp8_mma_e4m3_e4m3_m16n8k16
4+
func.func @fp8_mma_e4m3_e4m3_m16n8k16(%arg0: vector<2x4xf8E4M3FN>, %arg1: vector<1x4xf8E4M3FN>, %arg2: vector<2x2xf32>) -> vector<2x2xf32> {
5+
// CHECK: nvvm.mma.sync
6+
// CHECK-SAME: multiplicandAPtxType = #nvvm.mma_type<e4m3>
7+
// CHECK-SAME: multiplicandBPtxType = #nvvm.mma_type<e4m3>
8+
// CHECK-SAME: shape = #nvvm.shape<m = 16, n = 8, k = 16>
9+
%0 = nvgpu.mma.sync(%arg0, %arg1, %arg2) {mmaShape = [16, 8, 16]} : (vector<2x4xf8E4M3FN>, vector<1x4xf8E4M3FN>, vector<2x2xf32>) -> vector<2x2xf32>
10+
return %0 : vector<2x2xf32>
11+
}
12+
13+
// -----
14+
15+
// CHECK-LABEL: @fp8_mma_e4m3_e4m3_m16n8k32
16+
func.func @fp8_mma_e4m3_e4m3_m16n8k32(%arg0: vector<4x4xf8E4M3FN>, %arg1: vector<2x4xf8E4M3FN>, %arg2: vector<2x2xf32>) -> vector<2x2xf32> {
17+
// CHECK: nvvm.mma.sync
18+
// CHECK-SAME: multiplicandAPtxType = #nvvm.mma_type<e4m3>
19+
// CHECK-SAME: multiplicandBPtxType = #nvvm.mma_type<e4m3>
20+
// CHECK-SAME: shape = #nvvm.shape<m = 16, n = 8, k = 32>
21+
%0 = nvgpu.mma.sync(%arg0, %arg1, %arg2) {mmaShape = [16, 8, 32]} : (vector<4x4xf8E4M3FN>, vector<2x4xf8E4M3FN>, vector<2x2xf32>) -> vector<2x2xf32>
22+
return %0 : vector<2x2xf32>
23+
}
24+
25+
// -----
26+
27+
// CHECK-LABEL: @fp8_mma_e5m2_e5m2_m16n8k16
28+
func.func @fp8_mma_e5m2_e5m2_m16n8k16(%arg0: vector<2x4xf8E5M2>, %arg1: vector<1x4xf8E5M2>, %arg2: vector<2x2xf32>) -> vector<2x2xf32> {
29+
// CHECK: nvvm.mma.sync
30+
// CHECK-SAME: multiplicandAPtxType = #nvvm.mma_type<e5m2>
31+
// CHECK-SAME: multiplicandBPtxType = #nvvm.mma_type<e5m2>
32+
// CHECK-SAME: shape = #nvvm.shape<m = 16, n = 8, k = 16>
33+
%0 = nvgpu.mma.sync(%arg0, %arg1, %arg2) {mmaShape = [16, 8, 16]} : (vector<2x4xf8E5M2>, vector<1x4xf8E5M2>, vector<2x2xf32>) -> vector<2x2xf32>
34+
return %0 : vector<2x2xf32>
35+
}
36+
37+
// -----
38+
39+
// CHECK-LABEL: @fp8_mma_e5m2_e5m2_m16n8k32
40+
func.func @fp8_mma_e5m2_e5m2_m16n8k32(%arg0: vector<4x4xf8E5M2>, %arg1: vector<2x4xf8E5M2>, %arg2: vector<2x2xf32>) -> vector<2x2xf32> {
41+
// CHECK: nvvm.mma.sync
42+
// CHECK-SAME: multiplicandAPtxType = #nvvm.mma_type<e5m2>
43+
// CHECK-SAME: multiplicandBPtxType = #nvvm.mma_type<e5m2>
44+
// CHECK-SAME: shape = #nvvm.shape<m = 16, n = 8, k = 32>
45+
%0 = nvgpu.mma.sync(%arg0, %arg1, %arg2) {mmaShape = [16, 8, 32]} : (vector<4x4xf8E5M2>, vector<2x4xf8E5M2>, vector<2x2xf32>) -> vector<2x2xf32>
46+
return %0 : vector<2x2xf32>
47+
}

0 commit comments

Comments
 (0)