1 //===-------- interface.cpp - Target independent OpenMP target RTL --------===//
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
7 //===----------------------------------------------------------------------===//
9 // Implementation of the interface to be used by Clang during the codegen of a
12 //===----------------------------------------------------------------------===//
15 #include "omptarget.h"
24 ////////////////////////////////////////////////////////////////////////////////
25 /// adds requires flags
26 EXTERN
void __tgt_register_requires(int64_t flags
) {
28 PM
->RTLs
.RegisterRequires(flags
);
31 ////////////////////////////////////////////////////////////////////////////////
32 /// adds a target shared library to the target execution image
33 EXTERN
void __tgt_register_lib(__tgt_bin_desc
*desc
) {
35 std::call_once(PM
->RTLs
.initFlag
, &RTLsTy::LoadRTLs
, &PM
->RTLs
);
36 for (auto &RTL
: PM
->RTLs
.AllRTLs
) {
37 if (RTL
.register_lib
) {
38 if ((*RTL
.register_lib
)(desc
) != OFFLOAD_SUCCESS
) {
39 DP("Could not register library with %s", RTL
.RTLName
.c_str());
43 PM
->RTLs
.RegisterLib(desc
);
46 ////////////////////////////////////////////////////////////////////////////////
47 /// Initialize all available devices without registering any image
48 EXTERN
void __tgt_init_all_rtls() { PM
->RTLs
.initAllRTLs(); }
50 ////////////////////////////////////////////////////////////////////////////////
51 /// unloads a target shared library
52 EXTERN
void __tgt_unregister_lib(__tgt_bin_desc
*desc
) {
54 PM
->RTLs
.UnregisterLib(desc
);
55 for (auto &RTL
: PM
->RTLs
.UsedRTLs
) {
56 if (RTL
->unregister_lib
) {
57 if ((*RTL
->unregister_lib
)(desc
) != OFFLOAD_SUCCESS
) {
58 DP("Could not register library with %s", RTL
->RTLName
.c_str());
64 /// creates host-to-target data mapping, stores it in the
65 /// libomptarget.so internal structure (an entry in a stack of data maps)
66 /// and passes the data to the device.
67 EXTERN
void __tgt_target_data_begin(int64_t device_id
, int32_t arg_num
,
68 void **args_base
, void **args
,
69 int64_t *arg_sizes
, int64_t *arg_types
) {
71 __tgt_target_data_begin_mapper(nullptr, device_id
, arg_num
, args_base
, args
,
72 arg_sizes
, arg_types
, nullptr, nullptr);
75 EXTERN
void __tgt_target_data_begin_nowait(int64_t device_id
, int32_t arg_num
,
76 void **args_base
, void **args
,
78 int64_t *arg_types
, int32_t depNum
,
79 void *depList
, int32_t noAliasDepNum
,
80 void *noAliasDepList
) {
83 __tgt_target_data_begin_mapper(nullptr, device_id
, arg_num
, args_base
, args
,
84 arg_sizes
, arg_types
, nullptr, nullptr);
87 EXTERN
void __tgt_target_data_begin_mapper(ident_t
*loc
, int64_t device_id
,
88 int32_t arg_num
, void **args_base
,
89 void **args
, int64_t *arg_sizes
,
91 map_var_info_t
*arg_names
,
93 TIMESCOPE_WITH_IDENT(loc
);
94 DP("Entering data begin region for device %" PRId64
" with %d mappings\n",
96 if (checkDeviceAndCtors(device_id
, loc
)) {
97 DP("Not offloading to device %" PRId64
"\n", device_id
);
101 DeviceTy
&Device
= *PM
->Devices
[device_id
];
103 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS
)
104 printKernelArguments(loc
, device_id
, arg_num
, arg_sizes
, arg_types
,
105 arg_names
, "Entering OpenMP data region");
106 #ifdef OMPTARGET_DEBUG
107 for (int i
= 0; i
< arg_num
; ++i
) {
108 DP("Entry %2d: Base=" DPxMOD
", Begin=" DPxMOD
", Size=%" PRId64
109 ", Type=0x%" PRIx64
", Name=%s\n",
110 i
, DPxPTR(args_base
[i
]), DPxPTR(args
[i
]), arg_sizes
[i
], arg_types
[i
],
111 (arg_names
) ? getNameFromMapping(arg_names
[i
]).c_str() : "unknown");
115 AsyncInfoTy
AsyncInfo(Device
);
116 int rc
= targetDataBegin(loc
, Device
, arg_num
, args_base
, args
, arg_sizes
,
117 arg_types
, arg_names
, arg_mappers
, AsyncInfo
);
118 if (rc
== OFFLOAD_SUCCESS
)
119 rc
= AsyncInfo
.synchronize();
120 handleTargetOutcome(rc
== OFFLOAD_SUCCESS
, loc
);
123 EXTERN
void __tgt_target_data_begin_nowait_mapper(
124 ident_t
*loc
, int64_t device_id
, int32_t arg_num
, void **args_base
,
125 void **args
, int64_t *arg_sizes
, int64_t *arg_types
,
126 map_var_info_t
*arg_names
, void **arg_mappers
, int32_t depNum
,
127 void *depList
, int32_t noAliasDepNum
, void *noAliasDepList
) {
128 TIMESCOPE_WITH_IDENT(loc
);
130 __tgt_target_data_begin_mapper(loc
, device_id
, arg_num
, args_base
, args
,
131 arg_sizes
, arg_types
, arg_names
, arg_mappers
);
134 /// passes data from the target, releases target memory and destroys
135 /// the host-target mapping (top entry from the stack of data maps)
136 /// created by the last __tgt_target_data_begin.
137 EXTERN
void __tgt_target_data_end(int64_t device_id
, int32_t arg_num
,
138 void **args_base
, void **args
,
139 int64_t *arg_sizes
, int64_t *arg_types
) {
141 __tgt_target_data_end_mapper(nullptr, device_id
, arg_num
, args_base
, args
,
142 arg_sizes
, arg_types
, nullptr, nullptr);
145 EXTERN
void __tgt_target_data_end_nowait(int64_t device_id
, int32_t arg_num
,
146 void **args_base
, void **args
,
147 int64_t *arg_sizes
, int64_t *arg_types
,
148 int32_t depNum
, void *depList
,
149 int32_t noAliasDepNum
,
150 void *noAliasDepList
) {
153 __tgt_target_data_end_mapper(nullptr, device_id
, arg_num
, args_base
, args
,
154 arg_sizes
, arg_types
, nullptr, nullptr);
157 EXTERN
void __tgt_target_data_end_mapper(ident_t
*loc
, int64_t device_id
,
158 int32_t arg_num
, void **args_base
,
159 void **args
, int64_t *arg_sizes
,
161 map_var_info_t
*arg_names
,
162 void **arg_mappers
) {
163 TIMESCOPE_WITH_IDENT(loc
);
164 DP("Entering data end region with %d mappings\n", arg_num
);
165 if (checkDeviceAndCtors(device_id
, loc
)) {
166 DP("Not offloading to device %" PRId64
"\n", device_id
);
170 DeviceTy
&Device
= *PM
->Devices
[device_id
];
172 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS
)
173 printKernelArguments(loc
, device_id
, arg_num
, arg_sizes
, arg_types
,
174 arg_names
, "Exiting OpenMP data region");
175 #ifdef OMPTARGET_DEBUG
176 for (int i
= 0; i
< arg_num
; ++i
) {
177 DP("Entry %2d: Base=" DPxMOD
", Begin=" DPxMOD
", Size=%" PRId64
178 ", Type=0x%" PRIx64
", Name=%s\n",
179 i
, DPxPTR(args_base
[i
]), DPxPTR(args
[i
]), arg_sizes
[i
], arg_types
[i
],
180 (arg_names
) ? getNameFromMapping(arg_names
[i
]).c_str() : "unknown");
184 AsyncInfoTy
AsyncInfo(Device
);
185 int rc
= targetDataEnd(loc
, Device
, arg_num
, args_base
, args
, arg_sizes
,
186 arg_types
, arg_names
, arg_mappers
, AsyncInfo
);
187 if (rc
== OFFLOAD_SUCCESS
)
188 rc
= AsyncInfo
.synchronize();
189 handleTargetOutcome(rc
== OFFLOAD_SUCCESS
, loc
);
192 EXTERN
void __tgt_target_data_end_nowait_mapper(
193 ident_t
*loc
, int64_t device_id
, int32_t arg_num
, void **args_base
,
194 void **args
, int64_t *arg_sizes
, int64_t *arg_types
,
195 map_var_info_t
*arg_names
, void **arg_mappers
, int32_t depNum
,
196 void *depList
, int32_t noAliasDepNum
, void *noAliasDepList
) {
197 TIMESCOPE_WITH_IDENT(loc
);
199 __tgt_target_data_end_mapper(loc
, device_id
, arg_num
, args_base
, args
,
200 arg_sizes
, arg_types
, arg_names
, arg_mappers
);
203 EXTERN
void __tgt_target_data_update(int64_t device_id
, int32_t arg_num
,
204 void **args_base
, void **args
,
205 int64_t *arg_sizes
, int64_t *arg_types
) {
207 __tgt_target_data_update_mapper(nullptr, device_id
, arg_num
, args_base
, args
,
208 arg_sizes
, arg_types
, nullptr, nullptr);
211 EXTERN
void __tgt_target_data_update_nowait(
212 int64_t device_id
, int32_t arg_num
, void **args_base
, void **args
,
213 int64_t *arg_sizes
, int64_t *arg_types
, int32_t depNum
, void *depList
,
214 int32_t noAliasDepNum
, void *noAliasDepList
) {
217 __tgt_target_data_update_mapper(nullptr, device_id
, arg_num
, args_base
, args
,
218 arg_sizes
, arg_types
, nullptr, nullptr);
221 EXTERN
void __tgt_target_data_update_mapper(ident_t
*loc
, int64_t device_id
,
222 int32_t arg_num
, void **args_base
,
223 void **args
, int64_t *arg_sizes
,
225 map_var_info_t
*arg_names
,
226 void **arg_mappers
) {
227 TIMESCOPE_WITH_IDENT(loc
);
228 DP("Entering data update with %d mappings\n", arg_num
);
229 if (checkDeviceAndCtors(device_id
, loc
)) {
230 DP("Not offloading to device %" PRId64
"\n", device_id
);
234 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS
)
235 printKernelArguments(loc
, device_id
, arg_num
, arg_sizes
, arg_types
,
236 arg_names
, "Updating OpenMP data");
238 DeviceTy
&Device
= *PM
->Devices
[device_id
];
239 AsyncInfoTy
AsyncInfo(Device
);
240 int rc
= targetDataUpdate(loc
, Device
, arg_num
, args_base
, args
, arg_sizes
,
241 arg_types
, arg_names
, arg_mappers
, AsyncInfo
);
242 if (rc
== OFFLOAD_SUCCESS
)
243 rc
= AsyncInfo
.synchronize();
244 handleTargetOutcome(rc
== OFFLOAD_SUCCESS
, loc
);
247 EXTERN
void __tgt_target_data_update_nowait_mapper(
248 ident_t
*loc
, int64_t device_id
, int32_t arg_num
, void **args_base
,
249 void **args
, int64_t *arg_sizes
, int64_t *arg_types
,
250 map_var_info_t
*arg_names
, void **arg_mappers
, int32_t depNum
,
251 void *depList
, int32_t noAliasDepNum
, void *noAliasDepList
) {
252 TIMESCOPE_WITH_IDENT(loc
);
254 __tgt_target_data_update_mapper(loc
, device_id
, arg_num
, args_base
, args
,
255 arg_sizes
, arg_types
, arg_names
, arg_mappers
);
258 EXTERN
int __tgt_target(int64_t device_id
, void *host_ptr
, int32_t arg_num
,
259 void **args_base
, void **args
, int64_t *arg_sizes
,
260 int64_t *arg_types
) {
262 return __tgt_target_mapper(nullptr, device_id
, host_ptr
, arg_num
, args_base
,
263 args
, arg_sizes
, arg_types
, nullptr, nullptr);
266 EXTERN
int __tgt_target_nowait(int64_t device_id
, void *host_ptr
,
267 int32_t arg_num
, void **args_base
, void **args
,
268 int64_t *arg_sizes
, int64_t *arg_types
,
269 int32_t depNum
, void *depList
,
270 int32_t noAliasDepNum
, void *noAliasDepList
) {
273 return __tgt_target_mapper(nullptr, device_id
, host_ptr
, arg_num
, args_base
,
274 args
, arg_sizes
, arg_types
, nullptr, nullptr);
277 EXTERN
int __tgt_target_mapper(ident_t
*loc
, int64_t device_id
, void *host_ptr
,
278 int32_t arg_num
, void **args_base
, void **args
,
279 int64_t *arg_sizes
, int64_t *arg_types
,
280 map_var_info_t
*arg_names
, void **arg_mappers
) {
281 TIMESCOPE_WITH_IDENT(loc
);
282 DP("Entering target region with entry point " DPxMOD
" and device Id %" PRId64
284 DPxPTR(host_ptr
), device_id
);
285 if (checkDeviceAndCtors(device_id
, loc
)) {
286 DP("Not offloading to device %" PRId64
"\n", device_id
);
290 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS
)
291 printKernelArguments(loc
, device_id
, arg_num
, arg_sizes
, arg_types
,
292 arg_names
, "Entering OpenMP kernel");
293 #ifdef OMPTARGET_DEBUG
294 for (int i
= 0; i
< arg_num
; ++i
) {
295 DP("Entry %2d: Base=" DPxMOD
", Begin=" DPxMOD
", Size=%" PRId64
296 ", Type=0x%" PRIx64
", Name=%s\n",
297 i
, DPxPTR(args_base
[i
]), DPxPTR(args
[i
]), arg_sizes
[i
], arg_types
[i
],
298 (arg_names
) ? getNameFromMapping(arg_names
[i
]).c_str() : "unknown");
302 DeviceTy
&Device
= *PM
->Devices
[device_id
];
303 AsyncInfoTy
AsyncInfo(Device
);
304 int rc
= target(loc
, Device
, host_ptr
, arg_num
, args_base
, args
, arg_sizes
,
305 arg_types
, arg_names
, arg_mappers
, 0, 0, false /*team*/,
307 if (rc
== OFFLOAD_SUCCESS
)
308 rc
= AsyncInfo
.synchronize();
309 handleTargetOutcome(rc
== OFFLOAD_SUCCESS
, loc
);
310 assert(rc
== OFFLOAD_SUCCESS
&& "__tgt_target_mapper unexpected failure!");
311 return OMP_TGT_SUCCESS
;
314 EXTERN
int __tgt_target_nowait_mapper(
315 ident_t
*loc
, int64_t device_id
, void *host_ptr
, int32_t arg_num
,
316 void **args_base
, void **args
, int64_t *arg_sizes
, int64_t *arg_types
,
317 map_var_info_t
*arg_names
, void **arg_mappers
, int32_t depNum
,
318 void *depList
, int32_t noAliasDepNum
, void *noAliasDepList
) {
319 TIMESCOPE_WITH_IDENT(loc
);
321 return __tgt_target_mapper(loc
, device_id
, host_ptr
, arg_num
, args_base
, args
,
322 arg_sizes
, arg_types
, arg_names
, arg_mappers
);
325 EXTERN
int __tgt_target_teams(int64_t device_id
, void *host_ptr
,
326 int32_t arg_num
, void **args_base
, void **args
,
327 int64_t *arg_sizes
, int64_t *arg_types
,
328 int32_t team_num
, int32_t thread_limit
) {
330 return __tgt_target_teams_mapper(nullptr, device_id
, host_ptr
, arg_num
,
331 args_base
, args
, arg_sizes
, arg_types
,
332 nullptr, nullptr, team_num
, thread_limit
);
335 EXTERN
int __tgt_target_teams_nowait(int64_t device_id
, void *host_ptr
,
336 int32_t arg_num
, void **args_base
,
337 void **args
, int64_t *arg_sizes
,
338 int64_t *arg_types
, int32_t team_num
,
339 int32_t thread_limit
, int32_t depNum
,
340 void *depList
, int32_t noAliasDepNum
,
341 void *noAliasDepList
) {
344 return __tgt_target_teams_mapper(nullptr, device_id
, host_ptr
, arg_num
,
345 args_base
, args
, arg_sizes
, arg_types
,
346 nullptr, nullptr, team_num
, thread_limit
);
349 EXTERN
int __tgt_target_teams_mapper(ident_t
*loc
, int64_t device_id
,
350 void *host_ptr
, int32_t arg_num
,
351 void **args_base
, void **args
,
352 int64_t *arg_sizes
, int64_t *arg_types
,
353 map_var_info_t
*arg_names
,
354 void **arg_mappers
, int32_t team_num
,
355 int32_t thread_limit
) {
356 DP("Entering target region with entry point " DPxMOD
" and device Id %" PRId64
358 DPxPTR(host_ptr
), device_id
);
359 if (checkDeviceAndCtors(device_id
, loc
)) {
360 DP("Not offloading to device %" PRId64
"\n", device_id
);
364 if (getInfoLevel() & OMP_INFOTYPE_KERNEL_ARGS
)
365 printKernelArguments(loc
, device_id
, arg_num
, arg_sizes
, arg_types
,
366 arg_names
, "Entering OpenMP kernel");
367 #ifdef OMPTARGET_DEBUG
368 for (int i
= 0; i
< arg_num
; ++i
) {
369 DP("Entry %2d: Base=" DPxMOD
", Begin=" DPxMOD
", Size=%" PRId64
370 ", Type=0x%" PRIx64
", Name=%s\n",
371 i
, DPxPTR(args_base
[i
]), DPxPTR(args
[i
]), arg_sizes
[i
], arg_types
[i
],
372 (arg_names
) ? getNameFromMapping(arg_names
[i
]).c_str() : "unknown");
376 DeviceTy
&Device
= *PM
->Devices
[device_id
];
377 AsyncInfoTy
AsyncInfo(Device
);
378 int rc
= target(loc
, Device
, host_ptr
, arg_num
, args_base
, args
, arg_sizes
,
379 arg_types
, arg_names
, arg_mappers
, team_num
, thread_limit
,
380 true /*team*/, AsyncInfo
);
381 if (rc
== OFFLOAD_SUCCESS
)
382 rc
= AsyncInfo
.synchronize();
383 handleTargetOutcome(rc
== OFFLOAD_SUCCESS
, loc
);
384 assert(rc
== OFFLOAD_SUCCESS
&&
385 "__tgt_target_teams_mapper unexpected failure!");
386 return OMP_TGT_SUCCESS
;
389 EXTERN
int __tgt_target_teams_nowait_mapper(
390 ident_t
*loc
, int64_t device_id
, void *host_ptr
, int32_t arg_num
,
391 void **args_base
, void **args
, int64_t *arg_sizes
, int64_t *arg_types
,
392 map_var_info_t
*arg_names
, void **arg_mappers
, int32_t team_num
,
393 int32_t thread_limit
, int32_t depNum
, void *depList
, int32_t noAliasDepNum
,
394 void *noAliasDepList
) {
395 TIMESCOPE_WITH_IDENT(loc
);
397 return __tgt_target_teams_mapper(loc
, device_id
, host_ptr
, arg_num
, args_base
,
398 args
, arg_sizes
, arg_types
, arg_names
,
399 arg_mappers
, team_num
, thread_limit
);
402 // Get the current number of components for a user-defined mapper.
403 EXTERN
int64_t __tgt_mapper_num_components(void *rt_mapper_handle
) {
405 auto *MapperComponentsPtr
= (struct MapperComponentsTy
*)rt_mapper_handle
;
406 int64_t size
= MapperComponentsPtr
->Components
.size();
407 DP("__tgt_mapper_num_components(Handle=" DPxMOD
") returns %" PRId64
"\n",
408 DPxPTR(rt_mapper_handle
), size
);
412 // Push back one component for a user-defined mapper.
413 EXTERN
void __tgt_push_mapper_component(void *rt_mapper_handle
, void *base
,
414 void *begin
, int64_t size
, int64_t type
,
417 DP("__tgt_push_mapper_component(Handle=" DPxMOD
418 ") adds an entry (Base=" DPxMOD
", Begin=" DPxMOD
", Size=%" PRId64
419 ", Type=0x%" PRIx64
", Name=%s).\n",
420 DPxPTR(rt_mapper_handle
), DPxPTR(base
), DPxPTR(begin
), size
, type
,
421 (name
) ? getNameFromMapping(name
).c_str() : "unknown");
422 auto *MapperComponentsPtr
= (struct MapperComponentsTy
*)rt_mapper_handle
;
423 MapperComponentsPtr
->Components
.push_back(
424 MapComponentInfoTy(base
, begin
, size
, type
, name
));
427 EXTERN
void __kmpc_push_target_tripcount(int64_t device_id
,
428 uint64_t loop_tripcount
) {
429 __kmpc_push_target_tripcount_mapper(nullptr, device_id
, loop_tripcount
);
432 EXTERN
void __kmpc_push_target_tripcount_mapper(ident_t
*loc
, int64_t device_id
,
433 uint64_t loop_tripcount
) {
434 TIMESCOPE_WITH_IDENT(loc
);
435 if (checkDeviceAndCtors(device_id
, loc
)) {
436 DP("Not offloading to device %" PRId64
"\n", device_id
);
440 DP("__kmpc_push_target_tripcount(%" PRId64
", %" PRIu64
")\n", device_id
,
442 PM
->TblMapMtx
.lock();
443 PM
->Devices
[device_id
]->LoopTripCnt
.emplace(__kmpc_global_thread_num(NULL
),
445 PM
->TblMapMtx
.unlock();
448 EXTERN
void __tgt_set_info_flag(uint32_t NewInfoLevel
) {
449 std::atomic
<uint32_t> &InfoLevel
= getInfoLevelInternal();
450 InfoLevel
.store(NewInfoLevel
);
451 for (auto &R
: PM
->RTLs
.AllRTLs
) {
453 R
.set_info_flag(NewInfoLevel
);
457 EXTERN
int __tgt_print_device_info(int64_t device_id
) {
458 return PM
->Devices
[device_id
]->printDeviceInfo(
459 PM
->Devices
[device_id
]->RTLDeviceID
);