[Mlir-commits] [mlir] 81bcc62 - [MLIR][OpenMP] Added map clause support for Target

Akash Banerjee llvmlistbot at llvm.org
Tue Apr 11 08:33:48 PDT 2023


Author: Akash Banerjee
Date: 2023-04-11T16:33:39+01:00
New Revision: 81bcc62d0da0e1dd3b4d65e12b146a86ac00007c

URL: https://github.com/llvm/llvm-project/commit/81bcc62d0da0e1dd3b4d65e12b146a86ac00007c
DIFF: https://github.com/llvm/llvm-project/commit/81bcc62d0da0e1dd3b4d65e12b146a86ac00007c.diff

LOG: [MLIR][OpenMP] Added map clause support for Target

Added map clause support for the OMP Target directive with test.

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

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
    mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
    mlir/test/Dialect/OpenMP/invalid.mlir
    mlir/test/Dialect/OpenMP/ops.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index e20d467f0df63..f45781a978900 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -45,10 +45,10 @@ class OpenMP_Attr<string name, string attrMnemonic,
 }
 
 def IsDeviceAttr : OpenMP_Attr<"IsDevice", "isdevice"> {
-  let parameters = (ins 
+  let parameters = (ins
     "bool":$is_device
   );
-  
+
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
@@ -57,14 +57,14 @@ def IsDeviceAttr : OpenMP_Attr<"IsDevice", "isdevice"> {
 //===----------------------------------------------------------------------===//
 
 def FlagsAttr : OpenMP_Attr<"Flags", "flags"> {
-  let parameters = (ins 
+  let parameters = (ins
     DefaultValuedParameter<"uint32_t", "0">:$debug_kind,
     DefaultValuedParameter<"bool", "false">:$assume_teams_oversubscription,
     DefaultValuedParameter<"bool", "false">:$assume_threads_oversubscription,
     DefaultValuedParameter<"bool", "false">:$assume_no_thread_state,
     DefaultValuedParameter<"bool", "false">:$assume_no_nested_parallelism
   );
-  
+
   let assemblyFormat = "`<` struct(params) `>`";
 }
 
@@ -1065,24 +1065,29 @@ def TargetOp : OpenMP_Op<"target",[AttrSizedOperandSegments]> {
     The optional $nowait elliminates the implicit barrier so the parent task can make progress
     even if the target task is not yet completed.
 
-    TODO:  map, is_device_ptr, depend, defaultmap, in_reduction
+    TODO:  is_device_ptr, depend, defaultmap, in_reduction
 
   }];
 
   let arguments = (ins Optional<I1>:$if_expr,
                        Optional<AnyInteger>:$device,
                        Optional<AnyInteger>:$thread_limit,
-                       UnitAttr:$nowait);
+                       UnitAttr:$nowait,
+                       Variadic<OpenMP_PointerLikeType>:$map_operands,
+                       OptionalAttr<I64ArrayAttr>:$map_types);
 
   let regions = (region AnyRegion:$region);
 
   let assemblyFormat = [{
     oilist( `if` `(` $if_expr `)`
-          | `device` `(` $device `:` type($device) `)`
-          | `thread_limit` `(` $thread_limit `:` type($thread_limit) `)`
-          | `nowait` $nowait
+    | `device` `(` $device `:` type($device) `)`
+    | `thread_limit` `(` $thread_limit `:` type($thread_limit) `)`
+    | `nowait` $nowait
+    | `map` `(` custom<MapClause>($map_operands, type($map_operands), $map_types) `)`
     ) $region attr-dict
   }];
+
+  let hasVerifier = 1;
 }
 
 

diff  --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 1b5c15fccfad4..799ae2e0dc056 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -622,7 +622,7 @@ static LogicalResult verifySynchronizationHint(Operation *op, uint64_t hint) {
 }
 
 //===----------------------------------------------------------------------===//
-// Parser, printer and verifier for Target Data
+// Parser, printer and verifier for Target
 //===----------------------------------------------------------------------===//
 /// Parses a Map Clause.
 ///
@@ -756,7 +756,7 @@ static void printMapClause(OpAsmPrinter &p, Operation *op,
 }
 
 static LogicalResult verifyMapClause(Operation *op, OperandRange map_operands,
-                                     ArrayAttr map_types) {
+                                     std::optional<ArrayAttr> map_types) {
   // Helper function to get bitwise AND of `value` and 'flag'
   auto bitAnd = [](int64_t value,
                    llvm::omp::OpenMPOffloadMappingFlags flag) -> bool {
@@ -765,10 +765,13 @@ static LogicalResult verifyMapClause(Operation *op, OperandRange map_operands,
                std::underlying_type_t<llvm::omp::OpenMPOffloadMappingFlags>>(
                flag);
   };
-  if (map_operands.size() != map_types.size())
+  if (!map_types.has_value())
+    return success();
+
+  if (map_operands.size() != map_types->size())
     return failure();
 
-  for (const auto &mapTypeOp : map_types) {
+  for (const auto &mapTypeOp : *map_types) {
     int64_t mapTypeBits = 0x00;
 
     if (!mapTypeOp.isa<mlir::IntegerAttr>())
@@ -783,12 +786,14 @@ static LogicalResult verifyMapClause(Operation *op, OperandRange map_operands,
     bool del = bitAnd(mapTypeBits,
                       llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE);
 
-    if (isa<DataOp>(op) && del)
-      return failure();
+    if ((isa<DataOp>(op) || isa<TargetOp>(op)) && del)
+      return emitError(op->getLoc(),
+                       "to, from, tofrom and alloc map types are permitted");
     if (isa<EnterDataOp>(op) && (from || del))
-      return failure();
+      return emitError(op->getLoc(), "to and alloc map types are permitted");
     if (isa<ExitDataOp>(op) && to)
-      return failure();
+      return emitError(op->getLoc(),
+                       "from, release and delete map types are permitted");
   }
 
   return success();
@@ -806,6 +811,10 @@ LogicalResult ExitDataOp::verify() {
   return verifyMapClause(*this, getMapOperands(), getMapTypes());
 }
 
+LogicalResult TargetOp::verify() {
+  return verifyMapClause(*this, getMapOperands(), getMapTypes());
+}
+
 //===----------------------------------------------------------------------===//
 // ParallelOp
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index bdc935dd229a9..a3f0048a11c0b 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -1560,4 +1560,36 @@ func.func @omp_threadprivate() {
   return
 }
 
+// -----
+
+func.func @omp_target(%map1: memref<?xi32>) {
+  // expected-error @below {{to, from, tofrom and alloc map types are permitted}}
+  omp.target map((delete -> %map1 : memref<?xi32>)){}
+  return
+}
+
+// -----
+
+func.func @omp_target_data(%map1: memref<?xi32>) {
+  // expected-error @below {{to, from, tofrom and alloc map types are permitted}}
+  omp.target_data map((delete -> %map1 : memref<?xi32>)){}
+  return
+}
+
+// -----
+
+func.func @omp_target_enter_data(%map1: memref<?xi32>) {
+  // expected-error @below {{to and alloc map types are permitted}}
+  omp.target_enter_data map((from -> %map1 : memref<?xi32>)){}
+  return
+}
+
+// -----
+
+func.func @omp_target_exit_data(%map1: memref<?xi32>) {
+  // expected-error @below {{from, release and delete map types are permitted}}
+  omp.target_exit_data map((to -> %map1 : memref<?xi32>)){}
+  return
+}
+
 llvm.mlir.global internal @_QFsubEx() : i32

diff  --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 411a4c722b6f0..c9832f80369f8 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -480,14 +480,21 @@ func.func @omp_simdloop_pretty_multiple(%lb1 : index, %ub1 : index, %step1 : ind
 }
 
 // CHECK-LABEL: omp_target
-func.func @omp_target(%if_cond : i1, %device : si32,  %num_threads : i32) -> () {
+func.func @omp_target(%if_cond : i1, %device : si32,  %num_threads : i32, %map1: memref<?xi32>, %map2: memref<?xi32>) -> () {
 
     // Test with optional operands; if_expr, device, thread_limit, private, firstprivate and nowait.
     // CHECK: omp.target if({{.*}}) device({{.*}}) thread_limit({{.*}}) nowait
     "omp.target"(%if_cond, %device, %num_threads) ({
        // CHECK: omp.terminator
        omp.terminator
-    }) {nowait, operand_segment_sizes = array<i32: 1,1,1>} : ( i1, si32, i32 ) -> ()
+    }) {nowait, operand_segment_sizes = array<i32: 1,1,1,0>} : ( i1, si32, i32 ) -> ()
+
+    // Test with optional map clause.
+    // CHECK: omp.target map((tofrom -> %{{.*}} : memref<?xi32>), (alloc -> %{{.*}} : memref<?xi32>)) {
+    omp.target map((tofrom -> %map1 : memref<?xi32>), (alloc -> %map2 : memref<?xi32>)){}
+
+    // CHECK: omp.target map((to -> %{{.*}} : memref<?xi32>), (always, from -> %{{.*}} : memref<?xi32>)) {
+    omp.target map((to -> %map1 : memref<?xi32>), (always, from -> %map2 : memref<?xi32>)){}
 
     // CHECK: omp.barrier
     omp.barrier


        


More information about the Mlir-commits mailing list