brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · 02e097e Raw
178 lines · c
1//===-- OpenMP/InteropAPI.h - OpenMP interoperability types and API - 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#ifndef OMPTARGET_OPENMP_INTEROP_API_H12#define OMPTARGET_OPENMP_INTEROP_API_H13 14#include "omp.h"15 16#include "PerThreadTable.h"17#include "omptarget.h"18 19extern "C" {20 21typedef enum kmp_interop_type_t {22  kmp_interop_type_unknown = -1,23  kmp_interop_type_target,24  kmp_interop_type_targetsync,25} kmp_interop_type_t;26 27struct interop_attrs_t {28  uint32_t inorder : 1;29  uint32_t reserved : 31;30 31  /// Check if the supported attributes are compatible with the current32  ///   attributes. Only if an attribute is supported can the value be true,33  ///   otherwise it needs to be false34  bool checkSupportedOnly(interop_attrs_t supported) const {35    return supported.inorder || (!supported.inorder && !inorder);36  }37};38 39struct interop_spec_t {40  int32_t fr_id;41  interop_attrs_t attrs; // Common attributes42  int64_t impl_attrs; // Implementation specific attributes (recognized by each43                      // plugin)44};45 46struct interop_flags_t {47  uint32_t implicit : 1; // dispatch (true) or interop (false)48  uint32_t nowait : 1;   // has nowait flag49  uint32_t reserved : 30;50};51 52struct interop_ctx_t {53  uint32_t version; // version of the interface (current is 0)54  interop_flags_t flags;55  int32_t gtid;56};57 58struct dep_pack_t {59  int32_t ndeps;60  int32_t ndeps_noalias;61  kmp_depend_info_t *deplist;62  kmp_depend_info_t *noalias_deplist;63};64 65struct omp_interop_val_t;66 67typedef void ompx_interop_cb_t(omp_interop_val_t *interop, void *data);68 69struct omp_interop_cb_instance_t {70  ompx_interop_cb_t *cb;71  void *data;72 73  omp_interop_cb_instance_t(ompx_interop_cb_t *cb, void *data)74      : cb(cb), data(data) {}75 76  void operator()(omp_interop_val_t *interop) { cb(interop, data); }77};78 79/// The interop value type, aka. the interop object.80typedef struct omp_interop_val_t {81  /// Device and interop-type are determined at construction time and fix.82  omp_interop_val_t(intptr_t device_id, kmp_interop_type_t interop_type)83      : interop_type(interop_type), device_id(device_id) {}84  const char *err_str = nullptr;85  __tgt_async_info *async_info = nullptr;86  __tgt_device_info device_info;87  const kmp_interop_type_t interop_type;88  const intptr_t device_id;89  omp_vendor_id_t vendor_id = omp_vendor_llvm;90  tgt_foreign_runtime_id_t fr_id = tgt_fr_none;91  interop_attrs_t attrs{false, 0}; // Common prefer specification attributes92  int64_t impl_attrs = 0; // Implementation prefer specification attributes93 94  // Constants95  static constexpr int no_owner = -1; // This interop has no current owner96 97  void *rtl_property = nullptr; // Plugin dependent information98  // For implicitly created Interop objects (e.g., from a dispatch construct)99  // who owns the object100  int owner_gtid = no_owner;101  // Marks whether the object was requested since the last time it was synced102  bool clean = true;103 104  typedef llvm::SmallVector<omp_interop_cb_instance_t> callback_list_t;105 106  callback_list_t completion_cbs;107 108  void reset() {109    owner_gtid = no_owner;110    markClean();111    clearCompletionCbs();112  }113 114  llvm::Expected<DeviceTy &> getDevice() const;115 116  bool hasOwner() const { return owner_gtid != no_owner; }117 118  void setOwner(int gtid) { owner_gtid = gtid; }119  bool isOwnedBy(int gtid) { return owner_gtid == gtid; }120  bool isCompatibleWith(int32_t InteropType, const interop_spec_t &Spec);121  bool isCompatibleWith(int32_t InteropType, const interop_spec_t &Spec,122                        int64_t DeviceNum, int gtid);123  void markClean() { clean = true; }124  void markDirty() { clean = false; }125  bool isClean() const { return clean; }126 127  int32_t flush(DeviceTy &Device);128  int32_t sync_barrier(DeviceTy &Device);129  int32_t async_barrier(DeviceTy &Device);130  int32_t release(DeviceTy &Device);131 132  void addCompletionCb(ompx_interop_cb_t *cb, void *data) {133    completion_cbs.push_back(omp_interop_cb_instance_t(cb, data));134  }135 136  int numCompletionCbs() const { return completion_cbs.size(); }137  void clearCompletionCbs() { completion_cbs.clear(); }138 139  void runCompletionCbs() {140    for (auto &cbInstance : completion_cbs)141      cbInstance(this);142    clearCompletionCbs();143  }144} omp_interop_val_t;145 146} // extern "C"147 148struct InteropTableEntry {149  using ContainerTy = typename std::vector<omp_interop_val_t *>;150  using iterator = typename ContainerTy::iterator;151 152  ContainerTy Interops;153 154  static constexpr int reservedEntriesPerThread =155      20; // reserve some entries to avoid reallocation156 157  void add(omp_interop_val_t *obj) {158    if (Interops.capacity() == 0)159      Interops.reserve(reservedEntriesPerThread);160    Interops.push_back(obj);161  }162 163  /// vector interface164  int size() const { return Interops.size(); }165  iterator begin() { return Interops.begin(); }166  iterator end() { return Interops.end(); }167  void clear() { Interops.clear(); }168};169 170struct InteropTblTy171    : public PerThreadTable<InteropTableEntry, omp_interop_val_t *> {172  void clear();173};174 175void syncImplicitInterops(int gtid, void *event);176 177#endif // OMPTARGET_OPENMP_INTEROP_API_H178