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