MLIR 24.0.0git
ACCEmitRemarksLoop.cpp
Go to the documentation of this file.
1//===- ACCEmitRemarksLoop.cpp - Emit OpenACC loop mapping remarks --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass emits optimization remarks describing how loops inside OpenACC
10// compute regions are mapped to parallelism levels and GPU dimensions.
11//
12//===----------------------------------------------------------------------===//
13
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/Support/Debug.h"
25
26namespace mlir {
27namespace acc {
28#define GEN_PASS_DEF_ACCEMITREMARKSLOOP
29#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
30} // namespace acc
31} // namespace mlir
32
33#define DEBUG_TYPE "acc-emit-remarks-loop"
34
35using namespace mlir;
36
37namespace {
38
39static bool
40computeRegionInSpecializedAccRoutine(acc::ComputeRegionOp computeRegion) {
41 if (auto func = computeRegion->getParentOfType<FunctionOpInterface>())
43 return false;
44}
45
46static bool shouldEmitLoopRemarks(acc::ComputeRegionOp computeRegion) {
47 StringRef origin = computeRegion.getOrigin();
48 if (origin == acc::KernelsOp::getOperationName() ||
49 origin == acc::ParallelOp::getOperationName() ||
50 origin == acc::SerialOp::getOperationName())
51 return true;
52
53 return computeRegionInSpecializedAccRoutine(computeRegion);
54}
55
56static std::string getACCParLevelName(acc::GPUParallelDimAttr parDim,
57 const acc::ACCToGPUMappingPolicy &policy,
58 acc::ComputeRegionOp computeRegion) {
59 std::string accName;
60 if (policy.isSeq(parDim))
61 accName = "sequential";
62 else if (policy.isVector(parDim))
63 accName = "vector";
64 else if (policy.isWorker(parDim))
65 accName = "worker";
66 else if (policy.isGang(parDim))
67 accName = "gang";
68
69 // Don't specify the constant launch args for sequential loops or loops in
70 // specialized acc routines as the launch args are not determined here.
71 if (!policy.isSeq(parDim) &&
72 !computeRegionInSpecializedAccRoutine(computeRegion)) {
73 if (std::optional<uint64_t> constant =
74 computeRegion.getKnownConstantLaunchArg(parDim))
75 accName += "(" + std::to_string(*constant) + ")";
76 }
77 return accName;
78}
79
80static std::string getGPUParDimName(acc::GPUParallelDimAttr parDim,
81 llvm::StringRef separator) {
82 auto formatDim = [&](llvm::StringRef prefix, char axis) {
83 return (prefix + separator).str() + axis;
84 };
85
86 if (parDim.isThreadX())
87 return formatDim("threadidx", 'x');
88 if (parDim.isThreadY())
89 return formatDim("threadidx", 'y');
90 if (parDim.isThreadZ())
91 return formatDim("threadidx", 'z');
92 if (parDim.isBlockX())
93 return formatDim("blockidx", 'x');
94 if (parDim.isBlockY())
95 return formatDim("blockidx", 'y');
96 if (parDim.isBlockZ())
97 return formatDim("blockidx", 'z');
98 return {};
99}
100
101static void emitLoopMappingRemark(acc::ComputeRegionOp computeRegion,
102 LoopLikeOpInterface loopOp,
103 acc::OpenACCSupport &accSupport,
104 const acc::ACCToGPUMappingPolicy &policy,
105 llvm::StringRef gpuDimSeparator) {
106 acc::GPUParallelDimsAttr parDimsAttr =
107 loopOp->getAttrOfType<acc::GPUParallelDimsAttr>(
108 acc::GPUParallelDimsAttr::name);
109
112 if (parDimsAttr) {
113 parDims = parDimsAttr.getArray();
114 } else if (isa<scf::ForOp>(loopOp.getOperation())) {
115 seqParDims.push_back(acc::GPUParallelDimAttr::seqDim(loopOp->getContext()));
116 parDims = seqParDims;
117 } else {
118 return;
119 }
120
121 accSupport.emitRemark(
122 loopOp,
123 [&]() {
126
127 for (acc::GPUParallelDimAttr parDim : parDims) {
128 accMsgs.push_back(getACCParLevelName(parDim, policy, computeRegion));
129 if (std::string gpuName = getGPUParDimName(parDim, gpuDimSeparator);
130 !gpuName.empty())
131 gpuMsgs.push_back(std::move(gpuName));
132 }
133
134 std::string msg = "!$acc loop " + llvm::join(accMsgs, ", ");
135
136 if (uint64_t collapseCount = acc::getCollapseCount(loopOp);
137 collapseCount > 1)
138 msg += " collapse(" + std::to_string(collapseCount) + ")";
139
140 if (!gpuMsgs.empty())
141 msg += " ! " + llvm::join(gpuMsgs, " ");
142 return msg;
143 },
144 DEBUG_TYPE);
145}
146
147class ACCEmitRemarksLoop
148 : public acc::impl::ACCEmitRemarksLoopBase<ACCEmitRemarksLoop> {
149public:
150 using ACCEmitRemarksLoopBase<ACCEmitRemarksLoop>::ACCEmitRemarksLoopBase;
151
152 void runOnOperation() override {
153 func::FuncOp func = getOperation();
154 acc::OpenACCSupport &accSupport = getAnalysis<acc::OpenACCSupport>();
156 if (gpuDimSeparator.empty())
157 gpuDimSeparator = ".";
158
159 func.walk([&](acc::ComputeRegionOp computeRegion) {
160 if (!shouldEmitLoopRemarks(computeRegion))
161 return;
162
163 computeRegion.getRegion().walk([&](LoopLikeOpInterface loopOp) {
164 emitLoopMappingRemark(computeRegion, loopOp, accSupport, policy,
165 gpuDimSeparator);
166 });
167 });
168 }
169};
170
171} // namespace
#define DEBUG_TYPE
virtual bool isWorker(ParDimAttrT attr) const =0
Check if the attribute represents worker parallelism.
virtual bool isSeq(ParDimAttrT attr) const =0
Check if the attribute represents sequential execution.
virtual bool isVector(ParDimAttrT attr) const =0
Check if the attribute represents vector parallelism.
virtual bool isGang(ParDimAttrT attr) const =0
Check if the attribute represents gang parallelism (any gang dimension).
Default policy that provides the standard GPU mapping: gang(dim:1) -> BlockX (gridDim....
remark::detail::InFlightRemark emitRemark(Operation *op, std::function< std::string()> messageFn, llvm::StringRef category="openacc")
Emit an OpenACC remark with lazy message generation.
uint64_t getCollapseCount(Operation *op)
Number of original loops collapsed into op, or 1 when op carries no collapse_count attribute.
bool isSpecializedAccRoutine(mlir::Operation *op)
Used to check whether this is a specialized accelerator version of acc routine function.
Definition OpenACC.h:201
ACCParMappingPolicy< mlir::acc::GPUParallelDimAttr > ACCToGPUMappingPolicy
Type alias for the GPU-specific mapping policy.
Include the generated interface declarations.