10b57cec5SDimitry Andric /* 20b57cec5SDimitry Andric * ompt-specific.h - header of OMPT internal functions implementation 30b57cec5SDimitry Andric */ 40b57cec5SDimitry Andric 50b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 80b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 90b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef OMPT_SPECIFIC_H 140b57cec5SDimitry Andric #define OMPT_SPECIFIC_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "kmp.h" 170b57cec5SDimitry Andric 18480093f4SDimitry Andric #if OMPT_SUPPORT 190b57cec5SDimitry Andric /***************************************************************************** 200b57cec5SDimitry Andric * forward declarations 210b57cec5SDimitry Andric ****************************************************************************/ 220b57cec5SDimitry Andric 23bdd1243dSDimitry Andric /// Entrypoint used by libomptarget to register callbacks in libomp, if not 24bdd1243dSDimitry Andric /// done already 25bdd1243dSDimitry Andric void __ompt_force_initialization(); 26bdd1243dSDimitry Andric 270b57cec5SDimitry Andric void __ompt_team_assign_id(kmp_team_t *team, ompt_data_t ompt_pid); 280b57cec5SDimitry Andric void __ompt_thread_assign_wait_id(void *variable); 290b57cec5SDimitry Andric 30fe6060f1SDimitry Andric void __ompt_lw_taskteam_init(ompt_lw_taskteam_t *lwt, kmp_info_t *thr, int gtid, 31fe6060f1SDimitry Andric ompt_data_t *ompt_pid, void *codeptr); 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric void __ompt_lw_taskteam_link(ompt_lw_taskteam_t *lwt, kmp_info_t *thr, 34489b1cf2SDimitry Andric int on_heap, bool always = false); 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric void __ompt_lw_taskteam_unlink(kmp_info_t *thr); 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric ompt_team_info_t *__ompt_get_teaminfo(int depth, int *size); 390b57cec5SDimitry Andric 4006c3fb27SDimitry Andric ompt_data_t *__ompt_get_task_data(); 4106c3fb27SDimitry Andric 4206c3fb27SDimitry Andric ompt_data_t *__ompt_get_target_task_data(); 4306c3fb27SDimitry Andric 440b57cec5SDimitry Andric ompt_task_info_t *__ompt_get_task_info_object(int depth); 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric int __ompt_get_parallel_info_internal(int ancestor_level, 470b57cec5SDimitry Andric ompt_data_t **parallel_data, 480b57cec5SDimitry Andric int *team_size); 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric int __ompt_get_task_info_internal(int ancestor_level, int *type, 510b57cec5SDimitry Andric ompt_data_t **task_data, 520b57cec5SDimitry Andric ompt_frame_t **task_frame, 530b57cec5SDimitry Andric ompt_data_t **parallel_data, int *thread_num); 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric ompt_data_t *__ompt_get_thread_data_internal(); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric /* 580b57cec5SDimitry Andric * Unused currently 590b57cec5SDimitry Andric static uint64_t __ompt_get_get_unique_id_internal(); 600b57cec5SDimitry Andric */ 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric ompt_sync_region_t __ompt_get_barrier_kind(enum barrier_type, kmp_info_t *); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric /***************************************************************************** 650b57cec5SDimitry Andric * macros 660b57cec5SDimitry Andric ****************************************************************************/ 670b57cec5SDimitry Andric 6806c3fb27SDimitry Andric #define OMPT_CUR_TASK_INFO(thr) (&((thr)->th.th_current_task->ompt_task_info)) 690b57cec5SDimitry Andric #define OMPT_CUR_TASK_DATA(thr) \ 7006c3fb27SDimitry Andric (&((thr)->th.th_current_task->ompt_task_info.task_data)) 7106c3fb27SDimitry Andric #define OMPT_CUR_TEAM_INFO(thr) (&((thr)->th.th_team->t.ompt_team_info)) 720b57cec5SDimitry Andric #define OMPT_CUR_TEAM_DATA(thr) \ 7306c3fb27SDimitry Andric (&((thr)->th.th_team->t.ompt_team_info.parallel_data)) 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric #define OMPT_HAVE_WEAK_ATTRIBUTE KMP_HAVE_WEAK_ATTRIBUTE 760b57cec5SDimitry Andric #define OMPT_HAVE_PSAPI KMP_HAVE_PSAPI 770b57cec5SDimitry Andric #define OMPT_STR_MATCH(haystack, needle) __kmp_str_match(haystack, 0, needle) 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric inline void *__ompt_load_return_address(int gtid) { 800b57cec5SDimitry Andric kmp_info_t *thr = __kmp_threads[gtid]; 810b57cec5SDimitry Andric void *return_address = thr->th.ompt_thread_info.return_address; 820b57cec5SDimitry Andric thr->th.ompt_thread_info.return_address = NULL; 830b57cec5SDimitry Andric return return_address; 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 86e8d8bef9SDimitry Andric /*#define OMPT_STORE_RETURN_ADDRESS(gtid) \ 870b57cec5SDimitry Andric if (ompt_enabled.enabled && gtid >= 0 && __kmp_threads[gtid] && \ 880b57cec5SDimitry Andric !__kmp_threads[gtid]->th.ompt_thread_info.return_address) \ 890b57cec5SDimitry Andric __kmp_threads[gtid]->th.ompt_thread_info.return_address = \ 90e8d8bef9SDimitry Andric __builtin_return_address(0)*/ 91e8d8bef9SDimitry Andric #define OMPT_STORE_RETURN_ADDRESS(gtid) \ 92e8d8bef9SDimitry Andric OmptReturnAddressGuard ReturnAddressGuard{gtid, __builtin_return_address(0)}; 930b57cec5SDimitry Andric #define OMPT_LOAD_RETURN_ADDRESS(gtid) __ompt_load_return_address(gtid) 94e8d8bef9SDimitry Andric #define OMPT_LOAD_OR_GET_RETURN_ADDRESS(gtid) \ 95e8d8bef9SDimitry Andric ((ompt_enabled.enabled && gtid >= 0 && __kmp_threads[gtid] && \ 96fe6060f1SDimitry Andric __kmp_threads[gtid]->th.ompt_thread_info.return_address) \ 97fe6060f1SDimitry Andric ? __ompt_load_return_address(gtid) \ 98fe6060f1SDimitry Andric : __builtin_return_address(0)) 990b57cec5SDimitry Andric 10081ad6265SDimitry Andric #define OMPT_GET_DISPATCH_CHUNK(chunk, lb, ub, incr) \ 10181ad6265SDimitry Andric do { \ 10281ad6265SDimitry Andric if (incr > 0) { \ 10381ad6265SDimitry Andric chunk.start = static_cast<uint64_t>(lb); \ 10481ad6265SDimitry Andric chunk.iterations = static_cast<uint64_t>(((ub) - (lb)) / (incr) + 1); \ 10581ad6265SDimitry Andric } else { \ 10681ad6265SDimitry Andric chunk.start = static_cast<uint64_t>(ub); \ 10781ad6265SDimitry Andric chunk.iterations = static_cast<uint64_t>(((lb) - (ub)) / -(incr) + 1); \ 10881ad6265SDimitry Andric } \ 10981ad6265SDimitry Andric } while (0) 11081ad6265SDimitry Andric 1110b57cec5SDimitry Andric //****************************************************************************** 1120b57cec5SDimitry Andric // inline functions 1130b57cec5SDimitry Andric //****************************************************************************** 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric inline kmp_info_t *ompt_get_thread_gtid(int gtid) { 1160b57cec5SDimitry Andric return (gtid >= 0) ? __kmp_thread_from_gtid(gtid) : NULL; 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric inline kmp_info_t *ompt_get_thread() { 1200b57cec5SDimitry Andric int gtid = __kmp_get_gtid(); 1210b57cec5SDimitry Andric return ompt_get_thread_gtid(gtid); 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric inline void ompt_set_thread_state(kmp_info_t *thread, ompt_state_t state) { 125fe6060f1SDimitry Andric if (thread) 1260b57cec5SDimitry Andric thread->th.ompt_thread_info.state = state; 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric inline const char *ompt_get_runtime_version() { 1300b57cec5SDimitry Andric return &__kmp_version_lib_ver[KMP_VERSION_MAGIC_LEN]; 1310b57cec5SDimitry Andric } 132e8d8bef9SDimitry Andric 133*0fca6ea1SDimitry Andric inline ompt_work_t ompt_get_work_schedule(enum sched_type schedule) { 134*0fca6ea1SDimitry Andric switch (SCHEDULE_WITHOUT_MODIFIERS(schedule)) { 135*0fca6ea1SDimitry Andric case kmp_sch_static_chunked: 136*0fca6ea1SDimitry Andric case kmp_sch_static_balanced: 137*0fca6ea1SDimitry Andric case kmp_sch_static_greedy: 138*0fca6ea1SDimitry Andric return ompt_work_loop_static; 139*0fca6ea1SDimitry Andric case kmp_sch_dynamic_chunked: 140*0fca6ea1SDimitry Andric case kmp_sch_static_steal: 141*0fca6ea1SDimitry Andric return ompt_work_loop_dynamic; 142*0fca6ea1SDimitry Andric case kmp_sch_guided_iterative_chunked: 143*0fca6ea1SDimitry Andric case kmp_sch_guided_analytical_chunked: 144*0fca6ea1SDimitry Andric case kmp_sch_guided_chunked: 145*0fca6ea1SDimitry Andric case kmp_sch_guided_simd: 146*0fca6ea1SDimitry Andric return ompt_work_loop_guided; 147*0fca6ea1SDimitry Andric default: 148*0fca6ea1SDimitry Andric return ompt_work_loop_other; 149*0fca6ea1SDimitry Andric } 150*0fca6ea1SDimitry Andric } 151*0fca6ea1SDimitry Andric 152e8d8bef9SDimitry Andric class OmptReturnAddressGuard { 153e8d8bef9SDimitry Andric private: 154e8d8bef9SDimitry Andric bool SetAddress{false}; 155e8d8bef9SDimitry Andric int Gtid; 156e8d8bef9SDimitry Andric 157e8d8bef9SDimitry Andric public: 158e8d8bef9SDimitry Andric OmptReturnAddressGuard(int Gtid, void *ReturnAddress) : Gtid(Gtid) { 159e8d8bef9SDimitry Andric if (ompt_enabled.enabled && Gtid >= 0 && __kmp_threads[Gtid] && 160e8d8bef9SDimitry Andric !__kmp_threads[Gtid]->th.ompt_thread_info.return_address) { 161e8d8bef9SDimitry Andric SetAddress = true; 162e8d8bef9SDimitry Andric __kmp_threads[Gtid]->th.ompt_thread_info.return_address = ReturnAddress; 163e8d8bef9SDimitry Andric } 164e8d8bef9SDimitry Andric } 165e8d8bef9SDimitry Andric ~OmptReturnAddressGuard() { 166e8d8bef9SDimitry Andric if (SetAddress) 167e8d8bef9SDimitry Andric __kmp_threads[Gtid]->th.ompt_thread_info.return_address = NULL; 168e8d8bef9SDimitry Andric } 169e8d8bef9SDimitry Andric }; 170e8d8bef9SDimitry Andric 1715ffd83dbSDimitry Andric #endif // OMPT_SUPPORT 172480093f4SDimitry Andric 173480093f4SDimitry Andric // macros providing the OMPT callbacks for reduction clause 174480093f4SDimitry Andric #if OMPT_SUPPORT && OMPT_OPTIONAL 175480093f4SDimitry Andric #define OMPT_REDUCTION_DECL(this_thr, gtid) \ 176480093f4SDimitry Andric ompt_data_t *my_task_data = OMPT_CUR_TASK_DATA(this_thr); \ 177480093f4SDimitry Andric ompt_data_t *my_parallel_data = OMPT_CUR_TEAM_DATA(this_thr); \ 178480093f4SDimitry Andric void *return_address = OMPT_LOAD_RETURN_ADDRESS(gtid); 179480093f4SDimitry Andric #define OMPT_REDUCTION_BEGIN \ 180480093f4SDimitry Andric if (ompt_enabled.enabled && ompt_enabled.ompt_callback_reduction) { \ 181480093f4SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_reduction)( \ 182480093f4SDimitry Andric ompt_sync_region_reduction, ompt_scope_begin, my_parallel_data, \ 183480093f4SDimitry Andric my_task_data, return_address); \ 184480093f4SDimitry Andric } 185480093f4SDimitry Andric #define OMPT_REDUCTION_END \ 186480093f4SDimitry Andric if (ompt_enabled.enabled && ompt_enabled.ompt_callback_reduction) { \ 187480093f4SDimitry Andric ompt_callbacks.ompt_callback(ompt_callback_reduction)( \ 188480093f4SDimitry Andric ompt_sync_region_reduction, ompt_scope_end, my_parallel_data, \ 189480093f4SDimitry Andric my_task_data, return_address); \ 190480093f4SDimitry Andric } 191480093f4SDimitry Andric #else // OMPT_SUPPORT && OMPT_OPTIONAL 192480093f4SDimitry Andric #define OMPT_REDUCTION_DECL(this_thr, gtid) 193480093f4SDimitry Andric #define OMPT_REDUCTION_BEGIN 194480093f4SDimitry Andric #define OMPT_REDUCTION_END 195480093f4SDimitry Andric #endif // ! OMPT_SUPPORT && OMPT_OPTIONAL 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric #endif 198