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/// Obtain the active parallel dimensions carried by \p op, if any.
99ActiveParDimsAttr getActiveParDimsAttr(Operation *op);
100
101/// Return whether \p op carries active parallel dimensions.
102bool hasActiveParDimsAttr(Operation *op);
103
104/// Set active parallel dimensions on \p op.
105void setActiveParDimsAttr(Operation *op, ActiveParDimsAttr attr);
106
107/// Set active parallel dimensions on \p op from a dimension list.
108void setActiveParDimsAttr(Operation *op, ArrayRef<GPUParallelDimAttr> dims);
109
110/// Return whether \p op is marked with the `acc.gpu_block_redundant` attribute,
111/// i.e. it executes redundantly across all thread blocks. Such an op must not
112/// be assigned block/grid-level work-sharing; only thread-level parallelism may
113/// apply, and its enclosing block dimensions are treated as active (not
114/// predicated).
115bool hasGPUBlockRedundantAttr(Operation *op);
116
117/// Mark \p op with the `acc.gpu_block_redundant` attribute.
118void setGPUBlockRedundantAttr(Operation *op);
119
120/// Create a gang dim 1 GPUParallelDimsAttr based on the mapping policy.
121inline GPUParallelDimsAttr
123 return GPUParallelDimsAttr::get(
124 ctx, {policy.gangDim(ctx, acc::ParLevel::gang_dim1)});
125}
126
127/// Create a sequential GPUParallelDimsAttr based on the mapping policy.
128inline GPUParallelDimsAttr getSeqParDimsAttr(MLIRContext *ctx,
129 ACCToGPUMappingPolicy &policy) {
130 return GPUParallelDimsAttr::get(ctx, {policy.seqDim(ctx)});
131}
132
133/// Tracks aligned byte consumption against a configurable shared memory cap.
135public:
136 /// Default allocation alignment (bytes).
137 static constexpr int64_t kDefaultAlignmentBytes = 16;
138
140 : bytesUsed_(initialBytesUsed), maxTotalBytes_(maxTotalBytes) {}
141
142 /// Reserve \p bytes, rounding the current offset up to \p alignment first.
143 /// Returns false without mutating state if the reservation would exceed the
144 /// cap. \p alignment must be a power of two.
145 bool tryAllocate(int64_t bytes, int64_t alignment = kDefaultAlignmentBytes);
146 int64_t bytesUsed() const { return bytesUsed_; }
147 int64_t maxTotalBytes() const { return maxTotalBytes_; }
149 maxTotalBytes_ = maxTotalBytes;
150 }
151
152 /// Round \p offset up to the next multiple of \p alignment, which must be a
153 /// power of two.
154 static int64_t alignOffset(int64_t offset,
155 int64_t alignment = kDefaultAlignmentBytes);
156
157private:
158 int64_t bytesUsed_ = 0;
159 int64_t maxTotalBytes_ = 0;
160};
161
162/// Sum aligned static_upper_bound_bytes for all acc.gpu_shared_memory in \p
163/// region.
165
166/// Resolve the acc.privatize operation associated with a private local.
167PrivatizeOp getPrivatizeOp(PrivateLocalOp privateLocal,
168 ComputeRegionOp computeRegion);
169
170/// Returns the ranked MemRef type used to allocate privatized storage.
171///
172/// \p baseTy is the `baseTy` parameter of `acc.private_type` (the privatized
173/// variable's type).
174MemRefType getPrivateBaseMemRefType(Type baseTy, ModuleOp module);
175
176/// Collect parallel dimensions that govern privatization of \p privateLocal.
178collectPrivateLocalParDims(PrivateLocalOp privateLocal,
179 ComputeRegionOp computeRegion);
180
181/// True when \p privateLocal may be placed in shared memory.
183 PrivateLocalOp privateLocal, ComputeRegionOp computeRegion, ModuleOp module,
184 const ACCToGPUMappingPolicy &policy, OpenACCSupport *support = nullptr);
185
186/// Upper-bound byte size for a shared-memory private_local candidate, or
187/// std::nullopt when not eligible or not statically computable.
188std::optional<int64_t> getPrivateLocalSharedMemoryUpperBoundBytes(
189 PrivateLocalOp privateLocal, ComputeRegionOp computeRegion, ModuleOp module,
190 const ACCToGPUMappingPolicy &policy, OpenACCSupport *support = nullptr);
191
192} // namespace acc
193} // namespace mlir
194
195#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 setActiveParDimsAttr(Operation *op, ActiveParDimsAttr attr)
Set active parallel dimensions on op.
void insertParDim(llvm::SmallVector< GPUParallelDimAttr > &parDims, GPUParallelDimAttr parDim)
Insert parDim into parDims while preserving dimension ordering.
bool hasActiveParDimsAttr(Operation *op)
Return whether op carries active parallel dimensions.
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.
ActiveParDimsAttr getActiveParDimsAttr(Operation *op)
Obtain the active parallel dimensions carried by op, if any.
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.