[Mlir-commits] [mlir] 132c376 - [openacc] Add attribute to hold declare data clause information

Razvan Lupusoru llvmlistbot at llvm.org
Wed Jul 19 07:55:16 PDT 2023


Author: Razvan Lupusoru
Date: 2023-07-19T07:54:57-07:00
New Revision: 132c376a337e0001e997714bd8e8a69944861d86

URL: https://github.com/llvm/llvm-project/commit/132c376a337e0001e997714bd8e8a69944861d86
DIFF: https://github.com/llvm/llvm-project/commit/132c376a337e0001e997714bd8e8a69944861d86.diff

LOG: [openacc] Add attribute to hold declare data clause information

For variables in declare clauses, their producing operation should be
marked with the data clause for ease of lookup and consistency
verification. Thus add an attribute that can be used for this purpose
plus verification that declare data operation matches the declare
data clause on variable.

Reviewed By: clementval

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

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/OpenACC/OpenACC.h
    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/OpenACC.h b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
index fe7a407fe2c6fe..ff9d2c9b48a3e0 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
@@ -34,6 +34,22 @@
 #define GET_OP_CLASSES
 #include "mlir/Dialect/OpenACC/OpenACCOps.h.inc"
 
+#define ACC_DATA_ENTRY_OPS                                                     \
+  mlir::acc::CopyinOp, mlir::acc::CreateOp, mlir::acc::PresentOp,              \
+      mlir::acc::NoCreateOp, mlir::acc::AttachOp, mlir::acc::DevicePtrOp,      \
+      mlir::acc::GetDevicePtrOp, mlir::acc::PrivateOp,                         \
+      mlir::acc::FirstprivateOp, mlir::acc::UpdateDeviceOp,                    \
+      mlir::acc::UseDeviceOp, mlir::acc::ReductionOp,                          \
+      mlir::acc::DeclareDeviceResidentOp, mlir::acc::DeclareLinkOp
+#define ACC_COMPUTE_CONSTRUCT_OPS                                              \
+  mlir::acc::ParallelOp, mlir::acc::KernelsOp, mlir::acc::SerialOp
+#define ACC_DATA_CONSTRUCT_OPS                                                 \
+  mlir::acc::DataOp, mlir::acc::EnterDataOp, mlir::acc::ExitDataOp,            \
+      mlir::acc::UpdateOp, mlir::acc::HostDataOp,                              \
+      mlir::acc::DeclareEnterOp mlir::acc::DeclareExitOp
+#define ACC_COMPUTE_AND_DATA_CONSTRUCT_OPS                                     \
+  ACC_COMPUTE_CONSTRUCT_OPS, ACC_DATA_CONSTRUCT_OPS
+
 namespace mlir {
 namespace acc {
 
@@ -48,6 +64,20 @@ namespace acc {
 /// combined and the final mapping value would be 5 (4 | 1).
 enum OpenACCExecMapping { NONE = 0, VECTOR = 1, WORKER = 2, GANG = 4 };
 
+/// Used to obtain the `varPtr` from a data entry operation.
+/// Returns empty value if not a data entry operation.
+mlir::Value getVarPtr(mlir::Operation *accDataEntryOp);
+
+/// Used to obtain the `dataClause` from a data entry operation.
+/// Returns empty optional if not a data entry operation.
+std::optional<mlir::acc::DataClause>
+getDataClause(mlir::Operation *accDataEntryOp);
+
+/// Used to obtain the attribute name for declare.
+static constexpr StringLiteral getDeclareAttrName() {
+  return StringLiteral("acc.declare");
+}
+
 } // namespace acc
 } // namespace mlir
 

diff  --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
index f03b4ea4d3c445..a40ae060ca0aeb 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -116,6 +116,25 @@ def OpenACC_DataClauseEnum : I64EnumAttr<"DataClause",
 def OpenACC_DataClauseAttr : EnumAttr<OpenACC_Dialect, OpenACC_DataClauseEnum,
                                       "data_clause">;
 
+class OpenACC_Attr<string name, string attrMnemonic,
+                   list<Trait> traits = [],
+                   string baseCppClass = "::mlir::Attribute">
+    : AttrDef<OpenACC_Dialect, name, traits, baseCppClass> {
+  let mnemonic = attrMnemonic;
+}
+
+// Attribute to describe the declare data clause used on variable.
+// Intended to be used at the variable creation site (on the global op or the
+// corresponding allocation operation). This is used in conjunction with the
+// declare operations (`acc.declare_enter` and `acc.declare_exit`) since those
+// describe how the data action is performed. The attribute itself makes it
+// easier to find out whether the variable is in a declare clause and what kind
+// of clause it is.
+def DeclareAttr : OpenACC_Attr<"Declare", "declare"> {
+  let parameters = (ins "DataClauseAttr":$dataClause);
+  let assemblyFormat = "`<` struct(params) `>`";
+}
+
 // Used for data specification in data clauses (2.7.1).
 // Either (or both) extent and upperbound must be specified.
 def OpenACC_DataBoundsOp : OpenACC_Op<"bounds",

diff  --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index f166b9df2c1de3..f5d5149389c8d6 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -987,7 +987,7 @@ static LogicalResult checkDeclareOperands(Op &op,
         op->getLoc(),
         "at least one operand must appear on the declare operation");
 
-  for (mlir::Value operand : operands)
+  for (mlir::Value operand : operands) {
     if (!mlir::isa<acc::CopyinOp, acc::CopyoutOp, acc::CreateOp,
                    acc::DevicePtrOp, acc::GetDevicePtrOp, acc::PresentOp,
                    acc::DeclareDeviceResidentOp, acc::DeclareLinkOp>(
@@ -995,6 +995,32 @@ static LogicalResult checkDeclareOperands(Op &op,
       return op.emitError(
           "expect valid declare data entry operation or acc.getdeviceptr "
           "as defining op");
+
+    mlir::Value varPtr{getVarPtr(operand.getDefiningOp())};
+    assert(varPtr && "declare operands can only be data entry operations which "
+                     "must have varPtr");
+    std::optional<mlir::acc::DataClause> dataClauseOptional{
+        getDataClause(operand.getDefiningOp())};
+    assert(dataClauseOptional.has_value() &&
+           "declare operands can only be data entry operations which must have "
+           "dataClause");
+
+    // If varPtr has no defining op - there is nothing to check further.
+    if (!varPtr.getDefiningOp())
+      continue;
+
+    // Check that the varPtr has a declare attribute.
+    auto declareAttribute{
+        varPtr.getDefiningOp()->getAttr(mlir::acc::getDeclareAttrName())};
+    if (!declareAttribute)
+      return op.emitError(
+          "expect declare attribute on variable in declare operation");
+    if (llvm::cast<DataClauseAttr>(declareAttribute).getValue() !=
+        dataClauseOptional.value())
+      return op.emitError(
+          "expect matching declare attribute on variable in declare operation");
+  }
+
   return success();
 }
 
@@ -1106,3 +1132,26 @@ LogicalResult acc::WaitOp::verify() {
 
 #define GET_TYPEDEF_CLASSES
 #include "mlir/Dialect/OpenACC/OpenACCOpsTypes.cpp.inc"
+
+//===----------------------------------------------------------------------===//
+// acc dialect utilities
+//===----------------------------------------------------------------------===//
+
+mlir::Value mlir::acc::getVarPtr(mlir::Operation *accDataEntryOp) {
+  auto varPtr{llvm::TypeSwitch<mlir::Operation *, mlir::Value>(accDataEntryOp)
+                  .Case<ACC_DATA_ENTRY_OPS>(
+                      [&](auto entry) { return entry.getVarPtr(); })
+                  .Default([&](mlir::Operation *) { return mlir::Value(); })};
+  return varPtr;
+}
+
+std::optional<mlir::acc::DataClause>
+mlir::acc::getDataClause(mlir::Operation *accDataEntryOp) {
+  auto dataClause{
+      llvm::TypeSwitch<mlir::Operation *, std::optional<mlir::acc::DataClause>>(
+          accDataEntryOp)
+          .Case<ACC_DATA_ENTRY_OPS>(
+              [&](auto entry) { return entry.getDataClause(); })
+          .Default([&](mlir::Operation *) { return std::nullopt; })};
+  return dataClause;
+}

diff  --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir
index 125d26c15adc1a..af7f4f9aab25c8 100644
--- a/mlir/test/Dialect/OpenACC/ops.mlir
+++ b/mlir/test/Dialect/OpenACC/ops.mlir
@@ -1605,20 +1605,20 @@ func.func @testdeclareop(%a: memref<f32>, %b: memref<f32>, %c: memref<f32>) -> (
 
 // -----
 
-llvm.mlir.global external @globalvar() : i32 {
+llvm.mlir.global external @globalvar() { acc.declare = #acc<data_clause acc_create> } : i32 {
   %0 = llvm.mlir.constant(0 : i32) : i32
   llvm.return %0 : i32
 }
 
 acc.global_ctor @acc_constructor {
-  %0 = llvm.mlir.addressof @globalvar : !llvm.ptr<i32>
+  %0 = llvm.mlir.addressof @globalvar { acc.declare = #acc<data_clause acc_create> } : !llvm.ptr<i32>
   %1 = acc.create varPtr(%0 : !llvm.ptr<i32>) -> !llvm.ptr<i32>
   acc.declare_enter dataOperands(%1 : !llvm.ptr<i32>)
   acc.terminator
 }
 
 acc.global_dtor @acc_destructor {
-  %0 = llvm.mlir.addressof @globalvar : !llvm.ptr<i32>
+  %0 = llvm.mlir.addressof @globalvar { acc.declare = #acc<data_clause acc_create> } : !llvm.ptr<i32>
   %1 = acc.getdeviceptr varPtr(%0 : !llvm.ptr<i32>) -> !llvm.ptr<i32> { dataClause = #acc<data_clause acc_create>}
   acc.declare_exit dataOperands(%1 : !llvm.ptr<i32>)
   acc.delete accPtr(%1 : !llvm.ptr<i32>)
@@ -1626,11 +1626,11 @@ acc.global_dtor @acc_destructor {
 }
 
 // CHECK-LABEL: acc.global_ctor @acc_constructor
-// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @globalvar : !llvm.ptr<i32>
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @globalvar {acc.declare = #acc<data_clause acc_create>} : !llvm.ptr<i32>
 // CHECK-NEXT: %[[CREATE:.*]] = acc.create varPtr(%[[ADDR]] : !llvm.ptr<i32>) -> !llvm.ptr<i32>
 // CHECK-NEXT: acc.declare_enter dataOperands(%[[CREATE]] : !llvm.ptr<i32>)
 // CHECK: acc.global_dtor @acc_destructor
-// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @globalvar : !llvm.ptr<i32>
+// CHECK: %[[ADDR:.*]] = llvm.mlir.addressof @globalvar {acc.declare = #acc<data_clause acc_create>} : !llvm.ptr<i32>
 // CHECK-NEXT: %[[DELETE:.*]] = acc.getdeviceptr varPtr(%[[ADDR]] : !llvm.ptr<i32>) -> !llvm.ptr<i32> {dataClause = #acc<data_clause acc_create>}
 // CHECK-NEXT: acc.declare_exit dataOperands(%[[DELETE]] : !llvm.ptr<i32>)
 // CHECK-NEXT: acc.delete accPtr(%[[DELETE]] : !llvm.ptr<i32>)


        


More information about the Mlir-commits mailing list