1 //===-------- interface.cpp - 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 // Implementation of the interface to be used by Clang during the codegen of a
10 // target region.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "device.h"
15 #include "private.h"
16 #include "rtl.h"
17 
18 #include <cassert>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <mutex>
22 
23 ////////////////////////////////////////////////////////////////////////////////
24 /// manage the success or failure of a target construct
25 static void HandleDefaultTargetOffload() {
26   PM->TargetOffloadMtx.lock();
27   if (PM->TargetOffloadPolicy == tgt_default) {
28     if (omp_get_num_devices() > 0) {
29       DP("Default TARGET OFFLOAD policy is now mandatory "
30          "(devices were found)\n");
31       PM->TargetOffloadPolicy = tgt_mandatory;
32     } else {
33       DP("Default TARGET OFFLOAD policy is now disabled "
34          "(no devices were found)\n");
35       PM->TargetOffloadPolicy = tgt_disabled;
36     }
37   }
38   PM->TargetOffloadMtx.unlock();
39 }
40 
41 static int IsOffloadDisabled() {
42   if (PM->TargetOffloadPolicy == tgt_default)
43     HandleDefaultTargetOffload();
44   return PM->TargetOffloadPolicy == tgt_disabled;
45 }
46 
47 static void HandleTargetOutcome(bool success, ident_t *loc = nullptr) {
48   switch (PM->TargetOffloadPolicy) {
49   case tgt_disabled:
50     if (success) {
51       FATAL_MESSAGE0(1, "expected no offloading while offloading is disabled");
52     }
53     break;
54   case tgt_default:
55     FATAL_MESSAGE0(1, "default offloading policy must be switched to "
56                       "mandatory or disabled");
57     break;
58   case tgt_mandatory:
59     if (!success) {
60       if (getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE)
61         for (auto &Device : PM->Devices)
62           dumpTargetPointerMappings(loc, Device);
63       else
64         FAILURE_MESSAGE("Run with LIBOMPTARGET_DEBUG=%d to dump host-target "
65                         "pointer mappings.\n",
66                         OMP_INFOTYPE_DUMP_TABLE);
67 
68       SourceInfo info(loc);
69       if (info.isAvailible())
70         fprintf(stderr, "%s:%d:%d: ", info.getFilename(), info.getLine(),
71                 info.getColumn());
72       else
73         FAILURE_MESSAGE("Source location information not present. Compile with "
74                         "-g or -gline-tables-only.\n");
75       FATAL_MESSAGE0(
76           1, "failure of target construct while offloading is mandatory");
77     } else {
78       if (getInfoLevel() & OMP_INFOTYPE_DUMP_TABLE)
79         for (auto &Device : PM->Devices)
80           dumpTargetPointerMappings(loc, Device);
81     }
82     break;
83   }
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// adds requires flags
88 EXTERN void __tgt_register_requires(int64_t flags) {
89   TIMESCOPE();
90   PM->RTLs.RegisterRequires(flags);
91 }
92 
93 ////////////////////////////////////////////////////////////////////////////////
94 /// adds a target shared library to the target execution image
95 EXTERN void __tgt_register_lib(__tgt_bin_desc *desc) {
96   TIMESCOPE();
97   std::call_once(PM->RTLs.initFlag, &RTLsTy::LoadRTLs, &PM->RTLs);
98   for (auto &RTL : PM->RTLs.AllRTLs) {
99     if (RTL.register_lib) {
100       if ((*RTL.register_lib)(desc) != OFFLOAD_SUCCESS) {
101         DP("Could not register library with %s", RTL.RTLName.c_str());
102       }
103     }
104   }
105   PM->RTLs.RegisterLib(desc);
106 }
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// unloads a target shared library
110 EXTERN void __tgt_unregister_lib(__tgt_bin_desc *desc) {
111   TIMESCOPE();
112   PM->RTLs.UnregisterLib(desc);
113   for (auto &RTL : PM->RTLs.UsedRTLs) {
114     if (RTL->unregister_lib) {
115       if ((*RTL->unregister_lib)(desc) != OFFLOAD_SUCCESS) {
116         DP("Could not register library with %s", RTL->RTLName.c_str());
117       }
118     }
119   }
120 }
121 
122 /// creates host-to-target data mapping, stores it in the
123 /// libomptarget.so internal structure (an entry in a stack of data maps)
124 /// and passes the data to the device.
125 EXTERN void __tgt_target_data_begin(int64_t device_id, int32_t arg_num,
126                                     void **args_base, void **args,
127                                     int64_t *arg_sizes, int64_t *arg_types) {
128   TIMESCOPE();
129   __tgt_target_data_begin_mapper(nullptr, device_id, arg_num, args_base, args,
130                                  arg_sizes, arg_types, nullptr, nullptr);
131 }
132 
133 EXTERN void __tgt_target_data_begin_nowait(int64_t device_id, int32_t arg_num,
134                                            void **args_base, void **args,
135                                            int64_t *arg_sizes,
136                                            int64_t *arg_types, int32_t depNum,
137                                            void *depList, int32_t noAliasDepNum,
138                                            void *noAliasDepList) {
139   TIMESCOPE();
140   if (depNum + noAliasDepNum > 0)
141     __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL));
142 
143   __tgt_target_data_begin_mapper(nullptr, device_id, arg_num, args_base, args,
144                                  arg_sizes, arg_types, nullptr, nullptr);
145 }
146 
147 EXTERN void __tgt_target_data_begin_mapper(ident_t *loc, int64_t device_id,
148                                            int32_t arg_num, void **args_base,
149                                            void **args, int64_t *arg_sizes,
150                                            int64_t *arg_types,
151                                            map_var_info_t *arg_names,
152                                            void **arg_mappers) {
153   TIMESCOPE_WITH_IDENT(loc);
154   if (IsOffloadDisabled())
155     return;
156 
157   DP("Entering data begin region for device %" PRId64 " with %d mappings\n",
158      device_id, arg_num);
159 
160   // No devices available?
161   if (device_id == OFFLOAD_DEVICE_DEFAULT) {
162     device_id = omp_get_default_device();
163     DP("Use default device id %" PRId64 "\n", device_id);
164   }
165 
166   if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
167     DP("Failed to get device %" PRId64 " ready\n", device_id);
168     HandleTargetOutcome(false, loc);
169     return;
170   }
171 
172   DeviceTy &Device = PM->Devices[device_id];
173 
174   if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS)
175     printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types,
176                          arg_names, "Entering OpenMP data region");
177 #ifdef OMPTARGET_DEBUG
178   for (int i = 0; i < arg_num; ++i) {
179     DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64
180        ", Type=0x%" PRIx64 ", Name=%s\n",
181        i, DPxPTR(args_base[i]), DPxPTR(args[i]), arg_sizes[i], arg_types[i],
182        (arg_names) ? getNameFromMapping(arg_names[i]).c_str() : "unknown");
183   }
184 #endif
185 
186   int rc = targetDataBegin(loc, Device, arg_num, args_base, args, arg_sizes,
187                            arg_types, arg_names, arg_mappers, nullptr);
188   HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
189 }
190 
191 EXTERN void __tgt_target_data_begin_nowait_mapper(
192     ident_t *loc, int64_t device_id, int32_t arg_num, void **args_base,
193     void **args, int64_t *arg_sizes, int64_t *arg_types,
194     map_var_info_t *arg_names, void **arg_mappers, int32_t depNum,
195     void *depList, int32_t noAliasDepNum, void *noAliasDepList) {
196   TIMESCOPE_WITH_IDENT(loc);
197   if (depNum + noAliasDepNum > 0)
198     __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc));
199 
200   __tgt_target_data_begin_mapper(loc, device_id, arg_num, args_base, args,
201                                  arg_sizes, arg_types, arg_names, arg_mappers);
202 }
203 
204 /// passes data from the target, releases target memory and destroys
205 /// the host-target mapping (top entry from the stack of data maps)
206 /// created by the last __tgt_target_data_begin.
207 EXTERN void __tgt_target_data_end(int64_t device_id, int32_t arg_num,
208                                   void **args_base, void **args,
209                                   int64_t *arg_sizes, int64_t *arg_types) {
210   TIMESCOPE();
211   __tgt_target_data_end_mapper(nullptr, device_id, arg_num, args_base, args,
212                                arg_sizes, arg_types, nullptr, nullptr);
213 }
214 
215 EXTERN void __tgt_target_data_end_nowait(int64_t device_id, int32_t arg_num,
216                                          void **args_base, void **args,
217                                          int64_t *arg_sizes, int64_t *arg_types,
218                                          int32_t depNum, void *depList,
219                                          int32_t noAliasDepNum,
220                                          void *noAliasDepList) {
221   TIMESCOPE();
222   if (depNum + noAliasDepNum > 0)
223     __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL));
224 
225   __tgt_target_data_end_mapper(nullptr, device_id, arg_num, args_base, args,
226                                arg_sizes, arg_types, nullptr, nullptr);
227 }
228 
229 EXTERN void __tgt_target_data_end_mapper(ident_t *loc, int64_t device_id,
230                                          int32_t arg_num, void **args_base,
231                                          void **args, int64_t *arg_sizes,
232                                          int64_t *arg_types,
233                                          map_var_info_t *arg_names,
234                                          void **arg_mappers) {
235   TIMESCOPE_WITH_IDENT(loc);
236   if (IsOffloadDisabled())
237     return;
238   DP("Entering data end region with %d mappings\n", arg_num);
239 
240   // No devices available?
241   if (device_id == OFFLOAD_DEVICE_DEFAULT) {
242     device_id = omp_get_default_device();
243   }
244 
245   PM->RTLsMtx.lock();
246   size_t DevicesSize = PM->Devices.size();
247   PM->RTLsMtx.unlock();
248   if (DevicesSize <= (size_t)device_id) {
249     DP("Device ID  %" PRId64 " does not have a matching RTL.\n", device_id);
250     HandleTargetOutcome(false, loc);
251     return;
252   }
253 
254   DeviceTy &Device = PM->Devices[device_id];
255   if (!Device.IsInit) {
256     DP("Uninit device: ignore");
257     HandleTargetOutcome(false, loc);
258     return;
259   }
260 
261   if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS)
262     printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types,
263                          arg_names, "Exiting OpenMP data region");
264 #ifdef OMPTARGET_DEBUG
265   for (int i = 0; i < arg_num; ++i) {
266     DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64
267        ", Type=0x%" PRIx64 ", Name=%s\n",
268        i, DPxPTR(args_base[i]), DPxPTR(args[i]), arg_sizes[i], arg_types[i],
269        (arg_names) ? getNameFromMapping(arg_names[i]).c_str() : "unknown");
270   }
271 #endif
272 
273   int rc = targetDataEnd(loc, Device, arg_num, args_base, args, arg_sizes,
274                          arg_types, arg_names, arg_mappers, nullptr);
275   HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
276 }
277 
278 EXTERN void __tgt_target_data_end_nowait_mapper(
279     ident_t *loc, int64_t device_id, int32_t arg_num, void **args_base,
280     void **args, int64_t *arg_sizes, int64_t *arg_types,
281     map_var_info_t *arg_names, void **arg_mappers, int32_t depNum,
282     void *depList, int32_t noAliasDepNum, void *noAliasDepList) {
283   TIMESCOPE_WITH_IDENT(loc);
284   if (depNum + noAliasDepNum > 0)
285     __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc));
286 
287   __tgt_target_data_end_mapper(loc, device_id, arg_num, args_base, args,
288                                arg_sizes, arg_types, arg_names, arg_mappers);
289 }
290 
291 EXTERN void __tgt_target_data_update(int64_t device_id, int32_t arg_num,
292                                      void **args_base, void **args,
293                                      int64_t *arg_sizes, int64_t *arg_types) {
294   TIMESCOPE();
295   __tgt_target_data_update_mapper(nullptr, device_id, arg_num, args_base, args,
296                                   arg_sizes, arg_types, nullptr, nullptr);
297 }
298 
299 EXTERN void __tgt_target_data_update_nowait(
300     int64_t device_id, int32_t arg_num, void **args_base, void **args,
301     int64_t *arg_sizes, int64_t *arg_types, int32_t depNum, void *depList,
302     int32_t noAliasDepNum, void *noAliasDepList) {
303   TIMESCOPE();
304   if (depNum + noAliasDepNum > 0)
305     __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL));
306 
307   __tgt_target_data_update_mapper(nullptr, device_id, arg_num, args_base, args,
308                                   arg_sizes, arg_types, nullptr, nullptr);
309 }
310 
311 EXTERN void __tgt_target_data_update_mapper(ident_t *loc, int64_t device_id,
312                                             int32_t arg_num, void **args_base,
313                                             void **args, int64_t *arg_sizes,
314                                             int64_t *arg_types,
315                                             map_var_info_t *arg_names,
316                                             void **arg_mappers) {
317   TIMESCOPE_WITH_IDENT(loc);
318   if (IsOffloadDisabled())
319     return;
320   DP("Entering data update with %d mappings\n", arg_num);
321 
322   // No devices available?
323   if (device_id == OFFLOAD_DEVICE_DEFAULT) {
324     device_id = omp_get_default_device();
325   }
326 
327   if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
328     DP("Failed to get device %" PRId64 " ready\n", device_id);
329     HandleTargetOutcome(false, loc);
330     return;
331   }
332 
333   if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS)
334     printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types,
335                          arg_names, "Updating OpenMP data");
336 
337   DeviceTy &Device = PM->Devices[device_id];
338   int rc = targetDataUpdate(loc, Device, arg_num, args_base, args, arg_sizes,
339                             arg_types, arg_names, arg_mappers);
340   HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
341 }
342 
343 EXTERN void __tgt_target_data_update_nowait_mapper(
344     ident_t *loc, int64_t device_id, int32_t arg_num, void **args_base,
345     void **args, int64_t *arg_sizes, int64_t *arg_types,
346     map_var_info_t *arg_names, void **arg_mappers, int32_t depNum,
347     void *depList, int32_t noAliasDepNum, void *noAliasDepList) {
348   TIMESCOPE_WITH_IDENT(loc);
349   if (depNum + noAliasDepNum > 0)
350     __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc));
351 
352   __tgt_target_data_update_mapper(loc, device_id, arg_num, args_base, args,
353                                   arg_sizes, arg_types, arg_names, arg_mappers);
354 }
355 
356 EXTERN int __tgt_target(int64_t device_id, void *host_ptr, int32_t arg_num,
357                         void **args_base, void **args, int64_t *arg_sizes,
358                         int64_t *arg_types) {
359   TIMESCOPE();
360   return __tgt_target_mapper(nullptr, device_id, host_ptr, arg_num, args_base,
361                              args, arg_sizes, arg_types, nullptr, nullptr);
362 }
363 
364 EXTERN int __tgt_target_nowait(int64_t device_id, void *host_ptr,
365                                int32_t arg_num, void **args_base, void **args,
366                                int64_t *arg_sizes, int64_t *arg_types,
367                                int32_t depNum, void *depList,
368                                int32_t noAliasDepNum, void *noAliasDepList) {
369   TIMESCOPE();
370   if (depNum + noAliasDepNum > 0)
371     __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL));
372 
373   return __tgt_target_mapper(nullptr, device_id, host_ptr, arg_num, args_base,
374                              args, arg_sizes, arg_types, nullptr, nullptr);
375 }
376 
377 EXTERN int __tgt_target_mapper(ident_t *loc, int64_t device_id, void *host_ptr,
378                                int32_t arg_num, void **args_base, void **args,
379                                int64_t *arg_sizes, int64_t *arg_types,
380                                map_var_info_t *arg_names, void **arg_mappers) {
381   TIMESCOPE_WITH_IDENT(loc);
382   if (IsOffloadDisabled())
383     return OFFLOAD_FAIL;
384   DP("Entering target region with entry point " DPxMOD " and device Id %" PRId64
385      "\n",
386      DPxPTR(host_ptr), device_id);
387 
388   if (device_id == OFFLOAD_DEVICE_DEFAULT) {
389     device_id = omp_get_default_device();
390   }
391 
392   if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
393     REPORT("Failed to get device %" PRId64 " ready\n", device_id);
394     HandleTargetOutcome(false, loc);
395     return OFFLOAD_FAIL;
396   }
397 
398   if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS)
399     printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types,
400                          arg_names, "Entering OpenMP kernel");
401 #ifdef OMPTARGET_DEBUG
402   for (int i = 0; i < arg_num; ++i) {
403     DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64
404        ", Type=0x%" PRIx64 ", Name=%s\n",
405        i, DPxPTR(args_base[i]), DPxPTR(args[i]), arg_sizes[i], arg_types[i],
406        (arg_names) ? getNameFromMapping(arg_names[i]).c_str() : "unknown");
407   }
408 #endif
409 
410   int rc = target(loc, device_id, host_ptr, arg_num, args_base, args, arg_sizes,
411                   arg_types, arg_names, arg_mappers, 0, 0, false /*team*/);
412   HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
413   return rc;
414 }
415 
416 EXTERN int __tgt_target_nowait_mapper(
417     ident_t *loc, int64_t device_id, void *host_ptr, int32_t arg_num,
418     void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types,
419     map_var_info_t *arg_names, void **arg_mappers, int32_t depNum,
420     void *depList, int32_t noAliasDepNum, void *noAliasDepList) {
421   TIMESCOPE_WITH_IDENT(loc);
422   if (depNum + noAliasDepNum > 0)
423     __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc));
424 
425   return __tgt_target_mapper(loc, device_id, host_ptr, arg_num, args_base, args,
426                              arg_sizes, arg_types, arg_names, arg_mappers);
427 }
428 
429 EXTERN int __tgt_target_teams(int64_t device_id, void *host_ptr,
430                               int32_t arg_num, void **args_base, void **args,
431                               int64_t *arg_sizes, int64_t *arg_types,
432                               int32_t team_num, int32_t thread_limit) {
433   TIMESCOPE();
434   return __tgt_target_teams_mapper(nullptr, device_id, host_ptr, arg_num,
435                                    args_base, args, arg_sizes, arg_types,
436                                    nullptr, nullptr, team_num, thread_limit);
437 }
438 
439 EXTERN int __tgt_target_teams_nowait(int64_t device_id, void *host_ptr,
440                                      int32_t arg_num, void **args_base,
441                                      void **args, int64_t *arg_sizes,
442                                      int64_t *arg_types, int32_t team_num,
443                                      int32_t thread_limit, int32_t depNum,
444                                      void *depList, int32_t noAliasDepNum,
445                                      void *noAliasDepList) {
446   TIMESCOPE();
447   if (depNum + noAliasDepNum > 0)
448     __kmpc_omp_taskwait(NULL, __kmpc_global_thread_num(NULL));
449 
450   return __tgt_target_teams_mapper(nullptr, device_id, host_ptr, arg_num,
451                                    args_base, args, arg_sizes, arg_types,
452                                    nullptr, nullptr, team_num, thread_limit);
453 }
454 
455 EXTERN int __tgt_target_teams_mapper(ident_t *loc, int64_t device_id,
456                                      void *host_ptr, int32_t arg_num,
457                                      void **args_base, void **args,
458                                      int64_t *arg_sizes, int64_t *arg_types,
459                                      map_var_info_t *arg_names,
460                                      void **arg_mappers, int32_t team_num,
461                                      int32_t thread_limit) {
462   if (IsOffloadDisabled())
463     return OFFLOAD_FAIL;
464   DP("Entering target region with entry point " DPxMOD " and device Id %" PRId64
465      "\n",
466      DPxPTR(host_ptr), device_id);
467 
468   if (device_id == OFFLOAD_DEVICE_DEFAULT) {
469     device_id = omp_get_default_device();
470   }
471 
472   if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
473     REPORT("Failed to get device %" PRId64 " ready\n", device_id);
474     HandleTargetOutcome(false, loc);
475     return OFFLOAD_FAIL;
476   }
477 
478   if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS)
479     printKernelArguments(loc, device_id, arg_num, arg_sizes, arg_types,
480                          arg_names, "Entering OpenMP kernel");
481 #ifdef OMPTARGET_DEBUG
482   for (int i = 0; i < arg_num; ++i) {
483     DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64
484        ", Type=0x%" PRIx64 ", Name=%s\n",
485        i, DPxPTR(args_base[i]), DPxPTR(args[i]), arg_sizes[i], arg_types[i],
486        (arg_names) ? getNameFromMapping(arg_names[i]).c_str() : "unknown");
487   }
488 #endif
489 
490   int rc = target(loc, device_id, host_ptr, arg_num, args_base, args, arg_sizes,
491                   arg_types, arg_names, arg_mappers, team_num, thread_limit,
492                   true /*team*/);
493   HandleTargetOutcome(rc == OFFLOAD_SUCCESS, loc);
494   return rc;
495 }
496 
497 EXTERN int __tgt_target_teams_nowait_mapper(
498     ident_t *loc, int64_t device_id, void *host_ptr, int32_t arg_num,
499     void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types,
500     map_var_info_t *arg_names, void **arg_mappers, int32_t team_num,
501     int32_t thread_limit, int32_t depNum, void *depList, int32_t noAliasDepNum,
502     void *noAliasDepList) {
503   TIMESCOPE_WITH_IDENT(loc);
504   if (depNum + noAliasDepNum > 0)
505     __kmpc_omp_taskwait(loc, __kmpc_global_thread_num(loc));
506 
507   return __tgt_target_teams_mapper(loc, device_id, host_ptr, arg_num, args_base,
508                                    args, arg_sizes, arg_types, arg_names,
509                                    arg_mappers, team_num, thread_limit);
510 }
511 
512 // Get the current number of components for a user-defined mapper.
513 EXTERN int64_t __tgt_mapper_num_components(void *rt_mapper_handle) {
514   TIMESCOPE();
515   auto *MapperComponentsPtr = (struct MapperComponentsTy *)rt_mapper_handle;
516   int64_t size = MapperComponentsPtr->Components.size();
517   DP("__tgt_mapper_num_components(Handle=" DPxMOD ") returns %" PRId64 "\n",
518      DPxPTR(rt_mapper_handle), size);
519   return size;
520 }
521 
522 // Push back one component for a user-defined mapper.
523 EXTERN void __tgt_push_mapper_component(void *rt_mapper_handle, void *base,
524                                         void *begin, int64_t size, int64_t type,
525                                         void *name) {
526   TIMESCOPE();
527   DP("__tgt_push_mapper_component(Handle=" DPxMOD
528      ") adds an entry (Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64
529      ", Type=0x%" PRIx64 ", Name=%s).\n",
530      DPxPTR(rt_mapper_handle), DPxPTR(base), DPxPTR(begin), size, type,
531      (name) ? getNameFromMapping(name).c_str() : "unknown");
532   auto *MapperComponentsPtr = (struct MapperComponentsTy *)rt_mapper_handle;
533   MapperComponentsPtr->Components.push_back(
534       MapComponentInfoTy(base, begin, size, type, name));
535 }
536 
537 EXTERN void __kmpc_push_target_tripcount(ident_t *loc, int64_t device_id,
538                                          uint64_t loop_tripcount) {
539   TIMESCOPE_WITH_IDENT(loc);
540   if (IsOffloadDisabled())
541     return;
542 
543   if (device_id == OFFLOAD_DEVICE_DEFAULT) {
544     device_id = omp_get_default_device();
545   }
546 
547   if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) {
548     DP("Failed to get device %" PRId64 " ready\n", device_id);
549     HandleTargetOutcome(false, loc);
550     return;
551   }
552 
553   DP("__kmpc_push_target_tripcount(%" PRId64 ", %" PRIu64 ")\n", device_id,
554      loop_tripcount);
555   PM->TblMapMtx.lock();
556   PM->Devices[device_id].LoopTripCnt.emplace(__kmpc_global_thread_num(NULL),
557                                              loop_tripcount);
558   PM->TblMapMtx.unlock();
559 }
560