[Mlir-commits] [mlir] [OpenACC] apply par dims to reductions in parallel regions (PR #208258)
Scott Manley
llvmlistbot at llvm.org
Wed Jul 8 13:48:28 PDT 2026
https://github.com/rscottmanley updated https://github.com/llvm/llvm-project/pull/208258
>From aad6dde1b961cf5cb2d3c57660e597ea95986f45 Mon Sep 17 00:00:00 2001
From: Scott Manley <scmanley at nvidia.com>
Date: Wed, 8 Jul 2026 09:16:06 -0700
Subject: [PATCH 1/2] [OpenACC] apply par dims to reductions in parallel
regions
For reductions that come from parallel constructs, explicitly set the
GPU parallel dimensions attribute to blockXDim since they will always be
gang private.
---
.../OpenACC/Transforms/ACCRecipeMaterialization.cpp | 12 ++++++++++++
.../acc-recipe-materialization-reduction.mlir | 4 ++--
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCRecipeMaterialization.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCRecipeMaterialization.cpp
index 398f4d4bbfdf6..d2f7d9e1cb80e 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCRecipeMaterialization.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCRecipeMaterialization.cpp
@@ -44,6 +44,7 @@
#include "mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
+#include "mlir/Dialect/OpenACC/OpenACCUtilsCG.h"
#include "mlir/Dialect/OpenACC/OpenACCUtilsLoop.h"
#include "mlir/Dialect/OpenACC/Transforms/Passes.h"
#include "mlir/IR/Block.h"
@@ -380,6 +381,17 @@ ACCRecipeMaterialization::materialize(OpTy op, RecipeOpTy recipe, AccOpTy accOp,
cloneRegionIntoAccRegion(&combinerRegion, &combineRegionOp.getRegion(),
/*hasResult=*/false);
+ // For reductions that come from parallel constructs, explicitly set the
+ // GPU parallel dimensions attribute to blockXDim since they will always be
+ // gang private. GPU parallel dimensions cannot be determined for acc.loop
+ // at this point.
+ if constexpr (std::is_same_v<AccOpTy, acc::ParallelOp>) {
+ auto gpuParDimsAttr = acc::GPUParallelDimsAttr::get(b.getContext(),
+ {acc::GPUParallelDimAttr::blockXDim(b.getContext())});
+ acc::setParDimsAttr(reductionOp, gpuParDimsAttr);
+ acc::setParDimsAttr(combineRegionOp, gpuParDimsAttr);
+ }
+
auto setSeqParDimsForRecipeLoops = [](Region *r) {
r->walk([](LoopLikeOpInterface loopLike) {
loopLike->setAttr(
diff --git a/mlir/test/Dialect/OpenACC/acc-recipe-materialization-reduction.mlir b/mlir/test/Dialect/OpenACC/acc-recipe-materialization-reduction.mlir
index 083a6839b7d0a..6f2bafb2b6165 100644
--- a/mlir/test/Dialect/OpenACC/acc-recipe-materialization-reduction.mlir
+++ b/mlir/test/Dialect/OpenACC/acc-recipe-materialization-reduction.mlir
@@ -28,7 +28,7 @@ acc.reduction.recipe @reduction_add_memref_f64 : memref<f64> reduction_operator
// CHECK-NEXT: [[ALLOCA:%.*]] = memref.alloca() : memref<f64>
// CHECK-NEXT: memref.store [[ZERO]], [[ALLOCA]][]
// CHECK-NEXT: acc.yield {{.*}}
-// CHECK: } {{.*}}acc.var_name = #acc.var_name<"tmp">
+// CHECK: } {{.*}}acc.par_dims = #acc<par_dims[block_x]>, acc.var_name = #acc.var_name<"tmp">
// CHECK: memref.load [[PRIVATE]][]
// CHECK: memref.store {{.*}}, [[PRIVATE]][]
// CHECK: acc.reduction_combine_region [[PRIVATE]] into [[REDUCVAR:%.*]] : memref<f64> {
@@ -36,7 +36,7 @@ acc.reduction.recipe @reduction_add_memref_f64 : memref<f64> reduction_operator
// CHECK-NEXT: [[LOADPRIV:%.*]] = memref.load [[PRIVATE]][]
// CHECK-NEXT: [[COMBINE:%.*]] = arith.addf [[LOADVAR]], [[LOADPRIV]]
// CHECK-NEXT: memref.store [[COMBINE]], [[REDUCVAR]][]
-// CHECK-NEXT: }
+// CHECK-NEXT: } {acc.par_dims = #acc<par_dims[block_x]>}
// CHECK-NEXT: memref.dealloc [[PRIVATE]] : memref<f64>
// CHECK: acc.yield
>From d3aac4c4088dde504e61bc2e2b17ec9e378c45e7 Mon Sep 17 00:00:00 2001
From: Scott Manley <scmanley at nvidia.com>
Date: Wed, 8 Jul 2026 09:41:18 -0700
Subject: [PATCH 2/2] format
---
.../Transforms/ACCRecipeMaterialization.cpp | 49 +++++++++++--------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCRecipeMaterialization.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCRecipeMaterialization.cpp
index d2f7d9e1cb80e..d2e8d77c168d1 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCRecipeMaterialization.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCRecipeMaterialization.cpp
@@ -43,6 +43,7 @@
#include "mlir/Dialect/Arith/Utils/Utils.h"
#include "mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/Dialect/OpenACC/OpenACCParMapping.h"
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
#include "mlir/Dialect/OpenACC/OpenACCUtilsCG.h"
#include "mlir/Dialect/OpenACC/OpenACCUtilsLoop.h"
@@ -182,10 +183,11 @@ class ACCRecipeMaterialization
void removeRecipe(OpTy op, ModuleOp moduleOp) const;
template <typename OpTy, typename RecipeOpTy, typename AccOpTy>
LogicalResult materialize(OpTy op, RecipeOpTy recipe, AccOpTy accOp,
- acc::OpenACCSupport &accSupport) const;
+ acc::OpenACCSupport &accSupport,
+ acc::ACCToGPUMappingPolicy &policy) const;
template <typename OpTy>
- LogicalResult materializeForACCOp(OpTy accOp,
- acc::OpenACCSupport &accSupport) const;
+ LogicalResult materializeForACCOp(OpTy accOp, acc::OpenACCSupport &accSupport,
+ acc::ACCToGPUMappingPolicy &policy) const;
};
void ACCRecipeMaterialization::handleFirstprivateMapping(
@@ -221,9 +223,9 @@ void ACCRecipeMaterialization::removeRecipe(OpTy op, ModuleOp moduleOp) const {
}
template <typename OpTy, typename RecipeOpTy, typename AccOpTy>
-LogicalResult
-ACCRecipeMaterialization::materialize(OpTy op, RecipeOpTy recipe, AccOpTy accOp,
- acc::OpenACCSupport &accSupport) const {
+LogicalResult ACCRecipeMaterialization::materialize(
+ OpTy op, RecipeOpTy recipe, AccOpTy accOp, acc::OpenACCSupport &accSupport,
+ acc::ACCToGPUMappingPolicy &policy) const {
Region ®ion = accOp.getRegion();
Value origPtr = op.getVar();
Value accPtr = op.getAccVar();
@@ -381,22 +383,25 @@ ACCRecipeMaterialization::materialize(OpTy op, RecipeOpTy recipe, AccOpTy accOp,
cloneRegionIntoAccRegion(&combinerRegion, &combineRegionOp.getRegion(),
/*hasResult=*/false);
+ auto ctx = b.getContext();
+
// For reductions that come from parallel constructs, explicitly set the
// GPU parallel dimensions attribute to blockXDim since they will always be
// gang private. GPU parallel dimensions cannot be determined for acc.loop
// at this point.
if constexpr (std::is_same_v<AccOpTy, acc::ParallelOp>) {
- auto gpuParDimsAttr = acc::GPUParallelDimsAttr::get(b.getContext(),
- {acc::GPUParallelDimAttr::blockXDim(b.getContext())});
- acc::setParDimsAttr(reductionOp, gpuParDimsAttr);
- acc::setParDimsAttr(combineRegionOp, gpuParDimsAttr);
+ auto parDimsAttr = acc::GPUParallelDimsAttr::get(
+ ctx, {policy.gangDim(ctx, acc::ParLevel::gang_dim1)});
+ acc::setParDimsAttr(reductionOp, parDimsAttr);
+ acc::setParDimsAttr(combineRegionOp, parDimsAttr);
}
- auto setSeqParDimsForRecipeLoops = [](Region *r) {
- r->walk([](LoopLikeOpInterface loopLike) {
- loopLike->setAttr(
- acc::GPUParallelDimsAttr::name,
- acc::GPUParallelDimsAttr::seq(loopLike->getContext()));
+ // Set sequential parallel dimensions attribute for loops in the recipe.
+ auto seqParDimsAttr =
+ acc::GPUParallelDimsAttr::get(ctx, {policy.seqDim(ctx)});
+ auto setSeqParDimsForRecipeLoops = [&](Region *r) {
+ r->walk([&](LoopLikeOpInterface loopLike) {
+ acc::setParDimsAttr(loopLike, seqParDimsAttr);
});
};
setSeqParDimsForRecipeLoops(&reductionOp.getRegion());
@@ -418,7 +423,8 @@ ACCRecipeMaterialization::materialize(OpTy op, RecipeOpTy recipe, AccOpTy accOp,
template <typename OpTy>
LogicalResult ACCRecipeMaterialization::materializeForACCOp(
- OpTy accOp, acc::OpenACCSupport &accSupport) const {
+ OpTy accOp, acc::OpenACCSupport &accSupport,
+ acc::ACCToGPUMappingPolicy &policy) const {
assert(isa<ACC_COMPUTE_CONSTRUCT_AND_LOOP_OPS>(accOp));
if (!accOp.getFirstprivateOperands().empty()) {
@@ -434,7 +440,8 @@ LogicalResult ACCRecipeMaterialization::materializeForACCOp(
LLVM_DEBUG(llvm::dbgs() << "materializing: " << firstprivateOp << "\n"
<< symbolRef << "\n");
handleFirstprivateMapping(firstprivateOp);
- if (failed(materialize(firstprivateOp, recipeOp, accOp, accSupport)))
+ if (failed(
+ materialize(firstprivateOp, recipeOp, accOp, accSupport, policy)))
return failure();
}
}
@@ -451,7 +458,7 @@ LogicalResult ACCRecipeMaterialization::materializeForACCOp(
auto recipeOp = cast<acc::PrivateRecipeOp>(decl);
LLVM_DEBUG(llvm::dbgs() << "materializing: " << privateOp << "\n"
<< symbolRef << "\n");
- if (failed(materialize(privateOp, recipeOp, accOp, accSupport)))
+ if (failed(materialize(privateOp, recipeOp, accOp, accSupport, policy)))
return failure();
}
}
@@ -468,7 +475,7 @@ LogicalResult ACCRecipeMaterialization::materializeForACCOp(
auto recipeOp = cast<acc::ReductionRecipeOp>(decl);
LLVM_DEBUG(llvm::dbgs() << "materializing: " << reductionOp << "\n"
<< symbolRef << "\n");
- if (failed(materialize(reductionOp, recipeOp, accOp, accSupport)))
+ if (failed(materialize(reductionOp, recipeOp, accOp, accSupport, policy)))
return failure();
}
}
@@ -479,6 +486,8 @@ void ACCRecipeMaterialization::runOnOperation() {
ModuleOp moduleOp = getOperation();
acc::OpenACCSupport &accSupport = getAnalysis<acc::OpenACCSupport>();
+ acc::DefaultACCToGPUMappingPolicy policy;
+
// Materialize all recipes for all compute constructs and loop constructs.
bool anyFailed = false;
moduleOp.walk([&](Operation *op) {
@@ -486,7 +495,7 @@ void ACCRecipeMaterialization::runOnOperation() {
return;
TypeSwitch<Operation *>(op).Case<ACC_COMPUTE_CONSTRUCT_AND_LOOP_OPS>(
[&](auto constructOp) {
- if (failed(materializeForACCOp(constructOp, accSupport)))
+ if (failed(materializeForACCOp(constructOp, accSupport, policy)))
anyFailed = true;
});
});
More information about the Mlir-commits
mailing list