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