[Mlir-commits] [mlir] [mlir][OpenACC] Ignore non-constant worker and vector sizes on kernels loops (PR #228494)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Oct 2 08:50:18 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-openacc

Author: Delaram Talaashrafi (delaram-talaashrafi)

<details>
<summary>Changes</summary>

A non-constant worker and vector clause on `acc.loop` inside acc.kernels is skipped, instead of failing as not yet implemented. The pass reports the skip.

---
Full diff: https://github.com/llvm/llvm-project/pull/228494.diff


2 Files Affected:

- (modified) mlir/lib/Dialect/OpenACC/Transforms/ACCComputeLowering.cpp (+10-1) 
- (modified) mlir/test/Dialect/OpenACC/acc-compute-lowering-compute.mlir (+62) 


``````````diff
diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCComputeLowering.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCComputeLowering.cpp
index 65d69f447cb2c8..84867cf58d5e62 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCComputeLowering.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCComputeLowering.cpp
@@ -162,7 +162,8 @@ struct SizedLevel {
 };
 using SizedLevelMap = DenseMap<Operation *, SmallVector<SizedLevel>>;
 
-/// Record a sized clause if `size` is a constant; NYI otherwise.
+/// Record a sized clause if `size` is a constant. A non-constant vector or
+/// worker clause is ignored. Other non-constant sizes are NYI.
 static LogicalResult tryAddSizedLevel(SizedLevelMap &sizedLevelMap,
                                       Operation *computeOp, LoopOp loopOp,
                                       ParLevel level, Value size,
@@ -171,6 +172,14 @@ static LogicalResult tryAddSizedLevel(SizedLevelMap &sizedLevelMap,
     return success();
   std::optional<int64_t> constSize = getConstantIntValue(size);
   if (!constSize) {
+    if (level == ParLevel::vector || level == ParLevel::worker) {
+      accSupport.emitRemark(loopOp,
+                            level == ParLevel::vector
+                                ? "ignoring non-constant vector clause"
+                                : "ignoring non-constant worker clause",
+                            DEBUG_TYPE);
+      return success();
+    }
     accSupport.emitNYI(loopOp.getLoc(),
                        "non-constant sized parallelism clause");
     return failure();
diff --git a/mlir/test/Dialect/OpenACC/acc-compute-lowering-compute.mlir b/mlir/test/Dialect/OpenACC/acc-compute-lowering-compute.mlir
index f8719325874950..82e87179347a1d 100644
--- a/mlir/test/Dialect/OpenACC/acc-compute-lowering-compute.mlir
+++ b/mlir/test/Dialect/OpenACC/acc-compute-lowering-compute.mlir
@@ -1,4 +1,5 @@
 // RUN: mlir-opt %s -acc-compute-lowering | FileCheck %s
+// RUN: mlir-opt %s -acc-compute-lowering --remarks-filter="(open)?acc.*" 2>&1 | FileCheck %s --check-prefix=REMARK
 
 // CHECK-LABEL: func.func @parallel_gang_loop
 func.func @parallel_gang_loop(%buf: memref<1xi32>) {
@@ -301,3 +302,64 @@ func.func @kernels_loop_sized_vector(%buf: memref<4xi32>) {
   acc.copyout accPtr(%dev : memref<4xi32>) to varPtr(%buf : memref<4xi32>)
   return
 }
+
+// -----
+
+// A sized `worker(n)` clause on a loop inside acc.kernels supplies the worker
+// launch width when the construct itself has no num_workers clause.
+
+// CHECK-LABEL: func.func @kernels_loop_sized_worker
+func.func @kernels_loop_sized_worker(%buf: memref<4xi32>) {
+  %c0 = arith.constant 0 : index
+  %c1 = arith.constant 1 : index
+  %c4 = arith.constant 4 : index
+  %c8_i32 = arith.constant 8 : i32
+
+  %dev = acc.copyin varPtr(%buf : memref<4xi32>) -> memref<4xi32>
+  // CHECK: %[[NW:.*]] = arith.constant 8 : index
+  // CHECK: acc.kernel_environment
+  // CHECK: %[[PW:.*]] = acc.par_width %[[NW]] par_dim(#acc.par_dim<thread_y>)
+  // CHECK: acc.compute_region launch(%{{.*}} = %[[PW]])
+  // CHECK: scf.parallel
+  // CHECK: acc.par_dims = #acc<par_dims[thread_y]>
+  acc.kernels dataOperands(%dev : memref<4xi32>) {
+    acc.loop worker(%c8_i32 : i32) control(%i : index) = (%c0 : index) to (%c4 : index) step (%c1 : index) {
+      %vi = arith.index_cast %i : index to i32
+      memref.store %vi, %dev[%i] : memref<4xi32>
+      acc.yield
+    } independent
+    acc.terminator
+  }
+  acc.copyout accPtr(%dev : memref<4xi32>) to varPtr(%buf : memref<4xi32>)
+  return
+}
+
+// -----
+
+// A non-constant worker(n) on a loop inside acc.kernels is ignored. The loop
+// stays a worker loop, and the launch does not take a worker width from it.
+
+// REMARK: remark:{{.*}}Category:acc-compute-lowering{{.*}}Function=kernels_loop_nonconst_worker{{.*}}Remark="ignoring non-constant worker clause"
+// CHECK-LABEL: func.func @kernels_loop_nonconst_worker
+func.func @kernels_loop_nonconst_worker(%buf: memref<4xi32>, %workers: i32) {
+  %c0 = arith.constant 0 : index
+  %c1 = arith.constant 1 : index
+  %c4 = arith.constant 4 : index
+
+  %dev = acc.copyin varPtr(%buf : memref<4xi32>) -> memref<4xi32>
+  // CHECK: acc.kernel_environment
+  // CHECK-NOT: par_dim(#acc.par_dim<thread_y>)
+  // CHECK: acc.compute_region
+  // CHECK: scf.parallel
+  // CHECK: acc.par_dims = #acc<par_dims[thread_y]>
+  acc.kernels dataOperands(%dev : memref<4xi32>) {
+    acc.loop worker(%workers : i32) control(%i : index) = (%c0 : index) to (%c4 : index) step (%c1 : index) {
+      %vi = arith.index_cast %i : index to i32
+      memref.store %vi, %dev[%i] : memref<4xi32>
+      acc.yield
+    } independent
+    acc.terminator
+  }
+  acc.copyout accPtr(%dev : memref<4xi32>) to varPtr(%buf : memref<4xi32>)
+  return
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/228494


More information about the Mlir-commits mailing list