D97883 introduced a compile-time error in the experimental remote offloading libomptarget plugin, this patch fixes it and resolves a number of inconsistencies in the plugin as well: 1. Non-functional Asynchronous API 2. Unnecessarily verbose debug printing 3. Misc. code clean ups This is not intended to make any functional changes to the plugin. Differential Revision: https://reviews.llvm.org/D105325
712 lines
24 KiB
C++
712 lines
24 KiB
C++
//===----------------- Client.cpp - Client Implementation -----------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// gRPC (Client) for the remote plugin.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include <cmath>
|
|
|
|
#include "Client.h"
|
|
#include "omptarget.h"
|
|
#include "openmp.pb.h"
|
|
|
|
using namespace std::chrono;
|
|
|
|
using grpc::ClientContext;
|
|
using grpc::ClientReader;
|
|
using grpc::ClientWriter;
|
|
using grpc::Status;
|
|
|
|
template <typename Fn1, typename Fn2, typename TReturn>
|
|
auto RemoteOffloadClient::remoteCall(Fn1 Preprocessor, Fn2 Postprocessor,
|
|
TReturn ErrorValue, bool CanTimeOut) {
|
|
ArenaAllocatorLock->lock();
|
|
if (Arena->SpaceAllocated() >= MaxSize)
|
|
Arena->Reset();
|
|
ArenaAllocatorLock->unlock();
|
|
|
|
ClientContext Context;
|
|
if (CanTimeOut) {
|
|
auto Deadline =
|
|
std::chrono::system_clock::now() + std::chrono::seconds(Timeout);
|
|
Context.set_deadline(Deadline);
|
|
}
|
|
|
|
Status RPCStatus;
|
|
auto Reply = Preprocessor(RPCStatus, Context);
|
|
|
|
if (!RPCStatus.ok()) {
|
|
CLIENT_DBG("%s", RPCStatus.error_message().c_str())
|
|
} else {
|
|
return Postprocessor(Reply);
|
|
}
|
|
|
|
CLIENT_DBG("Failed")
|
|
return ErrorValue;
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::shutdown(void) {
|
|
ClientContext Context;
|
|
Null Request;
|
|
I32 Reply;
|
|
CLIENT_DBG("Shutting down server.")
|
|
auto Status = Stub->Shutdown(&Context, Request, &Reply);
|
|
if (Status.ok())
|
|
return Reply.number();
|
|
return 1;
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::registerLib(__tgt_bin_desc *Desc) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Request = protobuf::Arena::CreateMessage<TargetBinaryDescription>(
|
|
Arena.get());
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
loadTargetBinaryDescription(Desc, *Request);
|
|
Request->set_bin_ptr((uint64_t)Desc);
|
|
|
|
RPCStatus = Stub->RegisterLib(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](const auto &Reply) {
|
|
if (Reply->number() == 0) {
|
|
CLIENT_DBG("Registered library")
|
|
return 0;
|
|
}
|
|
return 1;
|
|
},
|
|
/* Error Value */ 1);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::unregisterLib(__tgt_bin_desc *Desc) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Request = protobuf::Arena::CreateMessage<Pointer>(Arena.get());
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
|
|
Request->set_number((uint64_t)Desc);
|
|
|
|
RPCStatus = Stub->UnregisterLib(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](const auto &Reply) {
|
|
if (Reply->number() == 0) {
|
|
CLIENT_DBG("Unregistered library")
|
|
return 0;
|
|
}
|
|
CLIENT_DBG("Failed to unregister library")
|
|
return 1;
|
|
},
|
|
/* Error Value */ 1);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::isValidBinary(__tgt_device_image *Image) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Request =
|
|
protobuf::Arena::CreateMessage<TargetDeviceImagePtr>(Arena.get());
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
|
|
Request->set_image_ptr((uint64_t)Image->ImageStart);
|
|
|
|
auto *EntryItr = Image->EntriesBegin;
|
|
while (EntryItr != Image->EntriesEnd)
|
|
Request->add_entry_ptrs((uint64_t)EntryItr++);
|
|
|
|
RPCStatus = Stub->IsValidBinary(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](const auto &Reply) {
|
|
if (Reply->number()) {
|
|
CLIENT_DBG("Validated binary")
|
|
} else {
|
|
CLIENT_DBG("Could not validate binary")
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/* Error Value */ 0);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::getNumberOfDevices() {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](Status &RPCStatus, ClientContext &Context) {
|
|
auto *Request = protobuf::Arena::CreateMessage<Null>(Arena.get());
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
|
|
RPCStatus = Stub->GetNumberOfDevices(&Context, *Request, Reply);
|
|
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](const auto &Reply) {
|
|
if (Reply->number()) {
|
|
CLIENT_DBG("Found %d devices", Reply->number())
|
|
} else {
|
|
CLIENT_DBG("Could not get the number of devices")
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/*Error Value*/ -1);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::initDevice(int32_t DeviceId) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Request = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
|
|
Request->set_number(DeviceId);
|
|
|
|
RPCStatus = Stub->InitDevice(&Context, *Request, Reply);
|
|
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](const auto &Reply) {
|
|
if (!Reply->number()) {
|
|
CLIENT_DBG("Initialized device %d", DeviceId)
|
|
} else {
|
|
CLIENT_DBG("Could not initialize device %d", DeviceId)
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/* Error Value */ -1);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::initRequires(int64_t RequiresFlags) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Request = protobuf::Arena::CreateMessage<I64>(Arena.get());
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
Request->set_number(RequiresFlags);
|
|
RPCStatus = Stub->InitRequires(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](const auto &Reply) {
|
|
if (Reply->number()) {
|
|
CLIENT_DBG("Initialized requires")
|
|
} else {
|
|
CLIENT_DBG("Could not initialize requires")
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/* Error Value */ -1);
|
|
}
|
|
|
|
__tgt_target_table *RemoteOffloadClient::loadBinary(int32_t DeviceId,
|
|
__tgt_device_image *Image) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *ImageMessage =
|
|
protobuf::Arena::CreateMessage<Binary>(Arena.get());
|
|
auto *Reply = protobuf::Arena::CreateMessage<TargetTable>(Arena.get());
|
|
ImageMessage->set_image_ptr((uint64_t)Image->ImageStart);
|
|
ImageMessage->set_device_id(DeviceId);
|
|
|
|
RPCStatus = Stub->LoadBinary(&Context, *ImageMessage, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](auto &Reply) {
|
|
if (Reply->entries_size() == 0) {
|
|
CLIENT_DBG("Could not load image %p onto device %d", Image, DeviceId)
|
|
return (__tgt_target_table *)nullptr;
|
|
}
|
|
DevicesToTables[DeviceId] = std::make_unique<__tgt_target_table>();
|
|
unloadTargetTable(*Reply, DevicesToTables[DeviceId].get(),
|
|
RemoteEntries[DeviceId]);
|
|
|
|
CLIENT_DBG("Loaded Image %p to device %d with %d entries", Image,
|
|
DeviceId, Reply->entries_size())
|
|
|
|
return DevicesToTables[DeviceId].get();
|
|
},
|
|
/* Error Value */ (__tgt_target_table *)nullptr,
|
|
/* CanTimeOut */ false);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::isDataExchangeable(int32_t SrcDevId,
|
|
int32_t DstDevId) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Request = protobuf::Arena::CreateMessage<DevicePair>(Arena.get());
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
|
|
Request->set_src_dev_id(SrcDevId);
|
|
Request->set_dst_dev_id(DstDevId);
|
|
|
|
RPCStatus = Stub->IsDataExchangeable(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](auto &Reply) {
|
|
if (Reply->number()) {
|
|
CLIENT_DBG("Data is exchangeable between %d, %d", SrcDevId, DstDevId)
|
|
} else {
|
|
CLIENT_DBG("Data is not exchangeable between %d, %d", SrcDevId,
|
|
DstDevId)
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/* Error Value */ -1);
|
|
}
|
|
|
|
void *RemoteOffloadClient::dataAlloc(int32_t DeviceId, int64_t Size,
|
|
void *HstPtr) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Reply = protobuf::Arena::CreateMessage<Pointer>(Arena.get());
|
|
auto *Request = protobuf::Arena::CreateMessage<AllocData>(Arena.get());
|
|
|
|
Request->set_device_id(DeviceId);
|
|
Request->set_size(Size);
|
|
Request->set_hst_ptr((uint64_t)HstPtr);
|
|
|
|
RPCStatus = Stub->DataAlloc(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](auto &Reply) {
|
|
if (Reply->number()) {
|
|
CLIENT_DBG("Allocated %ld bytes on device %d at %p", Size, DeviceId,
|
|
(void *)Reply->number())
|
|
} else {
|
|
CLIENT_DBG("Could not allocate %ld bytes on device %d at %p", Size,
|
|
DeviceId, (void *)Reply->number())
|
|
}
|
|
return (void *)Reply->number();
|
|
},
|
|
/* Error Value */ (void *)nullptr);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::dataSubmit(int32_t DeviceId, void *TgtPtr,
|
|
void *HstPtr, int64_t Size) {
|
|
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
std::unique_ptr<ClientWriter<SubmitData>> Writer(
|
|
Stub->DataSubmit(&Context, Reply));
|
|
|
|
if (Size > BlockSize) {
|
|
int64_t Start = 0, End = BlockSize;
|
|
for (auto I = 0; I < ceil((float)Size / BlockSize); I++) {
|
|
auto *Request =
|
|
protobuf::Arena::CreateMessage<SubmitData>(Arena.get());
|
|
|
|
Request->set_device_id(DeviceId);
|
|
Request->set_data((char *)HstPtr + Start, End - Start);
|
|
Request->set_hst_ptr((uint64_t)HstPtr);
|
|
Request->set_tgt_ptr((uint64_t)TgtPtr);
|
|
Request->set_start(Start);
|
|
Request->set_size(Size);
|
|
|
|
if (!Writer->Write(*Request)) {
|
|
CLIENT_DBG("Broken stream when submitting data")
|
|
Reply->set_number(0);
|
|
return Reply;
|
|
}
|
|
|
|
Start += BlockSize;
|
|
End += BlockSize;
|
|
if (End >= Size)
|
|
End = Size;
|
|
}
|
|
} else {
|
|
auto *Request =
|
|
protobuf::Arena::CreateMessage<SubmitData>(Arena.get());
|
|
|
|
Request->set_device_id(DeviceId);
|
|
Request->set_data(HstPtr, Size);
|
|
Request->set_hst_ptr((uint64_t)HstPtr);
|
|
Request->set_tgt_ptr((uint64_t)TgtPtr);
|
|
Request->set_start(0);
|
|
Request->set_size(Size);
|
|
|
|
if (!Writer->Write(*Request)) {
|
|
CLIENT_DBG("Broken stream when submitting data")
|
|
Reply->set_number(0);
|
|
return Reply;
|
|
}
|
|
}
|
|
|
|
Writer->WritesDone();
|
|
RPCStatus = Writer->Finish();
|
|
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](auto &Reply) {
|
|
if (!Reply->number()) {
|
|
CLIENT_DBG(" submitted %ld bytes on device %d at %p", Size, DeviceId,
|
|
TgtPtr)
|
|
} else {
|
|
CLIENT_DBG("Could not async submit %ld bytes on device %d at %p",
|
|
Size, DeviceId, TgtPtr)
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/* Error Value */ -1,
|
|
/* CanTimeOut */ false);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::dataRetrieve(int32_t DeviceId, void *HstPtr,
|
|
void *TgtPtr, int64_t Size) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Request =
|
|
protobuf::Arena::CreateMessage<RetrieveData>(Arena.get());
|
|
|
|
Request->set_device_id(DeviceId);
|
|
Request->set_size(Size);
|
|
Request->set_hst_ptr((int64_t)HstPtr);
|
|
Request->set_tgt_ptr((int64_t)TgtPtr);
|
|
|
|
auto *Reply = protobuf::Arena::CreateMessage<Data>(Arena.get());
|
|
std::unique_ptr<ClientReader<Data>> Reader(
|
|
Stub->DataRetrieve(&Context, *Request));
|
|
Reader->WaitForInitialMetadata();
|
|
while (Reader->Read(Reply)) {
|
|
if (Reply->ret()) {
|
|
CLIENT_DBG("Could not async retrieve %ld bytes on device %d at %p "
|
|
"for %p",
|
|
Size, DeviceId, TgtPtr, HstPtr)
|
|
return Reply;
|
|
}
|
|
|
|
if (Reply->start() == 0 && Reply->size() == Reply->data().size()) {
|
|
memcpy(HstPtr, Reply->data().data(), Reply->data().size());
|
|
|
|
return Reply;
|
|
}
|
|
|
|
memcpy((void *)((char *)HstPtr + Reply->start()),
|
|
Reply->data().data(), Reply->data().size());
|
|
}
|
|
RPCStatus = Reader->Finish();
|
|
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](auto &Reply) {
|
|
if (!Reply->ret()) {
|
|
CLIENT_DBG("Retrieved %ld bytes on Device %d", Size, DeviceId)
|
|
} else {
|
|
CLIENT_DBG("Could not async retrieve %ld bytes on Device %d", Size,
|
|
DeviceId)
|
|
}
|
|
return Reply->ret();
|
|
},
|
|
/* Error Value */ -1,
|
|
/* CanTimeOut */ false);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::dataExchange(int32_t SrcDevId, void *SrcPtr,
|
|
int32_t DstDevId, void *DstPtr,
|
|
int64_t Size) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
auto *Request =
|
|
protobuf::Arena::CreateMessage<ExchangeData>(Arena.get());
|
|
|
|
Request->set_src_dev_id(SrcDevId);
|
|
Request->set_src_ptr((uint64_t)SrcPtr);
|
|
Request->set_dst_dev_id(DstDevId);
|
|
Request->set_dst_ptr((uint64_t)DstPtr);
|
|
Request->set_size(Size);
|
|
|
|
RPCStatus = Stub->DataExchange(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](auto &Reply) {
|
|
if (Reply->number()) {
|
|
CLIENT_DBG(
|
|
"Exchanged %ld bytes on device %d at %p for %p on device %d",
|
|
Size, SrcDevId, SrcPtr, DstPtr, DstDevId)
|
|
} else {
|
|
CLIENT_DBG("Could not exchange %ld bytes on device %d at %p for %p "
|
|
"on device %d",
|
|
Size, SrcDevId, SrcPtr, DstPtr, DstDevId)
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/* Error Value */ -1);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::dataDelete(int32_t DeviceId, void *TgtPtr) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
auto *Request = protobuf::Arena::CreateMessage<DeleteData>(Arena.get());
|
|
|
|
Request->set_device_id(DeviceId);
|
|
Request->set_tgt_ptr((uint64_t)TgtPtr);
|
|
|
|
RPCStatus = Stub->DataDelete(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](auto &Reply) {
|
|
if (!Reply->number()) {
|
|
CLIENT_DBG("Deleted data at %p on device %d", TgtPtr, DeviceId)
|
|
} else {
|
|
CLIENT_DBG("Could not delete data at %p on device %d", TgtPtr,
|
|
DeviceId)
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/* Error Value */ -1);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::runTargetRegion(int32_t DeviceId,
|
|
void *TgtEntryPtr, void **TgtArgs,
|
|
ptrdiff_t *TgtOffsets,
|
|
int32_t ArgNum) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
auto *Request =
|
|
protobuf::Arena::CreateMessage<TargetRegion>(Arena.get());
|
|
|
|
Request->set_device_id(DeviceId);
|
|
|
|
Request->set_tgt_entry_ptr(
|
|
(uint64_t)RemoteEntries[DeviceId][TgtEntryPtr]);
|
|
|
|
char **ArgPtr = (char **)TgtArgs;
|
|
for (auto I = 0; I < ArgNum; I++, ArgPtr++)
|
|
Request->add_tgt_args((uint64_t)*ArgPtr);
|
|
|
|
char *OffsetPtr = (char *)TgtOffsets;
|
|
for (auto I = 0; I < ArgNum; I++, OffsetPtr++)
|
|
Request->add_tgt_offsets((uint64_t)*OffsetPtr);
|
|
|
|
Request->set_arg_num(ArgNum);
|
|
|
|
RPCStatus = Stub->RunTargetRegion(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](auto &Reply) {
|
|
if (!Reply->number()) {
|
|
CLIENT_DBG("Ran target region async on device %d", DeviceId)
|
|
} else {
|
|
CLIENT_DBG("Could not run target region async on device %d", DeviceId)
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/* Error Value */ -1,
|
|
/* CanTimeOut */ false);
|
|
}
|
|
|
|
int32_t RemoteOffloadClient::runTargetTeamRegion(
|
|
int32_t DeviceId, void *TgtEntryPtr, void **TgtArgs, ptrdiff_t *TgtOffsets,
|
|
int32_t ArgNum, int32_t TeamNum, int32_t ThreadLimit,
|
|
uint64_t LoopTripcount) {
|
|
return remoteCall(
|
|
/* Preprocessor */
|
|
[&](auto &RPCStatus, auto &Context) {
|
|
auto *Reply = protobuf::Arena::CreateMessage<I32>(Arena.get());
|
|
auto *Request =
|
|
protobuf::Arena::CreateMessage<TargetTeamRegion>(Arena.get());
|
|
|
|
Request->set_device_id(DeviceId);
|
|
|
|
Request->set_tgt_entry_ptr(
|
|
(uint64_t)RemoteEntries[DeviceId][TgtEntryPtr]);
|
|
|
|
char **ArgPtr = (char **)TgtArgs;
|
|
for (auto I = 0; I < ArgNum; I++, ArgPtr++) {
|
|
Request->add_tgt_args((uint64_t)*ArgPtr);
|
|
}
|
|
|
|
char *OffsetPtr = (char *)TgtOffsets;
|
|
for (auto I = 0; I < ArgNum; I++, OffsetPtr++)
|
|
Request->add_tgt_offsets((uint64_t)*OffsetPtr);
|
|
|
|
Request->set_arg_num(ArgNum);
|
|
Request->set_team_num(TeamNum);
|
|
Request->set_thread_limit(ThreadLimit);
|
|
Request->set_loop_tripcount(LoopTripcount);
|
|
|
|
RPCStatus = Stub->RunTargetTeamRegion(&Context, *Request, Reply);
|
|
return Reply;
|
|
},
|
|
/* Postprocessor */
|
|
[&](auto &Reply) {
|
|
if (!Reply->number()) {
|
|
CLIENT_DBG("Ran target team region async on device %d", DeviceId)
|
|
} else {
|
|
CLIENT_DBG("Could not run target team region async on device %d",
|
|
DeviceId)
|
|
}
|
|
return Reply->number();
|
|
},
|
|
/* Error Value */ -1,
|
|
/* CanTimeOut */ false);
|
|
}
|
|
|
|
int32_t RemoteClientManager::shutdown(void) {
|
|
int32_t Ret = 0;
|
|
for (auto &Client : Clients)
|
|
Ret &= Client.shutdown();
|
|
return Ret;
|
|
}
|
|
|
|
int32_t RemoteClientManager::registerLib(__tgt_bin_desc *Desc) {
|
|
int32_t Ret = 0;
|
|
for (auto &Client : Clients)
|
|
Ret &= Client.registerLib(Desc);
|
|
return Ret;
|
|
}
|
|
|
|
int32_t RemoteClientManager::unregisterLib(__tgt_bin_desc *Desc) {
|
|
int32_t Ret = 0;
|
|
for (auto &Client : Clients)
|
|
Ret &= Client.unregisterLib(Desc);
|
|
return Ret;
|
|
}
|
|
|
|
int32_t RemoteClientManager::isValidBinary(__tgt_device_image *Image) {
|
|
int32_t ClientIdx = 0;
|
|
for (auto &Client : Clients) {
|
|
if (auto Ret = Client.isValidBinary(Image))
|
|
return Ret;
|
|
ClientIdx++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int32_t RemoteClientManager::getNumberOfDevices() {
|
|
auto ClientIdx = 0;
|
|
for (auto &Client : Clients) {
|
|
if (auto NumDevices = Client.getNumberOfDevices()) {
|
|
Devices.push_back(NumDevices);
|
|
}
|
|
ClientIdx++;
|
|
}
|
|
|
|
return std::accumulate(Devices.begin(), Devices.end(), 0);
|
|
}
|
|
|
|
std::pair<int32_t, int32_t> RemoteClientManager::mapDeviceId(int32_t DeviceId) {
|
|
for (size_t ClientIdx = 0; ClientIdx < Devices.size(); ClientIdx++) {
|
|
if (DeviceId < Devices[ClientIdx])
|
|
return {ClientIdx, DeviceId};
|
|
DeviceId -= Devices[ClientIdx];
|
|
}
|
|
return {-1, -1};
|
|
}
|
|
|
|
int32_t RemoteClientManager::initDevice(int32_t DeviceId) {
|
|
int32_t ClientIdx, DeviceIdx;
|
|
std::tie(ClientIdx, DeviceIdx) = mapDeviceId(DeviceId);
|
|
return Clients[ClientIdx].initDevice(DeviceIdx);
|
|
}
|
|
|
|
int32_t RemoteClientManager::initRequires(int64_t RequiresFlags) {
|
|
for (auto &Client : Clients)
|
|
Client.initRequires(RequiresFlags);
|
|
|
|
return RequiresFlags;
|
|
}
|
|
|
|
__tgt_target_table *RemoteClientManager::loadBinary(int32_t DeviceId,
|
|
__tgt_device_image *Image) {
|
|
int32_t ClientIdx, DeviceIdx;
|
|
std::tie(ClientIdx, DeviceIdx) = mapDeviceId(DeviceId);
|
|
return Clients[ClientIdx].loadBinary(DeviceIdx, Image);
|
|
}
|
|
|
|
int32_t RemoteClientManager::isDataExchangeable(int32_t SrcDevId,
|
|
int32_t DstDevId) {
|
|
int32_t SrcClientIdx, SrcDeviceIdx, DstClientIdx, DstDeviceIdx;
|
|
std::tie(SrcClientIdx, SrcDeviceIdx) = mapDeviceId(SrcDevId);
|
|
std::tie(DstClientIdx, DstDeviceIdx) = mapDeviceId(DstDevId);
|
|
return Clients[SrcClientIdx].isDataExchangeable(SrcDeviceIdx, DstDeviceIdx);
|
|
}
|
|
|
|
void *RemoteClientManager::dataAlloc(int32_t DeviceId, int64_t Size,
|
|
void *HstPtr) {
|
|
int32_t ClientIdx, DeviceIdx;
|
|
std::tie(ClientIdx, DeviceIdx) = mapDeviceId(DeviceId);
|
|
return Clients[ClientIdx].dataAlloc(DeviceIdx, Size, HstPtr);
|
|
}
|
|
|
|
int32_t RemoteClientManager::dataDelete(int32_t DeviceId, void *TgtPtr) {
|
|
int32_t ClientIdx, DeviceIdx;
|
|
std::tie(ClientIdx, DeviceIdx) = mapDeviceId(DeviceId);
|
|
return Clients[ClientIdx].dataDelete(DeviceIdx, TgtPtr);
|
|
}
|
|
|
|
int32_t RemoteClientManager::dataSubmit(int32_t DeviceId, void *TgtPtr,
|
|
void *HstPtr, int64_t Size) {
|
|
int32_t ClientIdx, DeviceIdx;
|
|
std::tie(ClientIdx, DeviceIdx) = mapDeviceId(DeviceId);
|
|
return Clients[ClientIdx].dataSubmit(DeviceIdx, TgtPtr, HstPtr, Size);
|
|
}
|
|
|
|
int32_t RemoteClientManager::dataRetrieve(int32_t DeviceId, void *HstPtr,
|
|
void *TgtPtr, int64_t Size) {
|
|
int32_t ClientIdx, DeviceIdx;
|
|
std::tie(ClientIdx, DeviceIdx) = mapDeviceId(DeviceId);
|
|
return Clients[ClientIdx].dataRetrieve(DeviceIdx, HstPtr, TgtPtr, Size);
|
|
}
|
|
|
|
int32_t RemoteClientManager::dataExchange(int32_t SrcDevId, void *SrcPtr,
|
|
int32_t DstDevId, void *DstPtr,
|
|
int64_t Size) {
|
|
int32_t SrcClientIdx, SrcDeviceIdx, DstClientIdx, DstDeviceIdx;
|
|
std::tie(SrcClientIdx, SrcDeviceIdx) = mapDeviceId(SrcDevId);
|
|
std::tie(DstClientIdx, DstDeviceIdx) = mapDeviceId(DstDevId);
|
|
return Clients[SrcClientIdx].dataExchange(SrcDeviceIdx, SrcPtr, DstDeviceIdx,
|
|
DstPtr, Size);
|
|
}
|
|
|
|
int32_t RemoteClientManager::runTargetRegion(int32_t DeviceId,
|
|
void *TgtEntryPtr, void **TgtArgs,
|
|
ptrdiff_t *TgtOffsets,
|
|
int32_t ArgNum) {
|
|
int32_t ClientIdx, DeviceIdx;
|
|
std::tie(ClientIdx, DeviceIdx) = mapDeviceId(DeviceId);
|
|
return Clients[ClientIdx].runTargetRegion(DeviceIdx, TgtEntryPtr, TgtArgs,
|
|
TgtOffsets, ArgNum);
|
|
}
|
|
|
|
int32_t RemoteClientManager::runTargetTeamRegion(
|
|
int32_t DeviceId, void *TgtEntryPtr, void **TgtArgs, ptrdiff_t *TgtOffsets,
|
|
int32_t ArgNum, int32_t TeamNum, int32_t ThreadLimit,
|
|
uint64_t LoopTripCount) {
|
|
int32_t ClientIdx, DeviceIdx;
|
|
std::tie(ClientIdx, DeviceIdx) = mapDeviceId(DeviceId);
|
|
return Clients[ClientIdx].runTargetTeamRegion(DeviceIdx, TgtEntryPtr, TgtArgs,
|
|
TgtOffsets, ArgNum, TeamNum,
|
|
ThreadLimit, LoopTripCount);
|
|
}
|