Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / openmp / libomptarget / src / interop.cpp
blob0f6c887060ee54cd3f50838b6abec255893cba5e
1 //===---------------interop.cpp - Implementation of interop directive -----===//
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 //===----------------------------------------------------------------------===//
9 #include "interop.h"
10 #include "private.h"
12 namespace {
13 omp_interop_rc_t getPropertyErrorType(omp_interop_property_t Property) {
14 switch (Property) {
15 case omp_ipr_fr_id:
16 return omp_irc_type_int;
17 case omp_ipr_fr_name:
18 return omp_irc_type_str;
19 case omp_ipr_vendor:
20 return omp_irc_type_int;
21 case omp_ipr_vendor_name:
22 return omp_irc_type_str;
23 case omp_ipr_device_num:
24 return omp_irc_type_int;
25 case omp_ipr_platform:
26 return omp_irc_type_int;
27 case omp_ipr_device:
28 return omp_irc_type_ptr;
29 case omp_ipr_device_context:
30 return omp_irc_type_ptr;
31 case omp_ipr_targetsync:
32 return omp_irc_type_ptr;
34 return omp_irc_no_value;
37 void getTypeMismatch(omp_interop_property_t Property, int *Err) {
38 if (Err)
39 *Err = getPropertyErrorType(Property);
42 const char *getVendorIdToStr(const omp_foreign_runtime_ids_t VendorId) {
43 switch (VendorId) {
44 case cuda:
45 return ("cuda");
46 case cuda_driver:
47 return ("cuda_driver");
48 case opencl:
49 return ("opencl");
50 case sycl:
51 return ("sycl");
52 case hip:
53 return ("hip");
54 case level_zero:
55 return ("level_zero");
57 return ("unknown");
60 template <typename PropertyTy>
61 PropertyTy getProperty(omp_interop_val_t &InteropVal,
62 omp_interop_property_t Property, int *Err);
64 template <>
65 intptr_t getProperty<intptr_t>(omp_interop_val_t &InteropVal,
66 omp_interop_property_t Property, int *Err) {
67 switch (Property) {
68 case omp_ipr_fr_id:
69 return InteropVal.backend_type_id;
70 case omp_ipr_vendor:
71 return InteropVal.vendor_id;
72 case omp_ipr_device_num:
73 return InteropVal.device_id;
74 default:;
76 getTypeMismatch(Property, Err);
77 return 0;
80 template <>
81 const char *getProperty<const char *>(omp_interop_val_t &InteropVal,
82 omp_interop_property_t Property,
83 int *Err) {
84 switch (Property) {
85 case omp_ipr_fr_id:
86 return InteropVal.interop_type == kmp_interop_type_tasksync
87 ? "tasksync"
88 : "device+context";
89 case omp_ipr_vendor_name:
90 return getVendorIdToStr(InteropVal.vendor_id);
91 default:
92 getTypeMismatch(Property, Err);
93 return nullptr;
97 template <>
98 void *getProperty<void *>(omp_interop_val_t &InteropVal,
99 omp_interop_property_t Property, int *Err) {
100 switch (Property) {
101 case omp_ipr_device:
102 if (InteropVal.device_info.Device)
103 return InteropVal.device_info.Device;
104 *Err = omp_irc_no_value;
105 return const_cast<char *>(InteropVal.err_str);
106 case omp_ipr_device_context:
107 return InteropVal.device_info.Context;
108 case omp_ipr_targetsync:
109 return InteropVal.async_info->Queue;
110 default:;
112 getTypeMismatch(Property, Err);
113 return nullptr;
116 bool getPropertyCheck(omp_interop_val_t **InteropPtr,
117 omp_interop_property_t Property, int *Err) {
118 if (Err)
119 *Err = omp_irc_success;
120 if (!InteropPtr) {
121 if (Err)
122 *Err = omp_irc_empty;
123 return false;
125 if (Property >= 0 || Property < omp_ipr_first) {
126 if (Err)
127 *Err = omp_irc_out_of_range;
128 return false;
130 if (Property == omp_ipr_targetsync &&
131 (*InteropPtr)->interop_type != kmp_interop_type_tasksync) {
132 if (Err)
133 *Err = omp_irc_other;
134 return false;
136 if ((Property == omp_ipr_device || Property == omp_ipr_device_context) &&
137 (*InteropPtr)->interop_type == kmp_interop_type_tasksync) {
138 if (Err)
139 *Err = omp_irc_other;
140 return false;
142 return true;
145 } // namespace
147 #define __OMP_GET_INTEROP_TY(RETURN_TYPE, SUFFIX) \
148 RETURN_TYPE omp_get_interop_##SUFFIX(const omp_interop_t interop, \
149 omp_interop_property_t property_id, \
150 int *err) { \
151 omp_interop_val_t *interop_val = (omp_interop_val_t *)interop; \
152 assert((interop_val)->interop_type == kmp_interop_type_tasksync); \
153 if (!getPropertyCheck(&interop_val, property_id, err)) { \
154 return (RETURN_TYPE)(0); \
156 return getProperty<RETURN_TYPE>(*interop_val, property_id, err); \
158 __OMP_GET_INTEROP_TY(intptr_t, int)
159 __OMP_GET_INTEROP_TY(void *, ptr)
160 __OMP_GET_INTEROP_TY(const char *, str)
161 #undef __OMP_GET_INTEROP_TY
163 #define __OMP_GET_INTEROP_TY3(RETURN_TYPE, SUFFIX) \
164 RETURN_TYPE omp_get_interop_##SUFFIX(const omp_interop_t interop, \
165 omp_interop_property_t property_id) { \
166 int err; \
167 omp_interop_val_t *interop_val = (omp_interop_val_t *)interop; \
168 if (!getPropertyCheck(&interop_val, property_id, &err)) { \
169 return (RETURN_TYPE)(0); \
171 return nullptr; \
172 return getProperty<RETURN_TYPE>(*interop_val, property_id, &err); \
174 __OMP_GET_INTEROP_TY3(const char *, name)
175 __OMP_GET_INTEROP_TY3(const char *, type_desc)
176 __OMP_GET_INTEROP_TY3(const char *, rc_desc)
177 #undef __OMP_GET_INTEROP_TY3
179 typedef int64_t kmp_int64;
181 #ifdef __cplusplus
182 extern "C" {
183 #endif
184 void __tgt_interop_init(ident_t *LocRef, kmp_int32 Gtid,
185 omp_interop_val_t *&InteropPtr,
186 kmp_interop_type_t InteropType, kmp_int32 DeviceId,
187 kmp_int32 Ndeps, kmp_depend_info_t *DepList,
188 kmp_int32 HaveNowait) {
189 kmp_int32 NdepsNoalias = 0;
190 kmp_depend_info_t *NoaliasDepList = NULL;
191 assert(InteropType != kmp_interop_type_unknown &&
192 "Cannot initialize with unknown interop_type!");
193 if (DeviceId == -1) {
194 DeviceId = omp_get_default_device();
197 if (InteropType == kmp_interop_type_tasksync) {
198 __kmpc_omp_wait_deps(LocRef, Gtid, Ndeps, DepList, NdepsNoalias,
199 NoaliasDepList);
202 InteropPtr = new omp_interop_val_t(DeviceId, InteropType);
203 if (!deviceIsReady(DeviceId)) {
204 InteropPtr->err_str = "Device not ready!";
205 return;
208 DeviceTy &Device = *PM->Devices[DeviceId];
209 if (!Device.RTL || !Device.RTL->init_device_info ||
210 Device.RTL->init_device_info(DeviceId, &(InteropPtr)->device_info,
211 &(InteropPtr)->err_str)) {
212 delete InteropPtr;
213 InteropPtr = omp_interop_none;
215 if (InteropType == kmp_interop_type_tasksync) {
216 if (!Device.RTL || !Device.RTL->init_async_info ||
217 Device.RTL->init_async_info(DeviceId, &(InteropPtr)->async_info)) {
218 delete InteropPtr;
219 InteropPtr = omp_interop_none;
224 void __tgt_interop_use(ident_t *LocRef, kmp_int32 Gtid,
225 omp_interop_val_t *&InteropPtr, kmp_int32 DeviceId,
226 kmp_int32 Ndeps, kmp_depend_info_t *DepList,
227 kmp_int32 HaveNowait) {
228 kmp_int32 NdepsNoalias = 0;
229 kmp_depend_info_t *NoaliasDepList = NULL;
230 assert(InteropPtr && "Cannot use nullptr!");
231 omp_interop_val_t *InteropVal = InteropPtr;
232 if (DeviceId == -1) {
233 DeviceId = omp_get_default_device();
235 assert(InteropVal != omp_interop_none &&
236 "Cannot use uninitialized interop_ptr!");
237 assert((DeviceId == -1 || InteropVal->device_id == DeviceId) &&
238 "Inconsistent device-id usage!");
240 if (!deviceIsReady(DeviceId)) {
241 InteropPtr->err_str = "Device not ready!";
242 return;
245 if (InteropVal->interop_type == kmp_interop_type_tasksync) {
246 __kmpc_omp_wait_deps(LocRef, Gtid, Ndeps, DepList, NdepsNoalias,
247 NoaliasDepList);
249 // TODO Flush the queue associated with the interop through the plugin
252 void __tgt_interop_destroy(ident_t *LocRef, kmp_int32 Gtid,
253 omp_interop_val_t *&InteropPtr, kmp_int32 DeviceId,
254 kmp_int32 Ndeps, kmp_depend_info_t *DepList,
255 kmp_int32 HaveNowait) {
256 kmp_int32 NdepsNoalias = 0;
257 kmp_depend_info_t *NoaliasDepList = NULL;
258 assert(InteropPtr && "Cannot use nullptr!");
259 omp_interop_val_t *InteropVal = InteropPtr;
260 if (DeviceId == -1) {
261 DeviceId = omp_get_default_device();
264 if (InteropVal == omp_interop_none)
265 return;
267 assert((DeviceId == -1 || InteropVal->device_id == DeviceId) &&
268 "Inconsistent device-id usage!");
269 if (!deviceIsReady(DeviceId)) {
270 InteropPtr->err_str = "Device not ready!";
271 return;
274 if (InteropVal->interop_type == kmp_interop_type_tasksync) {
275 __kmpc_omp_wait_deps(LocRef, Gtid, Ndeps, DepList, NdepsNoalias,
276 NoaliasDepList);
278 // TODO Flush the queue associated with the interop through the plugin
279 // TODO Signal out dependences
281 delete InteropPtr;
282 InteropPtr = omp_interop_none;
284 #ifdef __cplusplus
285 } // extern "C"
286 #endif