19 #include "ompt-specific.cpp" 25 #define ompt_get_callback_success 1 26 #define ompt_get_callback_failure 0 28 #define no_tool_present 0 30 #define OMPT_API_ROUTINE static 32 #ifndef OMPT_STR_MATCH 33 #define OMPT_STR_MATCH(haystack, needle) (!strcasecmp(haystack, needle)) 41 const char *state_name;
48 } ompt_mutex_impl_info_t;
61 ompt_callbacks_active_t ompt_enabled;
63 omp_state_info_t omp_state_info[] = {
64 #define omp_state_macro(state, code) {#state, state}, 65 FOREACH_OMP_STATE(omp_state_macro)
66 #undef omp_state_macro 69 ompt_mutex_impl_info_t ompt_mutex_impl_info[] = {
70 #define ompt_mutex_impl_macro(name, id) {#name, name}, 71 FOREACH_OMPT_MUTEX_IMPL(ompt_mutex_impl_macro)
72 #undef ompt_mutex_impl_macro 75 ompt_callbacks_internal_t ompt_callbacks;
77 static ompt_start_tool_result_t *ompt_start_tool_result = NULL;
83 static ompt_interface_fn_t ompt_fn_lookup(
const char *s);
85 OMPT_API_ROUTINE ompt_data_t *ompt_get_thread_data(
void);
91 typedef ompt_start_tool_result_t *(*ompt_start_tool_t)(
unsigned int,
105 static ompt_start_tool_result_t *ompt_tool_darwin(
unsigned int omp_version,
106 const char *runtime_version) {
107 ompt_start_tool_result_t *ret = NULL;
109 ompt_start_tool_t start_tool =
110 (ompt_start_tool_t)dlsym(RTLD_DEFAULT,
"ompt_start_tool");
112 ret = start_tool(omp_version, runtime_version);
117 #elif OMPT_HAVE_WEAK_ATTRIBUTE 123 _OMP_EXTERN OMPT_WEAK_ATTRIBUTE ompt_start_tool_result_t *
124 ompt_start_tool(
unsigned int omp_version,
const char *runtime_version) {
125 ompt_start_tool_result_t *ret = NULL;
130 ompt_start_tool_t next_tool =
131 (ompt_start_tool_t)dlsym(RTLD_NEXT,
"ompt_start_tool");
133 ret = next_tool(omp_version, runtime_version);
138 #elif OMPT_HAVE_PSAPI 146 #pragma comment(lib, "psapi.lib") 149 #define NUM_MODULES 128 151 static ompt_start_tool_result_t *
152 ompt_tool_windows(
unsigned int omp_version,
const char *runtime_version) {
154 DWORD needed, new_size;
156 HANDLE process = GetCurrentProcess();
157 modules = (HMODULE *)malloc(NUM_MODULES *
sizeof(HMODULE));
158 ompt_start_tool_t ompt_tool_p = NULL;
161 printf(
"ompt_tool_windows(): looking for ompt_start_tool\n");
163 if (!EnumProcessModules(process, modules, NUM_MODULES *
sizeof(HMODULE),
170 new_size = needed /
sizeof(HMODULE);
171 if (new_size > NUM_MODULES) {
173 printf(
"ompt_tool_windows(): resize buffer to %d bytes\n", needed);
175 modules = (HMODULE *)realloc(modules, needed);
177 if (!EnumProcessModules(process, modules, needed, &needed)) {
182 for (i = 0; i < new_size; ++i) {
183 (FARPROC &)ompt_tool_p = GetProcAddress(modules[i],
"ompt_start_tool");
186 TCHAR modName[MAX_PATH];
187 if (GetModuleFileName(modules[i], modName, MAX_PATH))
188 printf(
"ompt_tool_windows(): ompt_start_tool found in module %s\n",
192 return (*ompt_tool_p)(omp_version, runtime_version);
196 TCHAR modName[MAX_PATH];
197 if (GetModuleFileName(modules[i], modName, MAX_PATH))
198 printf(
"ompt_tool_windows(): ompt_start_tool not found in module %s\n",
207 #error Activation of OMPT is not supported on this platform. 210 static ompt_start_tool_result_t *
211 ompt_try_start_tool(
unsigned int omp_version,
const char *runtime_version) {
212 ompt_start_tool_result_t *ret = NULL;
213 ompt_start_tool_t start_tool = NULL;
216 const char *sep =
";";
218 const char *sep =
":";
223 ret = ompt_tool_darwin(omp_version, runtime_version);
224 #elif OMPT_HAVE_WEAK_ATTRIBUTE 225 ret = ompt_start_tool(omp_version, runtime_version);
226 #elif OMPT_HAVE_PSAPI 227 ret = ompt_tool_windows(omp_version, runtime_version);
229 #error Activation of OMPT is not supported on this platform. 235 const char *tool_libs = getenv(
"OMP_TOOL_LIBRARIES");
237 char *libs = __kmp_str_format(
"%s", tool_libs);
239 char *fname = __kmp_str_token(libs, sep, &buf);
242 void *h = dlopen(fname, RTLD_LAZY);
244 start_tool = (ompt_start_tool_t)dlsym(h,
"ompt_start_tool");
246 HMODULE h = LoadLibrary(fname);
248 start_tool = (ompt_start_tool_t)GetProcAddress(h,
"ompt_start_tool");
250 #error Activation of OMPT is not supported on this platform. 252 if (start_tool && (ret = (*start_tool)(omp_version, runtime_version)))
255 fname = __kmp_str_token(NULL, sep, &buf);
257 __kmp_str_free(&libs);
262 void ompt_pre_init() {
266 static int ompt_pre_initialized = 0;
268 if (ompt_pre_initialized)
271 ompt_pre_initialized = 1;
276 const char *ompt_env_var = getenv(
"OMP_TOOL");
277 tool_setting_e tool_setting = omp_tool_error;
279 if (!ompt_env_var || !strcmp(ompt_env_var,
""))
280 tool_setting = omp_tool_unset;
281 else if (OMPT_STR_MATCH(ompt_env_var,
"disabled"))
282 tool_setting = omp_tool_disabled;
283 else if (OMPT_STR_MATCH(ompt_env_var,
"enabled"))
284 tool_setting = omp_tool_enabled;
287 printf(
"ompt_pre_init(): tool_setting = %d\n", tool_setting);
289 switch (tool_setting) {
290 case omp_tool_disabled:
294 case omp_tool_enabled:
299 ompt_start_tool_result =
300 ompt_try_start_tool(__kmp_openmp_version, ompt_get_runtime_version());
302 memset(&ompt_enabled, 0,
sizeof(ompt_enabled));
306 fprintf(stderr,
"Warning: OMP_TOOL has invalid value \"%s\".\n" 307 " legal values are (NULL,\"\",\"disabled\"," 313 printf(
"ompt_pre_init(): ompt_enabled = %d\n", ompt_enabled);
317 void ompt_post_init() {
321 static int ompt_post_initialized = 0;
323 if (ompt_post_initialized)
326 ompt_post_initialized = 1;
331 if (ompt_start_tool_result) {
332 ompt_enabled.enabled = !!ompt_start_tool_result->initialize(
333 ompt_fn_lookup, &(ompt_start_tool_result->tool_data));
335 ompt_thread_t *root_thread = ompt_get_thread();
337 ompt_set_thread_state(root_thread, omp_state_overhead);
339 if (ompt_enabled.ompt_callback_thread_begin) {
340 ompt_callbacks.ompt_callback(ompt_callback_thread_begin)(
341 ompt_thread_initial, __ompt_get_thread_data_internal());
343 ompt_data_t *task_data;
344 __ompt_get_task_info_internal(0, NULL, &task_data, NULL, NULL, NULL);
345 if (ompt_enabled.ompt_callback_task_create) {
346 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
347 NULL, NULL, task_data, ompt_task_initial, 0, NULL);
350 ompt_set_thread_state(root_thread, omp_state_work_serial);
355 if (ompt_enabled.enabled) {
356 ompt_start_tool_result->finalize(&(ompt_start_tool_result->tool_data));
359 memset(&ompt_enabled, 0,
sizeof(ompt_enabled));
370 OMPT_API_ROUTINE
int ompt_enumerate_states(
int current_state,
int *next_state,
371 const char **next_state_name) {
372 const static int len =
sizeof(omp_state_info) /
sizeof(omp_state_info_t);
375 for (i = 0; i < len - 1; i++) {
376 if (omp_state_info[i].state_id == current_state) {
377 *next_state = omp_state_info[i + 1].state_id;
378 *next_state_name = omp_state_info[i + 1].state_name;
386 OMPT_API_ROUTINE
int ompt_enumerate_mutex_impls(
int current_impl,
388 const char **next_impl_name) {
389 const static int len =
390 sizeof(ompt_mutex_impl_info) /
sizeof(ompt_mutex_impl_info_t);
392 for (i = 0; i < len - 1; i++) {
393 if (ompt_mutex_impl_info[i].
id != current_impl)
395 *next_impl = ompt_mutex_impl_info[i + 1].id;
396 *next_impl_name = ompt_mutex_impl_info[i + 1].name;
406 OMPT_API_ROUTINE
int ompt_set_callback(ompt_callbacks_t which,
407 ompt_callback_t callback) {
410 #define ompt_event_macro(event_name, callback_type, event_id) \ 412 if (ompt_event_implementation_status(event_name)) { \ 413 ompt_callbacks.ompt_callback(event_name) = (callback_type)callback; \ 414 ompt_enabled.event_name = (callback != 0); \ 417 return ompt_event_implementation_status(event_name); \ 419 return ompt_set_always; 421 FOREACH_OMPT_EVENT(ompt_event_macro)
423 #undef ompt_event_macro 426 return ompt_set_error;
430 OMPT_API_ROUTINE
int ompt_get_callback(ompt_callbacks_t which,
431 ompt_callback_t *callback) {
434 #define ompt_event_macro(event_name, callback_type, event_id) \ 436 if (ompt_event_implementation_status(event_name)) { \ 437 ompt_callback_t mycb = \ 438 (ompt_callback_t)ompt_callbacks.ompt_callback(event_name); \ 441 return ompt_get_callback_success; \ 444 return ompt_get_callback_failure; 446 FOREACH_OMPT_EVENT(ompt_event_macro)
448 #undef ompt_event_macro 451 return ompt_get_callback_failure;
459 OMPT_API_ROUTINE
int ompt_get_parallel_info(
int ancestor_level,
460 ompt_data_t **parallel_data,
462 return __ompt_get_parallel_info_internal(ancestor_level, parallel_data,
466 OMPT_API_ROUTINE omp_state_t ompt_get_state(ompt_wait_id_t *wait_id) {
467 omp_state_t thread_state = __ompt_get_state_internal(wait_id);
469 if (thread_state == omp_state_undefined) {
470 thread_state = omp_state_work_serial;
480 OMPT_API_ROUTINE ompt_data_t *ompt_get_thread_data(
void) {
481 return __ompt_get_thread_data_internal();
484 OMPT_API_ROUTINE
int ompt_get_task_info(
int ancestor_level,
int *type,
485 ompt_data_t **task_data,
486 ompt_frame_t **task_frame,
487 ompt_data_t **parallel_data,
489 return __ompt_get_task_info_internal(ancestor_level, type, task_data,
490 task_frame, parallel_data, thread_num);
497 OMPT_API_ROUTINE
int ompt_get_num_procs(
void) {
499 return __kmp_avail_proc;
506 OMPT_API_ROUTINE
int ompt_get_num_places(
void) {
508 #if !KMP_AFFINITY_SUPPORTED 511 if (!KMP_AFFINITY_CAPABLE())
513 return __kmp_affinity_num_masks;
517 OMPT_API_ROUTINE
int ompt_get_place_proc_ids(
int place_num,
int ids_size,
520 #if !KMP_AFFINITY_SUPPORTED 524 int tmp_ids[ids_size];
525 if (!KMP_AFFINITY_CAPABLE())
527 if (place_num < 0 || place_num >= (
int)__kmp_affinity_num_masks)
531 kmp_affin_mask_t *mask = KMP_CPU_INDEX(__kmp_affinity_masks, place_num);
533 KMP_CPU_SET_ITERATE(i, mask) {
534 if ((!KMP_CPU_ISSET(i, __kmp_affin_fullMask)) ||
535 (!KMP_CPU_ISSET(i, mask))) {
538 if (count < ids_size)
542 if (ids_size >= count) {
543 for (i = 0; i < count; i++) {
551 OMPT_API_ROUTINE
int ompt_get_place_num(
void) {
553 #if !KMP_AFFINITY_SUPPORTED 558 if (!KMP_AFFINITY_CAPABLE())
560 gtid = __kmp_entry_gtid();
561 thread = __kmp_thread_from_gtid(gtid);
562 if (thread == NULL || thread->th.th_current_place < 0)
564 return thread->th.th_current_place;
568 OMPT_API_ROUTINE
int ompt_get_partition_place_nums(
int place_nums_size,
571 #if !KMP_AFFINITY_SUPPORTED 574 int i, gtid, place_num, first_place, last_place, start, end;
576 if (!KMP_AFFINITY_CAPABLE())
578 gtid = __kmp_entry_gtid();
579 thread = __kmp_thread_from_gtid(gtid);
582 first_place = thread->th.th_first_place;
583 last_place = thread->th.th_last_place;
584 if (first_place < 0 || last_place < 0)
586 if (first_place <= last_place) {
593 if (end - start <= place_nums_size)
594 for (i = 0, place_num = start; place_num <= end; ++place_num, ++i) {
595 place_nums[i] = place_num;
605 OMPT_API_ROUTINE
int ompt_get_proc_id(
void) {
607 return sched_getcpu();
617 OMPT_API_ROUTINE
int ompt_get_ompt_version() {
return OMPT_VERSION; }
627 int __kmp_control_tool(uint64_t command, uint64_t modifier,
void *arg) {
629 if (ompt_enabled.enabled) {
630 if (ompt_enabled.ompt_callback_control_tool) {
631 return ompt_callbacks.ompt_callback(ompt_callback_control_tool)(
632 command, modifier, arg, OMPT_LOAD_RETURN_ADDRESS(__kmp_entry_gtid()));
645 OMPT_API_ROUTINE uint64_t ompt_get_unique_id(
void) {
646 return __ompt_get_unique_id_internal();
653 OMPT_API_ROUTINE
int ompt_get_target_info(uint64_t *device_num,
654 ompt_id_t *target_id,
655 ompt_id_t *host_op_id) {
659 OMPT_API_ROUTINE
int ompt_get_num_devices(
void) {
667 static ompt_interface_fn_t ompt_fn_lookup(
const char *s) {
669 #define ompt_interface_fn(fn) \ 670 fn##_t fn##_f = fn; \ 671 if (strcmp(s, #fn) == 0) \ 672 return (ompt_interface_fn_t)fn##_f; 674 FOREACH_OMPT_INQUIRY_FN(ompt_interface_fn)
676 return (ompt_interface_fn_t)0;