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 arg_num,
24                            void **args_base, void **args, int64_t *arg_sizes,
25                            int64_t *arg_types, map_var_info_t *arg_names,
26                            void **arg_mappers, 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 *arg_names,
32                          void **ArgMappers, AsyncInfoTy &AsyncInfo,
33                          bool FromMapper = false);
34 
35 extern int targetDataUpdate(ident_t *loc, DeviceTy &Device, int32_t arg_num,
36                             void **args_base, void **args, int64_t *arg_sizes,
37                             int64_t *arg_types, map_var_info_t *arg_names,
38                             void **arg_mappers, 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 *arg_names,
44                   void **ArgMappers, int32_t TeamNum, int32_t ThreadLimit,
45                   int IsTeamConstruct, AsyncInfoTy &AsyncInfo);
46 
47 extern void handleTargetOutcome(bool Success, ident_t *Loc);
48 extern int checkDeviceAndCtors(int64_t &DeviceID, ident_t *Loc);
49 extern void *targetAllocExplicit(size_t size, int device_num, int kind,
50                                  const char *name);
51 
52 // This structure stores information of a mapped memory region.
53 struct MapComponentInfoTy {
54   void *Base;
55   void *Begin;
56   int64_t Size;
57   int64_t Type;
58   void *Name;
59   MapComponentInfoTy() = default;
MapComponentInfoTyMapComponentInfoTy60   MapComponentInfoTy(void *Base, void *Begin, int64_t Size, int64_t Type,
61                      void *Name)
62       : Base(Base), Begin(Begin), Size(Size), Type(Type), Name(Name) {}
63 };
64 
65 // This structure stores all components of a user-defined mapper. The number of
66 // components are dynamically decided, so we utilize C++ STL vector
67 // implementation here.
68 struct MapperComponentsTy {
69   std::vector<MapComponentInfoTy> Components;
sizeMapperComponentsTy70   int32_t size() { return Components.size(); }
71 };
72 
73 // The mapper function pointer type. It follows the signature below:
74 // void .omp_mapper.<type_name>.<mapper_id>.(void *rt_mapper_handle,
75 //                                           void *base, void *begin,
76 //                                           size_t size, int64_t type,
77 //                                           void * name);
78 typedef void (*MapperFuncPtrTy)(void *, void *, void *, int64_t, int64_t,
79                                 void *);
80 
81 // Function pointer type for targetData* functions (targetDataBegin,
82 // targetDataEnd and targetDataUpdate).
83 typedef int (*TargetDataFuncPtrTy)(ident_t *, DeviceTy &, int32_t, void **,
84                                    void **, int64_t *, int64_t *,
85                                    map_var_info_t *, void **, AsyncInfoTy &,
86                                    bool);
87 
88 // Implemented in libomp, they are called from within __tgt_* functions.
89 #ifdef __cplusplus
90 extern "C" {
91 #endif
92 // functions that extract info from libomp; keep in sync
93 int omp_get_default_device(void) __attribute__((weak));
94 int32_t __kmpc_omp_taskwait(void *loc_ref, int32_t gtid) __attribute__((weak));
95 int32_t __kmpc_global_thread_num(void *) __attribute__((weak));
96 int __kmpc_get_target_offload(void) __attribute__((weak));
97 #ifdef __cplusplus
98 }
99 #endif
100 
101 #define TARGET_NAME Libomptarget
102 #define DEBUG_PREFIX GETNAME(TARGET_NAME)
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// dump a table of all the host-target pointer pairs on failure
dumpTargetPointerMappings(const ident_t * Loc,DeviceTy & Device)106 static inline void dumpTargetPointerMappings(const ident_t *Loc,
107                                              DeviceTy &Device) {
108   if (Device.HostDataToTargetMap.empty())
109     return;
110 
111   SourceInfo Kernel(Loc);
112   INFO(OMP_INFOTYPE_ALL, Device.DeviceID,
113        "OpenMP Host-Device pointer mappings after block at %s:%d:%d:\n",
114        Kernel.getFilename(), Kernel.getLine(), Kernel.getColumn());
115   INFO(OMP_INFOTYPE_ALL, Device.DeviceID, "%-18s %-18s %s %s %s\n", "Host Ptr",
116        "Target Ptr", "Size (B)", "RefCount", "Declaration");
117   Device.DataMapMtx.lock();
118   for (const auto &HostTargetMap : Device.HostDataToTargetMap) {
119     SourceInfo Info(HostTargetMap.HstPtrName);
120     INFO(OMP_INFOTYPE_ALL, Device.DeviceID,
121          DPxMOD " " DPxMOD " %-8" PRIuPTR " %-8s %s at %s:%d:%d\n",
122          DPxPTR(HostTargetMap.HstPtrBegin), DPxPTR(HostTargetMap.TgtPtrBegin),
123          HostTargetMap.HstPtrEnd - HostTargetMap.HstPtrBegin,
124          HostTargetMap.refCountToStr().c_str(), Info.getName(),
125          Info.getFilename(), Info.getLine(), Info.getColumn());
126   }
127   Device.DataMapMtx.unlock();
128 }
129 
130 ////////////////////////////////////////////////////////////////////////////////
131 /// Print out the names and properties of the arguments to each kernel
132 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)133 printKernelArguments(const ident_t *Loc, const int64_t DeviceId,
134                      const int32_t ArgNum, const int64_t *ArgSizes,
135                      const int64_t *ArgTypes, const map_var_info_t *ArgNames,
136                      const char *RegionType) {
137   SourceInfo info(Loc);
138   INFO(OMP_INFOTYPE_ALL, DeviceId, "%s at %s:%d:%d with %d arguments:\n",
139        RegionType, info.getFilename(), info.getLine(), info.getColumn(),
140        ArgNum);
141 
142   for (int32_t i = 0; i < ArgNum; ++i) {
143     const map_var_info_t varName = (ArgNames) ? ArgNames[i] : nullptr;
144     const char *type = nullptr;
145     const char *implicit =
146         (ArgTypes[i] & OMP_TGT_MAPTYPE_IMPLICIT) ? "(implicit)" : "";
147     if (ArgTypes[i] & OMP_TGT_MAPTYPE_TO && ArgTypes[i] & OMP_TGT_MAPTYPE_FROM)
148       type = "tofrom";
149     else if (ArgTypes[i] & OMP_TGT_MAPTYPE_TO)
150       type = "to";
151     else if (ArgTypes[i] & OMP_TGT_MAPTYPE_FROM)
152       type = "from";
153     else if (ArgTypes[i] & OMP_TGT_MAPTYPE_PRIVATE)
154       type = "private";
155     else if (ArgTypes[i] & OMP_TGT_MAPTYPE_LITERAL)
156       type = "firstprivate";
157     else if (ArgSizes[i] != 0)
158       type = "alloc";
159     else
160       type = "use_address";
161 
162     INFO(OMP_INFOTYPE_ALL, DeviceId, "%s(%s)[%" PRId64 "] %s\n", type,
163          getNameFromMapping(varName).c_str(), ArgSizes[i], implicit);
164   }
165 }
166 
167 #ifdef OMPTARGET_PROFILE_ENABLED
168 #include "llvm/Support/TimeProfiler.h"
169 #define TIMESCOPE() llvm::TimeTraceScope TimeScope(__FUNCTION__)
170 #define TIMESCOPE_WITH_IDENT(IDENT)                                            \
171   SourceInfo SI(IDENT);                                                        \
172   llvm::TimeTraceScope TimeScope(__FUNCTION__, SI.getProfileLocation())
173 #define TIMESCOPE_WITH_NAME_AND_IDENT(NAME, IDENT)                             \
174   SourceInfo SI(IDENT);                                                        \
175   llvm::TimeTraceScope TimeScope(NAME, SI.getProfileLocation())
176 #else
177 #define TIMESCOPE()
178 #define TIMESCOPE_WITH_IDENT(IDENT)
179 #define TIMESCOPE_WITH_NAME_AND_IDENT(NAME, IDENT)
180 #endif
181 
182 #endif
183