470 lines · cpp
1/*2 * kmp_stub.cpp -- stub versions of user-callable OpenMP RT functions.3 */4 5//===----------------------------------------------------------------------===//6//7// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.8// See https://llvm.org/LICENSE.txt for license information.9// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception10//11//===----------------------------------------------------------------------===//12 13#include <errno.h>14#include <limits.h>15#include <stdlib.h>16 17#define __KMP_IMP18#include "omp.h" // omp_* declarations, must be included before "kmp.h"19#include "kmp.h" // KMP_DEFAULT_STKSIZE20#include "kmp_stub.h"21 22#if KMP_OS_WINDOWS23#include <windows.h>24#else25#include <sys/time.h>26#endif27 28// Moved from omp.h29#define omp_set_max_active_levels ompc_set_max_active_levels30#define omp_set_schedule ompc_set_schedule31#define omp_get_ancestor_thread_num ompc_get_ancestor_thread_num32#define omp_get_team_size ompc_get_team_size33 34#define omp_set_num_threads ompc_set_num_threads35#define omp_set_dynamic ompc_set_dynamic36#define omp_set_nested ompc_set_nested37#define omp_set_affinity_format ompc_set_affinity_format38#define omp_get_affinity_format ompc_get_affinity_format39#define omp_display_affinity ompc_display_affinity40#define omp_capture_affinity ompc_capture_affinity41#define kmp_set_stacksize kmpc_set_stacksize42#define kmp_set_stacksize_s kmpc_set_stacksize_s43#define kmp_set_blocktime kmpc_set_blocktime44#define kmp_set_library kmpc_set_library45#define kmp_set_defaults kmpc_set_defaults46#define kmp_set_disp_num_buffers kmpc_set_disp_num_buffers47#define kmp_malloc kmpc_malloc48#define kmp_aligned_malloc kmpc_aligned_malloc49#define kmp_calloc kmpc_calloc50#define kmp_realloc kmpc_realloc51#define kmp_free kmpc_free52 53#if KMP_OS_WINDOWS54static double frequency = 0.0;55#endif56 57// Helper functions.58static size_t __kmps_init() {59 static int initialized = 0;60 static size_t dummy = 0;61 if (!initialized) {62 // TODO: Analyze KMP_VERSION environment variable, print63 // __kmp_version_copyright and __kmp_version_build_time.64 // WARNING: Do not use "fprintf(stderr, ...)" because it will cause65 // unresolved "__iob" symbol (see C70080). We need to extract __kmp_printf()66 // stuff from kmp_runtime.cpp and use it.67 68 // Trick with dummy variable forces linker to keep __kmp_version_copyright69 // and __kmp_version_build_time strings in executable file (in case of70 // static linkage). When KMP_VERSION analysis is implemented, dummy71 // variable should be deleted, function should return void.72 dummy = __kmp_version_copyright - __kmp_version_build_time;73 74#if KMP_OS_WINDOWS75 LARGE_INTEGER freq;76 BOOL status = QueryPerformanceFrequency(&freq);77 if (status) {78 frequency = double(freq.QuadPart);79 }80#endif81 82 initialized = 1;83 }84 return dummy;85} // __kmps_init86 87#define i __kmps_init();88 89/* set API functions */90void omp_set_num_threads(omp_int_t num_threads) { i; }91void omp_set_dynamic(omp_int_t dynamic) {92 i;93 __kmps_set_dynamic(dynamic);94}95void omp_set_nested(omp_int_t nested) {96 i;97 __kmps_set_nested(nested);98}99void omp_set_max_active_levels(omp_int_t max_active_levels) { i; }100void omp_set_schedule(omp_sched_t kind, omp_int_t modifier) {101 i;102 __kmps_set_schedule((kmp_sched_t)kind, modifier);103}104int omp_get_ancestor_thread_num(omp_int_t level) {105 i;106 return (level) ? (-1) : (0);107}108int omp_get_team_size(omp_int_t level) {109 i;110 return (level) ? (-1) : (1);111}112int kmpc_set_affinity_mask_proc(int proc, void **mask) {113 i;114 return -1;115}116int kmpc_unset_affinity_mask_proc(int proc, void **mask) {117 i;118 return -1;119}120int kmpc_get_affinity_mask_proc(int proc, void **mask) {121 i;122 return -1;123}124 125/* kmp API functions */126void kmp_set_stacksize(omp_int_t arg) {127 i;128 __kmps_set_stacksize((size_t)arg);129}130void kmp_set_stacksize_s(size_t arg) {131 i;132 __kmps_set_stacksize(arg);133}134void kmp_set_blocktime(omp_int_t arg) {135 i;136 __kmps_set_blocktime(arg);137}138void kmp_set_library(omp_int_t arg) {139 i;140 __kmps_set_library(arg);141}142void kmp_set_defaults(char const *str) { i; }143void kmp_set_disp_num_buffers(omp_int_t arg) { i; }144 145/* KMP memory management functions. */146void *kmp_malloc(size_t size) {147 i;148 void *res;149#if KMP_OS_WINDOWS150 // If successful returns a pointer to the memory block, otherwise returns151 // NULL.152 // Sets errno to ENOMEM or EINVAL if memory allocation failed or parameter153 // validation failed.154 res = _aligned_malloc(size, 1);155#else156 res = malloc(size);157#endif158 return res;159}160void *kmp_aligned_malloc(size_t sz, size_t a) {161 i;162 void *res;163#if KMP_OS_WINDOWS164 res = _aligned_malloc(sz, a);165#else166 int err;167 if ((err = posix_memalign(&res, a, sz))) {168 errno = err; // can be EINVAL or ENOMEM169 res = NULL;170 }171#endif172 return res;173}174void *kmp_calloc(size_t nelem, size_t elsize) {175 i;176 void *res;177#if KMP_OS_WINDOWS178 res = _aligned_recalloc(NULL, nelem, elsize, 1);179#else180 res = calloc(nelem, elsize);181#endif182 return res;183}184void *kmp_realloc(void *ptr, size_t size) {185 i;186 void *res;187#if KMP_OS_WINDOWS188 res = _aligned_realloc(ptr, size, 1);189#else190 res = realloc(ptr, size);191#endif192 return res;193}194void kmp_free(void *ptr) {195 i;196#if KMP_OS_WINDOWS197 _aligned_free(ptr);198#else199 free(ptr);200#endif201}202 203static int __kmps_blocktime = INT_MAX;204 205void __kmps_set_blocktime(int arg) {206 i;207 __kmps_blocktime = arg;208} // __kmps_set_blocktime209 210int __kmps_get_blocktime(void) {211 i;212 return __kmps_blocktime;213} // __kmps_get_blocktime214 215static int __kmps_dynamic = 0;216 217void __kmps_set_dynamic(int arg) {218 i;219 __kmps_dynamic = arg;220} // __kmps_set_dynamic221 222int __kmps_get_dynamic(void) {223 i;224 return __kmps_dynamic;225} // __kmps_get_dynamic226 227static int __kmps_library = 1000;228 229void __kmps_set_library(int arg) {230 i;231 __kmps_library = arg;232} // __kmps_set_library233 234int __kmps_get_library(void) {235 i;236 return __kmps_library;237} // __kmps_get_library238 239static int __kmps_nested = 0;240 241void __kmps_set_nested(int arg) {242 i;243 __kmps_nested = arg;244} // __kmps_set_nested245 246int __kmps_get_nested(void) {247 i;248 return __kmps_nested;249} // __kmps_get_nested250 251static size_t __kmps_stacksize = KMP_DEFAULT_STKSIZE;252 253void __kmps_set_stacksize(size_t arg) {254 i;255 __kmps_stacksize = arg;256} // __kmps_set_stacksize257 258size_t __kmps_get_stacksize(void) {259 i;260 return __kmps_stacksize;261} // __kmps_get_stacksize262 263static kmp_sched_t __kmps_sched_kind = kmp_sched_default;264static int __kmps_sched_modifier = 0;265 266void __kmps_set_schedule(kmp_sched_t kind, int modifier) {267 i;268 __kmps_sched_kind = kind;269 __kmps_sched_modifier = modifier;270} // __kmps_set_schedule271 272void __kmps_get_schedule(kmp_sched_t *kind, int *modifier) {273 i;274 *kind = __kmps_sched_kind;275 *modifier = __kmps_sched_modifier;276} // __kmps_get_schedule277 278kmp_proc_bind_t __kmps_get_proc_bind(void) {279 i;280 return proc_bind_false;281} // __kmps_get_proc_bind282 283double __kmps_get_wtime(void) {284 // Elapsed wall clock time (in second) from "sometime in the past".285 double wtime = 0.0;286 i;287#if KMP_OS_WINDOWS288 if (frequency > 0.0) {289 LARGE_INTEGER now;290 BOOL status = QueryPerformanceCounter(&now);291 if (status) {292 wtime = double(now.QuadPart) / frequency;293 }294 }295#else296 // gettimeofday() returns seconds and microseconds since the Epoch.297 struct timeval tval;298 int rc;299 rc = gettimeofday(&tval, NULL);300 if (rc == 0) {301 wtime = (double)(tval.tv_sec) + 1.0E-06 * (double)(tval.tv_usec);302 } else {303 // TODO: Assert or abort here.304 }305#endif306 return wtime;307} // __kmps_get_wtime308 309double __kmps_get_wtick(void) {310 // Number of seconds between successive clock ticks.311 double wtick = 0.0;312 i;313#if KMP_OS_WINDOWS314 {315 DWORD increment;316 DWORD adjustment;317 BOOL disabled;318 BOOL rc;319 rc = GetSystemTimeAdjustment(&adjustment, &increment, &disabled);320 if (rc) {321 wtick = 1.0E-07 * (double)(disabled ? increment : adjustment);322 } else {323 // TODO: Assert or abort here.324 wtick = 1.0E-03;325 }326 }327#else328 // TODO: gettimeofday() returns in microseconds, but what the precision?329 wtick = 1.0E-06;330#endif331 return wtick;332} // __kmps_get_wtick333 334/* OpenMP 5.0 Memory Management */335#if KMP_OS_WINDOWS336omp_allocator_handle_t const omp_null_allocator = 0;337omp_allocator_handle_t const omp_default_mem_alloc =338 (omp_allocator_handle_t const)1;339omp_allocator_handle_t const omp_large_cap_mem_alloc =340 (omp_allocator_handle_t const)2;341omp_allocator_handle_t const omp_const_mem_alloc =342 (omp_allocator_handle_t const)3;343omp_allocator_handle_t const omp_high_bw_mem_alloc =344 (omp_allocator_handle_t const)4;345omp_allocator_handle_t const omp_low_lat_mem_alloc =346 (omp_allocator_handle_t const)5;347omp_allocator_handle_t const omp_cgroup_mem_alloc =348 (omp_allocator_handle_t const)6;349omp_allocator_handle_t const omp_pteam_mem_alloc =350 (omp_allocator_handle_t const)7;351omp_allocator_handle_t const omp_thread_mem_alloc =352 (omp_allocator_handle_t const)8;353omp_allocator_handle_t const llvm_omp_target_host_mem_alloc =354 (omp_allocator_handle_t const)100;355omp_allocator_handle_t const llvm_omp_target_shared_mem_alloc =356 (omp_allocator_handle_t const)101;357omp_allocator_handle_t const llvm_omp_target_device_mem_alloc =358 (omp_allocator_handle_t const)102;359 360omp_memspace_handle_t const omp_null_mem_space = (omp_memspace_handle_t const)0;361omp_memspace_handle_t const omp_default_mem_space =362 (omp_memspace_handle_t const)99;363omp_memspace_handle_t const omp_large_cap_mem_space =364 (omp_memspace_handle_t const)1;365omp_memspace_handle_t const omp_const_mem_space =366 (omp_memspace_handle_t const)2;367omp_memspace_handle_t const omp_high_bw_mem_space =368 (omp_memspace_handle_t const)3;369omp_memspace_handle_t const omp_low_lat_mem_space =370 (omp_memspace_handle_t const)4;371omp_memspace_handle_t const llvm_omp_target_host_mem_space =372 (omp_memspace_handle_t const)100;373omp_memspace_handle_t const llvm_omp_target_shared_mem_space =374 (omp_memspace_handle_t const)101;375omp_memspace_handle_t const llvm_omp_target_device_mem_space =376 (omp_memspace_handle_t const)102;377#endif /* KMP_OS_WINDOWS */378 379void *omp_alloc(size_t size, omp_allocator_handle_t allocator) {380 i;381 void *res;382#if KMP_OS_WINDOWS383 // Returns a pointer to the memory block, or NULL if failed.384 // Sets errno to ENOMEM or EINVAL if memory allocation failed or parameter385 // validation failed.386 res = _aligned_malloc(size, 1);387#else388 res = malloc(size);389#endif390 return res;391}392 393void *omp_aligned_alloc(size_t a, size_t size, omp_allocator_handle_t al) {394 i;395 void *res;396#if KMP_OS_WINDOWS397 res = _aligned_malloc(size, a);398#else399 int err;400 if ((err = posix_memalign(&res, a, size))) {401 errno = err; // can be EINVAL or ENOMEM402 res = NULL;403 }404#endif405 return res;406}407 408void *omp_calloc(size_t nmemb, size_t size, omp_allocator_handle_t al) {409 i;410 void *res;411#if KMP_OS_WINDOWS412 res = _aligned_recalloc(NULL, nmemb, size, 1);413#else414 res = calloc(nmemb, size);415#endif416 return res;417}418 419void *omp_aligned_calloc(size_t a, size_t nmemb, size_t size,420 omp_allocator_handle_t al) {421 i;422 void *res;423#if KMP_OS_WINDOWS424 res = _aligned_recalloc(NULL, nmemb, size, a);425#else426 int err;427 if ((err = posix_memalign(&res, a, nmemb * size))) {428 errno = err; // can be EINVAL or ENOMEM429 res = NULL;430 }431 memset(res, 0x00, size);432#endif433 return res;434}435 436void *omp_realloc(void *ptr, size_t size, omp_allocator_handle_t al,437 omp_allocator_handle_t free_al) {438 i;439 void *res;440#if KMP_OS_WINDOWS441 res = _aligned_realloc(ptr, size, 1);442#else443 res = realloc(ptr, size);444#endif445 return res;446}447 448void omp_free(void *ptr, omp_allocator_handle_t allocator) {449 i;450#if KMP_OS_WINDOWS451 _aligned_free(ptr);452#else453 free(ptr);454#endif455}456 457/* OpenMP 5.0 Affinity Format */458void omp_set_affinity_format(char const *format) { i; }459size_t omp_get_affinity_format(char *buffer, size_t size) {460 i;461 return 0;462}463void omp_display_affinity(char const *format) { i; }464size_t omp_capture_affinity(char *buffer, size_t buf_size, char const *format) {465 i;466 return 0;467}468 469// end of file //470