[Mlir-commits] [mlir] d56b74e - [mlir][openacc] Add acc.kernels operation
Valentin Clement
llvmlistbot at llvm.org
Fri Apr 14 08:30:30 PDT 2023
Author: Valentin Clement
Date: 2023-04-14T08:30:23-07:00
New Revision: d56b74eac0afeabd7c02cbbead04ab567cdac28c
URL: https://github.com/llvm/llvm-project/commit/d56b74eac0afeabd7c02cbbead04ab567cdac28c
DIFF: https://github.com/llvm/llvm-project/commit/d56b74eac0afeabd7c02cbbead04ab567cdac28c.diff
LOG: [mlir][openacc] Add acc.kernels operation
The acc.kernels operation models the OpenACC kernels construct.
The kernels construct defines a region of a program that is
compiled into a sequence of kernels to be executed on the current device.
The operation is modelled on the acc.parallel operation and will
receive similar updates when the data operands operations will
be implemented.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D148277
Added:
Modified:
mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
mlir/test/Dialect/OpenACC/ops.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
index 2bc4267972e37..b2b3caf10bf7d 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -238,6 +238,87 @@ def OpenACC_SerialOp : OpenACC_Op<"serial", [AttrSizedOperandSegments]> {
}];
}
+//===----------------------------------------------------------------------===//
+// 2.5.1 kernels Construct
+//===----------------------------------------------------------------------===//
+
+def OpenACC_KernelsOp : OpenACC_Op<"kernels", [AttrSizedOperandSegments]> {
+ let summary = "kernels construct";
+ let description = [{
+ The "acc.kernels" operation represents a kernels construct block. It has
+ one region to be compiled into a sequence of kernels for execution on the
+ current device.
+
+ Example:
+
+ ```mlir
+ acc.kernels num_gangs(%c10) num_workers(%c10)
+ private(%c : memref<10xf32>) {
+ // kernels region
+ }
+ ```
+ }];
+
+ let arguments = (ins Optional<IntOrIndex>:$async,
+ UnitAttr:$asyncAttr,
+ Variadic<IntOrIndex>:$waitOperands,
+ UnitAttr:$waitAttr,
+ Optional<IntOrIndex>:$numGangs,
+ Optional<IntOrIndex>:$numWorkers,
+ Optional<IntOrIndex>:$vectorLength,
+ Optional<I1>:$ifCond,
+ Optional<I1>:$selfCond,
+ UnitAttr:$selfAttr,
+ Variadic<AnyType>:$copyOperands,
+ Variadic<AnyType>:$copyinOperands,
+ Variadic<AnyType>:$copyinReadonlyOperands,
+ Variadic<AnyType>:$copyoutOperands,
+ Variadic<AnyType>:$copyoutZeroOperands,
+ Variadic<AnyType>:$createOperands,
+ Variadic<AnyType>:$createZeroOperands,
+ Variadic<AnyType>:$noCreateOperands,
+ Variadic<AnyType>:$presentOperands,
+ Variadic<AnyType>:$devicePtrOperands,
+ Variadic<AnyType>:$attachOperands,
+ OptionalAttr<DefaultValueAttr>:$defaultAttr);
+
+ let regions = (region AnyRegion:$region);
+
+ let extraClassDeclaration = [{
+ /// The number of data operands.
+ unsigned getNumDataOperands();
+
+ /// The i-th data operand passed.
+ Value getDataOperand(unsigned i);
+ }];
+
+ let assemblyFormat = [{
+ oilist(
+ `attach` `(` $attachOperands `:` type($attachOperands) `)`
+ | `async` `(` $async `:` type($async) `)`
+ | `copy` `(` $copyOperands `:` type($copyOperands) `)`
+ | `copyin` `(` $copyinOperands `:` type($copyinOperands) `)`
+ | `copyin_readonly` `(` $copyinReadonlyOperands `:`
+ type($copyinReadonlyOperands) `)`
+ | `copyout` `(` $copyoutOperands `:` type($copyoutOperands) `)`
+ | `copyout_zero` `(` $copyoutZeroOperands `:`
+ type($copyoutZeroOperands) `)`
+ | `create` `(` $createOperands `:` type($createOperands) `)`
+ | `create_zero` `(` $createZeroOperands `:` type($createZeroOperands) `)`
+ | `deviceptr` `(` $devicePtrOperands `:` type($devicePtrOperands) `)`
+ | `no_create` `(` $noCreateOperands `:` type($noCreateOperands) `)`
+ | `num_gangs` `(` $numGangs `:` type($numGangs) `)`
+ | `num_workers` `(` $numWorkers `:` type($numWorkers) `)`
+ | `present` `(` $presentOperands `:` type($presentOperands) `)`
+ | `vector_length` `(` $vectorLength `:` type($vectorLength) `)`
+ | `wait` `(` $waitOperands `:` type($waitOperands) `)`
+ | `self` `(` $selfCond `)`
+ | `if` `(` $ifCond `)`
+ )
+ $region attr-dict-with-keyword
+ }];
+}
+
//===----------------------------------------------------------------------===//
// 2.6.5 data Construct
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index 1dbb0442978aa..82b358d659a24 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -208,6 +208,26 @@ Value SerialOp::getDataOperand(unsigned i) {
return getOperand(getWaitOperands().size() + numOptional + i);
}
+//===----------------------------------------------------------------------===//
+// KernelsOp
+//===----------------------------------------------------------------------===//
+
+unsigned KernelsOp::getNumDataOperands() {
+ return getCopyOperands().size() + getCopyinOperands().size() +
+ getCopyinReadonlyOperands().size() + getCopyoutOperands().size() +
+ getCopyoutZeroOperands().size() + getCreateOperands().size() +
+ getCreateZeroOperands().size() + getNoCreateOperands().size() +
+ getPresentOperands().size() + getDevicePtrOperands().size() +
+ getAttachOperands().size();
+}
+
+Value KernelsOp::getDataOperand(unsigned i) {
+ unsigned numOptional = getAsync() ? 1 : 0;
+ numOptional += getIfCond() ? 1 : 0;
+ numOptional += getSelfCond() ? 1 : 0;
+ return getOperand(getWaitOperands().size() + numOptional + i);
+}
+
//===----------------------------------------------------------------------===//
// LoopOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir
index be014fd374ef3..c1eaa499496e0 100644
--- a/mlir/test/Dialect/OpenACC/ops.mlir
+++ b/mlir/test/Dialect/OpenACC/ops.mlir
@@ -586,6 +586,103 @@ func.func @testserialop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10
// -----
+
+func.func @testserialop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {
+ %i64value = arith.constant 1 : i64
+ %i32value = arith.constant 1 : i32
+ %idxValue = arith.constant 1 : index
+ acc.kernels async(%i64value: i64) {
+ }
+ acc.kernels async(%i32value: i32) {
+ }
+ acc.kernels async(%idxValue: index) {
+ }
+ acc.kernels wait(%i64value: i64) {
+ }
+ acc.kernels wait(%i32value: i32) {
+ }
+ acc.kernels wait(%idxValue: index) {
+ }
+ acc.kernels wait(%i64value, %i32value, %idxValue : i64, i32, index) {
+ }
+ acc.kernels copyin(%a, %b : memref<10xf32>, memref<10xf32>) {
+ }
+ acc.kernels copyin_readonly(%a, %b : memref<10xf32>, memref<10xf32>) {
+ }
+ acc.kernels copyin(%a: memref<10xf32>) copyout_zero(%b, %c : memref<10xf32>, memref<10x10xf32>) {
+ }
+ acc.kernels copyout(%b, %c : memref<10xf32>, memref<10x10xf32>) create(%a: memref<10xf32>) {
+ }
+ acc.kernels copyout_zero(%b, %c : memref<10xf32>, memref<10x10xf32>) create_zero(%a: memref<10xf32>) {
+ }
+ acc.kernels no_create(%a: memref<10xf32>) present(%b, %c : memref<10xf32>, memref<10x10xf32>) {
+ }
+ acc.kernels deviceptr(%a: memref<10xf32>) attach(%b, %c : memref<10xf32>, memref<10x10xf32>) {
+ }
+ acc.kernels {
+ } attributes {defaultAttr = #acc<defaultvalue none>}
+ acc.kernels {
+ } attributes {defaultAttr = #acc<defaultvalue present>}
+ acc.kernels {
+ } attributes {asyncAttr}
+ acc.kernels {
+ } attributes {waitAttr}
+ acc.kernels {
+ } attributes {selfAttr}
+ acc.kernels {
+ acc.terminator
+ } attributes {selfAttr}
+ return
+}
+
+// CHECK: func @testserialop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) {
+// CHECK: [[I64VALUE:%.*]] = arith.constant 1 : i64
+// CHECK: [[I32VALUE:%.*]] = arith.constant 1 : i32
+// CHECK: [[IDXVALUE:%.*]] = arith.constant 1 : index
+// CHECK: acc.kernels async([[I64VALUE]] : i64) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels async([[I32VALUE]] : i32) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels async([[IDXVALUE]] : index) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels wait([[I64VALUE]] : i64) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels wait([[I32VALUE]] : i32) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels wait([[IDXVALUE]] : index) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels wait([[I64VALUE]], [[I32VALUE]], [[IDXVALUE]] : i64, i32, index) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels copyin([[ARGA]], [[ARGB]] : memref<10xf32>, memref<10xf32>) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels copyin_readonly([[ARGA]], [[ARGB]] : memref<10xf32>, memref<10xf32>) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels copyin([[ARGA]] : memref<10xf32>) copyout_zero([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels copyout([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) create([[ARGA]] : memref<10xf32>) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels copyout_zero([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) create_zero([[ARGA]] : memref<10xf32>) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels no_create([[ARGA]] : memref<10xf32>) present([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels attach([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) deviceptr([[ARGA]] : memref<10xf32>) {
+// CHECK-NEXT: }
+// CHECK: acc.kernels {
+// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>}
+// CHECK: acc.kernels {
+// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue present>}
+// CHECK: acc.kernels {
+// CHECK-NEXT: } attributes {asyncAttr}
+// CHECK: acc.kernels {
+// CHECK-NEXT: } attributes {waitAttr}
+// CHECK: acc.kernels {
+// CHECK-NEXT: } attributes {selfAttr}
+// CHECK: acc.kernels {
+// CHECK: acc.terminator
+// CHECK-NEXT: } attributes {selfAttr}
+
+// -----
+
func.func @testdataop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () {
%ifCond = arith.constant true
acc.data if(%ifCond) present(%a : memref<10xf32>) {
More information about the Mlir-commits
mailing list