brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · a53fb43 Raw
140 lines · cpp
1//===--------- Misc.cpp - OpenMP device misc interfaces ----------- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//10//===----------------------------------------------------------------------===//11 12#include "Allocator.h"13#include "Configuration.h"14#include "DeviceTypes.h"15#include "Shared/RPCOpcodes.h"16#include "shared/rpc.h"17 18#include "Debug.h"19 20namespace ompx {21namespace impl {22 23/// Lookup a device-side function using a host pointer /p HstPtr using the table24/// provided by the device plugin. The table is an ordered pair of host and25/// device pointers sorted on the value of the host pointer.26static void *indirectCallLookup(void *HstPtr) {27  if (!HstPtr)28    return nullptr;29 30  struct IndirectCallTable {31    void *HstPtr;32    void *DevPtr;33  };34  IndirectCallTable *Table =35      reinterpret_cast<IndirectCallTable *>(config::getIndirectCallTablePtr());36  uint64_t TableSize = config::getIndirectCallTableSize();37 38  // If the table is empty we assume this is device pointer.39  if (!Table || !TableSize)40    return HstPtr;41 42  uint32_t Left = 0;43  uint32_t Right = TableSize;44 45  // If the pointer is definitely not contained in the table we exit early.46  if (HstPtr < Table[Left].HstPtr || HstPtr > Table[Right - 1].HstPtr)47    return HstPtr;48 49  while (Left != Right) {50    uint32_t Current = Left + (Right - Left) / 2;51    if (Table[Current].HstPtr == HstPtr)52      return Table[Current].DevPtr;53 54    if (HstPtr < Table[Current].HstPtr)55      Right = Current;56    else57      Left = Current;58  }59 60  // If we searched the whole table and found nothing this is a device pointer.61  return HstPtr;62}63 64/// The openmp client instance used to communicate with the server.65[[gnu::visibility("protected"),66  gnu::weak]] rpc::Client Client asm("__llvm_rpc_client");67 68} // namespace impl69} // namespace ompx70 71/// Interfaces72///73///{74 75extern "C" {76int32_t __kmpc_cancellationpoint(IdentTy *, int32_t, int32_t) { return 0; }77 78int32_t __kmpc_cancel(IdentTy *, int32_t, int32_t) { return 0; }79 80double omp_get_wtick(void) {81  // The number of ticks per second for the AMDGPU clock varies by card and can82  // only be retrieved by querying the driver. We rely on the device environment83  // to inform us what the proper frequency is. NVPTX uses a nanosecond84  // resolution, we could omit the global read but this makes it consistent.85  return 1.0 / ompx::config::getClockFrequency();86}87 88double omp_get_wtime(void) {89  return static_cast<double>(__builtin_readsteadycounter()) * omp_get_wtick();90}91 92void *__llvm_omp_indirect_call_lookup(void *HstPtr) {93  return ompx::impl::indirectCallLookup(HstPtr);94}95 96void *omp_alloc(size_t size, omp_allocator_handle_t allocator) {97  switch (allocator) {98  case omp_default_mem_alloc:99  case omp_large_cap_mem_alloc:100  case omp_const_mem_alloc:101  case omp_high_bw_mem_alloc:102  case omp_low_lat_mem_alloc:103    return ompx::allocator::alloc(size);104  default:105    return nullptr;106  }107}108 109void omp_free(void *ptr, omp_allocator_handle_t allocator) {110  switch (allocator) {111  case omp_default_mem_alloc:112  case omp_large_cap_mem_alloc:113  case omp_const_mem_alloc:114  case omp_high_bw_mem_alloc:115  case omp_low_lat_mem_alloc:116    ompx::allocator::free(ptr);117    return;118  case omp_null_allocator:119  default:120    return;121  }122}123 124unsigned long long __llvm_omp_host_call(void *fn, void *data, size_t size) {125  rpc::Client::Port Port = ompx::impl::Client.open<OFFLOAD_HOST_CALL>();126  Port.send_n(data, size);127  Port.send([=](rpc::Buffer *buffer, uint32_t) {128    buffer->data[0] = reinterpret_cast<uintptr_t>(fn);129  });130  unsigned long long Ret;131  Port.recv([&](rpc::Buffer *Buffer, uint32_t) {132    Ret = static_cast<unsigned long long>(Buffer->data[0]);133  });134  Port.close();135  return Ret;136}137}138 139///}140