1 //===-------- omptarget.h - Target independent OpenMP target RTL -- C++ -*-===// 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 // Interface to be used by Clang during the codegen of a 10 // target region. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef _OMPTARGET_H_ 15 #define _OMPTARGET_H_ 16 17 #include <stdint.h> 18 #include <stddef.h> 19 20 #define OFFLOAD_SUCCESS (0) 21 #define OFFLOAD_FAIL (~0) 22 23 #define OFFLOAD_DEVICE_DEFAULT -1 24 #define HOST_DEVICE -10 25 26 /// Data attributes for each data reference used in an OpenMP target region. 27 enum tgt_map_type { 28 // No flags 29 OMP_TGT_MAPTYPE_NONE = 0x000, 30 // copy data from host to device 31 OMP_TGT_MAPTYPE_TO = 0x001, 32 // copy data from device to host 33 OMP_TGT_MAPTYPE_FROM = 0x002, 34 // copy regardless of the reference count 35 OMP_TGT_MAPTYPE_ALWAYS = 0x004, 36 // force unmapping of data 37 OMP_TGT_MAPTYPE_DELETE = 0x008, 38 // map the pointer as well as the pointee 39 OMP_TGT_MAPTYPE_PTR_AND_OBJ = 0x010, 40 // pass device base address to kernel 41 OMP_TGT_MAPTYPE_TARGET_PARAM = 0x020, 42 // return base device address of mapped data 43 OMP_TGT_MAPTYPE_RETURN_PARAM = 0x040, 44 // private variable - not mapped 45 OMP_TGT_MAPTYPE_PRIVATE = 0x080, 46 // copy by value - not mapped 47 OMP_TGT_MAPTYPE_LITERAL = 0x100, 48 // mapping is implicit 49 OMP_TGT_MAPTYPE_IMPLICIT = 0x200, 50 // copy data to device 51 OMP_TGT_MAPTYPE_CLOSE = 0x400, 52 // member of struct, member given by [16 MSBs] - 1 53 OMP_TGT_MAPTYPE_MEMBER_OF = 0xffff000000000000 54 }; 55 56 enum OpenMPOffloadingDeclareTargetFlags { 57 /// Mark the entry as having a 'link' attribute. 58 OMP_DECLARE_TARGET_LINK = 0x01, 59 /// Mark the entry as being a global constructor. 60 OMP_DECLARE_TARGET_CTOR = 0x02, 61 /// Mark the entry as being a global destructor. 62 OMP_DECLARE_TARGET_DTOR = 0x04 63 }; 64 65 enum OpenMPOffloadingRequiresDirFlags { 66 /// flag undefined. 67 OMP_REQ_UNDEFINED = 0x000, 68 /// no requires directive present. 69 OMP_REQ_NONE = 0x001, 70 /// reverse_offload clause. 71 OMP_REQ_REVERSE_OFFLOAD = 0x002, 72 /// unified_address clause. 73 OMP_REQ_UNIFIED_ADDRESS = 0x004, 74 /// unified_shared_memory clause. 75 OMP_REQ_UNIFIED_SHARED_MEMORY = 0x008, 76 /// dynamic_allocators clause. 77 OMP_REQ_DYNAMIC_ALLOCATORS = 0x010 78 }; 79 80 /// This struct is a record of an entry point or global. For a function 81 /// entry point the size is expected to be zero 82 struct __tgt_offload_entry { 83 void *addr; // Pointer to the offload entry info (function or global) 84 char *name; // Name of the function or global 85 size_t size; // Size of the entry info (0 if it is a function) 86 int32_t flags; // Flags associated with the entry, e.g. 'link'. 87 int32_t reserved; // Reserved, to be used by the runtime library. 88 }; 89 90 /// This struct is a record of the device image information 91 struct __tgt_device_image { 92 void *ImageStart; // Pointer to the target code start 93 void *ImageEnd; // Pointer to the target code end 94 __tgt_offload_entry *EntriesBegin; // Begin of table with all target entries 95 __tgt_offload_entry *EntriesEnd; // End of table (non inclusive) 96 }; 97 98 /// This struct is a record of all the host code that may be offloaded to a 99 /// target. 100 struct __tgt_bin_desc { 101 int32_t NumDeviceImages; // Number of device types supported 102 __tgt_device_image *DeviceImages; // Array of device images (1 per dev. type) 103 __tgt_offload_entry *HostEntriesBegin; // Begin of table with all host entries 104 __tgt_offload_entry *HostEntriesEnd; // End of table (non inclusive) 105 }; 106 107 /// This struct contains the offload entries identified by the target runtime 108 struct __tgt_target_table { 109 __tgt_offload_entry *EntriesBegin; // Begin of the table with all the entries 110 __tgt_offload_entry 111 *EntriesEnd; // End of the table with all the entries (non inclusive) 112 }; 113 114 #ifdef __cplusplus 115 extern "C" { 116 #endif 117 118 int omp_get_num_devices(void); 119 int omp_get_initial_device(void); 120 void *omp_target_alloc(size_t size, int device_num); 121 void omp_target_free(void *device_ptr, int device_num); 122 int omp_target_is_present(void *ptr, int device_num); 123 int omp_target_memcpy(void *dst, void *src, size_t length, size_t dst_offset, 124 size_t src_offset, int dst_device, int src_device); 125 int omp_target_memcpy_rect(void *dst, void *src, size_t element_size, 126 int num_dims, const size_t *volume, const size_t *dst_offsets, 127 const size_t *src_offsets, const size_t *dst_dimensions, 128 const size_t *src_dimensions, int dst_device, int src_device); 129 int omp_target_associate_ptr(void *host_ptr, void *device_ptr, size_t size, 130 size_t device_offset, int device_num); 131 int omp_target_disassociate_ptr(void *host_ptr, int device_num); 132 133 /// add the clauses of the requires directives in a given file 134 void __tgt_register_requires(int64_t flags); 135 136 /// adds a target shared library to the target execution image 137 void __tgt_register_lib(__tgt_bin_desc *desc); 138 139 /// removes a target shared library from the target execution image 140 void __tgt_unregister_lib(__tgt_bin_desc *desc); 141 142 // creates the host to target data mapping, stores it in the 143 // libomptarget.so internal structure (an entry in a stack of data maps) and 144 // passes the data to the device; 145 void __tgt_target_data_begin(int64_t device_id, int32_t arg_num, 146 void **args_base, void **args, int64_t *arg_sizes, 147 int64_t *arg_types); 148 void __tgt_target_data_begin_nowait(int64_t device_id, int32_t arg_num, 149 void **args_base, void **args, 150 int64_t *arg_sizes, int64_t *arg_types, 151 int32_t depNum, void *depList, 152 int32_t noAliasDepNum, 153 void *noAliasDepList); 154 155 // passes data from the target, release target memory and destroys the 156 // host-target mapping (top entry from the stack of data maps) created by 157 // the last __tgt_target_data_begin 158 void __tgt_target_data_end(int64_t device_id, int32_t arg_num, void **args_base, 159 void **args, int64_t *arg_sizes, int64_t *arg_types); 160 void __tgt_target_data_end_nowait(int64_t device_id, int32_t arg_num, 161 void **args_base, void **args, 162 int64_t *arg_sizes, int64_t *arg_types, 163 int32_t depNum, void *depList, 164 int32_t noAliasDepNum, void *noAliasDepList); 165 166 /// passes data to/from the target 167 void __tgt_target_data_update(int64_t device_id, int32_t arg_num, 168 void **args_base, void **args, int64_t *arg_sizes, 169 int64_t *arg_types); 170 void __tgt_target_data_update_nowait(int64_t device_id, int32_t arg_num, 171 void **args_base, void **args, 172 int64_t *arg_sizes, int64_t *arg_types, 173 int32_t depNum, void *depList, 174 int32_t noAliasDepNum, 175 void *noAliasDepList); 176 177 // Performs the same actions as data_begin in case arg_num is non-zero 178 // and initiates run of offloaded region on target platform; if arg_num 179 // is non-zero after the region execution is done it also performs the 180 // same action as data_end above. The following types are used; this 181 // function returns 0 if it was able to transfer the execution to a 182 // target and an int different from zero otherwise. 183 int __tgt_target(int64_t device_id, void *host_ptr, int32_t arg_num, 184 void **args_base, void **args, int64_t *arg_sizes, 185 int64_t *arg_types); 186 int __tgt_target_nowait(int64_t device_id, void *host_ptr, int32_t arg_num, 187 void **args_base, void **args, int64_t *arg_sizes, 188 int64_t *arg_types, int32_t depNum, void *depList, 189 int32_t noAliasDepNum, void *noAliasDepList); 190 191 int __tgt_target_teams(int64_t device_id, void *host_ptr, int32_t arg_num, 192 void **args_base, void **args, int64_t *arg_sizes, 193 int64_t *arg_types, int32_t num_teams, 194 int32_t thread_limit); 195 int __tgt_target_teams_nowait(int64_t device_id, void *host_ptr, 196 int32_t arg_num, void **args_base, void **args, 197 int64_t *arg_sizes, int64_t *arg_types, 198 int32_t num_teams, int32_t thread_limit, 199 int32_t depNum, void *depList, 200 int32_t noAliasDepNum, void *noAliasDepList); 201 void __kmpc_push_target_tripcount(int64_t device_id, uint64_t loop_tripcount); 202 203 #ifdef __cplusplus 204 } 205 #endif 206 207 #ifdef OMPTARGET_DEBUG 208 #include <stdio.h> 209 #define DEBUGP(prefix, ...) \ 210 { \ 211 fprintf(stderr, "%s --> ", prefix); \ 212 fprintf(stderr, __VA_ARGS__); \ 213 } 214 215 #ifndef __STDC_FORMAT_MACROS 216 #define __STDC_FORMAT_MACROS 217 #endif 218 219 #include <inttypes.h> 220 #define DPxMOD "0x%0*" PRIxPTR 221 #define DPxPTR(ptr) ((int)(2*sizeof(uintptr_t))), ((uintptr_t) (ptr)) 222 223 /* 224 * To printf a pointer in hex with a fixed width of 16 digits and a leading 0x, 225 * use printf("ptr=" DPxMOD "...\n", DPxPTR(ptr)); 226 * 227 * DPxMOD expands to: 228 * "0x%0*" PRIxPTR 229 * where PRIxPTR expands to an appropriate modifier for the type uintptr_t on a 230 * specific platform, e.g. "lu" if uintptr_t is typedef'd as unsigned long: 231 * "0x%0*lu" 232 * 233 * Ultimately, the whole statement expands to: 234 * printf("ptr=0x%0*lu...\n", // the 0* modifier expects an extra argument 235 * // specifying the width of the output 236 * (int)(2*sizeof(uintptr_t)), // the extra argument specifying the width 237 * // 8 digits for 32bit systems 238 * // 16 digits for 64bit 239 * (uintptr_t) ptr); 240 */ 241 #else 242 #define DEBUGP(prefix, ...) \ 243 {} 244 #endif 245 246 #ifdef __cplusplus 247 #define EXTERN extern "C" 248 #else 249 #define EXTERN extern 250 #endif 251 252 #endif // _OMPTARGET_H_ 253