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