1 //===-------- interface.cpp - Target independent OpenMP target RTL --------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.txt for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Implementation of the interface to be used by Clang during the codegen of a 11 // target region. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include <omptarget.h> 16 17 #include "device.h" 18 #include "private.h" 19 #include "rtl.h" 20 21 #include <cassert> 22 #include <cstdlib> 23 24 //////////////////////////////////////////////////////////////////////////////// 25 /// adds a target shared library to the target execution image 26 EXTERN void __tgt_register_lib(__tgt_bin_desc *desc) { 27 RTLs.RegisterLib(desc); 28 } 29 30 //////////////////////////////////////////////////////////////////////////////// 31 /// unloads a target shared library 32 EXTERN void __tgt_unregister_lib(__tgt_bin_desc *desc) { 33 RTLs.UnregisterLib(desc); 34 } 35 36 /// creates host-to-target data mapping, stores it in the 37 /// libomptarget.so internal structure (an entry in a stack of data maps) 38 /// and passes the data to the device. 39 EXTERN void __tgt_target_data_begin(int64_t device_id, int32_t arg_num, 40 void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types) { 41 DP("Entering data begin region for device %" PRId64 " with %d mappings\n", 42 device_id, arg_num); 43 44 // No devices available? 45 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 46 device_id = omp_get_default_device(); 47 DP("Use default device id %" PRId64 "\n", device_id); 48 } 49 50 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 51 DP("Failed to get device %" PRId64 " ready\n", device_id); 52 return; 53 } 54 55 DeviceTy& Device = Devices[device_id]; 56 57 #ifdef OMPTARGET_DEBUG 58 for (int i=0; i<arg_num; ++i) { 59 DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64 60 ", Type=0x%" PRIx64 "\n", i, DPxPTR(args_base[i]), DPxPTR(args[i]), 61 arg_sizes[i], arg_types[i]); 62 } 63 #endif 64 65 target_data_begin(Device, arg_num, args_base, args, arg_sizes, arg_types); 66 } 67 68 EXTERN void __tgt_target_data_begin_nowait(int64_t device_id, int32_t arg_num, 69 void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types, 70 int32_t depNum, void *depList, int32_t noAliasDepNum, 71 void *noAliasDepList) { 72 if (depNum + noAliasDepNum > 0) 73 __kmpc_omp_taskwait(NULL, 0); 74 75 __tgt_target_data_begin(device_id, arg_num, args_base, args, arg_sizes, 76 arg_types); 77 } 78 79 /// passes data from the target, releases target memory and destroys 80 /// the host-target mapping (top entry from the stack of data maps) 81 /// created by the last __tgt_target_data_begin. 82 EXTERN void __tgt_target_data_end(int64_t device_id, int32_t arg_num, 83 void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types) { 84 DP("Entering data end region with %d mappings\n", arg_num); 85 86 // No devices available? 87 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 88 device_id = omp_get_default_device(); 89 } 90 91 RTLsMtx.lock(); 92 size_t Devices_size = Devices.size(); 93 RTLsMtx.unlock(); 94 if (Devices_size <= (size_t)device_id) { 95 DP("Device ID %" PRId64 " does not have a matching RTL.\n", device_id); 96 return; 97 } 98 99 DeviceTy &Device = Devices[device_id]; 100 if (!Device.IsInit) { 101 DP("Uninit device: ignore"); 102 return; 103 } 104 105 #ifdef OMPTARGET_DEBUG 106 for (int i=0; i<arg_num; ++i) { 107 DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64 108 ", Type=0x%" PRIx64 "\n", i, DPxPTR(args_base[i]), DPxPTR(args[i]), 109 arg_sizes[i], arg_types[i]); 110 } 111 #endif 112 113 target_data_end(Device, arg_num, args_base, args, arg_sizes, arg_types); 114 } 115 116 EXTERN void __tgt_target_data_end_nowait(int64_t device_id, int32_t arg_num, 117 void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types, 118 int32_t depNum, void *depList, int32_t noAliasDepNum, 119 void *noAliasDepList) { 120 if (depNum + noAliasDepNum > 0) 121 __kmpc_omp_taskwait(NULL, 0); 122 123 __tgt_target_data_end(device_id, arg_num, args_base, args, arg_sizes, 124 arg_types); 125 } 126 127 EXTERN void __tgt_target_data_update(int64_t device_id, int32_t arg_num, 128 void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types) { 129 DP("Entering data update with %d mappings\n", arg_num); 130 131 // No devices available? 132 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 133 device_id = omp_get_default_device(); 134 } 135 136 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 137 DP("Failed to get device %" PRId64 " ready\n", device_id); 138 return; 139 } 140 141 DeviceTy& Device = Devices[device_id]; 142 target_data_update(Device, arg_num, args_base, args, arg_sizes, arg_types); 143 } 144 145 EXTERN void __tgt_target_data_update_nowait( 146 int64_t device_id, int32_t arg_num, void **args_base, void **args, 147 int64_t *arg_sizes, int64_t *arg_types, int32_t depNum, void *depList, 148 int32_t noAliasDepNum, void *noAliasDepList) { 149 if (depNum + noAliasDepNum > 0) 150 __kmpc_omp_taskwait(NULL, 0); 151 152 __tgt_target_data_update(device_id, arg_num, args_base, args, arg_sizes, 153 arg_types); 154 } 155 156 EXTERN int __tgt_target(int64_t device_id, void *host_ptr, int32_t arg_num, 157 void **args_base, void **args, int64_t *arg_sizes, int64_t *arg_types) { 158 DP("Entering target region with entry point " DPxMOD " and device Id %" 159 PRId64 "\n", DPxPTR(host_ptr), device_id); 160 161 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 162 device_id = omp_get_default_device(); 163 } 164 165 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 166 DP("Failed to get device %" PRId64 " ready\n", device_id); 167 return OFFLOAD_FAIL; 168 } 169 170 #ifdef OMPTARGET_DEBUG 171 for (int i=0; i<arg_num; ++i) { 172 DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64 173 ", Type=0x%" PRIx64 "\n", i, DPxPTR(args_base[i]), DPxPTR(args[i]), 174 arg_sizes[i], arg_types[i]); 175 } 176 #endif 177 178 int rc = target(device_id, host_ptr, arg_num, args_base, args, arg_sizes, 179 arg_types, 0, 0, false /*team*/); 180 181 return rc; 182 } 183 184 EXTERN int __tgt_target_nowait(int64_t device_id, void *host_ptr, 185 int32_t arg_num, void **args_base, void **args, int64_t *arg_sizes, 186 int64_t *arg_types, int32_t depNum, void *depList, int32_t noAliasDepNum, 187 void *noAliasDepList) { 188 if (depNum + noAliasDepNum > 0) 189 __kmpc_omp_taskwait(NULL, 0); 190 191 return __tgt_target(device_id, host_ptr, arg_num, args_base, args, arg_sizes, 192 arg_types); 193 } 194 195 EXTERN int __tgt_target_teams(int64_t device_id, void *host_ptr, 196 int32_t arg_num, void **args_base, void **args, int64_t *arg_sizes, 197 int64_t *arg_types, int32_t team_num, int32_t thread_limit) { 198 DP("Entering target region with entry point " DPxMOD " and device Id %" 199 PRId64 "\n", DPxPTR(host_ptr), device_id); 200 201 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 202 device_id = omp_get_default_device(); 203 } 204 205 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 206 DP("Failed to get device %" PRId64 " ready\n", device_id); 207 return OFFLOAD_FAIL; 208 } 209 210 #ifdef OMPTARGET_DEBUG 211 for (int i=0; i<arg_num; ++i) { 212 DP("Entry %2d: Base=" DPxMOD ", Begin=" DPxMOD ", Size=%" PRId64 213 ", Type=0x%" PRIx64 "\n", i, DPxPTR(args_base[i]), DPxPTR(args[i]), 214 arg_sizes[i], arg_types[i]); 215 } 216 #endif 217 218 int rc = target(device_id, host_ptr, arg_num, args_base, args, arg_sizes, 219 arg_types, team_num, thread_limit, true /*team*/); 220 221 return rc; 222 } 223 224 EXTERN int __tgt_target_teams_nowait(int64_t device_id, void *host_ptr, 225 int32_t arg_num, void **args_base, void **args, int64_t *arg_sizes, 226 int64_t *arg_types, int32_t team_num, int32_t thread_limit, int32_t depNum, 227 void *depList, int32_t noAliasDepNum, void *noAliasDepList) { 228 if (depNum + noAliasDepNum > 0) 229 __kmpc_omp_taskwait(NULL, 0); 230 231 return __tgt_target_teams(device_id, host_ptr, arg_num, args_base, args, 232 arg_sizes, arg_types, team_num, thread_limit); 233 } 234 235 236 // The trip count mechanism will be revised - this scheme is not thread-safe. 237 EXTERN void __kmpc_push_target_tripcount(int64_t device_id, 238 uint64_t loop_tripcount) { 239 if (device_id == OFFLOAD_DEVICE_DEFAULT) { 240 device_id = omp_get_default_device(); 241 } 242 243 if (CheckDeviceAndCtors(device_id) != OFFLOAD_SUCCESS) { 244 DP("Failed to get device %" PRId64 " ready\n", device_id); 245 return; 246 } 247 248 DP("__kmpc_push_target_tripcount(%" PRId64 ", %" PRIu64 ")\n", device_id, 249 loop_tripcount); 250 Devices[device_id].loopTripCnt = loop_tripcount; 251 } 252