Skip to content

Commit 80ff67b

Browse files
authored
[mlir][nvvm] Introduce nvvm.fence.proxy (#74057)
This PR introduce `nvvm.fence.proxy` OP for the following cases: ``` nvvm.fence.proxy { kind = #nvvm.proxy_kind<alias>} nvvm.fence.proxy { kind = #nvvm.proxy_kind<async>} nvvm.fence.proxy { kind = #nvvm.proxy_kind<async.global>} nvvm.fence.proxy { kind = #nvvm.proxy_kind<async.shared>, space = #nvvm.shared_space<cta>} nvvm.fence.proxy { kind = #nvvm.proxy_kind<async.shared>, space = #nvvm.shared_space<cluster>} ```
1 parent 3a03da3 commit 80ff67b

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,55 @@ def NVVM_FenceScClusterOp : NVVM_Op<"fence.sc.cluster"> {
400400
let assemblyFormat = "attr-dict";
401401
}
402402

403+
def SharedSpaceCTA : I32EnumAttrCase<"shared_cta", 0, "cta">;
404+
def SharedSpaceCluster : I32EnumAttrCase<"shared_cluster", 1, "cluster">;
405+
def SharedSpace : I32EnumAttr<"SharedSpace", "Shared memory space",
406+
[SharedSpaceCTA, SharedSpaceCluster]> {
407+
let genSpecializedAttr = 0;
408+
let cppNamespace = "::mlir::NVVM";
409+
}
410+
def SharedSpaceAttr : EnumAttr<NVVM_Dialect, SharedSpace, "shared_space"> {
411+
let assemblyFormat = "`<` $value `>`";
412+
}
413+
414+
def ProxyAlias : I32EnumAttrCase<"alias", 0, "alias">;
415+
def ProxyAsync : I32EnumAttrCase<"async", 1, "async">;
416+
def ProxyAsyncGlobal : I32EnumAttrCase<"async_global", 2, "async.global">;
417+
def ProxyAsyncShared : I32EnumAttrCase<"async_shared", 3, "async.shared">;
418+
def ProxyKind : I32EnumAttr<"ProxyKind", "Proxy kind",
419+
[ProxyAlias, ProxyAsync, ProxyAsyncGlobal, ProxyAsyncShared]> {
420+
let genSpecializedAttr = 0;
421+
let cppNamespace = "::mlir::NVVM";
422+
}
423+
424+
def ProxyKindAttr : EnumAttr<NVVM_Dialect, ProxyKind, "proxy_kind"> {
425+
let assemblyFormat = "`<` $value `>`";
426+
}
427+
428+
def NVVM_FenceProxyOp : NVVM_PTXBuilder_Op<"fence.proxy">,
429+
Arguments<(ins ProxyKindAttr:$kind,
430+
OptionalAttr<SharedSpaceAttr>:$space)> {
431+
let description = [{
432+
Fence operation with proxy to establish an ordering between memory accesses
433+
that may happen through different proxies.
434+
[For more information, see PTX ISA]
435+
(https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-membar)
436+
}];
437+
438+
let assemblyFormat = "attr-dict";
439+
let extraClassDefinition = [{
440+
std::string $cppClass::getPtx() {
441+
std::string ptx = "fence.proxy.";
442+
ptx += stringifyProxyKind(getKind());
443+
if(getKind() == NVVM::ProxyKind::async_shared)
444+
{ ptx += "::"; ptx += stringifySharedSpace(getSpace().value()); }
445+
ptx += ";";
446+
return ptx;
447+
}
448+
}];
449+
let hasVerifier = 1;
450+
}
451+
403452
def SetMaxRegisterActionIncrease : I32EnumAttrCase<"increase", 0>;
404453
def SetMaxRegisterActionDecrease : I32EnumAttrCase<"decrease", 1>;
405454
def SetMaxRegisterAction : I32EnumAttr<"SetMaxRegisterAction", "NVVM set max register action",

mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "mlir/IR/Builders.h"
2323
#include "mlir/IR/BuiltinAttributes.h"
2424
#include "mlir/IR/BuiltinTypes.h"
25+
#include "mlir/IR/Diagnostics.h"
2526
#include "mlir/IR/DialectImplementation.h"
2627
#include "mlir/IR/MLIRContext.h"
2728
#include "mlir/IR/Operation.h"
@@ -1006,6 +1007,15 @@ void NVVM::WgmmaMmaAsyncOp::getAsmValues(
10061007
mlir::NVVM::PTXRegisterMod::Read});
10071008
}
10081009
}
1010+
LogicalResult NVVM::FenceProxyOp::verify() {
1011+
if (getKind() == NVVM::ProxyKind::async_shared && !getSpace().has_value()) {
1012+
return emitOpError() << "async_shared fence requires space attribute";
1013+
}
1014+
if (getKind() != NVVM::ProxyKind::async_shared && getSpace().has_value()) {
1015+
return emitOpError() << "only async_shared fence can have space attribute";
1016+
}
1017+
return success();
1018+
}
10091019

10101020
LogicalResult NVVM::SetMaxRegisterOp::verify() {
10111021
if (getRegCount() % 8)

mlir/test/Conversion/NVVMToLLVM/invalid.mlir

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,19 @@ func.func @set_max_register() {
147147
nvvm.setmaxregister decrease 51
148148
func.return
149149
}
150+
151+
// -----
152+
153+
func.func @fence_proxy() {
154+
// expected-error @+1 {{op only async_shared fence can have space attribute}}
155+
nvvm.fence.proxy { kind = #nvvm.proxy_kind<async>, space = #nvvm.shared_space<cluster>}
156+
func.return
157+
}
158+
159+
// -----
160+
161+
func.func @fence_proxy() {
162+
// expected-error @+1 {{op async_shared fence requires space attribute}}
163+
nvvm.fence.proxy { kind = #nvvm.proxy_kind<async.shared>}
164+
func.return
165+
}

mlir/test/Conversion/NVVMToLLVM/nvvm-to-llvm.mlir

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,3 +629,18 @@ func.func @cp_bulk_commit() {
629629
nvvm.cp.async.bulk.commit.group
630630
func.return
631631
}
632+
// -----
633+
634+
func.func @fence_proxy() {
635+
//CHECK: llvm.inline_asm has_side_effects asm_dialect = att "fence.proxy.alias;", "" : () -> ()
636+
nvvm.fence.proxy { kind = #nvvm.proxy_kind<alias>}
637+
//CHECK: llvm.inline_asm has_side_effects asm_dialect = att "fence.proxy.async;", "" : () -> ()
638+
nvvm.fence.proxy { kind = #nvvm.proxy_kind<async>}
639+
//CHECK: llvm.inline_asm has_side_effects asm_dialect = att "fence.proxy.async.global;", "" : () -> ()
640+
nvvm.fence.proxy { kind = #nvvm.proxy_kind<async.global>}
641+
//CHECK: llvm.inline_asm has_side_effects asm_dialect = att "fence.proxy.async.shared::cta;", "" : () -> ()
642+
nvvm.fence.proxy { kind = #nvvm.proxy_kind<async.shared>, space = #nvvm.shared_space<cta>}
643+
//CHECK: llvm.inline_asm has_side_effects asm_dialect = att "fence.proxy.async.shared::cluster;", "" : () -> ()
644+
nvvm.fence.proxy { kind = #nvvm.proxy_kind<async.shared>, space = #nvvm.shared_space<cluster>}
645+
func.return
646+
}

0 commit comments

Comments
 (0)