23 #define GEN_PASS_DEF_GPUMAPPARALLELLOOPSPASS
24 #include "mlir/Dialect/GPU/Transforms/Passes.h.inc"
29 using scf::ParallelOp;
38 for (
auto dimAttr : mapping) {
39 gpu::Processor processor = dimAttr.getProcessor();
40 if (processor != gpu::Processor::Sequential &&
41 specifiedMappings.count(processor))
42 return ploopOp.emitError(
43 "invalid mapping multiple loops to same processor");
44 specifiedMappings.insert(processor);
46 ArrayRef<Attribute> mappingAsAttrs(mapping.data(), mapping.size());
54 enum MappingLevel { MapGrid = 0, MapBlock = 1, Sequential = 2 };
55 enum class MappingPolicy { OutermostFirst, InnermostFirst };
62 static MappingLevel &
operator++(MappingLevel &mappingLevel) {
63 if (mappingLevel < Sequential) {
64 mappingLevel =
static_cast<MappingLevel
>(mappingLevel + 1);
72 std::string policyCanonical = policy.trim().lower();
74 std::optional<MappingPolicy> option =
76 .Case(
"innermost-first", MappingPolicy::InnermostFirst)
77 .Case(
"outermost-first", MappingPolicy::OutermostFirst)
78 .Default(std::nullopt);
91 return Processor::Sequential;
97 return Processor::BlockX;
99 return Processor::BlockY;
101 return Processor::BlockZ;
103 return Processor::Sequential;
109 return Processor::ThreadX;
111 return Processor::ThreadY;
113 return Processor::ThreadZ;
115 return Processor::Sequential;
119 return Processor::Sequential;
127 MappingPolicy mappingPolicy = MappingPolicy::OutermostFirst) {
130 ((mappingLevel == MapGrid) && parallelOp->getParentOfType<ParallelOp>()))
133 const int numLoops =
static_cast<int>(parallelOp.getNumLoops());
139 attrs.reserve(numLoops);
141 for (
int i = 0; i < numLoops; ++i) {
146 if (i < loopsToMap) {
147 hwMapping = (mappingPolicy == MappingPolicy::OutermostFirst)
149 : (loopsToMap - 1 - i);
152 attrs.push_back(b.
getAttr<ParallelLoopDimMappingAttr>(
160 for (
Operation &op : *parallelOp.getBody()) {
161 if (ParallelOp nested = dyn_cast<ParallelOp>(op))
167 struct GpuMapParallelLoopsPass
168 :
public impl::GpuMapParallelLoopsPassBase<GpuMapParallelLoopsPass> {
171 void runOnOperation()
override {
173 FailureOr<MappingPolicy> policyOrFailure =
175 if (
failed(policyOrFailure)) {
176 getOperation()->emitError() <<
"Invalid mapping policy specified.";
177 return signalPassFailure();
180 MappingPolicy policy = *policyOrFailure;
181 MappingLevel topLevel = MappingLevel::MapGrid;
183 for (Region ®ion : getOperation()->getRegions()) {
184 region.walk([&](ParallelOp parallelOp) {
static Value min(ImplicitLocOpBuilder &builder, Value value, Value bound)
This class is a general helper class for creating context-global objects like types,...
AffineMap getDimIdentityMap()
Attr getAttr(Args &&...args)
Get or construct an instance of the attribute Attr with provided arguments.
MLIRContext is the top-level object for a collection of MLIR operations.
Operation is the basic unit of execution within MLIR.
static Processor getHardwareIdForMapping(MappingLevel level, int dimension)
Computed the hardware id to use for a given mapping level.
static MappingLevel & operator++(MappingLevel &mappingLevel)
Bounded increment on MappingLevel.
static FailureOr< MappingPolicy > getMappingPolicyFromStr(StringRef policy)
LogicalResult setMappingAttr(scf::ParallelOp ploopOp, ArrayRef< ParallelLoopDimMappingAttr > mapping)
Sets the mapping attribute of a scf.parallel operation.
static constexpr int kNumHardwareIds
StringRef getMappingAttrName()
Name of the mapping attribute produced by loop mappers.
static void mapParallelOp(ParallelOp parallelOp, MappingLevel mappingLevel=MapGrid, MappingPolicy mappingPolicy=MappingPolicy::OutermostFirst)
Add mapping information to the given parallel loop.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...