Expand Up
@@ -16,6 +16,8 @@
#include " private.h"
#include " rtl.h"
#include " Utilities.h"
#include < cassert>
#include < cstdlib>
#include < cstring>
Expand All
@@ -24,16 +26,17 @@
using namespace llvm ;
using namespace llvm ::sys;
using namespace llvm ::omp::target;
// List of all plugins that can support offloading.
static const char *RTLNames[] = {
/* PowerPC target */ " libomptarget.rtl.ppc64.so " ,
/* x86_64 target */ " libomptarget.rtl.x86_64.so " ,
/* CUDA target */ " libomptarget.rtl.cuda.so " ,
/* AArch64 target */ " libomptarget.rtl.aarch64.so " ,
/* SX-Aurora VE target */ " libomptarget.rtl.ve.so " ,
/* AMDGPU target */ " libomptarget.rtl.amdgpu.so " ,
/* Remote target */ " libomptarget.rtl.rpc.so " ,
/* PowerPC target */ " libomptarget.rtl.ppc64" ,
/* x86_64 target */ " libomptarget.rtl.x86_64" ,
/* CUDA target */ " libomptarget.rtl.cuda" ,
/* AArch64 target */ " libomptarget.rtl.aarch64" ,
/* SX-Aurora VE target */ " libomptarget.rtl.ve" ,
/* AMDGPU target */ " libomptarget.rtl.amdgpu" ,
/* Remote target */ " libomptarget.rtl.rpc" ,
};
PluginManager *PM;
Expand Down
Expand Up
@@ -86,152 +89,166 @@ void RTLsTy::loadRTLs() {
DP (" Loading RTLs...\n " );
BoolEnvar NextGenPlugins (" LIBOMPTARGET_NEXTGEN_PLUGINS" , false );
// Attempt to open all the plugins and, if they exist, check if the interface
// is correct and if they are supporting any devices.
for (auto *Name : RTLNames) {
DP (" Loading library '%s'...\n " , Name);
std::string ErrMsg;
auto DynLibrary = std::make_unique<sys::DynamicLibrary>(
sys::DynamicLibrary::getPermanentLibrary (Name, &ErrMsg));
if (!DynLibrary->isValid ()) {
// Library does not exist or cannot be found.
DP (" Unable to load library '%s': %s!\n " , Name, ErrMsg.c_str ());
continue ;
}
DP (" Successfully loaded library '%s'!\n " , Name);
for (const char *Name : RTLNames) {
AllRTLs.emplace_back ();
// Retrieve the RTL information from the runtime library.
RTLInfoTy &R = AllRTLs.back ();
// Remove plugin on failure to call optional init_plugin
*((void **)&R.init_plugin ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_plugin" );
if (R.init_plugin ) {
int32_t Rc = R.init_plugin ();
if (Rc != OFFLOAD_SUCCESS) {
DP (" Unable to initialize library '%s': %u!\n " , Name, Rc);
AllRTLs.pop_back ();
RTLInfoTy &RTL = AllRTLs.back ();
const std::string BaseRTLName (Name);
if (NextGenPlugins) {
if (attemptLoadRTL (BaseRTLName + " .nextgen.so" , RTL))
continue ;
}
}
bool ValidPlugin = true ;
if (!(*((void **)&R.is_valid_binary ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_is_valid_binary" )))
ValidPlugin = false ;
if (!(*((void **)&R.number_of_devices ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_number_of_devices" )))
ValidPlugin = false ;
if (!(*((void **)&R.init_device ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_device" )))
ValidPlugin = false ;
if (!(*((void **)&R.load_binary ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_load_binary" )))
ValidPlugin = false ;
if (!(*((void **)&R.data_alloc ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_alloc" )))
ValidPlugin = false ;
if (!(*((void **)&R.data_submit ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_submit" )))
ValidPlugin = false ;
if (!(*((void **)&R.data_retrieve ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_retrieve" )))
ValidPlugin = false ;
if (!(*((void **)&R.data_delete ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_delete" )))
ValidPlugin = false ;
if (!(*((void **)&R.run_region ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_run_target_region" )))
ValidPlugin = false ;
if (!(*((void **)&R.run_team_region ) = DynLibrary->getAddressOfSymbol (
" __tgt_rtl_run_target_team_region" )))
ValidPlugin = false ;
// Invalid plugin
if (!ValidPlugin) {
DP (" Invalid plugin as necessary interface is not found.\n " );
AllRTLs.pop_back ();
continue ;
DP (" Falling back to original plugin...\n " );
}
// No devices are supported by this RTL?
if (!(R.NumberOfDevices = R.number_of_devices ())) {
// The RTL is invalid! Will pop the object from the RTLs list.
DP (" No devices supported in this RTL\n " );
if (!attemptLoadRTL (BaseRTLName + " .so" , RTL))
AllRTLs.pop_back ();
continue ;
}
DP (" RTLs loaded!\n " );
}
bool RTLsTy::attemptLoadRTL (const std::string &RTLName, RTLInfoTy &RTL) {
const char *Name = RTLName.c_str ();
DP (" Loading library '%s'...\n " , Name);
std::string ErrMsg;
auto DynLibrary = std::make_unique<sys::DynamicLibrary>(
sys::DynamicLibrary::getPermanentLibrary (Name, &ErrMsg));
if (!DynLibrary->isValid ()) {
// Library does not exist or cannot be found.
DP (" Unable to load library '%s': %s!\n " , Name, ErrMsg.c_str ());
return false ;
}
DP (" Successfully loaded library '%s'!\n " , Name);
// Remove plugin on failure to call optional init_plugin
*((void **)&RTL.init_plugin ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_plugin" );
if (RTL.init_plugin ) {
int32_t Rc = RTL.init_plugin ();
if (Rc != OFFLOAD_SUCCESS) {
DP (" Unable to initialize library '%s': %u!\n " , Name, Rc);
return false ;
}
}
#ifdef OMPTARGET_DEBUG
R.RTLName = Name;
#endif
bool ValidPlugin = true ;
if (!(*((void **)&RTL.is_valid_binary ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_is_valid_binary" )))
ValidPlugin = false ;
if (!(*((void **)&RTL.number_of_devices ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_number_of_devices" )))
ValidPlugin = false ;
if (!(*((void **)&RTL.init_device ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_device" )))
ValidPlugin = false ;
if (!(*((void **)&RTL.load_binary ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_load_binary" )))
ValidPlugin = false ;
if (!(*((void **)&RTL.data_alloc ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_alloc" )))
ValidPlugin = false ;
if (!(*((void **)&RTL.data_submit ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_submit" )))
ValidPlugin = false ;
if (!(*((void **)&RTL.data_retrieve ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_retrieve" )))
ValidPlugin = false ;
if (!(*((void **)&RTL.data_delete ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_delete" )))
ValidPlugin = false ;
if (!(*((void **)&RTL.run_region ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_run_target_region" )))
ValidPlugin = false ;
if (!(*((void **)&RTL.run_team_region ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_run_target_team_region" )))
ValidPlugin = false ;
// Invalid plugin
if (!ValidPlugin) {
DP (" Invalid plugin as necessary interface is not found.\n " );
return false ;
}
DP (" Registering RTL %s supporting %d devices!\n " , R.RTLName .c_str (),
R.NumberOfDevices );
// Optional functions
*((void **)&R.deinit_plugin ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_deinit_plugin" );
*((void **)&R.is_valid_binary_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_is_valid_binary_info" );
*((void **)&R.deinit_device ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_deinit_device" );
*((void **)&R.init_requires ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_requires" );
*((void **)&R.data_submit_async ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_submit_async" );
*((void **)&R.data_retrieve_async ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_retrieve_async" );
*((void **)&R.run_region_async ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_run_target_region_async" );
*((void **)&R.run_team_region_async ) = DynLibrary->getAddressOfSymbol (
" __tgt_rtl_run_target_team_region_async" );
*((void **)&R.synchronize ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_synchronize" );
*((void **)&R.data_exchange ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_exchange" );
*((void **)&R.data_exchange_async ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_exchange_async" );
*((void **)&R.is_data_exchangable ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_is_data_exchangable" );
*((void **)&R.register_lib ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_register_lib" );
*((void **)&R.unregister_lib ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_unregister_lib" );
*((void **)&R.supports_empty_images ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_supports_empty_images" );
*((void **)&R.set_info_flag ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_set_info_flag" );
*((void **)&R.print_device_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_print_device_info" );
*((void **)&R.create_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_create_event" );
*((void **)&R.record_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_record_event" );
*((void **)&R.wait_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_wait_event" );
*((void **)&R.sync_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_sync_event" );
*((void **)&R.destroy_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_destroy_event" );
*((void **)&R.release_async_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_release_async_info" );
*((void **)&R.init_async_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_async_info" );
*((void **)&R.init_device_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_device_info" );
R.LibraryHandler = std::move (DynLibrary);
// No devices are supported by this RTL?
if (!(RTL.NumberOfDevices = RTL.number_of_devices ())) {
// The RTL is invalid! Will pop the object from the RTLs list.
DP (" No devices supported in this RTL\n " );
return false ;
}
DP (" RTLs loaded!\n " );
#ifdef LIBOMPTARGET_DEBUG
RTL.RTLName = Name;
#endif
return ;
DP (" Registering RTL %s supporting %d devices!\n " , Name, RTL.NumberOfDevices );
// Optional functions
*((void **)&RTL.deinit_plugin ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_deinit_plugin" );
*((void **)&RTL.is_valid_binary_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_is_valid_binary_info" );
*((void **)&RTL.deinit_device ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_deinit_device" );
*((void **)&RTL.init_requires ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_requires" );
*((void **)&RTL.data_submit_async ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_submit_async" );
*((void **)&RTL.data_retrieve_async ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_retrieve_async" );
*((void **)&RTL.run_region_async ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_run_target_region_async" );
*((void **)&RTL.run_team_region_async ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_run_target_team_region_async" );
*((void **)&RTL.synchronize ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_synchronize" );
*((void **)&RTL.data_exchange ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_exchange" );
*((void **)&RTL.data_exchange_async ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_data_exchange_async" );
*((void **)&RTL.is_data_exchangable ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_is_data_exchangable" );
*((void **)&RTL.register_lib ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_register_lib" );
*((void **)&RTL.unregister_lib ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_unregister_lib" );
*((void **)&RTL.supports_empty_images ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_supports_empty_images" );
*((void **)&RTL.set_info_flag ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_set_info_flag" );
*((void **)&RTL.print_device_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_print_device_info" );
*((void **)&RTL.create_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_create_event" );
*((void **)&RTL.record_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_record_event" );
*((void **)&RTL.wait_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_wait_event" );
*((void **)&RTL.sync_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_sync_event" );
*((void **)&RTL.destroy_event ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_destroy_event" );
*((void **)&RTL.release_async_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_release_async_info" );
*((void **)&RTL.init_async_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_async_info" );
*((void **)&RTL.init_device_info ) =
DynLibrary->getAddressOfSymbol (" __tgt_rtl_init_device_info" );
RTL.LibraryHandler = std::move (DynLibrary);
// Successfully loaded
return true ;
}
// //////////////////////////////////////////////////////////////////////////////
Expand Down