Skip to content

Commit 473b364

Browse files
committed
1 parent c303d9b commit 473b364

File tree

7 files changed

+122
-4
lines changed

7 files changed

+122
-4
lines changed

mlir/include/mlir/Dialect/GPU/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
add_mlir_dialect(GPUOps gpu)
22
add_mlir_doc(GPUOps -gen-op-doc GPUOps Dialects/)
33

4+
set(LLVM_TARGET_DEFINITIONS GPUBase.td)
5+
mlir_tablegen(GPUOpInterfaces.h.inc -gen-op-interface-decls)
6+
mlir_tablegen(GPUOpInterfaces.cpp.inc -gen-op-interface-defs)
7+
add_public_tablegen_target(MLIRGPUOpInterfacesIncGen)
8+
49
set(LLVM_TARGET_DEFINITIONS ParallelLoopMapperAttr.td)
510
mlir_tablegen(ParallelLoopMapperAttr.h.inc -gen-struct-attr-decls)
611
mlir_tablegen(ParallelLoopMapperAttr.cpp.inc -gen-struct-attr-defs)

mlir/include/mlir/Dialect/GPU/GPUBase.td

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,53 @@ def GPU_Dialect : Dialect {
5353
}];
5454
}
5555

56+
def GPU_AsyncToken : DialectType<
57+
GPU_Dialect, CPred<"$_self.isa<::mlir::gpu::AsyncTokenType>()">, "async token type">,
58+
BuildableType<"mlir::gpu::AsyncTokenType::get($_builder.getContext())">;
59+
60+
def GPU_AsyncOpInterface : OpInterface<"AsyncOpInterface"> {
61+
let description = [{
62+
Interface for GPU operations that execute asynchronously on the device.
63+
64+
GPU operations implementing this interface take a list of dependencies
65+
as `gpu.async.token` arguments and optionally return a `gpu.async.token`.
66+
67+
The op doesn't start executing until all depent ops producing the async
68+
dependency tokens have finished executing.
69+
70+
If the op returns a token, the op merely schedules the execution on the
71+
device and returns immediately, without waiting for the execution to
72+
complete. On the hand, if the op does not return a token, the op will wait
73+
for the execution to complete.
74+
}];
75+
let cppNamespace = "::mlir::gpu";
76+
77+
let methods = [
78+
InterfaceMethod<[{
79+
Query the operands that represent async dependency tokens.
80+
}],
81+
"OperandRange", "getAsyncDependencies", (ins), [{}], [{
82+
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
83+
return op.asyncDependencies();
84+
}]
85+
>,
86+
InterfaceMethod<[{
87+
Adds a new token to the list of async dependencies.
88+
}],
89+
"void", "addAsyncDependency", (ins "Value":$token),
90+
[{}], [{
91+
::mlir::gpu::addAsyncDependency(this->getOperation(), token);
92+
}]
93+
>,
94+
InterfaceMethod<[{
95+
Query the result that represents the async token to depend on.
96+
}],
97+
"OpResult", "getAsyncToken", (ins), [{}], [{
98+
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
99+
return op.asyncToken().template dyn_cast_or_null<OpResult>();
100+
}]
101+
>
102+
];
103+
}
104+
56105
#endif // GPU_BASE

mlir/include/mlir/Dialect/GPU/GPUDialect.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef MLIR_DIALECT_GPU_GPUDIALECT_H
1515
#define MLIR_DIALECT_GPU_GPUDIALECT_H
1616

17+
#include "mlir/IR/Builders.h"
1718
#include "mlir/IR/Dialect.h"
1819
#include "mlir/IR/FunctionSupport.h"
1920
#include "mlir/IR/OpDefinition.h"
@@ -34,13 +35,24 @@ struct KernelDim3 {
3435
Value z;
3536
};
3637

38+
class AsyncTokenType
39+
: public Type::TypeBase<AsyncTokenType, Type, TypeStorage> {
40+
public:
41+
// Used for generic hooks in TypeBase.
42+
using Base::Base;
43+
};
44+
45+
// Adds a `gpu.async.token` to the front of the argument list.
46+
void addAsyncDependency(Operation *op, Value token);
47+
3748
} // end namespace gpu
3849
} // end namespace mlir
3950

4051
#include "mlir/Dialect/GPU/GPUOpsDialect.h.inc"
4152

53+
#include "mlir/Dialect/GPU/GPUOpInterfaces.h.inc"
54+
4255
#define GET_OP_CLASSES
4356
#include "mlir/Dialect/GPU/GPUOps.h.inc"
4457

45-
4658
#endif // MLIR_DIALECT_GPU_GPUDIALECT_H

mlir/include/mlir/Dialect/GPU/GPUOps.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def GPU_GPUFuncOp : GPU_Op<"func", [HasParent<"GPUModuleOp">,
249249
return getBody().getNumArguments() - getType().getNumInputs() -
250250
getNumWorkgroupAttributions();
251251
}
252-
252+
253253
/// Returns a list of block arguments that correspond to buffers located in
254254
/// the private memory.
255255
ArrayRef<BlockArgument> getPrivateAttributions() {
@@ -301,7 +301,7 @@ def GPU_LaunchFuncOp : GPU_Op<"launch_func">,
301301
IntOrIndex:$blockSizeY, IntOrIndex:$blockSizeZ,
302302
Variadic<AnyType>:$operands)>,
303303
Results<(outs)> {
304-
let summary = "Launches a function as a GPU kerneel";
304+
let summary = "Launches a function as a GPU kernel";
305305

306306
let description = [{
307307
Launch a kernel function on the specified grid of thread blocks.

mlir/lib/Dialect/GPU/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ add_mlir_dialect_library(MLIRGPU
1010

1111
DEPENDS
1212
MLIRGPUOpsIncGen
13+
MLIRGPUOpInterfacesIncGen
1314
MLIRGPUPassIncGen
1415
MLIRParallelLoopMapperAttrGen
1516
MLIRParallelLoopMapperEnumsGen

mlir/lib/Dialect/GPU/IR/GPUDialect.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@
1616
#include "mlir/Dialect/StandardOps/IR/Ops.h"
1717
#include "mlir/IR/Attributes.h"
1818
#include "mlir/IR/Builders.h"
19-
#include "mlir/IR/Function.h"
19+
#include "mlir/IR/DialectImplementation.h"
2020
#include "mlir/IR/FunctionImplementation.h"
2121
#include "mlir/IR/Module.h"
2222
#include "mlir/IR/OpImplementation.h"
2323
#include "mlir/IR/PatternMatch.h"
2424
#include "mlir/IR/StandardTypes.h"
25+
#include "llvm/ADT/TypeSwitch.h"
2526

2627
using namespace mlir;
2728
using namespace mlir::gpu;
@@ -36,12 +37,34 @@ bool GPUDialect::isKernel(Operation *op) {
3637
}
3738

3839
void GPUDialect::initialize() {
40+
addTypes<AsyncTokenType>();
3941
addOperations<
4042
#define GET_OP_LIST
4143
#include "mlir/Dialect/GPU/GPUOps.cpp.inc"
4244
>();
4345
}
4446

47+
Type GPUDialect::parseType(DialectAsmParser &parser) const {
48+
// Parse the main keyword for the type.
49+
StringRef keyword;
50+
if (parser.parseKeyword(&keyword))
51+
return Type();
52+
MLIRContext *context = getContext();
53+
54+
// Handle 'async token' types.
55+
if (keyword == "async.token")
56+
return AsyncTokenType::get(context);
57+
58+
parser.emitError(parser.getNameLoc(), "unknown gpu type: " + keyword);
59+
return Type();
60+
}
61+
62+
void GPUDialect::printType(Type type, DialectAsmPrinter &os) const {
63+
TypeSwitch<Type>(type)
64+
.Case<AsyncTokenType>([&](Type) { os << "async.token"; })
65+
.Default([](Type) { llvm_unreachable("unexpected 'gpu' type kind"); });
66+
}
67+
4568
LogicalResult GPUDialect::verifyOperationAttribute(Operation *op,
4669
NamedAttribute attr) {
4770
if (!attr.second.isa<UnitAttr>() ||
@@ -195,6 +218,26 @@ static ParseResult parseShuffleOp(OpAsmParser &parser, OperationState &state) {
195218
return success();
196219
}
197220

221+
//===----------------------------------------------------------------------===//
222+
// AsyncOpInterface
223+
//===----------------------------------------------------------------------===//
224+
225+
void gpu::addAsyncDependency(Operation *op, Value token) {
226+
op->insertOperands(0, {token});
227+
if (!op->template hasTrait<OpTrait::AttrSizedOperandSegments>())
228+
return;
229+
auto attrName =
230+
OpTrait::AttrSizedOperandSegments<void>::getOperandSegmentSizeAttr();
231+
auto sizeAttr = op->template getAttrOfType<DenseIntElementsAttr>(attrName);
232+
if (!sizeAttr)
233+
return; // Async dependencies is the only variadic operand.
234+
SmallVector<int32_t, 8> sizes;
235+
for (auto size : sizeAttr.getIntValues())
236+
sizes.push_back(size.getSExtValue());
237+
++sizes.front();
238+
op->setAttr(attrName, Builder(op->getContext()).getI32VectorAttr(sizes));
239+
}
240+
198241
//===----------------------------------------------------------------------===//
199242
// LaunchOp
200243
//===----------------------------------------------------------------------===//
@@ -775,5 +818,7 @@ static void print(OpAsmPrinter &p, GPUModuleOp op) {
775818
/*printBlockTerminators=*/false);
776819
}
777820

821+
#include "mlir/Dialect/GPU/GPUOpInterfaces.cpp.inc"
822+
778823
#define GET_OP_CLASSES
779824
#include "mlir/Dialect/GPU/GPUOps.cpp.inc"

mlir/test/Dialect/GPU/ops.mlir

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,10 @@ module attributes {gpu.container_module} {
143143
"gpu.return"() : () -> ()
144144
} ) {gpu.kernel, sym_name = "kernel_1", type = (f32, memref<?xf32>) -> (), workgroup_attributions = 1: i64} : () -> ()
145145
}
146+
147+
func @async_token(%arg0 : !gpu.async.token) -> !gpu.async.token {
148+
// CHECK-LABEL: func @async_token({{.*}}: !gpu.async.token)
149+
// CHECK: return {{.*}} : !gpu.async.token
150+
return %arg0 : !gpu.async.token
151+
}
146152
}

0 commit comments

Comments
 (0)