//===-- PluginManager.cpp - Plugin loading and communication API ---------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Functionality for handling plugins.
//
//===----------------------------------------------------------------------===//

#include "PluginManager.h"
#include "OmpAccError.h"
#include "OpenMP/OMPT/Interface.h"
#include "OpenMP/OffloadRTL.h"
#include "Shared/Debug.h"
#include "Shared/Environment.h"
#include "Shared/Profile.h"
#include "device.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <memory>
#include <string>

#ifdef OMPT_SUPPORT
using namespace llvm::omp::target::ompt;
#endif

using namespace llvm;
using namespace llvm::sys;
using namespace llvm::omp::target::error;
using namespace llvm::omp::target::debug;
using namespace llvm::omp::target::helpers;

namespace llvm::offload::tmp {
GenericPluginTy *__ol_tgt_GetPluginFromPlatform(ol_platform_handle_t Platform);
llvm::omp::target::plugin::DeviceImageTy *
__ol_tgt_GetDeviceImageFromProgram(ol_program_handle_t Program);
} // namespace llvm::offload::tmp

void PluginManager::init() {
  TIMESCOPE();

  ODBG(ODT_Init) << "Loading RTLs";
  if (ol_result_t Res = olInit(nullptr)) {
    REPORT() << "Failed to initialize liboffload: " << Res->Details;
    return;
  }
  LibOffloadInitialized = true;

  if (auto Err = iteratePlatforms(
          [](ol_platform_handle_t Platform, void *Data) {
            auto *PM = static_cast<PluginManager *>(Data);
            auto *Plugin =
                llvm::offload::tmp::__ol_tgt_GetPluginFromPlatform(Platform);
            PlatformTy &P =
                PM->Platforms
                    .try_emplace(Platform, PlatformTy::create(Platform))
                    .first->second;
            ODBG(ODT_Init) << "Adding plugin " << P.getName()
                           << " from liboffload";
            PM->Plugins.push_back(Plugin);
          },
          this))
    REPORT() << "Failed to iterate platforms: " << toString(std::move(Err));

  ODBG(ODT_Init) << "RTLs loaded!";
}

void PluginManager::deinit() {
  TIMESCOPE();
  ODBG(ODT_Deinit) << "Unloading RTLs...";

  auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
  for (DeviceTy &Device : devices(ExclusiveDevicesAccessor)) {
    if (auto Err = Device.deinit())
      REPORT() << "Failed to deinitialize device " << Device.DeviceID << ": "
               << toString(std::move(Err));
  }

  Plugins.clear();
  Platforms.clear();
  if (LibOffloadInitialized) {
    if (auto Err = olShutDown())
      REPORT() << "Failed to denitialize liboffload: " << Err->Details;
  }

  ODBG(ODT_Deinit) << "RTLs unloaded!";
}

bool PluginManager::initializeDevice(ol_device_handle_t DeviceHandle) {
  if (DeviceIds.find(DeviceHandle) != DeviceIds.end()) {
    auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
    (*ExclusiveDevicesAccessor)[DeviceIds[DeviceHandle]]->setHasPendingImages(
        true);
    return true;
  }

  ol_platform_handle_t PlatformHandle;
  if (olGetDeviceInfo(DeviceHandle, OL_DEVICE_INFO_PLATFORM,
                      sizeof(PlatformHandle), &PlatformHandle)) {
    REPORT() << "Failed to get platform while initializing device "
             << DeviceHandle;
    return false;
  }

  // Initialize the device information for the RTL we are about to use.
  auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();

  int32_t UserId = ExclusiveDevicesAccessor->size();

  auto Device =
      std::make_unique<DeviceTy>(UserId, PlatformHandle, DeviceHandle, this);
  if (auto Err = Device->init()) {
    std::string InfoMsg = toString(std::move(Err));
    ODBG(ODT_Init) << "Failed to init device " << UserId << ": " << InfoMsg;
    return false;
  }

  ExclusiveDevicesAccessor->push_back(std::move(Device));

  // We need to map between the liboffload device handle and the OpenMP device
  // id.
  DeviceIds[DeviceHandle] = UserId;

  return true;
}

void PluginManager::initializeAllDevices() {
  if (!LibOffloadInitialized)
    return;
  if (auto Err = iterateDevices(
          [this](ol_device_handle_t Device) { initializeDevice(Device); })) {
    REPORT() << "Failed to iterate devices: " << toString(std::move(Err));
  }
}

// Returns a pointer to the binary descriptor, upgrading from a legacy format if
// necessary.
__tgt_bin_desc *PluginManager::upgradeLegacyEntries(__tgt_bin_desc *Desc) {
  struct LegacyEntryTy {
    void *Address;
    char *SymbolName;
    size_t Size;
    int32_t Flags;
    int32_t Data;
  };

  if (UpgradedDescriptors.contains(Desc))
    return &UpgradedDescriptors[Desc];

  if (Desc->HostEntriesBegin == Desc->HostEntriesEnd ||
      Desc->HostEntriesBegin->Reserved == 0)
    return Desc;

  // The new format mandates that each entry starts with eight bytes of zeroes.
  // This allows us to detect the old format as this is a null pointer.
  llvm::SmallVector<llvm::offloading::EntryTy, 0> &NewEntries =
      LegacyEntries.emplace_back();
  for (LegacyEntryTy &Entry : llvm::make_range(
           reinterpret_cast<LegacyEntryTy *>(Desc->HostEntriesBegin),
           reinterpret_cast<LegacyEntryTy *>(Desc->HostEntriesEnd))) {
    llvm::offloading::EntryTy &NewEntry = NewEntries.emplace_back();

    NewEntry.Address = Entry.Address;
    NewEntry.Flags = Entry.Flags;
    NewEntry.Data = Entry.Data;
    NewEntry.Size = Entry.Size;
    NewEntry.SymbolName = Entry.SymbolName;
    NewEntry.Kind = object::OffloadKind::OFK_OpenMP;
  }

  // Create a new image struct so we can update the entries list.
  llvm::SmallVector<__tgt_device_image, 0> &NewImages =
      LegacyImages.emplace_back();
  for (int32_t Image = 0; Image < Desc->NumDeviceImages; ++Image)
    NewImages.emplace_back(
        __tgt_device_image{Desc->DeviceImages[Image].ImageStart,
                           Desc->DeviceImages[Image].ImageEnd,
                           NewEntries.begin(), NewEntries.end()});

  // Create the new binary descriptor containing the newly created memory.
  __tgt_bin_desc &NewDesc = UpgradedDescriptors[Desc];
  NewDesc.DeviceImages = NewImages.begin();
  NewDesc.NumDeviceImages = Desc->NumDeviceImages;
  NewDesc.HostEntriesBegin = NewEntries.begin();
  NewDesc.HostEntriesEnd = NewEntries.end();

  return &NewDesc;
}

bool PluginManager::registerImageOnDevice(
    ol_device_handle_t DeviceHandle, __tgt_bin_desc *Desc,
    __tgt_device_image *Img,
    llvm::SmallVectorImpl<ol_device_handle_t> &UsedDevices) {

  ol_platform_handle_t PlatformHandle;
  if (auto Res = olGetDeviceInfo(DeviceHandle, OL_DEVICE_INFO_PLATFORM,
                                 sizeof(PlatformHandle), &PlatformHandle)) {
    REPORT() << "Failed to get platform info for device " << DeviceHandle << ":"
             << Res->Details;
    PlatformHandle = nullptr;
  }

  llvm::StringRef PlatformName = "Unknown";
  if (PlatformHandle)
    if (const PlatformTy *Platform = getPlatform(PlatformHandle))
      PlatformName = Platform->getName();

  // We only want a single matching image to be registered for each binary
  // descriptor. This prevents multiple of the same image from being registered
  // for the same device in the case that they are mutually compatible, such as
  // sm_80 and sm_89.
  if (llvm::is_contained(UsedDevices, DeviceHandle)) {
    ODBG(ODT_Init) << "Image " << Img->ImageStart
                   << " is a duplicate, not loaded on RTL " << PlatformName
                   << " on device " << DeviceHandle;
    return false;
  }

  ODBG(ODT_Init) << "Image " << Img->ImageStart << " with RTL " << PlatformName
                 << " on device " << DeviceHandle;

  if (!initializeDevice(DeviceHandle)) {
    ODBG(ODT_Init) << "Skipping image " << Img->ImageStart << " on device "
                   << DeviceHandle << ": device failed to initialize";
    return false;
  }

  // Initialize (if necessary) translation table for this library.
  std::lock_guard<std::mutex> LG(TrlTblMtx);
  if (!HostEntriesBeginToTransTable.count(Desc->HostEntriesBegin)) {
    HostEntriesBeginRegistrationOrder.push_back(Desc->HostEntriesBegin);
    TranslationTable &TT = HostEntriesBeginToTransTable[Desc->HostEntriesBegin];
    TT.HostTable.EntriesBegin = Desc->HostEntriesBegin;
    TT.HostTable.EntriesEnd = Desc->HostEntriesEnd;
  }

  // Retrieve translation table for this library.
  TranslationTable &TT = HostEntriesBeginToTransTable[Desc->HostEntriesBegin];

  ODBG(ODT_Init) << "Registering image " << Img->ImageStart << " with RTL "
                 << PlatformName;

  auto UserId = DeviceIds.at(DeviceHandle);
  if (TT.TargetsTable.size() < static_cast<size_t>(UserId + 1)) {
    TT.DeviceTables.resize(UserId + 1, {});
    TT.TargetsImages.resize(UserId + 1, nullptr);
    TT.TargetsEntries.resize(UserId + 1, {});
    TT.TargetsTable.resize(UserId + 1, nullptr);
  }

  // Register the image for this target type and invalidate the table.
  TT.TargetsImages[UserId] = Img;
  TT.TargetsTable[UserId] = nullptr;

  UsedDevices.push_back(DeviceHandle);
  return true;
}

void PluginManager::registerLib(__tgt_bin_desc *Desc) {
  // There are no devices to register with if liboffload was not initialized.
  if (!LibOffloadInitialized)
    return;

  RTLsMtx.lock();

  // Upgrade the entries from the legacy implementation if necessary.
  Desc = upgradeLegacyEntries(Desc);

  // Add in all the OpenMP requirements associated with this binary.
  for (llvm::offloading::EntryTy &Entry :
       llvm::make_range(Desc->HostEntriesBegin, Desc->HostEntriesEnd))
    if (Entry.Kind == object::OffloadKind::OFK_OpenMP &&
        Entry.Flags == OMP_REGISTER_REQUIRES)
      addRequirements(Entry.Data);

  // Extract the executable image and extra information if available.
  for (int32_t i = 0; i < Desc->NumDeviceImages; ++i)
    addDeviceImage(*Desc, Desc->DeviceImages[i]);

  // Register the images with the RTLs that understand them, if any.
  llvm::SmallVector<ol_device_handle_t> UsedDevices;
  for (int32_t i = 0; i < Desc->NumDeviceImages; ++i) {
    // Obtain the image and information that was previously extracted.
    __tgt_device_image *Img = &Desc->DeviceImages[i];

    struct RegisterImageState {
      PluginManager *PM;
      __tgt_bin_desc *Desc;
      __tgt_device_image *Img;
      llvm::SmallVectorImpl<ol_device_handle_t> &UsedDevices;
      bool FoundRTL = false;
    } State{this, Desc, Img, UsedDevices, false};

    if (ol_result_t Res = olIterateCompatibleDevices(
            Img->ImageStart, utils::getPtrDiff(Img->ImageEnd, Img->ImageStart),
            [](ol_device_handle_t DeviceHandle, void *Data) {
              auto &State = *static_cast<RegisterImageState *>(Data);
              if (State.PM->registerImageOnDevice(DeviceHandle, State.Desc,
                                                  State.Img, State.UsedDevices))
                State.FoundRTL = true;
              return true;
            },
            &State))
      REPORT() << "Failed to iterate compatible devices: " << Res->Details;

    if (!State.FoundRTL)
      ODBG(ODT_Init) << "No RTL found for image " << Img->ImageStart << "!";
  }
  RTLsMtx.unlock();

  bool UseAutoZeroCopy = false;

  auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
  // APUs are homogeneous set of GPUs. Check the first device for
  // configuring Auto Zero-Copy.
  if (ExclusiveDevicesAccessor->size() > 0) {
    auto &Device = *(*ExclusiveDevicesAccessor)[0];
    UseAutoZeroCopy = Device.useAutoZeroCopy();
  }

  if (UseAutoZeroCopy)
    addRequirements(OMPX_REQ_AUTO_ZERO_COPY);

  ODBG(ODT_Init) << "Done registering entries!";
}

void PluginManager::unregisterLib(__tgt_bin_desc *Desc) {
  ODBG(ODT_Deinit) << "Unloading target library!";

  Desc = upgradeLegacyEntries(Desc);

  // Remove entries from HostPtrToTableMap
  TblMapMtx.lock();
  for (llvm::offloading::EntryTy *Cur = Desc->HostEntriesBegin;
       Cur < Desc->HostEntriesEnd; ++Cur) {
    if (Cur->Kind == object::OffloadKind::OFK_OpenMP)
      HostPtrToTableMap.erase(Cur->Address);
  }

  // Remove translation table for this descriptor.
  auto TransTable = HostEntriesBeginToTransTable.find(Desc->HostEntriesBegin);
  if (TransTable != HostEntriesBeginToTransTable.end()) {
    ODBG(ODT_Deinit) << "Removing translation table for descriptor "
                     << Desc->HostEntriesBegin;
    HostEntriesBeginToTransTable.erase(TransTable);
  } else {
    ODBG(ODT_Deinit) << "Translation table for descriptor "
                     << Desc->HostEntriesBegin << " cannot be found, probably "
                     << "it has been already removed.";
  }

  TblMapMtx.unlock();

  ODBG(ODT_Deinit) << "Done unregistering library!";
}

/// Map global data and execute pending ctors
int PluginManager::loadImagesOntoDevice(DeviceTy &Device) {
  /*
   * Map global data
   */
  int32_t DeviceId = Device.DeviceID;
  int Rc = OFFLOAD_SUCCESS;
  {
    std::lock_guard<decltype(TrlTblMtx)> LG(TrlTblMtx);
    for (auto *HostEntriesBegin : HostEntriesBeginRegistrationOrder) {
      TranslationTable *TransTable =
          &HostEntriesBeginToTransTable[HostEntriesBegin];
      ODBG(ODT_Init) << "Trans table " << TransTable->HostTable.EntriesBegin
                     << " : " << TransTable->HostTable.EntriesEnd;
      if (TransTable->HostTable.EntriesBegin ==
          TransTable->HostTable.EntriesEnd) {
        // No host entry so no need to proceed
        continue;
      }

      if (TransTable->TargetsTable[DeviceId] != 0) {
        // Library entries have already been processed
        continue;
      }

      // 1) get image.
      assert(TransTable->TargetsImages.size() > (size_t)DeviceId &&
             "Not expecting a device ID outside the table's bounds!");
      __tgt_device_image *Img = TransTable->TargetsImages[DeviceId];
      if (!Img) {
        REPORT() << "No image loaded for device id " << DeviceId << ".";
        Rc = OFFLOAD_FAIL;
        break;
      }

      // 2) Load the image onto the given device.
      auto LoadedOrErr = Device.loadBinary(Img);
      if (llvm::Error Err = LoadedOrErr.takeError()) {
        REPORT() << "Failed to load image " << llvm::toString(std::move(Err));
        Rc = OFFLOAD_FAIL;
        break;
      }

      // 3) Create the translation table.
      llvm::SmallVector<llvm::offloading::EntryTy> &DeviceEntries =
          TransTable->TargetsEntries[DeviceId];
      for (llvm::offloading::EntryTy &Entry :
           llvm::make_range(Img->EntriesBegin, Img->EntriesEnd)) {
        if (Entry.Kind != object::OffloadKind::OFK_OpenMP)
          continue;

        ProgramTy &Program = *LoadedOrErr;

        llvm::offloading::EntryTy DeviceEntry = Entry;
        if (Entry.Size) {
          if (!(Entry.Flags & OMP_DECLARE_TARGET_INDIRECT_VTABLE)) {
            auto AddrOrErr = Device.getAndRecordGlobalAddress(
                Program, Entry.SymbolName, Entry.Size);
            if (!AddrOrErr) {
              REPORT() << "Failed to load symbol " << Entry.SymbolName << ": "
                       << llvm::toString(AddrOrErr.takeError());
            } else {
              DeviceEntry.Address = *AddrOrErr;
            }
          }

          // If unified memory is active, the corresponding global is a device
          // reference to the host global. We need to initialize the pointer on
          // the device to point to the memory on the host.
          if (!(Entry.Flags & OMP_DECLARE_TARGET_INDIRECT_VTABLE) &&
              !(Entry.Flags & OMP_DECLARE_TARGET_INDIRECT) &&
              ((getRequirements() & OMP_REQ_UNIFIED_SHARED_MEMORY) ||
               (getRequirements() & OMPX_REQ_AUTO_ZERO_COPY))) {
            if (Device.submitDataSync(DeviceEntry.Address, Entry.Address,
                                      Entry.Size) != OFFLOAD_SUCCESS)
              REPORT() << "Failed to write symbol for USM " << Entry.SymbolName;
          }
        } else if (Entry.Address) {
          auto AddrOrErr = Program.getKernelAddress(Entry.SymbolName);
          if (!AddrOrErr) {
            REPORT() << "Failed to load kernel " << Entry.SymbolName << ": "
                     << llvm::toString(AddrOrErr.takeError());
          } else {
            ol_symbol_handle_t KernelSym = *AddrOrErr;
            DeviceEntry.Address = KernelSym;

            // Read this kernel's launch-geometry properties once, from its
            // "<name>_kernel_environment" global, and cache them on the device
            // for use at launch time.
            SmallString<128> EnvName(Entry.SymbolName);
            EnvName += "_kernel_environment";
            KernelEnvironmentTy KernelEnv{};
            // Read the kernel environment from the image on the host; it is
            // constant, so no device access is needed.
            if (auto Err = Program.readGlobalFromImage(
                    EnvName.c_str(), &KernelEnv, sizeof(KernelEnv))) {
              std::string ErrStr = toString(std::move(Err));
              KernelEnv = KernelEnvironmentTy{};
              KernelEnv.Configuration.ExecMode =
                  llvm::omp::OMP_TGT_EXEC_MODE_BARE;
              ODBG(ODT_Mapping)
                  << "Failed to read kernel environment for '"
                  << Entry.SymbolName << "' (" << ErrStr << "), using default "
                  << KernelLaunchInfoTy::getExecutionModeName(
                         static_cast<llvm::omp::OMPTgtExecModeFlags>(
                             KernelEnv.Configuration.ExecMode))
                  << " execution mode";
            }
            uint32_t StaticBlockMemSize = 0;
            uint32_t KernelMaxThreads = 0;
            if (auto Res = olGetSymbolInfo(
                    KernelSym, OL_SYMBOL_INFO_KERNEL_STATIC_BLOCK_MEM_SIZE,
                    sizeof(StaticBlockMemSize), &StaticBlockMemSize))
              REPORT() << "Failed to query static block memory size of "
                       << Entry.SymbolName << ": " << Res->Details;
            if (auto Res = olGetSymbolInfo(
                    KernelSym, OL_SYMBOL_INFO_KERNEL_MAX_THREADS,
                    sizeof(KernelMaxThreads), &KernelMaxThreads))
              REPORT() << "Failed to query max threads of " << Entry.SymbolName
                       << ": " << Res->Details;

            auto &Image =
                *llvm::offload::tmp::__ol_tgt_GetDeviceImageFromProgram(
                    Program.getHandle());
            const auto &Cfg = KernelEnv.Configuration;
            KernelLaunchInfoTy LaunchInfo;
            LaunchInfo.Name = Entry.SymbolName;
            LaunchInfo.Image = Image.getMemoryBuffer();
            LaunchInfo.IRImage = Image.getIRImageMemoryBuffer();
            LaunchInfo.Mode =
                static_cast<llvm::omp::OMPTgtExecModeFlags>(Cfg.ExecMode);
            LaunchInfo.ReductionDataSize = Cfg.ReductionDataSize;
            LaunchInfo.StaticBlockMemSize = StaticBlockMemSize;
            // Max = Config.Max > 0 ? min(Config.Max, Device.Max) : Device.Max,
            // further clamped to the kernel function's own driver-reported
            // maximum.
            uint32_t DeviceThreadLimit = Device.getThreadLimit();
            LaunchInfo.MaxNumThreads =
                std::min(Cfg.MaxThreads > 0 ? std::min(uint32_t(Cfg.MaxThreads),
                                                       DeviceThreadLimit)
                                            : DeviceThreadLimit,
                         KernelMaxThreads);
            uint32_t DefaultNumThreads = Device.getDefaultNumThreads();
            LaunchInfo.PreferredNumThreads =
                Cfg.MinThreads > 0
                    ? std::max(Cfg.MinThreads, int32_t(DefaultNumThreads))
                    : DefaultNumThreads;

            Device.setKernelLaunchInfo(DeviceEntry.Address, LaunchInfo);
          }
        }
        ODBG(ODT_Mapping) << "Entry point " << Entry.Address << " maps to"
                          << (Entry.Size ? " global" : "") << " "
                          << Entry.SymbolName << " (" << DeviceEntry.Address
                          << ")";

        DeviceEntries.emplace_back(DeviceEntry);
      }

      // Set the storage for the table and get a pointer to it.
      __tgt_target_table DeviceTable{&DeviceEntries[0],
                                     &DeviceEntries[0] + DeviceEntries.size()};
      TransTable->DeviceTables[DeviceId] = DeviceTable;
      __tgt_target_table *TargetTable = TransTable->TargetsTable[DeviceId] =
          &TransTable->DeviceTables[DeviceId];

      MappingInfoTy::HDTTMapAccessorTy HDTTMap =
          Device.getMappingInfo().HostDataToTargetMap.getExclusiveAccessor();

      __tgt_target_table *HostTable = &TransTable->HostTable;
      for (llvm::offloading::EntryTy *
               CurrDeviceEntry = TargetTable->EntriesBegin,
              *CurrHostEntry = HostTable->EntriesBegin,
              *EntryDeviceEnd = TargetTable->EntriesEnd;
           CurrDeviceEntry != EntryDeviceEnd;
           CurrDeviceEntry++, CurrHostEntry++) {
        if (CurrDeviceEntry->Size == 0 ||
            CurrDeviceEntry->Kind != object::OffloadKind::OFK_OpenMP)
          continue;

        assert(CurrDeviceEntry->Size == CurrHostEntry->Size &&
               "data size mismatch");

        // Fortran may use multiple weak declarations for the same symbol,
        // therefore we must allow for multiple weak symbols to be loaded from
        // the fat binary. Treat these mappings as any other "regular"
        // mapping. Add entry to map.
        if (Device.getMappingInfo().getTgtPtrBegin(
                HDTTMap, CurrHostEntry->Address, CurrHostEntry->Size))
          continue;

        void *CurrDeviceEntryAddr = CurrDeviceEntry->Address;

        // For indirect mapping, follow the indirection and map the actual
        // target.
        if (CurrDeviceEntry->Flags & OMP_DECLARE_TARGET_INDIRECT) {
          AsyncInfoTy AsyncInfo(Device);
          void *DevPtr;
          Device.retrieveData(&DevPtr, CurrDeviceEntryAddr, sizeof(void *),
                              AsyncInfo, /*Entry=*/nullptr, &HDTTMap);
          if (AsyncInfo.synchronize() != OFFLOAD_SUCCESS)
            return OFFLOAD_FAIL;
          CurrDeviceEntryAddr = DevPtr;
        }

        ODBG(ODT_Mapping) << "Add mapping from host " << CurrHostEntry->Address
                          << " to device " << CurrDeviceEntry->Address
                          << " with size " << CurrDeviceEntry->Size
                          << ", name \"" << CurrDeviceEntry->SymbolName << "\"";
        HDTTMap->emplace(new HostDataToTargetTy(
            (uintptr_t)CurrHostEntry->Address /*HstPtrBase*/,
            (uintptr_t)CurrHostEntry->Address /*HstPtrBegin*/,
            (uintptr_t)CurrHostEntry->Address +
                CurrHostEntry->Size /*HstPtrEnd*/,
            (uintptr_t)CurrDeviceEntryAddr /*TgtAllocBegin*/,
            (uintptr_t)CurrDeviceEntryAddr /*TgtPtrBegin*/,
            false /*UseHoldRefCount*/, CurrHostEntry->SymbolName,
            true /*IsRefCountINF*/));

        // Notify about the new mapping.
        if (Device.notifyDataMapped(CurrHostEntry->Address,
                                    CurrHostEntry->Size))
          return OFFLOAD_FAIL;
      }
    }
    Device.setHasPendingImages(false);
  }

  if (Rc != OFFLOAD_SUCCESS)
    return Rc;

  static Int32Envar DumpOffloadEntries =
      Int32Envar("OMPTARGET_DUMP_OFFLOAD_ENTRIES", -1);
  if (DumpOffloadEntries.get() == DeviceId)
    Device.dumpOffloadEntries();

  return OFFLOAD_SUCCESS;
}

Expected<DeviceTy &> PluginManager::getDevice(uint32_t DeviceNo) {
  DeviceTy *DevicePtr;
  {
    auto ExclusiveDevicesAccessor = getExclusiveDevicesAccessor();
    if (DeviceNo >= ExclusiveDevicesAccessor->size())
      return createError(
          ErrorCode::InvalidValue,
          "device number '%i' out of range, only %i devices available",
          DeviceNo, ExclusiveDevicesAccessor->size());

    DevicePtr = &*(*ExclusiveDevicesAccessor)[DeviceNo];
  }

  // Check whether global data has been mapped for this device
  if (DevicePtr->hasPendingImages())
    if (loadImagesOntoDevice(*DevicePtr) != OFFLOAD_SUCCESS)
      return createError(ErrorCode::BackendFailure,
                         "failed to load images on device '%i'", DeviceNo);
  return *DevicePtr;
}

int PluginManager::getNumActivePlugins() const {
  if (!LibOffloadInitialized)
    return 0;
  int count = 0;
  if (auto Err = iteratePlatforms(
          [](ol_platform_handle_t Platform, void *Data) {
            bool Active = false;
            if (olGetPlatformInfo(Platform, OL_PLATFORM_INFO_ACTIVE,
                                  sizeof(Active), &Active) == OL_SUCCESS &&
                Active)
              ++(*static_cast<int *>(Data));
          },
          static_cast<void *>(&count))) {
    consumeError(std::move(Err));
  }
  return count;
}
