#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/Requirements.h"
#include "device.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <list>
#include <memory>
#include <mutex>
#include <string>
using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy;
struct PluginManager {
using DeviceContainerTy = llvm::SmallVector<std::unique_ptr<DeviceTy>>;
using ExclusiveDevicesAccessorTy = Accessor<DeviceContainerTy>;
PluginManager() {}
void init();
void deinit();
void registerLib(__tgt_bin_desc *Desc);
void unregisterLib(__tgt_bin_desc *Desc);
void addDeviceImage(__tgt_bin_desc &TgtBinDesc,
__tgt_device_image &TgtDeviceImage) {
DeviceImages.emplace_back(
std::make_unique<DeviceImageTy>(TgtBinDesc, TgtDeviceImage));
}
llvm::Expected<DeviceTy &> getDevice(uint32_t DeviceNo);
auto devices(ExclusiveDevicesAccessorTy &DevicesAccessor) {
return llvm::make_pointee_range(*DevicesAccessor);
}
auto deviceImages() { return llvm::make_pointee_range(DeviceImages); }
HostEntriesBeginToTransTableTy HostEntriesBeginToTransTable;
std::mutex TrlTblMtx;
llvm::SmallVector<__tgt_offload_entry *> HostEntriesBeginRegistrationOrder;
HostPtrToTableMapTy HostPtrToTableMap;
std::mutex TblMapMtx;
bool delayRegisterLib(__tgt_bin_desc *Desc) {
if (RTLsLoaded)
return false;
DelayedBinDesc.push_back(Desc);
return true;
}
void registerDelayedLibraries() {
RTLsLoaded = true;
for (auto *Desc : DelayedBinDesc)
__tgt_register_lib(Desc);
DelayedBinDesc.clear();
}
int getNumDevices() { return getExclusiveDevicesAccessor()->size(); }
ExclusiveDevicesAccessorTy getExclusiveDevicesAccessor() {
return Devices.getExclusiveAccessor();
}
void initAllPlugins();
auto plugins() { return llvm::make_pointee_range(Plugins); }
auto plugins() const { return llvm::make_pointee_range(Plugins); }
int64_t getRequirements() const { return Requirements.getRequirements(); }
void addRequirements(int64_t Flags) { Requirements.addRequirements(Flags); }
int getNumActivePlugins() const {
int count = 0;
for (auto &R : plugins())
if (R.is_initialized())
++count;
return count;
}
private:
bool RTLsLoaded = false;
llvm::SmallVector<__tgt_bin_desc *> DelayedBinDesc;
llvm::SmallVector<std::unique_ptr<GenericPluginTy>> Plugins;
llvm::DenseMap<std::pair<const GenericPluginTy *, int32_t>, int32_t>
DeviceIds;
llvm::DenseSet<const __tgt_device_image *> UsedImages;
llvm::SmallVector<std::unique_ptr<DeviceImageTy>> DeviceImages;
RequirementCollection Requirements;
std::mutex RTLsMtx;
ProtectedObj<DeviceContainerTy> Devices;
};
void initRuntime();
void deinitRuntime();
extern PluginManager *PM;
#endif