diff options
Diffstat (limited to 'openmp/runtime/src/ompt-general.cpp')
| -rw-r--r-- | openmp/runtime/src/ompt-general.cpp | 401 |
1 files changed, 315 insertions, 86 deletions
diff --git a/openmp/runtime/src/ompt-general.cpp b/openmp/runtime/src/ompt-general.cpp index fa66d9cae5d..a6f0647b78e 100644 --- a/openmp/runtime/src/ompt-general.cpp +++ b/openmp/runtime/src/ompt-general.cpp @@ -8,6 +8,9 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#if KMP_OS_UNIX +#include <dlfcn.h> +#endif /***************************************************************************** * ompt include files @@ -36,8 +39,13 @@ typedef struct { const char *state_name; - ompt_state_t state_id; -} ompt_state_info_t; + omp_state_t state_id; +} omp_state_info_t; + +typedef struct { + const char *name; + ompt_mutex_impl_t id; +} ompt_mutex_impl_info_t; enum tool_setting_e { omp_tool_error, @@ -46,25 +54,27 @@ enum tool_setting_e { omp_tool_enabled }; -typedef void (*ompt_initialize_t)(ompt_function_lookup_t ompt_fn_lookup, - const char *version, - unsigned int ompt_version); - /***************************************************************************** * global variables ****************************************************************************/ -int ompt_enabled = 0; +ompt_callbacks_active_t ompt_enabled; + +omp_state_info_t omp_state_info[] = { +#define omp_state_macro(state, code) {#state, state}, + FOREACH_OMP_STATE(omp_state_macro) +#undef omp_state_macro +}; -ompt_state_info_t ompt_state_info[] = { -#define ompt_state_macro(state, code) {#state, state}, - FOREACH_OMPT_STATE(ompt_state_macro) -#undef ompt_state_macro +ompt_mutex_impl_info_t ompt_mutex_impl_info[] = { +#define ompt_mutex_impl_macro(name, id) {#name, name}, + FOREACH_OMPT_MUTEX_IMPL(ompt_mutex_impl_macro) +#undef ompt_mutex_impl_macro }; -ompt_callbacks_t ompt_callbacks; +ompt_callbacks_internal_t ompt_callbacks; -static ompt_initialize_t ompt_initialize_fn = NULL; +static ompt_fns_t *ompt_fns = NULL; /***************************************************************************** * forward declarations @@ -72,48 +82,71 @@ static ompt_initialize_t ompt_initialize_fn = NULL; static ompt_interface_fn_t ompt_fn_lookup(const char *s); -OMPT_API_ROUTINE ompt_thread_id_t ompt_get_thread_id(void); +OMPT_API_ROUTINE ompt_data_t *ompt_get_thread_data(void); /***************************************************************************** * initialization and finalization (private operations) ****************************************************************************/ /* On Unix-like systems that support weak symbols the following implementation - * of ompt_tool() will be used in case no tool-supplied implementation of + * of ompt_start_tool() will be used in case no tool-supplied implementation of * this function is present in the address space of a process. * * On Windows, the ompt_tool_windows function is used to find the * ompt_tool symbol across all modules loaded by a process. If ompt_tool is * found, ompt_tool's return value is used to initialize the tool. Otherwise, * NULL is returned and OMPT won't be enabled */ + +typedef ompt_fns_t *(*ompt_start_tool_t)(unsigned int, const char *); + +#if KMP_OS_UNIX + #if OMPT_HAVE_WEAK_ATTRIBUTE +_OMP_EXTERN __attribute__((weak)) +#elif defined KMP_DYNAMIC_LIB _OMP_EXTERN -__attribute__((weak)) ompt_initialize_t ompt_tool() { +#warning Activation of OMPT is might fail for tools statically linked into the application. +#else +#error Activation of OMPT is not supported on this platform. +#endif +ompt_fns_t * +ompt_start_tool(unsigned int omp_version, const char *runtime_version) { +#ifdef KMP_DYNAMIC_LIB + ompt_fns_t *ret = NULL; + // Try next symbol in the address space + ompt_start_tool_t next_tool = NULL; + next_tool = (ompt_start_tool_t)dlsym(RTLD_NEXT, "ompt_start_tool"); + if (next_tool) + ret = (next_tool)(omp_version, runtime_version); + return ret; +#else #if OMPT_DEBUG - printf("ompt_tool() is called from the RTL\n"); + printf("ompt_start_tool() is called from the RTL\n"); #endif return NULL; +#endif } #elif OMPT_HAVE_PSAPI #include <psapi.h> #pragma comment(lib, "psapi.lib") -#define ompt_tool ompt_tool_windows +#define ompt_start_tool ompt_tool_windows // The number of loaded modules to start enumeration with EnumProcessModules() #define NUM_MODULES 128 -static ompt_initialize_t ompt_tool_windows() { +static ompt_fns_t *ompt_tool_windows(unsigned int omp_version, + const char *runtime_version) { int i; DWORD needed, new_size; HMODULE *modules; HANDLE process = GetCurrentProcess(); modules = (HMODULE *)malloc(NUM_MODULES * sizeof(HMODULE)); - ompt_initialize_t (*ompt_tool_p)() = NULL; + ompt_start_tool_t ompt_tool_p = NULL; #if OMPT_DEBUG - printf("ompt_tool_windows(): looking for ompt_tool\n"); + printf("ompt_tool_windows(): looking for ompt_start_tool\n"); #endif if (!EnumProcessModules(process, modules, NUM_MODULES * sizeof(HMODULE), &needed)) { @@ -135,21 +168,22 @@ static ompt_initialize_t ompt_tool_windows() { } } for (i = 0; i < new_size; ++i) { - (FARPROC &)ompt_tool_p = GetProcAddress(modules[i], "ompt_tool"); + (FARPROC &)ompt_tool_p = GetProcAddress(modules[i], "ompt_start_tool"); if (ompt_tool_p) { #if OMPT_DEBUG TCHAR modName[MAX_PATH]; if (GetModuleFileName(modules[i], modName, MAX_PATH)) - printf("ompt_tool_windows(): ompt_tool found in module %s\n", modName); + printf("ompt_tool_windows(): ompt_start_tool found in module %s\n", + modName); #endif free(modules); - return ompt_tool_p(); + return (*ompt_tool_p)(omp_version, runtime_version); } #if OMPT_DEBUG else { TCHAR modName[MAX_PATH]; if (GetModuleFileName(modules[i], modName, MAX_PATH)) - printf("ompt_tool_windows(): ompt_tool not found in module %s\n", + printf("ompt_tool_windows(): ompt_start_tool not found in module %s\n", modName); } #endif @@ -161,6 +195,49 @@ static ompt_initialize_t ompt_tool_windows() { #error Either __attribute__((weak)) or psapi.dll are required for OMPT support #endif // OMPT_HAVE_WEAK_ATTRIBUTE +static ompt_fns_t *ompt_try_start_tool(unsigned int omp_version, + const char *runtime_version) { + ompt_fns_t *ret = NULL; + ompt_start_tool_t start_tool = NULL; +#if KMP_OS_WINDOWS + // Cannot use colon to describe a list of absolute paths on Windows + const char *sep = ";"; +#else + const char *sep = ":"; +#endif + + // Try in the current address space + if ((ret = ompt_start_tool(omp_version, runtime_version))) + return ret; + + // Try tool-libraries-var ICV + const char *tool_libs = getenv("OMP_TOOL_LIBRARIES"); + if (tool_libs) { + const char *libs = __kmp_str_format("%s", tool_libs); + char *buf; + char *fname = __kmp_str_token(CCAST(char *, libs), sep, &buf); + while (fname) { +#if KMP_OS_UNIX + void *h = dlopen(fname, RTLD_LAZY); + if (h) { + start_tool = (ompt_start_tool_t)dlsym(h, "ompt_start_tool"); +#elif KMP_OS_WINDOWS + HMODULE h = LoadLibrary(fname); + if (h) { + start_tool = (ompt_start_tool_t)GetProcAddress(h, "ompt_start_tool"); +#else +#error Activation of OMPT is not supported on this platform. +#endif + if (start_tool && (ret = (*start_tool)(omp_version, runtime_version))) + break; + } + fname = __kmp_str_token(NULL, sep, &buf); + } + __kmp_str_free(&libs); + } + return ret; +} + void ompt_pre_init() { //-------------------------------------------------- // Execute the pre-initialization logic only once. @@ -194,10 +271,14 @@ void ompt_pre_init() { case omp_tool_unset: case omp_tool_enabled: - ompt_initialize_fn = ompt_tool(); - if (ompt_initialize_fn) { - ompt_enabled = 1; - } + + //-------------------------------------------------- + // Load tool iff specified in environment variable + //-------------------------------------------------- + ompt_fns = + ompt_try_start_tool(__kmp_openmp_version, ompt_get_runtime_version()); + + memset(&ompt_enabled, 0, sizeof(ompt_enabled)); break; case omp_tool_error: @@ -226,31 +307,34 @@ void ompt_post_init() { //-------------------------------------------------- // Initialize the tool if so indicated. //-------------------------------------------------- - if (ompt_enabled) { - ompt_initialize_fn(ompt_fn_lookup, ompt_get_runtime_version(), - OMPT_VERSION); + if (ompt_fns) { + ompt_enabled.enabled = !!ompt_fns->initialize(ompt_fn_lookup, ompt_fns); ompt_thread_t *root_thread = ompt_get_thread(); - ompt_set_thread_state(root_thread, ompt_state_overhead); + ompt_set_thread_state(root_thread, omp_state_overhead); - if (ompt_callbacks.ompt_callback(ompt_event_thread_begin)) { - ompt_callbacks.ompt_callback(ompt_event_thread_begin)( - ompt_thread_initial, ompt_get_thread_id()); + if (ompt_enabled.ompt_callback_thread_begin) { + ompt_callbacks.ompt_callback(ompt_callback_thread_begin)( + ompt_thread_initial, __ompt_get_thread_data_internal()); + } + ompt_data_t *task_data; + __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL, NULL); + if (ompt_enabled.ompt_callback_task_create) { + ompt_callbacks.ompt_callback(ompt_callback_task_create)( + NULL, NULL, task_data, ompt_task_initial, 0, NULL); } - ompt_set_thread_state(root_thread, ompt_state_work_serial); + ompt_set_thread_state(root_thread, omp_state_work_serial); } } void ompt_fini() { - if (ompt_enabled) { - if (ompt_callbacks.ompt_callback(ompt_event_runtime_shutdown)) { - ompt_callbacks.ompt_callback(ompt_event_runtime_shutdown)(); - } + if (ompt_enabled.enabled) { + ompt_fns->finalize(ompt_fns); } - ompt_enabled = 0; + memset(&ompt_enabled, 0, sizeof(ompt_enabled)); } /***************************************************************************** @@ -261,15 +345,15 @@ void ompt_fini() { * state ****************************************************************************/ -OMPT_API_ROUTINE int ompt_enumerate_state(int current_state, int *next_state, - const char **next_state_name) { - const static int len = sizeof(ompt_state_info) / sizeof(ompt_state_info_t); +OMPT_API_ROUTINE int ompt_enumerate_states(int current_state, int *next_state, + const char **next_state_name) { + const static int len = sizeof(omp_state_info) / sizeof(omp_state_info_t); int i = 0; for (i = 0; i < len - 1; i++) { - if (ompt_state_info[i].state_id == current_state) { - *next_state = ompt_state_info[i + 1].state_id; - *next_state_name = ompt_state_info[i + 1].state_name; + if (omp_state_info[i].state_id == current_state) { + *next_state = omp_state_info[i + 1].state_id; + *next_state_name = omp_state_info[i + 1].state_name; return 1; } } @@ -277,17 +361,35 @@ OMPT_API_ROUTINE int ompt_enumerate_state(int current_state, int *next_state, return 0; } +OMPT_API_ROUTINE int ompt_enumerate_mutex_impls(int current_impl, + int *next_impl, + const char **next_impl_name) { + const static int len = + sizeof(ompt_mutex_impl_info) / sizeof(ompt_mutex_impl_info_t); + int i = 0; + for (i = 0; i < len - 1; i++) { + if (ompt_mutex_impl_info[i].id != current_impl) + continue; + *next_impl = ompt_mutex_impl_info[i + 1].id; + *next_impl_name = ompt_mutex_impl_info[i + 1].name; + return 1; + } + return 0; +} + /***************************************************************************** * callbacks ****************************************************************************/ -OMPT_API_ROUTINE int ompt_set_callback(ompt_event_t evid, ompt_callback_t cb) { - switch (evid) { +OMPT_API_ROUTINE int ompt_set_callback(ompt_callbacks_t which, + ompt_callback_t callback) { + switch (which) { #define ompt_event_macro(event_name, callback_type, event_id) \ case event_name: \ if (ompt_event_implementation_status(event_name)) { \ - ompt_callbacks.ompt_callback(event_name) = (callback_type)cb; \ + ompt_callbacks.ompt_callback(event_name) = (callback_type)callback; \ + ompt_enabled.event_name = 1; \ } \ return ompt_event_implementation_status(event_name); @@ -296,12 +398,13 @@ OMPT_API_ROUTINE int ompt_set_callback(ompt_event_t evid, ompt_callback_t cb) { #undef ompt_event_macro default: - return ompt_set_result_registration_error; + return ompt_set_error; } } -OMPT_API_ROUTINE int ompt_get_callback(ompt_event_t evid, ompt_callback_t *cb) { - switch (evid) { +OMPT_API_ROUTINE int ompt_get_callback(ompt_callbacks_t which, + ompt_callback_t *callback) { + switch (which) { #define ompt_event_macro(event_name, callback_type, event_id) \ case event_name: \ @@ -309,7 +412,7 @@ OMPT_API_ROUTINE int ompt_get_callback(ompt_event_t evid, ompt_callback_t *cb) { ompt_callback_t mycb = \ (ompt_callback_t)ompt_callbacks.ompt_callback(event_name); \ if (mycb) { \ - *cb = mycb; \ + *callback = mycb; \ return ompt_get_callback_success; \ } \ } \ @@ -328,54 +431,149 @@ OMPT_API_ROUTINE int ompt_get_callback(ompt_event_t evid, ompt_callback_t *cb) { * parallel regions ****************************************************************************/ -OMPT_API_ROUTINE ompt_parallel_id_t ompt_get_parallel_id(int ancestor_level) { - return __ompt_get_parallel_id_internal(ancestor_level); -} - -OMPT_API_ROUTINE int ompt_get_parallel_team_size(int ancestor_level) { - return __ompt_get_parallel_team_size_internal(ancestor_level); -} - -OMPT_API_ROUTINE void *ompt_get_parallel_function(int ancestor_level) { - return __ompt_get_parallel_function_internal(ancestor_level); +OMPT_API_ROUTINE int ompt_get_parallel_info(int ancestor_level, + ompt_data_t **parallel_data, + int *team_size) { + return __ompt_get_parallel_info_internal(ancestor_level, parallel_data, + team_size); } -OMPT_API_ROUTINE ompt_state_t ompt_get_state(ompt_wait_id_t *ompt_wait_id) { - ompt_state_t thread_state = __ompt_get_state_internal(ompt_wait_id); +OMPT_API_ROUTINE omp_state_t ompt_get_state(ompt_wait_id_t *wait_id) { + omp_state_t thread_state = __ompt_get_state_internal(wait_id); - if (thread_state == ompt_state_undefined) { - thread_state = ompt_state_work_serial; + if (thread_state == omp_state_undefined) { + thread_state = omp_state_work_serial; } return thread_state; } /***************************************************************************** - * threads + * tasks ****************************************************************************/ -OMPT_API_ROUTINE void *ompt_get_idle_frame() { - return __ompt_get_idle_frame_internal(); +OMPT_API_ROUTINE ompt_data_t *ompt_get_thread_data(void) { + return __ompt_get_thread_data_internal(); +} + +OMPT_API_ROUTINE int ompt_get_task_info(int ancestor_level, int *type, + ompt_data_t **task_data, + ompt_frame_t **task_frame, + ompt_data_t **parallel_data, + int *thread_num) { + return __ompt_get_task_info_internal(ancestor_level, type, task_data, + task_frame, parallel_data, thread_num); } /***************************************************************************** - * tasks + * places ****************************************************************************/ -OMPT_API_ROUTINE ompt_thread_id_t ompt_get_thread_id(void) { - return __ompt_get_thread_id_internal(); +OMPT_API_ROUTINE int ompt_get_num_places(void) { +// copied from kmp_ftn_entry.h (but modified) +#if !KMP_AFFINITY_SUPPORTED + return 0; +#else + if (!KMP_AFFINITY_CAPABLE()) + return 0; + return __kmp_affinity_num_masks; +#endif +} + +OMPT_API_ROUTINE int ompt_get_place_proc_ids(int place_num, int ids_size, + int *ids) { +// copied from kmp_ftn_entry.h (but modified) +#if !KMP_AFFINITY_SUPPORTED + return 0; +#else + int i, count; + int tmp_ids[ids_size]; + if (!KMP_AFFINITY_CAPABLE()) + return 0; + if (place_num < 0 || place_num >= (int)__kmp_affinity_num_masks) + return 0; + /* TODO: Is this safe for asynchronous call from signal handler during runtime + * shutdown? */ + kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num); + count = 0; + KMP_CPU_SET_ITERATE(i, mask) { + if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) || + (!KMP_CPU_ISSET(i, mask))) { + continue; + } + if (count < ids_size) + tmp_ids[count] = i; + count++; + } + if (ids_size >= count) { + for (i = 0; i < count; i++) { + ids[i] = tmp_ids[i]; + } + } + return count; +#endif } -OMPT_API_ROUTINE ompt_task_id_t ompt_get_task_id(int depth) { - return __ompt_get_task_id_internal(depth); +OMPT_API_ROUTINE int ompt_get_place_num(void) { +// copied from kmp_ftn_entry.h (but modified) +#if !KMP_AFFINITY_SUPPORTED + return -1; +#else + int gtid; + kmp_info_t *thread; + if (!KMP_AFFINITY_CAPABLE()) + return -1; + gtid = __kmp_entry_gtid(); + thread = __kmp_thread_from_gtid(gtid); + if (thread == NULL || thread->th.th_current_place < 0) + return -1; + return thread->th.th_current_place; +#endif } -OMPT_API_ROUTINE ompt_frame_t *ompt_get_task_frame(int depth) { - return __ompt_get_task_frame_internal(depth); +OMPT_API_ROUTINE int ompt_get_partition_place_nums(int place_nums_size, + int *place_nums) { +// copied from kmp_ftn_entry.h (but modified) +#if !KMP_AFFINITY_SUPPORTED + return 0; +#else + int i, gtid, place_num, first_place, last_place, start, end; + kmp_info_t *thread; + if (!KMP_AFFINITY_CAPABLE()) + return 0; + gtid = __kmp_entry_gtid(); + thread = __kmp_thread_from_gtid(gtid); + if (thread == NULL) + return 0; + first_place = thread->th.th_first_place; + last_place = thread->th.th_last_place; + if (first_place < 0 || last_place < 0) + return 0; + if (first_place <= last_place) { + start = first_place; + end = last_place; + } else { + start = last_place; + end = first_place; + } + if (end - start <= place_nums_size) + for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) { + place_nums[i] = place_num; + } + return end - start; +#endif } -OMPT_API_ROUTINE void *ompt_get_task_function(int depth) { - return __ompt_get_task_function_internal(depth); +/***************************************************************************** + * places + ****************************************************************************/ + +OMPT_API_ROUTINE int ompt_get_proc_id(void) { +#if KMP_OS_LINUX + return sched_getcpu(); +#else + return -1; +#endif } /***************************************************************************** @@ -435,28 +633,59 @@ OMPT_API_PLACEHOLDER void ompt_mutex_wait(void) { OMPT_API_ROUTINE int ompt_get_ompt_version() { return OMPT_VERSION; } /***************************************************************************** - * application-facing API +* application-facing API ****************************************************************************/ /*---------------------------------------------------------------------------- | control ---------------------------------------------------------------------------*/ -_OMP_EXTERN void ompt_control(uint64_t command, uint64_t modifier) { - if (ompt_enabled && ompt_callbacks.ompt_callback(ompt_event_control)) { - ompt_callbacks.ompt_callback(ompt_event_control)(command, modifier); +int __kmp_control_tool(uint64_t command, uint64_t modifier, void *arg) { + + if (ompt_enabled.enabled) { + if (ompt_enabled.ompt_callback_control_tool) { + return ompt_callbacks.ompt_callback(ompt_callback_control_tool)( + command, modifier, arg, OMPT_LOAD_RETURN_ADDRESS(__kmp_entry_gtid())); + } else { + return -1; + } + } else { + return -2; } } /***************************************************************************** + * misc + ****************************************************************************/ + +OMPT_API_ROUTINE uint64_t ompt_get_unique_id(void) { + return __ompt_get_unique_id_internal(); +} + +/***************************************************************************** + * Target + ****************************************************************************/ + +OMPT_API_ROUTINE int ompt_get_target_info(uint64_t *device_num, + ompt_id_t *target_id, + ompt_id_t *host_op_id) { + return 0; // thread is not in a target region +} + +OMPT_API_ROUTINE int ompt_get_num_devices(void) { + return 1; // only one device (the current device) is available +} + +/***************************************************************************** * API inquiry for tool ****************************************************************************/ static ompt_interface_fn_t ompt_fn_lookup(const char *s) { #define ompt_interface_fn(fn) \ + fn##_t fn##_f = fn; \ if (strcmp(s, #fn) == 0) \ - return (ompt_interface_fn_t)fn; + return (ompt_interface_fn_t)fn##_f; FOREACH_OMPT_INQUIRY_FN(ompt_interface_fn) |

