1f44e41afSSri Hari Krishna Narayanan //===---------------interop.cpp - Implementation of interop directive -----===//
2f44e41afSSri Hari Krishna Narayanan //
3f44e41afSSri Hari Krishna Narayanan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f44e41afSSri Hari Krishna Narayanan // See https://llvm.org/LICENSE.txt for license information.
5f44e41afSSri Hari Krishna Narayanan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f44e41afSSri Hari Krishna Narayanan //
7f44e41afSSri Hari Krishna Narayanan //===----------------------------------------------------------------------===//
8f44e41afSSri Hari Krishna Narayanan
9f44e41afSSri Hari Krishna Narayanan #include "interop.h"
10f44e41afSSri Hari Krishna Narayanan #include "private.h"
11f44e41afSSri Hari Krishna Narayanan
12f44e41afSSri Hari Krishna Narayanan namespace {
getPropertyErrorType(omp_interop_property_t Property)13f44e41afSSri Hari Krishna Narayanan omp_interop_rc_t getPropertyErrorType(omp_interop_property_t Property) {
14f44e41afSSri Hari Krishna Narayanan switch (Property) {
15f44e41afSSri Hari Krishna Narayanan case omp_ipr_fr_id:
16f44e41afSSri Hari Krishna Narayanan return omp_irc_type_int;
17f44e41afSSri Hari Krishna Narayanan case omp_ipr_fr_name:
18f44e41afSSri Hari Krishna Narayanan return omp_irc_type_str;
19f44e41afSSri Hari Krishna Narayanan case omp_ipr_vendor:
20f44e41afSSri Hari Krishna Narayanan return omp_irc_type_int;
21f44e41afSSri Hari Krishna Narayanan case omp_ipr_vendor_name:
22f44e41afSSri Hari Krishna Narayanan return omp_irc_type_str;
23f44e41afSSri Hari Krishna Narayanan case omp_ipr_device_num:
24f44e41afSSri Hari Krishna Narayanan return omp_irc_type_int;
25f44e41afSSri Hari Krishna Narayanan case omp_ipr_platform:
26f44e41afSSri Hari Krishna Narayanan return omp_irc_type_int;
27f44e41afSSri Hari Krishna Narayanan case omp_ipr_device:
28f44e41afSSri Hari Krishna Narayanan return omp_irc_type_ptr;
29f44e41afSSri Hari Krishna Narayanan case omp_ipr_device_context:
30f44e41afSSri Hari Krishna Narayanan return omp_irc_type_ptr;
31f44e41afSSri Hari Krishna Narayanan case omp_ipr_targetsync:
32f44e41afSSri Hari Krishna Narayanan return omp_irc_type_ptr;
33f44e41afSSri Hari Krishna Narayanan };
34f44e41afSSri Hari Krishna Narayanan return omp_irc_no_value;
35f44e41afSSri Hari Krishna Narayanan }
36f44e41afSSri Hari Krishna Narayanan
getTypeMismatch(omp_interop_property_t Property,int * Err)37f44e41afSSri Hari Krishna Narayanan void getTypeMismatch(omp_interop_property_t Property, int *Err) {
38f44e41afSSri Hari Krishna Narayanan if (Err)
39f44e41afSSri Hari Krishna Narayanan *Err = getPropertyErrorType(Property);
40f44e41afSSri Hari Krishna Narayanan }
41f44e41afSSri Hari Krishna Narayanan
getVendorIdToStr(const omp_foreign_runtime_ids_t VendorId)42f44e41afSSri Hari Krishna Narayanan const char *getVendorIdToStr(const omp_foreign_runtime_ids_t VendorId) {
43f44e41afSSri Hari Krishna Narayanan switch (VendorId) {
44f44e41afSSri Hari Krishna Narayanan case cuda:
45f44e41afSSri Hari Krishna Narayanan return ("cuda");
46f44e41afSSri Hari Krishna Narayanan case cuda_driver:
47f44e41afSSri Hari Krishna Narayanan return ("cuda_driver");
48f44e41afSSri Hari Krishna Narayanan case opencl:
49f44e41afSSri Hari Krishna Narayanan return ("opencl");
50f44e41afSSri Hari Krishna Narayanan case sycl:
51f44e41afSSri Hari Krishna Narayanan return ("sycl");
52f44e41afSSri Hari Krishna Narayanan case hip:
53f44e41afSSri Hari Krishna Narayanan return ("hip");
54f44e41afSSri Hari Krishna Narayanan case level_zero:
55f44e41afSSri Hari Krishna Narayanan return ("level_zero");
56f44e41afSSri Hari Krishna Narayanan }
57f44e41afSSri Hari Krishna Narayanan return ("unknown");
58f44e41afSSri Hari Krishna Narayanan }
59f44e41afSSri Hari Krishna Narayanan
60f44e41afSSri Hari Krishna Narayanan template <typename PropertyTy>
61f44e41afSSri Hari Krishna Narayanan PropertyTy getProperty(omp_interop_val_t &InteropVal,
62f44e41afSSri Hari Krishna Narayanan omp_interop_property_t Property, int *Err);
63f44e41afSSri Hari Krishna Narayanan
64f44e41afSSri Hari Krishna Narayanan template <>
getProperty(omp_interop_val_t & InteropVal,omp_interop_property_t Property,int * Err)65*d27d0a67SJoseph Huber intptr_t getProperty<intptr_t>(omp_interop_val_t &InteropVal,
66*d27d0a67SJoseph Huber omp_interop_property_t Property, int *Err) {
67*d27d0a67SJoseph Huber switch (Property) {
68f44e41afSSri Hari Krishna Narayanan case omp_ipr_fr_id:
69*d27d0a67SJoseph Huber return InteropVal.backend_type_id;
70f44e41afSSri Hari Krishna Narayanan case omp_ipr_vendor:
71*d27d0a67SJoseph Huber return InteropVal.vendor_id;
72f44e41afSSri Hari Krishna Narayanan case omp_ipr_device_num:
73*d27d0a67SJoseph Huber return InteropVal.device_id;
74f44e41afSSri Hari Krishna Narayanan default:;
75f44e41afSSri Hari Krishna Narayanan }
76*d27d0a67SJoseph Huber getTypeMismatch(Property, Err);
77f44e41afSSri Hari Krishna Narayanan return 0;
78f44e41afSSri Hari Krishna Narayanan }
79f44e41afSSri Hari Krishna Narayanan
80f44e41afSSri Hari Krishna Narayanan template <>
getProperty(omp_interop_val_t & InteropVal,omp_interop_property_t Property,int * Err)81*d27d0a67SJoseph Huber const char *getProperty<const char *>(omp_interop_val_t &InteropVal,
82*d27d0a67SJoseph Huber omp_interop_property_t Property,
83*d27d0a67SJoseph Huber int *Err) {
84*d27d0a67SJoseph Huber switch (Property) {
85f44e41afSSri Hari Krishna Narayanan case omp_ipr_fr_id:
86*d27d0a67SJoseph Huber return InteropVal.interop_type == kmp_interop_type_tasksync
87f44e41afSSri Hari Krishna Narayanan ? "tasksync"
88f44e41afSSri Hari Krishna Narayanan : "device+context";
89f44e41afSSri Hari Krishna Narayanan case omp_ipr_vendor_name:
90*d27d0a67SJoseph Huber return getVendorIdToStr(InteropVal.vendor_id);
91f44e41afSSri Hari Krishna Narayanan default:
92*d27d0a67SJoseph Huber getTypeMismatch(Property, Err);
93f44e41afSSri Hari Krishna Narayanan return nullptr;
94f44e41afSSri Hari Krishna Narayanan }
95f44e41afSSri Hari Krishna Narayanan }
96f44e41afSSri Hari Krishna Narayanan
97f44e41afSSri Hari Krishna Narayanan template <>
getProperty(omp_interop_val_t & InteropVal,omp_interop_property_t Property,int * Err)98*d27d0a67SJoseph Huber void *getProperty<void *>(omp_interop_val_t &InteropVal,
99*d27d0a67SJoseph Huber omp_interop_property_t Property, int *Err) {
100*d27d0a67SJoseph Huber switch (Property) {
101f44e41afSSri Hari Krishna Narayanan case omp_ipr_device:
102*d27d0a67SJoseph Huber if (InteropVal.device_info.Device)
103*d27d0a67SJoseph Huber return InteropVal.device_info.Device;
104*d27d0a67SJoseph Huber *Err = omp_irc_no_value;
105*d27d0a67SJoseph Huber return const_cast<char *>(InteropVal.err_str);
106f44e41afSSri Hari Krishna Narayanan case omp_ipr_device_context:
107*d27d0a67SJoseph Huber return InteropVal.device_info.Context;
108f44e41afSSri Hari Krishna Narayanan case omp_ipr_targetsync:
109*d27d0a67SJoseph Huber return InteropVal.async_info->Queue;
110f44e41afSSri Hari Krishna Narayanan default:;
111f44e41afSSri Hari Krishna Narayanan }
112*d27d0a67SJoseph Huber getTypeMismatch(Property, Err);
113f44e41afSSri Hari Krishna Narayanan return nullptr;
114f44e41afSSri Hari Krishna Narayanan }
115f44e41afSSri Hari Krishna Narayanan
getPropertyCheck(omp_interop_val_t ** InteropPtr,omp_interop_property_t Property,int * Err)116*d27d0a67SJoseph Huber bool getPropertyCheck(omp_interop_val_t **InteropPtr,
117*d27d0a67SJoseph Huber omp_interop_property_t Property, int *Err) {
118*d27d0a67SJoseph Huber if (Err)
119*d27d0a67SJoseph Huber *Err = omp_irc_success;
120*d27d0a67SJoseph Huber if (!InteropPtr) {
121*d27d0a67SJoseph Huber if (Err)
122*d27d0a67SJoseph Huber *Err = omp_irc_empty;
123f44e41afSSri Hari Krishna Narayanan return false;
124f44e41afSSri Hari Krishna Narayanan }
125*d27d0a67SJoseph Huber if (Property >= 0 || Property < omp_ipr_first) {
126*d27d0a67SJoseph Huber if (Err)
127*d27d0a67SJoseph Huber *Err = omp_irc_out_of_range;
128f44e41afSSri Hari Krishna Narayanan return false;
129f44e41afSSri Hari Krishna Narayanan }
130*d27d0a67SJoseph Huber if (Property == omp_ipr_targetsync &&
131*d27d0a67SJoseph Huber (*InteropPtr)->interop_type != kmp_interop_type_tasksync) {
132*d27d0a67SJoseph Huber if (Err)
133*d27d0a67SJoseph Huber *Err = omp_irc_other;
134f44e41afSSri Hari Krishna Narayanan return false;
135f44e41afSSri Hari Krishna Narayanan }
136*d27d0a67SJoseph Huber if ((Property == omp_ipr_device || Property == omp_ipr_device_context) &&
137*d27d0a67SJoseph Huber (*InteropPtr)->interop_type == kmp_interop_type_tasksync) {
138*d27d0a67SJoseph Huber if (Err)
139*d27d0a67SJoseph Huber *Err = omp_irc_other;
140f44e41afSSri Hari Krishna Narayanan return false;
141f44e41afSSri Hari Krishna Narayanan }
142f44e41afSSri Hari Krishna Narayanan return true;
143f44e41afSSri Hari Krishna Narayanan }
144f44e41afSSri Hari Krishna Narayanan
145f44e41afSSri Hari Krishna Narayanan } // namespace
146f44e41afSSri Hari Krishna Narayanan
147f44e41afSSri Hari Krishna Narayanan #define __OMP_GET_INTEROP_TY(RETURN_TYPE, SUFFIX) \
148f44e41afSSri Hari Krishna Narayanan RETURN_TYPE omp_get_interop_##SUFFIX(const omp_interop_t interop, \
149f44e41afSSri Hari Krishna Narayanan omp_interop_property_t property_id, \
150f44e41afSSri Hari Krishna Narayanan int *err) { \
151f44e41afSSri Hari Krishna Narayanan omp_interop_val_t *interop_val = (omp_interop_val_t *)interop; \
152f44e41afSSri Hari Krishna Narayanan assert((interop_val)->interop_type == kmp_interop_type_tasksync); \
153f44e41afSSri Hari Krishna Narayanan if (!getPropertyCheck(&interop_val, property_id, err)) { \
154f44e41afSSri Hari Krishna Narayanan return (RETURN_TYPE)(0); \
155f44e41afSSri Hari Krishna Narayanan } \
156f44e41afSSri Hari Krishna Narayanan return getProperty<RETURN_TYPE>(*interop_val, property_id, err); \
157f44e41afSSri Hari Krishna Narayanan }
158f44e41afSSri Hari Krishna Narayanan __OMP_GET_INTEROP_TY(intptr_t, int)
159f44e41afSSri Hari Krishna Narayanan __OMP_GET_INTEROP_TY(void *, ptr)
160f44e41afSSri Hari Krishna Narayanan __OMP_GET_INTEROP_TY(const char *, str)
161f44e41afSSri Hari Krishna Narayanan #undef __OMP_GET_INTEROP_TY
162f44e41afSSri Hari Krishna Narayanan
163f44e41afSSri Hari Krishna Narayanan #define __OMP_GET_INTEROP_TY3(RETURN_TYPE, SUFFIX) \
164f44e41afSSri Hari Krishna Narayanan RETURN_TYPE omp_get_interop_##SUFFIX(const omp_interop_t interop, \
165f44e41afSSri Hari Krishna Narayanan omp_interop_property_t property_id) { \
166f44e41afSSri Hari Krishna Narayanan int err; \
167f44e41afSSri Hari Krishna Narayanan omp_interop_val_t *interop_val = (omp_interop_val_t *)interop; \
168f44e41afSSri Hari Krishna Narayanan if (!getPropertyCheck(&interop_val, property_id, &err)) { \
169f44e41afSSri Hari Krishna Narayanan return (RETURN_TYPE)(0); \
170f44e41afSSri Hari Krishna Narayanan } \
171f44e41afSSri Hari Krishna Narayanan return nullptr; \
172f44e41afSSri Hari Krishna Narayanan return getProperty<RETURN_TYPE>(*interop_val, property_id, &err); \
173f44e41afSSri Hari Krishna Narayanan }
174f44e41afSSri Hari Krishna Narayanan __OMP_GET_INTEROP_TY3(const char *, name)
175f44e41afSSri Hari Krishna Narayanan __OMP_GET_INTEROP_TY3(const char *, type_desc)
176f44e41afSSri Hari Krishna Narayanan __OMP_GET_INTEROP_TY3(const char *, rc_desc)
177f44e41afSSri Hari Krishna Narayanan #undef __OMP_GET_INTEROP_TY3
178f44e41afSSri Hari Krishna Narayanan
179f44e41afSSri Hari Krishna Narayanan typedef int64_t kmp_int64;
180f44e41afSSri Hari Krishna Narayanan
181f44e41afSSri Hari Krishna Narayanan #ifdef __cplusplus
182f44e41afSSri Hari Krishna Narayanan extern "C" {
183f44e41afSSri Hari Krishna Narayanan #endif
__tgt_interop_init(ident_t * LocRef,kmp_int32 Gtid,omp_interop_val_t * & InteropPtr,kmp_interop_type_t InteropType,kmp_int32 DeviceId,kmp_int64 Ndeps,kmp_depend_info_t * DepList,kmp_int32 HaveNowait)184*d27d0a67SJoseph Huber void __tgt_interop_init(ident_t *LocRef, kmp_int32 Gtid,
185*d27d0a67SJoseph Huber omp_interop_val_t *&InteropPtr,
186*d27d0a67SJoseph Huber kmp_interop_type_t InteropType, kmp_int32 DeviceId,
187*d27d0a67SJoseph Huber kmp_int64 Ndeps, kmp_depend_info_t *DepList,
188*d27d0a67SJoseph Huber kmp_int32 HaveNowait) {
189*d27d0a67SJoseph Huber kmp_int32 NdepsNoalias = 0;
190*d27d0a67SJoseph Huber kmp_depend_info_t *NoaliasDepList = NULL;
191*d27d0a67SJoseph Huber assert(InteropType != kmp_interop_type_unknown &&
192f44e41afSSri Hari Krishna Narayanan "Cannot initialize with unknown interop_type!");
193*d27d0a67SJoseph Huber if (DeviceId == -1) {
194*d27d0a67SJoseph Huber DeviceId = omp_get_default_device();
195f44e41afSSri Hari Krishna Narayanan }
196f44e41afSSri Hari Krishna Narayanan
197*d27d0a67SJoseph Huber if (InteropType == kmp_interop_type_tasksync) {
198*d27d0a67SJoseph Huber __kmpc_omp_wait_deps(LocRef, Gtid, Ndeps, DepList, NdepsNoalias,
199*d27d0a67SJoseph Huber NoaliasDepList);
200f44e41afSSri Hari Krishna Narayanan }
201f44e41afSSri Hari Krishna Narayanan
202*d27d0a67SJoseph Huber InteropPtr = new omp_interop_val_t(DeviceId, InteropType);
203*d27d0a67SJoseph Huber if (!deviceIsReady(DeviceId)) {
204*d27d0a67SJoseph Huber InteropPtr->err_str = "Device not ready!";
205f44e41afSSri Hari Krishna Narayanan return;
206f44e41afSSri Hari Krishna Narayanan }
207f44e41afSSri Hari Krishna Narayanan
208*d27d0a67SJoseph Huber DeviceTy &Device = *PM->Devices[DeviceId];
209f44e41afSSri Hari Krishna Narayanan if (!Device.RTL || !Device.RTL->init_device_info ||
210*d27d0a67SJoseph Huber Device.RTL->init_device_info(DeviceId, &(InteropPtr)->device_info,
211*d27d0a67SJoseph Huber &(InteropPtr)->err_str)) {
212*d27d0a67SJoseph Huber delete InteropPtr;
213*d27d0a67SJoseph Huber InteropPtr = omp_interop_none;
214f44e41afSSri Hari Krishna Narayanan }
215*d27d0a67SJoseph Huber if (InteropType == kmp_interop_type_tasksync) {
216f44e41afSSri Hari Krishna Narayanan if (!Device.RTL || !Device.RTL->init_async_info ||
217*d27d0a67SJoseph Huber Device.RTL->init_async_info(DeviceId, &(InteropPtr)->async_info)) {
218*d27d0a67SJoseph Huber delete InteropPtr;
219*d27d0a67SJoseph Huber InteropPtr = omp_interop_none;
220f44e41afSSri Hari Krishna Narayanan }
221f44e41afSSri Hari Krishna Narayanan }
222f44e41afSSri Hari Krishna Narayanan }
223f44e41afSSri Hari Krishna Narayanan
__tgt_interop_use(ident_t * LocRef,kmp_int32 Gtid,omp_interop_val_t * & InteropPtr,kmp_int32 DeviceId,kmp_int32 Ndeps,kmp_depend_info_t * DepList,kmp_int32 HaveNowait)224*d27d0a67SJoseph Huber void __tgt_interop_use(ident_t *LocRef, kmp_int32 Gtid,
225*d27d0a67SJoseph Huber omp_interop_val_t *&InteropPtr, kmp_int32 DeviceId,
226*d27d0a67SJoseph Huber kmp_int32 Ndeps, kmp_depend_info_t *DepList,
227*d27d0a67SJoseph Huber kmp_int32 HaveNowait) {
228*d27d0a67SJoseph Huber kmp_int32 NdepsNoalias = 0;
229*d27d0a67SJoseph Huber kmp_depend_info_t *NoaliasDepList = NULL;
230*d27d0a67SJoseph Huber assert(InteropPtr && "Cannot use nullptr!");
231*d27d0a67SJoseph Huber omp_interop_val_t *InteropVal = InteropPtr;
232*d27d0a67SJoseph Huber if (DeviceId == -1) {
233*d27d0a67SJoseph Huber DeviceId = omp_get_default_device();
234f44e41afSSri Hari Krishna Narayanan }
235*d27d0a67SJoseph Huber assert(InteropVal != omp_interop_none &&
236f44e41afSSri Hari Krishna Narayanan "Cannot use uninitialized interop_ptr!");
237*d27d0a67SJoseph Huber assert((DeviceId == -1 || InteropVal->device_id == DeviceId) &&
238f44e41afSSri Hari Krishna Narayanan "Inconsistent device-id usage!");
239f44e41afSSri Hari Krishna Narayanan
240*d27d0a67SJoseph Huber if (!deviceIsReady(DeviceId)) {
241*d27d0a67SJoseph Huber InteropPtr->err_str = "Device not ready!";
242f44e41afSSri Hari Krishna Narayanan return;
243f44e41afSSri Hari Krishna Narayanan }
244f44e41afSSri Hari Krishna Narayanan
245*d27d0a67SJoseph Huber if (InteropVal->interop_type == kmp_interop_type_tasksync) {
246*d27d0a67SJoseph Huber __kmpc_omp_wait_deps(LocRef, Gtid, Ndeps, DepList, NdepsNoalias,
247*d27d0a67SJoseph Huber NoaliasDepList);
248f44e41afSSri Hari Krishna Narayanan }
249f44e41afSSri Hari Krishna Narayanan // TODO Flush the queue associated with the interop through the plugin
250f44e41afSSri Hari Krishna Narayanan }
251f44e41afSSri Hari Krishna Narayanan
__tgt_interop_destroy(ident_t * LocRef,kmp_int32 Gtid,omp_interop_val_t * & InteropPtr,kmp_int32 DeviceId,kmp_int32 Ndeps,kmp_depend_info_t * DepList,kmp_int32 HaveNowait)252*d27d0a67SJoseph Huber void __tgt_interop_destroy(ident_t *LocRef, kmp_int32 Gtid,
253*d27d0a67SJoseph Huber omp_interop_val_t *&InteropPtr, kmp_int32 DeviceId,
254*d27d0a67SJoseph Huber kmp_int32 Ndeps, kmp_depend_info_t *DepList,
255*d27d0a67SJoseph Huber kmp_int32 HaveNowait) {
256*d27d0a67SJoseph Huber kmp_int32 NdepsNoalias = 0;
257*d27d0a67SJoseph Huber kmp_depend_info_t *NoaliasDepList = NULL;
258*d27d0a67SJoseph Huber assert(InteropPtr && "Cannot use nullptr!");
259*d27d0a67SJoseph Huber omp_interop_val_t *InteropVal = InteropPtr;
260*d27d0a67SJoseph Huber if (DeviceId == -1) {
261*d27d0a67SJoseph Huber DeviceId = omp_get_default_device();
262f44e41afSSri Hari Krishna Narayanan }
263f44e41afSSri Hari Krishna Narayanan
264*d27d0a67SJoseph Huber if (InteropVal == omp_interop_none)
265f44e41afSSri Hari Krishna Narayanan return;
266f44e41afSSri Hari Krishna Narayanan
267*d27d0a67SJoseph Huber assert((DeviceId == -1 || InteropVal->device_id == DeviceId) &&
268f44e41afSSri Hari Krishna Narayanan "Inconsistent device-id usage!");
269*d27d0a67SJoseph Huber if (!deviceIsReady(DeviceId)) {
270*d27d0a67SJoseph Huber InteropPtr->err_str = "Device not ready!";
271f44e41afSSri Hari Krishna Narayanan return;
272f44e41afSSri Hari Krishna Narayanan }
273f44e41afSSri Hari Krishna Narayanan
274*d27d0a67SJoseph Huber if (InteropVal->interop_type == kmp_interop_type_tasksync) {
275*d27d0a67SJoseph Huber __kmpc_omp_wait_deps(LocRef, Gtid, Ndeps, DepList, NdepsNoalias,
276*d27d0a67SJoseph Huber NoaliasDepList);
277f44e41afSSri Hari Krishna Narayanan }
278f44e41afSSri Hari Krishna Narayanan // TODO Flush the queue associated with the interop through the plugin
279f44e41afSSri Hari Krishna Narayanan // TODO Signal out dependences
280f44e41afSSri Hari Krishna Narayanan
281*d27d0a67SJoseph Huber delete InteropPtr;
282*d27d0a67SJoseph Huber InteropPtr = omp_interop_none;
283f44e41afSSri Hari Krishna Narayanan }
284f44e41afSSri Hari Krishna Narayanan #ifdef __cplusplus
285f44e41afSSri Hari Krishna Narayanan } // extern "C"
286f44e41afSSri Hari Krishna Narayanan #endif
287