[clang] e5e6607 - Revert "[Libomptarget] Statically link all plugin runtimes (#87009)"
Joseph Huber via cfe-commits
cfe-commits at lists.llvm.org
Thu May 9 05:05:30 PDT 2024
Author: Joseph Huber
Date: 2024-05-09T07:05:23-05:00
New Revision: e5e66073c3d404f4dedf1b0be160b7815ccf8903
URL: https://github.com/llvm/llvm-project/commit/e5e66073c3d404f4dedf1b0be160b7815ccf8903
DIFF: https://github.com/llvm/llvm-project/commit/e5e66073c3d404f4dedf1b0be160b7815ccf8903.diff
LOG: Revert "[Libomptarget] Statically link all plugin runtimes (#87009)"
Caused failures on build-bots, reverting to investigate.
This reverts commit 80f9e814ec896fdc57ee84afad8ac4cb1f8e4627.
Added:
Modified:
clang/test/Driver/linker-wrapper-image.c
llvm/lib/Frontend/Offloading/OffloadWrapper.cpp
offload/include/PluginManager.h
offload/include/device.h
offload/plugins-nextgen/CMakeLists.txt
offload/plugins-nextgen/amdgpu/CMakeLists.txt
offload/plugins-nextgen/amdgpu/src/rtl.cpp
offload/plugins-nextgen/common/CMakeLists.txt
offload/plugins-nextgen/common/include/PluginInterface.h
offload/plugins-nextgen/common/include/Utils/ELF.h
offload/plugins-nextgen/common/src/JIT.cpp
offload/plugins-nextgen/common/src/PluginInterface.cpp
offload/plugins-nextgen/cuda/CMakeLists.txt
offload/plugins-nextgen/cuda/src/rtl.cpp
offload/plugins-nextgen/host/CMakeLists.txt
offload/plugins-nextgen/host/src/rtl.cpp
offload/src/CMakeLists.txt
offload/src/OffloadRTL.cpp
offload/src/OpenMP/InteropAPI.cpp
offload/src/PluginManager.cpp
offload/src/device.cpp
offload/src/interface.cpp
offload/tools/kernelreplay/llvm-omp-kernel-replay.cpp
offload/unittests/Plugins/NextgenPluginsTest.cpp
Removed:
################################################################################
diff --git a/clang/test/Driver/linker-wrapper-image.c b/clang/test/Driver/linker-wrapper-image.c
index 5d5d62805e174..d01445e3aed04 100644
--- a/clang/test/Driver/linker-wrapper-image.c
+++ b/clang/test/Driver/linker-wrapper-image.c
@@ -30,8 +30,8 @@
// OPENMP: define internal void @.omp_offloading.descriptor_reg() section ".text.startup" {
// OPENMP-NEXT: entry:
-// OPENMP-NEXT: call void @__tgt_register_lib(ptr @.omp_offloading.descriptor)
// OPENMP-NEXT: %0 = call i32 @atexit(ptr @.omp_offloading.descriptor_unreg)
+// OPENMP-NEXT: call void @__tgt_register_lib(ptr @.omp_offloading.descriptor)
// OPENMP-NEXT: ret void
// OPENMP-NEXT: }
diff --git a/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp b/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp
index 8b6f9ea1f4cca..7241d15ed1c67 100644
--- a/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp
+++ b/llvm/lib/Frontend/Offloading/OffloadWrapper.cpp
@@ -232,13 +232,12 @@ void createRegisterFunction(Module &M, GlobalVariable *BinDesc,
// Construct function body
IRBuilder<> Builder(BasicBlock::Create(C, "entry", Func));
- Builder.CreateCall(RegFuncC, BinDesc);
-
// Register the destructors with 'atexit'. This is expected by the CUDA
// runtime and ensures that we clean up before dynamic objects are destroyed.
- // This needs to be done after plugin initialization to ensure that it is
- // called before the plugin runtime is destroyed.
+ // This needs to be done before the runtime is called and registers its own.
Builder.CreateCall(AtExit, UnregFunc);
+
+ Builder.CreateCall(RegFuncC, BinDesc);
Builder.CreateRetVoid();
// Add this function to constructors.
diff --git a/offload/include/PluginManager.h b/offload/include/PluginManager.h
index 1d6804da75d92..eece7525e25e7 100644
--- a/offload/include/PluginManager.h
+++ b/offload/include/PluginManager.h
@@ -13,11 +13,10 @@
#ifndef OMPTARGET_PLUGIN_MANAGER_H
#define OMPTARGET_PLUGIN_MANAGER_H
-#include "PluginInterface.h"
-
#include "DeviceImage.h"
#include "ExclusiveAccess.h"
#include "Shared/APITypes.h"
+#include "Shared/PluginAPI.h"
#include "Shared/Requirements.h"
#include "device.h"
@@ -35,7 +34,38 @@
#include <mutex>
#include <string>
-using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy;
+struct PluginManager;
+
+/// Plugin adaptors should be created via `PluginAdaptorTy::create` which will
+/// invoke the constructor and call `PluginAdaptorTy::init`. Eventual errors are
+/// reported back to the caller, otherwise a valid and initialized adaptor is
+/// returned.
+struct PluginAdaptorTy {
+ /// Try to create a plugin adaptor from a filename.
+ static llvm::Expected<std::unique_ptr<PluginAdaptorTy>>
+ create(const std::string &Name);
+
+ /// Name of the shared object file representing the plugin.
+ std::string Name;
+
+ /// Access to the shared object file representing the plugin.
+ std::unique_ptr<llvm::sys::DynamicLibrary> LibraryHandler;
+
+#define PLUGIN_API_HANDLE(NAME) \
+ using NAME##_ty = decltype(__tgt_rtl_##NAME); \
+ NAME##_ty *NAME = nullptr;
+
+#include "Shared/PluginAPI.inc"
+#undef PLUGIN_API_HANDLE
+
+ /// Create a plugin adaptor for filename \p Name with a dynamic library \p DL.
+ PluginAdaptorTy(const std::string &Name,
+ std::unique_ptr<llvm::sys::DynamicLibrary> DL);
+
+ /// Initialize the plugin adaptor, this can fail in which case the adaptor is
+ /// useless.
+ llvm::Error init();
+};
/// Struct for the data required to handle plugins
struct PluginManager {
@@ -50,8 +80,6 @@ struct PluginManager {
void init();
- void deinit();
-
// Register a shared library with all (compatible) RTLs.
void registerLib(__tgt_bin_desc *Desc);
@@ -64,9 +92,10 @@ struct PluginManager {
std::make_unique<DeviceImageTy>(TgtBinDesc, TgtDeviceImage));
}
- /// Initialize as many devices as possible for this plugin. Devices that fail
- /// to initialize are ignored.
- void initDevices(GenericPluginTy &RTL);
+ /// Initialize as many devices as possible for this plugin adaptor. Devices
+ /// that fail to initialize are ignored. Returns the offset the devices were
+ /// registered at.
+ void initDevices(PluginAdaptorTy &RTL);
/// Return the device presented to the user as device \p DeviceNo if it is
/// initialized and ready. Otherwise return an error explaining the problem.
@@ -122,8 +151,8 @@ struct PluginManager {
// Initialize all plugins.
void initAllPlugins();
- /// Iterator range for all plugins (in use or not, but always valid).
- auto plugins() { return llvm::make_pointee_range(Plugins); }
+ /// Iterator range for all plugin adaptors (in use or not, but always valid).
+ auto pluginAdaptors() { return llvm::make_pointee_range(PluginAdaptors); }
/// Return the user provided requirements.
int64_t getRequirements() const { return Requirements.getRequirements(); }
@@ -135,14 +164,14 @@ struct PluginManager {
bool RTLsLoaded = false;
llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
- // List of all plugins, in use or not.
- llvm::SmallVector<std::unique_ptr<GenericPluginTy>> Plugins;
+ // List of all plugin adaptors, in use or not.
+ llvm::SmallVector<std::unique_ptr<PluginAdaptorTy>> PluginAdaptors;
- // Mapping of plugins to offsets in the device table.
- llvm::DenseMap<const GenericPluginTy *, int32_t> DeviceOffsets;
+ // Mapping of plugin adaptors to offsets in the device table.
+ llvm::DenseMap<const PluginAdaptorTy *, int32_t> DeviceOffsets;
- // Mapping of plugins to the number of used devices.
- llvm::DenseMap<const GenericPluginTy *, int32_t> DeviceUsed;
+ // Mapping of plugin adaptors to the number of used devices.
+ llvm::DenseMap<const PluginAdaptorTy *, int32_t> DeviceUsed;
// Set of all device images currently in use.
llvm::DenseSet<const __tgt_device_image *> UsedImages;
diff --git a/offload/include/device.h b/offload/include/device.h
index fd6e5fba5fc53..bd2829722bb32 100644
--- a/offload/include/device.h
+++ b/offload/include/device.h
@@ -33,19 +33,17 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "PluginInterface.h"
-using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy;
-
// Forward declarations.
+struct PluginAdaptorTy;
struct __tgt_bin_desc;
struct __tgt_target_table;
struct DeviceTy {
int32_t DeviceID;
- GenericPluginTy *RTL;
+ PluginAdaptorTy *RTL;
int32_t RTLDeviceID;
- DeviceTy(GenericPluginTy *RTL, int32_t DeviceID, int32_t RTLDeviceID);
+ DeviceTy(PluginAdaptorTy *RTL, int32_t DeviceID, int32_t RTLDeviceID);
// DeviceTy is not copyable
DeviceTy(const DeviceTy &D) = delete;
DeviceTy &operator=(const DeviceTy &D) = delete;
diff --git a/offload/plugins-nextgen/CMakeLists.txt b/offload/plugins-nextgen/CMakeLists.txt
index d1079f8a3e9cc..df625e97c7ebf 100644
--- a/offload/plugins-nextgen/CMakeLists.txt
+++ b/offload/plugins-nextgen/CMakeLists.txt
@@ -14,7 +14,7 @@
set(common_dir ${CMAKE_CURRENT_SOURCE_DIR}/common)
add_subdirectory(common)
function(add_target_library target_name lib_name)
- add_llvm_library(${target_name} STATIC
+ add_llvm_library(${target_name} SHARED
LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
AggressiveInstCombine
@@ -46,14 +46,27 @@ function(add_target_library target_name lib_name)
)
llvm_update_compile_flags(${target_name})
- target_include_directories(${target_name} PUBLIC ${common_dir}/include)
target_link_libraries(${target_name} PRIVATE
PluginCommon ${OPENMP_PTHREAD_LIB})
target_compile_definitions(${target_name} PRIVATE TARGET_NAME=${lib_name})
target_compile_definitions(${target_name} PRIVATE
DEBUG_PREFIX="TARGET ${lib_name} RTL")
- set_target_properties(${target_name} PROPERTIES POSITION_INDEPENDENT_CODE ON)
+
+ if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ # On FreeBSD, the 'environ' symbol is undefined at link time, but resolved by
+ # the dynamic linker at runtime. Therefore, allow the symbol to be undefined
+ # when creating a shared library.
+ target_link_libraries(${target_name} PRIVATE "-Wl,--allow-shlib-undefined")
+ else()
+ target_link_libraries(${target_name} PRIVATE "-Wl,-z,defs")
+ endif()
+
+ if(LIBOMP_HAVE_VERSION_SCRIPT_FLAG)
+ target_link_libraries(${target_name} PRIVATE
+ "-Wl,--version-script=${common_dir}/../exports")
+ endif()
+ set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET protected)
endfunction()
foreach(plugin IN LISTS LIBOMPTARGET_PLUGINS_TO_BUILD)
diff --git a/offload/plugins-nextgen/amdgpu/CMakeLists.txt b/offload/plugins-nextgen/amdgpu/CMakeLists.txt
index 738183f8945ed..f5f7096137c20 100644
--- a/offload/plugins-nextgen/amdgpu/CMakeLists.txt
+++ b/offload/plugins-nextgen/amdgpu/CMakeLists.txt
@@ -57,3 +57,8 @@ else()
libomptarget_say("Not generating AMDGPU tests, no supported devices detected."
" Use 'LIBOMPTARGET_FORCE_AMDGPU_TESTS' to override.")
endif()
+
+# Install plugin under the lib destination folder.
+install(TARGETS omptarget.rtl.amdgpu LIBRARY DESTINATION "${OFFLOAD_INSTALL_LIBDIR}")
+set_target_properties(omptarget.rtl.amdgpu PROPERTIES
+ INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..")
diff --git a/offload/plugins-nextgen/amdgpu/src/rtl.cpp b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
index 295685fceaa43..00650b801b420 100644
--- a/offload/plugins-nextgen/amdgpu/src/rtl.cpp
+++ b/offload/plugins-nextgen/amdgpu/src/rtl.cpp
@@ -3064,6 +3064,10 @@ struct AMDGPUPluginTy final : public GenericPluginTy {
// HSA functions from now on, e.g., hsa_shut_down.
Initialized = true;
+#ifdef OMPT_SUPPORT
+ ompt::connectLibrary();
+#endif
+
// Register event handler to detect memory errors on the devices.
Status = hsa_amd_register_system_event_handler(eventHandler, nullptr);
if (auto Err = Plugin::check(
@@ -3151,8 +3155,6 @@ struct AMDGPUPluginTy final : public GenericPluginTy {
Triple::ArchType getTripleArch() const override { return Triple::amdgcn; }
- const char *getName() const override { return GETNAME(TARGET_NAME); }
-
/// Get the ELF code for recognizing the compatible image binary.
uint16_t getMagicElfBits() const override { return ELF::EM_AMDGPU; }
@@ -3385,6 +3387,8 @@ Error AMDGPUKernelTy::printLaunchInfoDetails(GenericDeviceTy &GenericDevice,
return Plugin::success();
}
+GenericPluginTy *PluginTy::createPlugin() { return new AMDGPUPluginTy(); }
+
template <typename... ArgsTy>
static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
hsa_status_t ResultCode = static_cast<hsa_status_t>(Code);
@@ -3472,9 +3476,3 @@ void *AMDGPUDeviceTy::allocate(size_t Size, void *, TargetAllocTy Kind) {
} // namespace target
} // namespace omp
} // namespace llvm
-
-extern "C" {
-llvm::omp::target::plugin::GenericPluginTy *createPlugin_amdgpu() {
- return new llvm::omp::target::plugin::AMDGPUPluginTy();
-}
-}
diff --git a/offload/plugins-nextgen/common/CMakeLists.txt b/offload/plugins-nextgen/common/CMakeLists.txt
index a6bbb7e9454bd..acf0af63f0508 100644
--- a/offload/plugins-nextgen/common/CMakeLists.txt
+++ b/offload/plugins-nextgen/common/CMakeLists.txt
@@ -46,6 +46,7 @@ endif()
# If we have OMPT enabled include it in the list of sources.
if (OMPT_TARGET_DEFAULT AND LIBOMPTARGET_OMPT_SUPPORT)
+ target_sources(PluginCommon PRIVATE OMPT/OmptCallback.cpp)
target_include_directories(PluginCommon PRIVATE OMPT)
endif()
@@ -65,4 +66,6 @@ target_include_directories(PluginCommon PUBLIC
${LIBOMPTARGET_INCLUDE_DIR}
)
-set_target_properties(PluginCommon PROPERTIES POSITION_INDEPENDENT_CODE ON)
+set_target_properties(PluginCommon PROPERTIES
+ POSITION_INDEPENDENT_CODE ON
+ CXX_VISIBILITY_PRESET protected)
diff --git a/offload/plugins-nextgen/common/include/PluginInterface.h b/offload/plugins-nextgen/common/include/PluginInterface.h
index e7a008f3a8573..79e8464bfda5c 100644
--- a/offload/plugins-nextgen/common/include/PluginInterface.h
+++ b/offload/plugins-nextgen/common/include/PluginInterface.h
@@ -1010,9 +1010,6 @@ struct GenericPluginTy {
/// Get the target triple of this plugin.
virtual Triple::ArchType getTripleArch() const = 0;
- /// Get the constant name identifier for this plugin.
- virtual const char *getName() const = 0;
-
/// Allocate a structure using the internal allocator.
template <typename Ty> Ty *allocate() {
return reinterpret_cast<Ty *>(Allocator.Allocate(sizeof(Ty), alignof(Ty)));
@@ -1229,7 +1226,7 @@ namespace Plugin {
/// Create a success error. This is the same as calling Error::success(), but
/// it is recommended to use this one for consistency with Plugin::error() and
/// Plugin::check().
-static inline Error success() { return Error::success(); }
+static Error success() { return Error::success(); }
/// Create a string error.
template <typename... ArgsTy>
@@ -1249,6 +1246,95 @@ template <typename... ArgsTy>
static Error check(int32_t ErrorCode, const char *ErrFmt, ArgsTy... Args);
} // namespace Plugin
+/// Class for simplifying the getter operation of the plugin. Anywhere on the
+/// code, the current plugin can be retrieved by Plugin::get(). The class also
+/// declares functions to create plugin-specific object instances. The check(),
+/// createPlugin(), createDevice() and createGlobalHandler() functions should be
+/// defined by each plugin implementation.
+class PluginTy {
+ // Reference to the plugin instance.
+ static GenericPluginTy *SpecificPlugin;
+
+ PluginTy() {
+ if (auto Err = init())
+ REPORT("Failed to initialize plugin: %s\n",
+ toString(std::move(Err)).data());
+ }
+
+ ~PluginTy() {
+ if (auto Err = deinit())
+ REPORT("Failed to deinitialize plugin: %s\n",
+ toString(std::move(Err)).data());
+ }
+
+ PluginTy(const PluginTy &) = delete;
+ void operator=(const PluginTy &) = delete;
+
+ /// Create and intialize the plugin instance.
+ static Error init() {
+ assert(!SpecificPlugin && "Plugin already created");
+
+ // Create the specific plugin.
+ SpecificPlugin = createPlugin();
+ assert(SpecificPlugin && "Plugin was not created");
+
+ // Initialize the plugin.
+ return SpecificPlugin->init();
+ }
+
+ // Deinitialize and destroy the plugin instance.
+ static Error deinit() {
+ assert(SpecificPlugin && "Plugin no longer valid");
+
+ for (int32_t DevNo = 0, NumDev = SpecificPlugin->getNumDevices();
+ DevNo < NumDev; ++DevNo)
+ if (auto Err = SpecificPlugin->deinitDevice(DevNo))
+ return Err;
+
+ // Deinitialize the plugin.
+ if (auto Err = SpecificPlugin->deinit())
+ return Err;
+
+ // Delete the plugin instance.
+ delete SpecificPlugin;
+
+ // Invalidate the plugin reference.
+ SpecificPlugin = nullptr;
+
+ return Plugin::success();
+ }
+
+public:
+ /// Initialize the plugin if needed. The plugin could have been initialized by
+ /// a previous call to Plugin::get().
+ static Error initIfNeeded() {
+ // Trigger the initialization if needed.
+ get();
+
+ return Error::success();
+ }
+
+ /// Get a reference (or create if it was not created) to the plugin instance.
+ static GenericPluginTy &get() {
+ // This static variable will initialize the underlying plugin instance in
+ // case there was no previous explicit initialization. The initialization is
+ // thread safe.
+ static PluginTy Plugin;
+
+ assert(SpecificPlugin && "Plugin is not active");
+ return *SpecificPlugin;
+ }
+
+ /// Get a reference to the plugin with a specific plugin-specific type.
+ template <typename Ty> static Ty &get() { return static_cast<Ty &>(get()); }
+
+ /// Indicate whether the plugin is active.
+ static bool isActive() { return SpecificPlugin != nullptr; }
+
+ /// Create a plugin instance.
+ static GenericPluginTy *createPlugin();
+};
+
/// Auxiliary interface class for GenericDeviceResourceManagerTy. This class
/// acts as a reference to a device resource, such as a stream, and requires
/// some basic functions to be implemented. The derived class should define an
diff --git a/offload/plugins-nextgen/common/include/Utils/ELF.h b/offload/plugins-nextgen/common/include/Utils/ELF.h
index dcfdb5bd7b035..f87e0a5ed02b4 100644
--- a/offload/plugins-nextgen/common/include/Utils/ELF.h
+++ b/offload/plugins-nextgen/common/include/Utils/ELF.h
@@ -13,6 +13,8 @@
#ifndef LLVM_OPENMP_LIBOMPTARGET_PLUGINS_ELF_UTILS_H
#define LLVM_OPENMP_LIBOMPTARGET_PLUGINS_ELF_UTILS_H
+#include "Shared/PluginAPI.h"
+
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFObjectFile.h"
diff --git a/offload/plugins-nextgen/common/src/JIT.cpp b/offload/plugins-nextgen/common/src/JIT.cpp
index 9d58e6060646b..9eb610cab4de6 100644
--- a/offload/plugins-nextgen/common/src/JIT.cpp
+++ b/offload/plugins-nextgen/common/src/JIT.cpp
@@ -56,6 +56,28 @@ bool isImageBitcode(const __tgt_device_image &Image) {
return identify_magic(Binary) == file_magic::bitcode;
}
+std::once_flag InitFlag;
+
+void init(Triple TT) {
+ codegen::RegisterCodeGenFlags();
+#ifdef LIBOMPTARGET_JIT_NVPTX
+ if (TT.isNVPTX()) {
+ LLVMInitializeNVPTXTargetInfo();
+ LLVMInitializeNVPTXTarget();
+ LLVMInitializeNVPTXTargetMC();
+ LLVMInitializeNVPTXAsmPrinter();
+ }
+#endif
+#ifdef LIBOMPTARGET_JIT_AMDGPU
+ if (TT.isAMDGPU()) {
+ LLVMInitializeAMDGPUTargetInfo();
+ LLVMInitializeAMDGPUTarget();
+ LLVMInitializeAMDGPUTargetMC();
+ LLVMInitializeAMDGPUAsmPrinter();
+ }
+#endif
+}
+
Expected<std::unique_ptr<Module>>
createModuleFromMemoryBuffer(std::unique_ptr<MemoryBuffer> &MB,
LLVMContext &Context) {
@@ -126,23 +148,7 @@ createTargetMachine(Module &M, std::string CPU, unsigned OptLevel) {
} // namespace
JITEngine::JITEngine(Triple::ArchType TA) : TT(Triple::getArchTypeName(TA)) {
- codegen::RegisterCodeGenFlags();
-#ifdef LIBOMPTARGET_JIT_NVPTX
- if (TT.isNVPTX()) {
- LLVMInitializeNVPTXTargetInfo();
- LLVMInitializeNVPTXTarget();
- LLVMInitializeNVPTXTargetMC();
- LLVMInitializeNVPTXAsmPrinter();
- }
-#endif
-#ifdef LIBOMPTARGET_JIT_AMDGPU
- if (TT.isAMDGPU()) {
- LLVMInitializeAMDGPUTargetInfo();
- LLVMInitializeAMDGPUTarget();
- LLVMInitializeAMDGPUTargetMC();
- LLVMInitializeAMDGPUAsmPrinter();
- }
-#endif
+ std::call_once(InitFlag, init, TT);
}
void JITEngine::opt(TargetMachine *TM, TargetLibraryInfoImpl *TLII, Module &M,
diff --git a/offload/plugins-nextgen/common/src/PluginInterface.cpp b/offload/plugins-nextgen/common/src/PluginInterface.cpp
index fae197527850a..8de93ba17a560 100644
--- a/offload/plugins-nextgen/common/src/PluginInterface.cpp
+++ b/offload/plugins-nextgen/common/src/PluginInterface.cpp
@@ -13,6 +13,7 @@
#include "Shared/APITypes.h"
#include "Shared/Debug.h"
#include "Shared/Environment.h"
+#include "Shared/PluginAPI.h"
#include "GlobalHandler.h"
#include "JIT.h"
@@ -38,6 +39,8 @@ using namespace omp;
using namespace target;
using namespace plugin;
+GenericPluginTy *PluginTy::SpecificPlugin = nullptr;
+
// TODO: Fix any thread safety issues for multi-threaded kernel recording.
struct RecordReplayTy {
@@ -2032,3 +2035,205 @@ bool llvm::omp::target::plugin::libomptargetSupportsRPC() {
return false;
#endif
}
+
+/// Exposed library API function, basically wrappers around the GenericDeviceTy
+/// functionality with the same name. All non-async functions are redirected
+/// to the async versions right away with a NULL AsyncInfoPtr.
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t __tgt_rtl_init_plugin() {
+ auto Err = PluginTy::initIfNeeded();
+ if (Err) {
+ [[maybe_unused]] std::string ErrStr = toString(std::move(Err));
+ DP("Failed to init plugin: %s", ErrStr.c_str());
+ return OFFLOAD_FAIL;
+ }
+
+ return OFFLOAD_SUCCESS;
+}
+
+int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *Image) {
+ if (!PluginTy::isActive())
+ return false;
+
+ return PluginTy::get().is_valid_binary(Image);
+}
+
+int32_t __tgt_rtl_init_device(int32_t DeviceId) {
+ return PluginTy::get().init_device(DeviceId);
+}
+
+int32_t __tgt_rtl_number_of_devices() {
+ return PluginTy::get().number_of_devices();
+}
+
+int64_t __tgt_rtl_init_requires(int64_t RequiresFlags) {
+ return PluginTy::get().init_requires(RequiresFlags);
+}
+
+int32_t __tgt_rtl_is_data_exchangable(int32_t SrcDeviceId,
+ int32_t DstDeviceId) {
+ return PluginTy::get().is_data_exchangable(SrcDeviceId, DstDeviceId);
+}
+
+int32_t __tgt_rtl_initialize_record_replay(int32_t DeviceId, int64_t MemorySize,
+ void *VAddr, bool isRecord,
+ bool SaveOutput,
+ uint64_t &ReqPtrArgOffset) {
+ return PluginTy::get().initialize_record_replay(
+ DeviceId, MemorySize, VAddr, isRecord, SaveOutput, ReqPtrArgOffset);
+}
+
+int32_t __tgt_rtl_load_binary(int32_t DeviceId, __tgt_device_image *TgtImage,
+ __tgt_device_binary *Binary) {
+ return PluginTy::get().load_binary(DeviceId, TgtImage, Binary);
+}
+
+void *__tgt_rtl_data_alloc(int32_t DeviceId, int64_t Size, void *HostPtr,
+ int32_t Kind) {
+ return PluginTy::get().data_alloc(DeviceId, Size, HostPtr, Kind);
+}
+
+int32_t __tgt_rtl_data_delete(int32_t DeviceId, void *TgtPtr, int32_t Kind) {
+ return PluginTy::get().data_delete(DeviceId, TgtPtr, Kind);
+}
+
+int32_t __tgt_rtl_data_lock(int32_t DeviceId, void *Ptr, int64_t Size,
+ void **LockedPtr) {
+ return PluginTy::get().data_lock(DeviceId, Ptr, Size, LockedPtr);
+}
+
+int32_t __tgt_rtl_data_unlock(int32_t DeviceId, void *Ptr) {
+ return PluginTy::get().data_unlock(DeviceId, Ptr);
+}
+
+int32_t __tgt_rtl_data_notify_mapped(int32_t DeviceId, void *HstPtr,
+ int64_t Size) {
+ return PluginTy::get().data_notify_mapped(DeviceId, HstPtr, Size);
+}
+
+int32_t __tgt_rtl_data_notify_unmapped(int32_t DeviceId, void *HstPtr) {
+ return PluginTy::get().data_notify_unmapped(DeviceId, HstPtr);
+}
+
+int32_t __tgt_rtl_data_submit(int32_t DeviceId, void *TgtPtr, void *HstPtr,
+ int64_t Size) {
+ return PluginTy::get().data_submit(DeviceId, TgtPtr, HstPtr, Size);
+}
+
+int32_t __tgt_rtl_data_submit_async(int32_t DeviceId, void *TgtPtr,
+ void *HstPtr, int64_t Size,
+ __tgt_async_info *AsyncInfoPtr) {
+ return PluginTy::get().data_submit_async(DeviceId, TgtPtr, HstPtr, Size,
+ AsyncInfoPtr);
+}
+
+int32_t __tgt_rtl_data_retrieve(int32_t DeviceId, void *HstPtr, void *TgtPtr,
+ int64_t Size) {
+ return PluginTy::get().data_retrieve(DeviceId, HstPtr, TgtPtr, Size);
+}
+
+int32_t __tgt_rtl_data_retrieve_async(int32_t DeviceId, void *HstPtr,
+ void *TgtPtr, int64_t Size,
+ __tgt_async_info *AsyncInfoPtr) {
+ return PluginTy::get().data_retrieve_async(DeviceId, HstPtr, TgtPtr, Size,
+ AsyncInfoPtr);
+}
+
+int32_t __tgt_rtl_data_exchange(int32_t SrcDeviceId, void *SrcPtr,
+ int32_t DstDeviceId, void *DstPtr,
+ int64_t Size) {
+ return PluginTy::get().data_exchange(SrcDeviceId, SrcPtr, DstDeviceId, DstPtr,
+ Size);
+}
+
+int32_t __tgt_rtl_data_exchange_async(int32_t SrcDeviceId, void *SrcPtr,
+ int DstDeviceId, void *DstPtr,
+ int64_t Size,
+ __tgt_async_info *AsyncInfo) {
+ return PluginTy::get().data_exchange_async(SrcDeviceId, SrcPtr, DstDeviceId,
+ DstPtr, Size, AsyncInfo);
+}
+
+int32_t __tgt_rtl_launch_kernel(int32_t DeviceId, void *TgtEntryPtr,
+ void **TgtArgs, ptr
diff _t *TgtOffsets,
+ KernelArgsTy *KernelArgs,
+ __tgt_async_info *AsyncInfoPtr) {
+ return PluginTy::get().launch_kernel(DeviceId, TgtEntryPtr, TgtArgs,
+ TgtOffsets, KernelArgs, AsyncInfoPtr);
+}
+
+int32_t __tgt_rtl_synchronize(int32_t DeviceId,
+ __tgt_async_info *AsyncInfoPtr) {
+ return PluginTy::get().synchronize(DeviceId, AsyncInfoPtr);
+}
+
+int32_t __tgt_rtl_query_async(int32_t DeviceId,
+ __tgt_async_info *AsyncInfoPtr) {
+ return PluginTy::get().query_async(DeviceId, AsyncInfoPtr);
+}
+
+void __tgt_rtl_print_device_info(int32_t DeviceId) {
+ PluginTy::get().print_device_info(DeviceId);
+}
+
+int32_t __tgt_rtl_create_event(int32_t DeviceId, void **EventPtr) {
+ return PluginTy::get().create_event(DeviceId, EventPtr);
+}
+
+int32_t __tgt_rtl_record_event(int32_t DeviceId, void *EventPtr,
+ __tgt_async_info *AsyncInfoPtr) {
+ return PluginTy::get().record_event(DeviceId, EventPtr, AsyncInfoPtr);
+}
+
+int32_t __tgt_rtl_wait_event(int32_t DeviceId, void *EventPtr,
+ __tgt_async_info *AsyncInfoPtr) {
+ return PluginTy::get().wait_event(DeviceId, EventPtr, AsyncInfoPtr);
+}
+
+int32_t __tgt_rtl_sync_event(int32_t DeviceId, void *EventPtr) {
+ return PluginTy::get().sync_event(DeviceId, EventPtr);
+}
+
+int32_t __tgt_rtl_destroy_event(int32_t DeviceId, void *EventPtr) {
+ return PluginTy::get().destroy_event(DeviceId, EventPtr);
+}
+
+void __tgt_rtl_set_info_flag(uint32_t NewInfoLevel) {
+ return PluginTy::get().set_info_flag(NewInfoLevel);
+}
+
+int32_t __tgt_rtl_init_async_info(int32_t DeviceId,
+ __tgt_async_info **AsyncInfoPtr) {
+ return PluginTy::get().init_async_info(DeviceId, AsyncInfoPtr);
+}
+
+int32_t __tgt_rtl_init_device_info(int32_t DeviceId,
+ __tgt_device_info *DeviceInfo,
+ const char **ErrStr) {
+ return PluginTy::get().init_device_info(DeviceId, DeviceInfo, ErrStr);
+}
+
+int32_t __tgt_rtl_set_device_offset(int32_t DeviceIdOffset) {
+ return PluginTy::get().set_device_offset(DeviceIdOffset);
+}
+
+int32_t __tgt_rtl_use_auto_zero_copy(int32_t DeviceId) {
+ return PluginTy::get().use_auto_zero_copy(DeviceId);
+}
+
+int32_t __tgt_rtl_get_global(__tgt_device_binary Binary, uint64_t Size,
+ const char *Name, void **DevicePtr) {
+ return PluginTy::get().get_global(Binary, Size, Name, DevicePtr);
+}
+
+int32_t __tgt_rtl_get_function(__tgt_device_binary Binary, const char *Name,
+ void **KernelPtr) {
+ return PluginTy::get().get_function(Binary, Name, KernelPtr);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/offload/plugins-nextgen/cuda/CMakeLists.txt b/offload/plugins-nextgen/cuda/CMakeLists.txt
index dd684bb223431..0284bd22d2a4d 100644
--- a/offload/plugins-nextgen/cuda/CMakeLists.txt
+++ b/offload/plugins-nextgen/cuda/CMakeLists.txt
@@ -51,3 +51,8 @@ else()
libomptarget_say("Not generating NVIDIA tests, no supported devices detected."
" Use 'LIBOMPTARGET_FORCE_NVIDIA_TESTS' to override.")
endif()
+
+# Install plugin under the lib destination folder.
+install(TARGETS omptarget.rtl.cuda LIBRARY DESTINATION "${OFFLOAD_INSTALL_LIBDIR}")
+set_target_properties(omptarget.rtl.cuda PROPERTIES
+ INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/..")
diff --git a/offload/plugins-nextgen/cuda/src/rtl.cpp b/offload/plugins-nextgen/cuda/src/rtl.cpp
index b260334baa18b..fc74c6aa23fdd 100644
--- a/offload/plugins-nextgen/cuda/src/rtl.cpp
+++ b/offload/plugins-nextgen/cuda/src/rtl.cpp
@@ -1342,6 +1342,10 @@ struct CUDAPluginTy final : public GenericPluginTy {
return 0;
}
+#ifdef OMPT_SUPPORT
+ ompt::connectLibrary();
+#endif
+
if (Res == CUDA_ERROR_NO_DEVICE) {
// Do not initialize if there are no devices.
DP("There are no devices supporting CUDA.\n");
@@ -1386,8 +1390,6 @@ struct CUDAPluginTy final : public GenericPluginTy {
return Triple::nvptx64;
}
- const char *getName() const override { return GETNAME(TARGET_NAME); }
-
/// Check whether the image is compatible with the available CUDA devices.
Expected<bool> isELFCompatible(StringRef Image) const override {
auto ElfOrErr =
@@ -1493,6 +1495,8 @@ Error CUDADeviceTy::dataExchangeImpl(const void *SrcPtr,
return Plugin::check(Res, "Error in cuMemcpyDtoDAsync: %s");
}
+GenericPluginTy *PluginTy::createPlugin() { return new CUDAPluginTy(); }
+
template <typename... ArgsTy>
static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
CUresult ResultCode = static_cast<CUresult>(Code);
@@ -1512,9 +1516,3 @@ static Error Plugin::check(int32_t Code, const char *ErrFmt, ArgsTy... Args) {
} // namespace target
} // namespace omp
} // namespace llvm
-
-extern "C" {
-llvm::omp::target::plugin::GenericPluginTy *createPlugin_cuda() {
- return new llvm::omp::target::plugin::CUDAPluginTy();
-}
-}
diff --git a/offload/plugins-nextgen/host/CMakeLists.txt b/offload/plugins-nextgen/host/CMakeLists.txt
index 72b5681283fe2..1d000442c84d4 100644
--- a/offload/plugins-nextgen/host/CMakeLists.txt
+++ b/offload/plugins-nextgen/host/CMakeLists.txt
@@ -31,6 +31,14 @@ else()
target_include_directories(omptarget.rtl.host PRIVATE dynamic_ffi)
endif()
+# Install plugin under the lib destination folder.
+install(TARGETS omptarget.rtl.host
+ LIBRARY DESTINATION "${OFFLOAD_INSTALL_LIBDIR}")
+set_target_properties(omptarget.rtl.host PROPERTIES
+ INSTALL_RPATH "$ORIGIN" BUILD_RPATH "$ORIGIN:${CMAKE_CURRENT_BINARY_DIR}/.."
+ POSITION_INDEPENDENT_CODE ON
+ CXX_VISIBILITY_PRESET protected)
+
target_include_directories(omptarget.rtl.host PRIVATE
${LIBOMPTARGET_INCLUDE_DIR})
diff --git a/offload/plugins-nextgen/host/src/rtl.cpp b/offload/plugins-nextgen/host/src/rtl.cpp
index 409b44b1640ad..4bdcae3dd6a1b 100644
--- a/offload/plugins-nextgen/host/src/rtl.cpp
+++ b/offload/plugins-nextgen/host/src/rtl.cpp
@@ -385,6 +385,10 @@ struct GenELF64PluginTy final : public GenericPluginTy {
/// Initialize the plugin and return the number of devices.
Expected<int32_t> initImpl() override {
+#ifdef OMPT_SUPPORT
+ ompt::connectLibrary();
+#endif
+
#ifdef USES_DYNAMIC_FFI
if (auto Err = Plugin::check(ffi_init(), "Failed to initialize libffi"))
return std::move(Err);
@@ -441,10 +445,10 @@ struct GenELF64PluginTy final : public GenericPluginTy {
return llvm::Triple::UnknownArch;
#endif
}
-
- const char *getName() const override { return GETNAME(TARGET_NAME); }
};
+GenericPluginTy *PluginTy::createPlugin() { return new GenELF64PluginTy(); }
+
template <typename... ArgsTy>
static Error Plugin::check(int32_t Code, const char *ErrMsg, ArgsTy... Args) {
if (Code == 0)
@@ -458,9 +462,3 @@ static Error Plugin::check(int32_t Code, const char *ErrMsg, ArgsTy... Args) {
} // namespace target
} // namespace omp
} // namespace llvm
-
-extern "C" {
-llvm::omp::target::plugin::GenericPluginTy *createPlugin_host() {
- return new llvm::omp::target::plugin::GenELF64PluginTy();
-}
-}
diff --git a/offload/src/CMakeLists.txt b/offload/src/CMakeLists.txt
index 8fe6d19d83eb3..eda5a85ff1ab8 100644
--- a/offload/src/CMakeLists.txt
+++ b/offload/src/CMakeLists.txt
@@ -65,10 +65,6 @@ target_compile_definitions(omptarget PRIVATE
DEBUG_PREFIX="omptarget"
)
-foreach(plugin IN LISTS LIBOMPTARGET_PLUGINS_TO_BUILD)
- target_link_libraries(omptarget PRIVATE omptarget.rtl.${plugin})
-endforeach()
-
target_compile_options(omptarget PUBLIC ${offload_compile_flags})
target_link_options(omptarget PUBLIC ${offload_link_flags})
diff --git a/offload/src/OffloadRTL.cpp b/offload/src/OffloadRTL.cpp
index 29b573a27d087..dd75b1b181505 100644
--- a/offload/src/OffloadRTL.cpp
+++ b/offload/src/OffloadRTL.cpp
@@ -50,7 +50,6 @@ void deinitRuntime() {
if (RefCount == 1) {
DP("Deinit offload library!\n");
- PM->deinit();
delete PM;
PM = nullptr;
}
diff --git a/offload/src/OpenMP/InteropAPI.cpp b/offload/src/OpenMP/InteropAPI.cpp
index bdbc440c64a2c..1a995cde7816e 100644
--- a/offload/src/OpenMP/InteropAPI.cpp
+++ b/offload/src/OpenMP/InteropAPI.cpp
@@ -230,14 +230,14 @@ void __tgt_interop_init(ident_t *LocRef, int32_t Gtid,
}
DeviceTy &Device = *DeviceOrErr;
- if (!Device.RTL ||
+ if (!Device.RTL || !Device.RTL->init_device_info ||
Device.RTL->init_device_info(DeviceId, &(InteropPtr)->device_info,
&(InteropPtr)->err_str)) {
delete InteropPtr;
InteropPtr = omp_interop_none;
}
if (InteropType == kmp_interop_type_tasksync) {
- if (!Device.RTL ||
+ if (!Device.RTL || !Device.RTL->init_async_info ||
Device.RTL->init_async_info(DeviceId, &(InteropPtr)->async_info)) {
delete InteropPtr;
InteropPtr = omp_interop_none;
diff --git a/offload/src/PluginManager.cpp b/offload/src/PluginManager.cpp
index 191afa345641a..dbb556c179e58 100644
--- a/offload/src/PluginManager.cpp
+++ b/offload/src/PluginManager.cpp
@@ -23,25 +23,85 @@ using namespace llvm::sys;
PluginManager *PM = nullptr;
-// Every plugin exports this method to create an instance of the plugin type.
-#define PLUGIN_TARGET(Name) extern "C" GenericPluginTy *createPlugin_##Name();
-#include "Shared/Targets.def"
+Expected<std::unique_ptr<PluginAdaptorTy>>
+PluginAdaptorTy::create(const std::string &Name) {
+ DP("Attempting to load library '%s'...\n", Name.c_str());
+ TIMESCOPE_WITH_NAME_AND_IDENT(Name, (const ident_t *)nullptr);
+
+ std::string ErrMsg;
+ auto LibraryHandler = std::make_unique<DynamicLibrary>(
+ DynamicLibrary::getPermanentLibrary(Name.c_str(), &ErrMsg));
+
+ if (!LibraryHandler->isValid()) {
+ // Library does not exist or cannot be found.
+ return createStringError(inconvertibleErrorCode(),
+ "Unable to load library '%s': %s!\n", Name.c_str(),
+ ErrMsg.c_str());
+ }
+
+ DP("Successfully loaded library '%s'!\n", Name.c_str());
+ auto PluginAdaptor = std::unique_ptr<PluginAdaptorTy>(
+ new PluginAdaptorTy(Name, std::move(LibraryHandler)));
+ if (auto Err = PluginAdaptor->init())
+ return Err;
+ return std::move(PluginAdaptor);
+}
+
+PluginAdaptorTy::PluginAdaptorTy(const std::string &Name,
+ std::unique_ptr<llvm::sys::DynamicLibrary> DL)
+ : Name(Name), LibraryHandler(std::move(DL)) {}
+
+Error PluginAdaptorTy::init() {
+
+#define PLUGIN_API_HANDLE(NAME) \
+ NAME = reinterpret_cast<decltype(NAME)>( \
+ LibraryHandler->getAddressOfSymbol(GETNAME(__tgt_rtl_##NAME))); \
+ if (!NAME) { \
+ return createStringError(inconvertibleErrorCode(), \
+ "Invalid plugin as necessary interface function " \
+ "(%s) was not found.\n", \
+ std::string(#NAME).c_str()); \
+ }
+
+#include "Shared/PluginAPI.inc"
+#undef PLUGIN_API_HANDLE
+
+ // Remove plugin on failure to call optional init_plugin
+ int32_t Rc = init_plugin();
+ if (Rc != OFFLOAD_SUCCESS) {
+ return createStringError(inconvertibleErrorCode(),
+ "Unable to initialize library '%s': %u!\n",
+ Name.c_str(), Rc);
+ }
+
+ // No devices are supported by this RTL?
+ int32_t NumberOfPluginDevices = number_of_devices();
+ if (!NumberOfPluginDevices) {
+ return createStringError(inconvertibleErrorCode(),
+ "No devices supported in this RTL\n");
+ }
+
+ DP("Registered '%s' with %d plugin visible devices!\n", Name.c_str(),
+ NumberOfPluginDevices);
+ return Error::success();
+}
void PluginManager::init() {
TIMESCOPE();
DP("Loading RTLs...\n");
- // Attempt to create an instance of each supported plugin.
+ // Attempt to open all the plugins and, if they exist, check if the interface
+ // is correct and if they are supporting any devices.
#define PLUGIN_TARGET(Name) \
do { \
- auto Plugin = std::unique_ptr<GenericPluginTy>(createPlugin_##Name()); \
- if (auto Err = Plugin->init()) { \
- [[maybe_unused]] std::string InfoMsg = toString(std::move(Err)); \
- DP("Failed to init plugin: %s\n", InfoMsg.c_str()); \
+ auto PluginAdaptorOrErr = \
+ PluginAdaptorTy::create("libomptarget.rtl." #Name ".so"); \
+ if (!PluginAdaptorOrErr) { \
+ [[maybe_unused]] std::string InfoMsg = \
+ toString(PluginAdaptorOrErr.takeError()); \
+ DP("%s", InfoMsg.c_str()); \
} else { \
- DP("Registered plugin %s with %d visible device(s)\n", \
- Plugin->getName(), Plugin->number_of_devices()); \
- Plugins.emplace_back(std::move(Plugin)); \
+ PluginAdaptors.push_back(std::move(*PluginAdaptorOrErr)); \
} \
} while (false);
#include "Shared/Targets.def"
@@ -49,29 +109,15 @@ void PluginManager::init() {
DP("RTLs loaded!\n");
}
-void PluginManager::deinit() {
- TIMESCOPE();
- DP("Unloading RTLs...\n");
-
- for (auto &Plugin : Plugins) {
- if (auto Err = Plugin->deinit()) {
- [[maybe_unused]] std::string InfoMsg = toString(std::move(Err));
- DP("Failed to deinit plugin: %s\n", InfoMsg.c_str());
- }
- Plugin.release();
- }
-
- DP("RTLs unloaded!\n");
-}
-
-void PluginManager::initDevices(GenericPluginTy &RTL) {
+void PluginManager::initDevices(PluginAdaptorTy &RTL) {
// If this RTL has already been initialized.
if (PM->DeviceOffsets.contains(&RTL))
return;
TIMESCOPE();
// If this RTL is not already in use, initialize it.
- assert(RTL.number_of_devices() > 0 && "Tried to initialize useless plugin!");
+ assert(RTL.number_of_devices() > 0 &&
+ "Tried to initialize useless plugin adaptor");
// Initialize the device information for the RTL we are about to use.
auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
@@ -111,12 +157,13 @@ void PluginManager::initDevices(GenericPluginTy &RTL) {
DeviceOffsets[&RTL] = DeviceOffset;
DeviceUsed[&RTL] = NumberOfUserDevices;
- DP("Plugin has index %d, exposes %d out of %d devices!\n", DeviceOffset,
- NumberOfUserDevices, RTL.number_of_devices());
+ DP("Plugin adaptor " DPxMOD " has index %d, exposes %d out of %d devices!\n",
+ DPxPTR(RTL.LibraryHandler.get()), DeviceOffset, NumberOfUserDevices,
+ RTL.number_of_devices());
}
void PluginManager::initAllPlugins() {
- for (auto &R : Plugins)
+ for (auto &R : PluginAdaptors)
initDevices(*R);
}
@@ -169,22 +216,19 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) {
// Obtain the image and information that was previously extracted.
__tgt_device_image *Img = &DI.getExecutableImage();
- GenericPluginTy *FoundRTL = nullptr;
+ PluginAdaptorTy *FoundRTL = nullptr;
// Scan the RTLs that have associated images until we find one that supports
// the current image.
- for (auto &R : PM->plugins()) {
- if (!R.number_of_devices())
- continue;
-
+ for (auto &R : PM->pluginAdaptors()) {
if (!R.is_valid_binary(Img)) {
DP("Image " DPxMOD " is NOT compatible with RTL %s!\n",
- DPxPTR(Img->ImageStart), R.getName());
+ DPxPTR(Img->ImageStart), R.Name.c_str());
continue;
}
DP("Image " DPxMOD " is compatible with RTL %s!\n",
- DPxPTR(Img->ImageStart), R.getName());
+ DPxPTR(Img->ImageStart), R.Name.c_str());
PM->initDevices(R);
@@ -203,7 +247,7 @@ void PluginManager::registerLib(__tgt_bin_desc *Desc) {
(PM->HostEntriesBeginToTransTable)[Desc->HostEntriesBegin];
DP("Registering image " DPxMOD " with RTL %s!\n", DPxPTR(Img->ImageStart),
- R.getName());
+ R.Name.c_str());
registerImageIntoTranslationTable(TransTable, PM->DeviceOffsets[&R],
PM->DeviceUsed[&R], Img);
@@ -238,11 +282,11 @@ void PluginManager::unregisterLib(__tgt_bin_desc *Desc) {
// Obtain the image and information that was previously extracted.
__tgt_device_image *Img = &DI.getExecutableImage();
- GenericPluginTy *FoundRTL = NULL;
+ PluginAdaptorTy *FoundRTL = NULL;
// Scan the RTLs that have associated images until we find one that supports
// the current image. We only need to scan RTLs that are already being used.
- for (auto &R : PM->plugins()) {
+ for (auto &R : PM->pluginAdaptors()) {
if (!DeviceOffsets.contains(&R))
continue;
@@ -252,7 +296,8 @@ void PluginManager::unregisterLib(__tgt_bin_desc *Desc) {
FoundRTL = &R;
- DP("Unregistered image " DPxMOD " from RTL\n", DPxPTR(Img->ImageStart));
+ DP("Unregistered image " DPxMOD " from RTL " DPxMOD "!\n",
+ DPxPTR(Img->ImageStart), DPxPTR(R.LibraryHandler.get()));
break;
}
diff --git a/offload/src/device.cpp b/offload/src/device.cpp
index 749b4c567f8e4..44a2facc8d3dd 100644
--- a/offload/src/device.cpp
+++ b/offload/src/device.cpp
@@ -64,7 +64,7 @@ int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device,
return OFFLOAD_SUCCESS;
}
-DeviceTy::DeviceTy(GenericPluginTy *RTL, int32_t DeviceID, int32_t RTLDeviceID)
+DeviceTy::DeviceTy(PluginAdaptorTy *RTL, int32_t DeviceID, int32_t RTLDeviceID)
: DeviceID(DeviceID), RTL(RTL), RTLDeviceID(RTLDeviceID),
MappingInfo(*this) {}
@@ -192,6 +192,7 @@ int32_t DeviceTy::dataExchange(void *SrcPtr, DeviceTy &DstDev, void *DstPtr,
RTLDeviceID, SrcPtr, DstDev.RTLDeviceID, DstPtr, Size,
/*CodePtr=*/OMPT_GET_RETURN_ADDRESS);)
if (!AsyncInfo) {
+ assert(RTL->data_exchange && "RTL->data_exchange is nullptr");
return RTL->data_exchange(RTLDeviceID, SrcPtr, DstDev.RTLDeviceID, DstPtr,
Size);
}
diff --git a/offload/src/interface.cpp b/offload/src/interface.cpp
index 763b051cc6d77..557703632c625 100644
--- a/offload/src/interface.cpp
+++ b/offload/src/interface.cpp
@@ -456,6 +456,8 @@ EXTERN void __tgt_set_info_flag(uint32_t NewInfoLevel) {
assert(PM && "Runtime not initialized");
std::atomic<uint32_t> &InfoLevel = getInfoLevelInternal();
InfoLevel.store(NewInfoLevel);
+ for (auto &R : PM->pluginAdaptors())
+ R.set_info_flag(NewInfoLevel);
}
EXTERN int __tgt_print_device_info(int64_t DeviceId) {
diff --git a/offload/tools/kernelreplay/llvm-omp-kernel-replay.cpp b/offload/tools/kernelreplay/llvm-omp-kernel-replay.cpp
index 1e9a6a84d8058..761e04e4c7bbd 100644
--- a/offload/tools/kernelreplay/llvm-omp-kernel-replay.cpp
+++ b/offload/tools/kernelreplay/llvm-omp-kernel-replay.cpp
@@ -13,6 +13,8 @@
#include "omptarget.h"
+#include "Shared/PluginAPI.h"
+
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/MemoryBuffer.h"
diff --git a/offload/unittests/Plugins/NextgenPluginsTest.cpp b/offload/unittests/Plugins/NextgenPluginsTest.cpp
index 479b3f614aed2..635bd1637c903 100644
--- a/offload/unittests/Plugins/NextgenPluginsTest.cpp
+++ b/offload/unittests/Plugins/NextgenPluginsTest.cpp
@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
+#include "Shared/PluginAPI.h"
#include "omptarget.h"
#include "gtest/gtest.h"
More information about the cfe-commits
mailing list