1 //===----------------------------------------------------------------------===//
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 #ifndef _INTEROP_H_
10 #define _INTEROP_H_
11 
12 #include "omptarget.h"
13 #include <assert.h>
14 
15 #if defined(_WIN32)
16 #define __KAI_KMPC_CONVENTION __cdecl
17 #ifndef __KMP_IMP
18 #define __KMP_IMP __declspec(dllimport)
19 #endif
20 #else
21 #define __KAI_KMPC_CONVENTION
22 #ifndef __KMP_IMP
23 #define __KMP_IMP
24 #endif
25 #endif
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /// TODO: Include the `omp.h` of the current build
32 /* OpenMP 5.1 interop */
33 typedef intptr_t omp_intptr_t;
34 
35 /* 0..omp_get_num_interop_properties()-1 are reserved for implementation-defined
36  * properties */
37 typedef enum omp_interop_property {
38   omp_ipr_fr_id = -1,
39   omp_ipr_fr_name = -2,
40   omp_ipr_vendor = -3,
41   omp_ipr_vendor_name = -4,
42   omp_ipr_device_num = -5,
43   omp_ipr_platform = -6,
44   omp_ipr_device = -7,
45   omp_ipr_device_context = -8,
46   omp_ipr_targetsync = -9,
47   omp_ipr_first = -9
48 } omp_interop_property_t;
49 
50 #define omp_interop_none 0
51 
52 typedef enum omp_interop_rc {
53   omp_irc_no_value = 1,
54   omp_irc_success = 0,
55   omp_irc_empty = -1,
56   omp_irc_out_of_range = -2,
57   omp_irc_type_int = -3,
58   omp_irc_type_ptr = -4,
59   omp_irc_type_str = -5,
60   omp_irc_other = -6
61 } omp_interop_rc_t;
62 
63 typedef enum omp_interop_fr {
64   omp_ifr_cuda = 1,
65   omp_ifr_cuda_driver = 2,
66   omp_ifr_opencl = 3,
67   omp_ifr_sycl = 4,
68   omp_ifr_hip = 5,
69   omp_ifr_level_zero = 6,
70   omp_ifr_last = 7
71 } omp_interop_fr_t;
72 
73 typedef void *omp_interop_t;
74 
75 /*!
76  * The `omp_get_num_interop_properties` routine retrieves the number of
77  * implementation-defined properties available for an `omp_interop_t` object.
78  */
79 int __KAI_KMPC_CONVENTION omp_get_num_interop_properties(const omp_interop_t);
80 /*!
81  * The `omp_get_interop_int` routine retrieves an integer property from an
82  * `omp_interop_t` object.
83  */
84 omp_intptr_t __KAI_KMPC_CONVENTION omp_get_interop_int(const omp_interop_t,
85                                                        omp_interop_property_t,
86                                                        int *);
87 /*!
88  * The `omp_get_interop_ptr` routine retrieves a pointer property from an
89  * `omp_interop_t` object.
90  */
91 void *__KAI_KMPC_CONVENTION omp_get_interop_ptr(const omp_interop_t,
92                                                 omp_interop_property_t, int *);
93 /*!
94  * The `omp_get_interop_str` routine retrieves a string property from an
95  * `omp_interop_t` object.
96  */
97 const char *__KAI_KMPC_CONVENTION omp_get_interop_str(const omp_interop_t,
98                                                       omp_interop_property_t,
99                                                       int *);
100 /*!
101  * The `omp_get_interop_name` routine retrieves a property name from an
102  * `omp_interop_t` object.
103  */
104 const char *__KAI_KMPC_CONVENTION omp_get_interop_name(const omp_interop_t,
105                                                        omp_interop_property_t);
106 /*!
107  * The `omp_get_interop_type_desc` routine retrieves a description of the type
108  * of a property associated with an `omp_interop_t` object.
109  */
110 const char *__KAI_KMPC_CONVENTION
111 omp_get_interop_type_desc(const omp_interop_t, omp_interop_property_t);
112 /*!
113  * The `omp_get_interop_rc_desc` routine retrieves a description of the return
114  * code associated with an `omp_interop_t` object.
115  */
116 extern const char *__KAI_KMPC_CONVENTION
117 omp_get_interop_rc_desc(const omp_interop_t, omp_interop_rc_t);
118 
119 typedef struct kmp_tasking_flags { /* Total struct must be exactly 32 bits */
120   /* Compiler flags */             /* Total compiler flags must be 16 bits */
121   unsigned tiedness : 1;           /* task is either tied (1) or untied (0) */
122   unsigned final : 1;              /* task is final(1) so execute immediately */
123   unsigned merged_if0 : 1; // no __kmpc_task_{begin/complete}_if0 calls in if0
124   unsigned destructors_thunk : 1; // set if the compiler creates a thunk to
125   unsigned proxy : 1; // task is a proxy task (it will be executed outside the
126   unsigned priority_specified : 1; // set if the compiler provides priority
127   unsigned detachable : 1;         // 1 == can detach */
128   unsigned unshackled : 1;         /* 1 == unshackled task */
129   unsigned target : 1;             /* 1 == target task */
130   unsigned reserved : 7;           /* reserved for compiler use */
131   unsigned tasktype : 1;    /* task is either explicit(1) or implicit (0) */
132   unsigned task_serial : 1; // task is executed immediately (1) or deferred (0)
133   unsigned tasking_ser : 1; // all tasks in team are either executed immediately
134   unsigned team_serial : 1; // entire team is serial (1) [1 thread] or parallel
135   unsigned started : 1;     /* 1==started, 0==not started     */
136   unsigned executing : 1;   /* 1==executing, 0==not executing */
137   unsigned complete : 1;    /* 1==complete, 0==not complete   */
138   unsigned freed : 1;       /* 1==freed, 0==allocated        */
139   unsigned native : 1;      /* 1==gcc-compiled task, 0==intel */
140   unsigned reserved31 : 7;  /* reserved for library use */
141 } kmp_tasking_flags_t;
142 
143 typedef enum omp_interop_backend_type_t {
144   // reserve 0
145   omp_interop_backend_type_cuda_1 = 1,
146 } omp_interop_backend_type_t;
147 
148 typedef enum kmp_interop_type_t {
149   kmp_interop_type_unknown = -1,
150   kmp_interop_type_platform,
151   kmp_interop_type_device,
152   kmp_interop_type_tasksync,
153 } kmp_interop_type_t;
154 
155 typedef enum omp_foreign_runtime_ids {
156   cuda = 1,
157   cuda_driver = 2,
158   opencl = 3,
159   sycl = 4,
160   hip = 5,
161   level_zero = 6,
162 } omp_foreign_runtime_ids_t;
163 
164 /// The interop value type, aka. the interop object.
165 typedef struct omp_interop_val_t {
166   /// Device and interop-type are determined at construction time and fix.
omp_interop_val_tomp_interop_val_t167   omp_interop_val_t(intptr_t device_id, kmp_interop_type_t interop_type)
168       : interop_type(interop_type), device_id(device_id) {}
169   const char *err_str = nullptr;
170   __tgt_async_info *async_info = nullptr;
171   __tgt_device_info device_info;
172   const kmp_interop_type_t interop_type;
173   const intptr_t device_id;
174   const omp_foreign_runtime_ids_t vendor_id = cuda;
175   const intptr_t backend_type_id = omp_interop_backend_type_cuda_1;
176 } omp_interop_val_t;
177 
178 #ifdef __cplusplus
179 }
180 #endif
181 #endif
182