1 //===---------- private.h - 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 // Private function declarations and helper macros for debugging output.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef _OMPTARGET_PRIVATE_H
14 #define _OMPTARGET_PRIVATE_H
15
16 #include "device.h"
17 #include <Debug.h>
18 #include <SourceInfo.h>
19 #include <omptarget.h>
20
21 #include <cstdint>
22
23 extern int targetDataBegin(ident_t *Loc, DeviceTy &Device, int32_t ArgNum,
24 void **ArgsBase, void **Args, int64_t *ArgSizes,
25 int64_t *ArgTypes, map_var_info_t *ArgNames,
26 void **ArgMappers, AsyncInfoTy &AsyncInfo,
27 bool FromMapper = false);
28
29 extern int targetDataEnd(ident_t *Loc, DeviceTy &Device, int32_t ArgNum,
30 void **ArgBases, void **Args, int64_t *ArgSizes,
31 int64_t *ArgTypes, map_var_info_t *ArgNames,
32 void **ArgMappers, AsyncInfoTy &AsyncInfo,
33 bool FromMapper = false);
34
35 extern int targetDataUpdate(ident_t *Loc, DeviceTy &Device, int32_t ArgNum,
36 void **ArgsBase, void **Args, int64_t *ArgSizes,
37 int64_t *ArgTypes, map_var_info_t *ArgNames,
38 void **ArgMappers, AsyncInfoTy &AsyncInfo,
39 bool FromMapper = false);
40
41 extern int target(ident_t *Loc, DeviceTy &Device, void *HostPtr, int32_t ArgNum,
42 void **ArgBases, void **Args, int64_t *ArgSizes,
43 int64_t *ArgTypes, map_var_info_t *ArgNames,
44 void **ArgMappers, int32_t TeamNum, int32_t ThreadLimit,
45 uint64_t Tripcount, int IsTeamConstruct,
46 AsyncInfoTy &AsyncInfo);
47
48 extern void handleTargetOutcome(bool Success, ident_t *Loc);
49 extern bool checkDeviceAndCtors(int64_t &DeviceID, ident_t *Loc);
50 extern void *targetAllocExplicit(size_t Size, int DeviceNum, int Kind,
51 const char *Name);
52
53 // This structure stores information of a mapped memory region.
54 struct MapComponentInfoTy {
55 void *Base;
56 void *Begin;
57 int64_t Size;
58 int64_t Type;
59 void *Name;
60 MapComponentInfoTy() = default;
MapComponentInfoTyMapComponentInfoTy61 MapComponentInfoTy(void *Base, void *Begin, int64_t Size, int64_t Type,
62 void *Name)
63 : Base(Base), Begin(Begin), Size(Size), Type(Type), Name(Name) {}
64 };
65
66 // This structure stores all components of a user-defined mapper. The number of
67 // components are dynamically decided, so we utilize C++ STL vector
68 // implementation here.
69 struct MapperComponentsTy {
70 std::vector<MapComponentInfoTy> Components;
sizeMapperComponentsTy71 int32_t size() { return Components.size(); }
72 };
73
74 // The mapper function pointer type. It follows the signature below:
75 // void .omp_mapper.<type_name>.<mapper_id>.(void *rt_mapper_handle,
76 // void *base, void *begin,
77 // size_t size, int64_t type,
78 // void * name);
79 typedef void (*MapperFuncPtrTy)(void *, void *, void *, int64_t, int64_t,
80 void *);
81
82 // Function pointer type for targetData* functions (targetDataBegin,
83 // targetDataEnd and targetDataUpdate).
84 typedef int (*TargetDataFuncPtrTy)(ident_t *, DeviceTy &, int32_t, void **,
85 void **, int64_t *, int64_t *,
86 map_var_info_t *, void **, AsyncInfoTy &,
87 bool);
88
89 // Implemented in libomp, they are called from within __tgt_* functions.
90 #ifdef __cplusplus
91 extern "C" {
92 #endif
93 /*!
94 * The ident structure that describes a source location.
95 * The struct is identical to the one in the kmp.h file.
96 * We maintain the same data structure for compatibility.
97 */
98 typedef int kmp_int32;
99 typedef intptr_t kmp_intptr_t;
100 // Compiler sends us this info:
101 typedef struct kmp_depend_info {
102 kmp_intptr_t base_addr;
103 size_t len;
104 struct {
105 bool in : 1;
106 bool out : 1;
107 bool mtx : 1;
108 } flags;
109 } kmp_depend_info_t;
110 // functions that extract info from libomp; keep in sync
111 int omp_get_default_device(void) __attribute__((weak));
112 int32_t __kmpc_global_thread_num(void *) __attribute__((weak));
113 int __kmpc_get_target_offload(void) __attribute__((weak));
114 void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps,
115 kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias,
116 kmp_depend_info_t *noalias_dep_list)
117 __attribute__((weak));
118 #ifdef __cplusplus
119 }
120 #endif
121
122 #define TARGET_NAME Libomptarget
123 #define DEBUG_PREFIX GETNAME(TARGET_NAME)
124
125 ////////////////////////////////////////////////////////////////////////////////
126 /// dump a table of all the host-target pointer pairs on failure
dumpTargetPointerMappings(const ident_t * Loc,DeviceTy & Device)127 static inline void dumpTargetPointerMappings(const ident_t *Loc,
128 DeviceTy &Device) {
129 DeviceTy::HDTTMapAccessorTy HDTTMap =
130 Device.HostDataToTargetMap.getExclusiveAccessor();
131 if (HDTTMap->empty())
132 return;
133
134 SourceInfo Kernel(Loc);
135 INFO(OMP_INFOTYPE_ALL, Device.DeviceID,
136 "OpenMP Host-Device pointer mappings after block at %s:%d:%d:\n",
137 Kernel.getFilename(), Kernel.getLine(), Kernel.getColumn());
138 INFO(OMP_INFOTYPE_ALL, Device.DeviceID, "%-18s %-18s %s %s %s %s\n",
139 "Host Ptr", "Target Ptr", "Size (B)", "DynRefCount", "HoldRefCount",
140 "Declaration");
141 for (const auto &It : *HDTTMap) {
142 HostDataToTargetTy &HDTT = *It.HDTT;
143 SourceInfo Info(HDTT.HstPtrName);
144 INFO(OMP_INFOTYPE_ALL, Device.DeviceID,
145 DPxMOD " " DPxMOD " %-8" PRIuPTR " %-11s %-12s %s at %s:%d:%d\n",
146 DPxPTR(HDTT.HstPtrBegin), DPxPTR(HDTT.TgtPtrBegin),
147 HDTT.HstPtrEnd - HDTT.HstPtrBegin, HDTT.dynRefCountToStr().c_str(),
148 HDTT.holdRefCountToStr().c_str(), Info.getName(), Info.getFilename(),
149 Info.getLine(), Info.getColumn());
150 }
151 }
152
153 ////////////////////////////////////////////////////////////////////////////////
154 /// Print out the names and properties of the arguments to each kernel
155 static inline void
printKernelArguments(const ident_t * Loc,const int64_t DeviceId,const int32_t ArgNum,const int64_t * ArgSizes,const int64_t * ArgTypes,const map_var_info_t * ArgNames,const char * RegionType)156 printKernelArguments(const ident_t *Loc, const int64_t DeviceId,
157 const int32_t ArgNum, const int64_t *ArgSizes,
158 const int64_t *ArgTypes, const map_var_info_t *ArgNames,
159 const char *RegionType) {
160 SourceInfo Info(Loc);
161 INFO(OMP_INFOTYPE_ALL, DeviceId, "%s at %s:%d:%d with %d arguments:\n",
162 RegionType, Info.getFilename(), Info.getLine(), Info.getColumn(),
163 ArgNum);
164
165 for (int32_t I = 0; I < ArgNum; ++I) {
166 const map_var_info_t VarName = (ArgNames) ? ArgNames[I] : nullptr;
167 const char *Type = nullptr;
168 const char *Implicit =
169 (ArgTypes[I] & OMP_TGT_MAPTYPE_IMPLICIT) ? "(implicit)" : "";
170 if (ArgTypes[I] & OMP_TGT_MAPTYPE_TO && ArgTypes[I] & OMP_TGT_MAPTYPE_FROM)
171 Type = "tofrom";
172 else if (ArgTypes[I] & OMP_TGT_MAPTYPE_TO)
173 Type = "to";
174 else if (ArgTypes[I] & OMP_TGT_MAPTYPE_FROM)
175 Type = "from";
176 else if (ArgTypes[I] & OMP_TGT_MAPTYPE_PRIVATE)
177 Type = "private";
178 else if (ArgTypes[I] & OMP_TGT_MAPTYPE_LITERAL)
179 Type = "firstprivate";
180 else if (ArgSizes[I] != 0)
181 Type = "alloc";
182 else
183 Type = "use_address";
184
185 INFO(OMP_INFOTYPE_ALL, DeviceId, "%s(%s)[%" PRId64 "] %s\n", Type,
186 getNameFromMapping(VarName).c_str(), ArgSizes[I], Implicit);
187 }
188 }
189
190 #ifdef OMPTARGET_PROFILE_ENABLED
191 #include "llvm/Support/TimeProfiler.h"
192 #define TIMESCOPE() llvm::TimeTraceScope TimeScope(__FUNCTION__)
193 #define TIMESCOPE_WITH_IDENT(IDENT) \
194 SourceInfo SI(IDENT); \
195 llvm::TimeTraceScope TimeScope(__FUNCTION__, SI.getProfileLocation())
196 #define TIMESCOPE_WITH_NAME_AND_IDENT(NAME, IDENT) \
197 SourceInfo SI(IDENT); \
198 llvm::TimeTraceScope TimeScope(NAME, SI.getProfileLocation())
199 #else
200 #define TIMESCOPE()
201 #define TIMESCOPE_WITH_IDENT(IDENT)
202 #define TIMESCOPE_WITH_NAME_AND_IDENT(NAME, IDENT)
203 #endif
204
205 #endif
206