Path: blob/main/contrib/llvm-project/openmp/runtime/src/kmp_ftn_entry.h
35258 views
/*1* kmp_ftn_entry.h -- Fortran entry linkage support for OpenMP.2*/34//===----------------------------------------------------------------------===//5//6// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.7// See https://llvm.org/LICENSE.txt for license information.8// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception9//10//===----------------------------------------------------------------------===//1112#ifndef FTN_STDCALL13#error The support file kmp_ftn_entry.h should not be compiled by itself.14#endif1516#ifdef KMP_STUB17#include "kmp_stub.h"18#endif1920#include "kmp_i18n.h"2122// For affinity format functions23#include "kmp_io.h"24#include "kmp_str.h"2526#if OMPT_SUPPORT27#include "ompt-specific.h"28#endif2930#ifdef __cplusplus31extern "C" {32#endif // __cplusplus3334/* For compatibility with the Gnu/MS Open MP codegen, omp_set_num_threads(),35* omp_set_nested(), and omp_set_dynamic() [in lowercase on MS, and w/o36* a trailing underscore on Linux* OS] take call by value integer arguments.37* + omp_set_max_active_levels()38* + omp_set_schedule()39*40* For backward compatibility with 9.1 and previous Intel compiler, these41* entry points take call by reference integer arguments. */42#ifdef KMP_GOMP_COMPAT43#if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_UPPER)44#define PASS_ARGS_BY_VALUE 145#endif46#endif47#if KMP_OS_WINDOWS48#if (KMP_FTN_ENTRIES == KMP_FTN_PLAIN) || (KMP_FTN_ENTRIES == KMP_FTN_APPEND)49#define PASS_ARGS_BY_VALUE 150#endif51#endif5253// This macro helps to reduce code duplication.54#ifdef PASS_ARGS_BY_VALUE55#define KMP_DEREF56#else57#define KMP_DEREF *58#endif5960// For API with specific C vs. Fortran interfaces (ompc_* exists in61// kmp_csupport.cpp), only create GOMP versioned symbols of the API for the62// APPEND Fortran entries in this file. The GOMP versioned symbols of the C API63// will take place where the ompc_* functions are defined.64#if KMP_FTN_ENTRIES == KMP_FTN_APPEND65#define KMP_EXPAND_NAME_IF_APPEND(name) KMP_EXPAND_NAME(name)66#else67#define KMP_EXPAND_NAME_IF_APPEND(name) name68#endif6970void FTN_STDCALL FTN_SET_STACKSIZE(int KMP_DEREF arg) {71#ifdef KMP_STUB72__kmps_set_stacksize(KMP_DEREF arg);73#else74// __kmp_aux_set_stacksize initializes the library if needed75__kmp_aux_set_stacksize((size_t)KMP_DEREF arg);76#endif77}7879void FTN_STDCALL FTN_SET_STACKSIZE_S(size_t KMP_DEREF arg) {80#ifdef KMP_STUB81__kmps_set_stacksize(KMP_DEREF arg);82#else83// __kmp_aux_set_stacksize initializes the library if needed84__kmp_aux_set_stacksize(KMP_DEREF arg);85#endif86}8788int FTN_STDCALL FTN_GET_STACKSIZE(void) {89#ifdef KMP_STUB90return (int)__kmps_get_stacksize();91#else92if (!__kmp_init_serial) {93__kmp_serial_initialize();94}95return (int)__kmp_stksize;96#endif97}9899size_t FTN_STDCALL FTN_GET_STACKSIZE_S(void) {100#ifdef KMP_STUB101return __kmps_get_stacksize();102#else103if (!__kmp_init_serial) {104__kmp_serial_initialize();105}106return __kmp_stksize;107#endif108}109110void FTN_STDCALL FTN_SET_BLOCKTIME(int KMP_DEREF arg) {111#ifdef KMP_STUB112__kmps_set_blocktime(KMP_DEREF arg);113#else114int gtid, tid, bt = (KMP_DEREF arg);115kmp_info_t *thread;116117gtid = __kmp_entry_gtid();118tid = __kmp_tid_from_gtid(gtid);119thread = __kmp_thread_from_gtid(gtid);120121__kmp_aux_convert_blocktime(&bt);122__kmp_aux_set_blocktime(bt, thread, tid);123#endif124}125126// Gets blocktime in units used for KMP_BLOCKTIME, ms otherwise127int FTN_STDCALL FTN_GET_BLOCKTIME(void) {128#ifdef KMP_STUB129return __kmps_get_blocktime();130#else131int gtid, tid;132kmp_team_p *team;133134gtid = __kmp_entry_gtid();135tid = __kmp_tid_from_gtid(gtid);136team = __kmp_threads[gtid]->th.th_team;137138/* These must match the settings used in __kmp_wait_sleep() */139if (__kmp_dflt_blocktime == KMP_MAX_BLOCKTIME) {140KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d%cs\n", gtid,141team->t.t_id, tid, KMP_MAX_BLOCKTIME, __kmp_blocktime_units));142return KMP_MAX_BLOCKTIME;143}144#ifdef KMP_ADJUST_BLOCKTIME145else if (__kmp_zero_bt && !get__bt_set(team, tid)) {146KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d%cs\n", gtid,147team->t.t_id, tid, 0, __kmp_blocktime_units));148return 0;149}150#endif /* KMP_ADJUST_BLOCKTIME */151else {152int bt = get__blocktime(team, tid);153if (__kmp_blocktime_units == 'm')154bt = bt / 1000;155KF_TRACE(10, ("kmp_get_blocktime: T#%d(%d:%d), blocktime=%d%cs\n", gtid,156team->t.t_id, tid, bt, __kmp_blocktime_units));157return bt;158}159#endif160}161162void FTN_STDCALL FTN_SET_LIBRARY_SERIAL(void) {163#ifdef KMP_STUB164__kmps_set_library(library_serial);165#else166// __kmp_user_set_library initializes the library if needed167__kmp_user_set_library(library_serial);168#endif169}170171void FTN_STDCALL FTN_SET_LIBRARY_TURNAROUND(void) {172#ifdef KMP_STUB173__kmps_set_library(library_turnaround);174#else175// __kmp_user_set_library initializes the library if needed176__kmp_user_set_library(library_turnaround);177#endif178}179180void FTN_STDCALL FTN_SET_LIBRARY_THROUGHPUT(void) {181#ifdef KMP_STUB182__kmps_set_library(library_throughput);183#else184// __kmp_user_set_library initializes the library if needed185__kmp_user_set_library(library_throughput);186#endif187}188189void FTN_STDCALL FTN_SET_LIBRARY(int KMP_DEREF arg) {190#ifdef KMP_STUB191__kmps_set_library(KMP_DEREF arg);192#else193enum library_type lib;194lib = (enum library_type)KMP_DEREF arg;195// __kmp_user_set_library initializes the library if needed196__kmp_user_set_library(lib);197#endif198}199200int FTN_STDCALL FTN_GET_LIBRARY(void) {201#ifdef KMP_STUB202return __kmps_get_library();203#else204if (!__kmp_init_serial) {205__kmp_serial_initialize();206}207return ((int)__kmp_library);208#endif209}210211void FTN_STDCALL FTN_SET_DISP_NUM_BUFFERS(int KMP_DEREF arg) {212#ifdef KMP_STUB213; // empty routine214#else215// ignore after initialization because some teams have already216// allocated dispatch buffers217int num_buffers = KMP_DEREF arg;218if (__kmp_init_serial == FALSE && num_buffers >= KMP_MIN_DISP_NUM_BUFF &&219num_buffers <= KMP_MAX_DISP_NUM_BUFF) {220__kmp_dispatch_num_buffers = num_buffers;221}222#endif223}224225int FTN_STDCALL FTN_SET_AFFINITY(void **mask) {226#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED227return -1;228#else229if (!TCR_4(__kmp_init_middle)) {230__kmp_middle_initialize();231}232__kmp_assign_root_init_mask();233return __kmp_aux_set_affinity(mask);234#endif235}236237int FTN_STDCALL FTN_GET_AFFINITY(void **mask) {238#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED239return -1;240#else241if (!TCR_4(__kmp_init_middle)) {242__kmp_middle_initialize();243}244__kmp_assign_root_init_mask();245int gtid = __kmp_get_gtid();246if (__kmp_threads[gtid]->th.th_team->t.t_level == 0 &&247__kmp_affinity.flags.reset) {248__kmp_reset_root_init_mask(gtid);249}250return __kmp_aux_get_affinity(mask);251#endif252}253254int FTN_STDCALL FTN_GET_AFFINITY_MAX_PROC(void) {255#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED256return 0;257#else258// We really only NEED serial initialization here.259if (!TCR_4(__kmp_init_middle)) {260__kmp_middle_initialize();261}262__kmp_assign_root_init_mask();263return __kmp_aux_get_affinity_max_proc();264#endif265}266267void FTN_STDCALL FTN_CREATE_AFFINITY_MASK(void **mask) {268#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED269*mask = NULL;270#else271// We really only NEED serial initialization here.272kmp_affin_mask_t *mask_internals;273if (!TCR_4(__kmp_init_middle)) {274__kmp_middle_initialize();275}276__kmp_assign_root_init_mask();277mask_internals = __kmp_affinity_dispatch->allocate_mask();278KMP_CPU_ZERO(mask_internals);279*mask = mask_internals;280#endif281}282283void FTN_STDCALL FTN_DESTROY_AFFINITY_MASK(void **mask) {284#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED285// Nothing286#else287// We really only NEED serial initialization here.288kmp_affin_mask_t *mask_internals;289if (!TCR_4(__kmp_init_middle)) {290__kmp_middle_initialize();291}292__kmp_assign_root_init_mask();293if (__kmp_env_consistency_check) {294if (*mask == NULL) {295KMP_FATAL(AffinityInvalidMask, "kmp_destroy_affinity_mask");296}297}298mask_internals = (kmp_affin_mask_t *)(*mask);299__kmp_affinity_dispatch->deallocate_mask(mask_internals);300*mask = NULL;301#endif302}303304int FTN_STDCALL FTN_SET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {305#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED306return -1;307#else308if (!TCR_4(__kmp_init_middle)) {309__kmp_middle_initialize();310}311__kmp_assign_root_init_mask();312return __kmp_aux_set_affinity_mask_proc(KMP_DEREF proc, mask);313#endif314}315316int FTN_STDCALL FTN_UNSET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {317#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED318return -1;319#else320if (!TCR_4(__kmp_init_middle)) {321__kmp_middle_initialize();322}323__kmp_assign_root_init_mask();324return __kmp_aux_unset_affinity_mask_proc(KMP_DEREF proc, mask);325#endif326}327328int FTN_STDCALL FTN_GET_AFFINITY_MASK_PROC(int KMP_DEREF proc, void **mask) {329#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED330return -1;331#else332if (!TCR_4(__kmp_init_middle)) {333__kmp_middle_initialize();334}335__kmp_assign_root_init_mask();336return __kmp_aux_get_affinity_mask_proc(KMP_DEREF proc, mask);337#endif338}339340/* ------------------------------------------------------------------------ */341342/* sets the requested number of threads for the next parallel region */343void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NUM_THREADS)(int KMP_DEREF arg) {344#ifdef KMP_STUB345// Nothing.346#else347__kmp_set_num_threads(KMP_DEREF arg, __kmp_entry_gtid());348#endif349}350351/* returns the number of threads in current team */352int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_THREADS)(void) {353#ifdef KMP_STUB354return 1;355#else356// __kmpc_bound_num_threads initializes the library if needed357return __kmpc_bound_num_threads(NULL);358#endif359}360361int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_THREADS)(void) {362#ifdef KMP_STUB363return 1;364#else365int gtid;366kmp_info_t *thread;367if (!TCR_4(__kmp_init_middle)) {368__kmp_middle_initialize();369}370gtid = __kmp_entry_gtid();371thread = __kmp_threads[gtid];372#if KMP_AFFINITY_SUPPORTED373if (thread->th.th_team->t.t_level == 0 && !__kmp_affinity.flags.reset) {374__kmp_assign_root_init_mask();375}376#endif377// return thread -> th.th_team -> t.t_current_task[378// thread->th.th_info.ds.ds_tid ] -> icvs.nproc;379return thread->th.th_current_task->td_icvs.nproc;380#endif381}382383int FTN_STDCALL FTN_CONTROL_TOOL(int command, int modifier, void *arg) {384#if defined(KMP_STUB) || !OMPT_SUPPORT385return -2;386#else387OMPT_STORE_RETURN_ADDRESS(__kmp_entry_gtid());388if (!TCR_4(__kmp_init_middle)) {389return -2;390}391kmp_info_t *this_thr = __kmp_threads[__kmp_entry_gtid()];392ompt_task_info_t *parent_task_info = OMPT_CUR_TASK_INFO(this_thr);393parent_task_info->frame.enter_frame.ptr = OMPT_GET_FRAME_ADDRESS(0);394int ret = __kmp_control_tool(command, modifier, arg);395parent_task_info->frame.enter_frame.ptr = 0;396return ret;397#endif398}399400/* OpenMP 5.0 Memory Management support */401omp_allocator_handle_t FTN_STDCALL402FTN_INIT_ALLOCATOR(omp_memspace_handle_t KMP_DEREF m, int KMP_DEREF ntraits,403omp_alloctrait_t tr[]) {404#ifdef KMP_STUB405return NULL;406#else407return __kmpc_init_allocator(__kmp_entry_gtid(), KMP_DEREF m,408KMP_DEREF ntraits, tr);409#endif410}411412void FTN_STDCALL FTN_DESTROY_ALLOCATOR(omp_allocator_handle_t al) {413#ifndef KMP_STUB414__kmpc_destroy_allocator(__kmp_entry_gtid(), al);415#endif416}417void FTN_STDCALL FTN_SET_DEFAULT_ALLOCATOR(omp_allocator_handle_t al) {418#ifndef KMP_STUB419__kmpc_set_default_allocator(__kmp_entry_gtid(), al);420#endif421}422omp_allocator_handle_t FTN_STDCALL FTN_GET_DEFAULT_ALLOCATOR(void) {423#ifdef KMP_STUB424return NULL;425#else426return __kmpc_get_default_allocator(__kmp_entry_gtid());427#endif428}429430/* OpenMP 5.0 affinity format support */431#ifndef KMP_STUB432static void __kmp_fortran_strncpy_truncate(char *buffer, size_t buf_size,433char const *csrc, size_t csrc_size) {434size_t capped_src_size = csrc_size;435if (csrc_size >= buf_size) {436capped_src_size = buf_size - 1;437}438KMP_STRNCPY_S(buffer, buf_size, csrc, capped_src_size);439if (csrc_size >= buf_size) {440KMP_DEBUG_ASSERT(buffer[buf_size - 1] == '\0');441buffer[buf_size - 1] = csrc[buf_size - 1];442} else {443for (size_t i = csrc_size; i < buf_size; ++i)444buffer[i] = ' ';445}446}447448// Convert a Fortran string to a C string by adding null byte449class ConvertedString {450char *buf;451kmp_info_t *th;452453public:454ConvertedString(char const *fortran_str, size_t size) {455th = __kmp_get_thread();456buf = (char *)__kmp_thread_malloc(th, size + 1);457KMP_STRNCPY_S(buf, size + 1, fortran_str, size);458buf[size] = '\0';459}460~ConvertedString() { __kmp_thread_free(th, buf); }461const char *get() const { return buf; }462};463#endif // KMP_STUB464465/*466* Set the value of the affinity-format-var ICV on the current device to the467* format specified in the argument.468*/469void FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_SET_AFFINITY_FORMAT)(470char const *format, size_t size) {471#ifdef KMP_STUB472return;473#else474if (!__kmp_init_serial) {475__kmp_serial_initialize();476}477ConvertedString cformat(format, size);478// Since the __kmp_affinity_format variable is a C string, do not479// use the fortran strncpy function480__kmp_strncpy_truncate(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE,481cformat.get(), KMP_STRLEN(cformat.get()));482#endif483}484485/*486* Returns the number of characters required to hold the entire affinity format487* specification (not including null byte character) and writes the value of the488* affinity-format-var ICV on the current device to buffer. If the return value489* is larger than size, the affinity format specification is truncated.490*/491size_t FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_GET_AFFINITY_FORMAT)(492char *buffer, size_t size) {493#ifdef KMP_STUB494return 0;495#else496size_t format_size;497if (!__kmp_init_serial) {498__kmp_serial_initialize();499}500format_size = KMP_STRLEN(__kmp_affinity_format);501if (buffer && size) {502__kmp_fortran_strncpy_truncate(buffer, size, __kmp_affinity_format,503format_size);504}505return format_size;506#endif507}508509/*510* Prints the thread affinity information of the current thread in the format511* specified by the format argument. If the format is NULL or a zero-length512* string, the value of the affinity-format-var ICV is used.513*/514void FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_DISPLAY_AFFINITY)(515char const *format, size_t size) {516#ifdef KMP_STUB517return;518#else519int gtid;520if (!TCR_4(__kmp_init_middle)) {521__kmp_middle_initialize();522}523__kmp_assign_root_init_mask();524gtid = __kmp_get_gtid();525#if KMP_AFFINITY_SUPPORTED526if (__kmp_threads[gtid]->th.th_team->t.t_level == 0 &&527__kmp_affinity.flags.reset) {528__kmp_reset_root_init_mask(gtid);529}530#endif531ConvertedString cformat(format, size);532__kmp_aux_display_affinity(gtid, cformat.get());533#endif534}535536/*537* Returns the number of characters required to hold the entire affinity format538* specification (not including null byte) and prints the thread affinity539* information of the current thread into the character string buffer with the540* size of size in the format specified by the format argument. If the format is541* NULL or a zero-length string, the value of the affinity-format-var ICV is542* used. The buffer must be allocated prior to calling the routine. If the543* return value is larger than size, the affinity format specification is544* truncated.545*/546size_t FTN_STDCALL KMP_EXPAND_NAME_IF_APPEND(FTN_CAPTURE_AFFINITY)(547char *buffer, char const *format, size_t buf_size, size_t for_size) {548#if defined(KMP_STUB)549return 0;550#else551int gtid;552size_t num_required;553kmp_str_buf_t capture_buf;554if (!TCR_4(__kmp_init_middle)) {555__kmp_middle_initialize();556}557__kmp_assign_root_init_mask();558gtid = __kmp_get_gtid();559#if KMP_AFFINITY_SUPPORTED560if (__kmp_threads[gtid]->th.th_team->t.t_level == 0 &&561__kmp_affinity.flags.reset) {562__kmp_reset_root_init_mask(gtid);563}564#endif565__kmp_str_buf_init(&capture_buf);566ConvertedString cformat(format, for_size);567num_required = __kmp_aux_capture_affinity(gtid, cformat.get(), &capture_buf);568if (buffer && buf_size) {569__kmp_fortran_strncpy_truncate(buffer, buf_size, capture_buf.str,570capture_buf.used);571}572__kmp_str_buf_free(&capture_buf);573return num_required;574#endif575}576577int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_NUM)(void) {578#ifdef KMP_STUB579return 0;580#else581int gtid;582583#if KMP_OS_DARWIN || KMP_OS_DRAGONFLY || KMP_OS_FREEBSD || KMP_OS_NETBSD || \584KMP_OS_OPENBSD || KMP_OS_HURD || KMP_OS_SOLARIS || KMP_OS_AIX585gtid = __kmp_entry_gtid();586#elif KMP_OS_WINDOWS587if (!__kmp_init_parallel ||588(gtid = (int)((kmp_intptr_t)TlsGetValue(__kmp_gtid_threadprivate_key))) ==5890) {590// Either library isn't initialized or thread is not registered591// 0 is the correct TID in this case592return 0;593}594--gtid; // We keep (gtid+1) in TLS595#elif KMP_OS_LINUX || KMP_OS_WASI596#ifdef KMP_TDATA_GTID597if (__kmp_gtid_mode >= 3) {598if ((gtid = __kmp_gtid) == KMP_GTID_DNE) {599return 0;600}601} else {602#endif603if (!__kmp_init_parallel ||604(gtid = (int)((kmp_intptr_t)(605pthread_getspecific(__kmp_gtid_threadprivate_key)))) == 0) {606return 0;607}608--gtid;609#ifdef KMP_TDATA_GTID610}611#endif612#else613#error Unknown or unsupported OS614#endif615616return __kmp_tid_from_gtid(gtid);617#endif618}619620int FTN_STDCALL FTN_GET_NUM_KNOWN_THREADS(void) {621#ifdef KMP_STUB622return 1;623#else624if (!__kmp_init_serial) {625__kmp_serial_initialize();626}627/* NOTE: this is not syncronized, so it can change at any moment */628/* NOTE: this number also includes threads preallocated in hot-teams */629return TCR_4(__kmp_nth);630#endif631}632633int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_PROCS)(void) {634#ifdef KMP_STUB635return 1;636#else637if (!TCR_4(__kmp_init_middle)) {638__kmp_middle_initialize();639}640#if KMP_AFFINITY_SUPPORTED641if (!__kmp_affinity.flags.reset) {642// only bind root here if its affinity reset is not requested643int gtid = __kmp_entry_gtid();644kmp_info_t *thread = __kmp_threads[gtid];645if (thread->th.th_team->t.t_level == 0) {646__kmp_assign_root_init_mask();647}648}649#endif650return __kmp_avail_proc;651#endif652}653654void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NESTED)(int KMP_DEREF flag) {655#ifdef KMP_STUB656__kmps_set_nested(KMP_DEREF flag);657#else658kmp_info_t *thread;659/* For the thread-private internal controls implementation */660thread = __kmp_entry_thread();661KMP_INFORM(APIDeprecated, "omp_set_nested", "omp_set_max_active_levels");662__kmp_save_internal_controls(thread);663// Somewhat arbitrarily decide where to get a value for max_active_levels664int max_active_levels = get__max_active_levels(thread);665if (max_active_levels == 1)666max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT;667set__max_active_levels(thread, (KMP_DEREF flag) ? max_active_levels : 1);668#endif669}670671int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NESTED)(void) {672#ifdef KMP_STUB673return __kmps_get_nested();674#else675kmp_info_t *thread;676thread = __kmp_entry_thread();677KMP_INFORM(APIDeprecated, "omp_get_nested", "omp_get_max_active_levels");678return get__max_active_levels(thread) > 1;679#endif680}681682void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DYNAMIC)(int KMP_DEREF flag) {683#ifdef KMP_STUB684__kmps_set_dynamic(KMP_DEREF flag ? TRUE : FALSE);685#else686kmp_info_t *thread;687/* For the thread-private implementation of the internal controls */688thread = __kmp_entry_thread();689// !!! What if foreign thread calls it?690__kmp_save_internal_controls(thread);691set__dynamic(thread, KMP_DEREF flag ? true : false);692#endif693}694695int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DYNAMIC)(void) {696#ifdef KMP_STUB697return __kmps_get_dynamic();698#else699kmp_info_t *thread;700thread = __kmp_entry_thread();701return get__dynamic(thread);702#endif703}704705int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_PARALLEL)(void) {706#ifdef KMP_STUB707return 0;708#else709kmp_info_t *th = __kmp_entry_thread();710if (th->th.th_teams_microtask) {711// AC: r_in_parallel does not work inside teams construct where real712// parallel is inactive, but all threads have same root, so setting it in713// one team affects other teams.714// The solution is to use per-team nesting level715return (th->th.th_team->t.t_active_level ? 1 : 0);716} else717return (th->th.th_root->r.r_in_parallel ? FTN_TRUE : FTN_FALSE);718#endif719}720721void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_SCHEDULE)(kmp_sched_t KMP_DEREF kind,722int KMP_DEREF modifier) {723#ifdef KMP_STUB724__kmps_set_schedule(KMP_DEREF kind, KMP_DEREF modifier);725#else726/* TO DO: For the per-task implementation of the internal controls */727__kmp_set_schedule(__kmp_entry_gtid(), KMP_DEREF kind, KMP_DEREF modifier);728#endif729}730731void FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_SCHEDULE)(kmp_sched_t *kind,732int *modifier) {733#ifdef KMP_STUB734__kmps_get_schedule(kind, modifier);735#else736/* TO DO: For the per-task implementation of the internal controls */737__kmp_get_schedule(__kmp_entry_gtid(), kind, modifier);738#endif739}740741void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_MAX_ACTIVE_LEVELS)(int KMP_DEREF arg) {742#ifdef KMP_STUB743// Nothing.744#else745/* TO DO: We want per-task implementation of this internal control */746__kmp_set_max_active_levels(__kmp_entry_gtid(), KMP_DEREF arg);747#endif748}749750int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_ACTIVE_LEVELS)(void) {751#ifdef KMP_STUB752return 0;753#else754/* TO DO: We want per-task implementation of this internal control */755if (!TCR_4(__kmp_init_middle)) {756__kmp_middle_initialize();757}758return __kmp_get_max_active_levels(__kmp_entry_gtid());759#endif760}761762int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_ACTIVE_LEVEL)(void) {763#ifdef KMP_STUB764return 0; // returns 0 if it is called from the sequential part of the program765#else766/* TO DO: For the per-task implementation of the internal controls */767return __kmp_entry_thread()->th.th_team->t.t_active_level;768#endif769}770771int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_LEVEL)(void) {772#ifdef KMP_STUB773return 0; // returns 0 if it is called from the sequential part of the program774#else775/* TO DO: For the per-task implementation of the internal controls */776return __kmp_entry_thread()->th.th_team->t.t_level;777#endif778}779780int FTN_STDCALL781KMP_EXPAND_NAME(FTN_GET_ANCESTOR_THREAD_NUM)(int KMP_DEREF level) {782#ifdef KMP_STUB783return (KMP_DEREF level) ? (-1) : (0);784#else785return __kmp_get_ancestor_thread_num(__kmp_entry_gtid(), KMP_DEREF level);786#endif787}788789int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_SIZE)(int KMP_DEREF level) {790#ifdef KMP_STUB791return (KMP_DEREF level) ? (-1) : (1);792#else793return __kmp_get_team_size(__kmp_entry_gtid(), KMP_DEREF level);794#endif795}796797int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_THREAD_LIMIT)(void) {798#ifdef KMP_STUB799return 1; // TO DO: clarify whether it returns 1 or 0?800#else801int gtid;802kmp_info_t *thread;803if (!__kmp_init_serial) {804__kmp_serial_initialize();805}806807gtid = __kmp_entry_gtid();808thread = __kmp_threads[gtid];809// If thread_limit for the target task is defined, return that instead of the810// regular task thread_limit811if (int thread_limit = thread->th.th_current_task->td_icvs.task_thread_limit)812return thread_limit;813return thread->th.th_current_task->td_icvs.thread_limit;814#endif815}816817int FTN_STDCALL KMP_EXPAND_NAME(FTN_IN_FINAL)(void) {818#ifdef KMP_STUB819return 0; // TO DO: clarify whether it returns 1 or 0?820#else821if (!TCR_4(__kmp_init_parallel)) {822return 0;823}824return __kmp_entry_thread()->th.th_current_task->td_flags.final;825#endif826}827828kmp_proc_bind_t FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PROC_BIND)(void) {829#ifdef KMP_STUB830return __kmps_get_proc_bind();831#else832return get__proc_bind(__kmp_entry_thread());833#endif834}835836int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_PLACES)(void) {837#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED838return 0;839#else840if (!TCR_4(__kmp_init_middle)) {841__kmp_middle_initialize();842}843if (!KMP_AFFINITY_CAPABLE())844return 0;845if (!__kmp_affinity.flags.reset) {846// only bind root here if its affinity reset is not requested847int gtid = __kmp_entry_gtid();848kmp_info_t *thread = __kmp_threads[gtid];849if (thread->th.th_team->t.t_level == 0) {850__kmp_assign_root_init_mask();851}852}853return __kmp_affinity.num_masks;854#endif855}856857int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_NUM_PROCS)(int place_num) {858#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED859return 0;860#else861int i;862int retval = 0;863if (!TCR_4(__kmp_init_middle)) {864__kmp_middle_initialize();865}866if (!KMP_AFFINITY_CAPABLE())867return 0;868if (!__kmp_affinity.flags.reset) {869// only bind root here if its affinity reset is not requested870int gtid = __kmp_entry_gtid();871kmp_info_t *thread = __kmp_threads[gtid];872if (thread->th.th_team->t.t_level == 0) {873__kmp_assign_root_init_mask();874}875}876if (place_num < 0 || place_num >= (int)__kmp_affinity.num_masks)877return 0;878kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity.masks, place_num);879KMP_CPU_SET_ITERATE(i, mask) {880if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||881(!KMP_CPU_ISSET(i, mask))) {882continue;883}884++retval;885}886return retval;887#endif888}889890void FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_PROC_IDS)(int place_num,891int *ids) {892#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED893// Nothing.894#else895int i, j;896if (!TCR_4(__kmp_init_middle)) {897__kmp_middle_initialize();898}899if (!KMP_AFFINITY_CAPABLE())900return;901if (!__kmp_affinity.flags.reset) {902// only bind root here if its affinity reset is not requested903int gtid = __kmp_entry_gtid();904kmp_info_t *thread = __kmp_threads[gtid];905if (thread->th.th_team->t.t_level == 0) {906__kmp_assign_root_init_mask();907}908}909if (place_num < 0 || place_num >= (int)__kmp_affinity.num_masks)910return;911kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity.masks, place_num);912j = 0;913KMP_CPU_SET_ITERATE(i, mask) {914if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||915(!KMP_CPU_ISSET(i, mask))) {916continue;917}918ids[j++] = i;919}920#endif921}922923int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PLACE_NUM)(void) {924#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED925return -1;926#else927int gtid;928kmp_info_t *thread;929if (!TCR_4(__kmp_init_middle)) {930__kmp_middle_initialize();931}932if (!KMP_AFFINITY_CAPABLE())933return -1;934gtid = __kmp_entry_gtid();935thread = __kmp_thread_from_gtid(gtid);936if (thread->th.th_team->t.t_level == 0 && !__kmp_affinity.flags.reset) {937__kmp_assign_root_init_mask();938}939if (thread->th.th_current_place < 0)940return -1;941return thread->th.th_current_place;942#endif943}944945int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_PARTITION_NUM_PLACES)(void) {946#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED947return 0;948#else949int gtid, num_places, first_place, last_place;950kmp_info_t *thread;951if (!TCR_4(__kmp_init_middle)) {952__kmp_middle_initialize();953}954if (!KMP_AFFINITY_CAPABLE())955return 0;956gtid = __kmp_entry_gtid();957thread = __kmp_thread_from_gtid(gtid);958if (thread->th.th_team->t.t_level == 0 && !__kmp_affinity.flags.reset) {959__kmp_assign_root_init_mask();960}961first_place = thread->th.th_first_place;962last_place = thread->th.th_last_place;963if (first_place < 0 || last_place < 0)964return 0;965if (first_place <= last_place)966num_places = last_place - first_place + 1;967else968num_places = __kmp_affinity.num_masks - first_place + last_place + 1;969return num_places;970#endif971}972973void FTN_STDCALL974KMP_EXPAND_NAME(FTN_GET_PARTITION_PLACE_NUMS)(int *place_nums) {975#if defined(KMP_STUB) || !KMP_AFFINITY_SUPPORTED976// Nothing.977#else978int i, gtid, place_num, first_place, last_place, start, end;979kmp_info_t *thread;980if (!TCR_4(__kmp_init_middle)) {981__kmp_middle_initialize();982}983if (!KMP_AFFINITY_CAPABLE())984return;985gtid = __kmp_entry_gtid();986thread = __kmp_thread_from_gtid(gtid);987if (thread->th.th_team->t.t_level == 0 && !__kmp_affinity.flags.reset) {988__kmp_assign_root_init_mask();989}990first_place = thread->th.th_first_place;991last_place = thread->th.th_last_place;992if (first_place < 0 || last_place < 0)993return;994if (first_place <= last_place) {995start = first_place;996end = last_place;997} else {998start = last_place;999end = first_place;1000}1001for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) {1002place_nums[i] = place_num;1003}1004#endif1005}10061007int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_TEAMS)(void) {1008#ifdef KMP_STUB1009return 1;1010#else1011return __kmp_aux_get_num_teams();1012#endif1013}10141015int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_TEAM_NUM)(void) {1016#ifdef KMP_STUB1017return 0;1018#else1019return __kmp_aux_get_team_num();1020#endif1021}10221023int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_DEFAULT_DEVICE)(void) {1024#if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)1025return 0;1026#else1027return __kmp_entry_thread()->th.th_current_task->td_icvs.default_device;1028#endif1029}10301031void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_DEFAULT_DEVICE)(int KMP_DEREF arg) {1032#if KMP_MIC || KMP_OS_DARWIN || defined(KMP_STUB)1033// Nothing.1034#else1035__kmp_entry_thread()->th.th_current_task->td_icvs.default_device =1036KMP_DEREF arg;1037#endif1038}10391040// Get number of NON-HOST devices.1041// libomptarget, if loaded, provides this function in api.cpp.1042int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void)1043KMP_WEAK_ATTRIBUTE_EXTERNAL;1044int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)(void) {1045#if KMP_MIC || KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)1046return 0;1047#else1048int (*fptr)();1049if ((*(void **)(&fptr) = KMP_DLSYM("__tgt_get_num_devices"))) {1050return (*fptr)();1051} else if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_devices"))) {1052return (*fptr)();1053} else if ((*(void **)(&fptr) = KMP_DLSYM("_Offload_number_of_devices"))) {1054return (*fptr)();1055} else { // liboffload & libomptarget don't exist1056return 0;1057}1058#endif // KMP_MIC || KMP_OS_DARWIN || KMP_OS_WINDOWS || defined(KMP_STUB)1059}10601061// This function always returns true when called on host device.1062// Compiler/libomptarget should handle when it is called inside target region.1063int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void)1064KMP_WEAK_ATTRIBUTE_EXTERNAL;1065int FTN_STDCALL KMP_EXPAND_NAME(FTN_IS_INITIAL_DEVICE)(void) {1066return 1; // This is the host1067}10681069// libomptarget, if loaded, provides this function1070int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void)1071KMP_WEAK_ATTRIBUTE_EXTERNAL;1072int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)(void) {1073// same as omp_get_num_devices()1074return KMP_EXPAND_NAME(FTN_GET_NUM_DEVICES)();1075}10761077#if defined(KMP_STUB)1078// Entries for stubs library1079// As all *target* functions are C-only parameters always passed by value1080void *FTN_STDCALL FTN_TARGET_ALLOC(size_t size, int device_num) { return 0; }10811082void FTN_STDCALL FTN_TARGET_FREE(void *device_ptr, int device_num) {}10831084int FTN_STDCALL FTN_TARGET_IS_PRESENT(void *ptr, int device_num) { return 0; }10851086int FTN_STDCALL FTN_TARGET_MEMCPY(void *dst, void *src, size_t length,1087size_t dst_offset, size_t src_offset,1088int dst_device, int src_device) {1089return -1;1090}10911092int FTN_STDCALL FTN_TARGET_MEMCPY_RECT(1093void *dst, void *src, size_t element_size, int num_dims,1094const size_t *volume, const size_t *dst_offsets, const size_t *src_offsets,1095const size_t *dst_dimensions, const size_t *src_dimensions, int dst_device,1096int src_device) {1097return -1;1098}10991100int FTN_STDCALL FTN_TARGET_ASSOCIATE_PTR(void *host_ptr, void *device_ptr,1101size_t size, size_t device_offset,1102int device_num) {1103return -1;1104}11051106int FTN_STDCALL FTN_TARGET_DISASSOCIATE_PTR(void *host_ptr, int device_num) {1107return -1;1108}1109#endif // defined(KMP_STUB)11101111#ifdef KMP_STUB1112typedef enum { UNINIT = -1, UNLOCKED, LOCKED } kmp_stub_lock_t;1113#endif /* KMP_STUB */11141115#if KMP_USE_DYNAMIC_LOCK1116void FTN_STDCALL FTN_INIT_LOCK_WITH_HINT(void **user_lock,1117uintptr_t KMP_DEREF hint) {1118#ifdef KMP_STUB1119*((kmp_stub_lock_t *)user_lock) = UNLOCKED;1120#else1121int gtid = __kmp_entry_gtid();1122#if OMPT_SUPPORT && OMPT_OPTIONAL1123OMPT_STORE_RETURN_ADDRESS(gtid);1124#endif1125__kmpc_init_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);1126#endif1127}11281129void FTN_STDCALL FTN_INIT_NEST_LOCK_WITH_HINT(void **user_lock,1130uintptr_t KMP_DEREF hint) {1131#ifdef KMP_STUB1132*((kmp_stub_lock_t *)user_lock) = UNLOCKED;1133#else1134int gtid = __kmp_entry_gtid();1135#if OMPT_SUPPORT && OMPT_OPTIONAL1136OMPT_STORE_RETURN_ADDRESS(gtid);1137#endif1138__kmpc_init_nest_lock_with_hint(NULL, gtid, user_lock, KMP_DEREF hint);1139#endif1140}1141#endif11421143/* initialize the lock */1144void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_LOCK)(void **user_lock) {1145#ifdef KMP_STUB1146*((kmp_stub_lock_t *)user_lock) = UNLOCKED;1147#else1148int gtid = __kmp_entry_gtid();1149#if OMPT_SUPPORT && OMPT_OPTIONAL1150OMPT_STORE_RETURN_ADDRESS(gtid);1151#endif1152__kmpc_init_lock(NULL, gtid, user_lock);1153#endif1154}11551156/* initialize the lock */1157void FTN_STDCALL KMP_EXPAND_NAME(FTN_INIT_NEST_LOCK)(void **user_lock) {1158#ifdef KMP_STUB1159*((kmp_stub_lock_t *)user_lock) = UNLOCKED;1160#else1161int gtid = __kmp_entry_gtid();1162#if OMPT_SUPPORT && OMPT_OPTIONAL1163OMPT_STORE_RETURN_ADDRESS(gtid);1164#endif1165__kmpc_init_nest_lock(NULL, gtid, user_lock);1166#endif1167}11681169void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_LOCK)(void **user_lock) {1170#ifdef KMP_STUB1171*((kmp_stub_lock_t *)user_lock) = UNINIT;1172#else1173int gtid = __kmp_entry_gtid();1174#if OMPT_SUPPORT && OMPT_OPTIONAL1175OMPT_STORE_RETURN_ADDRESS(gtid);1176#endif1177__kmpc_destroy_lock(NULL, gtid, user_lock);1178#endif1179}11801181void FTN_STDCALL KMP_EXPAND_NAME(FTN_DESTROY_NEST_LOCK)(void **user_lock) {1182#ifdef KMP_STUB1183*((kmp_stub_lock_t *)user_lock) = UNINIT;1184#else1185int gtid = __kmp_entry_gtid();1186#if OMPT_SUPPORT && OMPT_OPTIONAL1187OMPT_STORE_RETURN_ADDRESS(gtid);1188#endif1189__kmpc_destroy_nest_lock(NULL, gtid, user_lock);1190#endif1191}11921193void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_LOCK)(void **user_lock) {1194#ifdef KMP_STUB1195if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {1196// TODO: Issue an error.1197}1198if (*((kmp_stub_lock_t *)user_lock) != UNLOCKED) {1199// TODO: Issue an error.1200}1201*((kmp_stub_lock_t *)user_lock) = LOCKED;1202#else1203int gtid = __kmp_entry_gtid();1204#if OMPT_SUPPORT && OMPT_OPTIONAL1205OMPT_STORE_RETURN_ADDRESS(gtid);1206#endif1207__kmpc_set_lock(NULL, gtid, user_lock);1208#endif1209}12101211void FTN_STDCALL KMP_EXPAND_NAME(FTN_SET_NEST_LOCK)(void **user_lock) {1212#ifdef KMP_STUB1213if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {1214// TODO: Issue an error.1215}1216(*((int *)user_lock))++;1217#else1218int gtid = __kmp_entry_gtid();1219#if OMPT_SUPPORT && OMPT_OPTIONAL1220OMPT_STORE_RETURN_ADDRESS(gtid);1221#endif1222__kmpc_set_nest_lock(NULL, gtid, user_lock);1223#endif1224}12251226void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_LOCK)(void **user_lock) {1227#ifdef KMP_STUB1228if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {1229// TODO: Issue an error.1230}1231if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {1232// TODO: Issue an error.1233}1234*((kmp_stub_lock_t *)user_lock) = UNLOCKED;1235#else1236int gtid = __kmp_entry_gtid();1237#if OMPT_SUPPORT && OMPT_OPTIONAL1238OMPT_STORE_RETURN_ADDRESS(gtid);1239#endif1240__kmpc_unset_lock(NULL, gtid, user_lock);1241#endif1242}12431244void FTN_STDCALL KMP_EXPAND_NAME(FTN_UNSET_NEST_LOCK)(void **user_lock) {1245#ifdef KMP_STUB1246if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {1247// TODO: Issue an error.1248}1249if (*((kmp_stub_lock_t *)user_lock) == UNLOCKED) {1250// TODO: Issue an error.1251}1252(*((int *)user_lock))--;1253#else1254int gtid = __kmp_entry_gtid();1255#if OMPT_SUPPORT && OMPT_OPTIONAL1256OMPT_STORE_RETURN_ADDRESS(gtid);1257#endif1258__kmpc_unset_nest_lock(NULL, gtid, user_lock);1259#endif1260}12611262int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_LOCK)(void **user_lock) {1263#ifdef KMP_STUB1264if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {1265// TODO: Issue an error.1266}1267if (*((kmp_stub_lock_t *)user_lock) == LOCKED) {1268return 0;1269}1270*((kmp_stub_lock_t *)user_lock) = LOCKED;1271return 1;1272#else1273int gtid = __kmp_entry_gtid();1274#if OMPT_SUPPORT && OMPT_OPTIONAL1275OMPT_STORE_RETURN_ADDRESS(gtid);1276#endif1277return __kmpc_test_lock(NULL, gtid, user_lock);1278#endif1279}12801281int FTN_STDCALL KMP_EXPAND_NAME(FTN_TEST_NEST_LOCK)(void **user_lock) {1282#ifdef KMP_STUB1283if (*((kmp_stub_lock_t *)user_lock) == UNINIT) {1284// TODO: Issue an error.1285}1286return ++(*((int *)user_lock));1287#else1288int gtid = __kmp_entry_gtid();1289#if OMPT_SUPPORT && OMPT_OPTIONAL1290OMPT_STORE_RETURN_ADDRESS(gtid);1291#endif1292return __kmpc_test_nest_lock(NULL, gtid, user_lock);1293#endif1294}12951296double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTIME)(void) {1297#ifdef KMP_STUB1298return __kmps_get_wtime();1299#else1300double data;1301#if !KMP_OS_LINUX1302// We don't need library initialization to get the time on Linux* OS. The1303// routine can be used to measure library initialization time on Linux* OS now1304if (!__kmp_init_serial) {1305__kmp_serial_initialize();1306}1307#endif1308__kmp_elapsed(&data);1309return data;1310#endif1311}13121313double FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_WTICK)(void) {1314#ifdef KMP_STUB1315return __kmps_get_wtick();1316#else1317double data;1318if (!__kmp_init_serial) {1319__kmp_serial_initialize();1320}1321__kmp_elapsed_tick(&data);1322return data;1323#endif1324}13251326/* ------------------------------------------------------------------------ */13271328void *FTN_STDCALL FTN_MALLOC(size_t KMP_DEREF size) {1329// kmpc_malloc initializes the library if needed1330return kmpc_malloc(KMP_DEREF size);1331}13321333void *FTN_STDCALL FTN_ALIGNED_MALLOC(size_t KMP_DEREF size,1334size_t KMP_DEREF alignment) {1335// kmpc_aligned_malloc initializes the library if needed1336return kmpc_aligned_malloc(KMP_DEREF size, KMP_DEREF alignment);1337}13381339void *FTN_STDCALL FTN_CALLOC(size_t KMP_DEREF nelem, size_t KMP_DEREF elsize) {1340// kmpc_calloc initializes the library if needed1341return kmpc_calloc(KMP_DEREF nelem, KMP_DEREF elsize);1342}13431344void *FTN_STDCALL FTN_REALLOC(void *KMP_DEREF ptr, size_t KMP_DEREF size) {1345// kmpc_realloc initializes the library if needed1346return kmpc_realloc(KMP_DEREF ptr, KMP_DEREF size);1347}13481349void FTN_STDCALL FTN_KFREE(void *KMP_DEREF ptr) {1350// does nothing if the library is not initialized1351kmpc_free(KMP_DEREF ptr);1352}13531354void FTN_STDCALL FTN_SET_WARNINGS_ON(void) {1355#ifndef KMP_STUB1356__kmp_generate_warnings = kmp_warnings_explicit;1357#endif1358}13591360void FTN_STDCALL FTN_SET_WARNINGS_OFF(void) {1361#ifndef KMP_STUB1362__kmp_generate_warnings = FALSE;1363#endif1364}13651366void FTN_STDCALL FTN_SET_DEFAULTS(char const *str1367#ifndef PASS_ARGS_BY_VALUE1368,1369int len1370#endif1371) {1372#ifndef KMP_STUB1373#ifdef PASS_ARGS_BY_VALUE1374int len = (int)KMP_STRLEN(str);1375#endif1376__kmp_aux_set_defaults(str, len);1377#endif1378}13791380/* ------------------------------------------------------------------------ */13811382/* returns the status of cancellation */1383int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_CANCELLATION)(void) {1384#ifdef KMP_STUB1385return 0 /* false */;1386#else1387// initialize the library if needed1388if (!__kmp_init_serial) {1389__kmp_serial_initialize();1390}1391return __kmp_omp_cancellation;1392#endif1393}13941395int FTN_STDCALL FTN_GET_CANCELLATION_STATUS(int cancel_kind) {1396#ifdef KMP_STUB1397return 0 /* false */;1398#else1399return __kmp_get_cancellation_status(cancel_kind);1400#endif1401}14021403/* returns the maximum allowed task priority */1404int FTN_STDCALL KMP_EXPAND_NAME(FTN_GET_MAX_TASK_PRIORITY)(void) {1405#ifdef KMP_STUB1406return 0;1407#else1408if (!__kmp_init_serial) {1409__kmp_serial_initialize();1410}1411return __kmp_max_task_priority;1412#endif1413}14141415// This function will be defined in libomptarget. When libomptarget is not1416// loaded, we assume we are on the host and return KMP_HOST_DEVICE.1417// Compiler/libomptarget will handle this if called inside target.1418int FTN_STDCALL FTN_GET_DEVICE_NUM(void) KMP_WEAK_ATTRIBUTE_EXTERNAL;1419int FTN_STDCALL FTN_GET_DEVICE_NUM(void) {1420return KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)();1421}14221423// Compiler will ensure that this is only called from host in sequential region1424int FTN_STDCALL KMP_EXPAND_NAME(FTN_PAUSE_RESOURCE)(kmp_pause_status_t kind,1425int device_num) {1426#ifdef KMP_STUB1427return 1; // just fail1428#else1429if (device_num == KMP_EXPAND_NAME(FTN_GET_INITIAL_DEVICE)())1430return __kmpc_pause_resource(kind);1431else {1432int (*fptr)(kmp_pause_status_t, int);1433if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource")))1434return (*fptr)(kind, device_num);1435else1436return 1; // just fail if there is no libomptarget1437}1438#endif1439}14401441// Compiler will ensure that this is only called from host in sequential region1442int FTN_STDCALL1443KMP_EXPAND_NAME(FTN_PAUSE_RESOURCE_ALL)(kmp_pause_status_t kind) {1444#ifdef KMP_STUB1445return 1; // just fail1446#else1447int fails = 0;1448int (*fptr)(kmp_pause_status_t, int);1449if ((*(void **)(&fptr) = KMP_DLSYM("tgt_pause_resource")))1450fails = (*fptr)(kind, KMP_DEVICE_ALL); // pause devices1451fails += __kmpc_pause_resource(kind); // pause host1452return fails;1453#endif1454}14551456// Returns the maximum number of nesting levels supported by implementation1457int FTN_STDCALL FTN_GET_SUPPORTED_ACTIVE_LEVELS(void) {1458#ifdef KMP_STUB1459return 1;1460#else1461return KMP_MAX_ACTIVE_LEVELS_LIMIT;1462#endif1463}14641465void FTN_STDCALL FTN_FULFILL_EVENT(kmp_event_t *event) {1466#ifndef KMP_STUB1467__kmp_fulfill_event(event);1468#endif1469}14701471// nteams-var per-device ICV1472void FTN_STDCALL FTN_SET_NUM_TEAMS(int KMP_DEREF num_teams) {1473#ifdef KMP_STUB1474// Nothing.1475#else1476if (!__kmp_init_serial) {1477__kmp_serial_initialize();1478}1479__kmp_set_num_teams(KMP_DEREF num_teams);1480#endif1481}1482int FTN_STDCALL FTN_GET_MAX_TEAMS(void) {1483#ifdef KMP_STUB1484return 1;1485#else1486if (!__kmp_init_serial) {1487__kmp_serial_initialize();1488}1489return __kmp_get_max_teams();1490#endif1491}1492// teams-thread-limit-var per-device ICV1493void FTN_STDCALL FTN_SET_TEAMS_THREAD_LIMIT(int KMP_DEREF limit) {1494#ifdef KMP_STUB1495// Nothing.1496#else1497if (!__kmp_init_serial) {1498__kmp_serial_initialize();1499}1500__kmp_set_teams_thread_limit(KMP_DEREF limit);1501#endif1502}1503int FTN_STDCALL FTN_GET_TEAMS_THREAD_LIMIT(void) {1504#ifdef KMP_STUB1505return 1;1506#else1507if (!__kmp_init_serial) {1508__kmp_serial_initialize();1509}1510return __kmp_get_teams_thread_limit();1511#endif1512}15131514/// TODO: Include the `omp.h` of the current build1515/* OpenMP 5.1 interop */1516typedef intptr_t omp_intptr_t;15171518/* 0..omp_get_num_interop_properties()-1 are reserved for implementation-defined1519* properties */1520typedef enum omp_interop_property {1521omp_ipr_fr_id = -1,1522omp_ipr_fr_name = -2,1523omp_ipr_vendor = -3,1524omp_ipr_vendor_name = -4,1525omp_ipr_device_num = -5,1526omp_ipr_platform = -6,1527omp_ipr_device = -7,1528omp_ipr_device_context = -8,1529omp_ipr_targetsync = -9,1530omp_ipr_first = -91531} omp_interop_property_t;15321533#define omp_interop_none 015341535typedef enum omp_interop_rc {1536omp_irc_no_value = 1,1537omp_irc_success = 0,1538omp_irc_empty = -1,1539omp_irc_out_of_range = -2,1540omp_irc_type_int = -3,1541omp_irc_type_ptr = -4,1542omp_irc_type_str = -5,1543omp_irc_other = -61544} omp_interop_rc_t;15451546typedef enum omp_interop_fr {1547omp_ifr_cuda = 1,1548omp_ifr_cuda_driver = 2,1549omp_ifr_opencl = 3,1550omp_ifr_sycl = 4,1551omp_ifr_hip = 5,1552omp_ifr_level_zero = 6,1553omp_ifr_last = 71554} omp_interop_fr_t;15551556typedef void *omp_interop_t;15571558// libomptarget, if loaded, provides this function1559int FTN_STDCALL FTN_GET_NUM_INTEROP_PROPERTIES(const omp_interop_t interop) {1560#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)1561return 0;1562#else1563int (*fptr)(const omp_interop_t);1564if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_num_interop_properties")))1565return (*fptr)(interop);1566return 0;1567#endif1568}15691570/// TODO Convert FTN_GET_INTEROP_XXX functions into a macro like interop.cpp1571// libomptarget, if loaded, provides this function1572intptr_t FTN_STDCALL FTN_GET_INTEROP_INT(const omp_interop_t interop,1573omp_interop_property_t property_id,1574int *err) {1575#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)1576return 0;1577#else1578intptr_t (*fptr)(const omp_interop_t, omp_interop_property_t, int *);1579if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_int")))1580return (*fptr)(interop, property_id, err);1581return 0;1582#endif1583}15841585// libomptarget, if loaded, provides this function1586void *FTN_STDCALL FTN_GET_INTEROP_PTR(const omp_interop_t interop,1587omp_interop_property_t property_id,1588int *err) {1589#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)1590return nullptr;1591#else1592void *(*fptr)(const omp_interop_t, omp_interop_property_t, int *);1593if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_ptr")))1594return (*fptr)(interop, property_id, err);1595return nullptr;1596#endif1597}15981599// libomptarget, if loaded, provides this function1600const char *FTN_STDCALL FTN_GET_INTEROP_STR(const omp_interop_t interop,1601omp_interop_property_t property_id,1602int *err) {1603#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)1604return nullptr;1605#else1606const char *(*fptr)(const omp_interop_t, omp_interop_property_t, int *);1607if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_str")))1608return (*fptr)(interop, property_id, err);1609return nullptr;1610#endif1611}16121613// libomptarget, if loaded, provides this function1614const char *FTN_STDCALL FTN_GET_INTEROP_NAME(1615const omp_interop_t interop, omp_interop_property_t property_id) {1616#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)1617return nullptr;1618#else1619const char *(*fptr)(const omp_interop_t, omp_interop_property_t);1620if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_name")))1621return (*fptr)(interop, property_id);1622return nullptr;1623#endif1624}16251626// libomptarget, if loaded, provides this function1627const char *FTN_STDCALL FTN_GET_INTEROP_TYPE_DESC(1628const omp_interop_t interop, omp_interop_property_t property_id) {1629#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)1630return nullptr;1631#else1632const char *(*fptr)(const omp_interop_t, omp_interop_property_t);1633if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_type_desc")))1634return (*fptr)(interop, property_id);1635return nullptr;1636#endif1637}16381639// libomptarget, if loaded, provides this function1640const char *FTN_STDCALL FTN_GET_INTEROP_RC_DESC(1641const omp_interop_t interop, omp_interop_property_t property_id) {1642#if KMP_OS_DARWIN || KMP_OS_WASI || defined(KMP_STUB)1643return nullptr;1644#else1645const char *(*fptr)(const omp_interop_t, omp_interop_property_t);1646if ((*(void **)(&fptr) = KMP_DLSYM_NEXT("omp_get_interop_rec_desc")))1647return (*fptr)(interop, property_id);1648return nullptr;1649#endif1650}16511652// display environment variables when requested1653void FTN_STDCALL FTN_DISPLAY_ENV(int verbose) {1654#ifndef KMP_STUB1655__kmp_omp_display_env(verbose);1656#endif1657}16581659int FTN_STDCALL FTN_IN_EXPLICIT_TASK(void) {1660#ifdef KMP_STUB1661return 0;1662#else1663int gtid = __kmp_entry_gtid();1664return __kmp_thread_from_gtid(gtid)->th.th_current_task->td_flags.tasktype;1665#endif1666}16671668// GCC compatibility (versioned symbols)1669#ifdef KMP_USE_VERSION_SYMBOLS16701671/* These following sections create versioned symbols for the1672omp_* routines. The KMP_VERSION_SYMBOL macro expands the API name and1673then maps it to a versioned symbol.1674libgomp ``versions'' its symbols (OMP_1.0, OMP_2.0, OMP_3.0, ...) while also1675retaining the default version which libomp uses: VERSION (defined in1676exports_so.txt). If you want to see the versioned symbols for libgomp.so.11677then just type:16781679objdump -T /path/to/libgomp.so.1 | grep omp_16801681Example:1682Step 1) Create __kmp_api_omp_set_num_threads_10_alias which is alias of1683__kmp_api_omp_set_num_threads1684Step 2) Set __kmp_api_omp_set_num_threads_10_alias to version:1685omp_set_num_threads@OMP_1.01686Step 2B) Set __kmp_api_omp_set_num_threads to default version:1687omp_set_num_threads@@VERSION1688*/16891690// OMP_1.0 versioned symbols1691KMP_VERSION_SYMBOL(FTN_SET_NUM_THREADS, 10, "OMP_1.0");1692KMP_VERSION_SYMBOL(FTN_GET_NUM_THREADS, 10, "OMP_1.0");1693KMP_VERSION_SYMBOL(FTN_GET_MAX_THREADS, 10, "OMP_1.0");1694KMP_VERSION_SYMBOL(FTN_GET_THREAD_NUM, 10, "OMP_1.0");1695KMP_VERSION_SYMBOL(FTN_GET_NUM_PROCS, 10, "OMP_1.0");1696KMP_VERSION_SYMBOL(FTN_IN_PARALLEL, 10, "OMP_1.0");1697KMP_VERSION_SYMBOL(FTN_SET_DYNAMIC, 10, "OMP_1.0");1698KMP_VERSION_SYMBOL(FTN_GET_DYNAMIC, 10, "OMP_1.0");1699KMP_VERSION_SYMBOL(FTN_SET_NESTED, 10, "OMP_1.0");1700KMP_VERSION_SYMBOL(FTN_GET_NESTED, 10, "OMP_1.0");1701KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 10, "OMP_1.0");1702KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 10, "OMP_1.0");1703KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 10, "OMP_1.0");1704KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 10, "OMP_1.0");1705KMP_VERSION_SYMBOL(FTN_SET_LOCK, 10, "OMP_1.0");1706KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 10, "OMP_1.0");1707KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 10, "OMP_1.0");1708KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 10, "OMP_1.0");1709KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 10, "OMP_1.0");1710KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 10, "OMP_1.0");17111712// OMP_2.0 versioned symbols1713KMP_VERSION_SYMBOL(FTN_GET_WTICK, 20, "OMP_2.0");1714KMP_VERSION_SYMBOL(FTN_GET_WTIME, 20, "OMP_2.0");17151716// OMP_3.0 versioned symbols1717KMP_VERSION_SYMBOL(FTN_SET_SCHEDULE, 30, "OMP_3.0");1718KMP_VERSION_SYMBOL(FTN_GET_SCHEDULE, 30, "OMP_3.0");1719KMP_VERSION_SYMBOL(FTN_GET_THREAD_LIMIT, 30, "OMP_3.0");1720KMP_VERSION_SYMBOL(FTN_SET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");1721KMP_VERSION_SYMBOL(FTN_GET_MAX_ACTIVE_LEVELS, 30, "OMP_3.0");1722KMP_VERSION_SYMBOL(FTN_GET_ANCESTOR_THREAD_NUM, 30, "OMP_3.0");1723KMP_VERSION_SYMBOL(FTN_GET_LEVEL, 30, "OMP_3.0");1724KMP_VERSION_SYMBOL(FTN_GET_TEAM_SIZE, 30, "OMP_3.0");1725KMP_VERSION_SYMBOL(FTN_GET_ACTIVE_LEVEL, 30, "OMP_3.0");17261727// the lock routines have a 1.0 and 3.0 version1728KMP_VERSION_SYMBOL(FTN_INIT_LOCK, 30, "OMP_3.0");1729KMP_VERSION_SYMBOL(FTN_INIT_NEST_LOCK, 30, "OMP_3.0");1730KMP_VERSION_SYMBOL(FTN_DESTROY_LOCK, 30, "OMP_3.0");1731KMP_VERSION_SYMBOL(FTN_DESTROY_NEST_LOCK, 30, "OMP_3.0");1732KMP_VERSION_SYMBOL(FTN_SET_LOCK, 30, "OMP_3.0");1733KMP_VERSION_SYMBOL(FTN_SET_NEST_LOCK, 30, "OMP_3.0");1734KMP_VERSION_SYMBOL(FTN_UNSET_LOCK, 30, "OMP_3.0");1735KMP_VERSION_SYMBOL(FTN_UNSET_NEST_LOCK, 30, "OMP_3.0");1736KMP_VERSION_SYMBOL(FTN_TEST_LOCK, 30, "OMP_3.0");1737KMP_VERSION_SYMBOL(FTN_TEST_NEST_LOCK, 30, "OMP_3.0");17381739// OMP_3.1 versioned symbol1740KMP_VERSION_SYMBOL(FTN_IN_FINAL, 31, "OMP_3.1");17411742// OMP_4.0 versioned symbols1743KMP_VERSION_SYMBOL(FTN_GET_PROC_BIND, 40, "OMP_4.0");1744KMP_VERSION_SYMBOL(FTN_GET_NUM_TEAMS, 40, "OMP_4.0");1745KMP_VERSION_SYMBOL(FTN_GET_TEAM_NUM, 40, "OMP_4.0");1746KMP_VERSION_SYMBOL(FTN_GET_CANCELLATION, 40, "OMP_4.0");1747KMP_VERSION_SYMBOL(FTN_GET_DEFAULT_DEVICE, 40, "OMP_4.0");1748KMP_VERSION_SYMBOL(FTN_SET_DEFAULT_DEVICE, 40, "OMP_4.0");1749KMP_VERSION_SYMBOL(FTN_IS_INITIAL_DEVICE, 40, "OMP_4.0");1750KMP_VERSION_SYMBOL(FTN_GET_NUM_DEVICES, 40, "OMP_4.0");17511752// OMP_4.5 versioned symbols1753KMP_VERSION_SYMBOL(FTN_GET_MAX_TASK_PRIORITY, 45, "OMP_4.5");1754KMP_VERSION_SYMBOL(FTN_GET_NUM_PLACES, 45, "OMP_4.5");1755KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM_PROCS, 45, "OMP_4.5");1756KMP_VERSION_SYMBOL(FTN_GET_PLACE_PROC_IDS, 45, "OMP_4.5");1757KMP_VERSION_SYMBOL(FTN_GET_PLACE_NUM, 45, "OMP_4.5");1758KMP_VERSION_SYMBOL(FTN_GET_PARTITION_NUM_PLACES, 45, "OMP_4.5");1759KMP_VERSION_SYMBOL(FTN_GET_PARTITION_PLACE_NUMS, 45, "OMP_4.5");1760KMP_VERSION_SYMBOL(FTN_GET_INITIAL_DEVICE, 45, "OMP_4.5");17611762// OMP_5.0 versioned symbols1763// KMP_VERSION_SYMBOL(FTN_GET_DEVICE_NUM, 50, "OMP_5.0");1764KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE, 50, "OMP_5.0");1765KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE_ALL, 50, "OMP_5.0");1766// The C versions (KMP_FTN_PLAIN) of these symbols are in kmp_csupport.c1767#if KMP_FTN_ENTRIES == KMP_FTN_APPEND1768KMP_VERSION_SYMBOL(FTN_CAPTURE_AFFINITY, 50, "OMP_5.0");1769KMP_VERSION_SYMBOL(FTN_DISPLAY_AFFINITY, 50, "OMP_5.0");1770KMP_VERSION_SYMBOL(FTN_GET_AFFINITY_FORMAT, 50, "OMP_5.0");1771KMP_VERSION_SYMBOL(FTN_SET_AFFINITY_FORMAT, 50, "OMP_5.0");1772#endif1773// KMP_VERSION_SYMBOL(FTN_GET_SUPPORTED_ACTIVE_LEVELS, 50, "OMP_5.0");1774// KMP_VERSION_SYMBOL(FTN_FULFILL_EVENT, 50, "OMP_5.0");17751776#endif // KMP_USE_VERSION_SYMBOLS17771778#ifdef __cplusplus1779} // extern "C"1780#endif // __cplusplus17811782// end of file //178317841785