CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
146 lines
4.8 KiB
C++
146 lines
4.8 KiB
C++
//===- ACCDeclareGPUModuleInsertion.cpp
|
|
//------------------------------------===//
|
|
//
|
|
// 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 pass copies globals marked with the `acc.declare` attribute into the
|
|
// GPU module so that device code (e.g. acc routine, compute regions) can
|
|
// reference them.
|
|
//
|
|
// Overview:
|
|
// ---------
|
|
// Globals that have the `acc.declare` attribute (from the OpenACC declare
|
|
// directive or from the `ACCImplicitDeclare` pass) must be present in the
|
|
// GPU module for device code to use them. This pass inserts copies of those
|
|
// globals into the GPU module, creating the module if it does not yet exist.
|
|
// The host copy of each global remains in the parent module.
|
|
//
|
|
// Example:
|
|
// --------
|
|
//
|
|
// Before:
|
|
// module {
|
|
// memref.global @arr : memref<7xf32> = dense<0.0>
|
|
// {acc.declare = #acc.declare<dataClause = acc_create>}
|
|
// }
|
|
//
|
|
// After:
|
|
// module attributes {gpu.container_module} {
|
|
// memref.global @arr : memref<7xf32> = dense<0.0>
|
|
// {acc.declare = #acc.declare<dataClause = acc_create>}
|
|
// gpu.module @acc_gpu_module {
|
|
// memref.global @arr : memref<7xf32> = dense<0.0>
|
|
// {acc.declare = #acc.declare<dataClause = acc_create>}
|
|
// }
|
|
// }
|
|
//
|
|
// Requirements:
|
|
// -------------
|
|
// The pass uses the `acc::OpenACCSupport` for:
|
|
// - getOrCreateGPUModule: to obtain or create the GPU module.
|
|
// - emitNYI: to report failure when GPU module creation is not supported.
|
|
// If no custom implementation is registered, the default implementation is
|
|
// used (see OpenACCSupport).
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
|
|
#include "mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h"
|
|
#include "mlir/Dialect/OpenACC/OpenACC.h"
|
|
#include "mlir/Dialect/OpenACC/Transforms/Passes.h"
|
|
#include "mlir/IR/BuiltinOps.h"
|
|
#include "mlir/IR/Operation.h"
|
|
#include "mlir/IR/OperationSupport.h"
|
|
#include "mlir/IR/SymbolTable.h"
|
|
|
|
namespace mlir {
|
|
namespace acc {
|
|
#define GEN_PASS_DEF_ACCDECLAREGPUMODULEINSERTION
|
|
#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
|
|
} // namespace acc
|
|
} // namespace mlir
|
|
|
|
#define DEBUG_TYPE "acc-declare-gpu-module-insertion"
|
|
|
|
using namespace mlir;
|
|
|
|
namespace {
|
|
|
|
static bool hasAccDeclareGlobals(ModuleOp mod) {
|
|
for (Operation &op : mod.getBody()->getOperations())
|
|
if (op.getAttr(acc::getDeclareAttrName()))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
class ACCDeclareGPUModuleInsertion
|
|
: public acc::impl::ACCDeclareGPUModuleInsertionBase<
|
|
ACCDeclareGPUModuleInsertion> {
|
|
public:
|
|
using acc::impl::ACCDeclareGPUModuleInsertionBase<
|
|
ACCDeclareGPUModuleInsertion>::ACCDeclareGPUModuleInsertionBase;
|
|
|
|
LogicalResult copyGlobalsToGPUModule(gpu::GPUModuleOp gpuMod, ModuleOp mod,
|
|
acc::OpenACCSupport &accSupport) const {
|
|
SymbolTable gpuSymTable(gpuMod);
|
|
|
|
for (Operation &globalOp : mod.getBody()->getOperations()) {
|
|
if (!globalOp.getAttr(acc::getDeclareAttrName()))
|
|
continue;
|
|
|
|
auto symOp = dyn_cast<SymbolOpInterface>(&globalOp);
|
|
if (!symOp)
|
|
continue;
|
|
|
|
StringAttr name = symOp.getNameAttr();
|
|
|
|
if (Operation *existing = gpuSymTable.lookup(name.getValue())) {
|
|
// Reuse only when the existing GPU symbol is structurally equivalent to
|
|
// the global we would insert. Otherwise treat as a conflict (different
|
|
// op type or different definition).
|
|
if (existing->getName() != globalOp.getName() ||
|
|
!OperationEquivalence::isEquivalentTo(
|
|
existing, &globalOp,
|
|
OperationEquivalence::ignoreValueEquivalence,
|
|
/*markEquivalent=*/nullptr,
|
|
OperationEquivalence::IgnoreLocations)) {
|
|
accSupport.emitNYI(globalOp.getLoc(),
|
|
llvm::Twine("duplicate global symbol '") +
|
|
name.getValue() + "' in gpu module");
|
|
return failure();
|
|
}
|
|
continue;
|
|
}
|
|
|
|
gpuSymTable.insert(globalOp.clone());
|
|
}
|
|
return success();
|
|
}
|
|
|
|
void runOnOperation() override {
|
|
ModuleOp mod = getOperation();
|
|
|
|
// Check for any candidates first - do this to avoid creating the GPU module
|
|
// if there are no candidates.
|
|
if (!hasAccDeclareGlobals(mod))
|
|
return;
|
|
|
|
acc::OpenACCSupport &accSupport = getAnalysis<acc::OpenACCSupport>();
|
|
std::optional<gpu::GPUModuleOp> gpuMod =
|
|
accSupport.getOrCreateGPUModule(mod);
|
|
if (!gpuMod) {
|
|
accSupport.emitNYI(mod.getLoc(), "Failed to create GPU module");
|
|
return;
|
|
}
|
|
|
|
if (failed(copyGlobalsToGPUModule(*gpuMod, mod, accSupport)))
|
|
return;
|
|
}
|
|
};
|
|
|
|
} // namespace
|