[Mlir-commits] [mlir] 5ba874e - [MLIR] [OpenMP] Add basic OpenMP parallel operation

David Truby llvmlistbot at llvm.org
Wed May 27 09:16:53 PDT 2020


Author: David Truby
Date: 2020-05-27T17:16:44+01:00
New Revision: 5ba874e4724e72838dfbb3e4b40392e0b24cc6f4

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

LOG: [MLIR] [OpenMP] Add basic OpenMP parallel operation

Summary:
This includes a basic implementation for the OpenMP parallel
operation without a custom pretty-printer and parser.
The if, num_threads, private, shared, first_private, last_private,
proc_bind and default clauses are included in this implementation.

Currently the reduction clause is omitted as it is more complex and
requires analysis to see if we can share implementation with the loop
dialect. The allocate clause is also omitted.

A discussion about the design of this operation can be found here:
https://llvm.discourse.group/t/openmp-parallel-operation-design-issues/686

The current OpenMP Specification can be found here:
https://www.openmp.org/wp-content/uploads/OpenMP-API-Specification-5.0.pdf

Co-authored-by: Kiran Chandramohan <kiran.chandramohan at arm.com>

Reviewers: jdoerfert

Subscribers: mgorny, yaxunl, kristof.beyls, guansong, mehdi_amini, rriddle, jpienaar, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, Joonsoo, grosul1, frgossen, Kayjukh, llvm-commits

Tags: #llvm

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/OpenMP/CMakeLists.txt b/mlir/include/mlir/Dialect/OpenMP/CMakeLists.txt
index 0df7a04f52b9..1254bbe8b8fc 100644
--- a/mlir/include/mlir/Dialect/OpenMP/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/OpenMP/CMakeLists.txt
@@ -1,2 +1,8 @@
-add_mlir_dialect(OpenMPOps omp)
+set(LLVM_TARGET_DEFINITIONS OpenMPOps.td)
+mlir_tablegen(OpenMPOpsDialect.h.inc -gen-dialect-decls -dialect=omp)
+mlir_tablegen(OpenMPOps.h.inc -gen-op-decls)
+mlir_tablegen(OpenMPOps.cpp.inc -gen-op-defs)
+mlir_tablegen(OpenMPOpsEnums.h.inc -gen-enum-decls)
+mlir_tablegen(OpenMPOpsEnums.cpp.inc -gen-enum-defs)
 add_mlir_doc(OpenMPOps -gen-dialect-doc OpenMPDialect Dialects/)
+add_public_tablegen_target(MLIROpenMPOpsIncGen)

diff  --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.h b/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.h
index 6761b51b55b5..8f0bb93e1043 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.h
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.h
@@ -16,6 +16,8 @@
 #include "mlir/IR/Dialect.h"
 #include "mlir/IR/OpDefinition.h"
 
+#include "mlir/Dialect/OpenMP/OpenMPOpsEnums.h.inc"
+
 namespace mlir {
 namespace omp {
 

diff  --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index af5e0433ef3c..27b2110bf71e 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -18,16 +18,103 @@ include "mlir/IR/OpBase.td"
 
 def OpenMP_Dialect : Dialect {
   let name = "omp";
+  let cppNamespace = "omp";
 }
 
 class OpenMP_Op<string mnemonic, list<OpTrait> traits = []> :
       Op<OpenMP_Dialect, mnemonic, traits>;
 
-def BarrierOp : OpenMP_Op<"barrier"> {
-  let summary = "barrier construct";
+
+//===----------------------------------------------------------------------===//
+// 2.6 parallel Construct
+//===----------------------------------------------------------------------===//
+
+// Possible values for the default clause
+def ClauseDefaultPrivate : StrEnumAttrCase<"defprivate">;
+def ClauseDefaultFirstPrivate : StrEnumAttrCase<"deffirstprivate">;
+def ClauseDefaultShared : StrEnumAttrCase<"defshared">;
+def ClauseDefaultNone : StrEnumAttrCase<"defnone">;
+
+def ClauseDefault : StrEnumAttr<
+    "ClauseDefault",
+    "default clause",
+    [ClauseDefaultPrivate, ClauseDefaultFirstPrivate, ClauseDefaultShared,
+     ClauseDefaultNone]> {
+  let cppNamespace = "::mlir::omp";
+}
+
+// Possible values for the proc_bind clause
+def ClauseProcMaster : StrEnumAttrCase<"master">;
+def ClauseProcClose : StrEnumAttrCase<"close">;
+def ClauseProcSpread : StrEnumAttrCase<"spread">;
+
+def ClauseProcBind : StrEnumAttr<
+    "ClauseProcBind",
+    "procbind clause",
+    [ClauseProcMaster, ClauseProcClose, ClauseProcSpread]> {
+  let cppNamespace = "::mlir::omp";
+}
+
+def ParallelOp : OpenMP_Op<"parallel", [AttrSizedOperandSegments]> {
+  let summary = "parallel construct";
   let description = [{
-    The barrier construct specifies an explicit barrier at the point at which
-    the construct appears.
+    The parallel construct includes a region of code which is to be executed
+    by a team of threads.
+
+    The optional $if_expr_var parameter specifies a boolean result of a
+    conditional check. If this value is 1 or is not provided then the parallel
+    region runs as normal, if it is 0 then the parallel region is executed with
+    one thread.
+
+    The optional $num_threads_var parameter specifies the number of threads which
+    should be used to execute the parallel region.
+
+    The optional $default_val attribute specifies the default data sharing attribute
+    of variables used in the parallel region that are not passed explicitly as parameters
+    to the operation.
+
+    The $private_vars, $firstprivate_vars, $shared_vars and $copyin_vars parameters
+    are a variadic list of variables that specify the data sharing attribute of
+    those variables.
+
+    The optional $proc_bind_val attribute controls the thread affinity for the execution
+    of the parallel region.
+  }];
+
+  let arguments = (ins Optional<I1>:$if_expr_var,
+             Optional<AnyInteger>:$num_threads_var,
+             OptionalAttr<ClauseDefault>:$default_val,
+             Variadic<AnyType>:$private_vars,
+             Variadic<AnyType>:$firstprivate_vars,
+             Variadic<AnyType>:$shared_vars,
+             Variadic<AnyType>:$copyin_vars,
+             OptionalAttr<ClauseProcBind>:$proc_bind_val);
+
+  let regions = (region AnyRegion:$region);
+}
+
+def TerminatorOp : OpenMP_Op<"terminator", [Terminator]> {
+  let summary = "terminator for OpenMP regions.";
+  let description = [{
+    A terminator operation for regions that appear in the body of OpenMP
+    operation.  These regions are not expected to return any value so the
+    terminator takes no operands. The terminator op returns control to the
+    enclosing op.
+  }];
+
+  let parser = [{ return success(); }];
+  let printer = [{ p << getOperationName(); }];
+}
+
+//===----------------------------------------------------------------------===//
+// 2.10.4 taskyield Construct
+//===----------------------------------------------------------------------===//
+
+def TaskyieldOp : OpenMP_Op<"taskyield"> {
+  let summary = "taskyield construct";
+  let description = [{
+    The taskyield construct specifies that the current task can be suspended
+    in favor of execution of a 
diff erent task.
   }];
 
   let assemblyFormat = "attr-dict";
@@ -50,21 +137,29 @@ def FlushOp : OpenMP_Op<"flush"> {
   let assemblyFormat = "attr-dict ($varList^ `:` type($varList))?";
 }
 
-def TaskwaitOp : OpenMP_Op<"taskwait"> {
-  let summary = "taskwait construct";
+//===----------------------------------------------------------------------===//
+// 2.17.2 barrier Construct
+//===----------------------------------------------------------------------===//
+
+def BarrierOp : OpenMP_Op<"barrier"> {
+  let summary = "barrier construct";
   let description = [{
-    The taskwait construct specifies a wait on the completion of child tasks
-    of the current task.
+    The barrier construct specifies an explicit barrier at the point at which
+    the construct appears.
   }];
 
   let assemblyFormat = "attr-dict";
 }
 
-def TaskyieldOp : OpenMP_Op<"taskyield"> {
-  let summary = "taskyield construct";
+//===----------------------------------------------------------------------===//
+// 2.17.5 taskwait Construct
+//===----------------------------------------------------------------------===//
+
+def TaskwaitOp : OpenMP_Op<"taskwait"> {
+  let summary = "taskwait construct";
   let description = [{
-    The taskyield construct specifies that the current task can be suspended
-    in favor of execution of a 
diff erent task.
+    The taskwait construct specifies a wait on the completion of child tasks
+    of the current task.
   }];
 
   let assemblyFormat = "attr-dict";

diff  --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index edb1a4eb5eb4..99c592c25b83 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -11,8 +11,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Dialect/StandardOps/IR/Ops.h"
 #include "mlir/IR/OpImplementation.h"
 
+#include "llvm/ADT/StringSwitch.h"
+
+#include "mlir/Dialect/OpenMP/OpenMPOpsEnums.cpp.inc"
+
 using namespace mlir;
 using namespace mlir::omp;
 

diff  --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 8a556196b0ea..bffc82417761 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -35,3 +35,39 @@ func @omp_flush(%arg0 : !llvm.i32) -> () {
 
   return
 }
+
+func @omp_terminator() -> () {
+  // CHECK: omp.terminator
+  omp.terminator
+}
+
+func @omp_parallel(%data_var : memref<i32>, %if_cond : i1, %num_threads : si32) -> () {
+  // CHECK: omp_parallel
+  "omp.parallel" (%if_cond, %num_threads, %data_var, %data_var, %data_var, %data_var) ({
+
+  // test without if condition
+  // CHECK: omp.parallel
+    "omp.parallel"(%num_threads, %data_var, %data_var, %data_var, %data_var) ({
+      omp.terminator
+    }) {operand_segment_sizes = dense<[0,1,1,1,1,1]>: vector<6xi32>, default_val = "defshared"} : (si32, memref<i32>, memref<i32>, memref<i32>, memref<i32>) -> ()
+
+  // CHECK: omp.barrier
+    omp.barrier
+
+  // test without num_threads
+  // CHECK: omp.parallel
+    "omp.parallel"(%if_cond, %data_var, %data_var, %data_var, %data_var) ({
+      omp.terminator
+    }) {operand_segment_sizes = dense<[1,0,1,1,1,1]> : vector<6xi32>} : (i1, memref<i32>, memref<i32>, memref<i32>, memref<i32>) -> ()
+
+    omp.terminator
+  }) {operand_segment_sizes = dense<[1,1,1,1,1,1]> : vector<6xi32>, proc_bind_val = "spread"} : (i1, si32, memref<i32>, memref<i32>, memref<i32>, memref<i32>) -> ()
+
+  // test with multiple parameters for single variadic argument
+  // CHECK: omp.parallel
+  "omp.parallel" (%data_var, %data_var, %data_var, %data_var, %data_var) ({
+    omp.terminator
+  }) {operand_segment_sizes = dense<[0,0,1,2,1,1]> : vector<6xi32>} : (memref<i32>, memref<i32>, memref<i32>, memref<i32>, memref<i32>) -> ()
+
+  return
+}


        


More information about the Mlir-commits mailing list