[Mlir-commits] [mlir] [MLIR][OpenACC] Add acc-emit-remarks-loop pass (PR #205203)
Delaram Talaashrafi
llvmlistbot at llvm.org
Tue Jun 23 12:59:44 PDT 2026
https://github.com/delaram-talaashrafi updated https://github.com/llvm/llvm-project/pull/205203
>From 27acf6de0674ce3e6af27af49461cc61fe607072 Mon Sep 17 00:00:00 2001
From: Delaram Talaashrafi <dtalaashrafi at rome5.pgi.net>
Date: Mon, 22 Jun 2026 14:53:02 -0700
Subject: [PATCH 1/2] [MLIR][OpenACC] Add acc-emit-remarks-loop pass
Add a function-level pass that emits optimization remarks for loops
in `acc.compute_region`, describing their mapping to OpenACC parallel
levels (gang, worker, vector, sequential) and GPU dimensions (blockIdx,
threadIdx).
---
.../mlir/Dialect/OpenACC/Transforms/Passes.td | 17 ++
.../OpenACC/Transforms/ACCEmitRemarksLoop.cpp | 152 ++++++++++++++++++
.../Dialect/OpenACC/Transforms/CMakeLists.txt | 1 +
.../acc-emit-remarks-loop-pipeline.mlir | 40 +++++
.../OpenACC/acc-emit-remarks-loop.mlir | 134 +++++++++++++++
5 files changed, 344 insertions(+)
create mode 100644 mlir/lib/Dialect/OpenACC/Transforms/ACCEmitRemarksLoop.cpp
create mode 100644 mlir/test/Dialect/OpenACC/acc-emit-remarks-loop-pipeline.mlir
create mode 100644 mlir/test/Dialect/OpenACC/acc-emit-remarks-loop.mlir
diff --git a/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td b/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
index 485f68dfc9338..121b381d65659 100644
--- a/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
+++ b/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
@@ -176,6 +176,23 @@ def ACCLegalizeSerial : Pass<"acc-legalize-serial", "mlir::func::FuncOp"> {
}
+def ACCEmitRemarksLoop : Pass<"acc-emit-remarks-loop", "mlir::func::FuncOp"> {
+ let summary = "Emit OpenACC loop parallelism mapping remarks";
+ let description = [{
+ This pass emits optimization remarks describing how loops inside OpenACC
+ compute regions are mapped to parallelism levels (gang, worker, vector,
+ sequential) and the corresponding GPU parallel dimensions.
+
+ The pass walks `acc.compute_region` operations that originated from OpenACC
+ compute constructs and reports remarks for each loop carrying an
+ `acc.par_dims` attribute.
+ }];
+ let dependentDialects = [
+ "mlir::acc::OpenACCDialect",
+ "mlir::scf::SCFDialect"
+ ];
+}
+
def ACCLoopTiling : Pass<"acc-loop-tiling", "mlir::func::FuncOp"> {
let summary = "Tile OpenACC loops with tile clauses";
let description = [{
diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCEmitRemarksLoop.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCEmitRemarksLoop.cpp
new file mode 100644
index 0000000000000..f9d115e8ca960
--- /dev/null
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCEmitRemarksLoop.cpp
@@ -0,0 +1,152 @@
+//===- ACCEmitRemarksLoop.cpp - Emit OpenACC loop mapping remarks --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass emits optimization remarks describing how loops inside OpenACC
+// compute regions are mapped to parallelism levels and GPU dimensions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/Dialect/OpenACC/OpenACCParMapping.h"
+#include "mlir/Dialect/OpenACC/OpenACCUtilsLoop.h"
+#include "mlir/Dialect/OpenACC/Transforms/Passes.h"
+#include "mlir/Dialect/SCF/IR/SCF.h"
+#include "mlir/Interfaces/FunctionInterfaces.h"
+#include "mlir/Interfaces/LoopLikeInterface.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Debug.h"
+
+namespace mlir {
+namespace acc {
+#define GEN_PASS_DEF_ACCEMITREMARKSLOOP
+#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
+} // namespace acc
+} // namespace mlir
+
+#define DEBUG_TYPE "acc-emit-remarks-loop"
+
+using namespace mlir;
+
+namespace {
+
+static bool shouldEmitLoopRemarks(acc::ComputeRegionOp computeRegion) {
+ StringRef origin = computeRegion.getOrigin();
+ if (origin == acc::KernelsOp::getOperationName() ||
+ origin == acc::ParallelOp::getOperationName())
+ return true;
+
+ if (auto func = computeRegion->getParentOfType<FunctionOpInterface>())
+ return acc::isSpecializedAccRoutine(func);
+ return false;
+}
+
+static std::string getACCParLevelName(acc::GPUParallelDimAttr parDim,
+ const acc::ACCToGPUMappingPolicy &policy,
+ acc::ComputeRegionOp computeRegion) {
+ std::string accName;
+ if (policy.isSeq(parDim))
+ accName = "sequential";
+ else if (policy.isVector(parDim))
+ accName = "vector";
+ else if (policy.isWorker(parDim))
+ accName = "worker";
+ else if (policy.isGang(parDim))
+ accName = "gang";
+
+ if (!policy.isSeq(parDim)) {
+ if (std::optional<uint64_t> constant =
+ computeRegion.getKnownConstantLaunchArg(parDim))
+ accName += "(" + std::to_string(*constant) + ")";
+ }
+ return accName;
+}
+
+static std::string getGPUParDimName(acc::GPUParallelDimAttr parDim) {
+ if (parDim.isThreadX())
+ return "threadidx%x";
+ if (parDim.isThreadY())
+ return "threadidx%y";
+ if (parDim.isThreadZ())
+ return "threadidx%z";
+ if (parDim.isBlockX())
+ return "blockidx%x";
+ if (parDim.isBlockY())
+ return "blockidx%y";
+ if (parDim.isBlockZ())
+ return "blockidx%z";
+ return {};
+}
+
+static void emitLoopMappingRemark(acc::ComputeRegionOp computeRegion,
+ LoopLikeOpInterface loopOp,
+ acc::OpenACCSupport &accSupport,
+ const acc::ACCToGPUMappingPolicy &policy) {
+ acc::GPUParallelDimsAttr parDimsAttr =
+ loopOp->getAttrOfType<acc::GPUParallelDimsAttr>(
+ acc::GPUParallelDimsAttr::name);
+
+ SmallVector<acc::GPUParallelDimAttr, 1> seqParDims;
+ ArrayRef<acc::GPUParallelDimAttr> parDims;
+ if (parDimsAttr) {
+ parDims = parDimsAttr.getArray();
+ } else if (isa<scf::ForOp>(loopOp.getOperation())) {
+ seqParDims.push_back(acc::GPUParallelDimAttr::seqDim(loopOp->getContext()));
+ parDims = seqParDims;
+ } else {
+ return;
+ }
+
+ accSupport.emitRemark(
+ loopOp,
+ [&]() {
+ SmallVector<std::string> accMsgs;
+ SmallVector<std::string> gpuMsgs;
+
+ for (acc::GPUParallelDimAttr parDim : parDims) {
+ accMsgs.push_back(getACCParLevelName(parDim, policy, computeRegion));
+ if (std::string gpuName = getGPUParDimName(parDim); !gpuName.empty())
+ gpuMsgs.push_back(std::move(gpuName));
+ }
+
+ std::string msg = "!$acc loop " + llvm::join(accMsgs, ", ");
+
+ if (uint64_t collapseCount = acc::getCollapseCount(loopOp);
+ collapseCount > 1)
+ msg += " collapse(" + std::to_string(collapseCount) + ")";
+
+ if (!gpuMsgs.empty())
+ msg += " ! " + llvm::join(gpuMsgs, " ");
+ return msg;
+ },
+ DEBUG_TYPE);
+}
+
+class ACCEmitRemarksLoop
+ : public acc::impl::ACCEmitRemarksLoopBase<ACCEmitRemarksLoop> {
+public:
+ using ACCEmitRemarksLoopBase<ACCEmitRemarksLoop>::ACCEmitRemarksLoopBase;
+
+ void runOnOperation() override {
+ func::FuncOp func = getOperation();
+ acc::OpenACCSupport &accSupport = getAnalysis<acc::OpenACCSupport>();
+ acc::DefaultACCToGPUMappingPolicy policy;
+
+ func.walk([&](acc::ComputeRegionOp computeRegion) {
+ if (!shouldEmitLoopRemarks(computeRegion))
+ return;
+
+ computeRegion.getRegion().walk([&](LoopLikeOpInterface loopOp) {
+ emitLoopMappingRemark(computeRegion, loopOp, accSupport, policy);
+ });
+ });
+ }
+};
+
+} // namespace
diff --git a/mlir/lib/Dialect/OpenACC/Transforms/CMakeLists.txt b/mlir/lib/Dialect/OpenACC/Transforms/CMakeLists.txt
index 5bb92592a6512..2ae3571673469 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/CMakeLists.txt
+++ b/mlir/lib/Dialect/OpenACC/Transforms/CMakeLists.txt
@@ -4,6 +4,7 @@ add_mlir_dialect_library(MLIROpenACCTransforms
ACCRoutineLowering.cpp
ACCRoutineToGPUFunc.cpp
ACCDeclareGPUModuleInsertion.cpp
+ ACCEmitRemarksLoop.cpp
ACCIfClauseLowering.cpp
ACCImplicitData.cpp
ACCRecipeMaterialization.cpp
diff --git a/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop-pipeline.mlir b/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop-pipeline.mlir
new file mode 100644
index 0000000000000..dae8f15b5a972
--- /dev/null
+++ b/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop-pipeline.mlir
@@ -0,0 +1,40 @@
+// RUN: mlir-opt %s -split-input-file -acc-compute-lowering -acc-emit-remarks-loop --remarks-filter="(open)?acc.*" 2>&1 | FileCheck %s
+
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=parallel_gang_loop | Remark="!$acc loop gang(10) ! blockidx%x"
+func.func @parallel_gang_loop(%buf: memref<1xi32>) {
+ %c0 = arith.constant 0 : index
+ %c1_i32 = arith.constant 1 : i32
+ %c10_i32 = arith.constant 10 : i32
+ %c100_i32 = arith.constant 100 : i32
+
+ %dev = acc.copyin varPtr(%buf : memref<1xi32>) -> memref<1xi32>
+ acc.parallel num_gangs({%c10_i32 : i32}) dataOperands(%dev : memref<1xi32>) {
+ acc.loop gang control(%arg0 : i32) = (%c1_i32 : i32) to (%c100_i32 : i32) step (%c1_i32 : i32) {
+ memref.store %arg0, %dev[%c0] : memref<1xi32>
+ acc.yield
+ } attributes {independent = [#acc.device_type<none>]}
+ acc.yield
+ }
+ acc.copyout accPtr(%dev : memref<1xi32>) to varPtr(%buf : memref<1xi32>)
+ return
+}
+
+// -----
+
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=parallel_loop_auto_collapse | Remark="!$acc loop sequential collapse(2)"
+func.func @parallel_loop_auto_collapse(%buf: memref<1xi32>, %lb0 : index, %ub0 : index, %lb1 : index, %ub1 : index) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+
+ %dev = acc.copyin varPtr(%buf : memref<1xi32>) -> memref<1xi32>
+ acc.parallel dataOperands(%dev : memref<1xi32>) {
+ acc.loop control(%i : index, %j : index) = (%lb0, %lb1 : index, index) to (%ub0, %ub1 : index, index) step (%c1, %c1 : index, index) {
+ %vi = arith.index_cast %i : index to i32
+ memref.store %vi, %dev[%c0] : memref<1xi32>
+ acc.yield
+ } attributes {auto_ = [#acc.device_type<none>]}
+ acc.yield
+ }
+ acc.copyout accPtr(%dev : memref<1xi32>) to varPtr(%buf : memref<1xi32>)
+ return
+}
diff --git a/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop.mlir b/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop.mlir
new file mode 100644
index 0000000000000..bc342e3f1cfd1
--- /dev/null
+++ b/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop.mlir
@@ -0,0 +1,134 @@
+// RUN: mlir-opt %s -split-input-file -acc-emit-remarks-loop --remarks-filter="(open)?acc.*" 2>&1 | FileCheck %s
+
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=vector_loop | Remark="!$acc loop vector(128) ! threadidx%x"
+func.func @vector_loop() {
+ %c128 = arith.constant 128 : index
+ acc.kernel_environment {
+ %w0 = acc.par_width %c128 {par_dim = #acc.par_dim<thread_x>}
+ acc.compute_region launch(%arg0 = %w0) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c128_inner = arith.constant 128 : index
+ scf.parallel (%iv) = (%c0) to (%c128_inner) step (%c1) {
+ scf.reduce
+ } {acc.par_dims = #acc<par_dims[thread_x]>}
+ acc.yield
+ } {origin = "acc.parallel"}
+ }
+ return
+}
+
+// -----
+
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=gang_loop | Remark="!$acc loop gang(8) ! blockidx%x"
+func.func @gang_loop() {
+ %c8 = arith.constant 8 : index
+ acc.kernel_environment {
+ %w0 = acc.par_width %c8 {par_dim = #acc.par_dim<block_x>}
+ acc.compute_region launch(%arg0 = %w0) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c8_inner = arith.constant 8 : index
+ scf.parallel (%iv) = (%c0) to (%c8_inner) step (%c1) {
+ scf.reduce
+ } {acc.par_dims = #acc<par_dims[block_x]>}
+ acc.yield
+ } {origin = "acc.parallel"}
+ }
+ return
+}
+
+// -----
+
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=worker_loop | Remark="!$acc loop worker(4) ! threadidx%y"
+func.func @worker_loop() {
+ %c4 = arith.constant 4 : index
+ acc.kernel_environment {
+ %w0 = acc.par_width %c4 {par_dim = #acc.par_dim<thread_y>}
+ acc.compute_region launch(%arg0 = %w0) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c8 = arith.constant 8 : index
+ scf.parallel (%iv) = (%c0) to (%c8) step (%c1) {
+ scf.reduce
+ } {acc.par_dims = #acc<par_dims[thread_y]>}
+ acc.yield
+ } {origin = "acc.parallel"}
+ }
+ return
+}
+
+// -----
+
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=sequential_loop | Remark="!$acc loop sequential"
+func.func @sequential_loop() {
+ acc.kernel_environment {
+ acc.compute_region {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c4 = arith.constant 4 : index
+ scf.parallel (%iv) = (%c0) to (%c4) step (%c1) {
+ scf.reduce
+ } {acc.par_dims = #acc<par_dims[sequential]>}
+ acc.yield
+ } {origin = "acc.kernels"}
+ }
+ return
+}
+
+// -----
+
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=block_and_vector | Remark="!$acc loop gang(8), vector(128) ! blockidx%x threadidx%x"
+func.func @block_and_vector() {
+ %c8 = arith.constant 8 : index
+ %c128 = arith.constant 128 : index
+ acc.kernel_environment {
+ %w0 = acc.par_width %c8 {par_dim = #acc.par_dim<block_x>}
+ %w1 = acc.par_width %c128 {par_dim = #acc.par_dim<thread_x>}
+ acc.compute_region launch(%arg0 = %w0, %arg1 = %w1) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c8_inner = arith.constant 8 : index
+ %c128_inner = arith.constant 128 : index
+ scf.parallel (%i, %j) = (%c0, %c0) to (%c8_inner, %c128_inner) step (%c1, %c1) {
+ scf.reduce
+ } {acc.par_dims = #acc<par_dims[block_x, thread_x]>}
+ acc.yield
+ } {origin = "acc.parallel"}
+ }
+ return
+}
+
+// -----
+
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=scf_for_sequential | Remark="!$acc loop sequential"
+func.func @scf_for_sequential() {
+ acc.kernel_environment {
+ acc.compute_region {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c4 = arith.constant 4 : index
+ scf.for %iv = %c0 to %c4 step %c1 {
+ }
+ acc.yield
+ } {origin = "acc.parallel"}
+ }
+ return
+}
+
+// -----
+
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=collapse_loop | Remark="!$acc loop sequential collapse(2)"
+func.func @collapse_loop() {
+ acc.kernel_environment {
+ acc.compute_region {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c4 = arith.constant 4 : index
+ scf.for %iv = %c0 to %c4 step %c1 {
+ } {acc.par_dims = #acc<par_dims[sequential]>, acc.collapse_count = 2 : i64}
+ acc.yield
+ } {origin = "acc.parallel"}
+ }
+ return
+}
>From c07c0ebe69c1d5699792337be5e8665b1e7ed667 Mon Sep 17 00:00:00 2001
From: Delaram Talaashrafi <dtalaashrafi at rome5.pgi.net>
Date: Tue, 23 Jun 2026 12:59:14 -0700
Subject: [PATCH 2/2] Address reviews
---
.../mlir/Dialect/OpenACC/Transforms/Passes.td | 6 ++--
.../OpenACC/Transforms/ACCEmitRemarksLoop.cpp | 33 ++++++++++++-------
.../acc-emit-remarks-loop-pipeline.mlir | 2 +-
.../OpenACC/acc-emit-remarks-loop.mlir | 29 +++++++++++++---
4 files changed, 51 insertions(+), 19 deletions(-)
diff --git a/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td b/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
index 121b381d65659..e35e38adceb02 100644
--- a/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
+++ b/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.td
@@ -187,9 +187,9 @@ def ACCEmitRemarksLoop : Pass<"acc-emit-remarks-loop", "mlir::func::FuncOp"> {
compute constructs and reports remarks for each loop carrying an
`acc.par_dims` attribute.
}];
- let dependentDialects = [
- "mlir::acc::OpenACCDialect",
- "mlir::scf::SCFDialect"
+ let options = [
+ Option<"gpuDimSeparator", "gpu-dim-separator", "std::string", "\".\"",
+ "Separator between GPU index prefix and axis name in remarks ">
];
}
diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCEmitRemarksLoop.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCEmitRemarksLoop.cpp
index f9d115e8ca960..29e71fe1e9097 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCEmitRemarksLoop.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCEmitRemarksLoop.cpp
@@ -39,7 +39,8 @@ namespace {
static bool shouldEmitLoopRemarks(acc::ComputeRegionOp computeRegion) {
StringRef origin = computeRegion.getOrigin();
if (origin == acc::KernelsOp::getOperationName() ||
- origin == acc::ParallelOp::getOperationName())
+ origin == acc::ParallelOp::getOperationName() ||
+ origin == acc::SerialOp::getOperationName())
return true;
if (auto func = computeRegion->getParentOfType<FunctionOpInterface>())
@@ -68,26 +69,32 @@ static std::string getACCParLevelName(acc::GPUParallelDimAttr parDim,
return accName;
}
-static std::string getGPUParDimName(acc::GPUParallelDimAttr parDim) {
+static std::string getGPUParDimName(acc::GPUParallelDimAttr parDim,
+ llvm::StringRef separator) {
+ auto formatDim = [&](llvm::StringRef prefix, char axis) {
+ return (prefix + separator).str() + axis;
+ };
+
if (parDim.isThreadX())
- return "threadidx%x";
+ return formatDim("threadidx", 'x');
if (parDim.isThreadY())
- return "threadidx%y";
+ return formatDim("threadidx", 'y');
if (parDim.isThreadZ())
- return "threadidx%z";
+ return formatDim("threadidx", 'z');
if (parDim.isBlockX())
- return "blockidx%x";
+ return formatDim("blockidx", 'x');
if (parDim.isBlockY())
- return "blockidx%y";
+ return formatDim("blockidx", 'y');
if (parDim.isBlockZ())
- return "blockidx%z";
+ return formatDim("blockidx", 'z');
return {};
}
static void emitLoopMappingRemark(acc::ComputeRegionOp computeRegion,
LoopLikeOpInterface loopOp,
acc::OpenACCSupport &accSupport,
- const acc::ACCToGPUMappingPolicy &policy) {
+ const acc::ACCToGPUMappingPolicy &policy,
+ llvm::StringRef gpuDimSeparator) {
acc::GPUParallelDimsAttr parDimsAttr =
loopOp->getAttrOfType<acc::GPUParallelDimsAttr>(
acc::GPUParallelDimsAttr::name);
@@ -111,7 +118,8 @@ static void emitLoopMappingRemark(acc::ComputeRegionOp computeRegion,
for (acc::GPUParallelDimAttr parDim : parDims) {
accMsgs.push_back(getACCParLevelName(parDim, policy, computeRegion));
- if (std::string gpuName = getGPUParDimName(parDim); !gpuName.empty())
+ if (std::string gpuName = getGPUParDimName(parDim, gpuDimSeparator);
+ !gpuName.empty())
gpuMsgs.push_back(std::move(gpuName));
}
@@ -137,13 +145,16 @@ class ACCEmitRemarksLoop
func::FuncOp func = getOperation();
acc::OpenACCSupport &accSupport = getAnalysis<acc::OpenACCSupport>();
acc::DefaultACCToGPUMappingPolicy policy;
+ if (gpuDimSeparator.empty())
+ gpuDimSeparator = ".";
func.walk([&](acc::ComputeRegionOp computeRegion) {
if (!shouldEmitLoopRemarks(computeRegion))
return;
computeRegion.getRegion().walk([&](LoopLikeOpInterface loopOp) {
- emitLoopMappingRemark(computeRegion, loopOp, accSupport, policy);
+ emitLoopMappingRemark(computeRegion, loopOp, accSupport, policy,
+ gpuDimSeparator);
});
});
}
diff --git a/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop-pipeline.mlir b/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop-pipeline.mlir
index dae8f15b5a972..c559ef68090e2 100644
--- a/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop-pipeline.mlir
+++ b/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop-pipeline.mlir
@@ -1,6 +1,6 @@
// RUN: mlir-opt %s -split-input-file -acc-compute-lowering -acc-emit-remarks-loop --remarks-filter="(open)?acc.*" 2>&1 | FileCheck %s
-// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=parallel_gang_loop | Remark="!$acc loop gang(10) ! blockidx%x"
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=parallel_gang_loop | Remark="!$acc loop gang(10) ! blockidx.x"
func.func @parallel_gang_loop(%buf: memref<1xi32>) {
%c0 = arith.constant 0 : index
%c1_i32 = arith.constant 1 : i32
diff --git a/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop.mlir b/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop.mlir
index bc342e3f1cfd1..0c310510652e7 100644
--- a/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop.mlir
+++ b/mlir/test/Dialect/OpenACC/acc-emit-remarks-loop.mlir
@@ -1,6 +1,7 @@
// RUN: mlir-opt %s -split-input-file -acc-emit-remarks-loop --remarks-filter="(open)?acc.*" 2>&1 | FileCheck %s
+// RUN: mlir-opt %s -split-input-file -acc-emit-remarks-loop='gpu-dim-separator=%' --remarks-filter="(open)?acc.*" 2>&1 | FileCheck %s --check-prefix=PERCENT
-// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=vector_loop | Remark="!$acc loop vector(128) ! threadidx%x"
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=vector_loop | Remark="!$acc loop vector(128) ! threadidx.x"
func.func @vector_loop() {
%c128 = arith.constant 128 : index
acc.kernel_environment {
@@ -20,7 +21,7 @@ func.func @vector_loop() {
// -----
-// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=gang_loop | Remark="!$acc loop gang(8) ! blockidx%x"
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=gang_loop | Remark="!$acc loop gang(8) ! blockidx.x"
func.func @gang_loop() {
%c8 = arith.constant 8 : index
acc.kernel_environment {
@@ -40,7 +41,7 @@ func.func @gang_loop() {
// -----
-// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=worker_loop | Remark="!$acc loop worker(4) ! threadidx%y"
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=worker_loop | Remark="!$acc loop worker(4) ! threadidx.y"
func.func @worker_loop() {
%c4 = arith.constant 4 : index
acc.kernel_environment {
@@ -78,7 +79,7 @@ func.func @sequential_loop() {
// -----
-// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=block_and_vector | Remark="!$acc loop gang(8), vector(128) ! blockidx%x threadidx%x"
+// CHECK: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=block_and_vector | Remark="!$acc loop gang(8), vector(128) ! blockidx.x threadidx.x"
func.func @block_and_vector() {
%c8 = arith.constant 8 : index
%c128 = arith.constant 128 : index
@@ -132,3 +133,23 @@ func.func @collapse_loop() {
}
return
}
+
+// -----
+
+// PERCENT: remark: [Passed] openacc | Category:acc-emit-remarks-loop | Function=percent_separator | Remark="!$acc loop vector(128) ! threadidx%x"
+func.func @percent_separator() {
+ %c128 = arith.constant 128 : index
+ acc.kernel_environment {
+ %w0 = acc.par_width %c128 {par_dim = #acc.par_dim<thread_x>}
+ acc.compute_region launch(%arg0 = %w0) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c128_inner = arith.constant 128 : index
+ scf.parallel (%iv) = (%c0) to (%c128_inner) step (%c1) {
+ scf.reduce
+ } {acc.par_dims = #acc<par_dims[thread_x]>}
+ acc.yield
+ } {origin = "acc.parallel"}
+ }
+ return
+}
More information about the Mlir-commits
mailing list