1ec8f4a38SAtmn Patel //===---------------- Utils.cpp - Utilities for Remote RTL ----------------===//
2ec8f4a38SAtmn Patel //
3ec8f4a38SAtmn Patel // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ec8f4a38SAtmn Patel // See https://llvm.org/LICENSE.txt for license information.
5ec8f4a38SAtmn Patel // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ec8f4a38SAtmn Patel //
7ec8f4a38SAtmn Patel //===----------------------------------------------------------------------===//
8ec8f4a38SAtmn Patel //
9ec8f4a38SAtmn Patel // Utilities for data movement and debugging.
10ec8f4a38SAtmn Patel //
11ec8f4a38SAtmn Patel //===----------------------------------------------------------------------===//
12ec8f4a38SAtmn Patel
13ec8f4a38SAtmn Patel #include "Utils.h"
14ec8f4a38SAtmn Patel #include "omptarget.h"
15ec8f4a38SAtmn Patel
16ec8f4a38SAtmn Patel namespace RemoteOffloading {
17ec8f4a38SAtmn Patel
loadTargetBinaryDescription(const __tgt_bin_desc * Desc,TargetBinaryDescription & Request)18ec8f4a38SAtmn Patel void loadTargetBinaryDescription(const __tgt_bin_desc *Desc,
19ec8f4a38SAtmn Patel TargetBinaryDescription &Request) {
20ec8f4a38SAtmn Patel // Keeps track of entries which have already been deep copied.
21ec8f4a38SAtmn Patel std::vector<void *> DeepCopiedEntryAddrs;
22ec8f4a38SAtmn Patel
23ec8f4a38SAtmn Patel // Copy Global Offload Entries
24ec8f4a38SAtmn Patel for (auto *CurEntry = Desc->HostEntriesBegin;
25ec8f4a38SAtmn Patel CurEntry != Desc->HostEntriesEnd; CurEntry++) {
26ec8f4a38SAtmn Patel auto *NewEntry = Request.add_entries();
27ec8f4a38SAtmn Patel copyOffloadEntry(CurEntry, NewEntry);
28ec8f4a38SAtmn Patel
29ec8f4a38SAtmn Patel // Copy the pointer of the offload entry of the image into the Request
30ec8f4a38SAtmn Patel Request.add_entry_ptrs((uint64_t)CurEntry);
31ec8f4a38SAtmn Patel DeepCopiedEntryAddrs.push_back(CurEntry);
32ec8f4a38SAtmn Patel }
33ec8f4a38SAtmn Patel
34ec8f4a38SAtmn Patel // Copy Device Images and Device Offload Entries
35ec8f4a38SAtmn Patel __tgt_device_image *CurImage = Desc->DeviceImages;
36ec8f4a38SAtmn Patel for (auto I = 0; I < Desc->NumDeviceImages; I++, CurImage++) {
37ec8f4a38SAtmn Patel auto *Image = Request.add_images();
38ec8f4a38SAtmn Patel auto Size = (char *)CurImage->ImageEnd - (char *)CurImage->ImageStart;
39ec8f4a38SAtmn Patel Image->set_binary(CurImage->ImageStart, Size);
40ec8f4a38SAtmn Patel
41ec8f4a38SAtmn Patel // Copy the pointer of the image into the Request
42ec8f4a38SAtmn Patel auto *NewImagePtr = Request.add_image_ptrs();
43ec8f4a38SAtmn Patel NewImagePtr->set_img_ptr((uint64_t)CurImage->ImageStart);
44ec8f4a38SAtmn Patel
45ec8f4a38SAtmn Patel // Copy Device Offload Entries
46ec8f4a38SAtmn Patel for (auto *CurEntry = CurImage->EntriesBegin;
47ec8f4a38SAtmn Patel CurEntry != CurImage->EntriesEnd; CurEntry++) {
48ec8f4a38SAtmn Patel auto *NewEntry = Image->add_entries();
49ec8f4a38SAtmn Patel
50ec8f4a38SAtmn Patel auto Entry = std::find(DeepCopiedEntryAddrs.begin(),
51ec8f4a38SAtmn Patel DeepCopiedEntryAddrs.end(), CurEntry);
52ec8f4a38SAtmn Patel if (Entry != DeepCopiedEntryAddrs.end()) {
53ec8f4a38SAtmn Patel // Offload entry has already been loaded
54ec8f4a38SAtmn Patel shallowCopyOffloadEntry(CurEntry, NewEntry);
55ec8f4a38SAtmn Patel } else { // Offload Entry has not been loaded into the Request
56ec8f4a38SAtmn Patel copyOffloadEntry(CurEntry, NewEntry);
57ec8f4a38SAtmn Patel DeepCopiedEntryAddrs.push_back(CurEntry);
58ec8f4a38SAtmn Patel }
59ec8f4a38SAtmn Patel
60ec8f4a38SAtmn Patel // Copy the pointer of the offload entry of the image into the Request
61ec8f4a38SAtmn Patel NewImagePtr->add_entry_ptrs((uint64_t)CurEntry);
62ec8f4a38SAtmn Patel }
63ec8f4a38SAtmn Patel }
64ec8f4a38SAtmn Patel }
65ec8f4a38SAtmn Patel
unloadTargetBinaryDescription(const TargetBinaryDescription * Request,__tgt_bin_desc * Desc,std::unordered_map<const void *,__tgt_device_image * > & HostToRemoteDeviceImage)66ec8f4a38SAtmn Patel void unloadTargetBinaryDescription(
67ec8f4a38SAtmn Patel const TargetBinaryDescription *Request, __tgt_bin_desc *Desc,
68ec8f4a38SAtmn Patel std::unordered_map<const void *, __tgt_device_image *>
69ec8f4a38SAtmn Patel &HostToRemoteDeviceImage) {
70ec8f4a38SAtmn Patel std::unordered_map<const void *, __tgt_offload_entry *> CopiedOffloadEntries;
71ec8f4a38SAtmn Patel Desc->NumDeviceImages = Request->images_size();
72ec8f4a38SAtmn Patel Desc->DeviceImages = new __tgt_device_image[Desc->NumDeviceImages];
73ec8f4a38SAtmn Patel
74ec8f4a38SAtmn Patel if (Request->entries_size())
75ec8f4a38SAtmn Patel Desc->HostEntriesBegin = new __tgt_offload_entry[Request->entries_size()];
76ec8f4a38SAtmn Patel else {
77ec8f4a38SAtmn Patel Desc->HostEntriesBegin = nullptr;
78ec8f4a38SAtmn Patel Desc->HostEntriesEnd = nullptr;
79ec8f4a38SAtmn Patel }
80ec8f4a38SAtmn Patel
81ec8f4a38SAtmn Patel // Copy Global Offload Entries
82ec8f4a38SAtmn Patel __tgt_offload_entry *CurEntry = Desc->HostEntriesBegin;
83*21e92612SAtmn Patel size_t I = 0;
84*21e92612SAtmn Patel for (auto &Entry : Request->entries()) {
85*21e92612SAtmn Patel copyOffloadEntry(Entry, CurEntry);
86*21e92612SAtmn Patel CopiedOffloadEntries[(void *)Request->entry_ptrs()[I]] = CurEntry;
87ec8f4a38SAtmn Patel CurEntry++;
88*21e92612SAtmn Patel I++;
89ec8f4a38SAtmn Patel }
90ec8f4a38SAtmn Patel Desc->HostEntriesEnd = CurEntry;
91ec8f4a38SAtmn Patel
92ec8f4a38SAtmn Patel // Copy Device Images and Device Offload Entries
93ec8f4a38SAtmn Patel __tgt_device_image *CurImage = Desc->DeviceImages;
94ec8f4a38SAtmn Patel auto ImageItr = Request->image_ptrs().begin();
95ec8f4a38SAtmn Patel for (auto Image : Request->images()) {
96ec8f4a38SAtmn Patel // Copy Device Offload Entries
97*21e92612SAtmn Patel CurEntry = Desc->HostEntriesBegin;
98ec8f4a38SAtmn Patel bool Found = false;
99ec8f4a38SAtmn Patel
100ec8f4a38SAtmn Patel if (!Desc->HostEntriesBegin) {
101ec8f4a38SAtmn Patel CurImage->EntriesBegin = nullptr;
102ec8f4a38SAtmn Patel CurImage->EntriesEnd = nullptr;
103ec8f4a38SAtmn Patel }
104ec8f4a38SAtmn Patel
105*21e92612SAtmn Patel for (size_t I = 0; I < Image.entries_size(); I++) {
106ec8f4a38SAtmn Patel auto TgtEntry =
107*21e92612SAtmn Patel CopiedOffloadEntries.find((void *)Request->entry_ptrs()[I]);
108ec8f4a38SAtmn Patel if (TgtEntry != CopiedOffloadEntries.end()) {
109ec8f4a38SAtmn Patel if (!Found)
110ec8f4a38SAtmn Patel CurImage->EntriesBegin = CurEntry;
111ec8f4a38SAtmn Patel
112ec8f4a38SAtmn Patel CurImage->EntriesEnd = CurEntry + 1;
113*21e92612SAtmn Patel Found = true;
114ec8f4a38SAtmn Patel } else {
115ec8f4a38SAtmn Patel Found = false;
116*21e92612SAtmn Patel copyOffloadEntry(Image.entries()[I], CurEntry);
117*21e92612SAtmn Patel CopiedOffloadEntries[(void *)(Request->entry_ptrs()[I])] = CurEntry;
118ec8f4a38SAtmn Patel }
119ec8f4a38SAtmn Patel CurEntry++;
120ec8f4a38SAtmn Patel }
121ec8f4a38SAtmn Patel
122ec8f4a38SAtmn Patel // Copy Device Image
123ec8f4a38SAtmn Patel CurImage->ImageStart = new uint8_t[Image.binary().size()];
124ec8f4a38SAtmn Patel memcpy(CurImage->ImageStart,
125ec8f4a38SAtmn Patel static_cast<const void *>(Image.binary().data()),
126ec8f4a38SAtmn Patel Image.binary().size());
127ec8f4a38SAtmn Patel CurImage->ImageEnd =
128ec8f4a38SAtmn Patel (void *)((char *)CurImage->ImageStart + Image.binary().size());
129ec8f4a38SAtmn Patel
130ec8f4a38SAtmn Patel HostToRemoteDeviceImage[(void *)ImageItr->img_ptr()] = CurImage;
131ec8f4a38SAtmn Patel CurImage++;
132ec8f4a38SAtmn Patel ImageItr++;
133ec8f4a38SAtmn Patel }
134ec8f4a38SAtmn Patel }
135ec8f4a38SAtmn Patel
freeTargetBinaryDescription(__tgt_bin_desc * Desc)136ec8f4a38SAtmn Patel void freeTargetBinaryDescription(__tgt_bin_desc *Desc) {
137ec8f4a38SAtmn Patel __tgt_device_image *CurImage = Desc->DeviceImages;
138ec8f4a38SAtmn Patel for (auto I = 0; I < Desc->NumDeviceImages; I++, CurImage++)
139ec8f4a38SAtmn Patel delete[](uint64_t *) CurImage->ImageStart;
140ec8f4a38SAtmn Patel
141ec8f4a38SAtmn Patel delete[] Desc->DeviceImages;
142ec8f4a38SAtmn Patel
143ec8f4a38SAtmn Patel for (auto *Entry = Desc->HostEntriesBegin; Entry != Desc->HostEntriesEnd;
144ec8f4a38SAtmn Patel Entry++) {
145ec8f4a38SAtmn Patel free(Entry->name);
146ec8f4a38SAtmn Patel free(Entry->addr);
147ec8f4a38SAtmn Patel }
148ec8f4a38SAtmn Patel
149ec8f4a38SAtmn Patel delete[] Desc->HostEntriesBegin;
150ec8f4a38SAtmn Patel }
151ec8f4a38SAtmn Patel
freeTargetTable(__tgt_target_table * Table)152ec8f4a38SAtmn Patel void freeTargetTable(__tgt_target_table *Table) {
153ec8f4a38SAtmn Patel for (auto *Entry = Table->EntriesBegin; Entry != Table->EntriesEnd; Entry++)
154ec8f4a38SAtmn Patel free(Entry->name);
155ec8f4a38SAtmn Patel
156ec8f4a38SAtmn Patel delete[] Table->EntriesBegin;
157ec8f4a38SAtmn Patel }
158ec8f4a38SAtmn Patel
loadTargetTable(__tgt_target_table * Table,TargetTable & TableResponse,__tgt_device_image * Image)159ec8f4a38SAtmn Patel void loadTargetTable(__tgt_target_table *Table, TargetTable &TableResponse,
160ec8f4a38SAtmn Patel __tgt_device_image *Image) {
161ec8f4a38SAtmn Patel auto *ImageEntry = Image->EntriesBegin;
162ec8f4a38SAtmn Patel for (__tgt_offload_entry *CurEntry = Table->EntriesBegin;
163ec8f4a38SAtmn Patel CurEntry != Table->EntriesEnd; CurEntry++, ImageEntry++) {
164ec8f4a38SAtmn Patel // TODO: This can probably be trimmed substantially.
165ec8f4a38SAtmn Patel auto *NewEntry = TableResponse.add_entries();
166ec8f4a38SAtmn Patel NewEntry->set_name(CurEntry->name);
167ec8f4a38SAtmn Patel NewEntry->set_addr((uint64_t)CurEntry->addr);
168ec8f4a38SAtmn Patel NewEntry->set_flags(CurEntry->flags);
169ec8f4a38SAtmn Patel NewEntry->set_reserved(CurEntry->reserved);
170ec8f4a38SAtmn Patel NewEntry->set_size(CurEntry->size);
171ec8f4a38SAtmn Patel TableResponse.add_entry_ptrs((int64_t)CurEntry);
172ec8f4a38SAtmn Patel }
173ec8f4a38SAtmn Patel }
174ec8f4a38SAtmn Patel
unloadTargetTable(TargetTable & TableResponse,__tgt_target_table * Table,std::unordered_map<void *,void * > & HostToRemoteTargetTableMap)175ec8f4a38SAtmn Patel void unloadTargetTable(
176ec8f4a38SAtmn Patel TargetTable &TableResponse, __tgt_target_table *Table,
177ec8f4a38SAtmn Patel std::unordered_map<void *, void *> &HostToRemoteTargetTableMap) {
178ec8f4a38SAtmn Patel Table->EntriesBegin = new __tgt_offload_entry[TableResponse.entries_size()];
179ec8f4a38SAtmn Patel
180ec8f4a38SAtmn Patel auto *CurEntry = Table->EntriesBegin;
181*21e92612SAtmn Patel for (size_t I = 0; I < TableResponse.entries_size(); I++) {
182*21e92612SAtmn Patel copyOffloadEntry(TableResponse.entries()[I], CurEntry);
183ec8f4a38SAtmn Patel HostToRemoteTargetTableMap[CurEntry->addr] =
184*21e92612SAtmn Patel (void *)TableResponse.entry_ptrs()[I];
185ec8f4a38SAtmn Patel CurEntry++;
186ec8f4a38SAtmn Patel }
187ec8f4a38SAtmn Patel Table->EntriesEnd = CurEntry;
188ec8f4a38SAtmn Patel }
189ec8f4a38SAtmn Patel
copyOffloadEntry(const TargetOffloadEntry & EntryResponse,__tgt_offload_entry * Entry)190ec8f4a38SAtmn Patel void copyOffloadEntry(const TargetOffloadEntry &EntryResponse,
191ec8f4a38SAtmn Patel __tgt_offload_entry *Entry) {
192ec8f4a38SAtmn Patel Entry->name = strdup(EntryResponse.name().c_str());
193ec8f4a38SAtmn Patel Entry->reserved = EntryResponse.reserved();
194ec8f4a38SAtmn Patel Entry->flags = EntryResponse.flags();
195ec8f4a38SAtmn Patel Entry->addr = strdup(EntryResponse.data().c_str());
196ec8f4a38SAtmn Patel Entry->size = EntryResponse.data().size();
197ec8f4a38SAtmn Patel }
198ec8f4a38SAtmn Patel
copyOffloadEntry(const DeviceOffloadEntry & EntryResponse,__tgt_offload_entry * Entry)199ec8f4a38SAtmn Patel void copyOffloadEntry(const DeviceOffloadEntry &EntryResponse,
200ec8f4a38SAtmn Patel __tgt_offload_entry *Entry) {
201ec8f4a38SAtmn Patel Entry->name = strdup(EntryResponse.name().c_str());
202ec8f4a38SAtmn Patel Entry->reserved = EntryResponse.reserved();
203ec8f4a38SAtmn Patel Entry->flags = EntryResponse.flags();
204ec8f4a38SAtmn Patel Entry->addr = (void *)EntryResponse.addr();
205ec8f4a38SAtmn Patel Entry->size = EntryResponse.size();
206ec8f4a38SAtmn Patel }
207ec8f4a38SAtmn Patel
208ec8f4a38SAtmn Patel /// We shallow copy with just the name because it is a convenient identifier, we
209ec8f4a38SAtmn Patel /// do actually just match off of the address.
shallowCopyOffloadEntry(const __tgt_offload_entry * Entry,TargetOffloadEntry * EntryResponse)210ec8f4a38SAtmn Patel void shallowCopyOffloadEntry(const __tgt_offload_entry *Entry,
211ec8f4a38SAtmn Patel TargetOffloadEntry *EntryResponse) {
212ec8f4a38SAtmn Patel EntryResponse->set_name(Entry->name);
213ec8f4a38SAtmn Patel }
214ec8f4a38SAtmn Patel
copyOffloadEntry(const __tgt_offload_entry * Entry,TargetOffloadEntry * EntryResponse)215ec8f4a38SAtmn Patel void copyOffloadEntry(const __tgt_offload_entry *Entry,
216ec8f4a38SAtmn Patel TargetOffloadEntry *EntryResponse) {
217ec8f4a38SAtmn Patel shallowCopyOffloadEntry(Entry, EntryResponse);
218ec8f4a38SAtmn Patel EntryResponse->set_reserved(Entry->reserved);
219ec8f4a38SAtmn Patel EntryResponse->set_flags(Entry->flags);
220ec8f4a38SAtmn Patel EntryResponse->set_data(Entry->addr, Entry->size);
221ec8f4a38SAtmn Patel }
222ec8f4a38SAtmn Patel
223ec8f4a38SAtmn Patel /// Dumps the memory region from Start to End in order to debug memory transfer
224ec8f4a38SAtmn Patel /// errors within the plugin
dump(const void * Start,const void * End)225ec8f4a38SAtmn Patel void dump(const void *Start, const void *End) {
226ec8f4a38SAtmn Patel unsigned char Line[17];
227ec8f4a38SAtmn Patel const unsigned char *PrintCharacter = (const unsigned char *)Start;
228ec8f4a38SAtmn Patel
229ec8f4a38SAtmn Patel unsigned int I = 0;
230ec8f4a38SAtmn Patel for (; I < ((const int *)End - (const int *)Start); I++) {
231ec8f4a38SAtmn Patel if ((I % 16) == 0) {
232ec8f4a38SAtmn Patel if (I != 0)
233ec8f4a38SAtmn Patel printf(" %s\n", Line);
234ec8f4a38SAtmn Patel
235ec8f4a38SAtmn Patel printf(" %04x ", I);
236ec8f4a38SAtmn Patel }
237ec8f4a38SAtmn Patel
238ec8f4a38SAtmn Patel printf(" %02x", PrintCharacter[I]);
239ec8f4a38SAtmn Patel
240ec8f4a38SAtmn Patel if ((PrintCharacter[I] < 0x20) || (PrintCharacter[I] > 0x7e))
241ec8f4a38SAtmn Patel Line[I % 16] = '.';
242ec8f4a38SAtmn Patel else
243ec8f4a38SAtmn Patel Line[I % 16] = PrintCharacter[I];
244ec8f4a38SAtmn Patel
245ec8f4a38SAtmn Patel Line[(I % 16) + 1] = '\0';
246ec8f4a38SAtmn Patel }
247ec8f4a38SAtmn Patel
248ec8f4a38SAtmn Patel while ((I % 16) != 0) {
249ec8f4a38SAtmn Patel printf(" ");
250ec8f4a38SAtmn Patel I++;
251ec8f4a38SAtmn Patel }
252ec8f4a38SAtmn Patel
253ec8f4a38SAtmn Patel printf(" %s\n", Line);
254ec8f4a38SAtmn Patel }
255ec8f4a38SAtmn Patel
dump(__tgt_offload_entry * Entry)256ec8f4a38SAtmn Patel void dump(__tgt_offload_entry *Entry) {
257ec8f4a38SAtmn Patel fprintf(stderr, "Entry (%p):\n", (void *)Entry);
258ec8f4a38SAtmn Patel fprintf(stderr, " Name: %s (%p)\n", Entry->name, (void *)&Entry->name);
259ec8f4a38SAtmn Patel fprintf(stderr, " Reserved: %d (%p)\n", Entry->reserved,
260ec8f4a38SAtmn Patel (void *)&Entry->reserved);
261ec8f4a38SAtmn Patel fprintf(stderr, " Flags: %d (%p)\n", Entry->flags, (void *)&Entry->flags);
262ec8f4a38SAtmn Patel fprintf(stderr, " Addr: %p\n", Entry->addr);
263ec8f4a38SAtmn Patel fprintf(stderr, " Size: %lu\n", Entry->size);
264ec8f4a38SAtmn Patel }
265ec8f4a38SAtmn Patel
dump(__tgt_target_table * Table)266ec8f4a38SAtmn Patel void dump(__tgt_target_table *Table) {
267ec8f4a38SAtmn Patel for (auto *CurEntry = Table->EntriesBegin; CurEntry != Table->EntriesEnd;
268ec8f4a38SAtmn Patel CurEntry++)
269ec8f4a38SAtmn Patel dump(CurEntry);
270ec8f4a38SAtmn Patel }
271ec8f4a38SAtmn Patel
dump(TargetOffloadEntry Entry)272ec8f4a38SAtmn Patel void dump(TargetOffloadEntry Entry) {
273ec8f4a38SAtmn Patel fprintf(stderr, "Entry: ");
274*21e92612SAtmn Patel fprintf(stderr, " Name: %s\n", Entry.name().c_str());
275*21e92612SAtmn Patel fprintf(stderr, " Reserved: %d\n", Entry.reserved());
276*21e92612SAtmn Patel fprintf(stderr, " Flags: %d\n", Entry.flags());
277*21e92612SAtmn Patel fprintf(stderr, " Size: %ld\n", Entry.data().size());
278ec8f4a38SAtmn Patel dump(static_cast<const void *>(Entry.data().data()),
279ec8f4a38SAtmn Patel static_cast<const void *>((Entry.data().c_str() + Entry.data().size())));
280ec8f4a38SAtmn Patel }
281ec8f4a38SAtmn Patel
dump(__tgt_device_image * Image)282ec8f4a38SAtmn Patel void dump(__tgt_device_image *Image) {
283ec8f4a38SAtmn Patel dump(Image->ImageStart, Image->ImageEnd);
284ec8f4a38SAtmn Patel __tgt_offload_entry *EntryItr = Image->EntriesBegin;
285ec8f4a38SAtmn Patel for (; EntryItr != Image->EntriesEnd; EntryItr++)
286ec8f4a38SAtmn Patel dump(EntryItr);
287ec8f4a38SAtmn Patel }
288ec8f4a38SAtmn Patel
dump(std::unordered_map<void *,__tgt_offload_entry * > & Map)289ec8f4a38SAtmn Patel void dump(std::unordered_map<void *, __tgt_offload_entry *> &Map) {
290ec8f4a38SAtmn Patel fprintf(stderr, "Host to Remote Entry Map:\n");
291ec8f4a38SAtmn Patel for (auto Entry : Map)
292ec8f4a38SAtmn Patel fprintf(stderr, " Host (%p) -> Tgt (%p): Addr((%p))\n", Entry.first,
293ec8f4a38SAtmn Patel (void *)Entry.second, (void *)Entry.second->addr);
294ec8f4a38SAtmn Patel }
295ec8f4a38SAtmn Patel } // namespace RemoteOffloading
296