MLIR 24.0.0git
OpenACCUtilsCG.h
Go to the documentation of this file.
1//===- OpenACCUtilsCG.h - OpenACC Code Generation Utilities -----*- C++ -*-===//
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 file defines utility functions for OpenACC code generation, including
10// data layout and type-related utilities.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef MLIR_DIALECT_OPENACC_OPENACCUTILSCG_H_
15#define MLIR_DIALECT_OPENACC_OPENACCUTILSCG_H_
16
19#include "mlir/IR/IRMapping.h"
20#include "mlir/IR/Value.h"
23#include "llvm/ADT/SmallVector.h"
24#include <optional>
25
26namespace mlir {
27namespace acc {
28
29class OpenACCSupport;
30
31/// Get the data layout for an operation.
32///
33/// Attempts to get the data layout from the operation or its parent module.
34/// If `allowDefault` is true (default), a default data layout may be
35/// constructed when no explicit data layout spec is found.
36///
37/// \param op The operation to get the data layout for.
38/// \param allowDefault If true, allow returning a default data layout.
39/// \return The data layout if available, std::nullopt otherwise.
40std::optional<DataLayout> getDataLayout(Operation *op,
41 bool allowDefault = true);
42
43/// Build an `acc.compute_region` operation by cloning a source region.
44///
45/// Creates a new `acc.compute_region` with the given launch arguments and
46/// origin string, then clones the operations from `regionToClone` into its
47/// body. Launch operands should be `acc.par_width` results (`index`); the
48/// region entry block gets matching `index` block arguments first, then
49/// arguments for each `ins` operand. Multi-block regions are wrapped with
50/// `scf.execute_region`.
51///
52/// The `mapping` is used and updated during cloning, allowing callers to
53/// track value correspondences. Optional `output`, `kernelFuncName`,
54/// `kernelModuleName`, and `stream` arguments are forwarded to the op.
55///
56/// When `inputArgsToMap` is non-empty, it is used as the key set for the
57/// clone mapping (instead of `inputArgs`). Use this when cloning a region
58/// that references one set of values (e.g. the source function's args) while
59/// the op's operands are another set (e.g. the current block's args).
60/// `inputArgsToMap` must have the same size as `inputArgs` when provided.
61ComputeRegionOp buildComputeRegion(Location loc, ValueRange launchArgs,
62 ValueRange inputArgs, llvm::StringRef origin,
63 Region &regionToClone,
64 RewriterBase &rewriter, IRMapping &mapping,
65 ValueRange output = {},
66 FlatSymbolRefAttr kernelFuncName = {},
67 FlatSymbolRefAttr kernelModuleName = {},
68 Value stream = {},
69 ValueRange inputArgsToMap = {});
70
71/// Insert \p parDim into \p parDims while preserving dimension ordering. If the
72/// dimension is already present, this is a no-op.
73void insertParDim(llvm::SmallVector<GPUParallelDimAttr> &parDims,
74 GPUParallelDimAttr parDim);
75
76/// Remove \p parDim from \p parDims if present.
77void removeParDim(llvm::SmallVector<GPUParallelDimAttr> &parDims,
78 GPUParallelDimAttr parDim);
79
80/// Obtain the parallel dimensions carried by \p op, if any.
81GPUParallelDimsAttr getParDimsAttr(Operation *op);
82
83/// Return whether \p op carries parallel dimensions.
84bool hasParDimsAttr(Operation *op);
85
86/// Return whether \p op carries sequential parallel dimensions.
87bool hasSeqParDims(Operation *op);
88
89/// Set parallel dimensions on \p op.
90void setParDimsAttr(Operation *op, GPUParallelDimsAttr attr);
91
92/// Update parallel dimensions on \p op.
93void updateParDimsAttr(Operation *op, GPUParallelDimsAttr attr);
94
95/// Copy parallel dimensions from \p from to \p to.
96void copyParDimsAttr(Operation *from, Operation *to);
97
98/// Return whether \p op is marked with the `acc.gpu_block_redundant` attribute,
99/// i.e. it executes redundantly across all thread blocks. Such an op must not
100/// be assigned block/grid-level work-sharing; only thread-level parallelism may
101/// apply, and its enclosing block dimensions are treated as active (not
102/// predicated).
103bool hasGPUBlockRedundantAttr(Operation *op);
104
105/// Mark \p op with the `acc.gpu_block_redundant` attribute.
106void setGPUBlockRedundantAttr(Operation *op);
107
108/// Create a gang dim 1 GPUParallelDimsAttr based on the mapping policy.
109inline GPUParallelDimsAttr
111 return GPUParallelDimsAttr::get(
112 ctx, {policy.gangDim(ctx, acc::ParLevel::gang_dim1)});
113}
114
115/// Create a sequential GPUParallelDimsAttr based on the mapping policy.
116inline GPUParallelDimsAttr getSeqParDimsAttr(MLIRContext *ctx,
117 ACCToGPUMappingPolicy &policy) {
118 return GPUParallelDimsAttr::get(ctx, {policy.seqDim(ctx)});
119}
120
121/// Tracks aligned byte consumption against a configurable shared memory cap.
123public:
124 /// Default allocation alignment (bytes).
125 static constexpr int64_t kDefaultAlignmentBytes = 16;
126
128 : bytesUsed_(initialBytesUsed), maxTotalBytes_(maxTotalBytes) {}
129
130 /// Reserve \p bytes, rounding the current offset up to \p alignment first.
131 /// Returns false without mutating state if the reservation would exceed the
132 /// cap. \p alignment must be a power of two.
133 bool tryAllocate(int64_t bytes, int64_t alignment = kDefaultAlignmentBytes);
134 int64_t bytesUsed() const { return bytesUsed_; }
135 int64_t maxTotalBytes() const { return maxTotalBytes_; }
137 maxTotalBytes_ = maxTotalBytes;
138 }
139
140 /// Round \p offset up to the next multiple of \p alignment, which must be a
141 /// power of two.
142 static int64_t alignOffset(int64_t offset,
143 int64_t alignment = kDefaultAlignmentBytes);
144
145private:
146 int64_t bytesUsed_ = 0;
147 int64_t maxTotalBytes_ = 0;
148};
149
150/// Sum aligned static_upper_bound_bytes for all acc.gpu_shared_memory in \p
151/// region.
153
154/// Resolve the acc.privatize operation associated with a private local.
155PrivatizeOp getPrivatizeOp(PrivateLocalOp privateLocal,
156 ComputeRegionOp computeRegion);
157
158/// Returns the ranked MemRef type used to allocate privatized storage.
159///
160/// \p baseTy is the `baseTy` parameter of `acc.private_type` (the privatized
161/// variable's type).
162MemRefType getPrivateBaseMemRefType(Type baseTy, ModuleOp module);
163
164/// Collect parallel dimensions that govern privatization of \p privateLocal.
166collectPrivateLocalParDims(PrivateLocalOp privateLocal,
167 ComputeRegionOp computeRegion);
168
169/// True when \p privateLocal may be placed in shared memory.
171 PrivateLocalOp privateLocal, ComputeRegionOp computeRegion, ModuleOp module,
172 const ACCToGPUMappingPolicy &policy, OpenACCSupport *support = nullptr);
173
174/// Upper-bound byte size for a shared-memory private_local candidate, or
175/// std::nullopt when not eligible or not statically computable.
176std::optional<int64_t> getPrivateLocalSharedMemoryUpperBoundBytes(
177 PrivateLocalOp privateLocal, ComputeRegionOp computeRegion, ModuleOp module,
178 const ACCToGPUMappingPolicy &policy, OpenACCSupport *support = nullptr);
179
180} // namespace acc
181} // namespace mlir
182
183#endif // MLIR_DIALECT_OPENACC_OPENACCUTILSCG_H_
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition Region.h:26
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
ParDimAttrT seqDim(MLIRContext *ctx) const
ParDimAttrT gangDim(MLIRContext *ctx, ParLevel level) const
Convenience methods for specific parallelism levels.
SharedMemoryBudget(int64_t maxTotalBytes, int64_t initialBytesUsed=0)
bool tryAllocate(int64_t bytes, int64_t alignment=kDefaultAlignmentBytes)
Reserve bytes, rounding the current offset up to alignment first.
static constexpr int64_t kDefaultAlignmentBytes
Default allocation alignment (bytes).
void setMaxTotalBytes(int64_t maxTotalBytes)
static int64_t alignOffset(int64_t offset, int64_t alignment=kDefaultAlignmentBytes)
Round offset up to the next multiple of alignment, which must be a power of two.
GPUParallelDimsAttr getParDimsAttr(Operation *op)
Obtain the parallel dimensions carried by op, if any.
std::optional< DataLayout > getDataLayout(Operation *op, bool allowDefault=true)
Get the data layout for an operation.
MemRefType getPrivateBaseMemRefType(Type baseTy, ModuleOp module)
Returns the ranked MemRef type used to allocate privatized storage.
void insertParDim(llvm::SmallVector< GPUParallelDimAttr > &parDims, GPUParallelDimAttr parDim)
Insert parDim into parDims while preserving dimension ordering.
bool hasParDimsAttr(Operation *op)
Return whether op carries parallel dimensions.
GPUParallelDimsAttr getGangDim1ParDimsAttr(MLIRContext *ctx, ACCToGPUMappingPolicy &policy)
Create a gang dim 1 GPUParallelDimsAttr based on the mapping policy.
ComputeRegionOp buildComputeRegion(Location loc, ValueRange launchArgs, ValueRange inputArgs, llvm::StringRef origin, Region &regionToClone, RewriterBase &rewriter, IRMapping &mapping, ValueRange output={}, FlatSymbolRefAttr kernelFuncName={}, FlatSymbolRefAttr kernelModuleName={}, Value stream={}, ValueRange inputArgsToMap={})
Build an acc.compute_region operation by cloning a source region.
void setGPUBlockRedundantAttr(Operation *op)
Mark op with the acc.gpu_block_redundant attribute.
FailureOr< bool > isPrivateLocalSharedMemoryCandidate(PrivateLocalOp privateLocal, ComputeRegionOp computeRegion, ModuleOp module, const ACCToGPUMappingPolicy &policy, OpenACCSupport *support=nullptr)
True when privateLocal may be placed in shared memory.
int64_t sumExistingSharedMemoryBytes(Region &region)
Sum aligned static_upper_bound_bytes for all acc.gpu_shared_memory in region.
GPUParallelDimsAttr getSeqParDimsAttr(MLIRContext *ctx, ACCToGPUMappingPolicy &policy)
Create a sequential GPUParallelDimsAttr based on the mapping policy.
void updateParDimsAttr(Operation *op, GPUParallelDimsAttr attr)
Update parallel dimensions on op.
PrivatizeOp getPrivatizeOp(PrivateLocalOp privateLocal, ComputeRegionOp computeRegion)
Resolve the acc.privatize operation associated with a private local.
bool hasSeqParDims(Operation *op)
Return whether op carries sequential parallel dimensions.
void copyParDimsAttr(Operation *from, Operation *to)
Copy parallel dimensions from from to to.
bool hasGPUBlockRedundantAttr(Operation *op)
Return whether op is marked with the acc.gpu_block_redundant attribute, i.e.
void removeParDim(llvm::SmallVector< GPUParallelDimAttr > &parDims, GPUParallelDimAttr parDim)
Remove parDim from parDims if present.
void setParDimsAttr(Operation *op, GPUParallelDimsAttr attr)
Set parallel dimensions on op.
std::optional< int64_t > getPrivateLocalSharedMemoryUpperBoundBytes(PrivateLocalOp privateLocal, ComputeRegionOp computeRegion, ModuleOp module, const ACCToGPUMappingPolicy &policy, OpenACCSupport *support=nullptr)
Upper-bound byte size for a shared-memory private_local candidate, or std::nullopt when not eligible ...
SmallVector< GPUParallelDimAttr > collectPrivateLocalParDims(PrivateLocalOp privateLocal, ComputeRegionOp computeRegion)
Collect parallel dimensions that govern privatization of privateLocal.
ACCParMappingPolicy< mlir::acc::GPUParallelDimAttr > ACCToGPUMappingPolicy
Type alias for the GPU-specific mapping policy.
Include the generated interface declarations.