diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -238,6 +238,87 @@ }]; } +//===----------------------------------------------------------------------===// +// 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:$async, + UnitAttr:$asyncAttr, + Variadic:$waitOperands, + UnitAttr:$waitAttr, + Optional:$numGangs, + Optional:$numWorkers, + Optional:$vectorLength, + Optional:$ifCond, + Optional:$selfCond, + UnitAttr:$selfAttr, + Variadic:$copyOperands, + Variadic:$copyinOperands, + Variadic:$copyinReadonlyOperands, + Variadic:$copyoutOperands, + Variadic:$copyoutZeroOperands, + Variadic:$createOperands, + Variadic:$createZeroOperands, + Variadic:$noCreateOperands, + Variadic:$presentOperands, + Variadic:$devicePtrOperands, + Variadic:$attachOperands, + OptionalAttr:$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 --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -208,6 +208,26 @@ 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 --- 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<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} + acc.kernels { + } attributes {defaultAttr = #acc} + 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} +// CHECK: acc.kernels { +// CHECK-NEXT: } attributes {defaultAttr = #acc} +// 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>) {