#include "Allocator.h"
#include "Configuration.h"
#include "DeviceTypes.h"
#include "Shared/RPCOpcodes.h"
#include "shared/rpc.h"
#include "Debug.h"
namespace ompx {
namespace impl {
static void *indirectCallLookup(void *HstPtr) {
if (!HstPtr)
return nullptr;
struct IndirectCallTable {
void *HstPtr;
void *DevPtr;
};
IndirectCallTable *Table =
reinterpret_cast<IndirectCallTable *>(config::getIndirectCallTablePtr());
uint64_t TableSize = config::getIndirectCallTableSize();
if (!Table || !TableSize)
return HstPtr;
uint32_t Left = 0;
uint32_t Right = TableSize;
if (HstPtr < Table[Left].HstPtr || HstPtr > Table[Right - 1].HstPtr)
return HstPtr;
while (Left != Right) {
uint32_t Current = Left + (Right - Left) / 2;
if (Table[Current].HstPtr == HstPtr)
return Table[Current].DevPtr;
if (HstPtr < Table[Current].HstPtr)
Right = Current;
else
Left = Current;
}
return HstPtr;
}
[[gnu::visibility("protected"),
gnu::weak]] rpc::Client Client asm("__llvm_rpc_client");
}
}
extern "C" {
int32_t __kmpc_cancellationpoint(IdentTy *, int32_t, int32_t) { return 0; }
int32_t __kmpc_cancel(IdentTy *, int32_t, int32_t) { return 0; }
double omp_get_wtick(void) {
return 1.0 / ompx::config::getClockFrequency();
}
double omp_get_wtime(void) {
return static_cast<double>(__builtin_readsteadycounter()) * omp_get_wtick();
}
void *__llvm_omp_indirect_call_lookup(void *HstPtr) {
return ompx::impl::indirectCallLookup(HstPtr);
}
void *omp_alloc(size_t size, omp_allocator_handle_t allocator) {
switch (allocator) {
case omp_default_mem_alloc:
case omp_large_cap_mem_alloc:
case omp_const_mem_alloc:
case omp_high_bw_mem_alloc:
case omp_low_lat_mem_alloc:
return ompx::allocator::alloc(size);
default:
return nullptr;
}
}
void omp_free(void *ptr, omp_allocator_handle_t allocator) {
switch (allocator) {
case omp_default_mem_alloc:
case omp_large_cap_mem_alloc:
case omp_const_mem_alloc:
case omp_high_bw_mem_alloc:
case omp_low_lat_mem_alloc:
ompx::allocator::free(ptr);
return;
case omp_null_allocator:
default:
return;
}
}
unsigned long long __llvm_omp_host_call(void *fn, void *data, size_t size) {
rpc::Client::Port Port = ompx::impl::Client.open<OFFLOAD_HOST_CALL>();
Port.send_n(data, size);
Port.send([=](rpc::Buffer *buffer, uint32_t) {
buffer->data[0] = reinterpret_cast<uintptr_t>(fn);
});
unsigned long long Ret;
Port.recv([&](rpc::Buffer *Buffer, uint32_t) {
Ret = static_cast<unsigned long long>(Buffer->data[0]);
});
Port.close();
return Ret;
}
}