[Mlir-commits] [mlir] [OpenACC] add acc::ReductionAccumulateArrayOp (PR #205617)

Scott Manley llvmlistbot at llvm.org
Wed Jun 24 10:53:25 PDT 2026


https://github.com/rscottmanley created https://github.com/llvm/llvm-project/pull/205617

Add an OpenACC Dialect operation to accumulate elements of a (private) array across threads. This operation only specifies the PointerLikeType and an acc::DataBoundsOp to represent the accumulation of the array at a high level. This will ultimately get lowered by "codegen".

>From 94511ee5189143da775aa6c1b4923fffddecdddf Mon Sep 17 00:00:00 2001
From: Scott Manley <scmanley at nvidia.com>
Date: Wed, 24 Jun 2026 10:32:03 -0700
Subject: [PATCH] [OpenACC] add acc::ReductionAccumulateArrayOp

Add an OpenACC Dialect operation to accumulate elements of a (private)
array across threads. This operation only specifies the PointerLikeType
and an acc::DataBoundsOp to represent the accumulation of the array at
a high level. This will ultimately get lowered by "codegen".
---
 .../mlir/Dialect/OpenACC/OpenACCCGOps.td      | 22 +++++++++++++++++++
 mlir/lib/Dialect/OpenACC/IR/OpenACCCG.cpp     | 10 +++++++++
 mlir/test/Dialect/OpenACC/invalid-cg.mlir     | 19 ++++++++++++++++
 mlir/test/Dialect/OpenACC/ops-cg.mlir         |  9 ++++++++
 4 files changed, 60 insertions(+)

diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
index 26fb6c10e51e6..d5bdd8e8115c5 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
@@ -170,6 +170,28 @@ def OpenACC_ReductionAccumulateOp
   let hasVerifier = 1;
 }
 
+//===----------------------------------------------------------------------===//
+// acc.reduction_accumulate_array
+//===----------------------------------------------------------------------===//
+
+def OpenACC_ReductionAccumulateArrayOp
+    : OpenACC_Op<"reduction_accumulate_array", []> {
+  let summary = "Accumulates elements of an array";
+  let description = [{
+    Accumulates elements of an array across threads given an acc.bounds op.
+  }];
+  let arguments = (ins Arg<OpenACC_PointerLikeTypeInterface,
+                           "Reduction variable to update",
+                           [MemRead, MemWrite]>:$memref,
+                       OpenACC_DataBoundsType:$bounds,
+                       OpenACC_ReductionOperatorAttr:$reductionOperator,
+                       OpenACC_GPUParallelDimsAttr:$par_dims);
+  let assemblyFormat = [{
+    $memref `bounds` `(` $bounds `)` $reductionOperator `:` type($memref) attr-dict
+  }];
+  let hasVerifier = 1;
+}
+
 //===----------------------------------------------------------------------===//
 // acc.kernel_environment
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACCCG.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACCCG.cpp
index a3c43a6867868..953acb7b7826e 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACCCG.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACCCG.cpp
@@ -485,6 +485,16 @@ LogicalResult ReductionAccumulateOp::verify() {
   return success();
 }
 
+//===----------------------------------------------------------------------===//
+// ReductionAccumulateArrayOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult ReductionAccumulateArrayOp::verify() {
+  if (getParDims().getArray().empty())
+    return emitOpError("par_dims must specify at least one parallel dimension");
+  return success();
+}
+
 //===----------------------------------------------------------------------===//
 // ReductionCombineOp
 //===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/OpenACC/invalid-cg.mlir b/mlir/test/Dialect/OpenACC/invalid-cg.mlir
index da280bda8ea91..b37d2da406ee2 100644
--- a/mlir/test/Dialect/OpenACC/invalid-cg.mlir
+++ b/mlir/test/Dialect/OpenACC/invalid-cg.mlir
@@ -75,6 +75,25 @@ func.func @reduction_accumulate_empty_par_dims() {
 
 // -----
 
+func.func @reduction_accumulate_array_invalid_operator(%private: memref<4xi32>, %bounds: !acc.data_bounds_ty) {
+  acc.reduction_accumulate_array %private bounds(%bounds) <addi>
+      : memref<4xi32> {par_dims = #acc<par_dims[thread_x]>}
+  // expected-error at -2 {{expected ::mlir::acc::ReductionOperator to be one of}}
+  // expected-error at -3 {{failed to parse OpenACC_ReductionOperatorAttr}}
+  return
+}
+
+// -----
+
+func.func @reduction_accumulate_array_empty_par_dims(%private: memref<4xi32>, %bounds: !acc.data_bounds_ty) {
+  // expected-error at +1 {{par_dims must specify at least one parallel dimension}}
+  acc.reduction_accumulate_array %private bounds(%bounds) <add>
+      : memref<4xi32> {par_dims = #acc<par_dims[]>}
+  return
+}
+
+// -----
+
 func.func @predicate_region_empty() {
   acc.compute_region {
     // expected-error at +1 {{region needs to have at least one block}}
diff --git a/mlir/test/Dialect/OpenACC/ops-cg.mlir b/mlir/test/Dialect/OpenACC/ops-cg.mlir
index 52ca1a38ebb73..6e5582a709bfe 100644
--- a/mlir/test/Dialect/OpenACC/ops-cg.mlir
+++ b/mlir/test/Dialect/OpenACC/ops-cg.mlir
@@ -320,6 +320,15 @@ func.func @reduction_accumulate_block_thread(%partial: i32, %private: memref<i32
 
 // -----
 
+// CHECK-LABEL: func @reduction_accumulate_array
+func.func @reduction_accumulate_array(%private: memref<4xi32>, %bounds: !acc.data_bounds_ty) {
+  acc.reduction_accumulate_array %private bounds(%bounds) <add> : memref<4xi32> {par_dims = #acc<par_dims[block_x, thread_x]>}
+  return
+}
+// CHECK: acc.reduction_accumulate_array  %{{.*}} bounds(%{{.*}}) <add> : memref<4xi32> {par_dims = #acc<par_dims[block_x, thread_x]>}
+
+// -----
+
 // CHECK-LABEL: func @compute_region_with_results
 func.func @compute_region_with_results() -> i32 {
   %w0 = acc.par_width {par_dim = #acc.par_dim<thread_x>}



More information about the Mlir-commits mailing list