1 //===----------- device.h - Target independent OpenMP target RTL ----------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Declarations for managing devices that are handled by RTL plugins. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef _OMPTARGET_DEVICE_H 14 #define _OMPTARGET_DEVICE_H 15 16 #include <cassert> 17 #include <cstddef> 18 #include <cstdint> 19 #include <cstring> 20 #include <list> 21 #include <map> 22 #include <memory> 23 #include <mutex> 24 #include <set> 25 26 #include "ExclusiveAccess.h" 27 #include "OffloadEntry.h" 28 #include "omptarget.h" 29 #include "rtl.h" 30 31 #include "OpenMP/Mapping.h" 32 33 #include "llvm/ADT/DenseMap.h" 34 #include "llvm/ADT/SmallVector.h" 35 36 #include "PluginInterface.h" 37 using GenericPluginTy = llvm::omp::target::plugin::GenericPluginTy; 38 39 // Forward declarations. 40 struct __tgt_bin_desc; 41 struct __tgt_target_table; 42 43 struct DeviceTy { 44 int32_t DeviceID; 45 GenericPluginTy *RTL; 46 int32_t RTLDeviceID; 47 48 DeviceTy(GenericPluginTy *RTL, int32_t DeviceID, int32_t RTLDeviceID); 49 // DeviceTy is not copyable 50 DeviceTy(const DeviceTy &D) = delete; 51 DeviceTy &operator=(const DeviceTy &D) = delete; 52 53 ~DeviceTy(); 54 55 /// Try to initialize the device and return any failure. 56 llvm::Error init(); 57 58 /// Provide access to the mapping handler. 59 MappingInfoTy &getMappingInfo() { return MappingInfo; } 60 61 llvm::Expected<__tgt_device_binary> loadBinary(__tgt_device_image *Img); 62 63 // device memory allocation/deallocation routines 64 /// Allocates \p Size bytes on the device, host or shared memory space 65 /// (depending on \p Kind) and returns the address/nullptr when 66 /// succeeds/fails. \p HstPtr is an address of the host data which the 67 /// allocated target data will be associated with. If it is unknown, the 68 /// default value of \p HstPtr is nullptr. Note: this function doesn't do 69 /// pointer association. Actually, all the __tgt_rtl_data_alloc 70 /// implementations ignore \p HstPtr. \p Kind dictates what allocator should 71 /// be used (host, shared, device). 72 void *allocData(int64_t Size, void *HstPtr = nullptr, 73 int32_t Kind = TARGET_ALLOC_DEFAULT); 74 75 /// Deallocates memory which \p TgtPtrBegin points at and returns 76 /// OFFLOAD_SUCCESS/OFFLOAD_FAIL when succeeds/fails. p Kind dictates what 77 /// allocator should be used (host, shared, device). 78 int32_t deleteData(void *TgtPtrBegin, int32_t Kind = TARGET_ALLOC_DEFAULT); 79 80 // Data transfer. When AsyncInfo is nullptr, the transfer will be 81 // synchronous. 82 // Copy data from host to device 83 int32_t submitData(void *TgtPtrBegin, void *HstPtrBegin, int64_t Size, 84 AsyncInfoTy &AsyncInfo, 85 HostDataToTargetTy *Entry = nullptr, 86 MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr); 87 88 // Copy data from device back to host 89 int32_t retrieveData(void *HstPtrBegin, void *TgtPtrBegin, int64_t Size, 90 AsyncInfoTy &AsyncInfo, 91 HostDataToTargetTy *Entry = nullptr, 92 MappingInfoTy::HDTTMapAccessorTy *HDTTMapPtr = nullptr); 93 94 // Return true if data can be copied to DstDevice directly 95 bool isDataExchangable(const DeviceTy &DstDevice); 96 97 // Copy data from current device to destination device directly 98 int32_t dataExchange(void *SrcPtr, DeviceTy &DstDev, void *DstPtr, 99 int64_t Size, AsyncInfoTy &AsyncInfo); 100 101 /// Notify the plugin about a new mapping starting at the host address 102 /// \p HstPtr and \p Size bytes. 103 int32_t notifyDataMapped(void *HstPtr, int64_t Size); 104 105 /// Notify the plugin about an existing mapping being unmapped starting at 106 /// the host address \p HstPtr. 107 int32_t notifyDataUnmapped(void *HstPtr); 108 109 // Launch the kernel identified by \p TgtEntryPtr with the given arguments. 110 int32_t launchKernel(void *TgtEntryPtr, void **TgtVarsPtr, 111 ptrdiff_t *TgtOffsets, KernelArgsTy &KernelArgs, 112 AsyncInfoTy &AsyncInfo); 113 114 /// Synchronize device/queue/event based on \p AsyncInfo and return 115 /// OFFLOAD_SUCCESS/OFFLOAD_FAIL when succeeds/fails. 116 int32_t synchronize(AsyncInfoTy &AsyncInfo); 117 118 /// Query for device/queue/event based completion on \p AsyncInfo in a 119 /// non-blocking manner and return OFFLOAD_SUCCESS/OFFLOAD_FAIL when 120 /// succeeds/fails. Must be called multiple times until AsyncInfo is 121 /// completed and AsyncInfo.isDone() returns true. 122 int32_t queryAsync(AsyncInfoTy &AsyncInfo); 123 124 /// Calls the corresponding print device info function in the plugin. 125 bool printDeviceInfo(); 126 127 /// Event related interfaces. 128 /// { 129 /// Create an event. 130 int32_t createEvent(void **Event); 131 132 /// Record the event based on status in AsyncInfo->Queue at the moment the 133 /// function is called. 134 int32_t recordEvent(void *Event, AsyncInfoTy &AsyncInfo); 135 136 /// Wait for an event. This function can be blocking or non-blocking, 137 /// depending on the implmentation. It is expected to set a dependence on the 138 /// event such that corresponding operations shall only start once the event 139 /// is fulfilled. 140 int32_t waitEvent(void *Event, AsyncInfoTy &AsyncInfo); 141 142 /// Synchronize the event. It is expected to block the thread. 143 int32_t syncEvent(void *Event); 144 145 /// Destroy the event. 146 int32_t destroyEvent(void *Event); 147 /// } 148 149 /// Print all offload entries to stderr. 150 void dumpOffloadEntries(); 151 152 /// Ask the device whether the runtime should use auto zero-copy. 153 bool useAutoZeroCopy(); 154 155 /// Check if there are pending images for this device. 156 bool hasPendingImages() const { return HasPendingImages; } 157 158 /// Indicate that there are pending images for this device or not. 159 void setHasPendingImages(bool V) { HasPendingImages = V; } 160 161 private: 162 /// Deinitialize the device (and plugin). 163 void deinit(); 164 165 /// All offload entries available on this device. 166 using DeviceOffloadEntriesMapTy = 167 llvm::DenseMap<llvm::StringRef, OffloadEntryTy>; 168 ProtectedObj<DeviceOffloadEntriesMapTy> DeviceOffloadEntries; 169 170 /// Handler to collect and organize host-2-device mapping information. 171 MappingInfoTy MappingInfo; 172 173 /// Flag to indicate pending images (true after construction). 174 bool HasPendingImages = true; 175 }; 176 177 #endif 178