blob: d0f454302a2a87b22626e144494c90ce79a69e89 [file] [edit]
//===- OpenACCUtilsGPU.cpp - OpenACC GPU Utilities ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements utility functions for OpenACC that depend on the GPU
// dialect.
//
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/OpenACC/OpenACCUtilsGPU.h"
#include "mlir/IR/SymbolTable.h"
namespace mlir {
namespace acc {
std::optional<gpu::GPUModuleOp> getOrCreateGPUModule(ModuleOp mod, bool create,
llvm::StringRef name) {
// Use default name if provided name is empty
llvm::StringRef moduleName =
name.empty() ? llvm::StringRef(kDefaultGPUModuleName) : name;
// Look for existing GPU module with the specified name
SymbolTable symTab(mod);
if (auto gpuMod = symTab.lookup<gpu::GPUModuleOp>(moduleName))
return gpuMod;
if (!create)
return std::nullopt;
// Create a new GPU module
auto *ctx = mod.getContext();
mod->setAttr(gpu::GPUDialect::getContainerModuleAttrName(),
UnitAttr::get(ctx));
OpBuilder builder(ctx);
auto gpuMod = gpu::GPUModuleOp::create(builder, mod.getLoc(), moduleName);
Block::iterator insertPt(mod.getBodyRegion().front().end());
symTab.insert(gpuMod, insertPt);
return gpuMod;
}
static Value getGPUSizeFromLaunch(gpu::LaunchOp launch,
gpu::Processor processor) {
gpu::KernelDim3 gridSize = launch.getGridSize();
gpu::KernelDim3 blockSize = launch.getBlockSize();
switch (processor) {
case gpu::Processor::ThreadX:
return blockSize.x;
case gpu::Processor::ThreadY:
return blockSize.y;
case gpu::Processor::ThreadZ:
return blockSize.z;
case gpu::Processor::BlockX:
return gridSize.x;
case gpu::Processor::BlockY:
return gridSize.y;
case gpu::Processor::BlockZ:
return gridSize.z;
default:
return {};
}
}
Value getGPUSize(gpu::Processor processor, gpu::LaunchOp launch,
const llvm::DenseMap<gpu::Processor, Value> &dimensionOps) {
if (launch)
return getGPUSizeFromLaunch(launch, processor);
assert(!dimensionOps.empty() && "dimension map is empty");
return dimensionOps.lookup(processor);
}
static Value getGPUThreadIdFromLaunch(gpu::LaunchOp launch,
gpu::Processor processor) {
gpu::KernelDim3 blockIds = launch.getBlockIds();
gpu::KernelDim3 threadIds = launch.getThreadIds();
switch (processor) {
case gpu::Processor::ThreadX:
return threadIds.x;
case gpu::Processor::ThreadY:
return threadIds.y;
case gpu::Processor::ThreadZ:
return threadIds.z;
case gpu::Processor::BlockX:
return blockIds.x;
case gpu::Processor::BlockY:
return blockIds.y;
case gpu::Processor::BlockZ:
return blockIds.z;
default:
return {};
}
}
Value getGPUThreadId(gpu::Processor processor, gpu::LaunchOp launch,
const llvm::DenseMap<gpu::Processor, Value> &indexOps) {
if (launch)
return getGPUThreadIdFromLaunch(launch, processor);
assert(!indexOps.empty() && "index map is empty");
return indexOps.lookup(processor);
}
} // namespace acc
} // namespace mlir