[Mlir-commits] [mlir] 5cbe338 - [mlir][openacc] Add host_data operation

Valentin Clement llvmlistbot at llvm.org
Thu May 11 14:55:44 PDT 2023


Author: Valentin Clement
Date: 2023-05-11T14:55:25-07:00
New Revision: 5cbe3381a65c14793f660f456f6daff674ac23bd

URL: https://github.com/llvm/llvm-project/commit/5cbe3381a65c14793f660f456f6daff674ac23bd
DIFF: https://github.com/llvm/llvm-project/commit/5cbe3381a65c14793f660f456f6daff674ac23bd.diff

LOG: [mlir][openacc] Add host_data operation

The acc.host_data operation models the OpenACC
host_data construct (2.8). The host_data construct
defines a region where the address of data in device memory
available on the host. The operation is modeled in a similar way
than acc.data operation.

Reviewed By: razvanlupusoru, jeanPerier

Differential Revision: https://reviews.llvm.org/D150289

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 1479ff10356ca..5370c8fa8feb6 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -87,6 +87,7 @@ def OpenACC_GetDevicePtrClause    : I64EnumAttrCase<"acc_getdeviceptr", 16>;
 def OpenACC_UpdateHost            : I64EnumAttrCase<"acc_update_host", 17>;
 def OpenACC_UpdateSelf            : I64EnumAttrCase<"acc_update_self", 18>;
 def OpenACC_UpdateDevice          : I64EnumAttrCase<"acc_update_device", 19>;
+def OpenACC_UseDevice             : I64EnumAttrCase<"acc_use_device", 20>;
 
 def OpenACC_DataClauseEnum : I64EnumAttr<"DataClause",
     "data clauses supported by OpenACC",
@@ -96,7 +97,7 @@ def OpenACC_DataClauseEnum : I64EnumAttr<"DataClause",
      OpenACC_AttachClause, OpenACC_DetachClause, OpenACC_NoCreateClause,
      OpenACC_PrivateClause, OpenACC_FirstPrivateClause,
      OpenACC_IsDevicePtrClause, OpenACC_GetDevicePtrClause, OpenACC_UpdateHost,
-     OpenACC_UpdateSelf, OpenACC_UpdateDevice,
+     OpenACC_UpdateSelf, OpenACC_UpdateDevice, OpenACC_UseDevice,
     ]> {
   let cppNamespace = "::mlir::acc";
 }
@@ -298,6 +299,14 @@ def OpenACC_UpdateDeviceOp : OpenACC_DataEntryOp<"update_device",
   let summary = "Represents acc update device semantics.";
 }
 
+//===----------------------------------------------------------------------===//
+// 2.8 use_device clause
+//===----------------------------------------------------------------------===//
+def OpenACC_UseDeviceOp : OpenACC_DataEntryOp<"use_device",
+    "mlir::acc::DataClause::acc_use_device"> {
+  let summary = "Represents acc use_device semantics.";
+}
+
 // Data exit operation does not refer to OpenACC spec terminology, but to
 // terminology used in this dialect. It refers to data operations that will appear
 // after data or compute region. It will be used as the base of acc dialect
@@ -740,6 +749,43 @@ def OpenACC_ExitDataOp : OpenACC_Op<"exit_data", [AttrSizedOperandSegments]> {
   let hasVerifier = 1;
 }
 
+//===----------------------------------------------------------------------===//
+// 2.8 Host_Data Construct
+//===----------------------------------------------------------------------===//
+
+def OpenACC_HostDataOp : OpenACC_Op<"host_data", [AttrSizedOperandSegments]> {
+  let summary = "host_data construct";
+
+  let description = [{
+    The "acc.host_data" operation represents the OpenACC host_data construct.
+
+    Example:
+
+    ```mlir
+    %0 = acc.use_device varPtr(%a : !llvm.ptr<f32>) -> !llvm.ptr<f32>
+    acc.host_data dataOperands(%0 : !llvm.ptr<f32>) {
+
+    }
+    ```
+  }];
+
+  let arguments = (ins Optional<I1>:$ifCond,
+                       Variadic<OpenACC_PointerLikeTypeInterface>:$dataOperands,
+                       UnitAttr:$ifPresent);
+
+  let regions = (region AnyRegion:$region);
+
+  let assemblyFormat = [{
+    oilist(
+        `if` `(` $ifCond `)`
+      | `dataOperands` `(` $dataOperands `:` type($dataOperands) `)`
+    )
+    $region attr-dict-with-keyword
+  }];
+
+  let hasVerifier = 1;
+}
+
 //===----------------------------------------------------------------------===//
 // 2.9 loop Construct
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index f92b040109334..1f73fc795caa3 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -235,6 +235,18 @@ LogicalResult acc::UpdateDeviceOp::verify() {
   return success();
 }
 
+//===----------------------------------------------------------------------===//
+// UseDeviceOp
+//===----------------------------------------------------------------------===//
+LogicalResult acc::UseDeviceOp::verify() {
+  // Test for all clauses this operation can be decomposed from:
+  if (getDataClause() != acc::DataClause::acc_use_device)
+    return emitError(
+        "data clause associated with use_device operation must match its intent"
+        " or specify original clause this operation was decomposed from");
+  return success();
+}
+
 template <typename StructureOp>
 static ParseResult parseRegions(OpAsmParser &parser, OperationState &state,
                                 unsigned nRegions = 1) {
@@ -359,6 +371,21 @@ LogicalResult acc::KernelsOp::verify() {
   return checkDataOperands<acc::KernelsOp>(*this, getDataClauseOperands());
 }
 
+//===----------------------------------------------------------------------===//
+// HostDataOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult acc::HostDataOp::verify() {
+  if (getDataOperands().empty())
+    return emitError("at least one operand must appear on the host_data "
+                     "operation");
+
+  for (mlir::Value operand : getDataOperands())
+    if (!mlir::isa<acc::UseDeviceOp>(operand.getDefiningOp()))
+      return emitError("expect data entry operation as defining op");
+  return success();
+}
+
 //===----------------------------------------------------------------------===//
 // LoopOp
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir
index 7260c05d3aaeb..3c35219de03b7 100644
--- a/mlir/test/Dialect/OpenACC/ops.mlir
+++ b/mlir/test/Dialect/OpenACC/ops.mlir
@@ -1266,3 +1266,24 @@ func.func @host_device_ops(%a: memref<f32>) -> () {
 // CHECK: acc.update dataOperands(%[[DEVPTR_A]] : memref<f32>)
 // CHECK: %[[DEVPTR_A:.*]] = acc.update_device varPtr(%[[A]] : memref<f32>)   -> memref<f32>
 // CHECK: acc.update dataOperands(%[[DEVPTR_A]] : memref<f32>)
+
+// -----
+
+func.func @host_data_ops(%a: !llvm.ptr<f32>, %ifCond: i1) -> () {
+  %0 = acc.use_device varPtr(%a : !llvm.ptr<f32>) -> !llvm.ptr<f32>
+  acc.host_data dataOperands(%0: !llvm.ptr<f32>) {
+  }
+  acc.host_data dataOperands(%0: !llvm.ptr<f32>) {
+  } attributes {if_present}
+  acc.host_data if(%ifCond) dataOperands(%0: !llvm.ptr<f32>) {
+  }
+  return
+}
+
+// CHECK-LABEL: func.func @host_data_ops(
+// CHECK-SAME:    %[[A:.*]]: !llvm.ptr<f32>, %[[IFCOND:.*]]: i1)
+// CHECK: %[[PTR:.*]] = acc.use_device varPtr(%[[A]] : !llvm.ptr<f32>) -> !llvm.ptr<f32>
+// CHECK: acc.host_data dataOperands(%[[PTR]] : !llvm.ptr<f32>)
+// CHECK: acc.host_data dataOperands(%[[PTR]] : !llvm.ptr<f32>) {
+// CHECK: } attributes {if_present}
+// CHECK: acc.host_data if(%[[IFCOND]]) dataOperands(%[[PTR]] : !llvm.ptr<f32>)


        


More information about the Mlir-commits mailing list