xref: /llvm-project/offload/include/device.h (revision ff12c0061b7dbb8a82681a0e02a513bb84b1d143)
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