From ea9e2d9d8609eada71a783e35901b2b9c709d922 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Thu, 21 May 2015 17:24:43 -0700 Subject: [PATCH 01/46] Init ompd, store offset and size information for ompd, implemented OMPD_STATE to activate state tracking for ompd --- runtime/src/kmp_runtime.c | 12 +++++++ runtime/src/makefile.mk | 8 +++++ runtime/src/ompd-specific.c | 46 ++++++++++++++++++++++++ runtime/src/ompd-specific.h | 72 +++++++++++++++++++++++++++++++++++++ runtime/src/ompt-general.c | 10 ++++++ runtime/tools/build.pl | 6 ++-- 6 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 runtime/src/ompd-specific.c create mode 100644 runtime/src/ompd-specific.h diff --git a/runtime/src/kmp_runtime.c b/runtime/src/kmp_runtime.c index 3fdbf0758..7eea02eba 100644 --- a/runtime/src/kmp_runtime.c +++ b/runtime/src/kmp_runtime.c @@ -29,6 +29,9 @@ #if OMPT_SUPPORT #include "ompt-specific.h" #endif +#if OMPD_SUPPORT +#include "ompd-specific.h" +#endif /* these are temporary issues to be dealt with */ #define KMP_USE_PRCTL 0 @@ -6565,6 +6568,9 @@ __kmp_do_serial_initialize( void ) #if OMPT_SUPPORT ompt_init(); #endif +#if OMPD_SUPPORT + ompd_init(); +#endif } void @@ -6712,6 +6718,9 @@ __kmp_middle_initialize( void ) #if OMPT_SUPPORT ompt_init(); #endif +#if OMPD_SUPPORT + ompd_init(); +#endif } void @@ -6784,6 +6793,9 @@ __kmp_parallel_initialize( void ) #if OMPT_SUPPORT ompt_init(); #endif +#if OMPD_SUPPORT + ompd_init(); +#endif } diff --git a/runtime/src/makefile.mk b/runtime/src/makefile.mk index 1d1b9aa69..bb9bf5bfe 100644 --- a/runtime/src/makefile.mk +++ b/runtime/src/makefile.mk @@ -94,6 +94,7 @@ define curr_config CXXFLAGS=$(subst $(space),_,$(CXXFLAGS)) FFLAGS=$(subst $(space),_,$(FFLAGS)) LDFLAGS=$(subst $(space),_,$(LDFLAGS)) + OMPD_SUPPORT=$(OMPD_SUPPORT) OMPT_SUPPORT=$(OMPT_SUPPORT) OMPT_BLAME=$(OMPT_BLAME) OMPT_TRACE=$(OMPT_TRACE) @@ -709,12 +710,19 @@ ifeq "$(OMPT_SUPPORT)" "on" endif endif +ifeq "$(OMPD_SUPPORT)" "on" + ompd_items = ompd-specific + cpp-flags += -D OMPD_SUPPORT=1 + +endif + # Library files. These files participate in all kinds of library. lib_c_items := \ kmp_ftn_cdecl \ kmp_ftn_extra \ kmp_version \ $(ompt_items) \ + $(ompd_items) \ $(empty) lib_cpp_items := lib_asm_items := diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c new file mode 100644 index 000000000..2cd63acf2 --- /dev/null +++ b/runtime/src/ompd-specific.c @@ -0,0 +1,46 @@ +#include "ompd-specific.h" + +/** + * Declaration of symbols to hold struct size and member offset information + */ + +#define ompd_declare_access(t,m) uint64_t ompd_access__##t##__##m; +OMPD_FOREACH_ACCESS(ompd_declare_access) +#undef ompd_declare_access + +#define ompd_declare_bitfield(t,m) uint64_t ompd_bitfield__##t##__##m; +OMPD_FOREACH_BITFIELD(ompd_declare_bitfield) +#undef ompd_declare_bitfield + +#define ompd_declare_sizeof(t) uint64_t ompd_sizeof__##t; +OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) +#undef ompd_declare_sizeof + +void ompd_init() +{ + +/** + * Calculate member offsets for structs and unions + */ + +#define ompd_init_access(t,m) ompd_access__##t##__##m = (uint64_t)&(((t*)0)->m); +OMPD_FOREACH_ACCESS(ompd_init_access) +#undef ompd_init_access + +/** + * Create bit mask for bitfield access + */ + +#define ompd_init_bitfield(t,m) ompd_bitfield__##t##__##m=0; ((t*)(&ompd_bitfield__##t##__##m))->m = 1; +OMPD_FOREACH_BITFIELD(ompd_init_bitfield) +#undef ompd_init_bitfield + +/** + * Calculate type size information + */ + +#define ompd_init_sizeof(t) ompd_sizeof__##t = sizeof(t); +OMPD_FOREACH_SIZEOF(ompd_init_sizeof) +#undef ompd_init_sizeof + +} diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h new file mode 100644 index 000000000..ae6f894a4 --- /dev/null +++ b/runtime/src/ompd-specific.h @@ -0,0 +1,72 @@ +#include "kmp.h" +#include + +#ifndef __OMPD_SPECIFIC_H__ +#define __OMPD_SPECIFIC_H__ + +void ompd_init(); + +#define OMPD_FOREACH_ACCESS(OMPD_ACCESS) \ +OMPD_ACCESS(kmp_base_info_t, th_current_task) \ +OMPD_ACCESS(kmp_base_info_t, th_team) \ +OMPD_ACCESS(kmp_base_info_t, th_info) \ +OMPD_ACCESS(kmp_base_info_t, ompt_thread_info) \ +\ +OMPD_ACCESS(kmp_base_root_t, r_in_parallel) \ +\ +OMPD_ACCESS(kmp_base_team_t, ompt_team_info) \ +OMPD_ACCESS(kmp_base_team_t, t_active_level) \ +OMPD_ACCESS(kmp_base_team_t, t_implicit_task_taskdata) \ +OMPD_ACCESS(kmp_base_team_t, t_nproc) \ +OMPD_ACCESS(kmp_base_team_t, t_level) \ +OMPD_ACCESS(kmp_base_team_t, t_parent) \ +OMPD_ACCESS(kmp_base_team_t, t_pkfn) \ +OMPD_ACCESS(kmp_base_team_t, t_threads) \ +\ +OMPD_ACCESS(kmp_desc_t, ds) \ +\ +OMPD_ACCESS(kmp_desc_base_t, ds_thread) \ +\ +OMPD_ACCESS(kmp_info_t, th) \ +\ +OMPD_ACCESS(kmp_r_sched_t, r_sched_type) \ +OMPD_ACCESS(kmp_r_sched_t, chunk) \ +\ +OMPD_ACCESS(kmp_root_t, r) \ +\ +OMPD_ACCESS(kmp_internal_control_t, dynamic) \ +OMPD_ACCESS(kmp_internal_control_t, max_active_levels) \ +OMPD_ACCESS(kmp_internal_control_t, proc_bind) \ +OMPD_ACCESS(kmp_internal_control_t, sched) \ +\ +OMPD_ACCESS(kmp_taskdata_t, ompt_task_info) \ +OMPD_ACCESS(kmp_taskdata_t, td_flags) \ +OMPD_ACCESS(kmp_taskdata_t, td_icvs) \ +OMPD_ACCESS(kmp_taskdata_t, td_parent) \ +\ +OMPD_ACCESS(kmp_team_p, t) \ +\ +OMPD_ACCESS(ompt_task_info_t, frame) \ +OMPD_ACCESS(ompt_task_info_t, task_id) \ +\ +OMPD_ACCESS(ompt_team_info_t, parallel_id) \ +\ +OMPD_ACCESS(ompt_thread_info_t, state) \ +OMPD_ACCESS(ompt_thread_info_t, wait_id) \ +\ +OMPD_ACCESS(ompt_frame_t, reenter_runtime_frame) \ +OMPD_ACCESS(ompt_frame_t, exit_runtime_frame) \ + + +#define OMPD_FOREACH_BITFIELD(OMPD_BITFIELD) \ +OMPD_BITFIELD(kmp_tasking_flags_t, final) \ + + +#define OMPD_FOREACH_SIZEOF(OMPD_SIZEOF) \ +OMPD_SIZEOF(kmp_info_t) \ +OMPD_SIZEOF(kmp_taskdata_t) \ +OMPD_SIZEOF(kmp_tasking_flags_t) \ + + +#endif + diff --git a/runtime/src/ompt-general.c b/runtime/src/ompt-general.c index 327de8db6..5b55fc656 100644 --- a/runtime/src/ompt-general.c +++ b/runtime/src/ompt-general.c @@ -203,6 +203,16 @@ void ompt_init() break; } + const char *ompd_env_var = getenv("OMPD_STATE"); + if (ompd_env_var && !strcmp(ompd_env_var, "enabled")) + { + fprintf(stderr, + "OMPD_STATE active\n"); + ompt_status = ompt_status_track_callback; + tool_setting = omp_tool_enabled; + __ompt_init_internal(); + } + ompt_initialized = 1; } diff --git a/runtime/tools/build.pl b/runtime/tools/build.pl index 53027a579..904611e88 100755 --- a/runtime/tools/build.pl +++ b/runtime/tools/build.pl @@ -65,7 +65,8 @@ "omp-version" => { targets => "rtl", base => 0, parms => { 40 => "", 30 => "", 41 => "*" }, suffix => sub { $_[ 0 ]; } }, "coverage" => { targets => "rtl", base => 0, parms => { off => "*", on => "" }, suffix => sub { $_[ 0 ] eq "on" ? "c1" : "c0"; } }, "stats" => { targets => "rtl", base => 0, parms => { off => "*", on => "" }, suffix => sub { $_[ 0 ] eq "on" ? "s1" : "s0"; } }, - "ompt-support" => { targets => "rtl", base => 0, parms => { off => "*", on => "" }, suffix => sub { $_[ 0 ] eq "on" ? "ompt" : "" } }, + "ompd-support" => { targets => "rtl", base => 0, parms => { off => "", on => "*" }, suffix => sub { $_[ 0 ] eq "on" ? "ompd" : "" } }, + "ompt-support" => { targets => "rtl", base => 0, parms => { off => "", on => "*" }, suffix => sub { $_[ 0 ] eq "on" ? "ompt" : "" } }, "ompt-blame" => { targets => "rtl", base => 0, parms => { off => "", on => "*" }, suffix => sub { $_[ 0 ] eq "on" ? "" : "no-ompt-blame" } }, "ompt-trace" => { targets => "rtl", base => 0, parms => { off => "", on => "*" }, suffix => sub { $_[ 0 ] eq "on" ? "" : "no-ompt-trace" } }, }; @@ -73,7 +74,7 @@ "debug" => [ qw{ dbg debg } ], }; # This array specifies order of options to process, so it cannot be initialized with keys( %$opts ). -my @all_opts = qw{ target version lib-type link-type mode omp-version coverage stats ompt-support ompt-blame ompt-trace }; +my @all_opts = qw{ target version lib-type link-type mode omp-version coverage stats ompd-support ompt-support ompt-blame ompt-trace }; # This is the list of base options. my @base_opts = grep( $opts->{ $_ }->{ base } == 1, @all_opts ); # This is the list of extra options. @@ -274,6 +275,7 @@ ($$@) "VERSION=" . $set->{ version }, "suffix=" . $suf, "stats=" . $set->{ stats }, + "OMPD_SUPPORT=" . $set->{ "ompd-support" }, "OMPT_SUPPORT=" . $set->{ "ompt-support" }, "OMPT_BLAME=" . $set->{ "ompt-blame" }, "OMPT_TRACE=" . $set->{ "ompt-trace" }, From 6fad833da830a49f91bf2a639d7963e0fcd714fb Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Mon, 1 Jun 2015 11:04:16 -0700 Subject: [PATCH 02/46] Add ompd to cmake build --- runtime/CMakeLists.txt | 13 +++++++++++++ runtime/cmake/SourceFiles.cmake | 3 +++ 2 files changed, 16 insertions(+) diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 0d402aaca..6c68ab43f 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -105,6 +105,9 @@ set(ompt_support false CACHE BOOL "OMPT-support?" set(ompt_blame true CACHE BOOL "OMPT-blame?" ) set(ompt_trace true CACHE BOOL "OMPT-trace?" ) +# OMPD-support +set(ompd_support false CACHE BOOL "OMPD-support?" ) + # User specified flags. These are appended to the predetermined flags found in CommonFlags.cmake and ${CMAKE_C_COMPILER_ID}/*Flags.cmake (e.g., GNU/CFlags.cmake) set(LIBIOMP_CFLAGS "" CACHE STRING "Appended user specified C compiler flags." ) set(LIBIOMP_CXXFLAGS "" CACHE STRING "Appended user specified C++ compiler flags." ) @@ -240,6 +243,12 @@ if(NOT "${ompt_trace}") # string "on" or "ON" is seen as boolean TRUE set(OMPT_TRACE FALSE) endif() +# OMPD-support +set(OMPD_SUPPORT FALSE) +if("${ompd_support}") # string "on" or "ON" is seen as boolean TRUE + set(OMPD_SUPPORT TRUE) +endif() + # Include itt notify interface? Right now, always. set(USE_ITT_NOTIFY TRUE) @@ -329,6 +338,9 @@ if(${OMPT_SUPPORT}) set(suffix "${suffix}.no-ompt-trace") endif() endif() +if(${OMPD_SUPPORT}) + set(suffix "${suffix}.ompd") +endif() #################################### # Setting file extensions / suffixes @@ -905,6 +917,7 @@ if(${LIBIOMP_STANDALONE_BUILD}) say("LIBIOMP: OMPT-blame -- ${ompt_blame}") say("LIBIOMP: OMPT-trace -- ${ompt_trace}") endif() + say("LIBIOMP: OMPD-support -- ${ompd_support}") say("LIBIOMP: Use build.pl rules -- ${USE_BUILDPL_RULES}") say("LIBIOMP: Adaptive locks -- ${USE_ADAPTIVE_LOCKS}") say("LIBIOMP: Use predefined linker flags -- ${USE_PREDEFINED_LINKER_FLAGS}") diff --git a/runtime/cmake/SourceFiles.cmake b/runtime/cmake/SourceFiles.cmake index c9d4a3210..a7c8a50a7 100644 --- a/runtime/cmake/SourceFiles.cmake +++ b/runtime/cmake/SourceFiles.cmake @@ -35,6 +35,9 @@ function(set_c_files input_c_source_files) if(${OMPT_SUPPORT}) append_c_source_file("ompt-general.c") endif() + if(${OMPD_SUPPORT}) + append_c_source_file("ompd-specific.c") + endif() if(${STUBS_LIBRARY}) append_c_source_file("kmp_stub.c") else() From 0cd2b52efda959c8095545a508fdfd2cb326ab73 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Mon, 29 Jun 2015 08:53:17 -0700 Subject: [PATCH 03/46] fix cmake build for ompd-support --- runtime/cmake/Definitions.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime/cmake/Definitions.cmake b/runtime/cmake/Definitions.cmake index f9b511698..8831a1ab0 100644 --- a/runtime/cmake/Definitions.cmake +++ b/runtime/cmake/Definitions.cmake @@ -115,6 +115,11 @@ function(append_cpp_flags input_cpp_flags) else() append_definitions("-D OMPT_TRACE=0") endif() + if(${OMPD_SUPPORT}) + append_definitions("-D OMPD_SUPPORT=1") + else() + append_definitions("-D OMPD_SUPPORT=0") + endif() # OpenMP version flags set(have_omp_50 0) From b1d7851b646f43e24ac9bc27a94e41a66fcc64dc Mon Sep 17 00:00:00 2001 From: John Mellor-Crummey Date: Sun, 28 Jun 2015 21:05:33 -0700 Subject: [PATCH 04/46] Remove use of assignment to multiple struct fields using .fieldname syntax. This doesn't work with gcc 4.8. --- runtime/src/kmp_tasking.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/runtime/src/kmp_tasking.c b/runtime/src/kmp_tasking.c index 92f5370f6..503b51d4f 100644 --- a/runtime/src/kmp_tasking.c +++ b/runtime/src/kmp_tasking.c @@ -758,10 +758,8 @@ __kmp_task_init_ompt( kmp_taskdata_t * task, int tid ) { task->ompt_task_info.task_id = __ompt_task_id_new(tid); task->ompt_task_info.function = NULL; - task->ompt_task_info.frame = (ompt_frame_t) { - .exit_runtime_frame = NULL, - .reenter_runtime_frame = NULL - }; + task->ompt_task_info.frame.exit_runtime_frame = NULL; + task->ompt_task_info.frame.reenter_runtime_frame = NULL; } #endif @@ -1035,8 +1033,8 @@ __kmp_task_alloc( ident_t *loc_ref, kmp_int32 gtid, kmp_tasking_flags_t *flags, if (ompt_status & ompt_status_track) { taskdata->ompt_task_info.task_id = __ompt_task_id_new(gtid); taskdata->ompt_task_info.function = (void*) task_entry; - taskdata->ompt_task_info.frame = (ompt_frame_t) - { .exit_runtime_frame = NULL, .reenter_runtime_frame = NULL }; + taskdata->ompt_task_info.frame.exit_runtime_frame = NULL; + taskdata->ompt_task_info.frame.reenter_runtime_frame = NULL; } #endif From e84ef6b0bec0e900571049e2587cb9a4b26a3cab Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Wed, 1 Jul 2015 13:12:10 +0200 Subject: [PATCH 05/46] add ompd_dll_location array and function. --- runtime/src/ompd-specific.c | 15 +++++++++++++++ runtime/src/ompd-specific.h | 10 +++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index 2cd63acf2..0113c2151 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -1,5 +1,7 @@ #include "ompd-specific.h" +#ifdef OMPD_SUPPORT + /** * Declaration of symbols to hold struct size and member offset information */ @@ -16,6 +18,8 @@ OMPD_FOREACH_BITFIELD(ompd_declare_bitfield) OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) #undef ompd_declare_sizeof +const char * * ompd_dll_locations=NULL; +const char * ompd_my_dll_locations[2] = {"libompd_intel.so",NULL}; void ompd_init() { @@ -43,4 +47,15 @@ OMPD_FOREACH_BITFIELD(ompd_init_bitfield) OMPD_FOREACH_SIZEOF(ompd_init_sizeof) #undef ompd_init_sizeof + ompd_dll_locations=ompd_my_dll_locations; + ompd_dll_locations_valid (); + } + +void ompd_dll_locations_valid ( void ){ + /* naive way of implementing hard to opt-out empty function + we might want to use a separate object file? */ + asm (""); +} + +#endif /* OMPD_SUPPORT */ diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index ae6f894a4..a4324b0f7 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -4,7 +4,15 @@ #ifndef __OMPD_SPECIFIC_H__ #define __OMPD_SPECIFIC_H__ +#ifdef OMPD_SUPPORT + void ompd_init(); +extern const char * * ompd_dll_locations; + +#ifdef __cplusplus +extern "C" +#endif +void ompd_dll_locations_valid ( void ); #define OMPD_FOREACH_ACCESS(OMPD_ACCESS) \ OMPD_ACCESS(kmp_base_info_t, th_current_task) \ @@ -67,6 +75,6 @@ OMPD_SIZEOF(kmp_info_t) \ OMPD_SIZEOF(kmp_taskdata_t) \ OMPD_SIZEOF(kmp_tasking_flags_t) \ - +#endif /* OMPD_SUPPORT */ #endif From 963af700203769be1d601198c18c83014fc07943 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Tue, 14 Jul 2015 07:23:25 -0700 Subject: [PATCH 06/46] Add additional type information needed for the new API functions --- runtime/src/ompd-specific.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index a4324b0f7..bcdf28852 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -25,6 +25,7 @@ OMPD_ACCESS(kmp_base_root_t, r_in_parallel) \ OMPD_ACCESS(kmp_base_team_t, ompt_team_info) \ OMPD_ACCESS(kmp_base_team_t, t_active_level) \ OMPD_ACCESS(kmp_base_team_t, t_implicit_task_taskdata) \ +OMPD_ACCESS(kmp_base_team_t, t_master_tid) \ OMPD_ACCESS(kmp_base_team_t, t_nproc) \ OMPD_ACCESS(kmp_base_team_t, t_level) \ OMPD_ACCESS(kmp_base_team_t, t_parent) \ @@ -51,6 +52,7 @@ OMPD_ACCESS(kmp_taskdata_t, ompt_task_info) \ OMPD_ACCESS(kmp_taskdata_t, td_flags) \ OMPD_ACCESS(kmp_taskdata_t, td_icvs) \ OMPD_ACCESS(kmp_taskdata_t, td_parent) \ +OMPD_ACCESS(kmp_taskdata_t, td_team) \ \ OMPD_ACCESS(kmp_team_p, t) \ \ @@ -68,6 +70,16 @@ OMPD_ACCESS(ompt_frame_t, exit_runtime_frame) \ #define OMPD_FOREACH_BITFIELD(OMPD_BITFIELD) \ OMPD_BITFIELD(kmp_tasking_flags_t, final) \ +OMPD_BITFIELD(kmp_tasking_flags_t, tiedness) \ +OMPD_BITFIELD(kmp_tasking_flags_t, tasktype) \ +OMPD_BITFIELD(kmp_tasking_flags_t, task_serial) \ +OMPD_BITFIELD(kmp_tasking_flags_t, tasking_ser) \ +OMPD_BITFIELD(kmp_tasking_flags_t, team_serial) \ +OMPD_BITFIELD(kmp_tasking_flags_t, started) \ +OMPD_BITFIELD(kmp_tasking_flags_t, executing) \ +OMPD_BITFIELD(kmp_tasking_flags_t, complete) \ +OMPD_BITFIELD(kmp_tasking_flags_t, freed) \ +OMPD_BITFIELD(kmp_tasking_flags_t, native) \ #define OMPD_FOREACH_SIZEOF(OMPD_SIZEOF) \ From 106290be0a38268eb914bd1b3a53e784123d70c6 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Wed, 5 Aug 2015 15:55:57 +0200 Subject: [PATCH 07/46] add ompd_breakpoints --- runtime/src/kmp.h | 4 +++ runtime/src/kmp_gsupport.c | 10 ++++++- runtime/src/kmp_runtime.c | 8 ++++++ runtime/src/kmp_tasking.c | 4 +++ runtime/src/kmp_wait_release.h | 24 ++++++++++++++++ runtime/src/ompd-specific.c | 51 ++++++++++++++++++++++++++++++++++ runtime/src/ompd-specific.h | 13 ++++++++- runtime/src/ompt-general.c | 10 ------- 8 files changed, 112 insertions(+), 12 deletions(-) diff --git a/runtime/src/kmp.h b/runtime/src/kmp.h index 2806dc5b6..396e55fa5 100644 --- a/runtime/src/kmp.h +++ b/runtime/src/kmp.h @@ -114,6 +114,10 @@ class kmp_stats_list; #include "ompt-internal.h" #endif +#if OMPD_SUPPORT +#include "ompd-specific.h" +#endif + /*Select data placement in NUMA memory */ #define NO_FIRST_TOUCH 0 #define FIRST_TOUCH 1 /* Exploit SGI's first touch page placement algo */ diff --git a/runtime/src/kmp_gsupport.c b/runtime/src/kmp_gsupport.c index 99dc82267..3c9ba2ed3 100644 --- a/runtime/src/kmp_gsupport.c +++ b/runtime/src/kmp_gsupport.c @@ -433,6 +433,10 @@ __kmp_GOMP_serialized_parallel(ident_t *loc, kmp_int32 gtid, void (*task)(void * #endif } #endif +#if OMPD_SUPPORT + if ( ompd_state & OMPD_ENABLE_BP ) + ompd_bp_parallel_begin (); +#endif } @@ -532,7 +536,11 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) ompt_state_work_serial : ompt_state_work_parallel); } #endif - +#if OMPD_SUPPORT + if ( ompd_state & OMPD_ENABLE_BP ) + ompd_bp_parallel_end (); +#endif + } } diff --git a/runtime/src/kmp_runtime.c b/runtime/src/kmp_runtime.c index 7eea02eba..70fbca456 100644 --- a/runtime/src/kmp_runtime.c +++ b/runtime/src/kmp_runtime.c @@ -1620,6 +1620,10 @@ __kmp_fork_call( #endif KMP_TIME_BLOCK(OMP_work); +#if OMPD_SUPPORT + if ( ompd_state & OMPD_ENABLE_BP ) + ompd_bp_parallel_begin (); +#endif __kmp_invoke_microtask( microtask, gtid, 0, argc, parent_team->t.t_argv #if OMPT_SUPPORT , exit_runtime_p @@ -1649,6 +1653,10 @@ __kmp_fork_call( } master_th->th.ompt_thread_info.state = ompt_state_overhead; } +#endif +#if OMPD_SUPPORT + if ( ompd_state & OMPD_ENABLE_BP ) + ompd_bp_parallel_end (); #endif return TRUE; } diff --git a/runtime/src/kmp_tasking.c b/runtime/src/kmp_tasking.c index 503b51d4f..655bde1e9 100644 --- a/runtime/src/kmp_tasking.c +++ b/runtime/src/kmp_tasking.c @@ -1144,6 +1144,10 @@ __kmp_invoke_task( kmp_int32 gtid, kmp_task_t *task, kmp_taskdata_t * current_ta // if (!discard) { #endif // OMP_40_ENABLED +#if OMPD_SUPPORT + if ( ompd_state & OMPD_ENABLE_BP ) + ompd_bp_task_begin (); +#endif #ifdef KMP_GOMP_COMPAT if (taskdata->td_flags.native) { ((void (*)(void *))(*(task->routine)))(task->shareds); diff --git a/runtime/src/kmp_wait_release.h b/runtime/src/kmp_wait_release.h index 3073a0711..d91506e8f 100644 --- a/runtime/src/kmp_wait_release.h +++ b/runtime/src/kmp_wait_release.h @@ -416,8 +416,16 @@ class kmp_flag_32 : public kmp_basic_flag { void resume(int th_gtid) { __kmp_resume_32(th_gtid, this); } int execute_tasks(kmp_info_t *this_thr, kmp_int32 gtid, int final_spin, int *thread_finished USE_ITT_BUILD_ARG(void * itt_sync_obj), kmp_int32 is_constrained) { +#if OMPD_SUPPORT + int ret = __kmp_execute_tasks_32(this_thr, gtid, this, final_spin, thread_finished + USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained); + if ( ompd_state & OMPD_ENABLE_BP ) + ompd_bp_task_end (); + return ret; +#else return __kmp_execute_tasks_32(this_thr, gtid, this, final_spin, thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained); +#endif } void wait(kmp_info_t *this_thr, int final_spin USE_ITT_BUILD_ARG(void * itt_sync_obj)) { @@ -436,8 +444,16 @@ class kmp_flag_64 : public kmp_basic_flag { void resume(int th_gtid) { __kmp_resume_64(th_gtid, this); } int execute_tasks(kmp_info_t *this_thr, kmp_int32 gtid, int final_spin, int *thread_finished USE_ITT_BUILD_ARG(void * itt_sync_obj), kmp_int32 is_constrained) { +#if OMPD_SUPPORT + int ret = __kmp_execute_tasks_64(this_thr, gtid, this, final_spin, thread_finished + USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained); + if ( ompd_state & OMPD_ENABLE_BP ) + ompd_bp_task_end (); + return ret; +#else return __kmp_execute_tasks_64(this_thr, gtid, this, final_spin, thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained); +#endif } void wait(kmp_info_t *this_thr, int final_spin USE_ITT_BUILD_ARG(void * itt_sync_obj)) { @@ -535,8 +551,16 @@ class kmp_flag_oncore : public kmp_flag { void resume(int th_gtid) { __kmp_resume_oncore(th_gtid, this); } int execute_tasks(kmp_info_t *this_thr, kmp_int32 gtid, int final_spin, int *thread_finished USE_ITT_BUILD_ARG(void * itt_sync_obj), kmp_int32 is_constrained) { +#if OMPD_SUPPORT + int ret = __kmp_execute_tasks_oncore(this_thr, gtid, this, final_spin, thread_finished + USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained); + if ( ompd_state & OMPD_ENABLE_BP ) + ompd_bp_task_end (); + return ret; +#else return __kmp_execute_tasks_oncore(this_thr, gtid, this, final_spin, thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), is_constrained); +#endif } }; diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index 0113c2151..b0f1e67c0 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -20,9 +20,18 @@ OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) const char * * ompd_dll_locations=NULL; const char * ompd_my_dll_locations[2] = {"libompd_intel.so",NULL}; +int ompd_state=0; + +extern void __ompt_init_internal(void); + void ompd_init() { +static int ompd_initialized = 0; + +if (ompd_initialized) + return; + /** * Calculate member offsets for structs and unions */ @@ -50,6 +59,26 @@ OMPD_FOREACH_SIZEOF(ompd_init_sizeof) ompd_dll_locations=ompd_my_dll_locations; ompd_dll_locations_valid (); + const char *ompd_env_var = getenv("OMP_OMPD"); + if (ompd_env_var && !strcmp(ompd_env_var, "on")) + { + fprintf(stderr, + "OMP_OMPD active\n"); + ompt_status = ompt_status_track_callback; + ompd_state |= OMPD_ENABLE_BP; + __ompt_init_internal(); + } + + ompd_initialized = 1; +} + +void omp_ompd_enable ( void ) +{ + fprintf(stderr, + "OMP_OMPD active\n"); + ompt_status = ompt_status_track_callback; + ompd_state |= OMPD_ENABLE_BP; + __ompt_init_internal(); } void ompd_dll_locations_valid ( void ){ @@ -58,4 +87,26 @@ void ompd_dll_locations_valid ( void ){ asm (""); } +void ompd_bp_parallel_begin ( void ){ + /* naive way of implementing hard to opt-out empty function + we might want to use a separate object file? */ + asm (""); +} +void ompd_bp_parallel_end ( void ){ + /* naive way of implementing hard to opt-out empty function + we might want to use a separate object file? */ + asm (""); +} +void ompd_bp_task_begin ( void ){ + /* naive way of implementing hard to opt-out empty function + we might want to use a separate object file? */ + asm (""); +} +void ompd_bp_task_end ( void ){ + /* naive way of implementing hard to opt-out empty function + we might want to use a separate object file? */ + asm (""); +} + + #endif /* OMPD_SUPPORT */ diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index a4324b0f7..9903d3c7f 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -10,9 +10,19 @@ void ompd_init(); extern const char * * ompd_dll_locations; #ifdef __cplusplus -extern "C" +extern "C" { #endif void ompd_dll_locations_valid ( void ); +void ompd_bp_parallel_begin ( void ); +void ompd_bp_parallel_end ( void ); +void ompd_bp_task_begin ( void ); +void ompd_bp_task_end ( void ); +#ifdef __cplusplus +} /* extern "C" */ +#endif + +extern int ompd_state; +#define OMPD_ENABLE_BP 0x1 #define OMPD_FOREACH_ACCESS(OMPD_ACCESS) \ OMPD_ACCESS(kmp_base_info_t, th_current_task) \ @@ -75,6 +85,7 @@ OMPD_SIZEOF(kmp_info_t) \ OMPD_SIZEOF(kmp_taskdata_t) \ OMPD_SIZEOF(kmp_tasking_flags_t) \ + #endif /* OMPD_SUPPORT */ #endif diff --git a/runtime/src/ompt-general.c b/runtime/src/ompt-general.c index 5b55fc656..327de8db6 100644 --- a/runtime/src/ompt-general.c +++ b/runtime/src/ompt-general.c @@ -203,16 +203,6 @@ void ompt_init() break; } - const char *ompd_env_var = getenv("OMPD_STATE"); - if (ompd_env_var && !strcmp(ompd_env_var, "enabled")) - { - fprintf(stderr, - "OMPD_STATE active\n"); - ompt_status = ompt_status_track_callback; - tool_setting = omp_tool_enabled; - __ompt_init_internal(); - } - ompt_initialized = 1; } From b89b9e0b466abe5a53a2815fcc030a9c13f5d1f3 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Wed, 5 Aug 2015 18:25:21 +0200 Subject: [PATCH 08/46] calculate offset and size information at compile time --- runtime/src/ompd-specific.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index b0f1e67c0..2deea9b11 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -6,7 +6,7 @@ * Declaration of symbols to hold struct size and member offset information */ -#define ompd_declare_access(t,m) uint64_t ompd_access__##t##__##m; +#define ompd_declare_access(t,m) const uint64_t ompd_access__##t##__##m = (uint64_t)&(((t*)0)->m); OMPD_FOREACH_ACCESS(ompd_declare_access) #undef ompd_declare_access @@ -14,7 +14,7 @@ OMPD_FOREACH_ACCESS(ompd_declare_access) OMPD_FOREACH_BITFIELD(ompd_declare_bitfield) #undef ompd_declare_bitfield -#define ompd_declare_sizeof(t) uint64_t ompd_sizeof__##t; +#define ompd_declare_sizeof(t) const uint64_t ompd_sizeof__##t = sizeof(t); OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) #undef ompd_declare_sizeof @@ -32,14 +32,6 @@ static int ompd_initialized = 0; if (ompd_initialized) return; -/** - * Calculate member offsets for structs and unions - */ - -#define ompd_init_access(t,m) ompd_access__##t##__##m = (uint64_t)&(((t*)0)->m); -OMPD_FOREACH_ACCESS(ompd_init_access) -#undef ompd_init_access - /** * Create bit mask for bitfield access */ @@ -48,14 +40,6 @@ OMPD_FOREACH_ACCESS(ompd_init_access) OMPD_FOREACH_BITFIELD(ompd_init_bitfield) #undef ompd_init_bitfield -/** - * Calculate type size information - */ - -#define ompd_init_sizeof(t) ompd_sizeof__##t = sizeof(t); -OMPD_FOREACH_SIZEOF(ompd_init_sizeof) -#undef ompd_init_sizeof - ompd_dll_locations=ompd_my_dll_locations; ompd_dll_locations_valid (); From 087759676b81a39ec5abf824fa78058d198482a6 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Sat, 8 Aug 2015 21:52:39 +0200 Subject: [PATCH 09/46] get size of target thread identifier --- runtime/src/ompd-specific.c | 2 +- runtime/src/ompd-specific.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index 2deea9b11..bdadfb86f 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -36,7 +36,7 @@ if (ompd_initialized) * Create bit mask for bitfield access */ -#define ompd_init_bitfield(t,m) ompd_bitfield__##t##__##m=0; ((t*)(&ompd_bitfield__##t##__##m))->m = 1; +#define ompd_init_bitfield(t,m) ompd_bitfield__##t##__##m=0; ((t*)(&ompd_bitfield__##t##__##m))->m = -1; OMPD_FOREACH_BITFIELD(ompd_init_bitfield) #undef ompd_init_bitfield diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index 20d24038e..858ba09c4 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -96,6 +96,7 @@ OMPD_BITFIELD(kmp_tasking_flags_t, native) \ OMPD_SIZEOF(kmp_info_t) \ OMPD_SIZEOF(kmp_taskdata_t) \ OMPD_SIZEOF(kmp_tasking_flags_t) \ +OMPD_SIZEOF(kmp_thread_t) \ #endif /* OMPD_SUPPORT */ From 9ea80d821984cdcf7f578a97d1a14e5a2a131a41 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Sun, 9 Aug 2015 02:15:42 -0700 Subject: [PATCH 10/46] Revert "calculate offset and size information at compile time" Issue with this change: const variables are optimized out and not available in the binary. This reverts commit b89b9e0b466abe5a53a2815fcc030a9c13f5d1f3. --- runtime/src/ompd-specific.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index bdadfb86f..371e2ade2 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -6,7 +6,7 @@ * Declaration of symbols to hold struct size and member offset information */ -#define ompd_declare_access(t,m) const uint64_t ompd_access__##t##__##m = (uint64_t)&(((t*)0)->m); +#define ompd_declare_access(t,m) uint64_t ompd_access__##t##__##m; OMPD_FOREACH_ACCESS(ompd_declare_access) #undef ompd_declare_access @@ -14,7 +14,7 @@ OMPD_FOREACH_ACCESS(ompd_declare_access) OMPD_FOREACH_BITFIELD(ompd_declare_bitfield) #undef ompd_declare_bitfield -#define ompd_declare_sizeof(t) const uint64_t ompd_sizeof__##t = sizeof(t); +#define ompd_declare_sizeof(t) uint64_t ompd_sizeof__##t; OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) #undef ompd_declare_sizeof @@ -32,6 +32,14 @@ static int ompd_initialized = 0; if (ompd_initialized) return; +/** + * Calculate member offsets for structs and unions + */ + +#define ompd_init_access(t,m) ompd_access__##t##__##m = (uint64_t)&(((t*)0)->m); +OMPD_FOREACH_ACCESS(ompd_init_access) +#undef ompd_init_access + /** * Create bit mask for bitfield access */ @@ -40,6 +48,14 @@ if (ompd_initialized) OMPD_FOREACH_BITFIELD(ompd_init_bitfield) #undef ompd_init_bitfield +/** + * Calculate type size information + */ + +#define ompd_init_sizeof(t) ompd_sizeof__##t = sizeof(t); +OMPD_FOREACH_SIZEOF(ompd_init_sizeof) +#undef ompd_init_sizeof + ompd_dll_locations=ompd_my_dll_locations; ompd_dll_locations_valid (); From ff81f9c35fb24eac9a7fa4231b5fee939068a35a Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Mon, 31 Aug 2015 16:10:50 +0200 Subject: [PATCH 11/46] add more size information for typedefed basic types and some variables --- runtime/src/ompd-specific.c | 4 +++- runtime/src/ompd-specific.h | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index bdadfb86f..1aa4a2027 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -24,6 +24,8 @@ int ompd_state=0; extern void __ompt_init_internal(void); +int ompd_rtl_version = 3; + void ompd_init() { @@ -36,7 +38,7 @@ if (ompd_initialized) * Create bit mask for bitfield access */ -#define ompd_init_bitfield(t,m) ompd_bitfield__##t##__##m=0; ((t*)(&ompd_bitfield__##t##__##m))->m = -1; +#define ompd_init_bitfield(t,m) ompd_bitfield__##t##__##m=0; ((t*)(&ompd_bitfield__##t##__##m))->m = 1; OMPD_FOREACH_BITFIELD(ompd_init_bitfield) #undef ompd_init_bitfield diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index 858ba09c4..b8c42976c 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -8,6 +8,7 @@ void ompd_init(); extern const char * * ompd_dll_locations; +extern int ompd_rtl_version; #ifdef __cplusplus extern "C" { @@ -97,6 +98,11 @@ OMPD_SIZEOF(kmp_info_t) \ OMPD_SIZEOF(kmp_taskdata_t) \ OMPD_SIZEOF(kmp_tasking_flags_t) \ OMPD_SIZEOF(kmp_thread_t) \ +OMPD_SIZEOF(ompt_parallel_id_t) \ +OMPD_SIZEOF(ompt_task_id_t) \ +OMPD_SIZEOF(__kmp_avail_proc) \ +OMPD_SIZEOF(__kmp_max_nth) \ +OMPD_SIZEOF(__kmp_gtid) \ #endif /* OMPD_SUPPORT */ From f14b3fef11fc1c040ea7125b41813eb1d641e9f5 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Mon, 21 Sep 2015 17:36:45 +0200 Subject: [PATCH 12/46] add additional struct offset information --- runtime/src/ompd-specific.c | 2 +- runtime/src/ompd-specific.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index 1aa4a2027..60bdf4a4c 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -24,7 +24,7 @@ int ompd_state=0; extern void __ompt_init_internal(void); -int ompd_rtl_version = 3; +int ompd_rtl_version = 4; void ompd_init() { diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index b8c42976c..e297675e3 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -69,8 +69,10 @@ OMPD_ACCESS(kmp_team_p, t) \ \ OMPD_ACCESS(ompt_task_info_t, frame) \ OMPD_ACCESS(ompt_task_info_t, task_id) \ +OMPD_ACCESS(ompt_task_info_t, function) \ \ OMPD_ACCESS(ompt_team_info_t, parallel_id) \ +OMPD_ACCESS(ompt_team_info_t, microtask) \ \ OMPD_ACCESS(ompt_thread_info_t, state) \ OMPD_ACCESS(ompt_thread_info_t, wait_id) \ From 5b65766fb8449f970332db43e446a32061b6ede0 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Thu, 8 Oct 2015 12:09:28 +0200 Subject: [PATCH 13/46] * resolve last merging conflict * add build description for ompd integration --- runtime/Build_With_CMake.txt | 3 +++ runtime/src/kmp_runtime.c | 24 ------------------------ 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/runtime/Build_With_CMake.txt b/runtime/Build_With_CMake.txt index c1ce0f80c..b65f81e06 100644 --- a/runtime/Build_With_CMake.txt +++ b/runtime/Build_With_CMake.txt @@ -153,6 +153,9 @@ Should OMPT blame functionality be included in the build? -DLIBOMP_OMPT_TRACE=on|off Should OMPT trace functionality be included in the build? +-DLIBOMP_OMPD_SUPPORT=off|on +Should OMPD support be included in the build? (Not supported on Windows) + -DLIBOMP_STATS=off|on Should include stats-gathering code be included in the build? diff --git a/runtime/src/kmp_runtime.c b/runtime/src/kmp_runtime.c index e555e29c4..b03dfff27 100644 --- a/runtime/src/kmp_runtime.c +++ b/runtime/src/kmp_runtime.c @@ -6635,15 +6635,9 @@ __kmp_do_serial_initialize( void ) KMP_MB(); KA_TRACE( 10, ("__kmp_do_serial_initialize: exit\n" ) ); -<<<<<<< HEAD -#if OMPT_SUPPORT - ompt_init(); -#endif #if OMPD_SUPPORT ompd_init(); #endif -======= ->>>>>>> master } void @@ -6788,15 +6782,6 @@ __kmp_middle_initialize( void ) } __kmp_do_middle_initialize(); __kmp_release_bootstrap_lock( &__kmp_initz_lock ); -<<<<<<< HEAD -#if OMPT_SUPPORT - ompt_init(); -#endif -#if OMPD_SUPPORT - ompd_init(); -#endif -======= ->>>>>>> master } void @@ -6866,15 +6851,6 @@ __kmp_parallel_initialize( void ) KA_TRACE( 10, ("__kmp_parallel_initialize: exit\n" ) ); __kmp_release_bootstrap_lock( &__kmp_initz_lock ); -<<<<<<< HEAD -#if OMPT_SUPPORT - ompt_init(); -#endif -#if OMPD_SUPPORT - ompd_init(); -#endif -======= ->>>>>>> master } From 530b3466f4858990fda9cb200325249b776088de Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Thu, 22 Oct 2015 10:18:49 +0200 Subject: [PATCH 14/46] Repair ompd runtime stuff after merge from master --- runtime/src/kmp_config.h.cmake | 2 ++ runtime/src/kmp_runtime.c | 6 +++--- runtime/src/ompd-specific.c | 11 +++++------ runtime/src/ompt-general.c | 3 ++- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/runtime/src/kmp_config.h.cmake b/runtime/src/kmp_config.h.cmake index 16d0b20a3..34d10bec4 100644 --- a/runtime/src/kmp_config.h.cmake +++ b/runtime/src/kmp_config.h.cmake @@ -37,6 +37,8 @@ #define OMPT_BLAME LIBOMP_OMPT_BLAME #cmakedefine01 LIBOMP_OMPT_TRACE #define OMPT_TRACE LIBOMP_OMPT_TRACE +#cmakedefine01 LIBOMP_OMPD_SUPPORT +#define OMPD_SUPPORT LIBOMP_OMPD_SUPPORT #cmakedefine01 LIBOMP_USE_ADAPTIVE_LOCKS #define KMP_USE_ADAPTIVE_LOCKS LIBOMP_USE_ADAPTIVE_LOCKS #define KMP_DEBUG_ADAPTIVE_LOCKS 0 diff --git a/runtime/src/kmp_runtime.c b/runtime/src/kmp_runtime.c index b03dfff27..4f00b804f 100644 --- a/runtime/src/kmp_runtime.c +++ b/runtime/src/kmp_runtime.c @@ -6390,6 +6390,9 @@ __kmp_do_serial_initialize( void ) #if OMPT_SUPPORT ompt_pre_init(); #endif +#if OMPD_SUPPORT + ompd_init(); +#endif __kmp_validate_locks(); @@ -6635,9 +6638,6 @@ __kmp_do_serial_initialize( void ) KMP_MB(); KA_TRACE( 10, ("__kmp_do_serial_initialize: exit\n" ) ); -#if OMPD_SUPPORT - ompd_init(); -#endif } void diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index 60bdf4a4c..3f9af2cc1 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -22,8 +22,6 @@ const char * * ompd_dll_locations=NULL; const char * ompd_my_dll_locations[2] = {"libompd_intel.so",NULL}; int ompd_state=0; -extern void __ompt_init_internal(void); - int ompd_rtl_version = 4; void ompd_init() @@ -50,9 +48,8 @@ OMPD_FOREACH_BITFIELD(ompd_init_bitfield) { fprintf(stderr, "OMP_OMPD active\n"); - ompt_status = ompt_status_track_callback; + ompt_enabled = 1; ompd_state |= OMPD_ENABLE_BP; - __ompt_init_internal(); } ompd_initialized = 1; @@ -62,9 +59,11 @@ void omp_ompd_enable ( void ) { fprintf(stderr, "OMP_OMPD active\n"); - ompt_status = ompt_status_track_callback; + ompt_enabled = 1; ompd_state |= OMPD_ENABLE_BP; - __ompt_init_internal(); +#ifdef OMPD_SUPPORT + ompt_post_init(); +#endif } void ompd_dll_locations_valid ( void ){ diff --git a/runtime/src/ompt-general.c b/runtime/src/ompt-general.c index 3d2aba2f3..37b577b40 100644 --- a/runtime/src/ompt-general.c +++ b/runtime/src/ompt-general.c @@ -161,7 +161,8 @@ void ompt_post_init() // Initialize the tool if so indicated. //-------------------------------------------------- if (ompt_enabled) { - ompt_initialize_fn(ompt_fn_lookup, ompt_get_runtime_version(), + if (ompt_initialize_fn) + ompt_initialize_fn(ompt_fn_lookup, ompt_get_runtime_version(), OMPT_VERSION); ompt_thread_t *root_thread = ompt_get_thread(); From 4884d031e406682e6c0e72713ec103fc9cea655e Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Thu, 22 Oct 2015 04:17:12 -0700 Subject: [PATCH 15/46] add offset information for omp_get_thread_num value --- runtime/src/ompd-specific.c | 2 +- runtime/src/ompd-specific.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index cef167ab3..9b86811a0 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -22,7 +22,7 @@ const char * * ompd_dll_locations=NULL; const char * ompd_my_dll_locations[2] = {"libompd_intel.so",NULL}; int ompd_state=0; -int ompd_rtl_version = 4; +int ompd_rtl_version = 5; void ompd_init() { diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index e297675e3..054fcf367 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -46,6 +46,7 @@ OMPD_ACCESS(kmp_base_team_t, t_threads) \ OMPD_ACCESS(kmp_desc_t, ds) \ \ OMPD_ACCESS(kmp_desc_base_t, ds_thread) \ +OMPD_ACCESS(kmp_desc_base_t, ds_tid) \ \ OMPD_ACCESS(kmp_info_t, th) \ \ From 1da0107e6ed5b174e4fb3ae58482deedc80e2dde Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Wed, 16 Dec 2015 09:29:49 +0100 Subject: [PATCH 16/46] Fix size of ompd_state --- runtime/src/ompd-specific.c | 2 +- runtime/src/ompd-specific.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index 60bdf4a4c..5b3e4556d 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -20,7 +20,7 @@ OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) const char * * ompd_dll_locations=NULL; const char * ompd_my_dll_locations[2] = {"libompd_intel.so",NULL}; -int ompd_state=0; +uint64_t ompd_state=0; extern void __ompt_init_internal(void); diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index e297675e3..d0760db82 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -22,7 +22,7 @@ void ompd_bp_task_end ( void ); } /* extern "C" */ #endif -extern int ompd_state; +extern uint64_t ompd_state; #define OMPD_ENABLE_BP 0x1 #define OMPD_FOREACH_ACCESS(OMPD_ACCESS) \ From 3de34d3392d0123f3f37fca101ca60868fd1a50f Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Tue, 19 Jan 2016 13:40:08 +0100 Subject: [PATCH 17/46] Add parallel outline function call as implicit task function --- runtime/src/kmp_runtime.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime/src/kmp_runtime.c b/runtime/src/kmp_runtime.c index 4f00b804f..182a5f83c 100644 --- a/runtime/src/kmp_runtime.c +++ b/runtime/src/kmp_runtime.c @@ -1587,6 +1587,7 @@ __kmp_fork_call( exit_runtime_p = &(lw_taskteam.ompt_task_info.frame.exit_runtime_frame); __ompt_lw_taskteam_link(&lw_taskteam, master_th); + lw_taskteam.ompt_task_info.function = unwrapped_task; #if OMPT_TRACE /* OMPT implicit task begin */ @@ -1791,6 +1792,7 @@ __kmp_fork_call( unwrapped_task, ompt_parallel_id); lw_taskteam.ompt_task_info.task_id = __ompt_task_id_new(gtid); exit_runtime_p = &(lw_taskteam.ompt_task_info.frame.exit_runtime_frame); + lw_taskteam.ompt_task_info.function = unwrapped_task; __ompt_lw_taskteam_link(&lw_taskteam, master_th); @@ -1893,6 +1895,7 @@ __kmp_fork_call( unwrapped_task, ompt_parallel_id); lw_taskteam.ompt_task_info.task_id = __ompt_task_id_new(gtid); exit_runtime_p = &(lw_taskteam.ompt_task_info.frame.exit_runtime_frame); + lw_taskteam.ompt_task_info.function = unwrapped_task; __ompt_lw_taskteam_link(&lw_taskteam, master_th); @@ -6917,6 +6920,8 @@ __kmp_invoke_task_func( int gtid ) if (ompt_enabled) { exit_runtime_p = &(team->t.t_implicit_task_taskdata[tid]. ompt_task_info.frame.exit_runtime_frame); + team->t.t_implicit_task_taskdata[tid]. + ompt_task_info.function = team->t.ompt_team_info.microtask; } else { exit_runtime_p = &dummy; } From 78504c8a4f4a7167e2107762484af2d08c1bbed0 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Thu, 11 Feb 2016 17:09:46 +0100 Subject: [PATCH 18/46] fix missing OMPT reenter_address for openmp taskwait --- runtime/src/kmp_tasking.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/runtime/src/kmp_tasking.c b/runtime/src/kmp_tasking.c index 3f73016a7..4ff4cacd0 100644 --- a/runtime/src/kmp_tasking.c +++ b/runtime/src/kmp_tasking.c @@ -1362,6 +1362,7 @@ __kmpc_omp_taskwait( ident_t *loc_ref, kmp_int32 gtid ) my_task_id = taskdata->ompt_task_info.task_id; my_parallel_id = team->t.ompt_team_info.parallel_id; + taskdata->ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(0); if (ompt_callbacks.ompt_callback(ompt_event_taskwait_begin)) { ompt_callbacks.ompt_callback(ompt_event_taskwait_begin)( my_parallel_id, my_task_id); @@ -1404,10 +1405,13 @@ __kmpc_omp_taskwait( ident_t *loc_ref, kmp_int32 gtid ) taskdata->td_taskwait_thread = - taskdata->td_taskwait_thread; #if OMPT_SUPPORT && OMPT_TRACE - if (ompt_enabled && - ompt_callbacks.ompt_callback(ompt_event_taskwait_end)) { - ompt_callbacks.ompt_callback(ompt_event_taskwait_end)( + if (ompt_enabled) + { + taskdata->ompt_task_info.frame.reenter_runtime_frame = 0; + if(ompt_callbacks.ompt_callback(ompt_event_taskwait_end)) { + ompt_callbacks.ompt_callback(ompt_event_taskwait_end)( my_parallel_id, my_task_id); + } } #endif } From bef673eed760a3f02f53d62ba59bfc9a6c0033f3 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Sun, 15 May 2016 00:37:41 +0200 Subject: [PATCH 19/46] adding size information for struct members --- runtime/src/ompd-specific.c | 10 +++++++++- runtime/src/ompd-specific.h | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index 3809e2255..bed100d0a 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -10,6 +10,10 @@ OMPD_FOREACH_ACCESS(ompd_declare_access) #undef ompd_declare_access +#define ompd_declare_sizeof_member(t,m) uint64_t ompd_sizeof__##t##__##m; +OMPD_FOREACH_ACCESS(ompd_declare_sizeof_member) +#undef ompd_declare_sizeof_member + #define ompd_declare_bitfield(t,m) uint64_t ompd_bitfield__##t##__##m; OMPD_FOREACH_BITFIELD(ompd_declare_bitfield) #undef ompd_declare_bitfield @@ -22,7 +26,7 @@ const char * * ompd_dll_locations=NULL; const char * ompd_my_dll_locations[2] = {"libompd_intel.so",NULL}; uint64_t ompd_state=0; -int ompd_rtl_version = 5; +int ompd_rtl_version = 6; void ompd_init() { @@ -52,6 +56,10 @@ OMPD_FOREACH_BITFIELD(ompd_init_bitfield) * Calculate type size information */ +#define ompd_init_sizeof_member(t,m) ompd_sizeof__##t##__##m = sizeof(((t*)0)->m); +OMPD_FOREACH_ACCESS(ompd_init_sizeof_member) +#undef ompd_init_sizeof_member + #define ompd_init_sizeof(t) ompd_sizeof__##t = sizeof(t); OMPD_FOREACH_SIZEOF(ompd_init_sizeof) #undef ompd_init_sizeof diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index efc1fbcdd..98fee75b9 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -57,6 +57,8 @@ OMPD_ACCESS(kmp_root_t, r) \ \ OMPD_ACCESS(kmp_internal_control_t, dynamic) \ OMPD_ACCESS(kmp_internal_control_t, max_active_levels) \ +OMPD_ACCESS(kmp_internal_control_t, nested) \ +OMPD_ACCESS(kmp_internal_control_t, nproc) \ OMPD_ACCESS(kmp_internal_control_t, proc_bind) \ OMPD_ACCESS(kmp_internal_control_t, sched) \ \ @@ -106,7 +108,7 @@ OMPD_SIZEOF(ompt_task_id_t) \ OMPD_SIZEOF(__kmp_avail_proc) \ OMPD_SIZEOF(__kmp_max_nth) \ OMPD_SIZEOF(__kmp_gtid) \ - +OMPD_SIZEOF(__kmp_nth) \ #endif /* OMPD_SUPPORT */ #endif From 432e053dfc0012c50d5a02c4141176bb27e8682a Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Wed, 27 Jul 2016 10:50:25 -0700 Subject: [PATCH 20/46] Fix the frame level pointed to by exit_runtime_frame --- runtime/src/kmp_gsupport.c | 6 +++--- runtime/src/kmp_tasking.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/src/kmp_gsupport.c b/runtime/src/kmp_gsupport.c index 0e50623f6..dfcb24370 100644 --- a/runtime/src/kmp_gsupport.c +++ b/runtime/src/kmp_gsupport.c @@ -266,7 +266,7 @@ __kmp_GOMP_microtask_wrapper(int *gtid, int *npr, void (*task)(void *), // set task frame ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->exit_runtime_frame = __builtin_frame_address(0); + ompt_frame->exit_runtime_frame = __builtin_frame_address(1); } #endif @@ -311,7 +311,7 @@ __kmp_GOMP_parallel_microtask_wrapper(int *gtid, int *npr, // set task frame ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->exit_runtime_frame = __builtin_frame_address(0); + ompt_frame->exit_runtime_frame = __builtin_frame_address(1); } #endif @@ -1000,7 +1000,7 @@ xexpand(KMP_API_NAME_GOMP_TASK)(void (*func)(void *), void *data, void (*copy_fu thread->th.ompt_thread_info.wait_id = 0; thread->th.ompt_thread_info.state = ompt_state_work_parallel; taskdata->ompt_task_info.frame.exit_runtime_frame = - __builtin_frame_address(0); + __builtin_frame_address(1); } #endif diff --git a/runtime/src/kmp_tasking.c b/runtime/src/kmp_tasking.c index abc4d1a59..5e8bc05b8 100644 --- a/runtime/src/kmp_tasking.c +++ b/runtime/src/kmp_tasking.c @@ -1173,7 +1173,7 @@ __kmp_invoke_task( kmp_int32 gtid, kmp_task_t *task, kmp_taskdata_t * current_ta oldInfo = thread->th.ompt_thread_info; thread->th.ompt_thread_info.wait_id = 0; thread->th.ompt_thread_info.state = ompt_state_work_parallel; - taskdata->ompt_task_info.frame.exit_runtime_frame = __builtin_frame_address(0); + taskdata->ompt_task_info.frame.exit_runtime_frame = __builtin_frame_address(1); } #endif From 83b61813097781bcceef5908af597990290ada56 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Thu, 28 Jul 2016 00:20:33 +0200 Subject: [PATCH 21/46] Fix the frame level pointed to by reenter_runtime_frame --- runtime/src/kmp_csupport.c | 4 ++-- runtime/src/kmp_gsupport.c | 20 ++++++++++---------- runtime/src/kmp_tasking.c | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/runtime/src/kmp_csupport.c b/runtime/src/kmp_csupport.c index 4c1d20411..07f325277 100644 --- a/runtime/src/kmp_csupport.c +++ b/runtime/src/kmp_csupport.c @@ -306,7 +306,7 @@ __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro microtask, ...) kmp_team_t *parent_team = master_th->th.th_team; if (ompt_enabled) { parent_team->t.t_implicit_task_taskdata[tid]. - ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(0); + ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(1); } #endif @@ -396,7 +396,7 @@ __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro microtask, ...) int tid = __kmp_tid_from_gtid( gtid ); if (ompt_enabled) { parent_team->t.t_implicit_task_taskdata[tid]. - ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(0); + ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(1); } #endif diff --git a/runtime/src/kmp_gsupport.c b/runtime/src/kmp_gsupport.c index 0e50623f6..27626540d 100644 --- a/runtime/src/kmp_gsupport.c +++ b/runtime/src/kmp_gsupport.c @@ -266,7 +266,7 @@ __kmp_GOMP_microtask_wrapper(int *gtid, int *npr, void (*task)(void *), // set task frame ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->exit_runtime_frame = __builtin_frame_address(0); + ompt_frame->exit_runtime_frame = __builtin_frame_address(1); } #endif @@ -311,7 +311,7 @@ __kmp_GOMP_parallel_microtask_wrapper(int *gtid, int *npr, // set task frame ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->exit_runtime_frame = __builtin_frame_address(0); + ompt_frame->exit_runtime_frame = __builtin_frame_address(1); } #endif @@ -446,7 +446,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_START)(void (*task)(void *), void *data, unsi if (ompt_enabled) { parent_frame = __ompt_get_task_frame_internal(0); - parent_frame->reenter_runtime_frame = __builtin_frame_address(0); + parent_frame->reenter_runtime_frame = __builtin_frame_address(1); } #endif @@ -499,7 +499,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) // Record that we re-entered the runtime system in the implicit // task frame representing the parallel region. ompt_frame = &task_info->frame; - ompt_frame->reenter_runtime_frame = __builtin_frame_address(0); + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); // unlink if necessary. no-op if there is not a lightweight task. ompt_lw_taskteam_t *lwt = __ompt_lw_taskteam_unlink(thr); @@ -513,7 +513,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) // remaining deepest task knows the stack frame where the runtime // was reentered. ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->reenter_runtime_frame = __builtin_frame_address(0); + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); } #endif } @@ -529,7 +529,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) // Set reenter frame in parent task, which will become current task // in the midst of join. This is needed before the end_parallel callback. ompt_frame = __ompt_get_task_frame_internal(1); - ompt_frame->reenter_runtime_frame = __builtin_frame_address(0); + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); } #endif @@ -559,7 +559,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) if (ompt_enabled) { // Record that we re-entered the runtime system in the frame that // created the parallel region. - ompt_frame->reenter_runtime_frame = __builtin_frame_address(0); + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); if (ompt_callbacks.ompt_callback(ompt_event_parallel_end)) { ompt_task_info_t *task_info = __ompt_get_taskinfo(0); @@ -907,7 +907,7 @@ LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT), \ ompt_frame_t *parent_frame; \ if (ompt_enabled) { \ parent_frame = __ompt_get_task_frame_internal(0); \ - parent_frame->reenter_runtime_frame = __builtin_frame_address(0); \ + parent_frame->reenter_runtime_frame = __builtin_frame_address(1); \ } @@ -1000,7 +1000,7 @@ xexpand(KMP_API_NAME_GOMP_TASK)(void (*func)(void *), void *data, void (*copy_fu thread->th.ompt_thread_info.wait_id = 0; thread->th.ompt_thread_info.state = ompt_state_work_parallel; taskdata->ompt_task_info.frame.exit_runtime_frame = - __builtin_frame_address(0); + __builtin_frame_address(1); } #endif @@ -1110,7 +1110,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START)(void (*task) (void *), void * if (ompt_enabled) { parent_frame = __ompt_get_task_frame_internal(0); - parent_frame->reenter_runtime_frame = __builtin_frame_address(0); + parent_frame->reenter_runtime_frame = __builtin_frame_address(1); } #endif diff --git a/runtime/src/kmp_tasking.c b/runtime/src/kmp_tasking.c index abc4d1a59..90e60615b 100644 --- a/runtime/src/kmp_tasking.c +++ b/runtime/src/kmp_tasking.c @@ -1173,7 +1173,7 @@ __kmp_invoke_task( kmp_int32 gtid, kmp_task_t *task, kmp_taskdata_t * current_ta oldInfo = thread->th.ompt_thread_info; thread->th.ompt_thread_info.wait_id = 0; thread->th.ompt_thread_info.state = ompt_state_work_parallel; - taskdata->ompt_task_info.frame.exit_runtime_frame = __builtin_frame_address(0); + taskdata->ompt_task_info.frame.exit_runtime_frame = __builtin_frame_address(1); } #endif @@ -1332,7 +1332,7 @@ __kmp_omp_task( kmp_int32 gtid, kmp_task_t * new_task, bool serialize_immediate #if OMPT_SUPPORT if (ompt_enabled) { new_taskdata->ompt_task_info.frame.reenter_runtime_frame = - __builtin_frame_address(0); + __builtin_frame_address(1); } #endif @@ -1417,7 +1417,7 @@ __kmpc_omp_taskwait( ident_t *loc_ref, kmp_int32 gtid ) my_task_id = taskdata->ompt_task_info.task_id; my_parallel_id = team->t.ompt_team_info.parallel_id; - taskdata->ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(0); + taskdata->ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(1); if (ompt_callbacks.ompt_callback(ompt_event_taskwait_begin)) { ompt_callbacks.ompt_callback(ompt_event_taskwait_begin)( my_parallel_id, my_task_id); From a677fc5cf780009604d785d15c21bf3a6784141b Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Fri, 5 Aug 2016 03:58:32 -0700 Subject: [PATCH 22/46] add scheduling parent --- runtime/src/include/45/ompt.h.var | 5 +++++ runtime/src/kmp_csupport.c | 19 ++++++++++++++--- runtime/src/kmp_gsupport.c | 20 +++++++++--------- runtime/src/kmp_tasking.c | 7 +++++-- runtime/src/ompd-specific.h | 1 + runtime/src/ompt-general.c | 5 +++++ runtime/src/ompt-internal.h | 3 ++- runtime/src/ompt-specific.c | 34 +++++++++++++++++++++++++++++++ 8 files changed, 78 insertions(+), 16 deletions(-) diff --git a/runtime/src/include/45/ompt.h.var b/runtime/src/include/45/ompt.h.var index 1f718c500..1f22c2d5a 100644 --- a/runtime/src/include/45/ompt.h.var +++ b/runtime/src/include/45/ompt.h.var @@ -25,6 +25,7 @@ \ macro (ompt_get_idle_frame) \ macro (ompt_get_task_frame) \ + macro (ompt_get_scheduling_task_frame) \ \ macro (ompt_get_state) \ \ @@ -408,6 +409,10 @@ OMPT_API_FUNCTION(ompt_frame_t *, ompt_get_task_frame, ( int depth )); +OMPT_API_FUNCTION(ompt_frame_t *, ompt_get_scheduling_task_frame, ( + int depth +)); + /**************************************************************************** diff --git a/runtime/src/kmp_csupport.c b/runtime/src/kmp_csupport.c index 4c1d20411..10512e83d 100644 --- a/runtime/src/kmp_csupport.c +++ b/runtime/src/kmp_csupport.c @@ -306,7 +306,7 @@ __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro microtask, ...) kmp_team_t *parent_team = master_th->th.th_team; if (ompt_enabled) { parent_team->t.t_implicit_task_taskdata[tid]. - ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(0); + ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(1); } #endif @@ -341,7 +341,7 @@ __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro microtask, ...) #if OMPT_SUPPORT if (ompt_enabled) { parent_team->t.t_implicit_task_taskdata[tid]. - ompt_task_info.frame.reenter_runtime_frame = 0; + ompt_task_info.frame.reenter_runtime_frame = NULL; } #endif } @@ -396,7 +396,7 @@ __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro microtask, ...) int tid = __kmp_tid_from_gtid( gtid ); if (ompt_enabled) { parent_team->t.t_implicit_task_taskdata[tid]. - ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(0); + ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(1); } #endif @@ -678,6 +678,14 @@ __kmpc_barrier(ident_t *loc, kmp_int32 global_tid) __kmp_check_barrier( global_tid, ct_barrier, loc ); } +#if OMPT_SUPPORT && OMPT_TRACE + ompt_frame_t * ompt_frame; + if (ompt_enabled ) { + ompt_frame = &( __kmp_threads[ global_tid ] -> th.th_team -> + t.t_implicit_task_taskdata[__kmp_tid_from_gtid(global_tid)].ompt_task_info.frame); + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); + } +#endif __kmp_threads[ global_tid ]->th.th_ident = loc; // TODO: explicit barrier_wait_id: // this function is called when 'barrier' directive is present or @@ -687,6 +695,11 @@ __kmpc_barrier(ident_t *loc, kmp_int32 global_tid) // 4) no sync is required __kmp_barrier( bs_plain_barrier, global_tid, FALSE, 0, NULL, NULL ); +#if OMPT_SUPPORT && OMPT_TRACE + if (ompt_enabled ) { + ompt_frame->reenter_runtime_frame = NULL; + } +#endif } /* The BARRIER for a MASTER section is always explicit */ diff --git a/runtime/src/kmp_gsupport.c b/runtime/src/kmp_gsupport.c index dfcb24370..32e7348d9 100644 --- a/runtime/src/kmp_gsupport.c +++ b/runtime/src/kmp_gsupport.c @@ -266,7 +266,7 @@ __kmp_GOMP_microtask_wrapper(int *gtid, int *npr, void (*task)(void *), // set task frame ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->exit_runtime_frame = __builtin_frame_address(1); + ompt_frame->exit_runtime_frame = __builtin_frame_address(0); } #endif @@ -311,7 +311,7 @@ __kmp_GOMP_parallel_microtask_wrapper(int *gtid, int *npr, // set task frame ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->exit_runtime_frame = __builtin_frame_address(1); + ompt_frame->exit_runtime_frame = __builtin_frame_address(0); } #endif @@ -446,7 +446,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_START)(void (*task)(void *), void *data, unsi if (ompt_enabled) { parent_frame = __ompt_get_task_frame_internal(0); - parent_frame->reenter_runtime_frame = __builtin_frame_address(0); + parent_frame->reenter_runtime_frame = __builtin_frame_address(1); } #endif @@ -499,7 +499,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) // Record that we re-entered the runtime system in the implicit // task frame representing the parallel region. ompt_frame = &task_info->frame; - ompt_frame->reenter_runtime_frame = __builtin_frame_address(0); + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); // unlink if necessary. no-op if there is not a lightweight task. ompt_lw_taskteam_t *lwt = __ompt_lw_taskteam_unlink(thr); @@ -513,7 +513,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) // remaining deepest task knows the stack frame where the runtime // was reentered. ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->reenter_runtime_frame = __builtin_frame_address(0); + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); } #endif } @@ -529,7 +529,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) // Set reenter frame in parent task, which will become current task // in the midst of join. This is needed before the end_parallel callback. ompt_frame = __ompt_get_task_frame_internal(1); - ompt_frame->reenter_runtime_frame = __builtin_frame_address(0); + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); } #endif @@ -559,7 +559,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_END)(void) if (ompt_enabled) { // Record that we re-entered the runtime system in the frame that // created the parallel region. - ompt_frame->reenter_runtime_frame = __builtin_frame_address(0); + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); if (ompt_callbacks.ompt_callback(ompt_event_parallel_end)) { ompt_task_info_t *task_info = __ompt_get_taskinfo(0); @@ -907,7 +907,7 @@ LOOP_NEXT_ULL(xexpand(KMP_API_NAME_GOMP_LOOP_ULL_ORDERED_RUNTIME_NEXT), \ ompt_frame_t *parent_frame; \ if (ompt_enabled) { \ parent_frame = __ompt_get_task_frame_internal(0); \ - parent_frame->reenter_runtime_frame = __builtin_frame_address(0); \ + parent_frame->reenter_runtime_frame = __builtin_frame_address(1); \ } @@ -1000,7 +1000,7 @@ xexpand(KMP_API_NAME_GOMP_TASK)(void (*func)(void *), void *data, void (*copy_fu thread->th.ompt_thread_info.wait_id = 0; thread->th.ompt_thread_info.state = ompt_state_work_parallel; taskdata->ompt_task_info.frame.exit_runtime_frame = - __builtin_frame_address(1); + __builtin_frame_address(0); } #endif @@ -1110,7 +1110,7 @@ xexpand(KMP_API_NAME_GOMP_PARALLEL_SECTIONS_START)(void (*task) (void *), void * if (ompt_enabled) { parent_frame = __ompt_get_task_frame_internal(0); - parent_frame->reenter_runtime_frame = __builtin_frame_address(0); + parent_frame->reenter_runtime_frame = __builtin_frame_address(1); } #endif diff --git a/runtime/src/kmp_tasking.c b/runtime/src/kmp_tasking.c index 5e8bc05b8..b4f0e4a5b 100644 --- a/runtime/src/kmp_tasking.c +++ b/runtime/src/kmp_tasking.c @@ -458,6 +458,9 @@ __kmp_task_start( kmp_int32 gtid, kmp_task_t * task, kmp_taskdata_t * current_ta taskdata->ompt_task_info.task_id, taskdata->ompt_task_info.function); } + if (ompt_enabled) + taskdata->ompt_task_info.scheduling_parent = current_task; + #endif #if OMP_40_ENABLED && OMPT_SUPPORT && OMPT_TRACE /* OMPT emit all dependences if requested by the tool */ @@ -1173,7 +1176,7 @@ __kmp_invoke_task( kmp_int32 gtid, kmp_task_t *task, kmp_taskdata_t * current_ta oldInfo = thread->th.ompt_thread_info; thread->th.ompt_thread_info.wait_id = 0; thread->th.ompt_thread_info.state = ompt_state_work_parallel; - taskdata->ompt_task_info.frame.exit_runtime_frame = __builtin_frame_address(1); + taskdata->ompt_task_info.frame.exit_runtime_frame = __builtin_frame_address(0); } #endif @@ -1332,7 +1335,7 @@ __kmp_omp_task( kmp_int32 gtid, kmp_task_t * new_task, bool serialize_immediate #if OMPT_SUPPORT if (ompt_enabled) { new_taskdata->ompt_task_info.frame.reenter_runtime_frame = - __builtin_frame_address(0); + __builtin_frame_address(1); } #endif diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index 98fee75b9..ad2f304c1 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -71,6 +71,7 @@ OMPD_ACCESS(kmp_taskdata_t, td_team) \ OMPD_ACCESS(kmp_team_p, t) \ \ OMPD_ACCESS(ompt_task_info_t, frame) \ +OMPD_ACCESS(ompt_task_info_t, scheduling_parent) \ OMPD_ACCESS(ompt_task_info_t, task_id) \ OMPD_ACCESS(ompt_task_info_t, function) \ \ diff --git a/runtime/src/ompt-general.c b/runtime/src/ompt-general.c index 7ba99a447..7a28720fd 100644 --- a/runtime/src/ompt-general.c +++ b/runtime/src/ompt-general.c @@ -421,6 +421,11 @@ OMPT_API_ROUTINE ompt_frame_t *ompt_get_task_frame(int depth) return __ompt_get_task_frame_internal(depth); } +OMPT_API_ROUTINE ompt_frame_t *ompt_get_scheduling_task_frame(int depth) +{ + return __ompt_get_scheduling_task_frame_internal(depth); +} + OMPT_API_ROUTINE void *ompt_get_task_function(int depth) { diff --git a/runtime/src/ompt-internal.h b/runtime/src/ompt-internal.h index 42da9d867..8dd0320c7 100644 --- a/runtime/src/ompt-internal.h +++ b/runtime/src/ompt-internal.h @@ -23,12 +23,13 @@ typedef struct ompt_callbacks_s { #undef ompt_event_macro } ompt_callbacks_t; - +typedef struct kmp_taskdata kmp_taskdata_t; typedef struct { ompt_frame_t frame; void* function; ompt_task_id_t task_id; + kmp_taskdata_t * scheduling_parent; #if OMP_40_ENABLED int ndeps; ompt_task_dependence_t *deps; diff --git a/runtime/src/ompt-specific.c b/runtime/src/ompt-specific.c index 49f668af1..c61810099 100644 --- a/runtime/src/ompt-specific.c +++ b/runtime/src/ompt-specific.c @@ -119,6 +119,32 @@ __ompt_get_taskinfo(int depth) return info; } +ompt_task_info_t * +__ompt_get_scheduling_taskinfo(int depth) +{ + ompt_task_info_t *info = NULL; + kmp_info_t *thr = ompt_get_thread(); + + if (thr) { + kmp_taskdata_t *taskdata = thr->th.th_current_task; +// ompt_lw_taskteam_t *lwt = LWT_FROM_TEAM(taskdata->td_team); + + while (depth > 0) { + + if (taskdata) { + taskdata = taskdata->ompt_task_info.scheduling_parent; + }else{ + return NULL; + } + depth--; + } + + info = &taskdata->ompt_task_info; + } + + return info; +} + //****************************************************************************** @@ -320,6 +346,14 @@ __ompt_get_task_frame_internal(int depth) return frame; } +ompt_frame_t * +__ompt_get_scheduling_task_frame_internal(int depth) +{ + ompt_task_info_t *info = __ompt_get_scheduling_taskinfo(depth); + ompt_frame_t *frame = info ? frame = &info->frame : NULL; + return frame; +} + //---------------------------------------------------------- // team support From d9b1d6139ac1a230f43495fa555bd9bbdd78c094 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Fri, 5 Aug 2016 17:12:39 +0200 Subject: [PATCH 23/46] Fix some task frame information: * save exit address to lwt if available * reset exit address after task invokation --- runtime/src/kmp_csupport.c | 21 ++++++++++++++------- runtime/src/kmp_runtime.c | 12 ++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/runtime/src/kmp_csupport.c b/runtime/src/kmp_csupport.c index 10512e83d..e50f14e78 100644 --- a/runtime/src/kmp_csupport.c +++ b/runtime/src/kmp_csupport.c @@ -301,12 +301,20 @@ __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro microtask, ...) va_start( ap, microtask ); #if OMPT_SUPPORT - int tid = __kmp_tid_from_gtid( gtid ); - kmp_info_t *master_th = __kmp_threads[ gtid ]; - kmp_team_t *parent_team = master_th->th.th_team; + ompt_frame_t* ompt_frame; if (ompt_enabled) { - parent_team->t.t_implicit_task_taskdata[tid]. - ompt_task_info.frame.reenter_runtime_frame = __builtin_frame_address(1); + kmp_info_t *master_th = __kmp_threads[ gtid ]; + kmp_team_t *parent_team = master_th->th.th_team; + ompt_lw_taskteam_t *lwt = parent_team->t.ompt_serialized_team_info; + if (lwt) + ompt_frame = &(lwt->ompt_task_info.frame); + else + { + int tid = __kmp_tid_from_gtid( gtid ); + ompt_frame = &(parent_team->t.t_implicit_task_taskdata[tid]. + ompt_task_info.frame); + } + ompt_frame->reenter_runtime_frame = __builtin_frame_address(1); } #endif @@ -340,8 +348,7 @@ __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro microtask, ...) #if OMPT_SUPPORT if (ompt_enabled) { - parent_team->t.t_implicit_task_taskdata[tid]. - ompt_task_info.frame.reenter_runtime_frame = NULL; + ompt_frame->reenter_runtime_frame = NULL; } #endif } diff --git a/runtime/src/kmp_runtime.c b/runtime/src/kmp_runtime.c index 04179fd6b..766b71541 100644 --- a/runtime/src/kmp_runtime.c +++ b/runtime/src/kmp_runtime.c @@ -1558,6 +1558,9 @@ __kmp_fork_call( , exit_runtime_p #endif ); +#if OMPT_SUPPORT + *exit_runtime_p=0; +#endif } #if OMPT_SUPPORT @@ -1760,6 +1763,9 @@ __kmp_fork_call( , exit_runtime_p #endif ); +#if OMPT_SUPPORT + *exit_runtime_p=0; +#endif } #if OMPT_SUPPORT @@ -1867,6 +1873,9 @@ __kmp_fork_call( , exit_runtime_p #endif ); +#if OMPT_SUPPORT + *exit_runtime_p=0; +#endif } #if OMPT_SUPPORT @@ -6844,6 +6853,9 @@ __kmp_invoke_task_func( int gtid ) , exit_runtime_p #endif ); +#if OMPT_SUPPORT + *exit_runtime_p=0; +#endif } #if USE_ITT_BUILD From f7789ecf151da786ac45aa5155600d63082100f1 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Sun, 7 Aug 2016 23:01:32 +0200 Subject: [PATCH 24/46] Fix team unrolling for presence of lwt --- runtime/src/ompt-specific.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/runtime/src/ompt-specific.c b/runtime/src/ompt-specific.c index c61810099..da2bee453 100644 --- a/runtime/src/ompt-specific.c +++ b/runtime/src/ompt-specific.c @@ -60,7 +60,12 @@ __ompt_get_teaminfo(int depth, int *size) // next heavyweight team (if any) after // lightweight teams are exhausted - if (!lwt && team) team=team->t.t_parent; + if (!lwt && team) { + team=team->t.t_parent; + if (team) { + lwt = LWT_FROM_TEAM(team); + } + } depth--; } From e52915298fa9c6db46b0b83ac0244da734776a2f Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Sun, 7 Aug 2016 23:03:26 +0200 Subject: [PATCH 25/46] Add OMPD offset information necessary for lwt handling --- runtime/src/ompd-specific.c | 2 +- runtime/src/ompd-specific.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/runtime/src/ompd-specific.c b/runtime/src/ompd-specific.c index bed100d0a..bc4efa8a1 100644 --- a/runtime/src/ompd-specific.c +++ b/runtime/src/ompd-specific.c @@ -26,7 +26,7 @@ const char * * ompd_dll_locations=NULL; const char * ompd_my_dll_locations[2] = {"libompd_intel.so",NULL}; uint64_t ompd_state=0; -int ompd_rtl_version = 6; +int ompd_rtl_version = 7; void ompd_init() { diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index ad2f304c1..3f499d736 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -34,6 +34,7 @@ OMPD_ACCESS(kmp_base_info_t, ompt_thread_info) \ OMPD_ACCESS(kmp_base_root_t, r_in_parallel) \ \ OMPD_ACCESS(kmp_base_team_t, ompt_team_info) \ +OMPD_ACCESS(kmp_base_team_t, ompt_serialized_team_info) \ OMPD_ACCESS(kmp_base_team_t, t_active_level) \ OMPD_ACCESS(kmp_base_team_t, t_implicit_task_taskdata) \ OMPD_ACCESS(kmp_base_team_t, t_master_tid) \ @@ -83,6 +84,10 @@ OMPD_ACCESS(ompt_thread_info_t, wait_id) \ \ OMPD_ACCESS(ompt_frame_t, reenter_runtime_frame) \ OMPD_ACCESS(ompt_frame_t, exit_runtime_frame) \ +\ +OMPD_ACCESS(ompt_lw_taskteam_t, parent) \ +OMPD_ACCESS(ompt_lw_taskteam_t, ompt_team_info) \ +OMPD_ACCESS(ompt_lw_taskteam_t, ompt_task_info) #define OMPD_FOREACH_BITFIELD(OMPD_BITFIELD) \ From 0091c9e149dcea448ecd397dd240dcf547236018 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Tue, 8 Nov 2016 09:34:01 +0100 Subject: [PATCH 26/46] fix regression introduced while merging --- runtime/src/kmp_gsupport.c | 6 +++--- runtime/src/kmp_tasking.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/src/kmp_gsupport.c b/runtime/src/kmp_gsupport.c index 528b0432a..a3af189d2 100644 --- a/runtime/src/kmp_gsupport.c +++ b/runtime/src/kmp_gsupport.c @@ -273,7 +273,7 @@ __kmp_GOMP_microtask_wrapper(int *gtid, int *npr, void (*task)(void *), // set task frame ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->exit_runtime_frame = __builtin_frame_address(1); + ompt_frame->exit_runtime_frame = __builtin_frame_address(0); } #endif @@ -318,7 +318,7 @@ __kmp_GOMP_parallel_microtask_wrapper(int *gtid, int *npr, // set task frame ompt_frame = __ompt_get_task_frame_internal(0); - ompt_frame->exit_runtime_frame = __builtin_frame_address(1); + ompt_frame->exit_runtime_frame = __builtin_frame_address(0); } #endif @@ -986,7 +986,7 @@ xexpand(KMP_API_NAME_GOMP_TASK)(void (*func)(void *), void *data, void (*copy_fu thread->th.ompt_thread_info.wait_id = 0; thread->th.ompt_thread_info.state = ompt_state_work_parallel; taskdata->ompt_task_info.frame.exit_runtime_frame = - __builtin_frame_address(1); + __builtin_frame_address(0); } #endif diff --git a/runtime/src/kmp_tasking.c b/runtime/src/kmp_tasking.c index e2e457fb5..cb6ea6b8f 100644 --- a/runtime/src/kmp_tasking.c +++ b/runtime/src/kmp_tasking.c @@ -1222,7 +1222,7 @@ __kmp_invoke_task( kmp_int32 gtid, kmp_task_t *task, kmp_taskdata_t * current_ta oldInfo = thread->th.ompt_thread_info; thread->th.ompt_thread_info.wait_id = 0; thread->th.ompt_thread_info.state = ompt_state_work_parallel; - taskdata->ompt_task_info.frame.exit_runtime_frame = __builtin_frame_address(1); + taskdata->ompt_task_info.frame.exit_runtime_frame = __builtin_frame_address(0); } #endif From 99c50892dd151edb22125219354567ca406a743b Mon Sep 17 00:00:00 2001 From: Ariel Burton Date: Fri, 20 Jan 2017 12:44:43 -0500 Subject: [PATCH 27/46] Small changes to allow the names of the variables needed by OMPD to be listed. Small changes to allow the names of the set of variables that the OMPD may need to satisfy requests from the debugger. The file generated by the changes to the CMakefile is not generated by default, and is not built into the runtime. So there should be absolutely no performance impact at all. What it does do is provide a convenient way to expand out the names that the debugger will eventually be asked about. Changes to be committed: modified: runtime/src/CMakeLists.txt new file: runtime/src/ompd-symbols.c.in --- runtime/src/CMakeLists.txt | 18 ++++++++++++++++++ runtime/src/ompd-symbols.c.in | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 runtime/src/ompd-symbols.c.in diff --git a/runtime/src/CMakeLists.txt b/runtime/src/CMakeLists.txt index 6aa82d0f2..433e22112 100644 --- a/runtime/src/CMakeLists.txt +++ b/runtime/src/CMakeLists.txt @@ -261,6 +261,24 @@ if(${LIBOMP_FORTRAN_MODULES}) set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES omp_lib${CMAKE_C_OUTPUT_EXTENSION}) endif() +# generate a C file containing the names of the variables that encode +# size and offset information for OMPD. +# This is not built into the runtime, but can be generated by invoking +# "gmake ompd-symbols". This will create a .c file in the build area, +# which be examined as needed. +libomp_get_cflags(OMPD_SYMBOLS_CFLAGS) +get_property(ompd_symbols_inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES) +message("OMPD_SYMBOLS_INC_DIRS == ${ompd_symbols_inc_dirs}") +foreach(d ${ompd_symbols_inc_dirs}) + set(OMPD_SYMBOLS_CFLAGS "${OMPD_SYMBOLS_CFLAGS} -I${d}") +endforeach() +SEPARATE_ARGUMENTS(OMPD_SYMBOLS_CFLAGS) +add_custom_target( + ompd-symbols + DEPENDS ${LIBOMP_SRC_DIR}/ompd-symbols.c.in + COMMAND ${CMAKE_C_COMPILER} -C -E -x c ${OMPD_SYMBOLS_CFLAGS} ${LIBOMP_SRC_DIR}/ompd-symbols.c.in | ${PERL_EXECUTABLE} -p -e "'s@___NEWLINE___@\\n@g'" > ${CMAKE_CURRENT_BINARY_DIR}/ompd-symbols.c +) + # Move files to exports/ directory if requested if(${LIBOMP_COPY_EXPORTS}) include(LibompExports) diff --git a/runtime/src/ompd-symbols.c.in b/runtime/src/ompd-symbols.c.in new file mode 100644 index 000000000..aec3951b6 --- /dev/null +++ b/runtime/src/ompd-symbols.c.in @@ -0,0 +1,33 @@ + +#include "ompd-specific.h" + + +#if OMPD_SUPPORT + +const char *ompd_symbols [] = { + + /* OMPD_FOREACH_ACCESS: ompd_access__##t##__##m, */ +# define ompd_define_symbol_string(t,m) "ompd_access__" #t "__" #m ,___NEWLINE___ +OMPD_FOREACH_ACCESS(ompd_define_symbol_string) +# undef ompd_define_symbol_string + + /* OMPD_FOREACH_ACCESS: ompd_sizeof__##t##__##m, */ +# define ompd_define_symbol_string(t,m) "ompd_sizeof__" #t "__" #m,___NEWLINE___ +OMPD_FOREACH_ACCESS(ompd_define_symbol_string) +# undef ompd_define_symbol_string + + /* OMPD_FOREACH_BITFIELD: ompd_bitfield__##t##__##m, */ +# define ompd_define_symbol_string(t,m) "ompd_bitfield__" #t "__" #m,___NEWLINE___ +OMPD_FOREACH_BITFIELD(ompd_define_symbol_string) +# undef ompd_define_symbol_string + + /* OMPD_FOREACH_SIZEOF: ompd_sizeof__##t, */ +# define ompd_define_symbol_string(t) "ompd_sizeof__" #t,___NEWLINE___ +OMPD_FOREACH_SIZEOF(ompd_define_symbol_string) +# undef ompd_define_symbol_string + + 0 +}; /* ompd_symbols */ + +#endif + From 35bc35199abbda5a31051f227b90a05e83a76335 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Fri, 2 Feb 2018 09:34:38 -0600 Subject: [PATCH 28/46] Cleanup OMPT after merge --- runtime/CMakeLists.txt | 9 +++------ runtime/src/CMakeLists.txt | 2 +- runtime/src/kmp_runtime.cpp | 8 +------- runtime/src/kmp_tasking.cpp | 3 --- runtime/src/ompt-internal.h | 2 -- 5 files changed, 5 insertions(+), 19 deletions(-) diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index f4463a833..3770a7cb9 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -194,12 +194,6 @@ elseif("${libomp_build_type_lowercase}" STREQUAL "minsizerel") set(MINSIZEREL_BUILD TRUE) endif() -# OMPD-support -set(OMPD_SUPPORT FALSE) -if("${ompd_support}") # string "on" or "ON" is seen as boolean TRUE - set(OMPD_SUPPORT TRUE) -endif() - # Include itt notify interface? set(LIBOMP_USE_ITT_NOTIFY TRUE CACHE BOOL "Enable ITT notify?") @@ -314,6 +308,9 @@ endif() set(LIBOMP_OMPT_SUPPORT ${OMPT_DEFAULT} CACHE BOOL "OMPT-support?") +set(LIBOMP_OMPD_SUPPORT FALSE CACHE BOOL "OMPD-support?") + + set(LIBOMP_OMPT_DEBUG FALSE CACHE BOOL "Trace OMPT initialization?") set(LIBOMP_OMPT_OPTIONAL TRUE CACHE BOOL diff --git a/runtime/src/CMakeLists.txt b/runtime/src/CMakeLists.txt index fc7af408b..b831adb0c 100644 --- a/runtime/src/CMakeLists.txt +++ b/runtime/src/CMakeLists.txt @@ -194,7 +194,7 @@ if(WIN32) libomp_append(LIBOMP_MASM_DEFINITIONS "-D_M_IA32" IF_TRUE IA32) libomp_append(LIBOMP_MASM_DEFINITIONS "-D_M_AMD64" IF_TRUE INTEL64) libomp_append(LIBOMP_MASM_DEFINITIONS "-DOMPT_SUPPORT" IF_TRUE_1_0 LIBOMP_OMPT_SUPPORT) - libomp_append(LIBOMP_MASM_DEFINITIONS "OMPD_SUPPORT" IF_TRUE_1_0 LIBOMP_OMPD_SUPPORT) + libomp_append(LIBOMP_MASM_DEFINITIONS "-DOMPD_SUPPORT" IF_TRUE_1_0 LIBOMP_OMPD_SUPPORT) libomp_list_to_string("${LIBOMP_MASM_DEFINITIONS}" LIBOMP_MASM_DEFINITIONS) set_property(SOURCE z_Windows_NT-586_asm.asm APPEND_STRING PROPERTY COMPILE_FLAGS " ${LIBOMP_MASM_DEFINITIONS}") set_source_files_properties(thirdparty/ittnotify/ittnotify_static.c PROPERTIES COMPILE_DEFINITIONS "UNICODE") diff --git a/runtime/src/kmp_runtime.cpp b/runtime/src/kmp_runtime.cpp index 0ead7f300..7c19d5cfd 100644 --- a/runtime/src/kmp_runtime.cpp +++ b/runtime/src/kmp_runtime.cpp @@ -1792,14 +1792,11 @@ int __kmp_fork_call(ident_t *loc, int gtid, exit_runtime_p #endif ); -#if OMPT_SUPPORT - *exit_runtime_p=0; -#endif } #if OMPT_SUPPORT if (ompt_enabled.enabled) { - exit_runtime_p = NULL; + *exit_runtime_p = NULL; if (ompt_enabled.ompt_callback_implicit_task) { ompt_callbacks.ompt_callback(ompt_callback_implicit_task)( ompt_scope_end, NULL, &(task_info->task_data), 1, @@ -1897,9 +1894,6 @@ int __kmp_fork_call(ident_t *loc, int gtid, exit_runtime_p #endif ); -#if OMPT_SUPPORT - *exit_runtime_p=0; -#endif } #if OMPT_SUPPORT diff --git a/runtime/src/kmp_tasking.cpp b/runtime/src/kmp_tasking.cpp index c9e01aec4..fe5713357 100644 --- a/runtime/src/kmp_tasking.cpp +++ b/runtime/src/kmp_tasking.cpp @@ -587,9 +587,6 @@ void __kmpc_omp_task_begin_if0(ident_t *loc_ref, kmp_int32 gtid, OMPT_LOAD_RETURN_ADDRESS(gtid)); return; } - if (ompt_enabled) - taskdata->ompt_task_info.scheduling_parent = current_task; - #endif __kmpc_omp_task_begin_if0_template(loc_ref, gtid, task, NULL, NULL); } diff --git a/runtime/src/ompt-internal.h b/runtime/src/ompt-internal.h index dd040099b..6139e002f 100644 --- a/runtime/src/ompt-internal.h +++ b/runtime/src/ompt-internal.h @@ -39,8 +39,6 @@ typedef struct ompt_callbacks_active_s { (info->td_flags.final ? ompt_task_final : 0x0) | \ (info->td_flags.merged_if0 ? ompt_task_mergeable : 0x0) -//typedef struct kmp_taskdata kmp_taskdata_t; - typedef struct { ompt_frame_t frame; ompt_data_t task_data; From 26783267abd64031d01e144d3ee8d831d9af7006 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Fri, 2 Feb 2018 09:44:40 -0600 Subject: [PATCH 29/46] Let the code compile with OMPD_SUPPORT --- runtime/src/ompd-specific.cpp | 8 ++++---- runtime/src/ompd-specific.h | 19 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/runtime/src/ompd-specific.cpp b/runtime/src/ompd-specific.cpp index bc4efa8a1..89892e00c 100644 --- a/runtime/src/ompd-specific.cpp +++ b/runtime/src/ompd-specific.cpp @@ -72,23 +72,23 @@ OMPD_FOREACH_SIZEOF(ompd_init_sizeof) { fprintf(stderr, "OMP_OMPD active\n"); - ompt_enabled = 1; + ompt_enabled.enabled = 1; ompd_state |= OMPD_ENABLE_BP; } ompd_initialized = 1; } -void omp_ompd_enable ( void ) +/*void omp_ompd_enable ( void ) { fprintf(stderr, "OMP_OMPD active\n"); - ompt_enabled = 1; + ompt_enabled.enabled = 1; ompd_state |= OMPD_ENABLE_BP; #ifdef OMPD_SUPPORT ompt_post_init(); #endif -} +}*/ void ompd_dll_locations_valid ( void ){ /* naive way of implementing hard to opt-out empty function diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index 3f499d736..d0f32422f 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -73,17 +73,20 @@ OMPD_ACCESS(kmp_team_p, t) \ \ OMPD_ACCESS(ompt_task_info_t, frame) \ OMPD_ACCESS(ompt_task_info_t, scheduling_parent) \ -OMPD_ACCESS(ompt_task_info_t, task_id) \ -OMPD_ACCESS(ompt_task_info_t, function) \ +OMPD_ACCESS(ompt_task_info_t, task_data) \ +/*OMPD_ACCESS(ompt_task_info_t, function)*/ \ \ -OMPD_ACCESS(ompt_team_info_t, parallel_id) \ -OMPD_ACCESS(ompt_team_info_t, microtask) \ +OMPD_ACCESS(ompt_team_info_t, parallel_data) \ +/*OMPD_ACCESS(ompt_team_info_t, microtask)*/ \ \ OMPD_ACCESS(ompt_thread_info_t, state) \ OMPD_ACCESS(ompt_thread_info_t, wait_id) \ \ -OMPD_ACCESS(ompt_frame_t, reenter_runtime_frame) \ -OMPD_ACCESS(ompt_frame_t, exit_runtime_frame) \ +OMPD_ACCESS(ompt_data_t, value) \ +OMPD_ACCESS(ompt_data_t, ptr) \ +\ +OMPD_ACCESS(ompt_frame_t, exit_frame) \ +OMPD_ACCESS(ompt_frame_t, enter_frame) \ \ OMPD_ACCESS(ompt_lw_taskteam_t, parent) \ OMPD_ACCESS(ompt_lw_taskteam_t, ompt_team_info) \ @@ -109,8 +112,8 @@ OMPD_SIZEOF(kmp_info_t) \ OMPD_SIZEOF(kmp_taskdata_t) \ OMPD_SIZEOF(kmp_tasking_flags_t) \ OMPD_SIZEOF(kmp_thread_t) \ -OMPD_SIZEOF(ompt_parallel_id_t) \ -OMPD_SIZEOF(ompt_task_id_t) \ +OMPD_SIZEOF(ompt_data_t) \ +OMPD_SIZEOF(ompt_id_t) \ OMPD_SIZEOF(__kmp_avail_proc) \ OMPD_SIZEOF(__kmp_max_nth) \ OMPD_SIZEOF(__kmp_gtid) \ From 30445f190df111d93be7412ba224e24bd48541bb Mon Sep 17 00:00:00 2001 From: Ignacio Laguna Date: Fri, 2 Feb 2018 19:08:33 -0800 Subject: [PATCH 30/46] Adding OMPD library directory, but it has problems with sed command to generate ompd.h --- CMakeLists.txt | 3 + libompd/CMakeLists.txt | 3 + libompd/src/CMakeLists.txt | 35 + libompd/src/Debug.cpp | 6 + libompd/src/Debug.h | 58 + libompd/src/TargetValue.cpp | 391 +++++++ libompd/src/TargetValue.h | 252 +++++ libompd/src/ompd-template.h | 1115 ++++++++++++++++++ libompd/src/ompd_intel.cpp | 1797 ++++++++++++++++++++++++++++++ libompd/src/ompd_intel.h | 90 ++ libompd/src/ompd_test.c | 81 ++ libompd/src/ompd_test.h | 29 + libompd/src/split_def_typedef.sh | 6 + 13 files changed, 3866 insertions(+) create mode 100644 libompd/CMakeLists.txt create mode 100644 libompd/src/CMakeLists.txt create mode 100644 libompd/src/Debug.cpp create mode 100644 libompd/src/Debug.h create mode 100644 libompd/src/TargetValue.cpp create mode 100644 libompd/src/TargetValue.h create mode 100644 libompd/src/ompd-template.h create mode 100644 libompd/src/ompd_intel.cpp create mode 100644 libompd/src/ompd_intel.h create mode 100644 libompd/src/ompd_test.c create mode 100644 libompd/src/ompd_test.h create mode 100755 libompd/src/split_def_typedef.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 8afa0df73..14fc4d680 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,9 @@ set(OPENMP_TEST_OPENMP_FLAGS ${OPENMP_TEST_COMPILER_OPENMP_FLAGS} CACHE STRING add_subdirectory(runtime) +# Build OMPD +add_subdirectory(libompd) + set(ENABLE_LIBOMPTARGET ON) # Currently libomptarget cannot be compiled on Windows or MacOS X. # Since the device plugins are only supported on Linux anyway, diff --git a/libompd/CMakeLists.txt b/libompd/CMakeLists.txt new file mode 100644 index 000000000..c07b50a77 --- /dev/null +++ b/libompd/CMakeLists.txt @@ -0,0 +1,3 @@ + + +add_subdirectory(src) diff --git a/libompd/src/CMakeLists.txt b/libompd/src/CMakeLists.txt new file mode 100644 index 000000000..46b887c87 --- /dev/null +++ b/libompd/src/CMakeLists.txt @@ -0,0 +1,35 @@ +project (libompd) + +add_library (ompd_intel SHARED TargetValue.cpp ompd_intel.cpp) + +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + +include_directories ( + ${CMAKE_BINARY_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR} +) + +file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/include) + +ADD_CUSTOM_TARGET ( + ompd-header ALL + DEPENDS ${CMAKE_BINARY_DIR}/include/ompd.h ${CMAKE_BINARY_DIR}/include/ompd_typedefs.h +) + +add_custom_command ( + OUTPUT ${CMAKE_BINARY_DIR}/include/ompd.h ${CMAKE_BINARY_DIR}/include/ompd_typedefs.h + COMMAND ${BASH} + ARGS ${CMAKE_CURRENT_SOURCE_DIR}/split_def_typedef.sh + ${CMAKE_CURRENT_SOURCE_DIR}/ompd-template.h + ${CMAKE_BINARY_DIR}/include/ompd_typedefs.h + ${CMAKE_BINARY_DIR}/include/ompd.h + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ompd-template.h +) + +INSTALL( TARGETS ompd_intel + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib/static + RUNTIME DESTINATION bin ) + +INSTALL(FILES ${CMAKE_BINARY_DIR}/include/ompd.h DESTINATION include) + diff --git a/libompd/src/Debug.cpp b/libompd/src/Debug.cpp new file mode 100644 index 000000000..786fad601 --- /dev/null +++ b/libompd/src/Debug.cpp @@ -0,0 +1,6 @@ +#include "Debug.h" + + std::ostream& GdbColor::operator<<(std::ostream& os, GdbColor::Code code) { + return os << "\033[" << static_cast(code) << "m"; + } + diff --git a/libompd/src/Debug.h b/libompd/src/Debug.h new file mode 100644 index 000000000..adb0877d5 --- /dev/null +++ b/libompd/src/Debug.h @@ -0,0 +1,58 @@ +#include +#include + +#ifndef GDB_DEBUG_H_ +#define GDB_DEBUG_H_ + + +namespace GdbColor { + enum Code { + FG_RED = 31, + FG_GREEN = 32, + FG_BLUE = 34, + FG_DEFAULT = 39, + BG_RED = 41, + BG_GREEN = 42, + BG_BLUE = 44, + BG_DEFAULT = 49 + }; +// std::ostream& operator<<(std::ostream& os, Code code); + std::ostream& operator<<(std::ostream& os, Code code) { + return os << "\033[" << static_cast(code) << "m"; + } +} + + //class ColorOut: public std::ostream + class ColorOut + { + private: + std::ostream& out; + GdbColor::Code color; + public: + ColorOut(std::ostream& _out, GdbColor::Code _color):out(_out), color(_color){} + template + const ColorOut& operator<< (const T& val) const + {out << color << val << GdbColor::FG_DEFAULT; + return *this;} +/* template + const ColorOut& operator<< (const T* val) const + {out << GdbColor::FG_RED << val << GdbColor::FG_DEFAULT; + return *this;} + template > + const ColorOut& operator<< ( const + std::basic_ios<_CharT,_Traits>& (*pf)(std::basic_ios<_CharT,_Traits>&))const + {out << GdbColor::FG_RED << pf << GdbColor::FG_DEFAULT; + return *this;} +*/ + const ColorOut& operator<< (std::ostream& (*pf)(std::ostream&)) const + {out << color << pf << GdbColor::FG_DEFAULT; + return *this;} + + }; + +static ColorOut dout(std::cout, GdbColor::FG_RED); +static ColorOut sout(std::cout, GdbColor::FG_GREEN); +static ColorOut hout(std::cout, GdbColor::FG_BLUE); + + +#endif /*GDB_DEBUG_H_*/ diff --git a/libompd/src/TargetValue.cpp b/libompd/src/TargetValue.cpp new file mode 100644 index 000000000..e5b77ca2a --- /dev/null +++ b/libompd/src/TargetValue.cpp @@ -0,0 +1,391 @@ + +#include "TargetValue.h" +#include "Debug.h" +#include +#include +#include + +const ompd_callbacks_t *TValue::callbacks=NULL; +ompd_target_type_sizes_t TValue::type_sizes; + +inline int ompd_sizeof(ompd_target_prim_types_t t) +{ + return (((int*)&TValue::type_sizes)[(int)t]); +} + +TType& TTypeFactory::getType( + ompd_address_space_context_t *context, + const char * typeName, + ompd_taddr_t segment +) +{ + TType empty(true); + + if ( ttypes.find(context) == ttypes.end() ) { + std::map empty; + ttypes[context] = empty; + } + + auto t = ttypes.find(context); + auto i = t->second.find(typeName); + if ( i == t->second.end() ) + i = t->second.insert(i, std::make_pair(typeName, TType(context, typeName, segment))); + else + i->second.context = context; + + return i->second; +} + + +TType::TType(ompd_address_space_context_t *_context, + const char* _typeName, + ompd_taddr_t _segment) : typeSize(0), fieldOffsets(), descSegment(_segment), + typeName(_typeName), context(_context), isvoid(false) +{ +} + +ompd_rc_t TType::getSize(ompd_size_t * size) +{ + ompd_rc_t ret = ompd_rc_ok; + if(typeSize==0) + { + ompd_address_t symbolAddr; + ompd_size_t tmpSize; + std::stringstream ss; + ss << "ompd_sizeof__" << typeName; + ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), &symbolAddr); + if (ret!=ompd_rc_ok){ + dout << "missing symbol " + << ss.str() + << " add this to ompd-specific.h:\nOMPD_SIZEOF(" << typeName << ") \\" + << std::endl; + return ret; + } + symbolAddr.segment = descSegment; + + ret = TValue::callbacks->read_tmemory(context, NULL, symbolAddr, + 1 * ompd_sizeof(ompd_type_long_long), &(tmpSize)); + if (ret!=ompd_rc_ok) + return ret; + ret = TValue::callbacks->target_to_host(context, &tmpSize, + ompd_sizeof(ompd_type_long_long), 1, &(typeSize)); + } + *size = typeSize; + return ret; +} + +ompd_rc_t TType::getBitfieldMask (const char* fieldName, uint64_t * bitfieldmask) +{ + ompd_rc_t ret = ompd_rc_ok; + auto i = bitfieldMasks.find(fieldName); + if ( i == bitfieldMasks.end() ) + { + uint64_t tmpMask, bitfieldMask; + ompd_address_t symbolAddr; +// ret = callbacks->ttype_offset(context, &OmpdTypeHandle, fieldName, &fieldOffset); + std::stringstream ss; + ss << "ompd_bitfield__" << typeName << "__" << fieldName; + ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), &symbolAddr); + if (ret!=ompd_rc_ok){ + dout << "missing symbol " << ss.str() << " add this to ompd-specific.h:\nOMPD_BITFIELD(" << typeName << "," << fieldName << ") \\" << std::endl; + return ret; + } + symbolAddr.segment = descSegment; + + ret = TValue::callbacks->read_tmemory(context, NULL, symbolAddr, + 1 * ompd_sizeof( ompd_type_long_long), &(tmpMask)); + if (ret!=ompd_rc_ok) + return ret; + ret = TValue::callbacks->target_to_host(context, &(tmpMask), + ompd_sizeof(ompd_type_long_long), 1, &(bitfieldMask)); + if (ret!=ompd_rc_ok){ + return ret; + } + i = bitfieldMasks.insert(i,std::make_pair(fieldName, bitfieldMask)); + } + *bitfieldmask = i->second; + return ret; +} + +ompd_rc_t TType::getElementOffset(const char* fieldName, ompd_size_t * offset) +{ + ompd_rc_t ret = ompd_rc_ok; + auto i = fieldOffsets.find(fieldName); + if ( i == fieldOffsets.end() ) + { + ompd_size_t tmpOffset, fieldOffset; + ompd_address_t symbolAddr; +// ret = callbacks->ttype_offset(context, &OmpdTypeHandle, fieldName, &fieldOffset); + std::stringstream ss; + ss << "ompd_access__" << typeName << "__" << fieldName; + ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), &symbolAddr); + if (ret!=ompd_rc_ok){ + dout << "missing symbol " << ss.str() << " add this to ompd-specific.h:\nOMPD_ACCESS(" << typeName << "," << fieldName << ") \\" << std::endl; + return ret; + } + symbolAddr.segment = descSegment; + + ret = TValue::callbacks->read_tmemory(context, NULL, symbolAddr, + 1* ompd_sizeof(ompd_type_long_long), &(tmpOffset)); + if (ret!=ompd_rc_ok) + return ret; + ret = TValue::callbacks->target_to_host(context, &(tmpOffset), + ompd_sizeof(ompd_type_long_long), 1, &fieldOffset); + if (ret!=ompd_rc_ok){ + return ret; + } + i = fieldOffsets.insert(i,std::make_pair(fieldName, fieldOffset)); + } + *offset = i->second; + return ret; +} + +ompd_rc_t TType::getElementSize(const char* fieldName, ompd_size_t * size) +{ + ompd_rc_t ret = ompd_rc_ok; + auto i = fieldSizes.find(fieldName); + if ( i == fieldSizes.end() ) + { + ompd_size_t tmpOffset, fieldSize; + ompd_address_t symbolAddr; +// ret = callbacks->ttype_offset(context, &OmpdTypeHandle, fieldName, &fieldOffset); + std::stringstream ss; + ss << "ompd_sizeof__" << typeName << "__" << fieldName; + ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), &symbolAddr); + if (ret!=ompd_rc_ok){ + dout << "missing symbol " << ss.str() << " add this to ompd-specific.h:\nOMPD_ACCESS(" << typeName << "," << fieldName << ") \\" << std::endl; + return ret; + } + symbolAddr.segment = descSegment; + + ret = TValue::callbacks->read_tmemory(context, NULL, symbolAddr, + 1* ompd_sizeof(ompd_type_long_long), &(tmpOffset)); + if (ret!=ompd_rc_ok) + return ret; + ret = TValue::callbacks->target_to_host(context, &tmpOffset, + ompd_sizeof(ompd_type_long_long), 1, &fieldSize); + if (ret!=ompd_rc_ok){ + return ret; + } + i = fieldSizes.insert(i,std::make_pair(fieldName, fieldSize)); + } + *size = i->second; + return ret; +} + + + +//class VoidType : TType +//{ +//public: +// virtual bool isVoid(){return true;} +//} + + +//static VoidType nullType(); + +//class TValue +//{ +//protected: +// TType& type = nullType; +// int pointerLevel; +// const char* valueName; +// ompd_address_space_context_t *context; +// ompd_address_t symbolAddr; +//public: +// TValue(ompd_address_space_context_t *context, const char* valueName); +// TValue& cast(const char* typeName); +// TValue& cast(const char* typeName, int pointerLevel); +// TValue& castBase(ompd_target_prim_types_t baseType); +// TValue access(const char* fieldName) const; +// TValue getArrayElement(int elemNumber) const; +//}; + + +TValue::TValue(ompd_address_space_context_t *_context, ompd_thread_context_t *_tcontext, const char* _valueName, ompd_taddr_t segment) +: errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), /*valueName(_valueName),*/ context(_context), tcontext(_tcontext), fieldSize(0) +{ + errorState.errorCode = callbacks->tsymbol_addr(context, tcontext, _valueName, &symbolAddr); + symbolAddr.segment = segment; +// assert((ret==ompd_rc_ok) && "Callback call failed"); +} + +TValue::TValue(ompd_address_space_context_t *_context, ompd_thread_context_t *_tcontext, ompd_address_t addr) +: errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), context(_context), tcontext(_tcontext), symbolAddr(addr), fieldSize(0) +{ + if(addr.address==0) + errorState.errorCode = ompd_rc_bad_input; +} + +// TValue::TValue(ompd_address_space_context_t *_context, ompd_thread_context_t *_tcontext, const struct ompd_handle* handle) +// : errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), context(_context), tcontext(_tcontext), symbolAddr(handle->th) +// { +// } + +TValue& TValue::cast(const char* typeName) +{ + if (gotError()) + return *this; + type = &tf.getType(context, typeName, symbolAddr.segment); + pointerLevel = 0; + assert(!type->isVoid() && "cast to invalid type failed"); + return *this; +} + +TValue& TValue::cast(const char* typeName, int _pointerLevel, ompd_taddr_t segment) +{ + if (gotError()) + return *this; + type = &tf.getType(context, typeName, symbolAddr.segment); + pointerLevel = _pointerLevel; + symbolAddr.segment = segment; + assert(!type->isVoid() && "cast to invalid type failed"); + return *this; +} + +TValue TValue::dereference() const +{ + if (gotError()) + return *this; + ompd_address_t tmpAddr; + assert(!type->isVoid() && "cannot work with void"); + assert(pointerLevel > 0 && "cannot dereference non-pointer"); + TValue ret=*this; + ret.pointerLevel--; + ret.errorState.errorCode = callbacks->read_tmemory(context, tcontext, symbolAddr, + 1 * ompd_sizeof( ompd_type_pointer), &(tmpAddr.address)); + if (ret.errorState.errorCode!=ompd_rc_ok) + return ret; + + ret.errorState.errorCode = callbacks->target_to_host(context, &(tmpAddr.address), + ompd_sizeof(ompd_type_pointer), 1, &(ret.symbolAddr.address)); + if (ret.errorState.errorCode!=ompd_rc_ok){ + return ret; + } + if (ret.symbolAddr.address==0) + ret.errorState.errorCode = ompd_rc_unsupported; + return ret; +} + +ompd_rc_t TValue::getAddress(ompd_address_t * addr) const +{ + *addr = symbolAddr; + if (symbolAddr.address==0) + return ompd_rc_unsupported; + return errorState.errorCode; +} + +ompd_rc_t TValue::getRawValue(void* buf, int count) +{ + if( errorState.errorCode != ompd_rc_ok ) + return errorState.errorCode; + ompd_size_t size; + errorState.errorCode = type->getSize(&size); + if( errorState.errorCode != ompd_rc_ok ) + return errorState.errorCode; + + errorState.errorCode = callbacks->read_tmemory(context, tcontext, symbolAddr, + size, buf); + return errorState.errorCode; +} + +// ompd_rc_t TValue::getAddress(struct ompd_handle* handle) const +// { +// handle->th = symbolAddr; +// return errorState.errorCode; +// } + +TBaseValue TValue::castBase(const char* varName) +{ + ompd_size_t size; + errorState.errorCode = tf.getType(context, varName, symbolAddr.segment).getSize(&size); + return TBaseValue(*this, size); +} + +TBaseValue TValue::castBase() const +{ + return TBaseValue(*this, fieldSize); +} + + +TBaseValue TValue::castBase(ompd_target_prim_types_t baseType) const +{ + return TBaseValue(*this, baseType); +} + +TValue TValue::access(const char* fieldName) const +{ + if (gotError()) + return *this; + TValue ret = *this; + assert (pointerLevel<2 && "access to field element of pointer array failed"); + if (pointerLevel==1) // -> operator + ret = ret.dereference(); + // we use *this for . operator + ompd_size_t offset; + ret.errorState.errorCode = type->getElementOffset(fieldName, &offset); + ret.errorState.errorCode = type->getElementSize(fieldName, &(ret.fieldSize)); + ret.symbolAddr.address += offset; + + return ret; +} + +ompd_rc_t TValue::check(const char* bitfieldName, ompd_tword_t* isSet) const +{ + if (gotError()) + return getError(); + int bitfield; + uint64_t bitfieldmask; + ompd_rc_t ret = this->castBase(ompd_type_int).getValue(&bitfield,1); + if (ret != ompd_rc_ok) + return ret; + ret = type->getBitfieldMask(bitfieldName, &bitfieldmask); + *isSet = ((bitfield & bitfieldmask)!=0); + return ret; +} + +TValue TValue::getArrayElement(int elemNumber) const +{ + if (gotError()) + return *this; + TValue ret=dereference(); + if (ret.pointerLevel==0) + { + ompd_size_t size; + ret.errorState.errorCode = type->getSize(&size); + ret.symbolAddr.address += elemNumber * size; + } + else + { + ret.symbolAddr.address += elemNumber * type_sizes.sizeof_pointer; + } + return ret; +} + +TBaseValue::TBaseValue(const TValue& _tvalue, ompd_target_prim_types_t _baseType): TValue(_tvalue), baseTypeSize(ompd_sizeof(_baseType)){} +TBaseValue::TBaseValue(const TValue& _tvalue, ompd_size_t _baseTypeSize): TValue(_tvalue), baseTypeSize(_baseTypeSize){} + +ompd_rc_t TBaseValue::getValue(void* buf, int count) +{ + if( errorState.errorCode != ompd_rc_ok ) + return errorState.errorCode; + errorState.errorCode = callbacks->read_tmemory(context, tcontext, symbolAddr, + count *baseTypeSize, buf); + if (errorState.errorCode!=ompd_rc_ok) + return errorState.errorCode; + errorState.errorCode = callbacks->target_to_host(context, buf, + baseTypeSize, count, buf); + return errorState.errorCode; +} + +// ompd_rc_t TBaseValue::getValue(struct ompd_handle* buf, int count) +// { +// if( errorState.errorCode != ompd_rc_ok ) +// return errorState.errorCode; +// errorState.errorCode = callbacks->read_tmemory(context, tcontext, symbolAddr, +// count, baseType, &(buf->th)); +// assert((errorState.errorCode == ompd_rc_ok) && "Callback call failed"); +// return errorState.errorCode; +// } + + diff --git a/libompd/src/TargetValue.h b/libompd/src/TargetValue.h new file mode 100644 index 000000000..2fe8fed9d --- /dev/null +++ b/libompd/src/TargetValue.h @@ -0,0 +1,252 @@ + +#include +#include "ompd.h" + +#ifndef SRC_TARGET_VALUE_H_ +#define SRC_TARGET_VALUE_H_ + +#ifdef __cplusplus + +#include +#include +#include + +class TType; +class TValue; +class TBaseValue; + +class TTypeFactory +{ +protected: + std::map > ttypes; + +public: + TTypeFactory(): ttypes() {} + TType& getType(ompd_address_space_context_t *context, + const char * typName, + ompd_taddr_t segment=OMPD_SEGMENT_UNSPECIFIED); +}; + +static thread_local TTypeFactory tf = TTypeFactory(); + +class TType +{ +protected: + ompd_size_t typeSize; + std::map fieldOffsets; + std::map fieldSizes; + std::map bitfieldMasks; + ompd_taddr_t descSegment; + const char* typeName; + ompd_address_space_context_t *context; + bool isvoid; + TType(ompd_address_space_context_t *context, + const char* typeName, + ompd_taddr_t _segment=OMPD_SEGMENT_UNSPECIFIED); +public: + TType(bool, ompd_taddr_t _segment=OMPD_SEGMENT_UNSPECIFIED): descSegment(_segment), isvoid(true) {} + bool isVoid() const{return isvoid;} + ompd_rc_t getElementOffset (const char* fieldName, ompd_size_t * offset); + ompd_rc_t getElementSize (const char* fieldName, ompd_size_t * size); + ompd_rc_t getBitfieldMask (const char* fieldName, uint64_t * bitfieldmask); + ompd_rc_t getSize (ompd_size_t * size); + friend TValue; + friend TTypeFactory; +}; + +static TType nullType(true); + +/** + * class TError + * As TValue is designed to concatenate operations, we use TError + * to catch errors that might happen on each operation and provide + * the according error code and which operation raised the error. + */ + +class TError +{ +protected: + ompd_rc_t errorCode; + TError():errorCode(ompd_rc_ok){} + TError(const ompd_rc_t& error):errorCode(error){} +public: + virtual std::string toString(){return std::string("TError messages not implemented yet");} + friend TValue; + friend TBaseValue; +}; + +/** + * class TValue + * This class encapsules the access to target values by using OMPD + * callback functions. The member functions are designed to concatinate + * the operations that are needed to access values from structures + * e.g., _a[6]->_b._c would read like : + * TValue(ctx, "_a").cast("A",2).getArrayElement(6).access("_b").cast("B").access("_c") + */ + +class TValue +{ +protected: + + TError errorState; + TType* type; + int pointerLevel; +// const char* valueName; + ompd_address_space_context_t *context; + ompd_thread_context_t *tcontext; + ompd_address_t symbolAddr; + //size_t fieldSize; + ompd_size_t fieldSize; +public: + static const ompd_callbacks_t *callbacks; + static ompd_target_type_sizes_t type_sizes; + + TValue():errorState(ompd_rc_error){} + /** + * Create a target value object from symbol name + */ + TValue(ompd_address_space_context_t *_context, + const char* _valueName, + ompd_taddr_t segment=OMPD_SEGMENT_UNSPECIFIED): + TValue(_context, NULL, _valueName, segment) {} + + TValue(ompd_address_space_context_t *context, + ompd_thread_context_t *tcontext, + const char* valueName, + ompd_taddr_t segment=OMPD_SEGMENT_UNSPECIFIED); + /** + * Create a target value object from target value address + */ + TValue(ompd_address_space_context_t *_context, ompd_address_t _addr): TValue(_context, NULL, _addr) {} + TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext, ompd_address_t addr); +// TValue(ompd_address_space_context_t *context, const struct ompd_handle* th): TValue(context, NULL, th) {} +// TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext, const struct ompd_handle* th); + /** + * Cast the target value object to some type of typeName + * + * This call modifies the object and returns a reference to the modified object + */ + TValue& cast(const char* typeName); + + /** + * Cast the target value object to some pointer of type typename + * pointerlevel gives the number of * + * e.g., char** would be: cast("char",2) + * + * This call modifies the object and returns a reference to the modified object + */ + TValue& cast(const char* typeName, int pointerLevel, ompd_taddr_t segment=OMPD_SEGMENT_UNSPECIFIED); + + /** + * Get the target address of the target value + */ + ompd_rc_t getAddress(ompd_address_t * addr) const; + /** + * Get the raw memory copy of the target value + */ + ompd_rc_t getRawValue(void* buf, int count); +// ompd_rc_t getAddress(struct ompd_handle* th) const; + /** + * Get a new target value object for the dereferenced target value + * reduces the pointer level, uses the target value as new target address, keeps the target type + */ + TValue dereference() const; + /** + * Cast to a base type + * Only values of base type may be read from target + */ + TBaseValue castBase(ompd_target_prim_types_t baseType) const; + /** + * Cast to a base type + * Get the size by fieldsize from runtime + */ + TBaseValue castBase() const; + /** + * Cast to a base type + * Get the size by name from the rtl + */ + TBaseValue castBase(const char* varName); + /** + * Resolve field access for structs/unions + * this supports both "->" and "." operator. + */ + TValue access(const char* fieldName) const; + /** + * Tests for a field bit in a bitfield + */ + ompd_rc_t check(const char* bitfieldName, ompd_tword_t* isSet) const; + /** + * Get an array element + */ + TValue getArrayElement(int elemNumber) const; + /** + * Did we raise some error yet? + */ + bool gotError() const {return errorState.errorCode != ompd_rc_ok; } + /** + * Get the error code + */ + ompd_rc_t getError() const {return errorState.errorCode; } + /** + * Did we raise some error yet? + */ + std::string getErrorMessage() {return errorState.toString();} +}; + +class TBaseValue : public TValue +{ +protected: +// ompd_target_prim_types_t baseType=ompd_type_invalid; + ompd_size_t baseTypeSize = 0; + TBaseValue(const TValue&, ompd_target_prim_types_t baseType); + TBaseValue(const TValue&, ompd_size_t baseTypeSize); + +public: +// ompd_rc_t getValue(struct ompd_handle* buf, int count); + ompd_rc_t getValue(void* buf, int count); + template + ompd_rc_t getValue(T& buf); + + friend TValue; +}; + +template +ompd_rc_t TBaseValue::getValue(T& buf) +{ + assert (sizeof(T) >= baseTypeSize); + ompd_rc_t ret = getValue(&buf, 1); + if (sizeof(T) > baseTypeSize) + { + switch (baseTypeSize){ + case 1: + buf = (T)*((int8_t*)&buf); + break; + case 2: + buf = (T)*((int16_t*)&buf); + break; + case 4: + buf = (T)*((int32_t*)&buf); + break; + case 8: + buf = (T)*((int64_t*)&buf); + break; + } + } + return ret; +} + + +#define EXTERN_C extern "C" +#else +#define EXTERN_C +#endif + +//EXTERN_C int getNumberOfOMPThreads(ompd_address_space_context_t *context); +//EXTERN_C int32_t getOmpThreadID(ompd_address_space_context_t *context); +//EXTERN_C uint64_t getSystemThreadID(ompd_address_space_context_t *context, ompd_thread_handle_t t); +//EXTERN_C ompd_thread_handle_t getOmpThreadHandle(ompd_address_space_context_t *context); +//EXTERN_C void getThreadState(ompd_address_space_context_t *context, ompd_thread_handle_t t, ompt_state_t *state, +// ompt_wait_id_t *wait_id); + + +#endif /*SRC_TARGET_VALUE_H_*/ diff --git a/libompd/src/ompd-template.h b/libompd/src/ompd-template.h new file mode 100644 index 000000000..5bdee012d --- /dev/null +++ b/libompd/src/ompd-template.h @@ -0,0 +1,1115 @@ +/* + * ompd.h + * + * Created on: Dec 22, 2014 + * Author: Ignacio Laguna + * Joachim Protze + * Contact: ilaguna@llnl.gov + * protze@llnl.gov + */ +#ifndef SRC_OMPD_H_ +#define SRC_OMPD_H_ + +/****************************************************************************** + * This header file defines the OMPD interface: an interface to help debuggers + * to inspect state associated with OpenMP programming abstractions in a target + * process. The interface is implemented in a dynamically loaded library (DLL) + * that the debugger loads into its address space. + * + * Name conventions: + * - All named entities start with the prefix "ompd_" (for OpenMP debugging) + * - Type entities end with the suffix "_t" (for type) + * - Function types end with the suffix "_fn_t" (for function type) + * - Return code entities have "_rc_" in it + * - Abstractions referring to the target have the prefix "t" (e.g., + * "tmemory" for memory in the target, or "tsymbol" for symbol in the target) + * - Abstractions referring to the debugger have the prefix "d" (e.g., + * "dmemory" for memory in the debugger) + * + * Comment conventions: + * - Input function parameters denoted by "IN:" + * - Output function parameters denoted by "OUT:" + */ + +#include +//#include "omp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * General types and data structures + */ + +/** + * Basic types. + */ +typedef uint64_t ompd_taddr_t; /* unsigned integer large enough */ + /* to hold a target address or a */ + /* target segment value */ +typedef int64_t ompd_tword_t; /* signed version of ompd_addr_t */ +typedef uint64_t ompd_parallel_id_t; /* parallel region instance ID */ +typedef uint64_t ompd_task_id_t; /* task region instance ID */ +typedef uint64_t ompd_wait_id_t; /* identifies what a thread is */ + /* waiting for */ +typedef uint64_t ompd_size_t; /* For sizes (e.g., size_t) */ + +typedef struct ompd_address_t { + ompd_taddr_t segment; /* target architecture specific */ + /* segment value */ + ompd_taddr_t address; /* target address in the segment */ +} ompd_address_t; + +#define OMPD_SEGMENT_UNSPECIFIED ((ompd_taddr_t) 0) +#define OMPD_SEGMENT_TEXT ((ompd_taddr_t) 1) +#define OMPD_SEGMENT_DATA ((ompd_taddr_t) 2) + +/** + * The following definitions match with ptx information stored in DWARF + */ +#define OMPD_SEGMENT_CUDA_PTX_UNSPECIFIED ((ompd_taddr_t)0) +#define OMPD_SEGMENT_CUDA_PTX_CODE ((ompd_taddr_t)1) +#define OMPD_SEGMENT_CUDA_PTX_REG ((ompd_taddr_t)2) +#define OMPD_SEGMENT_CUDA_PTX_SREG ((ompd_taddr_t)3) +#define OMPD_SEGMENT_CUDA_PTX_CONST ((ompd_taddr_t)4) +#define OMPD_SEGMENT_CUDA_PTX_GLOBAL ((ompd_taddr_t)5) +#define OMPD_SEGMENT_CUDA_PTX_LOCAL ((ompd_taddr_t)6) +#define OMPD_SEGMENT_CUDA_PTX_PARAM ((ompd_taddr_t)7) +#define OMPD_SEGMENT_CUDA_PTX_SHARED ((ompd_taddr_t)8) +#define OMPD_SEGMENT_CUDA_PTX_SURF ((ompd_taddr_t)9) +#define OMPD_SEGMENT_CUDA_PTX_TEX ((ompd_taddr_t)10) +#define OMPD_SEGMENT_CUDA_PTX_TEXSAMPLER ((ompd_taddr_t)11) +#define OMPD_SEGMENT_CUDA_PTX_GENERIC ((ompd_taddr_t)12) +#define OMPD_SEGMENT_CUDA_PTX_IPARAM ((ompd_taddr_t)13) +#define OMPD_SEGMENT_CUDA_PTX_OPARAM ((ompd_taddr_t)14) +#define OMPD_SEGMENT_CUDA_PTX_FRAME ((ompd_taddr_t)15) +#define OMPD_SEGMENT_CUDA_PTX_MAX ((ompd_taddr_t)16) + +/* + * Definition of OMPD states, taken from OMPT + */ +#define FOREACH_OMPD_STATE(macro) \ + \ + /* first */ \ + macro (ompd_state_first, 0x71) /* initial enumeration state */ \ + \ + /* work states (0..15) */ \ + macro (ompd_state_work_serial, 0x00) /* working outside parallel */ \ + macro (ompd_state_work_parallel, 0x01) /* working within parallel */ \ + macro (ompd_state_work_reduction, 0x02) /* performing a reduction */ \ + \ + /* idle (16..31) */ \ + macro (ompd_state_idle, 0x10) /* waiting for work */ \ + \ + /* overhead states (32..63) */ \ + macro (ompd_state_overhead, 0x20) /* overhead excluding wait states */ \ + \ + /* barrier wait states (64..79) */ \ + macro (ompd_state_wait_barrier, 0x40) /* waiting at a barrier */ \ + macro (ompd_state_wait_barrier_implicit, 0x41) /* implicit barrier */ \ + macro (ompd_state_wait_barrier_explicit, 0x42) /* explicit barrier */ \ + \ + /* task wait states (80..95) */ \ + macro (ompd_state_wait_taskwait, 0x50) /* waiting at a taskwait */ \ + macro (ompd_state_wait_taskgroup, 0x51) /* waiting at a taskgroup */ \ + \ + /* mutex wait states (96..111) */ \ + macro (ompd_state_wait_lock, 0x60) /* waiting for lock */ \ + macro (ompd_state_wait_nest_lock, 0x61) /* waiting for nest lock */ \ + macro (ompd_state_wait_critical, 0x62) /* waiting for critical */ \ + macro (ompd_state_wait_atomic, 0x63) /* waiting for atomic */ \ + macro (ompd_state_wait_ordered, 0x64) /* waiting for ordered */ \ + macro (ompd_state_wait_single, 0x6F) /* waiting for single region (non-standard!) */ \ + \ + /* misc (112..127) */ \ + macro (ompd_state_undefined, 0x70) /* undefined thread state */ + +typedef enum ompd_state_t { +#define ompd_state_macro(state, code) state = code, + FOREACH_OMPD_STATE(ompd_state_macro) +#undef ompd_state_macro +} ompd_state_t; + +typedef enum ompd_sched_t { + ompd_sched_static = 1, + ompd_sched_dynamic = 2, + ompd_sched_guided = 3, + ompd_sched_auto = 4, + ompd_sched_vendor_lo = 5, + ompd_sched_vendor_hi = 0x7fffffff +} ompd_sched_t; + +typedef enum ompd_proc_bind_t { + ompd_proc_bind_false = 0, + ompd_proc_bind_true = 1, + ompd_proc_bind_master = 2, + ompd_proc_bind_close = 3, + ompd_proc_bind_spread = 4 +} ompd_proc_bind_t; + +typedef uint64_t ompd_device_identifier_t; + +typedef enum ompd_device_kind_t { + ompd_device_kind_host = 1, + ompd_device_kind_cuda = 2 +} ompd_device_kind_t; + +/** + * Context handle. + * This is used by the debugger to identify a target process (or core file). + * This will be cast to concrete types within the debugger. The callbacks use + * context handles to specify the debugger where to look up (since the debugger + * can be handling different contexts at the same time, e.g., processes and/or + * core files). Without context handles the debugger would not know the target + * of a callback request. + */ + +typedef struct _ompd_address_space_context_s ompd_address_space_context_t; +typedef struct _ompd_thread_context_s ompd_thread_context_t; + +/** + * OpenMP abstractions handles. + * Each operation in the OMPD interface must explicitly specify a handle for the + * context of the operation. OMPD uses context handles for OpenMP entities, such + * as threads, parallel regions, and tasks. A handle for an entity is constant + * while the entity itself is live. + */ + +typedef struct _ompd_device_handle_s ompd_device_handle_t; +typedef struct _ompd_thread_handle_s ompd_thread_handle_t; +typedef struct _ompd_parallel_handle_s ompd_parallel_handle_t; +typedef struct _ompd_task_handle_s ompd_task_handle_t; +typedef struct _ompd_address_space_handle_s ompd_address_space_handle_t; + +/** + * Other handles. + */ +#define OMPD_OSTHREAD_PTHREAD 0 +#define OMPD_OSTHREAD_LWP 1 +#define OMPD_OSTHREAD_WINTHREAD 2 +#define OMPD_OSTHREAD_CUDALOGICAL 3 +#define OMPD_OSTHREAD_MAX 4 + +typedef enum ompd_osthread_kind_t { + ompd_osthread_pthread=0, + ompd_osthread_lwp=1, + ompd_osthread_winthread=2, + ompd_osthread_cudalogical=3 +} ompd_osthread_kind_t; + +/** + * Logical coordinates of OMP target device threads + */ +typedef struct ompd_dim3_t { + ompd_tword_t x; + ompd_tword_t y; + ompd_tword_t z; +} ompd_dim3_t; + +typedef struct ompd_cudathread_coord_t { + ompd_taddr_t cudaDevId; + ompd_taddr_t cudaContext; + ompd_taddr_t warpSize; + ompd_taddr_t gridId; + ompd_taddr_t kernelId; // TODO (MJM) - for some reason, cuda-gdb doesn't work with grids too well. + ompd_dim3_t gridDim; + ompd_dim3_t blockDim; + ompd_dim3_t blockIdx; + ompd_dim3_t threadIdx; +} ompd_cudathread_coord_t; + +/** + * Return codes. + * Each OMPD operation returns a code. + */ +typedef enum ompd_rc_t +{ + ompd_rc_ok = 0, /* operation was successful */ + ompd_rc_unavailable = 1, /* info is not available (in this context) */ + ompd_rc_stale_handle = 2, /* handle is no longer valid */ + ompd_rc_bad_input = 3, /* bad input parameters (other than handle) */ + ompd_rc_error = 4, /* error */ + ompd_rc_unsupported = 5, /* operation is not supported */ + ompd_rc_needs_state_tracking = 6, /* needs runtime state tracking enabled */ + ompd_rc_incompatible = 7, /* target is not compatible with this OMPD */ + ompd_rc_target_read_error = 8, /* error reading from the target */ + ompd_rc_target_write_error = 9, /* error writing from the target */ + ompd_rc_nomem = 10 /* unable to allocate memory */ +} ompd_rc_t; + +/** + * Primitive types. + */ +typedef enum ompd_target_prim_types_t +{ + ompd_type_invalid = -1, + ompd_type_char = 0, + ompd_type_short = 1, + ompd_type_int = 2, + ompd_type_long = 3, + ompd_type_long_long = 4, + ompd_type_pointer = 5, + ompd_type_max +} ompd_target_prim_types_t; + +/** + * Primitive type sizes. + * These types are used by OMPD to interrogate the debugger about the size of + * primitive types in the target. + */ +typedef struct ompd_target_type_sizes_t +{ + unsigned int sizeof_char; + unsigned int sizeof_short; + unsigned int sizeof_int; + unsigned int sizeof_long; + unsigned int sizeof_long_long; + unsigned int sizeof_pointer; +} ompd_target_type_sizes_t; + + +/****************************************************************************** + * Debugger callback signatures. + * These callback function signatures are used by OMPD to obtain state + * information of a target process, in particular to interrogate about info + * that is dependent on a particular OpenMP runtime library. Typical queries are + * sizes of primitive types in the target, symbols lookup, lookup of offsets of + * fields in a type/structure, and read/write to memory in the target. + */ + +/** + * Allocate memory in the debugger's address space. + */ +typedef ompd_rc_t (*ompd_dmemory_alloc_fn_t) ( + ompd_size_t bytes, /* IN: bytes of the primitive type */ + void **ptr /* OUT: pointer of the allocated memory */ + ); + +/** + * Free memory in the debugger's address space. + */ +typedef ompd_rc_t (*ompd_dmemory_free_fn_t) ( + void *ptr /* IN: pointer of memory to deallocate */ + ); + +/** + * Get thread specific context. + */ +typedef ompd_rc_t (*ompd_get_thread_context_for_osthread_fn_t) ( + ompd_address_space_context_t *context, + ompd_osthread_kind_t kind, + ompd_size_t sizeof_osthread, + const void* osthread, + ompd_thread_context_t** thread_context + ); + +/** + * Get containing (host) process context for address_space_context + */ +typedef ompd_rc_t (*ompd_get_process_context_for_context_fn_t) ( + ompd_address_space_context_t* + address_space_context, /* IN: OMP device/process addr space */ + ompd_address_space_context_t** + containing_address_space_context /* OUT: Containing omp process addr space */ +); + +/** + * Look up the sizes of primitive types in the target + */ +typedef ompd_rc_t (*ompd_tsizeof_prim_fn_t) ( + ompd_address_space_context_t *context, /* IN: debugger handle for the target */ + ompd_target_type_sizes_t *sizes /* OUT: type sizes */ + ); + +/** + * Look up the address of a global symbol in the target + */ +typedef ompd_rc_t (*ompd_tsymbol_addr_fn_t) ( + ompd_address_space_context_t *context, /* IN: debugger handle for the target */ + ompd_thread_context_t *tcontext, /* IN: debugger handle for a target thread might be NULL */ + const char *symbol_name, /* IN: global symbol name */ + ompd_address_t *symbol_addr /* OUT: symbol address */ + ); + +/** + * Read memory from the target + */ +typedef ompd_rc_t (*ompd_tmemory_read_fn_t) ( + ompd_address_space_context_t *context, /* IN: debugger handle for the target */ + ompd_thread_context_t *tcontext, /* IN: debugger handle for a target thread might be NULL */ + ompd_address_t addr, /* IN: address in the target */ + ompd_tword_t nbytes, /* IN: number of items to read */ + void *buffer /* OUT: output buffer */ + ); + +/** + * Write memory from the target + */ +typedef ompd_rc_t (*ompd_tmemory_write_fn_t) ( + ompd_address_space_context_t *context, /* IN: debugger handle for the target */ + ompd_thread_context_t *tcontext, /* IN: debugger handle for a target thread might be NULL */ + ompd_address_t addr, /* IN: address in the target */ + ompd_tword_t nbytes, /* IN: number of items to write */ + const void *buffer /* IN: output buffer */ + ); + +typedef ompd_rc_t (*ompd_target_host_fn_t) ( + ompd_address_space_context_t *address_space_context, /* IN */ + const void *input, /* IN */ + int unit_size, /* IN */ + int count, /* IN: number of primitive type */ + /* items to process */ + void *output /* OUT */ +); + +/** + * This is used by the OMPD library to have the debugger print a string. + * The OMPD should not print directly. + */ +typedef ompd_rc_t (*ompd_print_string_fn_t) ( + const char *str /* IN: message to print */ + ); + +/** + * Callbacks table. + */ +typedef struct ompd_callbacks_t +{ + /* Debugger interface */ + ompd_dmemory_alloc_fn_t dmemory_alloc; + ompd_dmemory_free_fn_t dmemory_free; + ompd_print_string_fn_t print_string; + + /* Target interface */ + ompd_tsizeof_prim_fn_t tsizeof_prim; + ompd_tsymbol_addr_fn_t tsymbol_addr; + ompd_tmemory_read_fn_t read_tmemory; + ompd_tmemory_write_fn_t write_tmemory; + + ompd_target_host_fn_t target_to_host; + ompd_target_host_fn_t host_to_target; + + ompd_get_thread_context_for_osthread_fn_t get_thread_context_for_osthread; + ompd_get_process_context_for_context_fn_t get_containing_process_context; + +} ompd_callbacks_t; + +/****************************************************************************** + * Call signatures from the debugger to the OMPD DLL. + */ + +/* --- 4 Initialization ----------------------------------------------------- */ + +/** + * The OMPD function ompd_get_version_string returns a descriptive string + * describing an implementation of the OMPD library. The function + * ompd_get_version_compatibility returns an integer code used to indicate the + * revision of the OMPD specification supported by an implementation of OMPD. + */ + +ompd_rc_t ompd_get_version ( + int *version + ); +typedef ompd_rc_t (*ompd_get_version_apifn_t) ( + int *version + ); + +ompd_rc_t ompd_get_version_string( + const char **string /* OUT: OMPD version string */ + ); +typedef ompd_rc_t (*ompd_get_version_string_apifn_t) ( + const char **string /* OUT: OMPD version string */ + ); + +/** + * Initialize OMPD. + * This provides the DLL the pointers to the debugger's functions to obtain + * information about the OpenMP runtime library. The debugger promises to + * maintain the functions valid for as long as needed. + */ +ompd_rc_t ompd_initialize ( + const ompd_callbacks_t *table /* IN: callbacks table */ + ); +typedef ompd_rc_t (*ompd_initialize_apifn_t) ( + const ompd_callbacks_t *table /* IN: callbacks table */ + ); + +ompd_rc_t ompd_process_initialize ( + ompd_address_space_context_t *context, /* IN: debugger handle for the target */ + ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the target */ + ); +typedef ompd_rc_t (*ompd_process_initialize_apifn_t) ( + ompd_address_space_context_t *context, /* IN: debugger handle for the target */ + ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the target */ + ); + +ompd_rc_t ompd_release_address_space_handle ( + ompd_address_space_handle_t *addr_handle /* IN: handle for the address space */ + ); +typedef ompd_rc_t (*ompd_release_address_space_handle_apifn_t) ( + ompd_address_space_handle_t *addr_handle /* IN: handle for the address space */ + ); + +ompd_rc_t ompd_device_initialize ( + ompd_address_space_context_t *context, /* IN: debugger handle for the device */ + ompd_device_identifier_t id, /* IN: object defined by native device API */ + ompd_device_kind_t kind, /* IN: */ + ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the device */ + ); +typedef ompd_rc_t (*ompd_device_initialize_apifn_t) ( + ompd_address_space_context_t *context, /* IN: debugger handle for the device */ + ompd_device_identifier_t id, /* IN: object defined by native device API */ + ompd_device_kind_t kind, /* IN: */ + ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the device */ + ); + +ompd_rc_t ompd_finalize ( void ); +typedef ompd_rc_t (*ompd_finalize_apifn_t) ( void ); + +/* --- 4 Handle Management -------------------------------------------------- */ + +/* --- 4.1 Thread Handles --------------------------------------------------- */ + +/** + * Retrieve handles for all OpenMP threads. + * + * The ompd_get_threads operation enables the debugger to obtain handles for all + * OpenMP threads. A successful invocation of ompd_get_threads returns a pointer + * to a vector of handles in thread_handle_array and returns the number of + * handles in num_handles. This call yields meaningful results only if all + * OpenMP threads are stopped; otherwise, the OpenMP runtime may be creating + * and/or destroying threads during or after the call, rendering useless the + * vector of handles returned. + */ +ompd_rc_t ompd_get_threads ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ + int *num_handles /* OUT: number of handles in the array */ + ); +typedef ompd_rc_t (*ompd_get_threads_apifn_t) ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ + int *num_handles /* OUT: number of handles in the array */ + ); + +/** + * Retrieve handles for OpenMP threads in a parallel region. + * + * The ompd_get_thread_in_parallel operation enables the debugger to obtain + * handles for all OpenMP threads associated with a parallel region. A + * successful invocation of ompd_get_thread_in_parallel returns a pointer to a + * vector of handles in thread_handle_array and returns the number of handles in + * num_handles. This call yields meaningful results only if all OpenMP threads + * in the parallel region are stopped; otherwise, the OpenMP runtime may be + * creating and/or destroying threads during or after the call, rendering + * useless the vector of handles returned. + */ +ompd_rc_t ompd_get_thread_in_parallel( + ompd_parallel_handle_t *parallel_handle, /* IN */ + ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ + int *num_handles /* OUT: number of handles in the array */ + ); +typedef ompd_rc_t (*ompd_get_thread_in_parallel_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, /* IN */ + ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ + int *num_handles /* OUT: number of handles in the array */ + ); + +ompd_rc_t ompd_get_master_thread_in_parallel ( + ompd_parallel_handle_t *parallel_handle, /* IN */ + ompd_thread_handle_t **thread_handle); +typedef ompd_rc_t (*ompd_get_master_thread_in_parallel_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, /* IN */ + ompd_thread_handle_t **thread_handle); + + +ompd_rc_t ompd_release_thread_handle ( + ompd_thread_handle_t *thread_handle +); +typedef ompd_rc_t (*ompd_release_thread_handle_apifn_t) ( + ompd_thread_handle_t *thread_handle +); + + +ompd_rc_t ompd_thread_handle_compare ( + ompd_thread_handle_t *thread_handle_1, + ompd_thread_handle_t *thread_handle_2, + int *cmp_value +); +typedef ompd_rc_t (*ompd_thread_handle_compare_apifn_t) ( + ompd_thread_handle_t *thread_handle_1, + ompd_thread_handle_t *thread_handle_2, + int *cmp_value +); + +ompd_rc_t ompd_get_thread_handle_string_id ( + ompd_thread_handle_t *thread_handle, + char **string_id +); +typedef ompd_rc_t (*ompd_get_thread_handle_string_id_apifn_t) ( + ompd_thread_handle_t *thread_handle, + char **string_id +); + +/* --- 4.2 Parallel Region Handles------------------------------------------- */ + +/** + * Retrieve the handle for the innermost patallel region for an OpenMP thread. + * + * The operation ompd_get_top_parallel_region enables the debugger to obtain + * the handle for the innermost parallel region associated with an OpenMP + * thread. This call is meaningful only if the thread whose handle is provided + * is stopped. + */ + +ompd_rc_t ompd_get_top_parallel_region( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ + ); +typedef ompd_rc_t (*ompd_get_top_parallel_region_apifn_t) ( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ + ); + +/** + * Retrieve the handle for an enclosing parallel region. + * + * The ompd_get_enclosing_parallel_handle operation enables the debugger to + * obtain the handle for the parallel region enclosing the parallel region + * specified by parallel_handle. This call is meaningful only if at least one + * thread in the parallel region is stopped. + */ + +ompd_rc_t ompd_get_enclosing_parallel_handle( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ); +typedef ompd_rc_t (*ompd_get_enclosing_parallel_handle_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ); + +/** + * Retrieve the handle for the enclosing parallel region or a task region. + * + * The ompd_get_task_enclosing_parallel_handle operation enables the debugger to + * obtain the handle for the parallel region enclosing the task region + * specified by task_handle. This call is meaningful only if at least one + * thread in the parallel region is stopped. + */ + +ompd_rc_t ompd_get_task_enclosing_parallel_handle( + ompd_task_handle_t* task_handle, /* IN: OpenMP task handle */ + ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ); +typedef ompd_rc_t (*ompd_get_task_enclosing_parallel_handle_apifn_t) ( + ompd_task_handle_t* task_handle, /* IN: OpenMP task handle */ + ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ); + + + +ompd_rc_t ompd_release_parallel_handle ( + ompd_parallel_handle_t *parallel_handle +); +typedef ompd_rc_t (*ompd_release_parallel_handle_apifn_t) ( + ompd_parallel_handle_t *parallel_handle +); + +ompd_rc_t ompd_parallel_handle_compare ( + ompd_parallel_handle_t *parallel_handle_1, + ompd_parallel_handle_t *parallel_handle_2, + int *cmp_value +); +typedef ompd_rc_t (*ompd_parallel_handle_compare_apifn_t) ( + ompd_parallel_handle_t *parallel_handle_1, + ompd_parallel_handle_t *parallel_handle_2, + int *cmp_value +); + +ompd_rc_t ompd_get_parallel_handle_string_id ( + ompd_parallel_handle_t *parallel_handle, + char **string_id +); +typedef ompd_rc_t (*ompd_get_parallel_handle_string_id_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, + char **string_id +); + +/* --- 4.3 Task Handles ----------------------------------------------------- */ + +/** + * Retrieve the handle for the innermost task for an OpenMP thread. + * + * The debugger uses the operation ompd_get_top_task_region to obtain the handle + * for the innermost task region associated with an OpenMP thread. This call is + * meaningful only if the thread whose handle is provided is stopped. + */ +ompd_rc_t ompd_get_top_task_region( + ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ + ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ + ); +typedef ompd_rc_t (*ompd_get_top_task_region_apifn_t) ( + ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ + ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ + ); + +/** + * Retrieve the handle for an enclosing task. + * + * The debugger uses ompd_get_ancestor_task_region to obtain the handle for the + * task region enclosing the task region specified by task_handle. This call is + * meaningful only if the thread executing the task specified by task_handle is + * stopped. + */ +ompd_rc_t ompd_get_ancestor_task_region( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ); +typedef ompd_rc_t (*ompd_get_ancestor_task_region_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ); + +ompd_rc_t ompd_get_generating_ancestor_task_region( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ); +typedef ompd_rc_t (*ompd_get_generating_ancestor_task_region_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ); + +ompd_rc_t ompd_get_scheduling_ancestor_task_region( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ); +typedef ompd_rc_t (*ompd_get_scheduling_ancestor_task_region_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ); + +/** + * Retrieve implicit task handle for a parallel region. + * + * The ompd_get_implicit_task_in_parallel operation enables the debugger to + * obtain handles for implicit tasks associated with a parallel region. This + * call is meaningful only if all threads associated with the parallel region + * are stopped. + */ +ompd_rc_t ompd_get_implicit_task_in_parallel( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_task_handle_t ***task_handle_array, /* OUT: array of OpenMP task handles */ + int *num_handles /* OUT: number of task handles */ + ); +typedef ompd_rc_t (*ompd_get_implicit_task_in_parallel_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_task_handle_t ***task_handle_array, /* OUT: array of OpenMP task handles */ + int *num_handles /* OUT: number of task handles */ + ); + +ompd_rc_t ompd_release_task_handle ( + ompd_task_handle_t *task_handle +); +typedef ompd_rc_t (*ompd_release_task_handle_apifn_t) ( + ompd_task_handle_t *task_handle +); + +ompd_rc_t ompd_task_handle_compare ( + ompd_task_handle_t *task_handle_1, + ompd_task_handle_t *task_handle_2, + int *cmp_value +); +typedef ompd_rc_t (*ompd_task_handle_compare_apifn_t) ( + ompd_task_handle_t *task_handle_1, + ompd_task_handle_t *task_handle_2, + int *cmp_value +); + +ompd_rc_t ompd_get_task_handle_string_id ( + ompd_task_handle_t *task_handle, + char **string_id +); +typedef ompd_rc_t (*ompd_get_task_handle_string_id_apifn_t) ( + ompd_task_handle_t *task_handle, + char **string_id +); + + +/* --- 5o Process and Thread Settings ---------------------------------------- */ + +/** + * The functions ompd_get_num_procs and ompd_get_thread_limit are third-party + * versions of the OpenMP runtime functions omp_get_num_procs and + * omp_get_thread_limit. + */ + +ompd_rc_t ompd_get_num_procs( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_tword_t *val /* OUT: number of processes */ + ); +typedef ompd_rc_t (*ompd_get_num_procs_apifn_t) ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_tword_t *val /* OUT: number of processes */ + ); + +ompd_rc_t ompd_get_thread_limit( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_tword_t *val /* OUT: max number of threads */ + ); +typedef ompd_rc_t (*ompd_get_thread_limit_apifn_t) ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_tword_t *val /* OUT: max number of threads */ + ); + +/* --- 6 Parallel Region Inqueries ------------------------------------------ */ +/* --- 6.1 Settings --------------------------------------------------------- */ + +/** + * Determine the number of threads associated with a parallel region. + */ +ompd_rc_t ompd_get_num_threads( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_tword_t *val /* OUT: number of threads */ + ); +typedef ompd_rc_t (*ompd_get_num_threads_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_tword_t *val /* OUT: number of threads */ + ); + +/** + * Determine the nesting depth of a particular parallel region instance. + */ +ompd_rc_t ompd_get_level( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_tword_t *val /* OUT: nesting level */ + ); +typedef ompd_rc_t (*ompd_get_level_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_tword_t *val /* OUT: nesting level */ + ); + +/** + * Determine the number of enclosing active parallel regions. + * + * ompd_get_active_level returns the number of nested, active parallel regions + * enclosing the parallel region specified by its handle. + */ +ompd_rc_t ompd_get_active_level( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_tword_t *val /* OUT: active nesting level */ + ); +typedef ompd_rc_t (*ompd_get_active_level_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_tword_t *val /* OUT: active nesting level */ + ); + +/* --- 6.2 OMPT Parallel Region Inquiry Analogues ------------------------- */ + +/** + * The functions ompd_get_parallel_id and ompd_get_parallel_function are + * third-party variants of their OMPT counterparts. The only difference between + * the OMPD and OMPT versions is that the OMPD must supply a parallel region + * handle to provide a context for these inquiries. + */ +ompd_rc_t ompd_get_parallel_id( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_parallel_id_t *id /* OUT: OpenMP parallel id */ + ); +typedef ompd_rc_t (*ompd_get_parallel_id_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_parallel_id_t *id /* OUT: OpenMP parallel id */ + ); + +ompd_rc_t ompd_get_parallel_function( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ + ); +typedef ompd_rc_t (*ompd_get_parallel_function_apifn_t) ( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ + ); + +/* --- 7 Thread Inquiry ----------------------------------------------------- */ +/* --- 7.1 Operating System Thread Inquiry ---------------------------------- */ + +/** + * Obtain an OpenMP thread handle and the internal OS thread handle for the + * selected (context) thread. + * If the function returns ompd_rc_ok then the operating system thread + * corresponds to an OpenMP thread and the thread_handle is initialized. The + * value of thread_handle ans os_thread is meaningful only to the OpenMP runtime + * system. + */ +ompd_rc_t ompd_get_thread_handle ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_osthread_kind_t kind, + ompd_size_t sizeof_osthread, + const void* osthread, + ompd_thread_handle_t **thread_handle /* OUT: OpenMP thread handle*/ + ); + +typedef ompd_rc_t (*ompd_get_thread_handle_apifn_t) ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_osthread_kind_t kind, + ompd_size_t sizeof_osthread, + const void* osthread, + ompd_thread_handle_t **thread_handle /* OUT: OpenMP thread handle*/ + ); + +/** + * Obtain the OS thread handle for an OpenMP thread handle. + * this might change over time in case virtual openmp threads migrate between + * OS threads. + */ +ompd_rc_t ompd_get_osthread ( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_osthread_kind_t kind, + ompd_size_t sizeof_osthread, + void *osthread + ); + +typedef ompd_rc_t (*ompd_get_osthread_apifn_t) ( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_osthread_kind_t kind, + ompd_size_t sizeof_osthread, + void *osthread + ); + +ompd_rc_t ompd_get_thread_num( + ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ + ompd_tword_t *val /* OUT: number of the thread within the team */ + ); + +typedef ompd_rc_t (*ompd_get_thread_num_apifn_t) ( + ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ + ompd_tword_t *val /* OUT: number of the thread within the team */ + ); + + +/* --- 7.2 OMPT Thread State Inquiry Analogue ------------------------------- */ + +/** + * Get the state of a thread. This can use OMPT state data structure to define + * different states of threads (e.g., idle, working, or barrier, etc) and what + * entity cased this state (e.g., address of a lock); + * + * The function ompd_get_state is a third-party version of ompt_get_state. The + * only difference between the OMPD and OMPT counterparts is that the OMPD + * version must supply a thread handle to provide a context for this inquiry. + */ +ompd_rc_t ompd_get_state ( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_state_t *state, /* OUT: State of this thread */ + ompd_wait_id_t *wait_id /* OUT: Wait ID */ +); +typedef ompd_rc_t (*ompd_get_state_apifn_t) ( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_state_t *state, /* OUT: State of this thread */ + ompd_wait_id_t *wait_id /* OUT: Wait ID */ +); + + +/* --- 8 Task Inquiry ------------------------------------------------------- */ + +/* --- 8.1 Task Function Entry Point ---------------------------------------- */ + +/** + * The ompd_get_task_function returns the entry point of the code that + * corresponds to the body of code executed by the task. + */ + + +ompd_rc_t ompd_get_task_function( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_address_t *entry_point /* OUT: first instruction in the task region */ + ); +typedef ompd_rc_t (*ompd_get_task_function_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_address_t *entry_point /* OUT: first instruction in the task region */ + ); + + +/* --- 8.2 Task Settings ---------------------------------------------------- */ + +/** + * Retrieve information from OpenMP tasks. These inquiry functions have no + * counterparts in the OMPT interface as a first-party tool can call OpenMP + * runtime inquiry functions directly. The only difference between the OMPD + * inquiry operations and their counterparts in the OpenMP runtime is that the + * OMPD version must supply a task handle to provide a context for each inquiry. + */ + +ompd_rc_t ompd_get_max_threads( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: max number of threads */ + ); + +typedef ompd_rc_t (*ompd_get_max_threads_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: max number of threads */ + ); + +ompd_rc_t ompd_in_parallel( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: Is OpenMP in parallel? */ + ); + +typedef ompd_rc_t (*ompd_in_parallel_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: Is OpenMP in parallel? */ + ); + +ompd_rc_t ompd_in_final( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: Is OpenMP in final? */ + ); + +typedef ompd_rc_t (*ompd_in_final_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: Is OpenMP in final? */ + ); + +ompd_rc_t ompd_get_dynamic( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: ? */ + ); + +typedef ompd_rc_t (*ompd_get_dynamic_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: ? */ + ); + +ompd_rc_t ompd_get_nested( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_tword_t *val /* OUT: Is this task nested? */ + ); + +typedef ompd_rc_t (*ompd_get_nested_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_tword_t *val /* OUT: Is this task nested? */ + ); + +ompd_rc_t ompd_get_max_active_levels( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_tword_t *val /* OUT: max active levels */ + ); + +typedef ompd_rc_t (*ompd_get_max_active_levels_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_tword_t *val /* OUT: max active levels */ + ); + +ompd_rc_t ompd_get_schedule( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_sched_t *kind, /* OUT: Kind of OpenMP schedule*/ + ompd_tword_t *modifier /* OUT: Schedunling modifier */ + ); + +typedef ompd_rc_t (*ompd_get_schedule_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_sched_t *kind, /* OUT: Kind of OpenMP schedule*/ + ompd_tword_t *modifier /* OUT: Schedunling modifier */ + ); + +ompd_rc_t ompd_get_proc_bind( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_proc_bind_t *bind /* OUT: Kind of proc-binding */ + ); +typedef ompd_rc_t (*ompd_get_proc_bind_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_proc_bind_t *bind /* OUT: Kind of proc-binding */ + ); + +ompd_rc_t ompd_is_implicit( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: implicit=1, explicit=0 */ + ); +typedef ompd_rc_t (*ompd_is_implicit_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: implicit=1, explicit=0 */ + ); + +/* --- 8.3 OMPT Task Inquiry Analogues -------------------------------------- */ + +/** + * The functions defined here are third-party versions of ompt_get_task_frame + * and ompt_get_task_id. The only difference between the OMPD and OMPT + * counterparts is that the OMPD version must supply a task handle to provide a + * context for these inquiries. + */ + +/** + * sp_exit + * + * This value is set once, the first time that a task exits the runtime to begin + * executing user code. This field points to the stack frame of the runtime + * procedure that called the user code. This value is NULL until just before the + * task exits the runtime. + * + * sp_reentry + * + * This value is set each time that current task re-enters the runtime to create + * new (implicit or explicit) tasks. This field points to the stack frame of the + * runtime procedure called by a task to re-enter the runtime. This value is NULL + * until just after the task re-enters the runtime. + */ + + +ompd_rc_t ompd_get_task_frame( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_address_t *sp_exit, /* OUT: next frame is user code */ + ompd_address_t *sp_reentry /* OUT: previous frame is user code */ + ); +typedef ompd_rc_t (*ompd_get_task_frame_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_address_t *sp_exit, /* OUT: next frame is user code */ + ompd_address_t *sp_reentry /* OUT: previous frame is user code */ + ); + +ompd_rc_t ompd_get_task_id( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_id_t *task_id /* OUT: OpenMP task ID */ + ); +typedef ompd_rc_t (*ompd_get_task_id_apifn_t) ( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_id_t *task_id /* OUT: OpenMP task ID */ + ); + + +/* --- 13 Display Control Variables ----------------------------------------- */ + +/** + * Using the ompd_display_control_vars function, the debugger can extract a + * string that contains a sequence of name/value pairs of control variables + * whose settings are (a) user controllable, and (b) important to the operation + * or performance of an OpenMP runtime system. The control variables exposed + * through this interface will include all of the OMP environment variables, + * settings that may come from vendor or platform- specific environment + * variables (e.g., the IBM XL compiler has an environment variable that + * controls spinning vs. blocking behavior), and other settings that affect + * the operation or functioning of an OpenMP runtime system (e.g., numactl + * settings that cause threads to be bound to cores). + */ + +ompd_rc_t ompd_get_display_control_vars ( + ompd_address_space_handle_t *handle, /* IN */ + const char * const **control_var_values /* OUT */ +); +typedef ompd_rc_t (*ompd_get_display_control_vars_apifn_t) ( + ompd_address_space_handle_t *handle, /* IN */ + const char * const **control_var_values /* OUT */ +); + +ompd_rc_t ompd_release_display_control_vars ( + const char * const **control_var_values /* IN */ +); +typedef ompd_rc_t (*ompd_release_display_control_vars_apifn_t) ( + const char * const **control_var_values /* IN */ +); + +#ifdef __cplusplus +} +#endif +#endif /* SRC_OMPD_H_ */ diff --git a/libompd/src/ompd_intel.cpp b/libompd/src/ompd_intel.cpp new file mode 100644 index 000000000..756bcbb64 --- /dev/null +++ b/libompd/src/ompd_intel.cpp @@ -0,0 +1,1797 @@ +/* + * ompd_intel.cpp + * + * Created on: Jan 14, 2015 + * Author: Ignacio Laguna + * Joachim Protze + * Contact: ilaguna@llnl.gov + * protze@llnl.gov + */ +/******************************************************************************* + * This implements an OMPD DLL the Intel runtime library. + */ + +#define NDEBUG 1 + +#include "ompd_intel.h" +#include "ompd.h" +// #include +#include +#include +#include +#include +#include +#include +#include "TargetValue.h" + +const ompd_callbacks_t *callbacks = NULL; +ompd_target_type_sizes_t type_sizes; +uint64_t ompd_state; + +//void* operator new(std::size_t size) /*throw (std::bad_alloc)*/ +/*{ + void* res; + ompd_rc_t ret = callbacks->dmemory_alloc(size, &res); + if (ret==ompd_rc_ok) + return res; + throw std::bad_alloc(); +}*/ +//void* operator new[](std::size_t size) /*throw (std::bad_alloc)*/ +/*{ + void* res; + ompd_rc_t ret = callbacks->dmemory_alloc(size, &res); + if (ret==ompd_rc_ok) + return res; + throw std::bad_alloc(); +} +void operator delete(void* addr) throw () +{ + ompd_rc_t ret = callbacks->dmemory_free(addr); + if (ret!=ompd_rc_ok) + throw std::bad_alloc(); +} +void operator delete[](void* addr) throw () +{ + ompd_rc_t ret = callbacks->dmemory_free(addr); + if (ret!=ompd_rc_ok) + throw std::bad_alloc(); +}*/ + + +/* --- OMPD functions ------------------------------------------------------- */ + +/* --- 3 Initialization ----------------------------------------------------- */ + +ompd_rc_t ompd_initialize (const ompd_callbacks_t *table) +{ + ompd_rc_t ret = table ? ompd_rc_ok : ompd_rc_bad_input; + callbacks = table; + TValue::callbacks = table; + + return ret; +} + +ompd_rc_t ompd_finalize ( void ){ + return ompd_rc_ok; +} + + +ompd_rc_t ompd_process_initialize ( + ompd_address_space_context_t *context, /* IN: debugger handle for the target */ + ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the target */ + ) +{ + if (!context) + return ompd_rc_bad_input; + if (!addrhandle) + return ompd_rc_bad_input; + + int rtl_version; + ompd_rc_t ret = initTypeSizes(context); + if (ret != ompd_rc_ok) + return ret; + ret = TValue(context, "ompd_rtl_version"). + castBase(ompd_type_int). + getValue(rtl_version); + if ((ret == ompd_rc_ok && rtl_version<5) || ret == ompd_rc_target_read_error) + return ompd_rc_incompatible; + if (ret != ompd_rc_ok) + return ret; + ret = TValue(context, "ompd_state"). + castBase(ompd_type_long_long). + getValue(ompd_state); + if (ret != ompd_rc_ok) + return ret; + *addrhandle = new ompd_address_space_handle_t; + if (!addrhandle) + return ompd_rc_error; + (*addrhandle)->context = context; + (*addrhandle)->kind = ompd_device_kind_host; + + return ompd_rc_ok; +} + +ompd_rc_t ompd_release_address_space_handle ( + ompd_address_space_handle_t *addr_handle /* IN: handle for the address space */ + ) +{ + if (!addr_handle) + return ompd_rc_bad_input; + + delete addr_handle; + return ompd_rc_ok; +} + +ompd_rc_t ompd_device_initialize ( + ompd_address_space_context_t *context, /* IN: */ + ompd_device_identifier_t id, /* IN: object defined by native device API */ + ompd_device_kind_t kind, /* IN: */ + ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the device */ + ) +{ + if (!context) + return ompd_rc_bad_input; + + ompd_rc_t ret = initTypeSizes(context); + if (ret != ompd_rc_ok) + return ret; + + uint64_t ompd_num_cuda_devices; + + ompd_address_space_context_t *process_context; + ret = callbacks->get_containing_process_context(context, &process_context); + if ( ret != ompd_rc_ok ) + return ret; + + ret = TValue(process_context, "ompd_num_cuda_devices"). + castBase(ompd_type_long_long). + getValue(ompd_num_cuda_devices); + if (ret != ompd_rc_ok) { + return ret; + } + + for (uint64_t i = 0; i < ompd_num_cuda_devices; i++) { + uint64_t cuda_ctx; + + /* TODO(mjm) - Hack! Currently using ompt_parallel_id_t. Need to find a + * place to define ID type information for CUDA contexts + */ + ret = TValue(process_context, "ompd_CudaContextArray"). + cast("ompt_parallel_id_t",1). + getArrayElement(i). + castBase(ompd_type_long_long). + getValue(cuda_ctx); + + if ( ret != ompd_rc_ok ) + continue; + + if (cuda_ctx == id) { + *addrhandle = new ompd_address_space_handle_t; + if (!addrhandle) + return ompd_rc_error; + (*addrhandle)->context = context; + + return ompd_rc_ok; + } + } + + /* TODO(mjm) - Find appropriate error return result for not finding a match */ + return ompd_rc_ok; +} + +/* --- 4 Handle Management -------------------------------------------------- */ + +/* --- 4.1 Thread Handles --------------------------------------------------- */ + +/* thread_handle is of type (kmp_base_info_t) */ + +ompd_rc_t ompd_get_threads ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ + int *num_handles /* OUT: number of handles in the array */ + ) +{ + int i; + if (!addr_handle) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = addr_handle->context; + ompd_rc_t ret; + + if (!context) + return ompd_rc_stale_handle; + + /* num_handles must be supplied, although thread_handle_array need not */ + if (!num_handles) + return ompd_rc_bad_input; + + assert(callbacks && "Callback table not initialized!"); + + int nth; + ret = TValue(context, "__kmp_nth"). + castBase("__kmp_nth"). + getValue(nth); + + if ( ret != ompd_rc_ok ) + return ret; + + *num_handles = nth; + + /* if thread_handle_array is NULL, then we return only the number of */ + /* thread handles */ + if ( ! thread_handle_array ) + return ret; + + TValue kmp_threads = TValue(context, "__kmp_threads"). /* __kmp_threads */ + cast("kmp_info_t",2); + if (kmp_threads.gotError()) + return kmp_threads.getError(); + + ret = callbacks->dmemory_alloc(nth * sizeof(ompd_thread_handle_t*), (void**)(thread_handle_array)); + if ( ret != ompd_rc_ok ) + return ret; + + /* From here on control *MUST* flow to the end of the function to make */ + /* sure any memory is released should an error occur. */ + + /* zero out the array: make clean up on error easier */ + for ( i = 0; i < *num_handles; i++ ) + (*thread_handle_array) [ i ] = 0; + + for (i =0; (ompd_rc_ok == ret) && (i<*num_handles); i++) + { + ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), (void**)(*thread_handle_array+i)); + if ( ompd_rc_ok == ret ) + { + (*thread_handle_array)[i]->ah = addr_handle; + ret = kmp_threads. + getArrayElement(i). /* __kmp_threads[i] */ + access("th"). /* __kmp_threads[i]->th */ + getAddress(&((*thread_handle_array)[i]->th)); + } + else + { + (*thread_handle_array) [ i ] = 0; + } + } + if ( ompd_rc_ok != ret ) + { + ompd_rc_t free_err; + + /* some error: we need to release the memory we've acquired */ + for ( i = 0; ((*thread_handle_array)[i]) && (i < *num_handles); i++ ) + { + free_err = callbacks->dmemory_free ( (void *) (*thread_handle_array)[i] ); + if ( ompd_rc_ok != free_err ) + { + /* we don't want to return free_err from the function as */ + /* this would mask the error we've detected. But we do */ + /* want some way to report that we're having trouble */ + /* releasing memory. */ + callbacks->print_string ( "OMPD (ompd_get_threads): error releasing thread handle after error\n" ); + } + } + /* now release the vector */ + free_err = callbacks->dmemory_free ( (void *) (*thread_handle_array) ); + if ( ompd_rc_ok != free_err ) + { + callbacks->print_string ( "OMPD (ompd_get_threads): error releasing thread handle vector after error\n" ); + } + (*thread_handle_array) = 0; + } + return ret; +} + +ompd_rc_t ompd_get_thread_in_parallel( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ + int *num_handles /* OUT: number of handles in the array */ + ) +{ + if (!parallel_handle) + return ompd_rc_stale_handle; + if (!parallel_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = parallel_handle->ah->context; + ompd_rc_t ret; + int i; + + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + TValue th = TValue(context, parallel_handle->th). /* t */ + cast("kmp_base_team_t",0); + if ( th.gotError() ) + return th.getError(); + + ret = th.access("t_nproc"). /*t.t_nproc*/ + castBase(). + getValue(*num_handles); + + if ( ret != ompd_rc_ok ) + return ret; + + ret = callbacks->dmemory_alloc((*num_handles) * sizeof(ompd_thread_handle_t*), (void**)thread_handle_array); + + if ( ret != ompd_rc_ok ) + return ret; + + /* From here on control *MUST* flow to the end of the function to make */ + /* sure any memory is released should an error occur. */ + + /* zero out the array: make clean up on error easier */ + for ( i = 0; i < *num_handles; i++ ) + (*thread_handle_array) [ i ] = 0; + + for ( i = 0; (i < *num_handles) && ( ret == ompd_rc_ok ); i++) + { + ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), (void**)(*thread_handle_array+i)); + if ( ret == ompd_rc_ok ) + { + (*thread_handle_array)[i]->ah=parallel_handle->ah; + ret = th.access("t_threads"). /*t.t_threads*/ + cast("kmp_info_t",2). + getArrayElement(i). /*t.t_threads[i]*/ + access("th"). /*t.t_threads[i]->th*/ + getAddress(&((*thread_handle_array)[i]->th)); + } + else + { + (*thread_handle_array)[i]=0; + } + } + if ( ompd_rc_ok != ret ) + { + ompd_rc_t free_err; + + /* some error: we need to release the memory we've acquired */ + for ( i = 0; ((*thread_handle_array)[i]) && (i < *num_handles); i++ ) + { + free_err = callbacks->dmemory_free ( (void *) (*thread_handle_array)[i] ); + if ( ompd_rc_ok != free_err ) + { + /* we don't want to return free_err from the function as */ + /* this would mask the error we've detected. But we do */ + /* want some way to report that we're having trouble */ + /* releasing memory. */ + callbacks->print_string ( "OMPD (ompd_get_thread_in_parallel): error releasing thread handle after error\n" ); + } + } + /* now release the vector */ + free_err = callbacks->dmemory_free ( (void *) (*thread_handle_array) ); + if ( ompd_rc_ok != free_err ) + { + callbacks->print_string ( "OMPD (ompd_get_thread_in_parallel): error releasing thread handle vector after error\n" ); + } + (*thread_handle_array) = 0; + } + return ret; +} + +ompd_rc_t ompd_get_master_thread_in_parallel ( + ompd_parallel_handle_t *parallel_handle, /* IN */ + ompd_thread_handle_t **thread_handle) +{ + if (!parallel_handle) + return ompd_rc_stale_handle; + if (!parallel_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = parallel_handle->ah->context; + ompd_rc_t ret; + + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + int tId; + ret = TValue(context, parallel_handle->th). /*t*/ + cast("kmp_base_team_t",0). + access("t_master_tid"). /*t.t_master_tid*/ + castBase(). + getValue(tId); + + if ( ret != ompd_rc_ok ) + return ret; + + if (tId < 0) /*thread is no omp worker*/ + return ompd_rc_unavailable; + ompd_address_t taddr; + + ret = TValue(context, "__kmp_threads"). /*__kmp_threads*/ + cast("kmp_info_t",2). + getArrayElement(tId). /* __kmp_threads[t]*/ + access("th"). /* __kmp_threads[t]->th*/ + getAddress(&taddr); + if ( ret != ompd_rc_ok ) + return ret; + + ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), (void**)(thread_handle)); + if ( ret != ompd_rc_ok ) + return ret; + (*thread_handle)->ah = parallel_handle->ah; + (*thread_handle)->th = taddr; + + return ret; +} + +ompd_rc_t ompd_release_thread_handle( + ompd_thread_handle_t *thread_handle /* IN: OpenMP parallel handle */ + ) +{ + if (!thread_handle) + return ompd_rc_stale_handle; + ompd_rc_t ret = callbacks->dmemory_free((void*)(thread_handle)); + if ( ret != ompd_rc_ok ) + return ret; + return ompd_rc_ok; +} + +ompd_rc_t ompd_thread_handle_compare ( + ompd_thread_handle_t *thread_handle_1, + ompd_thread_handle_t *thread_handle_2, + int *cmp_value +){ + if (!thread_handle_1) + return ompd_rc_stale_handle; + if (!thread_handle_2) + return ompd_rc_stale_handle; + *cmp_value = thread_handle_1->th.address - thread_handle_2->th.address; + return ompd_rc_ok; +} + +ompd_rc_t ompd_get_thread_handle_string_id ( + ompd_thread_handle_t *thread_handle, + char **string_id + ) +{ + pthread_t osthread; + ompd_rc_t ret; + ret = ompd_get_osthread(thread_handle, ompd_osthread_pthread, sizeof(pthread_t), &osthread); + if (ret!=ompd_rc_ok) + return ret; + ret = callbacks->dmemory_alloc(sizeof(void*)*2+3, (void**)string_id); + if (ret!=ompd_rc_ok) + return ret; + sprintf(*string_id, "0x%llx", (long long)osthread); + return ompd_rc_ok; +} + + +/* --- 4.2 Parallel Region Handles------------------------------------------- */ + +/* parallel_handle is of type (kmp_base_team_t)*/ + +ompd_rc_t ompd_get_top_parallel_region( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ + ) +{ + if (!thread_handle) + return ompd_rc_stale_handle; + if (!thread_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = thread_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + ompd_address_t taddr, lwt; + + TValue teamdata = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ + cast("kmp_base_info_t"). + access("th_team"). /*__kmp_threads[t]->th.th_team*/ + cast("kmp_team_p", 1). + access("t"); /*__kmp_threads[t]->th.th_team->t*/ + + ompd_rc_t ret = teamdata. + getAddress(&taddr); + if ( ret != ompd_rc_ok ) + return ret; + + lwt.segment = OMPD_SEGMENT_UNSPECIFIED; + ret = teamdata. + cast("kmp_base_team_t",0). + access("ompt_serialized_team_info"). + castBase(). + getValue(lwt.address); + if ( ret != ompd_rc_ok ) + return ret; + + ret = callbacks->dmemory_alloc(sizeof(ompd_parallel_handle_t), (void**)(parallel_handle)); + if ( ret != ompd_rc_ok ) + return ret; + + (*parallel_handle)->ah = thread_handle->ah; + (*parallel_handle)->th = taddr; + (*parallel_handle)->lwt = lwt; + return ompd_rc_ok; +} + +ompd_rc_t ompd_get_enclosing_parallel_handle( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ) +{ + if (!parallel_handle) + return ompd_rc_stale_handle; + if (!parallel_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = parallel_handle->ah->context; + + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + ompd_address_t taddr=parallel_handle->th, lwt; + + ompd_rc_t ret = ompd_rc_stale_handle; + TValue lwtValue = TValue(context, parallel_handle->lwt); + if (lwtValue.getError() == ompd_rc_ok) // lwt == 0x0 + { // if we are in lwt, get parent + ret = lwtValue. + cast("ompt_lw_taskteam_t",0). + access("parent"). + cast("ompt_lw_taskteam_t",1). + dereference(). + getAddress(&lwt); + } + if ( ret != ompd_rc_ok ) + { // no lwt or parent==0x0 + + TValue teamdata = TValue(context, parallel_handle->th). /*__kmp_threads[t]->th*/ + cast("kmp_base_team_t",0). /*t*/ + access("t_parent"). /*t.t_parent*/ + cast("kmp_team_p",1). + access("t"); /*t.t_parent->t*/ + + ret = teamdata. + getAddress(&taddr); + if ( ret != ompd_rc_ok ) + return ret; + + lwt.segment = OMPD_SEGMENT_UNSPECIFIED; + ret = teamdata. + cast("kmp_base_team_t",0). + access("ompt_serialized_team_info"). + castBase(). + getValue(lwt.address); + if ( ret != ompd_rc_ok ) + return ret; + } + + ret = callbacks->dmemory_alloc(sizeof(ompd_parallel_handle_t), (void**)(enclosing_parallel_handle)); + if ( ret != ompd_rc_ok ) + return ret; + (*enclosing_parallel_handle)->th = taddr; + (*enclosing_parallel_handle)->lwt = lwt; + (*enclosing_parallel_handle)->ah = parallel_handle->ah; + return ompd_rc_ok; +} + +ompd_rc_t ompd_get_task_enclosing_parallel_handle( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + ompd_address_t taddr; + + ompd_rc_t ret; + ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). /*td*/ + access("td_team"). /*td.td_team*/ + cast("kmp_team_p",1). + access("t"). /*td.td_team->t*/ + getAddress(&taddr); + + if ( ret != ompd_rc_ok ) + return ret; + + ret = callbacks->dmemory_alloc(sizeof(ompd_parallel_handle_t), (void**)(enclosing_parallel_handle)); + if ( ret != ompd_rc_ok ) + return ret; + + (*enclosing_parallel_handle)->ah = task_handle->ah; + (*enclosing_parallel_handle)->lwt = task_handle->lwt; + (*enclosing_parallel_handle)->th = taddr; + return ompd_rc_ok; +} + +ompd_rc_t ompd_release_parallel_handle( + ompd_parallel_handle_t *parallel_handle /* IN: OpenMP parallel handle */ + ) +{ + if (!parallel_handle) + return ompd_rc_stale_handle; + ompd_rc_t ret = callbacks->dmemory_free((void*)(parallel_handle)); + if ( ret != ompd_rc_ok ) + return ret; + return ompd_rc_ok; +} + + +ompd_rc_t ompd_parallel_handle_compare ( + ompd_parallel_handle_t *parallel_handle_1, + ompd_parallel_handle_t *parallel_handle_2, + int *cmp_value +){ + if (!parallel_handle_1) + return ompd_rc_stale_handle; + if (!parallel_handle_2) + return ompd_rc_stale_handle; + if (parallel_handle_1->th.address - parallel_handle_2->th.address) + *cmp_value = parallel_handle_1->th.address - parallel_handle_2->th.address; + else + *cmp_value = parallel_handle_1->lwt.address - parallel_handle_2->lwt.address; + return ompd_rc_ok; +} + +ompd_rc_t ompd_get_parallel_handle_string_id ( + ompd_parallel_handle_t *parallel_handle, + char **string_id + ) +{ + ompd_parallel_id_t id; + ompd_rc_t ret; + ret = ompd_get_parallel_id(parallel_handle, &id); + if (ret!=ompd_rc_ok) + return ret; + ret = callbacks->dmemory_alloc(sizeof(void*)*2+3, (void**)string_id); + if (ret!=ompd_rc_ok) + return ret; + sprintf(*string_id, "0x%llx", (long long)id); + return ompd_rc_ok; +} + + +/* --- 4.3 Task Handles ----------------------------------------------------- */ + +/* task_handle is of type (kmp_taskdata_t) */ + +ompd_rc_t ompd_get_top_task_region( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ + ) +{ + if (!thread_handle) + return ompd_rc_stale_handle; + if (!thread_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = thread_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + ompd_address_t taddr, lwt; + + TValue taskdata = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ + cast("kmp_base_info_t"). + access("th_current_task"). /*__kmp_threads[t]->th.th_current_task*/ + cast("kmp_taskdata_t", 1); + + ompd_rc_t ret = taskdata. + dereference(). + getAddress(&taddr); + if ( ret != ompd_rc_ok ) + return ret; + + lwt.segment = OMPD_SEGMENT_UNSPECIFIED; + ret = taskdata. + access("td_team"). /*td.td_team*/ + cast("kmp_team_p",1). + access("t"). /*td.td_team->t*/ + cast("kmp_base_team_t",0). + access("ompt_serialized_team_info"). + castBase(). + getValue(lwt.address); + if ( ret != ompd_rc_ok ) + return ret; + + ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(task_handle)); + if ( ret != ompd_rc_ok ) + return ret; + + (*task_handle)->th = taddr; + (*task_handle)->lwt = lwt; + (*task_handle)->ah = thread_handle->ah; + return ompd_rc_ok; +} + +ompd_rc_t ompd_get_ancestor_task_region( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ) +{ + return ompd_get_generating_ancestor_task_region(task_handle,parent_task_handle); +} + +ompd_rc_t ompd_get_generating_ancestor_task_region( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + ompd_address_t taddr=task_handle->th, lwt; + + ompd_rc_t ret = ompd_rc_stale_handle; + TValue lwtValue = TValue(context, task_handle->lwt); + if (lwtValue.getError() == ompd_rc_ok) // lwt == 0x0 + { // if we are in lwt, get parent + ret = lwtValue. + cast("ompt_lw_taskteam_t",0). + access("parent"). + cast("ompt_lw_taskteam_t",1). + dereference(). + getAddress(&lwt); + } + if ( ret != ompd_rc_ok ) + { // no lwt or parent==0x0 + + TValue taskdata = TValue(context, task_handle->th). /*__kmp_threads[t]->th*/ + cast("kmp_taskdata_t"). /*td*/ + access("td_parent"). /*td->td_parent*/ + cast("kmp_taskdata_t", 1); + + ret = taskdata. + dereference(). + getAddress(&taddr); + if ( ret != ompd_rc_ok ) + return ret; + + lwt.segment = OMPD_SEGMENT_UNSPECIFIED; + ret = taskdata. + access("td_team"). /*td.td_team*/ + cast("kmp_team_p",1). + access("t"). /*td.td_team->t*/ + cast("kmp_base_team_t",0). + access("ompt_serialized_team_info"). + castBase(). + getValue(lwt.address); + if ( ret != ompd_rc_ok ) + return ret; + } + + ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(parent_task_handle)); + if ( ret != ompd_rc_ok ) + return ret; + + (*parent_task_handle)->th = taddr; + (*parent_task_handle)->lwt = lwt; + (*parent_task_handle)->ah = task_handle->ah; + return ret; +} + +ompd_rc_t ompd_get_scheduling_ancestor_task_region( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + ompd_address_t taddr; + + ompd_rc_t ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). /*td*/ + access("ompt_task_info"). // td->ompt_task_info + cast("ompt_task_info_t"). + access("scheduling_parent"). // td->ompd_task_info.scheduling_parent + cast("kmp_taskdata_t", 1). + dereference(). + getAddress(&taddr); + + if ( ret != ompd_rc_ok ) + return ret; + ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(parent_task_handle)); + if ( ret != ompd_rc_ok ) + return ret; + + (*parent_task_handle)->th = taddr; + (*parent_task_handle)->ah = task_handle->ah; + return ret; +} + +ompd_rc_t ompd_get_implicit_task_in_parallel( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_task_handle_t ***task_handle_array, /* OUT: array of OpenMP task handles */ + int *num_handles /* OUT: number of task handles */ + ) +{ + int i; + if (!parallel_handle) + return ompd_rc_stale_handle; + if (!parallel_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = parallel_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + TValue th = TValue(context, parallel_handle->th). /*t*/ + cast("kmp_base_team_t",0); + if ( th.gotError() ) + return th.getError(); + + ompd_rc_t ret; + if (parallel_handle->lwt.address!=0) + *num_handles=1; + else + { + ret = th.access("t_nproc"). /*t.t_nproc*/ + castBase(). + getValue(*num_handles); + if ( ret != ompd_rc_ok ) + return ret; + } + + ret = callbacks->dmemory_alloc((*num_handles) * sizeof(ompd_task_handle_t*), (void**)task_handle_array); + + if ( ret != ompd_rc_ok ) + return ret; + + /* From here on control *MUST* flow to the end of the function to make */ + /* sure any memory is released should an error occur. */ + + /* zero out the array: make clean up on error easier */ + for ( i = 0; i < *num_handles; i++ ) + (*task_handle_array) [ i ] = 0; + + for ( i = 0; (i < *num_handles) && ( ret == ompd_rc_ok ); i++) + { + ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(*task_handle_array+i)); + if ( ret == ompd_rc_ok ) + { + (*task_handle_array)[i]->lwt = parallel_handle->lwt; + (*task_handle_array)[i]->ah = parallel_handle->ah; + ret = th.access("t_implicit_task_taskdata"). /*t.t_implicit_task_taskdata*/ + cast("kmp_taskdata_t",1). + getArrayElement(i). /*t.t_implicit_task_taskdata[i]*/ + getAddress(&((*task_handle_array)[i]->th)); + } + else + { + (*task_handle_array)[i]=0; + } + } + if ( ompd_rc_ok != ret ) + { + ompd_rc_t free_err; + + /* some error: we need to release the memory we've acquired */ + for ( i = 0; ((*task_handle_array)[i]) && (i < *num_handles); i++ ) + { + free_err = callbacks->dmemory_free ( (void *) (*task_handle_array)[i] ); + if ( ompd_rc_ok != free_err ) + { + /* we don't want to return free_err from the function as */ + /* this would mask the error we've detected. But we do */ + /* want some way to report that we're having trouble */ + /* releasing memory. */ + callbacks->print_string ( "OMPD (ompd_get_implicit_task_in_parallel): error releasing task handle after error\n" ); + } + } + /* now release the vector */ + free_err = callbacks->dmemory_free ( (void *) (*task_handle_array) ); + if ( ompd_rc_ok != free_err ) + { + callbacks->print_string ( "OMPD (ompd_get_implicit_task_in_parallel): error releasing task handle vector after error\n" ); + } + (*task_handle_array) = 0; + } + return ret; +} + +ompd_rc_t ompd_release_task_handle( + ompd_task_handle_t *task_handle /* IN: OpenMP task handle */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + ompd_rc_t ret = callbacks->dmemory_free((void*)(task_handle)); + if ( ret != ompd_rc_ok ) + return ret; + return ompd_rc_ok; +} + +ompd_rc_t ompd_task_handle_compare ( + ompd_task_handle_t *task_handle_1, + ompd_task_handle_t *task_handle_2, + int *cmp_value +){ + if (!task_handle_1) + return ompd_rc_stale_handle; + if (!task_handle_2) + return ompd_rc_stale_handle; + if (task_handle_1->th.address - task_handle_2->th.address) + *cmp_value = task_handle_1->th.address - task_handle_2->th.address; + else + *cmp_value = task_handle_1->lwt.address - task_handle_2->lwt.address; + return ompd_rc_ok; +} + +ompd_rc_t ompd_get_task_handle_string_id ( + ompd_task_handle_t *task_handle, + char **string_id + ) +{ + ompd_task_id_t id; + ompd_rc_t ret = ompd_get_task_id(task_handle, &id); + if (ret!=ompd_rc_ok) + return ret; + ret = callbacks->dmemory_alloc(sizeof(void*)*2+3, (void**)string_id); + if (ret!=ompd_rc_ok) + return ret; + sprintf(*string_id, "0x%llx", (long long)id); + return ompd_rc_ok; +} + + +/* --- 5 Process and Thread Settings ---------------------------------------- */ + +ompd_rc_t ompd_get_num_procs( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_tword_t *val /* OUT: number of processes */ + ) +{ + if (!addr_handle) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = addr_handle->context; + ompd_rc_t ret; + + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + int nth; + ret = TValue(context, "__kmp_avail_proc"). + castBase("__kmp_avail_proc"). + getValue(nth); + *val = nth; + return ret; +} + +ompd_rc_t ompd_get_thread_limit( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_tword_t *val /* OUT: max number of threads */ + ) +{ + if (!addr_handle) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = addr_handle->context; + ompd_rc_t ret; + + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + int nth; + ret = TValue(context, "__kmp_max_nth"). + castBase("__kmp_max_nth"). + getValue(nth); + *val = nth; + return ret; +} + +/* --- 6 Parallel Region Inqueries ------------------------------------------ */ +/* --- 6.1 Settings --------------------------------------------------------- */ + +ompd_rc_t ompd_get_num_threads( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_tword_t *val /* OUT: number of threads */ + ) +{ + if (!parallel_handle) + return ompd_rc_stale_handle; + if (!parallel_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = parallel_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ompd_rc_t ret = ompd_rc_ok; + if (parallel_handle->lwt.address!=0) + *val = 1; + else + { + uint32_t res; + ret = TValue(context, parallel_handle->th). + cast("kmp_base_team_t",0). /*t*/ + access("t_nproc"). /*t.t_nproc*/ + castBase(). + getValue(res); + *val = res; + } + return ret; +} + +ompd_rc_t ompd_get_level( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_tword_t *val /* OUT: nesting level */ + ) +{ + if (!parallel_handle) + return ompd_rc_stale_handle; + if (!parallel_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = parallel_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + uint32_t res; + + ompd_rc_t ret = TValue(context, parallel_handle->th). + cast("kmp_base_team_t",0). /*t*/ + access("t_level"). /*t.t_level*/ + castBase(). + getValue(res); + *val = res; + return ret; +} + +ompd_rc_t ompd_get_active_level( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_tword_t *val /* OUT: active nesting level */ + ) +{ + if (!parallel_handle) + return ompd_rc_stale_handle; + if (!parallel_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = parallel_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + uint32_t res; + + ompd_rc_t ret = TValue(context, parallel_handle->th). + cast("kmp_base_team_t",0). /*t*/ + access("t_active_level"). /*t.t_active_level*/ + castBase(). + getValue(res); + *val = res; + return ret; +} + +/* --- 6.2 OMPT Parallel Region Inquiry Analogues ------------------------- */ + +ompd_rc_t ompd_get_parallel_id( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_parallel_id_t *id /* OUT: OpenMP parallel id */ + ) +{ + if (!parallel_handle) + return ompd_rc_stale_handle; + if (!parallel_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = parallel_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + if (!ompd_state) + return ompd_rc_needs_state_tracking; + + assert(callbacks && "Callback table not initialized!"); + + TValue teamInfo; + if(parallel_handle->lwt.address!=0) + teamInfo = TValue(context, parallel_handle->lwt). + cast("ompt_lw_taskteam_t",0); /*lwt*/ + else + teamInfo = TValue(context, parallel_handle->th). + cast("kmp_base_team_t",0); /*t*/ + ompd_rc_t ret = teamInfo. + access("ompt_team_info"). /*t.ompt_team_info*/ + cast("ompt_team_info_t",0). + access("parallel_id"). /*t.ompt_team_info.parallel_id*/ + castBase("ompt_parallel_id_t"). /*type: ompt_parallel_id_t*/ + getValue(*id); + return ret; +} + +ompd_rc_t ompd_get_parallel_function( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ + ) +{ + if (!parallel_handle) + return ompd_rc_stale_handle; + if (!parallel_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = parallel_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + if (!ompd_state) + return ompd_rc_needs_state_tracking; + + assert(callbacks && "Callback table not initialized!"); + parallel_addr->segment = OMPD_SEGMENT_UNSPECIFIED; + + TValue teamInfo; + if(parallel_handle->lwt.address!=0) + teamInfo = TValue(context, parallel_handle->lwt). + cast("ompt_lw_taskteam_t",0); /*lwt*/ + else + teamInfo = TValue(context, parallel_handle->th). + cast("kmp_base_team_t",0); /*t*/ + ompd_rc_t ret = teamInfo. + access("ompt_team_info"). /*t.ompt_team_info*/ + cast("ompt_team_info_t",0). + access("microtask"). /*t.ompt_team_info.microtask*/ + castBase(). + getValue(parallel_addr->address); + return ret; +} + +/* --- 7 Thread Inquiry ----------------------------------------------------- */ + +/* --- 7.1 Operating System Thread Inquiry ---------------------------------- */ + +ompd_rc_t ompd_get_thread_handle ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_osthread_kind_t kind, + ompd_size_t sizeof_osthread, + const void* osthread, + ompd_thread_handle_t **thread_handle) +{ + if (!addr_handle) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = addr_handle->context; + ompd_rc_t ret; + + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + ompd_thread_context_t *tcontext; + ret = callbacks->get_thread_context_for_osthread(context, kind, sizeof_osthread, osthread, &tcontext); + if ( ret != ompd_rc_ok ) + return ret; + + int tId; + + if (kind == ompd_osthread_cudalogical) + { + ompd_cudathread_coord_t* p = (ompd_cudathread_coord_t*)osthread; + + // omptarget_nvptx_threadPrivateContext->topTaskDescr[p->threadIdx.x]->data.items.threadId + + ret = TValue(context, tcontext, "omptarget_nvptx_threadPrivateContext", OMPD_SEGMENT_CUDA_PTX_SHARED). + cast("omptarget_nvptx_ThreadPrivateContext", 1, OMPD_SEGMENT_CUDA_PTX_SHARED). + access("topTaskDescr"). + cast("omptarget_nvptx_TaskDescr", 1, OMPD_SEGMENT_CUDA_PTX_GLOBAL). + getArrayElement(p->threadIdx.x). + access("data__items__threadId"). + castBase(ompd_type_short). + getValue(tId); + + if ( ret != ompd_rc_ok ) + return ret; + + if (tId != p->threadIdx.x) + return ompd_rc_stale_handle; + } + else + { + ret = TValue(context, tcontext, "__kmp_gtid"). + castBase("__kmp_gtid"). + getValue(tId); + if ( ret != ompd_rc_ok ) + return ret; + + if (tId < 0) // thread is no omp worker + return ompd_rc_unavailable; + + TValue th = TValue(context, "__kmp_threads"). // __kmp_threads + cast("kmp_info_t",2). + getArrayElement(tId). /*__kmp_threads[t]*/ + access("th"); /*__kmp_threads[t]->th*/ + + ompd_address_t taddr; + ret = th.getAddress(&taddr); + if ( ret != ompd_rc_ok ) + return ret; + ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), (void**)(thread_handle)); + if ( ret != ompd_rc_ok ) + return ret; + (*thread_handle)->ah = addr_handle; + (*thread_handle)->th = taddr; + +#ifndef NDEBUG + if ( ret != ompd_rc_ok ) + return ret; + + pthread_t oshandle; + TBaseValue ds_handle = th.cast("kmp_base_info_t"). + access("th_info"). /*__kmp_threads[t]->th.th_info*/ + cast("kmp_desc_t"). + access("ds"). /*__kmp_threads[t]->th.th_info.ds*/ + cast("kmp_desc_base_t"). + access("ds_thread"). /*__kmp_threads[t]->th.th_info.ds.ds_thread*/ + castBase(); + + assert( ompd_rc_ok == ds_handle.getValue(oshandle) && oshandle == *(pthread_t*)(osthread) && "Callback table not initialized!"); +#endif + } + return ret; +} + +ompd_rc_t ompd_get_osthread ( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_osthread_kind_t kind, + ompd_size_t sizeof_osthread, + void *osthread + ) +{ + if (kind!=ompd_osthread_pthread) + return ompd_rc_bad_input; + if (!thread_handle) + return ompd_rc_stale_handle; + if (!thread_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = thread_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + ompd_size_t size; + ompd_rc_t ret = tf.getType(context, "kmp_thread_t").getSize(&size); + if ( ret != ompd_rc_ok ) + return ret; + if (sizeof_osthread!=size) + return ompd_rc_bad_input; + + assert(callbacks && "Callback table not initialized!"); + + ret = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ + cast("kmp_base_info_t"). + access("th_info"). /*__kmp_threads[t]->th.th_info*/ + cast("kmp_desc_t"). + access("ds"). /*__kmp_threads[t]->th.th_info.ds*/ + cast("kmp_desc_base_t"). + access("ds_thread"). /*__kmp_threads[t]->th.th_info.ds.ds_thread*/ + cast("kmp_thread_t"). + getRawValue(osthread,1); + return ret; +} + +ompd_rc_t ompd_get_thread_num( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_tword_t *val /* OUT: number of the thread within the team */ + ) +{ +// __kmp_threads[8]->th.th_info.ds.ds_tid + if (!thread_handle) + return ompd_rc_stale_handle; + if (!thread_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = thread_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ompd_rc_t ret = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ + cast("kmp_base_info_t"). + access("th_info"). /*__kmp_threads[t]->th.th_info*/ + cast("kmp_desc_t"). + access("ds"). /*__kmp_threads[t]->th.th_info.ds*/ + cast("kmp_desc_base_t"). + access("ds_tid"). /*__kmp_threads[t]->th.th_info.ds.ds_tid*/ + castBase(). + getValue(*val); + return ret; +} + + +/* --- 7.2 OMPT Thread State Inquiry Analogue ------------------------------- */ + +ompd_rc_t ompd_get_state ( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_state_t *state, /* OUT: State of this thread */ + ompd_wait_id_t *wait_id /* OUT: Wait ID */ + ) +{ + if (!thread_handle) + return ompd_rc_stale_handle; + if (!thread_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = thread_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + if (!ompd_state) + return ompd_rc_needs_state_tracking; + + assert(callbacks && "Callback table not initialized!"); + + TValue ompt_thread_info = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ + cast("kmp_base_info_t"). + access("ompt_thread_info"). /*__kmp_threads[t]->th.ompt_thread_info*/ + cast("ompt_thread_info_t"); + if (ompt_thread_info.gotError()) + return ompt_thread_info.getError(); + ompd_rc_t ret = ompt_thread_info. + access("state"). /*__kmp_threads[t]->th.ompt_thread_info.state*/ + castBase(). + getValue(*state); + if ( ret != ompd_rc_ok ) + return ret; + ret = ompt_thread_info. + access("wait_id"). /*__kmp_threads[t]->th.ompt_thread_info.state*/ + castBase(). + getValue(*wait_id); + return ret; +} + + +/* --- 8 Task Inquiry ------------------------------------------------------- */ + +/* --- 8.1 Task Settings ---------------------------------------------------- */ + +ompd_rc_t ompd_get_max_threads( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: max number of threads */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ompd_rc_t ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). // td + access("td_icvs"). // td->td_icvs + cast("kmp_internal_control_t", 0). + access("nproc"). // td->td_icvs.dynamic + castBase(). + getValue(*val); + + return ret; +} + +ompd_rc_t ompd_in_parallel( // Why do we need a task context for _in_parallel? + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: max number of threads */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + ompd_rc_t ret; + + assert(callbacks && "Callback table not initialized!"); + + ret = TValue(context, "__kmp_root"). // __kmp_root + cast("kmp_root_t",2). + dereference(). // (*__kmp_root) + access("r"). // (*__kmp_root)->r + cast("kmp_base_root_t"). + access("r_in_parallel"). // (*__kmp_root)->r.r_in_parallel + castBase(). + getValue(*val); + if ( ret != ompd_rc_ok ) + return ret; + if ( *val ) + *val=1; + + return ret; +} + +ompd_rc_t ompd_in_final( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: max number of threads */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ompd_rc_t ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). // td + access("td_flags"). // td->td_icvs + cast("kmp_tasking_flags_t"). + check("final", val); // td->td_icvs.max_active_levels + + return ret; +} + +ompd_rc_t ompd_get_dynamic( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: max number of threads */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ompd_rc_t ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). // td + access("td_icvs"). // td->td_icvs + cast("kmp_internal_control_t", 0). + access("dynamic"). // td->td_icvs.dynamic + castBase(). + getValue(*val); + + return ret; +} + +ompd_rc_t ompd_get_nested( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: max number of threads */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ompd_rc_t ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). // td + access("td_icvs"). // td->td_icvs + cast("kmp_internal_control_t", 0). + access("nested"). // td->td_icvs.nested + castBase(). + getValue(*val); + + return ret; +} + +ompd_rc_t ompd_get_max_active_levels( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: max number of threads */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ompd_rc_t ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). // td + access("td_icvs"). // td->td_icvs + cast("kmp_internal_control_t", 0). + access("max_active_levels"). // td->td_icvs.max_active_levels + castBase(). + getValue(*val); + + return ret; +} + +ompd_rc_t ompd_get_schedule( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_sched_t *kind, /* OUT: Kind of OpenMP schedule*/ + ompd_tword_t *modifier /* OUT: Schedunling modifier */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + TValue sched = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). // td + access("td_icvs"). // td->td_icvs + cast("kmp_internal_control_t", 0). + access("sched"). // td->td_icvs.sched + cast("kmp_r_sched_t", 0); + + ompd_rc_t ret = sched.access("r_sched_type"). // td->td_icvs.sched.r_sched_type + castBase(). + getValue(*kind); + if ( ret != ompd_rc_ok ) + return ret; + ret = sched.access("chunk"). // td->td_icvs.sched.r_sched_type + castBase(). + getValue(*modifier); + return ret; + +} + +ompd_rc_t ompd_get_proc_bind( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_proc_bind_t *bind /* OUT: Kind of proc-binding */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ompd_rc_t ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). // td + access("td_icvs"). // td->td_icvs + cast("kmp_internal_control_t", 0). + access("proc_bind"). // td->td_icvs.proc_bind + castBase(). + getValue(*bind); + + return ret; +} + +ompd_rc_t ompd_is_implicit( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_tword_t *val /* OUT: max number of threads */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ompd_rc_t ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t"). // td + access("td_flags"). // td->td_flags + cast("kmp_tasking_flags_t"). + check("tasktype", val); // td->td_flags.tasktype + *val^=1; // tasktype: explicit = 1, implicit = 0 => invert the value + return ret; +} + +/* --- 8.2 OMPT Task Inquiry Analogues -------------------------------------- */ + +ompd_rc_t ompd_get_task_frame( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_address_t *sp_exit, /* OUT: next frame is user code */ + ompd_address_t *sp_reentry /* OUT: previous frame is user code */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + if (!ompd_state) + return ompd_rc_needs_state_tracking; + + assert(callbacks && "Callback table not initialized!"); + + TValue taskInfo; + if(task_handle->lwt.address!=0) + taskInfo = TValue(context, task_handle->lwt). + cast("ompt_lw_taskteam_t",0); /*lwt*/ + else + taskInfo = TValue(context, task_handle->th). + cast("kmp_taskdata_t",0); /*t*/ + TValue frame = taskInfo. + access("ompt_task_info"). // td->ompt_task_info + cast("ompt_task_info_t"). + access("frame"). // td->ompd_task_info.frame + cast("ompt_frame_t", 0); + sp_reentry->segment = OMPD_SEGMENT_UNSPECIFIED; + ompd_rc_t ret = frame. + access("reenter_runtime_frame"). // td->ompt_task_info.frame.reenter_runtime_frame + castBase(). + getValue(sp_reentry->address); + + if ( ret != ompd_rc_ok ) + return ret; + + sp_exit->segment = OMPD_SEGMENT_UNSPECIFIED; + ret = frame. + access("exit_runtime_frame"). // td->ompt_task_info.frame.exit_runtime_frame + castBase(). + getValue(sp_exit->address); + + return ret; +} + +ompd_rc_t ompd_get_task_id( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_task_id_t *task_id /* OUT: OpenMP task ID */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + if (!ompd_state) + return ompd_rc_needs_state_tracking; + + assert(callbacks && "Callback table not initialized!"); + + TValue taskInfo; + if(task_handle->lwt.address!=0) + taskInfo = TValue(context, task_handle->lwt). + cast("ompt_lw_taskteam_t",0); /*lwt*/ + else + taskInfo = TValue(context, task_handle->th). + cast("kmp_taskdata_t",0); /*t*/ + ompd_rc_t ret = taskInfo. + access("ompt_task_info"). // td->ompt_task_info + cast("ompt_task_info_t"). + access("task_id"). // td->ompt_task_info.task_id + castBase("ompt_task_id_t"). + getValue(*task_id); + + return ret; +} + +ompd_rc_t ompd_get_task_function( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_address_t *task_addr /* OUT: first instruction in the task region */ + ) +{ + if (!task_handle) + return ompd_rc_stale_handle; + if (!task_handle->ah) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = task_handle->ah->context; + if (!context) + return ompd_rc_stale_handle; + if (!ompd_state) + return ompd_rc_needs_state_tracking; + + assert(callbacks && "Callback table not initialized!"); + +#if 0 + /* We don't have a task function for implicit tasks */ + ompd_tword_t implicit; + ompd_rc_t ret = ompd_is_implicit (task_handle, &implicit); + if (ret != ompd_rc_ok) + return ret; + if (implicit) + return ompd_rc_bad_input; +#else + ompd_rc_t ret; +#endif + task_addr->segment = OMPD_SEGMENT_UNSPECIFIED; + TValue taskInfo; + if(task_handle->lwt.address!=0) + taskInfo = TValue(context, task_handle->lwt). + cast("ompt_lw_taskteam_t",0); /*lwt*/ + else + taskInfo = TValue(context, task_handle->th). + cast("kmp_taskdata_t",0); /*t*/ + ret = taskInfo. + access("ompt_task_info"). /*td->ompt_task_info*/ + cast("ompt_task_info_t"). + access("function"). /*td->ompt_task_info.function*/ + castBase(). + getValue(task_addr->address); + return ret; +} + + +/* --- 9 OMPD Version and Compatibility Information ------------------------- */ + +ompd_rc_t ompd_get_version ( + int *version + ) +{ + *version = OMPD_VERSION; + return ompd_rc_ok; +} + +ompd_rc_t ompd_get_version_string( + const char **string /* OUT: OMPD version string */ + ) +{ + static char version_string[256]={0}; + if(version_string[0]=='\0') + sprintf(version_string, "Intel OpenMP %i.%i Debugging Library implemnting TR %i%c",OMPD_IMPLEMENTS_OPENMP, OMPD_IMPLEMENTS_OPENMP_SUBVERSION, OMPD_TR_VERSION, OMPD_TR_SUBVERSION); + *string = version_string; + return ompd_rc_ok; +} + +/* --- 12 Display Control Variables ----------------------------------------- */ + +ompd_rc_t ompd_get_display_control_vars ( + ompd_address_space_handle_t *handle, + const char * const **control_var_values +) +{ + static const char * const control_vars[] = {NULL}; + *control_var_values = control_vars; + return ompd_rc_ok; +} + +ompd_rc_t ompd_release_display_control_vars ( + const char * const **control_var_values +) +{ + return ompd_rc_ok; +} + + + + +/* --- Helper functions ----------------------------------------------------- */ + +ompd_rc_t initTypeSizes(ompd_address_space_context_t *context) +{ + static int inited=0; + static ompd_rc_t ret; + if (inited) + return ret; + ret = callbacks->tsizeof_prim(context, &type_sizes); + if (ret != ompd_rc_ok ) + return ret; + if (! (type_sizes.sizeof_pointer > 0) ) + return ompd_rc_error; + ret = callbacks->tsizeof_prim(context, &TValue::type_sizes); + if (ret != ompd_rc_ok ) + return ret; + inited=1; + return ret; +} diff --git a/libompd/src/ompd_intel.h b/libompd/src/ompd_intel.h new file mode 100644 index 000000000..5d571d841 --- /dev/null +++ b/libompd/src/ompd_intel.h @@ -0,0 +1,90 @@ +/* + * ompd_intel.h + * + * Created on: Jan 14, 2015 + * Author: Ignacio Laguna + * Joachim Protze + * Contact: ilaguna@llnl.gov + * protze@llnl.gov + */ +#ifndef SRC_OMPD_INTEL_H_ +#define SRC_OMPD_INTEL_H_ + +#ifdef __cplusplus + +#include +//#include +//void* operator new(std::size_t size) /*throw (std::bad_alloc)*/; +//void* operator new[](std::size_t size) /*throw (std::bad_alloc)*/; +//void operator delete(void* addr) throw (); +//void operator delete[](void* addr) throw (); + +extern "C" { +#endif + + +#define OMPD_IMPLEMENTS_OPENMP 3 +#define OMPD_IMPLEMENTS_OPENMP_SUBVERSION 1 +#define OMPD_TR_VERSION 6 +#define OMPD_TR_SUBVERSION 'j' +#define OMPD_VERSION (OMPD_IMPLEMENTS_OPENMP << 24) + (OMPD_IMPLEMENTS_OPENMP_SUBVERSION << 16) + (OMPD_TR_VERSION << 8) + OMPD_TR_SUBVERSION + +#include "ompd.h" +#include "ompd_typedefs.h" + +/****************************************************************************** + * General helper functions + */ +ompd_rc_t initTypeSizes(ompd_address_space_context_t *context); +//uint32_t getThreadLevel(ompd_context_t *context, int t); +/*int getNumberOfOMPThreads(ompd_context_t *context); +uint64_t getSystemThreadID(ompd_context_t *context, int t); +int64_t getOmpThreadID(ompd_context_t *context);*/ + + +#ifdef __cplusplus +} +#endif + + +typedef struct _ompd_address_space_context_s ompd_address_space_context_t; + +typedef struct _ompd_process_handle_s +{ + ompd_address_space_context_t* context; +} ompd_process_handle_t; + +typedef struct _ompd_address_space_handle_s +{ + ompd_address_space_context_t* context; + ompd_device_kind_t kind; + ompd_device_identifier_t id; +} ompd_address_space_handle_t; + +typedef struct _ompd_device_handle_s { + ompd_address_space_handle_t* ah; + ompd_address_t th; /* target handle */ +} ompd_device_handle_t; + +typedef struct _ompd_thread_handle_s +{ + ompd_address_space_handle_t* ah; + ompd_address_t th; /* target handle */ +} ompd_thread_handle_t; + +typedef struct _ompd_parallel_handle_s +{ + ompd_address_space_handle_t* ah; + ompd_address_t th; /* target handle */ + ompd_address_t lwt; /* lwt handle */ +} ompd_parallel_handle_t; + +typedef struct _ompd_task_handle_s +{ + ompd_address_space_handle_t* ah; + ompd_address_t th; /* target handle */ + ompd_address_t lwt; /* lwt handle */ +} ompd_task_handle_t; + + +#endif /* SRC_OMPD_INTEL_H_ */ diff --git a/libompd/src/ompd_test.c b/libompd/src/ompd_test.c new file mode 100644 index 000000000..cff8da96a --- /dev/null +++ b/libompd/src/ompd_test.c @@ -0,0 +1,81 @@ +/* + * ompd_test.c + * + * Created on: Dec 28, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +/******************************************************************************* + * This implements an OMPD DLL for testing purposes. + * It can be used as a template to implement (runtime-specific) OMPD DLLs. + */ + +#include +#include "ompd_test.h" +#include "assert.h" + +static ompd_callbacks_t *callbacks = NULL; + +ompd_rc_t ompd_initialize (ompd_callbacks_t *table) +{ + ompd_rc_t ret = table ? ompd_rc_ok : ompd_rc_bad_input; + callbacks = table; + return ret; +} + +/******************************************************************************* + * Testing interface. + * NOTE: *** These calls are not part of OMPD *** + * These calls perform tests of each callback routine that is defined in the + * debugger. The test routines start with "test_CB_". + */ + +void test_print_header() +{ + printf("\n*** OMPD Test ***\n"); +} + +void test_CB_dmemory_alloc() +{ + assert(callbacks && "Invalid callbacks table"); + test_print_header(); + + ompd_rc_t ret; + ompd_size_t bytes = 1024; + void *ptr = NULL; + printf("Allocate %lu bytes of memory...", bytes); + ret = callbacks->dmemory_alloc((ompd_context_t *)1, bytes, &ptr); + if (ret == ompd_rc_ok && ptr != NULL) + printf("Bytes allocated!\n"); + else + printf("Failed!\n"); + + printf("Free memory..."); + ret = callbacks->dmemory_free((ompd_context_t *)1, ptr); + if (ret == ompd_rc_ok) + printf("Memory freed.\n"); + else + printf("Failed!\n"); +} + +void test_CB_tsizeof_prim() +{ + assert(callbacks && "Invalid callbacks table"); + test_print_header(); + + ompd_rc_t ret; + ompd_target_type_sizes_t sizes; + ret = callbacks->tsizeof_prim((ompd_context_t *)1, &sizes); + if (ret == ompd_rc_ok) + { + printf("%-20s %du\n", "Size of char:", sizes.sizeof_char); + printf("%-20s %du\n", "Size of short:", sizes.sizeof_short); + printf("%-20s %du\n", "Size of int:", sizes.sizeof_int); + printf("%-20s %du\n", "Size of long:", sizes.sizeof_long); + printf("%-20s %du\n", "Size of long long:", sizes.sizeof_long_long); + printf("%-20s %du\n", "Size of pointer:", sizes.sizeof_pointer); + } + else + printf("Failed getting primitive sizes\n"); +} diff --git a/libompd/src/ompd_test.h b/libompd/src/ompd_test.h new file mode 100644 index 000000000..009ed7741 --- /dev/null +++ b/libompd/src/ompd_test.h @@ -0,0 +1,29 @@ +/* + * ompd_test.h + * + * Created on: Dec 28, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#ifndef SRC_OMPD_TEST_H_ +#define SRC_OMPD_TEST_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ompd.h" +#include "stdio.h" + +/******************************************************************************* + * NOTE: These calls are not part of OMPD. They are only used for testing. + */ + +void test_print_header(); +void test_CB_dmemory_alloc(); +void test_CB_tsizeof_prim(); + +#ifdef __cplusplus +} +#endif +#endif /* SRC_OMPD_TEST_H_ */ diff --git a/libompd/src/split_def_typedef.sh b/libompd/src/split_def_typedef.sh new file mode 100755 index 000000000..618dc2a1c --- /dev/null +++ b/libompd/src/split_def_typedef.sh @@ -0,0 +1,6 @@ +#!/bin/bash +# $0 +# keep block comments, and api function typedefs +sed '/^\/\*/{:b1;N;/\*\//!bb1;p};/^typedef.*_apifn_t/{:b2;N;/);/!bb2;s/_apifn_t/_fn_t/;p};d' $1 > $2 +# remove api function typedefs +sed '/^typedef.*_apifn_t/{:b2;N;/);/!bb2;d}' $1 > $3 From 8299cc2b29393adbb46a7f1af6b607552e4c1c5d Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Sat, 3 Feb 2018 06:01:56 -0600 Subject: [PATCH 31/46] Update ompd library to the symbol names in libomp --- libompd/src/CMakeLists.txt | 18 ++++---- libompd/src/{ompd_intel.cpp => omp-debug.cpp} | 42 +++++++++++-------- libompd/src/{ompd_intel.h => omp-debug.h} | 3 ++ libompd/src/ompd-template.h | 31 +++++++------- 4 files changed, 54 insertions(+), 40 deletions(-) rename libompd/src/{ompd_intel.cpp => omp-debug.cpp} (97%) rename libompd/src/{ompd_intel.h => omp-debug.h} (97%) diff --git a/libompd/src/CMakeLists.txt b/libompd/src/CMakeLists.txt index 46b887c87..676efb953 100644 --- a/libompd/src/CMakeLists.txt +++ b/libompd/src/CMakeLists.txt @@ -1,35 +1,35 @@ project (libompd) -add_library (ompd_intel SHARED TargetValue.cpp ompd_intel.cpp) +add_library (ompd SHARED TargetValue.cpp omp-debug.cpp) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") include_directories ( - ${CMAKE_BINARY_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR} ) -file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/include) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include) ADD_CUSTOM_TARGET ( ompd-header ALL - DEPENDS ${CMAKE_BINARY_DIR}/include/ompd.h ${CMAKE_BINARY_DIR}/include/ompd_typedefs.h + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/include/ompd.h ${CMAKE_CURRENT_BINARY_DIR}/include/ompd_typedefs.h ) add_custom_command ( - OUTPUT ${CMAKE_BINARY_DIR}/include/ompd.h ${CMAKE_BINARY_DIR}/include/ompd_typedefs.h + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/include/ompd.h ${CMAKE_CURRENT_BINARY_DIR}/include/ompd_typedefs.h COMMAND ${BASH} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/split_def_typedef.sh ${CMAKE_CURRENT_SOURCE_DIR}/ompd-template.h - ${CMAKE_BINARY_DIR}/include/ompd_typedefs.h - ${CMAKE_BINARY_DIR}/include/ompd.h + ${CMAKE_CURRENT_BINARY_DIR}/include/ompd_typedefs.h + ${CMAKE_CURRENT_BINARY_DIR}/include/ompd.h DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ompd-template.h ) -INSTALL( TARGETS ompd_intel +INSTALL( TARGETS ompd LIBRARY DESTINATION lib ARCHIVE DESTINATION lib/static RUNTIME DESTINATION bin ) -INSTALL(FILES ${CMAKE_BINARY_DIR}/include/ompd.h DESTINATION include) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/ompd.h DESTINATION include) diff --git a/libompd/src/ompd_intel.cpp b/libompd/src/omp-debug.cpp similarity index 97% rename from libompd/src/ompd_intel.cpp rename to libompd/src/omp-debug.cpp index 756bcbb64..b7832bdd1 100644 --- a/libompd/src/ompd_intel.cpp +++ b/libompd/src/omp-debug.cpp @@ -1,5 +1,5 @@ /* - * ompd_intel.cpp + * omp-debug.cpp * * Created on: Jan 14, 2015 * Author: Ignacio Laguna @@ -13,7 +13,7 @@ #define NDEBUG 1 -#include "ompd_intel.h" +#include "omp-debug.h" #include "ompd.h" // #include #include @@ -122,6 +122,7 @@ ompd_rc_t ompd_release_address_space_handle ( return ompd_rc_ok; } +#if 0 // no device support yet ompd_rc_t ompd_device_initialize ( ompd_address_space_context_t *context, /* IN: */ ompd_device_identifier_t id, /* IN: object defined by native device API */ @@ -178,6 +179,7 @@ ompd_rc_t ompd_device_initialize ( /* TODO(mjm) - Find appropriate error return result for not finding a match */ return ompd_rc_ok; } +#endif // no device support /* --- 4 Handle Management -------------------------------------------------- */ @@ -637,6 +639,7 @@ ompd_rc_t ompd_parallel_handle_compare ( return ompd_rc_ok; } +#if 0 // parallel-id is initialized to zero ompd_rc_t ompd_get_parallel_handle_string_id ( ompd_parallel_handle_t *parallel_handle, char **string_id @@ -653,6 +656,7 @@ ompd_rc_t ompd_get_parallel_handle_string_id ( sprintf(*string_id, "0x%llx", (long long)id); return ompd_rc_ok; } +#endif /* --- 4.3 Task Handles ----------------------------------------------------- */ @@ -935,6 +939,7 @@ ompd_rc_t ompd_task_handle_compare ( return ompd_rc_ok; } +#if 0 // all task ids are initialized to zero ompd_rc_t ompd_get_task_handle_string_id ( ompd_task_handle_t *task_handle, char **string_id @@ -950,6 +955,7 @@ ompd_rc_t ompd_get_task_handle_string_id ( sprintf(*string_id, "0x%llx", (long long)id); return ompd_rc_ok; } +#endif /* --- 5 Process and Thread Settings ---------------------------------------- */ @@ -1088,9 +1094,9 @@ ompd_rc_t ompd_get_active_level( /* --- 6.2 OMPT Parallel Region Inquiry Analogues ------------------------- */ -ompd_rc_t ompd_get_parallel_id( +ompd_rc_t ompd_get_parallel_data( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_parallel_id_t *id /* OUT: OpenMP parallel id */ + ompd_address_t *data /* OUT: OpenMP parallel id */ ) { if (!parallel_handle) @@ -1115,12 +1121,12 @@ ompd_rc_t ompd_get_parallel_id( ompd_rc_t ret = teamInfo. access("ompt_team_info"). /*t.ompt_team_info*/ cast("ompt_team_info_t",0). - access("parallel_id"). /*t.ompt_team_info.parallel_id*/ - castBase("ompt_parallel_id_t"). /*type: ompt_parallel_id_t*/ - getValue(*id); + access("parallel_data"). /*t.ompt_team_info.parallel_id*/ + getAddress(data); return ret; } +#if 0 // there is no such thing as a parallel function ompd_rc_t ompd_get_parallel_function( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ @@ -1154,6 +1160,7 @@ ompd_rc_t ompd_get_parallel_function( getValue(parallel_addr->address); return ret; } +#endif // no parallel function /* --- 7 Thread Inquiry ----------------------------------------------------- */ @@ -1637,7 +1644,7 @@ ompd_rc_t ompd_get_task_frame( cast("ompt_frame_t", 0); sp_reentry->segment = OMPD_SEGMENT_UNSPECIFIED; ompd_rc_t ret = frame. - access("reenter_runtime_frame"). // td->ompt_task_info.frame.reenter_runtime_frame + access("enter_frame"). // td->ompt_task_info.frame.enter_frame castBase(). getValue(sp_reentry->address); @@ -1646,16 +1653,16 @@ ompd_rc_t ompd_get_task_frame( sp_exit->segment = OMPD_SEGMENT_UNSPECIFIED; ret = frame. - access("exit_runtime_frame"). // td->ompt_task_info.frame.exit_runtime_frame + access("exit_frame"). // td->ompt_task_info.frame.exit_frame castBase(). getValue(sp_exit->address); return ret; } -ompd_rc_t ompd_get_task_id( +ompd_rc_t ompd_get_task_data( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_task_id_t *task_id /* OUT: OpenMP task ID */ + ompd_address_t *task_data /* OUT: OpenMP task ID */ ) { if (!task_handle) @@ -1680,13 +1687,13 @@ ompd_rc_t ompd_get_task_id( ompd_rc_t ret = taskInfo. access("ompt_task_info"). // td->ompt_task_info cast("ompt_task_info_t"). - access("task_id"). // td->ompt_task_info.task_id - castBase("ompt_task_id_t"). - getValue(*task_id); + access("task_data"). // td->ompt_task_info.task_data + getAddress(task_data); return ret; } +#if 0 // the runtime currently does not have task function information ompd_rc_t ompd_get_task_function( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_address_t *task_addr /* OUT: first instruction in the task region */ @@ -1731,7 +1738,7 @@ ompd_rc_t ompd_get_task_function( getValue(task_addr->address); return ret; } - +#endif /* --- 9 OMPD Version and Compatibility Information ------------------------- */ @@ -1747,9 +1754,10 @@ ompd_rc_t ompd_get_version_string( const char **string /* OUT: OMPD version string */ ) { - static char version_string[256]={0}; +/* static char version_string[256]={0}; if(version_string[0]=='\0') - sprintf(version_string, "Intel OpenMP %i.%i Debugging Library implemnting TR %i%c",OMPD_IMPLEMENTS_OPENMP, OMPD_IMPLEMENTS_OPENMP_SUBVERSION, OMPD_TR_VERSION, OMPD_TR_SUBVERSION); + sprintf(version_string, "LLVM OpenMP %i.%i Debugging Library implemnting TR %i%c",OMPD_IMPLEMENTS_OPENMP, OMPD_IMPLEMENTS_OPENMP_SUBVERSION, OMPD_TR_VERSION, OMPD_TR_SUBVERSION);*/ + static const char version_string[] = "LLVM OpenMP " STR(OMPD_IMPLEMENTS_OPENMP) "." STR(OMPD_IMPLEMENTS_OPENMP_SUBVERSION) " Debugging Library implemnting TR " STR(OMPD_TR_VERSION) "" STR(OMPD_TR_SUBVERSION) ; *string = version_string; return ompd_rc_ok; } diff --git a/libompd/src/ompd_intel.h b/libompd/src/omp-debug.h similarity index 97% rename from libompd/src/ompd_intel.h rename to libompd/src/omp-debug.h index 5d571d841..595c4aa4a 100644 --- a/libompd/src/ompd_intel.h +++ b/libompd/src/omp-debug.h @@ -28,6 +28,9 @@ extern "C" { #define OMPD_TR_VERSION 6 #define OMPD_TR_SUBVERSION 'j' #define OMPD_VERSION (OMPD_IMPLEMENTS_OPENMP << 24) + (OMPD_IMPLEMENTS_OPENMP_SUBVERSION << 16) + (OMPD_TR_VERSION << 8) + OMPD_TR_SUBVERSION + +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) #include "ompd.h" #include "ompd_typedefs.h" diff --git a/libompd/src/ompd-template.h b/libompd/src/ompd-template.h index 5bdee012d..693855196 100644 --- a/libompd/src/ompd-template.h +++ b/libompd/src/ompd-template.h @@ -49,8 +49,6 @@ typedef uint64_t ompd_taddr_t; /* unsigned integer large enough */ /* to hold a target address or a */ /* target segment value */ typedef int64_t ompd_tword_t; /* signed version of ompd_addr_t */ -typedef uint64_t ompd_parallel_id_t; /* parallel region instance ID */ -typedef uint64_t ompd_task_id_t; /* task region instance ID */ typedef uint64_t ompd_wait_id_t; /* identifies what a thread is */ /* waiting for */ typedef uint64_t ompd_size_t; /* For sizes (e.g., size_t) */ @@ -628,6 +626,7 @@ typedef ompd_rc_t (*ompd_parallel_handle_compare_apifn_t) ( int *cmp_value ); +#if 0 ompd_rc_t ompd_get_parallel_handle_string_id ( ompd_parallel_handle_t *parallel_handle, char **string_id @@ -636,6 +635,7 @@ typedef ompd_rc_t (*ompd_get_parallel_handle_string_id_apifn_t) ( ompd_parallel_handle_t *parallel_handle, char **string_id ); +#endif /* --- 4.3 Task Handles ----------------------------------------------------- */ @@ -727,6 +727,7 @@ typedef ompd_rc_t (*ompd_task_handle_compare_apifn_t) ( int *cmp_value ); +#if 0 ompd_rc_t ompd_get_task_handle_string_id ( ompd_task_handle_t *task_handle, char **string_id @@ -735,7 +736,7 @@ typedef ompd_rc_t (*ompd_get_task_handle_string_id_apifn_t) ( ompd_task_handle_t *task_handle, char **string_id ); - +#endif /* --- 5o Process and Thread Settings ---------------------------------------- */ @@ -813,15 +814,16 @@ typedef ompd_rc_t (*ompd_get_active_level_apifn_t) ( * the OMPD and OMPT versions is that the OMPD must supply a parallel region * handle to provide a context for these inquiries. */ -ompd_rc_t ompd_get_parallel_id( +ompd_rc_t ompd_get_parallel_data( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_parallel_id_t *id /* OUT: OpenMP parallel id */ + ompd_address_t *data /* OUT: OpenMP parallel id */ ); -typedef ompd_rc_t (*ompd_get_parallel_id_apifn_t) ( +typedef ompd_rc_t (*ompd_get_parallel_data_apifn_t) ( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_parallel_id_t *id /* OUT: OpenMP parallel id */ + ompd_address_t *data /* OUT: OpenMP parallel id */ ); +#if 0 ompd_rc_t ompd_get_parallel_function( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ @@ -830,6 +832,7 @@ typedef ompd_rc_t (*ompd_get_parallel_function_apifn_t) ( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ ); +#endif /* --- 7 Thread Inquiry ----------------------------------------------------- */ /* --- 7.1 Operating System Thread Inquiry ---------------------------------- */ @@ -920,7 +923,7 @@ typedef ompd_rc_t (*ompd_get_state_apifn_t) ( * corresponds to the body of code executed by the task. */ - +#if 0 ompd_rc_t ompd_get_task_function( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ ompd_address_t *entry_point /* OUT: first instruction in the task region */ @@ -929,7 +932,7 @@ typedef ompd_rc_t (*ompd_get_task_function_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ ompd_address_t *entry_point /* OUT: first instruction in the task region */ ); - +#endif /* --- 8.2 Task Settings ---------------------------------------------------- */ @@ -1035,7 +1038,7 @@ typedef ompd_rc_t (*ompd_is_implicit_apifn_t) ( /** * The functions defined here are third-party versions of ompt_get_task_frame - * and ompt_get_task_id. The only difference between the OMPD and OMPT + * and ompt_get_task_data. The only difference between the OMPD and OMPT * counterparts is that the OMPD version must supply a task handle to provide a * context for these inquiries. */ @@ -1068,13 +1071,13 @@ typedef ompd_rc_t (*ompd_get_task_frame_apifn_t) ( ompd_address_t *sp_reentry /* OUT: previous frame is user code */ ); -ompd_rc_t ompd_get_task_id( +ompd_rc_t ompd_get_task_data( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_id_t *task_id /* OUT: OpenMP task ID */ + ompd_address_t *task_data /* OUT: OpenMP task ID */ ); -typedef ompd_rc_t (*ompd_get_task_id_apifn_t) ( +typedef ompd_rc_t (*ompd_get_task_data_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_id_t *task_id /* OUT: OpenMP task ID */ + ompd_address_t *task_data /* OUT: OpenMP task ID */ ); From 918c9893269a6f62f42fa33f6a20495a74b0e193 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Sat, 3 Feb 2018 14:09:19 -0600 Subject: [PATCH 32/46] Update most of the interface to current spec --- libompd/src/CMakeLists.txt | 2 + libompd/src/TargetValue.cpp | 10 +- libompd/src/TargetValue.h | 16 +- libompd/src/omp-debug.cpp | 394 +++++++----------------------------- libompd/src/ompd-template.h | 319 ++++++++++++++++------------- 5 files changed, 261 insertions(+), 480 deletions(-) diff --git a/libompd/src/CMakeLists.txt b/libompd/src/CMakeLists.txt index 676efb953..9b4c03ec3 100644 --- a/libompd/src/CMakeLists.txt +++ b/libompd/src/CMakeLists.txt @@ -2,6 +2,8 @@ project (libompd) add_library (ompd SHARED TargetValue.cpp omp-debug.cpp) +add_dependencies(ompd ompd-header) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") include_directories ( diff --git a/libompd/src/TargetValue.cpp b/libompd/src/TargetValue.cpp index e5b77ca2a..48528f2ec 100644 --- a/libompd/src/TargetValue.cpp +++ b/libompd/src/TargetValue.cpp @@ -16,7 +16,7 @@ inline int ompd_sizeof(ompd_target_prim_types_t t) TType& TTypeFactory::getType( ompd_address_space_context_t *context, const char * typeName, - ompd_taddr_t segment + ompd_addr_t segment ) { TType empty(true); @@ -39,7 +39,7 @@ TType& TTypeFactory::getType( TType::TType(ompd_address_space_context_t *_context, const char* _typeName, - ompd_taddr_t _segment) : typeSize(0), fieldOffsets(), descSegment(_segment), + ompd_addr_t _segment) : typeSize(0), fieldOffsets(), descSegment(_segment), typeName(_typeName), context(_context), isvoid(false) { } @@ -202,7 +202,7 @@ ompd_rc_t TType::getElementSize(const char* fieldName, ompd_size_t * size) //}; -TValue::TValue(ompd_address_space_context_t *_context, ompd_thread_context_t *_tcontext, const char* _valueName, ompd_taddr_t segment) +TValue::TValue(ompd_address_space_context_t *_context, ompd_thread_context_t *_tcontext, const char* _valueName, ompd_addr_t segment) : errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), /*valueName(_valueName),*/ context(_context), tcontext(_tcontext), fieldSize(0) { errorState.errorCode = callbacks->tsymbol_addr(context, tcontext, _valueName, &symbolAddr); @@ -232,7 +232,7 @@ TValue& TValue::cast(const char* typeName) return *this; } -TValue& TValue::cast(const char* typeName, int _pointerLevel, ompd_taddr_t segment) +TValue& TValue::cast(const char* typeName, int _pointerLevel, ompd_addr_t segment) { if (gotError()) return *this; @@ -330,7 +330,7 @@ TValue TValue::access(const char* fieldName) const return ret; } -ompd_rc_t TValue::check(const char* bitfieldName, ompd_tword_t* isSet) const +ompd_rc_t TValue::check(const char* bitfieldName, ompd_word_t* isSet) const { if (gotError()) return getError(); diff --git a/libompd/src/TargetValue.h b/libompd/src/TargetValue.h index 2fe8fed9d..60cd0888a 100644 --- a/libompd/src/TargetValue.h +++ b/libompd/src/TargetValue.h @@ -24,7 +24,7 @@ class TTypeFactory TTypeFactory(): ttypes() {} TType& getType(ompd_address_space_context_t *context, const char * typName, - ompd_taddr_t segment=OMPD_SEGMENT_UNSPECIFIED); + ompd_addr_t segment=OMPD_SEGMENT_UNSPECIFIED); }; static thread_local TTypeFactory tf = TTypeFactory(); @@ -36,15 +36,15 @@ class TType std::map fieldOffsets; std::map fieldSizes; std::map bitfieldMasks; - ompd_taddr_t descSegment; + ompd_addr_t descSegment; const char* typeName; ompd_address_space_context_t *context; bool isvoid; TType(ompd_address_space_context_t *context, const char* typeName, - ompd_taddr_t _segment=OMPD_SEGMENT_UNSPECIFIED); + ompd_addr_t _segment=OMPD_SEGMENT_UNSPECIFIED); public: - TType(bool, ompd_taddr_t _segment=OMPD_SEGMENT_UNSPECIFIED): descSegment(_segment), isvoid(true) {} + TType(bool, ompd_addr_t _segment=OMPD_SEGMENT_UNSPECIFIED): descSegment(_segment), isvoid(true) {} bool isVoid() const{return isvoid;} ompd_rc_t getElementOffset (const char* fieldName, ompd_size_t * offset); ompd_rc_t getElementSize (const char* fieldName, ompd_size_t * size); @@ -107,13 +107,13 @@ class TValue */ TValue(ompd_address_space_context_t *_context, const char* _valueName, - ompd_taddr_t segment=OMPD_SEGMENT_UNSPECIFIED): + ompd_addr_t segment=OMPD_SEGMENT_UNSPECIFIED): TValue(_context, NULL, _valueName, segment) {} TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext, const char* valueName, - ompd_taddr_t segment=OMPD_SEGMENT_UNSPECIFIED); + ompd_addr_t segment=OMPD_SEGMENT_UNSPECIFIED); /** * Create a target value object from target value address */ @@ -135,7 +135,7 @@ class TValue * * This call modifies the object and returns a reference to the modified object */ - TValue& cast(const char* typeName, int pointerLevel, ompd_taddr_t segment=OMPD_SEGMENT_UNSPECIFIED); + TValue& cast(const char* typeName, int pointerLevel, ompd_addr_t segment=OMPD_SEGMENT_UNSPECIFIED); /** * Get the target address of the target value @@ -174,7 +174,7 @@ class TValue /** * Tests for a field bit in a bitfield */ - ompd_rc_t check(const char* bitfieldName, ompd_tword_t* isSet) const; + ompd_rc_t check(const char* bitfieldName, ompd_word_t* isSet) const; /** * Get an array element */ diff --git a/libompd/src/omp-debug.cpp b/libompd/src/omp-debug.cpp index b7832bdd1..3d38c8917 100644 --- a/libompd/src/omp-debug.cpp +++ b/libompd/src/omp-debug.cpp @@ -62,7 +62,7 @@ void operator delete[](void* addr) throw () /* --- 3 Initialization ----------------------------------------------------- */ -ompd_rc_t ompd_initialize (const ompd_callbacks_t *table) +ompd_rc_t ompd_initialize (const ompd_callbacks_t *table, ompd_word_t version) { ompd_rc_t ret = table ? ompd_rc_ok : ompd_rc_bad_input; callbacks = table; @@ -187,106 +187,10 @@ ompd_rc_t ompd_device_initialize ( /* thread_handle is of type (kmp_base_info_t) */ -ompd_rc_t ompd_get_threads ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ - int *num_handles /* OUT: number of handles in the array */ - ) -{ - int i; - if (!addr_handle) - return ompd_rc_stale_handle; - ompd_address_space_context_t *context = addr_handle->context; - ompd_rc_t ret; - - if (!context) - return ompd_rc_stale_handle; - - /* num_handles must be supplied, although thread_handle_array need not */ - if (!num_handles) - return ompd_rc_bad_input; - - assert(callbacks && "Callback table not initialized!"); - - int nth; - ret = TValue(context, "__kmp_nth"). - castBase("__kmp_nth"). - getValue(nth); - - if ( ret != ompd_rc_ok ) - return ret; - - *num_handles = nth; - - /* if thread_handle_array is NULL, then we return only the number of */ - /* thread handles */ - if ( ! thread_handle_array ) - return ret; - - TValue kmp_threads = TValue(context, "__kmp_threads"). /* __kmp_threads */ - cast("kmp_info_t",2); - if (kmp_threads.gotError()) - return kmp_threads.getError(); - - ret = callbacks->dmemory_alloc(nth * sizeof(ompd_thread_handle_t*), (void**)(thread_handle_array)); - if ( ret != ompd_rc_ok ) - return ret; - - /* From here on control *MUST* flow to the end of the function to make */ - /* sure any memory is released should an error occur. */ - - /* zero out the array: make clean up on error easier */ - for ( i = 0; i < *num_handles; i++ ) - (*thread_handle_array) [ i ] = 0; - - for (i =0; (ompd_rc_ok == ret) && (i<*num_handles); i++) - { - ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), (void**)(*thread_handle_array+i)); - if ( ompd_rc_ok == ret ) - { - (*thread_handle_array)[i]->ah = addr_handle; - ret = kmp_threads. - getArrayElement(i). /* __kmp_threads[i] */ - access("th"). /* __kmp_threads[i]->th */ - getAddress(&((*thread_handle_array)[i]->th)); - } - else - { - (*thread_handle_array) [ i ] = 0; - } - } - if ( ompd_rc_ok != ret ) - { - ompd_rc_t free_err; - - /* some error: we need to release the memory we've acquired */ - for ( i = 0; ((*thread_handle_array)[i]) && (i < *num_handles); i++ ) - { - free_err = callbacks->dmemory_free ( (void *) (*thread_handle_array)[i] ); - if ( ompd_rc_ok != free_err ) - { - /* we don't want to return free_err from the function as */ - /* this would mask the error we've detected. But we do */ - /* want some way to report that we're having trouble */ - /* releasing memory. */ - callbacks->print_string ( "OMPD (ompd_get_threads): error releasing thread handle after error\n" ); - } - } - /* now release the vector */ - free_err = callbacks->dmemory_free ( (void *) (*thread_handle_array) ); - if ( ompd_rc_ok != free_err ) - { - callbacks->print_string ( "OMPD (ompd_get_threads): error releasing thread handle vector after error\n" ); - } - (*thread_handle_array) = 0; - } - return ret; -} - ompd_rc_t ompd_get_thread_in_parallel( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ - int *num_handles /* OUT: number of handles in the array */ + int nth_handle, /* OUT: number of handles in the array */ + ompd_thread_handle_t **thread_handle /* OUT: handle */ ) { if (!parallel_handle) @@ -302,119 +206,24 @@ ompd_rc_t ompd_get_thread_in_parallel( assert(callbacks && "Callback table not initialized!"); - TValue th = TValue(context, parallel_handle->th). /* t */ - cast("kmp_base_team_t",0); - if ( th.gotError() ) - return th.getError(); - - ret = th.access("t_nproc"). /*t.t_nproc*/ - castBase(). - getValue(*num_handles); - - if ( ret != ompd_rc_ok ) - return ret; - - ret = callbacks->dmemory_alloc((*num_handles) * sizeof(ompd_thread_handle_t*), (void**)thread_handle_array); - - if ( ret != ompd_rc_ok ) - return ret; - - /* From here on control *MUST* flow to the end of the function to make */ - /* sure any memory is released should an error occur. */ - - /* zero out the array: make clean up on error easier */ - for ( i = 0; i < *num_handles; i++ ) - (*thread_handle_array) [ i ] = 0; - - for ( i = 0; (i < *num_handles) && ( ret == ompd_rc_ok ); i++) - { - ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), (void**)(*thread_handle_array+i)); - if ( ret == ompd_rc_ok ) - { - (*thread_handle_array)[i]->ah=parallel_handle->ah; - ret = th.access("t_threads"). /*t.t_threads*/ - cast("kmp_info_t",2). - getArrayElement(i). /*t.t_threads[i]*/ - access("th"). /*t.t_threads[i]->th*/ - getAddress(&((*thread_handle_array)[i]->th)); - } - else - { - (*thread_handle_array)[i]=0; - } - } - if ( ompd_rc_ok != ret ) - { - ompd_rc_t free_err; - - /* some error: we need to release the memory we've acquired */ - for ( i = 0; ((*thread_handle_array)[i]) && (i < *num_handles); i++ ) - { - free_err = callbacks->dmemory_free ( (void *) (*thread_handle_array)[i] ); - if ( ompd_rc_ok != free_err ) - { - /* we don't want to return free_err from the function as */ - /* this would mask the error we've detected. But we do */ - /* want some way to report that we're having trouble */ - /* releasing memory. */ - callbacks->print_string ( "OMPD (ompd_get_thread_in_parallel): error releasing thread handle after error\n" ); - } - } - /* now release the vector */ - free_err = callbacks->dmemory_free ( (void *) (*thread_handle_array) ); - if ( ompd_rc_ok != free_err ) - { - callbacks->print_string ( "OMPD (ompd_get_thread_in_parallel): error releasing thread handle vector after error\n" ); - } - (*thread_handle_array) = 0; - } - return ret; -} - -ompd_rc_t ompd_get_master_thread_in_parallel ( - ompd_parallel_handle_t *parallel_handle, /* IN */ - ompd_thread_handle_t **thread_handle) -{ - if (!parallel_handle) - return ompd_rc_stale_handle; - if (!parallel_handle->ah) - return ompd_rc_stale_handle; - ompd_address_space_context_t *context = parallel_handle->ah->context; - ompd_rc_t ret; - - if (!context) - return ompd_rc_stale_handle; - - assert(callbacks && "Callback table not initialized!"); - - int tId; - ret = TValue(context, parallel_handle->th). /*t*/ - cast("kmp_base_team_t",0). - access("t_master_tid"). /*t.t_master_tid*/ - castBase(). - getValue(tId); - - if ( ret != ompd_rc_ok ) - return ret; - - if (tId < 0) /*thread is no omp worker*/ - return ompd_rc_unavailable; ompd_address_t taddr; - ret = TValue(context, "__kmp_threads"). /*__kmp_threads*/ - cast("kmp_info_t",2). - getArrayElement(tId). /* __kmp_threads[t]*/ - access("th"). /* __kmp_threads[t]->th*/ + ret = TValue(context, parallel_handle->th). /* t */ + cast("kmp_base_team_t",0). + access("t_threads"). /*t.t_threads*/ + cast("kmp_info_t",2). + getArrayElement(nth_handle). /*t.t_threads[nth_handle]*/ + access("th"). /*t.t_threads[i]->th*/ getAddress(&taddr); + if ( ret != ompd_rc_ok ) return ret; - ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), (void**)(thread_handle)); if ( ret != ompd_rc_ok ) return ret; - (*thread_handle)->ah = parallel_handle->ah; + (*thread_handle)->th = taddr; - + (*thread_handle)->ah = parallel_handle->ah; return ret; } @@ -443,29 +252,30 @@ ompd_rc_t ompd_thread_handle_compare ( return ompd_rc_ok; } +#if 0 ompd_rc_t ompd_get_thread_handle_string_id ( ompd_thread_handle_t *thread_handle, char **string_id ) { - pthread_t osthread; + pthread_t thread_id; ompd_rc_t ret; - ret = ompd_get_osthread(thread_handle, ompd_osthread_pthread, sizeof(pthread_t), &osthread); + ret = ompd_get_thread_id(thread_handle, ompd_thread_id_pthread, sizeof(pthread_t), &thread_id); if (ret!=ompd_rc_ok) return ret; ret = callbacks->dmemory_alloc(sizeof(void*)*2+3, (void**)string_id); if (ret!=ompd_rc_ok) return ret; - sprintf(*string_id, "0x%llx", (long long)osthread); + sprintf(*string_id, "0x%llx", (long long)thread_id); return ompd_rc_ok; } - +#endif /* --- 4.2 Parallel Region Handles------------------------------------------- */ /* parallel_handle is of type (kmp_base_team_t)*/ -ompd_rc_t ompd_get_top_parallel_region( +ompd_rc_t ompd_get_current_parallel_handle( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ ) @@ -572,7 +382,7 @@ ompd_rc_t ompd_get_enclosing_parallel_handle( return ompd_rc_ok; } -ompd_rc_t ompd_get_task_enclosing_parallel_handle( +ompd_rc_t ompd_get_task_parallel_handle( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ ) @@ -663,7 +473,7 @@ ompd_rc_t ompd_get_parallel_handle_string_id ( /* task_handle is of type (kmp_taskdata_t) */ -ompd_rc_t ompd_get_top_task_region( +ompd_rc_t ompd_get_current_task__handle( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ ) @@ -712,15 +522,7 @@ ompd_rc_t ompd_get_top_task_region( return ompd_rc_ok; } -ompd_rc_t ompd_get_ancestor_task_region( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ - ) -{ - return ompd_get_generating_ancestor_task_region(task_handle,parent_task_handle); -} - -ompd_rc_t ompd_get_generating_ancestor_task_region( +ompd_rc_t ompd_get_generating_ancestor_task_handle( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ ) @@ -784,7 +586,7 @@ ompd_rc_t ompd_get_generating_ancestor_task_region( return ret; } -ompd_rc_t ompd_get_scheduling_ancestor_task_region( +ompd_rc_t ompd_get_scheduling_ancestor_task_handle( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ ) @@ -820,10 +622,10 @@ ompd_rc_t ompd_get_scheduling_ancestor_task_region( return ret; } -ompd_rc_t ompd_get_implicit_task_in_parallel( +ompd_rc_t ompd_get_task_in_parallel( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_task_handle_t ***task_handle_array, /* OUT: array of OpenMP task handles */ - int *num_handles /* OUT: number of task handles */ + int nth_handle, /* OUT: number of the task handle */ + ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ ) { int i; @@ -837,77 +639,23 @@ ompd_rc_t ompd_get_implicit_task_in_parallel( assert(callbacks && "Callback table not initialized!"); - TValue th = TValue(context, parallel_handle->th). /*t*/ - cast("kmp_base_team_t",0); - if ( th.gotError() ) - return th.getError(); - ompd_rc_t ret; - if (parallel_handle->lwt.address!=0) - *num_handles=1; - else - { - ret = th.access("t_nproc"). /*t.t_nproc*/ - castBase(). - getValue(*num_handles); - if ( ret != ompd_rc_ok ) - return ret; - } - - ret = callbacks->dmemory_alloc((*num_handles) * sizeof(ompd_task_handle_t*), (void**)task_handle_array); + ompd_address_t taddr; + ret = TValue(context, parallel_handle->th). /* t */ + cast("kmp_base_team_t",0). + access("t_implicit_task_taskdata"). /*t.t_implicit_task_taskdata*/ + cast("kmp_taskdata_t", 1). + getArrayElement(nth_handle). /*t.t_implicit_task_taskdata[nth_handle]*/ + getAddress(&taddr); + if ( ret != ompd_rc_ok ) + return ret; + ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(task_handle)); if ( ret != ompd_rc_ok ) return ret; - /* From here on control *MUST* flow to the end of the function to make */ - /* sure any memory is released should an error occur. */ - - /* zero out the array: make clean up on error easier */ - for ( i = 0; i < *num_handles; i++ ) - (*task_handle_array) [ i ] = 0; - - for ( i = 0; (i < *num_handles) && ( ret == ompd_rc_ok ); i++) - { - ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(*task_handle_array+i)); - if ( ret == ompd_rc_ok ) - { - (*task_handle_array)[i]->lwt = parallel_handle->lwt; - (*task_handle_array)[i]->ah = parallel_handle->ah; - ret = th.access("t_implicit_task_taskdata"). /*t.t_implicit_task_taskdata*/ - cast("kmp_taskdata_t",1). - getArrayElement(i). /*t.t_implicit_task_taskdata[i]*/ - getAddress(&((*task_handle_array)[i]->th)); - } - else - { - (*task_handle_array)[i]=0; - } - } - if ( ompd_rc_ok != ret ) - { - ompd_rc_t free_err; - - /* some error: we need to release the memory we've acquired */ - for ( i = 0; ((*task_handle_array)[i]) && (i < *num_handles); i++ ) - { - free_err = callbacks->dmemory_free ( (void *) (*task_handle_array)[i] ); - if ( ompd_rc_ok != free_err ) - { - /* we don't want to return free_err from the function as */ - /* this would mask the error we've detected. But we do */ - /* want some way to report that we're having trouble */ - /* releasing memory. */ - callbacks->print_string ( "OMPD (ompd_get_implicit_task_in_parallel): error releasing task handle after error\n" ); - } - } - /* now release the vector */ - free_err = callbacks->dmemory_free ( (void *) (*task_handle_array) ); - if ( ompd_rc_ok != free_err ) - { - callbacks->print_string ( "OMPD (ompd_get_implicit_task_in_parallel): error releasing task handle vector after error\n" ); - } - (*task_handle_array) = 0; - } + (*task_handle)->th = taddr; + (*task_handle)->ah = parallel_handle->ah; return ret; } @@ -962,7 +710,7 @@ ompd_rc_t ompd_get_task_handle_string_id ( ompd_rc_t ompd_get_num_procs( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_tword_t *val /* OUT: number of processes */ + ompd_word_t *val /* OUT: number of processes */ ) { if (!addr_handle) @@ -985,7 +733,7 @@ ompd_rc_t ompd_get_num_procs( ompd_rc_t ompd_get_thread_limit( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ) { if (!addr_handle) @@ -1011,7 +759,7 @@ ompd_rc_t ompd_get_thread_limit( ompd_rc_t ompd_get_num_threads( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_tword_t *val /* OUT: number of threads */ + ompd_word_t *val /* OUT: number of threads */ ) { if (!parallel_handle) @@ -1042,7 +790,7 @@ ompd_rc_t ompd_get_num_threads( ompd_rc_t ompd_get_level( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_tword_t *val /* OUT: nesting level */ + ompd_word_t *val /* OUT: nesting level */ ) { if (!parallel_handle) @@ -1068,7 +816,7 @@ ompd_rc_t ompd_get_level( ompd_rc_t ompd_get_active_level( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_tword_t *val /* OUT: active nesting level */ + ompd_word_t *val /* OUT: active nesting level */ ) { if (!parallel_handle) @@ -1168,9 +916,9 @@ ompd_rc_t ompd_get_parallel_function( ompd_rc_t ompd_get_thread_handle ( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_osthread_kind_t kind, - ompd_size_t sizeof_osthread, - const void* osthread, + ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, + const void* thread_id, ompd_thread_handle_t **thread_handle) { if (!addr_handle) @@ -1183,15 +931,15 @@ ompd_rc_t ompd_get_thread_handle ( assert(callbacks && "Callback table not initialized!"); ompd_thread_context_t *tcontext; - ret = callbacks->get_thread_context_for_osthread(context, kind, sizeof_osthread, osthread, &tcontext); + ret = callbacks->get_thread_context_for_thread_id(context, kind, sizeof_thread_id, thread_id, &tcontext); if ( ret != ompd_rc_ok ) return ret; int tId; - if (kind == ompd_osthread_cudalogical) + if (kind == ompd_thread_id_cudalogical) { - ompd_cudathread_coord_t* p = (ompd_cudathread_coord_t*)osthread; + ompd_cudathread_coord_t* p = (ompd_cudathread_coord_t*)thread_id; // omptarget_nvptx_threadPrivateContext->topTaskDescr[p->threadIdx.x]->data.items.threadId @@ -1249,20 +997,20 @@ ompd_rc_t ompd_get_thread_handle ( access("ds_thread"). /*__kmp_threads[t]->th.th_info.ds.ds_thread*/ castBase(); - assert( ompd_rc_ok == ds_handle.getValue(oshandle) && oshandle == *(pthread_t*)(osthread) && "Callback table not initialized!"); + assert( ompd_rc_ok == ds_handle.getValue(oshandle) && oshandle == *(pthread_t*)(thread_id) && "Callback table not initialized!"); #endif } return ret; } -ompd_rc_t ompd_get_osthread ( +ompd_rc_t ompd_get_thread_id ( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_osthread_kind_t kind, - ompd_size_t sizeof_osthread, - void *osthread + ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, + void *thread_id ) { - if (kind!=ompd_osthread_pthread) + if (kind!=ompd_thread_id_pthread) return ompd_rc_bad_input; if (!thread_handle) return ompd_rc_stale_handle; @@ -1275,7 +1023,7 @@ ompd_rc_t ompd_get_osthread ( ompd_rc_t ret = tf.getType(context, "kmp_thread_t").getSize(&size); if ( ret != ompd_rc_ok ) return ret; - if (sizeof_osthread!=size) + if (sizeof_thread_id!=size) return ompd_rc_bad_input; assert(callbacks && "Callback table not initialized!"); @@ -1288,13 +1036,13 @@ ompd_rc_t ompd_get_osthread ( cast("kmp_desc_base_t"). access("ds_thread"). /*__kmp_threads[t]->th.th_info.ds.ds_thread*/ cast("kmp_thread_t"). - getRawValue(osthread,1); + getRawValue(thread_id,1); return ret; } ompd_rc_t ompd_get_thread_num( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_tword_t *val /* OUT: number of the thread within the team */ + ompd_word_t *val /* OUT: number of the thread within the team */ ) { // __kmp_threads[8]->th.th_info.ds.ds_tid @@ -1325,7 +1073,7 @@ ompd_rc_t ompd_get_thread_num( ompd_rc_t ompd_get_state ( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_state_t *state, /* OUT: State of this thread */ + ompd_word_t *state, /* OUT: State of this thread */ ompd_wait_id_t *wait_id /* OUT: Wait ID */ ) { @@ -1367,7 +1115,7 @@ ompd_rc_t ompd_get_state ( ompd_rc_t ompd_get_max_threads( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ) { if (!task_handle) @@ -1393,7 +1141,7 @@ ompd_rc_t ompd_get_max_threads( ompd_rc_t ompd_in_parallel( // Why do we need a task context for _in_parallel? ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ) { if (!task_handle) @@ -1425,7 +1173,7 @@ ompd_rc_t ompd_in_parallel( // Why do we need a task context for _in_parallel? ompd_rc_t ompd_in_final( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ) { if (!task_handle) @@ -1449,7 +1197,7 @@ ompd_rc_t ompd_in_final( ompd_rc_t ompd_get_dynamic( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ) { if (!task_handle) @@ -1475,7 +1223,7 @@ ompd_rc_t ompd_get_dynamic( ompd_rc_t ompd_get_nested( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ) { if (!task_handle) @@ -1501,7 +1249,7 @@ ompd_rc_t ompd_get_nested( ompd_rc_t ompd_get_max_active_levels( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ) { if (!task_handle) @@ -1527,8 +1275,8 @@ ompd_rc_t ompd_get_max_active_levels( ompd_rc_t ompd_get_schedule( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_sched_t *kind, /* OUT: Kind of OpenMP schedule*/ - ompd_tword_t *modifier /* OUT: Schedunling modifier */ + ompd_word_t *kind, /* OUT: Kind of OpenMP schedule*/ + ompd_word_t *modifier /* OUT: Schedunling modifier */ ) { if (!task_handle) @@ -1562,7 +1310,7 @@ ompd_rc_t ompd_get_schedule( ompd_rc_t ompd_get_proc_bind( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_proc_bind_t *bind /* OUT: Kind of proc-binding */ + ompd_word_t *bind /* OUT: Kind of proc-binding */ ) { if (!task_handle) @@ -1588,7 +1336,7 @@ ompd_rc_t ompd_get_proc_bind( ompd_rc_t ompd_is_implicit( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ) { if (!task_handle) @@ -1713,7 +1461,7 @@ ompd_rc_t ompd_get_task_function( #if 0 /* We don't have a task function for implicit tasks */ - ompd_tword_t implicit; + ompd_word_t implicit; ompd_rc_t ret = ompd_is_implicit (task_handle, &implicit); if (ret != ompd_rc_ok) return ret; @@ -1742,7 +1490,7 @@ ompd_rc_t ompd_get_task_function( /* --- 9 OMPD Version and Compatibility Information ------------------------- */ -ompd_rc_t ompd_get_version ( +ompd_rc_t ompd_get_api_version ( int *version ) { @@ -1750,7 +1498,7 @@ ompd_rc_t ompd_get_version ( return ompd_rc_ok; } -ompd_rc_t ompd_get_version_string( +ompd_rc_t ompd_get_api_version_string( const char **string /* OUT: OMPD version string */ ) { diff --git a/libompd/src/ompd-template.h b/libompd/src/ompd-template.h index 693855196..79d949bea 100644 --- a/libompd/src/ompd-template.h +++ b/libompd/src/ompd-template.h @@ -45,45 +45,47 @@ extern "C" { /** * Basic types. */ -typedef uint64_t ompd_taddr_t; /* unsigned integer large enough */ +typedef uint64_t ompd_addr_t; /* unsigned integer large enough */ /* to hold a target address or a */ /* target segment value */ -typedef int64_t ompd_tword_t; /* signed version of ompd_addr_t */ +typedef int64_t ompd_word_t; /* signed version of ompd_addr_t */ +typedef uint64_t ompd_seg_t; typedef uint64_t ompd_wait_id_t; /* identifies what a thread is */ /* waiting for */ typedef uint64_t ompd_size_t; /* For sizes (e.g., size_t) */ typedef struct ompd_address_t { - ompd_taddr_t segment; /* target architecture specific */ + ompd_seg_t segment; /* target architecture specific */ /* segment value */ - ompd_taddr_t address; /* target address in the segment */ + ompd_addr_t address; /* target address in the segment */ } ompd_address_t; -#define OMPD_SEGMENT_UNSPECIFIED ((ompd_taddr_t) 0) -#define OMPD_SEGMENT_TEXT ((ompd_taddr_t) 1) -#define OMPD_SEGMENT_DATA ((ompd_taddr_t) 2) +#define OMPD_SEGMENT_UNSPECIFIED ((ompd_seg_t) 0) +#define OMPD_SEGMENT_TEXT ((ompd_seg_t) 1) +#define OMPD_SEGMENT_DATA ((ompd_seg_t) 2) /** * The following definitions match with ptx information stored in DWARF */ -#define OMPD_SEGMENT_CUDA_PTX_UNSPECIFIED ((ompd_taddr_t)0) -#define OMPD_SEGMENT_CUDA_PTX_CODE ((ompd_taddr_t)1) -#define OMPD_SEGMENT_CUDA_PTX_REG ((ompd_taddr_t)2) -#define OMPD_SEGMENT_CUDA_PTX_SREG ((ompd_taddr_t)3) -#define OMPD_SEGMENT_CUDA_PTX_CONST ((ompd_taddr_t)4) -#define OMPD_SEGMENT_CUDA_PTX_GLOBAL ((ompd_taddr_t)5) -#define OMPD_SEGMENT_CUDA_PTX_LOCAL ((ompd_taddr_t)6) -#define OMPD_SEGMENT_CUDA_PTX_PARAM ((ompd_taddr_t)7) -#define OMPD_SEGMENT_CUDA_PTX_SHARED ((ompd_taddr_t)8) -#define OMPD_SEGMENT_CUDA_PTX_SURF ((ompd_taddr_t)9) -#define OMPD_SEGMENT_CUDA_PTX_TEX ((ompd_taddr_t)10) -#define OMPD_SEGMENT_CUDA_PTX_TEXSAMPLER ((ompd_taddr_t)11) -#define OMPD_SEGMENT_CUDA_PTX_GENERIC ((ompd_taddr_t)12) -#define OMPD_SEGMENT_CUDA_PTX_IPARAM ((ompd_taddr_t)13) -#define OMPD_SEGMENT_CUDA_PTX_OPARAM ((ompd_taddr_t)14) -#define OMPD_SEGMENT_CUDA_PTX_FRAME ((ompd_taddr_t)15) -#define OMPD_SEGMENT_CUDA_PTX_MAX ((ompd_taddr_t)16) - +#define OMPD_SEGMENT_CUDA_PTX_UNSPECIFIED ((ompd_seg_t)0) +#define OMPD_SEGMENT_CUDA_PTX_CODE ((ompd_seg_t)1) +#define OMPD_SEGMENT_CUDA_PTX_REG ((ompd_seg_t)2) +#define OMPD_SEGMENT_CUDA_PTX_SREG ((ompd_seg_t)3) +#define OMPD_SEGMENT_CUDA_PTX_CONST ((ompd_seg_t)4) +#define OMPD_SEGMENT_CUDA_PTX_GLOBAL ((ompd_seg_t)5) +#define OMPD_SEGMENT_CUDA_PTX_LOCAL ((ompd_seg_t)6) +#define OMPD_SEGMENT_CUDA_PTX_PARAM ((ompd_seg_t)7) +#define OMPD_SEGMENT_CUDA_PTX_SHARED ((ompd_seg_t)8) +#define OMPD_SEGMENT_CUDA_PTX_SURF ((ompd_seg_t)9) +#define OMPD_SEGMENT_CUDA_PTX_TEX ((ompd_seg_t)10) +#define OMPD_SEGMENT_CUDA_PTX_TEXSAMPLER ((ompd_seg_t)11) +#define OMPD_SEGMENT_CUDA_PTX_GENERIC ((ompd_seg_t)12) +#define OMPD_SEGMENT_CUDA_PTX_IPARAM ((ompd_seg_t)13) +#define OMPD_SEGMENT_CUDA_PTX_OPARAM ((ompd_seg_t)14) +#define OMPD_SEGMENT_CUDA_PTX_FRAME ((ompd_seg_t)15) +#define OMPD_SEGMENT_CUDA_PTX_MAX ((ompd_seg_t)16) + +#if 0 // types removed in Austin F2F /* * Definition of OMPD states, taken from OMPT */ @@ -145,6 +147,7 @@ typedef enum ompd_proc_bind_t { ompd_proc_bind_close = 3, ompd_proc_bind_spread = 4 } ompd_proc_bind_t; +#endif typedef uint64_t ompd_device_identifier_t; @@ -183,34 +186,34 @@ typedef struct _ompd_address_space_handle_s ompd_address_space_handle_t; /** * Other handles. */ -#define OMPD_OSTHREAD_PTHREAD 0 -#define OMPD_OSTHREAD_LWP 1 -#define OMPD_OSTHREAD_WINTHREAD 2 -#define OMPD_OSTHREAD_CUDALOGICAL 3 -#define OMPD_OSTHREAD_MAX 4 - -typedef enum ompd_osthread_kind_t { - ompd_osthread_pthread=0, - ompd_osthread_lwp=1, - ompd_osthread_winthread=2, - ompd_osthread_cudalogical=3 -} ompd_osthread_kind_t; +#define OMPD_THREAD_ID_PTHREAD 0 +#define OMPD_THREAD_ID_LWP 1 +#define OMPD_THREAD_ID_WINTHREAD 2 +#define OMPD_THREAD_ID_CUDALOGICAL 3 +#define OMPD_THREAD_ID_MAX 4 + +typedef enum ompd_thread_id_kind_t { + ompd_thread_id_pthread=0, + ompd_thread_id_lwp=1, + ompd_thread_id_winthread=2, + ompd_thread_id_cudalogical=3 +} ompd_thread_id_kind_t; /** * Logical coordinates of OMP target device threads */ typedef struct ompd_dim3_t { - ompd_tword_t x; - ompd_tword_t y; - ompd_tword_t z; + ompd_word_t x; + ompd_word_t y; + ompd_word_t z; } ompd_dim3_t; typedef struct ompd_cudathread_coord_t { - ompd_taddr_t cudaDevId; - ompd_taddr_t cudaContext; - ompd_taddr_t warpSize; - ompd_taddr_t gridId; - ompd_taddr_t kernelId; // TODO (MJM) - for some reason, cuda-gdb doesn't work with grids too well. + ompd_addr_t cudaDevId; + ompd_addr_t cudaContext; + ompd_addr_t warpSize; + ompd_addr_t gridId; + ompd_addr_t kernelId; // TODO (MJM) - for some reason, cuda-gdb doesn't work with grids too well. ompd_dim3_t gridDim; ompd_dim3_t blockDim; ompd_dim3_t blockIdx; @@ -258,13 +261,13 @@ typedef enum ompd_target_prim_types_t */ typedef struct ompd_target_type_sizes_t { - unsigned int sizeof_char; - unsigned int sizeof_short; - unsigned int sizeof_int; - unsigned int sizeof_long; - unsigned int sizeof_long_long; - unsigned int sizeof_pointer; -} ompd_target_type_sizes_t; + uint8_t sizeof_char; + uint8_t sizeof_short; + uint8_t sizeof_int; + uint8_t sizeof_long; + uint8_t sizeof_long_long; + uint8_t sizeof_pointer; +} ompd_device_type_sizes_t; /****************************************************************************** @@ -294,14 +297,15 @@ typedef ompd_rc_t (*ompd_dmemory_free_fn_t) ( /** * Get thread specific context. */ -typedef ompd_rc_t (*ompd_get_thread_context_for_osthread_fn_t) ( +typedef ompd_rc_t (*ompd_get_thread_context_for_thread_id_fn_t) ( ompd_address_space_context_t *context, - ompd_osthread_kind_t kind, - ompd_size_t sizeof_osthread, - const void* osthread, + ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, + const void* thread_id, ompd_thread_context_t** thread_context ); +#if 0 /** * Get containing (host) process context for address_space_context */ @@ -311,6 +315,7 @@ typedef ompd_rc_t (*ompd_get_process_context_for_context_fn_t) ( ompd_address_space_context_t** containing_address_space_context /* OUT: Containing omp process addr space */ ); +#endif /** * Look up the sizes of primitive types in the target @@ -337,7 +342,7 @@ typedef ompd_rc_t (*ompd_tmemory_read_fn_t) ( ompd_address_space_context_t *context, /* IN: debugger handle for the target */ ompd_thread_context_t *tcontext, /* IN: debugger handle for a target thread might be NULL */ ompd_address_t addr, /* IN: address in the target */ - ompd_tword_t nbytes, /* IN: number of items to read */ + ompd_word_t nbytes, /* IN: number of items to read */ void *buffer /* OUT: output buffer */ ); @@ -348,7 +353,7 @@ typedef ompd_rc_t (*ompd_tmemory_write_fn_t) ( ompd_address_space_context_t *context, /* IN: debugger handle for the target */ ompd_thread_context_t *tcontext, /* IN: debugger handle for a target thread might be NULL */ ompd_address_t addr, /* IN: address in the target */ - ompd_tword_t nbytes, /* IN: number of items to write */ + ompd_word_t nbytes, /* IN: number of items to write */ const void *buffer /* IN: output buffer */ ); @@ -388,8 +393,8 @@ typedef struct ompd_callbacks_t ompd_target_host_fn_t target_to_host; ompd_target_host_fn_t host_to_target; - ompd_get_thread_context_for_osthread_fn_t get_thread_context_for_osthread; - ompd_get_process_context_for_context_fn_t get_containing_process_context; + ompd_get_thread_context_for_thread_id_fn_t get_thread_context_for_thread_id; +// ompd_get_process_context_for_context_fn_t get_containing_process_context; } ompd_callbacks_t; @@ -406,17 +411,17 @@ typedef struct ompd_callbacks_t * revision of the OMPD specification supported by an implementation of OMPD. */ -ompd_rc_t ompd_get_version ( - int *version +ompd_rc_t ompd_get_api_version ( + ompd_word_t *version ); -typedef ompd_rc_t (*ompd_get_version_apifn_t) ( - int *version +typedef ompd_rc_t (*ompd_get_api_version_apifn_t) ( + ompd_word_t *version ); -ompd_rc_t ompd_get_version_string( +ompd_rc_t ompd_get_api_version_string( const char **string /* OUT: OMPD version string */ ); -typedef ompd_rc_t (*ompd_get_version_string_apifn_t) ( +typedef ompd_rc_t (*ompd_get_api_version_string_apifn_t) ( const char **string /* OUT: OMPD version string */ ); @@ -427,10 +432,12 @@ typedef ompd_rc_t (*ompd_get_version_string_apifn_t) ( * maintain the functions valid for as long as needed. */ ompd_rc_t ompd_initialize ( - const ompd_callbacks_t *table /* IN: callbacks table */ + const ompd_callbacks_t *table, /* IN: callbacks table */ + ompd_word_t version ); typedef ompd_rc_t (*ompd_initialize_apifn_t) ( - const ompd_callbacks_t *table /* IN: callbacks table */ + const ompd_callbacks_t *table, /* IN: callbacks table */ + ompd_word_t version ); ompd_rc_t ompd_process_initialize ( @@ -442,6 +449,15 @@ typedef ompd_rc_t (*ompd_process_initialize_apifn_t) ( ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the target */ ); +ompd_rc_t ompd_get_openmp_version ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_word_t *version + ); +typedef ompd_rc_t (*ompd_get_openmp_version_apifn_t) ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_word_t *version + ); + ompd_rc_t ompd_release_address_space_handle ( ompd_address_space_handle_t *addr_handle /* IN: handle for the address space */ ); @@ -480,6 +496,7 @@ typedef ompd_rc_t (*ompd_finalize_apifn_t) ( void ); * and/or destroying threads during or after the call, rendering useless the * vector of handles returned. */ +#if 0 ompd_rc_t ompd_get_threads ( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ @@ -490,7 +507,7 @@ typedef ompd_rc_t (*ompd_get_threads_apifn_t) ( ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ int *num_handles /* OUT: number of handles in the array */ ); - +#endif /** * Retrieve handles for OpenMP threads in a parallel region. * @@ -505,22 +522,23 @@ typedef ompd_rc_t (*ompd_get_threads_apifn_t) ( */ ompd_rc_t ompd_get_thread_in_parallel( ompd_parallel_handle_t *parallel_handle, /* IN */ - ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ - int *num_handles /* OUT: number of handles in the array */ + int nth_thread, /* IN: number of the thread in team */ + ompd_thread_handle_t **thread_handle /* OUT: handle */ ); typedef ompd_rc_t (*ompd_get_thread_in_parallel_apifn_t) ( ompd_parallel_handle_t *parallel_handle, /* IN */ - ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ - int *num_handles /* OUT: number of handles in the array */ + int nth_thread, /* IN: number of the thread in team */ + ompd_thread_handle_t **thread_handle /* OUT: handle */ ); +#if 0 ompd_rc_t ompd_get_master_thread_in_parallel ( ompd_parallel_handle_t *parallel_handle, /* IN */ ompd_thread_handle_t **thread_handle); typedef ompd_rc_t (*ompd_get_master_thread_in_parallel_apifn_t) ( ompd_parallel_handle_t *parallel_handle, /* IN */ ompd_thread_handle_t **thread_handle); - +#endif ompd_rc_t ompd_release_thread_handle ( ompd_thread_handle_t *thread_handle @@ -541,6 +559,7 @@ typedef ompd_rc_t (*ompd_thread_handle_compare_apifn_t) ( int *cmp_value ); +#if 0 ompd_rc_t ompd_get_thread_handle_string_id ( ompd_thread_handle_t *thread_handle, char **string_id @@ -549,23 +568,24 @@ typedef ompd_rc_t (*ompd_get_thread_handle_string_id_apifn_t) ( ompd_thread_handle_t *thread_handle, char **string_id ); +#endif /* --- 4.2 Parallel Region Handles------------------------------------------- */ /** * Retrieve the handle for the innermost patallel region for an OpenMP thread. * - * The operation ompd_get_top_parallel_region enables the debugger to obtain + * The operation ompd_get_current_parallel_handle enables the debugger to obtain * the handle for the innermost parallel region associated with an OpenMP * thread. This call is meaningful only if the thread whose handle is provided * is stopped. */ -ompd_rc_t ompd_get_top_parallel_region( +ompd_rc_t ompd_get_current_parallel_handle( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ ); -typedef ompd_rc_t (*ompd_get_top_parallel_region_apifn_t) ( +typedef ompd_rc_t (*ompd_get_current_parallel_handle_apifn_t) ( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ ); @@ -591,17 +611,17 @@ typedef ompd_rc_t (*ompd_get_enclosing_parallel_handle_apifn_t) ( /** * Retrieve the handle for the enclosing parallel region or a task region. * - * The ompd_get_task_enclosing_parallel_handle operation enables the debugger to + * The ompd_get_task_parallel_handle operation enables the debugger to * obtain the handle for the parallel region enclosing the task region * specified by task_handle. This call is meaningful only if at least one * thread in the parallel region is stopped. */ -ompd_rc_t ompd_get_task_enclosing_parallel_handle( +ompd_rc_t ompd_get_task_parallel_handle( ompd_task_handle_t* task_handle, /* IN: OpenMP task handle */ ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ ); -typedef ompd_rc_t (*ompd_get_task_enclosing_parallel_handle_apifn_t) ( +typedef ompd_rc_t (*ompd_get_task_parallel_handle_apifn_t) ( ompd_task_handle_t* task_handle, /* IN: OpenMP task handle */ ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ ); @@ -642,15 +662,15 @@ typedef ompd_rc_t (*ompd_get_parallel_handle_string_id_apifn_t) ( /** * Retrieve the handle for the innermost task for an OpenMP thread. * - * The debugger uses the operation ompd_get_top_task_region to obtain the handle + * The debugger uses the operation ompd_get_current_task__handle to obtain the handle * for the innermost task region associated with an OpenMP thread. This call is * meaningful only if the thread whose handle is provided is stopped. */ -ompd_rc_t ompd_get_top_task_region( +ompd_rc_t ompd_get_current_task__handle( ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ ); -typedef ompd_rc_t (*ompd_get_top_task_region_apifn_t) ( +typedef ompd_rc_t (*ompd_get_current_task__handle_apifn_t) ( ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ ); @@ -658,34 +678,36 @@ typedef ompd_rc_t (*ompd_get_top_task_region_apifn_t) ( /** * Retrieve the handle for an enclosing task. * - * The debugger uses ompd_get_ancestor_task_region to obtain the handle for the + * The debugger uses ompd_get_ancestor_task_handle to obtain the handle for the * task region enclosing the task region specified by task_handle. This call is * meaningful only if the thread executing the task specified by task_handle is * stopped. */ -ompd_rc_t ompd_get_ancestor_task_region( +#if 0 +ompd_rc_t ompd_get_ancestor_task_handle( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ ); -typedef ompd_rc_t (*ompd_get_ancestor_task_region_apifn_t) ( +typedef ompd_rc_t (*ompd_get_ancestor_task_handle_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ ); +#endif -ompd_rc_t ompd_get_generating_ancestor_task_region( +ompd_rc_t ompd_get_generating_ancestor_task_handle( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ ); -typedef ompd_rc_t (*ompd_get_generating_ancestor_task_region_apifn_t) ( +typedef ompd_rc_t (*ompd_get_generating_ancestor_task_handle_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ ); -ompd_rc_t ompd_get_scheduling_ancestor_task_region( +ompd_rc_t ompd_get_scheduling_ancestor_task_handle( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ ); -typedef ompd_rc_t (*ompd_get_scheduling_ancestor_task_region_apifn_t) ( +typedef ompd_rc_t (*ompd_get_scheduling_ancestor_task_handle_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ ); @@ -698,15 +720,15 @@ typedef ompd_rc_t (*ompd_get_scheduling_ancestor_task_region_apifn_t) ( * call is meaningful only if all threads associated with the parallel region * are stopped. */ -ompd_rc_t ompd_get_implicit_task_in_parallel( +ompd_rc_t ompd_get_task_in_parallel( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_task_handle_t ***task_handle_array, /* OUT: array of OpenMP task handles */ - int *num_handles /* OUT: number of task handles */ + int nth_handle, /* IN: number of the task handle */ + ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ ); -typedef ompd_rc_t (*ompd_get_implicit_task_in_parallel_apifn_t) ( +typedef ompd_rc_t (*ompd_get_task_in_parallel_apifn_t) ( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_task_handle_t ***task_handle_array, /* OUT: array of OpenMP task handles */ - int *num_handles /* OUT: number of task handles */ + int nth_handle, /* IN: number of the task handle */ + ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ ); ompd_rc_t ompd_release_task_handle ( @@ -748,20 +770,20 @@ typedef ompd_rc_t (*ompd_get_task_handle_string_id_apifn_t) ( ompd_rc_t ompd_get_num_procs( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_tword_t *val /* OUT: number of processes */ + ompd_word_t *val /* OUT: number of processes */ ); typedef ompd_rc_t (*ompd_get_num_procs_apifn_t) ( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_tword_t *val /* OUT: number of processes */ + ompd_word_t *val /* OUT: number of processes */ ); ompd_rc_t ompd_get_thread_limit( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ); typedef ompd_rc_t (*ompd_get_thread_limit_apifn_t) ( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ); /* --- 6 Parallel Region Inqueries ------------------------------------------ */ @@ -772,11 +794,11 @@ typedef ompd_rc_t (*ompd_get_thread_limit_apifn_t) ( */ ompd_rc_t ompd_get_num_threads( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_tword_t *val /* OUT: number of threads */ + ompd_word_t *val /* OUT: number of threads */ ); typedef ompd_rc_t (*ompd_get_num_threads_apifn_t) ( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_tword_t *val /* OUT: number of threads */ + ompd_word_t *val /* OUT: number of threads */ ); /** @@ -784,11 +806,11 @@ typedef ompd_rc_t (*ompd_get_num_threads_apifn_t) ( */ ompd_rc_t ompd_get_level( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_tword_t *val /* OUT: nesting level */ + ompd_word_t *val /* OUT: nesting level */ ); typedef ompd_rc_t (*ompd_get_level_apifn_t) ( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_tword_t *val /* OUT: nesting level */ + ompd_word_t *val /* OUT: nesting level */ ); /** @@ -799,11 +821,11 @@ typedef ompd_rc_t (*ompd_get_level_apifn_t) ( */ ompd_rc_t ompd_get_active_level( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_tword_t *val /* OUT: active nesting level */ + ompd_word_t *val /* OUT: active nesting level */ ); typedef ompd_rc_t (*ompd_get_active_level_apifn_t) ( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_tword_t *val /* OUT: active nesting level */ + ompd_word_t *val /* OUT: active nesting level */ ); /* --- 6.2 OMPT Parallel Region Inquiry Analogues ------------------------- */ @@ -847,17 +869,17 @@ typedef ompd_rc_t (*ompd_get_parallel_function_apifn_t) ( */ ompd_rc_t ompd_get_thread_handle ( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_osthread_kind_t kind, - ompd_size_t sizeof_osthread, - const void* osthread, + ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, + const void* thread_id, ompd_thread_handle_t **thread_handle /* OUT: OpenMP thread handle*/ ); typedef ompd_rc_t (*ompd_get_thread_handle_apifn_t) ( ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_osthread_kind_t kind, - ompd_size_t sizeof_osthread, - const void* osthread, + ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, + const void* thread_id, ompd_thread_handle_t **thread_handle /* OUT: OpenMP thread handle*/ ); @@ -866,28 +888,37 @@ typedef ompd_rc_t (*ompd_get_thread_handle_apifn_t) ( * this might change over time in case virtual openmp threads migrate between * OS threads. */ -ompd_rc_t ompd_get_osthread ( +ompd_rc_t ompd_get_thread_id ( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, + void *thread_id + ); + +typedef ompd_rc_t (*ompd_get_thread_id_apifn_t) ( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_osthread_kind_t kind, - ompd_size_t sizeof_osthread, - void *osthread + ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, + void *thread_id ); -typedef ompd_rc_t (*ompd_get_osthread_apifn_t) ( +ompd_rc_t ompd_get_thread_data( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_address_t *data /* OUT: OpenMP thread data */ + ); +typedef ompd_rc_t (*ompd_get_thread_data_apifn_t) ( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_osthread_kind_t kind, - ompd_size_t sizeof_osthread, - void *osthread + ompd_address_t *data /* OUT: OpenMP thread data */ ); ompd_rc_t ompd_get_thread_num( ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ - ompd_tword_t *val /* OUT: number of the thread within the team */ + ompd_word_t *val /* OUT: number of the thread within the team */ ); typedef ompd_rc_t (*ompd_get_thread_num_apifn_t) ( ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ - ompd_tword_t *val /* OUT: number of the thread within the team */ + ompd_word_t *val /* OUT: number of the thread within the team */ ); @@ -904,12 +935,12 @@ typedef ompd_rc_t (*ompd_get_thread_num_apifn_t) ( */ ompd_rc_t ompd_get_state ( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_state_t *state, /* OUT: State of this thread */ + ompd_word_t *state, /* OUT: State of this thread */ ompd_wait_id_t *wait_id /* OUT: Wait ID */ ); typedef ompd_rc_t (*ompd_get_state_apifn_t) ( ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_state_t *state, /* OUT: State of this thread */ + ompd_word_t *state, /* OUT: State of this thread */ ompd_wait_id_t *wait_id /* OUT: Wait ID */ ); @@ -946,92 +977,92 @@ typedef ompd_rc_t (*ompd_get_task_function_apifn_t) ( ompd_rc_t ompd_get_max_threads( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ); typedef ompd_rc_t (*ompd_get_max_threads_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: max number of threads */ + ompd_word_t *val /* OUT: max number of threads */ ); ompd_rc_t ompd_in_parallel( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: Is OpenMP in parallel? */ + ompd_word_t *val /* OUT: Is OpenMP in parallel? */ ); typedef ompd_rc_t (*ompd_in_parallel_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: Is OpenMP in parallel? */ + ompd_word_t *val /* OUT: Is OpenMP in parallel? */ ); ompd_rc_t ompd_in_final( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: Is OpenMP in final? */ + ompd_word_t *val /* OUT: Is OpenMP in final? */ ); typedef ompd_rc_t (*ompd_in_final_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: Is OpenMP in final? */ + ompd_word_t *val /* OUT: Is OpenMP in final? */ ); ompd_rc_t ompd_get_dynamic( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: ? */ + ompd_word_t *val /* OUT: ? */ ); typedef ompd_rc_t (*ompd_get_dynamic_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: ? */ + ompd_word_t *val /* OUT: ? */ ); ompd_rc_t ompd_get_nested( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_tword_t *val /* OUT: Is this task nested? */ + ompd_word_t *val /* OUT: Is this task nested? */ ); typedef ompd_rc_t (*ompd_get_nested_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_tword_t *val /* OUT: Is this task nested? */ + ompd_word_t *val /* OUT: Is this task nested? */ ); ompd_rc_t ompd_get_max_active_levels( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_tword_t *val /* OUT: max active levels */ + ompd_word_t *val /* OUT: max active levels */ ); typedef ompd_rc_t (*ompd_get_max_active_levels_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_tword_t *val /* OUT: max active levels */ + ompd_word_t *val /* OUT: max active levels */ ); ompd_rc_t ompd_get_schedule( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_sched_t *kind, /* OUT: Kind of OpenMP schedule*/ - ompd_tword_t *modifier /* OUT: Schedunling modifier */ + ompd_word_t *kind, /* OUT: Kind of OpenMP schedule*/ + ompd_word_t *modifier /* OUT: Schedunling modifier */ ); typedef ompd_rc_t (*ompd_get_schedule_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_sched_t *kind, /* OUT: Kind of OpenMP schedule*/ - ompd_tword_t *modifier /* OUT: Schedunling modifier */ + ompd_word_t *kind, /* OUT: Kind of OpenMP schedule*/ + ompd_word_t *modifier /* OUT: Schedunling modifier */ ); ompd_rc_t ompd_get_proc_bind( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_proc_bind_t *bind /* OUT: Kind of proc-binding */ + ompd_word_t *bind /* OUT: Kind of proc-binding */ ); typedef ompd_rc_t (*ompd_get_proc_bind_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_proc_bind_t *bind /* OUT: Kind of proc-binding */ + ompd_word_t *bind /* OUT: Kind of proc-binding */ ); ompd_rc_t ompd_is_implicit( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: implicit=1, explicit=0 */ + ompd_word_t *val /* OUT: implicit=1, explicit=0 */ ); typedef ompd_rc_t (*ompd_is_implicit_apifn_t) ( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_tword_t *val /* OUT: implicit=1, explicit=0 */ + ompd_word_t *val /* OUT: implicit=1, explicit=0 */ ); /* --- 8.3 OMPT Task Inquiry Analogues -------------------------------------- */ From 88108b28b097904432c8a2f929b4d90d8652d065 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Sat, 3 Feb 2018 14:16:41 -0600 Subject: [PATCH 33/46] Stop generating ompd.h, only build libompd if active in cmake --- libompd/CMakeLists.txt | 6 +- libompd/src/CMakeLists.txt | 22 +- libompd/src/omp-debug.h | 1 - libompd/src/ompd-template.h | 1149 ------------------------------ libompd/src/split_def_typedef.sh | 6 - 5 files changed, 4 insertions(+), 1180 deletions(-) delete mode 100644 libompd/src/ompd-template.h delete mode 100755 libompd/src/split_def_typedef.sh diff --git a/libompd/CMakeLists.txt b/libompd/CMakeLists.txt index c07b50a77..69232bc20 100644 --- a/libompd/CMakeLists.txt +++ b/libompd/CMakeLists.txt @@ -1,3 +1,3 @@ - - -add_subdirectory(src) +if(LIBOMP_OMPD_SUPPORT) + add_subdirectory(src) +endif() diff --git a/libompd/src/CMakeLists.txt b/libompd/src/CMakeLists.txt index 9b4c03ec3..a2662ad31 100644 --- a/libompd/src/CMakeLists.txt +++ b/libompd/src/CMakeLists.txt @@ -2,36 +2,16 @@ project (libompd) add_library (ompd SHARED TargetValue.cpp omp-debug.cpp) -add_dependencies(ompd ompd-header) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") include_directories ( - ${CMAKE_CURRENT_BINARY_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR} ) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include) - -ADD_CUSTOM_TARGET ( - ompd-header ALL - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/include/ompd.h ${CMAKE_CURRENT_BINARY_DIR}/include/ompd_typedefs.h -) - -add_custom_command ( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/include/ompd.h ${CMAKE_CURRENT_BINARY_DIR}/include/ompd_typedefs.h - COMMAND ${BASH} - ARGS ${CMAKE_CURRENT_SOURCE_DIR}/split_def_typedef.sh - ${CMAKE_CURRENT_SOURCE_DIR}/ompd-template.h - ${CMAKE_CURRENT_BINARY_DIR}/include/ompd_typedefs.h - ${CMAKE_CURRENT_BINARY_DIR}/include/ompd.h - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ompd-template.h -) - INSTALL( TARGETS ompd LIBRARY DESTINATION lib ARCHIVE DESTINATION lib/static RUNTIME DESTINATION bin ) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/ompd.h DESTINATION include) +INSTALL(FILES ompd.h DESTINATION include) diff --git a/libompd/src/omp-debug.h b/libompd/src/omp-debug.h index 595c4aa4a..cebf5a337 100644 --- a/libompd/src/omp-debug.h +++ b/libompd/src/omp-debug.h @@ -33,7 +33,6 @@ extern "C" { #define STR(x) STR_HELPER(x) #include "ompd.h" -#include "ompd_typedefs.h" /****************************************************************************** * General helper functions diff --git a/libompd/src/ompd-template.h b/libompd/src/ompd-template.h deleted file mode 100644 index 79d949bea..000000000 --- a/libompd/src/ompd-template.h +++ /dev/null @@ -1,1149 +0,0 @@ -/* - * ompd.h - * - * Created on: Dec 22, 2014 - * Author: Ignacio Laguna - * Joachim Protze - * Contact: ilaguna@llnl.gov - * protze@llnl.gov - */ -#ifndef SRC_OMPD_H_ -#define SRC_OMPD_H_ - -/****************************************************************************** - * This header file defines the OMPD interface: an interface to help debuggers - * to inspect state associated with OpenMP programming abstractions in a target - * process. The interface is implemented in a dynamically loaded library (DLL) - * that the debugger loads into its address space. - * - * Name conventions: - * - All named entities start with the prefix "ompd_" (for OpenMP debugging) - * - Type entities end with the suffix "_t" (for type) - * - Function types end with the suffix "_fn_t" (for function type) - * - Return code entities have "_rc_" in it - * - Abstractions referring to the target have the prefix "t" (e.g., - * "tmemory" for memory in the target, or "tsymbol" for symbol in the target) - * - Abstractions referring to the debugger have the prefix "d" (e.g., - * "dmemory" for memory in the debugger) - * - * Comment conventions: - * - Input function parameters denoted by "IN:" - * - Output function parameters denoted by "OUT:" - */ - -#include -//#include "omp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/****************************************************************************** - * General types and data structures - */ - -/** - * Basic types. - */ -typedef uint64_t ompd_addr_t; /* unsigned integer large enough */ - /* to hold a target address or a */ - /* target segment value */ -typedef int64_t ompd_word_t; /* signed version of ompd_addr_t */ -typedef uint64_t ompd_seg_t; -typedef uint64_t ompd_wait_id_t; /* identifies what a thread is */ - /* waiting for */ -typedef uint64_t ompd_size_t; /* For sizes (e.g., size_t) */ - -typedef struct ompd_address_t { - ompd_seg_t segment; /* target architecture specific */ - /* segment value */ - ompd_addr_t address; /* target address in the segment */ -} ompd_address_t; - -#define OMPD_SEGMENT_UNSPECIFIED ((ompd_seg_t) 0) -#define OMPD_SEGMENT_TEXT ((ompd_seg_t) 1) -#define OMPD_SEGMENT_DATA ((ompd_seg_t) 2) - -/** - * The following definitions match with ptx information stored in DWARF - */ -#define OMPD_SEGMENT_CUDA_PTX_UNSPECIFIED ((ompd_seg_t)0) -#define OMPD_SEGMENT_CUDA_PTX_CODE ((ompd_seg_t)1) -#define OMPD_SEGMENT_CUDA_PTX_REG ((ompd_seg_t)2) -#define OMPD_SEGMENT_CUDA_PTX_SREG ((ompd_seg_t)3) -#define OMPD_SEGMENT_CUDA_PTX_CONST ((ompd_seg_t)4) -#define OMPD_SEGMENT_CUDA_PTX_GLOBAL ((ompd_seg_t)5) -#define OMPD_SEGMENT_CUDA_PTX_LOCAL ((ompd_seg_t)6) -#define OMPD_SEGMENT_CUDA_PTX_PARAM ((ompd_seg_t)7) -#define OMPD_SEGMENT_CUDA_PTX_SHARED ((ompd_seg_t)8) -#define OMPD_SEGMENT_CUDA_PTX_SURF ((ompd_seg_t)9) -#define OMPD_SEGMENT_CUDA_PTX_TEX ((ompd_seg_t)10) -#define OMPD_SEGMENT_CUDA_PTX_TEXSAMPLER ((ompd_seg_t)11) -#define OMPD_SEGMENT_CUDA_PTX_GENERIC ((ompd_seg_t)12) -#define OMPD_SEGMENT_CUDA_PTX_IPARAM ((ompd_seg_t)13) -#define OMPD_SEGMENT_CUDA_PTX_OPARAM ((ompd_seg_t)14) -#define OMPD_SEGMENT_CUDA_PTX_FRAME ((ompd_seg_t)15) -#define OMPD_SEGMENT_CUDA_PTX_MAX ((ompd_seg_t)16) - -#if 0 // types removed in Austin F2F -/* - * Definition of OMPD states, taken from OMPT - */ -#define FOREACH_OMPD_STATE(macro) \ - \ - /* first */ \ - macro (ompd_state_first, 0x71) /* initial enumeration state */ \ - \ - /* work states (0..15) */ \ - macro (ompd_state_work_serial, 0x00) /* working outside parallel */ \ - macro (ompd_state_work_parallel, 0x01) /* working within parallel */ \ - macro (ompd_state_work_reduction, 0x02) /* performing a reduction */ \ - \ - /* idle (16..31) */ \ - macro (ompd_state_idle, 0x10) /* waiting for work */ \ - \ - /* overhead states (32..63) */ \ - macro (ompd_state_overhead, 0x20) /* overhead excluding wait states */ \ - \ - /* barrier wait states (64..79) */ \ - macro (ompd_state_wait_barrier, 0x40) /* waiting at a barrier */ \ - macro (ompd_state_wait_barrier_implicit, 0x41) /* implicit barrier */ \ - macro (ompd_state_wait_barrier_explicit, 0x42) /* explicit barrier */ \ - \ - /* task wait states (80..95) */ \ - macro (ompd_state_wait_taskwait, 0x50) /* waiting at a taskwait */ \ - macro (ompd_state_wait_taskgroup, 0x51) /* waiting at a taskgroup */ \ - \ - /* mutex wait states (96..111) */ \ - macro (ompd_state_wait_lock, 0x60) /* waiting for lock */ \ - macro (ompd_state_wait_nest_lock, 0x61) /* waiting for nest lock */ \ - macro (ompd_state_wait_critical, 0x62) /* waiting for critical */ \ - macro (ompd_state_wait_atomic, 0x63) /* waiting for atomic */ \ - macro (ompd_state_wait_ordered, 0x64) /* waiting for ordered */ \ - macro (ompd_state_wait_single, 0x6F) /* waiting for single region (non-standard!) */ \ - \ - /* misc (112..127) */ \ - macro (ompd_state_undefined, 0x70) /* undefined thread state */ - -typedef enum ompd_state_t { -#define ompd_state_macro(state, code) state = code, - FOREACH_OMPD_STATE(ompd_state_macro) -#undef ompd_state_macro -} ompd_state_t; - -typedef enum ompd_sched_t { - ompd_sched_static = 1, - ompd_sched_dynamic = 2, - ompd_sched_guided = 3, - ompd_sched_auto = 4, - ompd_sched_vendor_lo = 5, - ompd_sched_vendor_hi = 0x7fffffff -} ompd_sched_t; - -typedef enum ompd_proc_bind_t { - ompd_proc_bind_false = 0, - ompd_proc_bind_true = 1, - ompd_proc_bind_master = 2, - ompd_proc_bind_close = 3, - ompd_proc_bind_spread = 4 -} ompd_proc_bind_t; -#endif - -typedef uint64_t ompd_device_identifier_t; - -typedef enum ompd_device_kind_t { - ompd_device_kind_host = 1, - ompd_device_kind_cuda = 2 -} ompd_device_kind_t; - -/** - * Context handle. - * This is used by the debugger to identify a target process (or core file). - * This will be cast to concrete types within the debugger. The callbacks use - * context handles to specify the debugger where to look up (since the debugger - * can be handling different contexts at the same time, e.g., processes and/or - * core files). Without context handles the debugger would not know the target - * of a callback request. - */ - -typedef struct _ompd_address_space_context_s ompd_address_space_context_t; -typedef struct _ompd_thread_context_s ompd_thread_context_t; - -/** - * OpenMP abstractions handles. - * Each operation in the OMPD interface must explicitly specify a handle for the - * context of the operation. OMPD uses context handles for OpenMP entities, such - * as threads, parallel regions, and tasks. A handle for an entity is constant - * while the entity itself is live. - */ - -typedef struct _ompd_device_handle_s ompd_device_handle_t; -typedef struct _ompd_thread_handle_s ompd_thread_handle_t; -typedef struct _ompd_parallel_handle_s ompd_parallel_handle_t; -typedef struct _ompd_task_handle_s ompd_task_handle_t; -typedef struct _ompd_address_space_handle_s ompd_address_space_handle_t; - -/** - * Other handles. - */ -#define OMPD_THREAD_ID_PTHREAD 0 -#define OMPD_THREAD_ID_LWP 1 -#define OMPD_THREAD_ID_WINTHREAD 2 -#define OMPD_THREAD_ID_CUDALOGICAL 3 -#define OMPD_THREAD_ID_MAX 4 - -typedef enum ompd_thread_id_kind_t { - ompd_thread_id_pthread=0, - ompd_thread_id_lwp=1, - ompd_thread_id_winthread=2, - ompd_thread_id_cudalogical=3 -} ompd_thread_id_kind_t; - -/** - * Logical coordinates of OMP target device threads - */ -typedef struct ompd_dim3_t { - ompd_word_t x; - ompd_word_t y; - ompd_word_t z; -} ompd_dim3_t; - -typedef struct ompd_cudathread_coord_t { - ompd_addr_t cudaDevId; - ompd_addr_t cudaContext; - ompd_addr_t warpSize; - ompd_addr_t gridId; - ompd_addr_t kernelId; // TODO (MJM) - for some reason, cuda-gdb doesn't work with grids too well. - ompd_dim3_t gridDim; - ompd_dim3_t blockDim; - ompd_dim3_t blockIdx; - ompd_dim3_t threadIdx; -} ompd_cudathread_coord_t; - -/** - * Return codes. - * Each OMPD operation returns a code. - */ -typedef enum ompd_rc_t -{ - ompd_rc_ok = 0, /* operation was successful */ - ompd_rc_unavailable = 1, /* info is not available (in this context) */ - ompd_rc_stale_handle = 2, /* handle is no longer valid */ - ompd_rc_bad_input = 3, /* bad input parameters (other than handle) */ - ompd_rc_error = 4, /* error */ - ompd_rc_unsupported = 5, /* operation is not supported */ - ompd_rc_needs_state_tracking = 6, /* needs runtime state tracking enabled */ - ompd_rc_incompatible = 7, /* target is not compatible with this OMPD */ - ompd_rc_target_read_error = 8, /* error reading from the target */ - ompd_rc_target_write_error = 9, /* error writing from the target */ - ompd_rc_nomem = 10 /* unable to allocate memory */ -} ompd_rc_t; - -/** - * Primitive types. - */ -typedef enum ompd_target_prim_types_t -{ - ompd_type_invalid = -1, - ompd_type_char = 0, - ompd_type_short = 1, - ompd_type_int = 2, - ompd_type_long = 3, - ompd_type_long_long = 4, - ompd_type_pointer = 5, - ompd_type_max -} ompd_target_prim_types_t; - -/** - * Primitive type sizes. - * These types are used by OMPD to interrogate the debugger about the size of - * primitive types in the target. - */ -typedef struct ompd_target_type_sizes_t -{ - uint8_t sizeof_char; - uint8_t sizeof_short; - uint8_t sizeof_int; - uint8_t sizeof_long; - uint8_t sizeof_long_long; - uint8_t sizeof_pointer; -} ompd_device_type_sizes_t; - - -/****************************************************************************** - * Debugger callback signatures. - * These callback function signatures are used by OMPD to obtain state - * information of a target process, in particular to interrogate about info - * that is dependent on a particular OpenMP runtime library. Typical queries are - * sizes of primitive types in the target, symbols lookup, lookup of offsets of - * fields in a type/structure, and read/write to memory in the target. - */ - -/** - * Allocate memory in the debugger's address space. - */ -typedef ompd_rc_t (*ompd_dmemory_alloc_fn_t) ( - ompd_size_t bytes, /* IN: bytes of the primitive type */ - void **ptr /* OUT: pointer of the allocated memory */ - ); - -/** - * Free memory in the debugger's address space. - */ -typedef ompd_rc_t (*ompd_dmemory_free_fn_t) ( - void *ptr /* IN: pointer of memory to deallocate */ - ); - -/** - * Get thread specific context. - */ -typedef ompd_rc_t (*ompd_get_thread_context_for_thread_id_fn_t) ( - ompd_address_space_context_t *context, - ompd_thread_id_kind_t kind, - ompd_size_t sizeof_thread_id, - const void* thread_id, - ompd_thread_context_t** thread_context - ); - -#if 0 -/** - * Get containing (host) process context for address_space_context - */ -typedef ompd_rc_t (*ompd_get_process_context_for_context_fn_t) ( - ompd_address_space_context_t* - address_space_context, /* IN: OMP device/process addr space */ - ompd_address_space_context_t** - containing_address_space_context /* OUT: Containing omp process addr space */ -); -#endif - -/** - * Look up the sizes of primitive types in the target - */ -typedef ompd_rc_t (*ompd_tsizeof_prim_fn_t) ( - ompd_address_space_context_t *context, /* IN: debugger handle for the target */ - ompd_target_type_sizes_t *sizes /* OUT: type sizes */ - ); - -/** - * Look up the address of a global symbol in the target - */ -typedef ompd_rc_t (*ompd_tsymbol_addr_fn_t) ( - ompd_address_space_context_t *context, /* IN: debugger handle for the target */ - ompd_thread_context_t *tcontext, /* IN: debugger handle for a target thread might be NULL */ - const char *symbol_name, /* IN: global symbol name */ - ompd_address_t *symbol_addr /* OUT: symbol address */ - ); - -/** - * Read memory from the target - */ -typedef ompd_rc_t (*ompd_tmemory_read_fn_t) ( - ompd_address_space_context_t *context, /* IN: debugger handle for the target */ - ompd_thread_context_t *tcontext, /* IN: debugger handle for a target thread might be NULL */ - ompd_address_t addr, /* IN: address in the target */ - ompd_word_t nbytes, /* IN: number of items to read */ - void *buffer /* OUT: output buffer */ - ); - -/** - * Write memory from the target - */ -typedef ompd_rc_t (*ompd_tmemory_write_fn_t) ( - ompd_address_space_context_t *context, /* IN: debugger handle for the target */ - ompd_thread_context_t *tcontext, /* IN: debugger handle for a target thread might be NULL */ - ompd_address_t addr, /* IN: address in the target */ - ompd_word_t nbytes, /* IN: number of items to write */ - const void *buffer /* IN: output buffer */ - ); - -typedef ompd_rc_t (*ompd_target_host_fn_t) ( - ompd_address_space_context_t *address_space_context, /* IN */ - const void *input, /* IN */ - int unit_size, /* IN */ - int count, /* IN: number of primitive type */ - /* items to process */ - void *output /* OUT */ -); - -/** - * This is used by the OMPD library to have the debugger print a string. - * The OMPD should not print directly. - */ -typedef ompd_rc_t (*ompd_print_string_fn_t) ( - const char *str /* IN: message to print */ - ); - -/** - * Callbacks table. - */ -typedef struct ompd_callbacks_t -{ - /* Debugger interface */ - ompd_dmemory_alloc_fn_t dmemory_alloc; - ompd_dmemory_free_fn_t dmemory_free; - ompd_print_string_fn_t print_string; - - /* Target interface */ - ompd_tsizeof_prim_fn_t tsizeof_prim; - ompd_tsymbol_addr_fn_t tsymbol_addr; - ompd_tmemory_read_fn_t read_tmemory; - ompd_tmemory_write_fn_t write_tmemory; - - ompd_target_host_fn_t target_to_host; - ompd_target_host_fn_t host_to_target; - - ompd_get_thread_context_for_thread_id_fn_t get_thread_context_for_thread_id; -// ompd_get_process_context_for_context_fn_t get_containing_process_context; - -} ompd_callbacks_t; - -/****************************************************************************** - * Call signatures from the debugger to the OMPD DLL. - */ - -/* --- 4 Initialization ----------------------------------------------------- */ - -/** - * The OMPD function ompd_get_version_string returns a descriptive string - * describing an implementation of the OMPD library. The function - * ompd_get_version_compatibility returns an integer code used to indicate the - * revision of the OMPD specification supported by an implementation of OMPD. - */ - -ompd_rc_t ompd_get_api_version ( - ompd_word_t *version - ); -typedef ompd_rc_t (*ompd_get_api_version_apifn_t) ( - ompd_word_t *version - ); - -ompd_rc_t ompd_get_api_version_string( - const char **string /* OUT: OMPD version string */ - ); -typedef ompd_rc_t (*ompd_get_api_version_string_apifn_t) ( - const char **string /* OUT: OMPD version string */ - ); - -/** - * Initialize OMPD. - * This provides the DLL the pointers to the debugger's functions to obtain - * information about the OpenMP runtime library. The debugger promises to - * maintain the functions valid for as long as needed. - */ -ompd_rc_t ompd_initialize ( - const ompd_callbacks_t *table, /* IN: callbacks table */ - ompd_word_t version - ); -typedef ompd_rc_t (*ompd_initialize_apifn_t) ( - const ompd_callbacks_t *table, /* IN: callbacks table */ - ompd_word_t version - ); - -ompd_rc_t ompd_process_initialize ( - ompd_address_space_context_t *context, /* IN: debugger handle for the target */ - ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the target */ - ); -typedef ompd_rc_t (*ompd_process_initialize_apifn_t) ( - ompd_address_space_context_t *context, /* IN: debugger handle for the target */ - ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the target */ - ); - -ompd_rc_t ompd_get_openmp_version ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_word_t *version - ); -typedef ompd_rc_t (*ompd_get_openmp_version_apifn_t) ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_word_t *version - ); - -ompd_rc_t ompd_release_address_space_handle ( - ompd_address_space_handle_t *addr_handle /* IN: handle for the address space */ - ); -typedef ompd_rc_t (*ompd_release_address_space_handle_apifn_t) ( - ompd_address_space_handle_t *addr_handle /* IN: handle for the address space */ - ); - -ompd_rc_t ompd_device_initialize ( - ompd_address_space_context_t *context, /* IN: debugger handle for the device */ - ompd_device_identifier_t id, /* IN: object defined by native device API */ - ompd_device_kind_t kind, /* IN: */ - ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the device */ - ); -typedef ompd_rc_t (*ompd_device_initialize_apifn_t) ( - ompd_address_space_context_t *context, /* IN: debugger handle for the device */ - ompd_device_identifier_t id, /* IN: object defined by native device API */ - ompd_device_kind_t kind, /* IN: */ - ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the device */ - ); - -ompd_rc_t ompd_finalize ( void ); -typedef ompd_rc_t (*ompd_finalize_apifn_t) ( void ); - -/* --- 4 Handle Management -------------------------------------------------- */ - -/* --- 4.1 Thread Handles --------------------------------------------------- */ - -/** - * Retrieve handles for all OpenMP threads. - * - * The ompd_get_threads operation enables the debugger to obtain handles for all - * OpenMP threads. A successful invocation of ompd_get_threads returns a pointer - * to a vector of handles in thread_handle_array and returns the number of - * handles in num_handles. This call yields meaningful results only if all - * OpenMP threads are stopped; otherwise, the OpenMP runtime may be creating - * and/or destroying threads during or after the call, rendering useless the - * vector of handles returned. - */ -#if 0 -ompd_rc_t ompd_get_threads ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ - int *num_handles /* OUT: number of handles in the array */ - ); -typedef ompd_rc_t (*ompd_get_threads_apifn_t) ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ - int *num_handles /* OUT: number of handles in the array */ - ); -#endif -/** - * Retrieve handles for OpenMP threads in a parallel region. - * - * The ompd_get_thread_in_parallel operation enables the debugger to obtain - * handles for all OpenMP threads associated with a parallel region. A - * successful invocation of ompd_get_thread_in_parallel returns a pointer to a - * vector of handles in thread_handle_array and returns the number of handles in - * num_handles. This call yields meaningful results only if all OpenMP threads - * in the parallel region are stopped; otherwise, the OpenMP runtime may be - * creating and/or destroying threads during or after the call, rendering - * useless the vector of handles returned. - */ -ompd_rc_t ompd_get_thread_in_parallel( - ompd_parallel_handle_t *parallel_handle, /* IN */ - int nth_thread, /* IN: number of the thread in team */ - ompd_thread_handle_t **thread_handle /* OUT: handle */ - ); -typedef ompd_rc_t (*ompd_get_thread_in_parallel_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, /* IN */ - int nth_thread, /* IN: number of the thread in team */ - ompd_thread_handle_t **thread_handle /* OUT: handle */ - ); - -#if 0 -ompd_rc_t ompd_get_master_thread_in_parallel ( - ompd_parallel_handle_t *parallel_handle, /* IN */ - ompd_thread_handle_t **thread_handle); -typedef ompd_rc_t (*ompd_get_master_thread_in_parallel_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, /* IN */ - ompd_thread_handle_t **thread_handle); -#endif - -ompd_rc_t ompd_release_thread_handle ( - ompd_thread_handle_t *thread_handle -); -typedef ompd_rc_t (*ompd_release_thread_handle_apifn_t) ( - ompd_thread_handle_t *thread_handle -); - - -ompd_rc_t ompd_thread_handle_compare ( - ompd_thread_handle_t *thread_handle_1, - ompd_thread_handle_t *thread_handle_2, - int *cmp_value -); -typedef ompd_rc_t (*ompd_thread_handle_compare_apifn_t) ( - ompd_thread_handle_t *thread_handle_1, - ompd_thread_handle_t *thread_handle_2, - int *cmp_value -); - -#if 0 -ompd_rc_t ompd_get_thread_handle_string_id ( - ompd_thread_handle_t *thread_handle, - char **string_id -); -typedef ompd_rc_t (*ompd_get_thread_handle_string_id_apifn_t) ( - ompd_thread_handle_t *thread_handle, - char **string_id -); -#endif - -/* --- 4.2 Parallel Region Handles------------------------------------------- */ - -/** - * Retrieve the handle for the innermost patallel region for an OpenMP thread. - * - * The operation ompd_get_current_parallel_handle enables the debugger to obtain - * the handle for the innermost parallel region associated with an OpenMP - * thread. This call is meaningful only if the thread whose handle is provided - * is stopped. - */ - -ompd_rc_t ompd_get_current_parallel_handle( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ - ); -typedef ompd_rc_t (*ompd_get_current_parallel_handle_apifn_t) ( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ - ); - -/** - * Retrieve the handle for an enclosing parallel region. - * - * The ompd_get_enclosing_parallel_handle operation enables the debugger to - * obtain the handle for the parallel region enclosing the parallel region - * specified by parallel_handle. This call is meaningful only if at least one - * thread in the parallel region is stopped. - */ - -ompd_rc_t ompd_get_enclosing_parallel_handle( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ - ); -typedef ompd_rc_t (*ompd_get_enclosing_parallel_handle_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ - ); - -/** - * Retrieve the handle for the enclosing parallel region or a task region. - * - * The ompd_get_task_parallel_handle operation enables the debugger to - * obtain the handle for the parallel region enclosing the task region - * specified by task_handle. This call is meaningful only if at least one - * thread in the parallel region is stopped. - */ - -ompd_rc_t ompd_get_task_parallel_handle( - ompd_task_handle_t* task_handle, /* IN: OpenMP task handle */ - ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ - ); -typedef ompd_rc_t (*ompd_get_task_parallel_handle_apifn_t) ( - ompd_task_handle_t* task_handle, /* IN: OpenMP task handle */ - ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ - ); - - - -ompd_rc_t ompd_release_parallel_handle ( - ompd_parallel_handle_t *parallel_handle -); -typedef ompd_rc_t (*ompd_release_parallel_handle_apifn_t) ( - ompd_parallel_handle_t *parallel_handle -); - -ompd_rc_t ompd_parallel_handle_compare ( - ompd_parallel_handle_t *parallel_handle_1, - ompd_parallel_handle_t *parallel_handle_2, - int *cmp_value -); -typedef ompd_rc_t (*ompd_parallel_handle_compare_apifn_t) ( - ompd_parallel_handle_t *parallel_handle_1, - ompd_parallel_handle_t *parallel_handle_2, - int *cmp_value -); - -#if 0 -ompd_rc_t ompd_get_parallel_handle_string_id ( - ompd_parallel_handle_t *parallel_handle, - char **string_id -); -typedef ompd_rc_t (*ompd_get_parallel_handle_string_id_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, - char **string_id -); -#endif - -/* --- 4.3 Task Handles ----------------------------------------------------- */ - -/** - * Retrieve the handle for the innermost task for an OpenMP thread. - * - * The debugger uses the operation ompd_get_current_task__handle to obtain the handle - * for the innermost task region associated with an OpenMP thread. This call is - * meaningful only if the thread whose handle is provided is stopped. - */ -ompd_rc_t ompd_get_current_task__handle( - ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ - ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ - ); -typedef ompd_rc_t (*ompd_get_current_task__handle_apifn_t) ( - ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ - ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ - ); - -/** - * Retrieve the handle for an enclosing task. - * - * The debugger uses ompd_get_ancestor_task_handle to obtain the handle for the - * task region enclosing the task region specified by task_handle. This call is - * meaningful only if the thread executing the task specified by task_handle is - * stopped. - */ -#if 0 -ompd_rc_t ompd_get_ancestor_task_handle( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ - ); -typedef ompd_rc_t (*ompd_get_ancestor_task_handle_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ - ); -#endif - -ompd_rc_t ompd_get_generating_ancestor_task_handle( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ - ); -typedef ompd_rc_t (*ompd_get_generating_ancestor_task_handle_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ - ); - -ompd_rc_t ompd_get_scheduling_ancestor_task_handle( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ - ); -typedef ompd_rc_t (*ompd_get_scheduling_ancestor_task_handle_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ - ); - -/** - * Retrieve implicit task handle for a parallel region. - * - * The ompd_get_implicit_task_in_parallel operation enables the debugger to - * obtain handles for implicit tasks associated with a parallel region. This - * call is meaningful only if all threads associated with the parallel region - * are stopped. - */ -ompd_rc_t ompd_get_task_in_parallel( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - int nth_handle, /* IN: number of the task handle */ - ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ - ); -typedef ompd_rc_t (*ompd_get_task_in_parallel_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - int nth_handle, /* IN: number of the task handle */ - ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ - ); - -ompd_rc_t ompd_release_task_handle ( - ompd_task_handle_t *task_handle -); -typedef ompd_rc_t (*ompd_release_task_handle_apifn_t) ( - ompd_task_handle_t *task_handle -); - -ompd_rc_t ompd_task_handle_compare ( - ompd_task_handle_t *task_handle_1, - ompd_task_handle_t *task_handle_2, - int *cmp_value -); -typedef ompd_rc_t (*ompd_task_handle_compare_apifn_t) ( - ompd_task_handle_t *task_handle_1, - ompd_task_handle_t *task_handle_2, - int *cmp_value -); - -#if 0 -ompd_rc_t ompd_get_task_handle_string_id ( - ompd_task_handle_t *task_handle, - char **string_id -); -typedef ompd_rc_t (*ompd_get_task_handle_string_id_apifn_t) ( - ompd_task_handle_t *task_handle, - char **string_id -); -#endif - -/* --- 5o Process and Thread Settings ---------------------------------------- */ - -/** - * The functions ompd_get_num_procs and ompd_get_thread_limit are third-party - * versions of the OpenMP runtime functions omp_get_num_procs and - * omp_get_thread_limit. - */ - -ompd_rc_t ompd_get_num_procs( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_word_t *val /* OUT: number of processes */ - ); -typedef ompd_rc_t (*ompd_get_num_procs_apifn_t) ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_word_t *val /* OUT: number of processes */ - ); - -ompd_rc_t ompd_get_thread_limit( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_word_t *val /* OUT: max number of threads */ - ); -typedef ompd_rc_t (*ompd_get_thread_limit_apifn_t) ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_word_t *val /* OUT: max number of threads */ - ); - -/* --- 6 Parallel Region Inqueries ------------------------------------------ */ -/* --- 6.1 Settings --------------------------------------------------------- */ - -/** - * Determine the number of threads associated with a parallel region. - */ -ompd_rc_t ompd_get_num_threads( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_word_t *val /* OUT: number of threads */ - ); -typedef ompd_rc_t (*ompd_get_num_threads_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_word_t *val /* OUT: number of threads */ - ); - -/** - * Determine the nesting depth of a particular parallel region instance. - */ -ompd_rc_t ompd_get_level( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_word_t *val /* OUT: nesting level */ - ); -typedef ompd_rc_t (*ompd_get_level_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_word_t *val /* OUT: nesting level */ - ); - -/** - * Determine the number of enclosing active parallel regions. - * - * ompd_get_active_level returns the number of nested, active parallel regions - * enclosing the parallel region specified by its handle. - */ -ompd_rc_t ompd_get_active_level( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_word_t *val /* OUT: active nesting level */ - ); -typedef ompd_rc_t (*ompd_get_active_level_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_word_t *val /* OUT: active nesting level */ - ); - -/* --- 6.2 OMPT Parallel Region Inquiry Analogues ------------------------- */ - -/** - * The functions ompd_get_parallel_id and ompd_get_parallel_function are - * third-party variants of their OMPT counterparts. The only difference between - * the OMPD and OMPT versions is that the OMPD must supply a parallel region - * handle to provide a context for these inquiries. - */ -ompd_rc_t ompd_get_parallel_data( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_address_t *data /* OUT: OpenMP parallel id */ - ); -typedef ompd_rc_t (*ompd_get_parallel_data_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_address_t *data /* OUT: OpenMP parallel id */ - ); - -#if 0 -ompd_rc_t ompd_get_parallel_function( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ - ); -typedef ompd_rc_t (*ompd_get_parallel_function_apifn_t) ( - ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ - ); -#endif - -/* --- 7 Thread Inquiry ----------------------------------------------------- */ -/* --- 7.1 Operating System Thread Inquiry ---------------------------------- */ - -/** - * Obtain an OpenMP thread handle and the internal OS thread handle for the - * selected (context) thread. - * If the function returns ompd_rc_ok then the operating system thread - * corresponds to an OpenMP thread and the thread_handle is initialized. The - * value of thread_handle ans os_thread is meaningful only to the OpenMP runtime - * system. - */ -ompd_rc_t ompd_get_thread_handle ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_thread_id_kind_t kind, - ompd_size_t sizeof_thread_id, - const void* thread_id, - ompd_thread_handle_t **thread_handle /* OUT: OpenMP thread handle*/ - ); - -typedef ompd_rc_t (*ompd_get_thread_handle_apifn_t) ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_thread_id_kind_t kind, - ompd_size_t sizeof_thread_id, - const void* thread_id, - ompd_thread_handle_t **thread_handle /* OUT: OpenMP thread handle*/ - ); - -/** - * Obtain the OS thread handle for an OpenMP thread handle. - * this might change over time in case virtual openmp threads migrate between - * OS threads. - */ -ompd_rc_t ompd_get_thread_id ( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_thread_id_kind_t kind, - ompd_size_t sizeof_thread_id, - void *thread_id - ); - -typedef ompd_rc_t (*ompd_get_thread_id_apifn_t) ( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_thread_id_kind_t kind, - ompd_size_t sizeof_thread_id, - void *thread_id - ); - -ompd_rc_t ompd_get_thread_data( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_address_t *data /* OUT: OpenMP thread data */ - ); -typedef ompd_rc_t (*ompd_get_thread_data_apifn_t) ( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_address_t *data /* OUT: OpenMP thread data */ - ); - -ompd_rc_t ompd_get_thread_num( - ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ - ompd_word_t *val /* OUT: number of the thread within the team */ - ); - -typedef ompd_rc_t (*ompd_get_thread_num_apifn_t) ( - ompd_thread_handle_t* thread_handle, /* IN: OpenMP thread handle*/ - ompd_word_t *val /* OUT: number of the thread within the team */ - ); - - -/* --- 7.2 OMPT Thread State Inquiry Analogue ------------------------------- */ - -/** - * Get the state of a thread. This can use OMPT state data structure to define - * different states of threads (e.g., idle, working, or barrier, etc) and what - * entity cased this state (e.g., address of a lock); - * - * The function ompd_get_state is a third-party version of ompt_get_state. The - * only difference between the OMPD and OMPT counterparts is that the OMPD - * version must supply a thread handle to provide a context for this inquiry. - */ -ompd_rc_t ompd_get_state ( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_word_t *state, /* OUT: State of this thread */ - ompd_wait_id_t *wait_id /* OUT: Wait ID */ -); -typedef ompd_rc_t (*ompd_get_state_apifn_t) ( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_word_t *state, /* OUT: State of this thread */ - ompd_wait_id_t *wait_id /* OUT: Wait ID */ -); - - -/* --- 8 Task Inquiry ------------------------------------------------------- */ - -/* --- 8.1 Task Function Entry Point ---------------------------------------- */ - -/** - * The ompd_get_task_function returns the entry point of the code that - * corresponds to the body of code executed by the task. - */ - -#if 0 -ompd_rc_t ompd_get_task_function( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_address_t *entry_point /* OUT: first instruction in the task region */ - ); -typedef ompd_rc_t (*ompd_get_task_function_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_address_t *entry_point /* OUT: first instruction in the task region */ - ); -#endif - -/* --- 8.2 Task Settings ---------------------------------------------------- */ - -/** - * Retrieve information from OpenMP tasks. These inquiry functions have no - * counterparts in the OMPT interface as a first-party tool can call OpenMP - * runtime inquiry functions directly. The only difference between the OMPD - * inquiry operations and their counterparts in the OpenMP runtime is that the - * OMPD version must supply a task handle to provide a context for each inquiry. - */ - -ompd_rc_t ompd_get_max_threads( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: max number of threads */ - ); - -typedef ompd_rc_t (*ompd_get_max_threads_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: max number of threads */ - ); - -ompd_rc_t ompd_in_parallel( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: Is OpenMP in parallel? */ - ); - -typedef ompd_rc_t (*ompd_in_parallel_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: Is OpenMP in parallel? */ - ); - -ompd_rc_t ompd_in_final( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: Is OpenMP in final? */ - ); - -typedef ompd_rc_t (*ompd_in_final_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: Is OpenMP in final? */ - ); - -ompd_rc_t ompd_get_dynamic( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: ? */ - ); - -typedef ompd_rc_t (*ompd_get_dynamic_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: ? */ - ); - -ompd_rc_t ompd_get_nested( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_word_t *val /* OUT: Is this task nested? */ - ); - -typedef ompd_rc_t (*ompd_get_nested_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_word_t *val /* OUT: Is this task nested? */ - ); - -ompd_rc_t ompd_get_max_active_levels( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_word_t *val /* OUT: max active levels */ - ); - -typedef ompd_rc_t (*ompd_get_max_active_levels_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_word_t *val /* OUT: max active levels */ - ); - -ompd_rc_t ompd_get_schedule( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *kind, /* OUT: Kind of OpenMP schedule*/ - ompd_word_t *modifier /* OUT: Schedunling modifier */ - ); - -typedef ompd_rc_t (*ompd_get_schedule_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *kind, /* OUT: Kind of OpenMP schedule*/ - ompd_word_t *modifier /* OUT: Schedunling modifier */ - ); - -ompd_rc_t ompd_get_proc_bind( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *bind /* OUT: Kind of proc-binding */ - ); -typedef ompd_rc_t (*ompd_get_proc_bind_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *bind /* OUT: Kind of proc-binding */ - ); - -ompd_rc_t ompd_is_implicit( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: implicit=1, explicit=0 */ - ); -typedef ompd_rc_t (*ompd_is_implicit_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: implicit=1, explicit=0 */ - ); - -/* --- 8.3 OMPT Task Inquiry Analogues -------------------------------------- */ - -/** - * The functions defined here are third-party versions of ompt_get_task_frame - * and ompt_get_task_data. The only difference between the OMPD and OMPT - * counterparts is that the OMPD version must supply a task handle to provide a - * context for these inquiries. - */ - -/** - * sp_exit - * - * This value is set once, the first time that a task exits the runtime to begin - * executing user code. This field points to the stack frame of the runtime - * procedure that called the user code. This value is NULL until just before the - * task exits the runtime. - * - * sp_reentry - * - * This value is set each time that current task re-enters the runtime to create - * new (implicit or explicit) tasks. This field points to the stack frame of the - * runtime procedure called by a task to re-enter the runtime. This value is NULL - * until just after the task re-enters the runtime. - */ - - -ompd_rc_t ompd_get_task_frame( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_address_t *sp_exit, /* OUT: next frame is user code */ - ompd_address_t *sp_reentry /* OUT: previous frame is user code */ - ); -typedef ompd_rc_t (*ompd_get_task_frame_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_address_t *sp_exit, /* OUT: next frame is user code */ - ompd_address_t *sp_reentry /* OUT: previous frame is user code */ - ); - -ompd_rc_t ompd_get_task_data( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_address_t *task_data /* OUT: OpenMP task ID */ - ); -typedef ompd_rc_t (*ompd_get_task_data_apifn_t) ( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_address_t *task_data /* OUT: OpenMP task ID */ - ); - - -/* --- 13 Display Control Variables ----------------------------------------- */ - -/** - * Using the ompd_display_control_vars function, the debugger can extract a - * string that contains a sequence of name/value pairs of control variables - * whose settings are (a) user controllable, and (b) important to the operation - * or performance of an OpenMP runtime system. The control variables exposed - * through this interface will include all of the OMP environment variables, - * settings that may come from vendor or platform- specific environment - * variables (e.g., the IBM XL compiler has an environment variable that - * controls spinning vs. blocking behavior), and other settings that affect - * the operation or functioning of an OpenMP runtime system (e.g., numactl - * settings that cause threads to be bound to cores). - */ - -ompd_rc_t ompd_get_display_control_vars ( - ompd_address_space_handle_t *handle, /* IN */ - const char * const **control_var_values /* OUT */ -); -typedef ompd_rc_t (*ompd_get_display_control_vars_apifn_t) ( - ompd_address_space_handle_t *handle, /* IN */ - const char * const **control_var_values /* OUT */ -); - -ompd_rc_t ompd_release_display_control_vars ( - const char * const **control_var_values /* IN */ -); -typedef ompd_rc_t (*ompd_release_display_control_vars_apifn_t) ( - const char * const **control_var_values /* IN */ -); - -#ifdef __cplusplus -} -#endif -#endif /* SRC_OMPD_H_ */ diff --git a/libompd/src/split_def_typedef.sh b/libompd/src/split_def_typedef.sh deleted file mode 100755 index 618dc2a1c..000000000 --- a/libompd/src/split_def_typedef.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -# $0 -# keep block comments, and api function typedefs -sed '/^\/\*/{:b1;N;/\*\//!bb1;p};/^typedef.*_apifn_t/{:b2;N;/);/!bb2;s/_apifn_t/_fn_t/;p};d' $1 > $2 -# remove api function typedefs -sed '/^typedef.*_apifn_t/{:b2;N;/);/!bb2;d}' $1 > $3 From 51fa12c479f66cffc3cbeed82f3e208d872abd97 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Mon, 12 Feb 2018 11:56:37 +0100 Subject: [PATCH 34/46] Initial pass with clang-format --- libompd/src/Debug.cpp | 7 +- libompd/src/Debug.h | 86 +-- libompd/src/TargetValue.cpp | 341 +++++------ libompd/src/TargetValue.h | 216 +++---- libompd/src/omp-debug.cpp | 1150 +++++++++++++++++------------------ libompd/src/omp-debug.h | 55 +- libompd/src/ompd_test.c | 22 +- libompd/src/ompd_test.h | 4 +- 8 files changed, 910 insertions(+), 971 deletions(-) diff --git a/libompd/src/Debug.cpp b/libompd/src/Debug.cpp index 786fad601..1c0c87ec9 100644 --- a/libompd/src/Debug.cpp +++ b/libompd/src/Debug.cpp @@ -1,6 +1,5 @@ #include "Debug.h" - std::ostream& GdbColor::operator<<(std::ostream& os, GdbColor::Code code) { - return os << "\033[" << static_cast(code) << "m"; - } - +std::ostream &GdbColor::operator<<(std::ostream &os, GdbColor::Code code) { + return os << "\033[" << static_cast(code) << "m"; +} diff --git a/libompd/src/Debug.h b/libompd/src/Debug.h index adb0877d5..48358168d 100644 --- a/libompd/src/Debug.h +++ b/libompd/src/Debug.h @@ -1,58 +1,58 @@ -#include #include +#include #ifndef GDB_DEBUG_H_ #define GDB_DEBUG_H_ - namespace GdbColor { - enum Code { - FG_RED = 31, - FG_GREEN = 32, - FG_BLUE = 34, - FG_DEFAULT = 39, - BG_RED = 41, - BG_GREEN = 42, - BG_BLUE = 44, - BG_DEFAULT = 49 - }; +enum Code { + FG_RED = 31, + FG_GREEN = 32, + FG_BLUE = 34, + FG_DEFAULT = 39, + BG_RED = 41, + BG_GREEN = 42, + BG_BLUE = 44, + BG_DEFAULT = 49 +}; // std::ostream& operator<<(std::ostream& os, Code code); - std::ostream& operator<<(std::ostream& os, Code code) { - return os << "\033[" << static_cast(code) << "m"; - } +std::ostream &operator<<(std::ostream &os, Code code) { + return os << "\033[" << static_cast(code) << "m"; +} } - //class ColorOut: public std::ostream - class ColorOut - { - private: - std::ostream& out; - GdbColor::Code color; - public: - ColorOut(std::ostream& _out, GdbColor::Code _color):out(_out), color(_color){} - template - const ColorOut& operator<< (const T& val) const - {out << color << val << GdbColor::FG_DEFAULT; - return *this;} -/* template - const ColorOut& operator<< (const T* val) const - {out << GdbColor::FG_RED << val << GdbColor::FG_DEFAULT; - return *this;} - template > - const ColorOut& operator<< ( const - std::basic_ios<_CharT,_Traits>& (*pf)(std::basic_ios<_CharT,_Traits>&))const - {out << GdbColor::FG_RED << pf << GdbColor::FG_DEFAULT; - return *this;} -*/ - const ColorOut& operator<< (std::ostream& (*pf)(std::ostream&)) const - {out << color << pf << GdbColor::FG_DEFAULT; - return *this;} - - }; +// class ColorOut: public std::ostream +class ColorOut { +private: + std::ostream &out; + GdbColor::Code color; + +public: + ColorOut(std::ostream &_out, GdbColor::Code _color) + : out(_out), color(_color) {} + template const ColorOut &operator<<(const T &val) const { + out << color << val << GdbColor::FG_DEFAULT; + return *this; + } + /* template + const ColorOut& operator<< (const T* val) const + {out << GdbColor::FG_RED << val << GdbColor::FG_DEFAULT; + return *this;} + template > + const ColorOut& operator<< ( const + std::basic_ios<_CharT,_Traits>& + (*pf)(std::basic_ios<_CharT,_Traits>&))const + {out << GdbColor::FG_RED << pf << GdbColor::FG_DEFAULT; + return *this;} + */ + const ColorOut &operator<<(std::ostream &(*pf)(std::ostream &)) const { + out << color << pf << GdbColor::FG_DEFAULT; + return *this; + } +}; static ColorOut dout(std::cout, GdbColor::FG_RED); static ColorOut sout(std::cout, GdbColor::FG_GREEN); static ColorOut hout(std::cout, GdbColor::FG_BLUE); - #endif /*GDB_DEBUG_H_*/ diff --git a/libompd/src/TargetValue.cpp b/libompd/src/TargetValue.cpp index 48528f2ec..5afb2ab47 100644 --- a/libompd/src/TargetValue.cpp +++ b/libompd/src/TargetValue.cpp @@ -1,198 +1,199 @@ #include "TargetValue.h" #include "Debug.h" -#include #include +#include #include -const ompd_callbacks_t *TValue::callbacks=NULL; +const ompd_callbacks_t *TValue::callbacks = NULL; ompd_target_type_sizes_t TValue::type_sizes; -inline int ompd_sizeof(ompd_target_prim_types_t t) -{ - return (((int*)&TValue::type_sizes)[(int)t]); +inline int ompd_sizeof(ompd_target_prim_types_t t) { + return (((int *)&TValue::type_sizes)[(int)t]); } -TType& TTypeFactory::getType( - ompd_address_space_context_t *context, - const char * typeName, - ompd_addr_t segment -) -{ - TType empty(true); - - if ( ttypes.find(context) == ttypes.end() ) { - std::map empty; - ttypes[context] = empty; - } - - auto t = ttypes.find(context); - auto i = t->second.find(typeName); - if ( i == t->second.end() ) - i = t->second.insert(i, std::make_pair(typeName, TType(context, typeName, segment))); - else - i->second.context = context; +TType &TTypeFactory::getType(ompd_address_space_context_t *context, + const char *typeName, ompd_addr_t segment) { + TType empty(true); - return i->second; -} + if (ttypes.find(context) == ttypes.end()) { + std::map empty; + ttypes[context] = empty; + } + auto t = ttypes.find(context); + auto i = t->second.find(typeName); + if (i == t->second.end()) + i = t->second.insert( + i, std::make_pair(typeName, TType(context, typeName, segment))); + else + i->second.context = context; -TType::TType(ompd_address_space_context_t *_context, - const char* _typeName, - ompd_addr_t _segment) : typeSize(0), fieldOffsets(), descSegment(_segment), - typeName(_typeName), context(_context), isvoid(false) -{ + return i->second; } -ompd_rc_t TType::getSize(ompd_size_t * size) -{ +TType::TType(ompd_address_space_context_t *_context, const char *_typeName, + ompd_addr_t _segment) + : typeSize(0), fieldOffsets(), descSegment(_segment), typeName(_typeName), + context(_context), isvoid(false) {} + +ompd_rc_t TType::getSize(ompd_size_t *size) { ompd_rc_t ret = ompd_rc_ok; - if(typeSize==0) - { + if (typeSize == 0) { ompd_address_t symbolAddr; ompd_size_t tmpSize; std::stringstream ss; ss << "ompd_sizeof__" << typeName; - ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), &symbolAddr); - if (ret!=ompd_rc_ok){ - dout << "missing symbol " - << ss.str() - << " add this to ompd-specific.h:\nOMPD_SIZEOF(" << typeName << ") \\" - << std::endl; + ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), + &symbolAddr); + if (ret != ompd_rc_ok) { + dout << "missing symbol " << ss.str() + << " add this to ompd-specific.h:\nOMPD_SIZEOF(" << typeName + << ") \\" << std::endl; return ret; } symbolAddr.segment = descSegment; ret = TValue::callbacks->read_tmemory(context, NULL, symbolAddr, - 1 * ompd_sizeof(ompd_type_long_long), &(tmpSize)); - if (ret!=ompd_rc_ok) + 1 * ompd_sizeof(ompd_type_long_long), + &(tmpSize)); + if (ret != ompd_rc_ok) return ret; - ret = TValue::callbacks->target_to_host(context, &tmpSize, - ompd_sizeof(ompd_type_long_long), 1, &(typeSize)); + ret = TValue::callbacks->target_to_host( + context, &tmpSize, ompd_sizeof(ompd_type_long_long), 1, &(typeSize)); } *size = typeSize; return ret; } -ompd_rc_t TType::getBitfieldMask (const char* fieldName, uint64_t * bitfieldmask) -{ +ompd_rc_t TType::getBitfieldMask(const char *fieldName, + uint64_t *bitfieldmask) { ompd_rc_t ret = ompd_rc_ok; auto i = bitfieldMasks.find(fieldName); - if ( i == bitfieldMasks.end() ) - { + if (i == bitfieldMasks.end()) { uint64_t tmpMask, bitfieldMask; ompd_address_t symbolAddr; -// ret = callbacks->ttype_offset(context, &OmpdTypeHandle, fieldName, &fieldOffset); + // ret = callbacks->ttype_offset(context, &OmpdTypeHandle, fieldName, + // &fieldOffset); std::stringstream ss; ss << "ompd_bitfield__" << typeName << "__" << fieldName; - ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), &symbolAddr); - if (ret!=ompd_rc_ok){ - dout << "missing symbol " << ss.str() << " add this to ompd-specific.h:\nOMPD_BITFIELD(" << typeName << "," << fieldName << ") \\" << std::endl; + ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), + &symbolAddr); + if (ret != ompd_rc_ok) { + dout << "missing symbol " << ss.str() + << " add this to ompd-specific.h:\nOMPD_BITFIELD(" << typeName << "," + << fieldName << ") \\" << std::endl; return ret; } symbolAddr.segment = descSegment; ret = TValue::callbacks->read_tmemory(context, NULL, symbolAddr, - 1 * ompd_sizeof( ompd_type_long_long), &(tmpMask)); - if (ret!=ompd_rc_ok) + 1 * ompd_sizeof(ompd_type_long_long), + &(tmpMask)); + if (ret != ompd_rc_ok) return ret; - ret = TValue::callbacks->target_to_host(context, &(tmpMask), - ompd_sizeof(ompd_type_long_long), 1, &(bitfieldMask)); - if (ret!=ompd_rc_ok){ + ret = TValue::callbacks->target_to_host(context, &(tmpMask), + ompd_sizeof(ompd_type_long_long), 1, + &(bitfieldMask)); + if (ret != ompd_rc_ok) { return ret; } - i = bitfieldMasks.insert(i,std::make_pair(fieldName, bitfieldMask)); + i = bitfieldMasks.insert(i, std::make_pair(fieldName, bitfieldMask)); } *bitfieldmask = i->second; return ret; } -ompd_rc_t TType::getElementOffset(const char* fieldName, ompd_size_t * offset) -{ +ompd_rc_t TType::getElementOffset(const char *fieldName, ompd_size_t *offset) { ompd_rc_t ret = ompd_rc_ok; auto i = fieldOffsets.find(fieldName); - if ( i == fieldOffsets.end() ) - { + if (i == fieldOffsets.end()) { ompd_size_t tmpOffset, fieldOffset; ompd_address_t symbolAddr; -// ret = callbacks->ttype_offset(context, &OmpdTypeHandle, fieldName, &fieldOffset); + // ret = callbacks->ttype_offset(context, &OmpdTypeHandle, fieldName, + // &fieldOffset); std::stringstream ss; ss << "ompd_access__" << typeName << "__" << fieldName; - ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), &symbolAddr); - if (ret!=ompd_rc_ok){ - dout << "missing symbol " << ss.str() << " add this to ompd-specific.h:\nOMPD_ACCESS(" << typeName << "," << fieldName << ") \\" << std::endl; + ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), + &symbolAddr); + if (ret != ompd_rc_ok) { + dout << "missing symbol " << ss.str() + << " add this to ompd-specific.h:\nOMPD_ACCESS(" << typeName << "," + << fieldName << ") \\" << std::endl; return ret; } symbolAddr.segment = descSegment; ret = TValue::callbacks->read_tmemory(context, NULL, symbolAddr, - 1* ompd_sizeof(ompd_type_long_long), &(tmpOffset)); - if (ret!=ompd_rc_ok) + 1 * ompd_sizeof(ompd_type_long_long), + &(tmpOffset)); + if (ret != ompd_rc_ok) return ret; - ret = TValue::callbacks->target_to_host(context, &(tmpOffset), - ompd_sizeof(ompd_type_long_long), 1, &fieldOffset); - if (ret!=ompd_rc_ok){ + ret = TValue::callbacks->target_to_host(context, &(tmpOffset), + ompd_sizeof(ompd_type_long_long), 1, + &fieldOffset); + if (ret != ompd_rc_ok) { return ret; } - i = fieldOffsets.insert(i,std::make_pair(fieldName, fieldOffset)); + i = fieldOffsets.insert(i, std::make_pair(fieldName, fieldOffset)); } *offset = i->second; return ret; } -ompd_rc_t TType::getElementSize(const char* fieldName, ompd_size_t * size) -{ +ompd_rc_t TType::getElementSize(const char *fieldName, ompd_size_t *size) { ompd_rc_t ret = ompd_rc_ok; auto i = fieldSizes.find(fieldName); - if ( i == fieldSizes.end() ) - { + if (i == fieldSizes.end()) { ompd_size_t tmpOffset, fieldSize; ompd_address_t symbolAddr; -// ret = callbacks->ttype_offset(context, &OmpdTypeHandle, fieldName, &fieldOffset); + // ret = callbacks->ttype_offset(context, &OmpdTypeHandle, fieldName, + // &fieldOffset); std::stringstream ss; ss << "ompd_sizeof__" << typeName << "__" << fieldName; - ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), &symbolAddr); - if (ret!=ompd_rc_ok){ - dout << "missing symbol " << ss.str() << " add this to ompd-specific.h:\nOMPD_ACCESS(" << typeName << "," << fieldName << ") \\" << std::endl; + ret = TValue::callbacks->tsymbol_addr(context, NULL, ss.str().c_str(), + &symbolAddr); + if (ret != ompd_rc_ok) { + dout << "missing symbol " << ss.str() + << " add this to ompd-specific.h:\nOMPD_ACCESS(" << typeName << "," + << fieldName << ") \\" << std::endl; return ret; } symbolAddr.segment = descSegment; ret = TValue::callbacks->read_tmemory(context, NULL, symbolAddr, - 1* ompd_sizeof(ompd_type_long_long), &(tmpOffset)); - if (ret!=ompd_rc_ok) + 1 * ompd_sizeof(ompd_type_long_long), + &(tmpOffset)); + if (ret != ompd_rc_ok) return ret; - ret = TValue::callbacks->target_to_host(context, &tmpOffset, - ompd_sizeof(ompd_type_long_long), 1, &fieldSize); - if (ret!=ompd_rc_ok){ + ret = TValue::callbacks->target_to_host( + context, &tmpOffset, ompd_sizeof(ompd_type_long_long), 1, &fieldSize); + if (ret != ompd_rc_ok) { return ret; } - i = fieldSizes.insert(i,std::make_pair(fieldName, fieldSize)); + i = fieldSizes.insert(i, std::make_pair(fieldName, fieldSize)); } *size = i->second; return ret; } - - -//class VoidType : TType +// class VoidType : TType //{ -//public: +// public: // virtual bool isVoid(){return true;} //} +// static VoidType nullType(); -//static VoidType nullType(); - -//class TValue +// class TValue //{ -//protected: +// protected: // TType& type = nullType; // int pointerLevel; // const char* valueName; // ompd_address_space_context_t *context; // ompd_address_t symbolAddr; -//public: +// public: // TValue(ompd_address_space_context_t *context, const char* valueName); // TValue& cast(const char* typeName); // TValue& cast(const char* typeName, int pointerLevel); @@ -201,29 +202,34 @@ ompd_rc_t TType::getElementSize(const char* fieldName, ompd_size_t * size) // TValue getArrayElement(int elemNumber) const; //}; - -TValue::TValue(ompd_address_space_context_t *_context, ompd_thread_context_t *_tcontext, const char* _valueName, ompd_addr_t segment) -: errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), /*valueName(_valueName),*/ context(_context), tcontext(_tcontext), fieldSize(0) -{ - errorState.errorCode = callbacks->tsymbol_addr(context, tcontext, _valueName, &symbolAddr); +TValue::TValue(ompd_address_space_context_t *_context, + ompd_thread_context_t *_tcontext, const char *_valueName, + ompd_addr_t segment) + : errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), + /*valueName(_valueName),*/ context(_context), tcontext(_tcontext), + fieldSize(0) { + errorState.errorCode = + callbacks->tsymbol_addr(context, tcontext, _valueName, &symbolAddr); symbolAddr.segment = segment; -// assert((ret==ompd_rc_ok) && "Callback call failed"); + // assert((ret==ompd_rc_ok) && "Callback call failed"); } -TValue::TValue(ompd_address_space_context_t *_context, ompd_thread_context_t *_tcontext, ompd_address_t addr) -: errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), context(_context), tcontext(_tcontext), symbolAddr(addr), fieldSize(0) -{ - if(addr.address==0) +TValue::TValue(ompd_address_space_context_t *_context, + ompd_thread_context_t *_tcontext, ompd_address_t addr) + : errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), + context(_context), tcontext(_tcontext), symbolAddr(addr), fieldSize(0) { + if (addr.address == 0) errorState.errorCode = ompd_rc_bad_input; } -// TValue::TValue(ompd_address_space_context_t *_context, ompd_thread_context_t *_tcontext, const struct ompd_handle* handle) -// : errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), context(_context), tcontext(_tcontext), symbolAddr(handle->th) +// TValue::TValue(ompd_address_space_context_t *_context, ompd_thread_context_t +// *_tcontext, const struct ompd_handle* handle) +// : errorState(ompd_rc_ok), type(&nullType), pointerLevel(0), +// context(_context), tcontext(_tcontext), symbolAddr(handle->th) // { // } -TValue& TValue::cast(const char* typeName) -{ +TValue &TValue::cast(const char *typeName) { if (gotError()) return *this; type = &tf.getType(context, typeName, symbolAddr.segment); @@ -232,8 +238,8 @@ TValue& TValue::cast(const char* typeName) return *this; } -TValue& TValue::cast(const char* typeName, int _pointerLevel, ompd_addr_t segment) -{ +TValue &TValue::cast(const char *typeName, int _pointerLevel, + ompd_addr_t segment) { if (gotError()) return *this; type = &tf.getType(context, typeName, symbolAddr.segment); @@ -243,49 +249,48 @@ TValue& TValue::cast(const char* typeName, int _pointerLevel, ompd_addr_t segmen return *this; } -TValue TValue::dereference() const -{ +TValue TValue::dereference() const { if (gotError()) return *this; ompd_address_t tmpAddr; assert(!type->isVoid() && "cannot work with void"); assert(pointerLevel > 0 && "cannot dereference non-pointer"); - TValue ret=*this; + TValue ret = *this; ret.pointerLevel--; - ret.errorState.errorCode = callbacks->read_tmemory(context, tcontext, symbolAddr, - 1 * ompd_sizeof( ompd_type_pointer), &(tmpAddr.address)); - if (ret.errorState.errorCode!=ompd_rc_ok) - return ret; + ret.errorState.errorCode = callbacks->read_tmemory( + context, tcontext, symbolAddr, 1 * ompd_sizeof(ompd_type_pointer), + &(tmpAddr.address)); + if (ret.errorState.errorCode != ompd_rc_ok) + return ret; - ret.errorState.errorCode = callbacks->target_to_host(context, &(tmpAddr.address), - ompd_sizeof(ompd_type_pointer), 1, &(ret.symbolAddr.address)); - if (ret.errorState.errorCode!=ompd_rc_ok){ + ret.errorState.errorCode = callbacks->target_to_host( + context, &(tmpAddr.address), ompd_sizeof(ompd_type_pointer), 1, + &(ret.symbolAddr.address)); + if (ret.errorState.errorCode != ompd_rc_ok) { return ret; } - if (ret.symbolAddr.address==0) + if (ret.symbolAddr.address == 0) ret.errorState.errorCode = ompd_rc_unsupported; return ret; } -ompd_rc_t TValue::getAddress(ompd_address_t * addr) const -{ +ompd_rc_t TValue::getAddress(ompd_address_t *addr) const { *addr = symbolAddr; - if (symbolAddr.address==0) + if (symbolAddr.address == 0) return ompd_rc_unsupported; return errorState.errorCode; } -ompd_rc_t TValue::getRawValue(void* buf, int count) -{ - if( errorState.errorCode != ompd_rc_ok ) +ompd_rc_t TValue::getRawValue(void *buf, int count) { + if (errorState.errorCode != ompd_rc_ok) return errorState.errorCode; ompd_size_t size; errorState.errorCode = type->getSize(&size); - if( errorState.errorCode != ompd_rc_ok ) + if (errorState.errorCode != ompd_rc_ok) return errorState.errorCode; - errorState.errorCode = callbacks->read_tmemory(context, tcontext, symbolAddr, - size, buf); + errorState.errorCode = + callbacks->read_tmemory(context, tcontext, symbolAddr, size, buf); return errorState.errorCode; } @@ -295,86 +300,77 @@ ompd_rc_t TValue::getRawValue(void* buf, int count) // return errorState.errorCode; // } -TBaseValue TValue::castBase(const char* varName) -{ +TBaseValue TValue::castBase(const char *varName) { ompd_size_t size; - errorState.errorCode = tf.getType(context, varName, symbolAddr.segment).getSize(&size); + errorState.errorCode = + tf.getType(context, varName, symbolAddr.segment).getSize(&size); return TBaseValue(*this, size); } -TBaseValue TValue::castBase() const -{ - return TBaseValue(*this, fieldSize); -} - +TBaseValue TValue::castBase() const { return TBaseValue(*this, fieldSize); } -TBaseValue TValue::castBase(ompd_target_prim_types_t baseType) const -{ +TBaseValue TValue::castBase(ompd_target_prim_types_t baseType) const { return TBaseValue(*this, baseType); } -TValue TValue::access(const char* fieldName) const -{ +TValue TValue::access(const char *fieldName) const { if (gotError()) return *this; TValue ret = *this; - assert (pointerLevel<2 && "access to field element of pointer array failed"); - if (pointerLevel==1) // -> operator + assert(pointerLevel < 2 && "access to field element of pointer array failed"); + if (pointerLevel == 1) // -> operator ret = ret.dereference(); - // we use *this for . operator + // we use *this for . operator ompd_size_t offset; ret.errorState.errorCode = type->getElementOffset(fieldName, &offset); ret.errorState.errorCode = type->getElementSize(fieldName, &(ret.fieldSize)); ret.symbolAddr.address += offset; - + return ret; } -ompd_rc_t TValue::check(const char* bitfieldName, ompd_word_t* isSet) const -{ +ompd_rc_t TValue::check(const char *bitfieldName, ompd_word_t *isSet) const { if (gotError()) return getError(); int bitfield; uint64_t bitfieldmask; - ompd_rc_t ret = this->castBase(ompd_type_int).getValue(&bitfield,1); + ompd_rc_t ret = this->castBase(ompd_type_int).getValue(&bitfield, 1); if (ret != ompd_rc_ok) return ret; ret = type->getBitfieldMask(bitfieldName, &bitfieldmask); - *isSet = ((bitfield & bitfieldmask)!=0); + *isSet = ((bitfield & bitfieldmask) != 0); return ret; } -TValue TValue::getArrayElement(int elemNumber) const -{ +TValue TValue::getArrayElement(int elemNumber) const { if (gotError()) return *this; - TValue ret=dereference(); - if (ret.pointerLevel==0) - { + TValue ret = dereference(); + if (ret.pointerLevel == 0) { ompd_size_t size; ret.errorState.errorCode = type->getSize(&size); ret.symbolAddr.address += elemNumber * size; - } - else - { + } else { ret.symbolAddr.address += elemNumber * type_sizes.sizeof_pointer; } return ret; } -TBaseValue::TBaseValue(const TValue& _tvalue, ompd_target_prim_types_t _baseType): TValue(_tvalue), baseTypeSize(ompd_sizeof(_baseType)){} -TBaseValue::TBaseValue(const TValue& _tvalue, ompd_size_t _baseTypeSize): TValue(_tvalue), baseTypeSize(_baseTypeSize){} +TBaseValue::TBaseValue(const TValue &_tvalue, + ompd_target_prim_types_t _baseType) + : TValue(_tvalue), baseTypeSize(ompd_sizeof(_baseType)) {} +TBaseValue::TBaseValue(const TValue &_tvalue, ompd_size_t _baseTypeSize) + : TValue(_tvalue), baseTypeSize(_baseTypeSize) {} -ompd_rc_t TBaseValue::getValue(void* buf, int count) -{ - if( errorState.errorCode != ompd_rc_ok ) +ompd_rc_t TBaseValue::getValue(void *buf, int count) { + if (errorState.errorCode != ompd_rc_ok) return errorState.errorCode; errorState.errorCode = callbacks->read_tmemory(context, tcontext, symbolAddr, - count *baseTypeSize, buf); - if (errorState.errorCode!=ompd_rc_ok) - return errorState.errorCode; - errorState.errorCode = callbacks->target_to_host(context, buf, - baseTypeSize, count, buf); + count * baseTypeSize, buf); + if (errorState.errorCode != ompd_rc_ok) + return errorState.errorCode; + errorState.errorCode = + callbacks->target_to_host(context, buf, baseTypeSize, count, buf); return errorState.errorCode; } @@ -382,10 +378,9 @@ ompd_rc_t TBaseValue::getValue(void* buf, int count) // { // if( errorState.errorCode != ompd_rc_ok ) // return errorState.errorCode; -// errorState.errorCode = callbacks->read_tmemory(context, tcontext, symbolAddr, +// errorState.errorCode = callbacks->read_tmemory(context, tcontext, +// symbolAddr, // count, baseType, &(buf->th)); // assert((errorState.errorCode == ompd_rc_ok) && "Callback call failed"); // return errorState.errorCode; // } - - diff --git a/libompd/src/TargetValue.h b/libompd/src/TargetValue.h index 60cd0888a..cbf8a4f9f 100644 --- a/libompd/src/TargetValue.h +++ b/libompd/src/TargetValue.h @@ -1,55 +1,54 @@ -#include #include "ompd.h" +#include #ifndef SRC_TARGET_VALUE_H_ #define SRC_TARGET_VALUE_H_ -#ifdef __cplusplus +#ifdef __cplusplus +#include #include #include -#include class TType; class TValue; class TBaseValue; -class TTypeFactory -{ +class TTypeFactory { protected: - std::map > ttypes; + std::map> + ttypes; -public: - TTypeFactory(): ttypes() {} - TType& getType(ompd_address_space_context_t *context, - const char * typName, - ompd_addr_t segment=OMPD_SEGMENT_UNSPECIFIED); +public: + TTypeFactory() : ttypes() {} + TType &getType(ompd_address_space_context_t *context, const char *typName, + ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED); }; static thread_local TTypeFactory tf = TTypeFactory(); -class TType -{ +class TType { protected: ompd_size_t typeSize; - std::map fieldOffsets; - std::map fieldSizes; - std::map bitfieldMasks; + std::map fieldOffsets; + std::map fieldSizes; + std::map bitfieldMasks; ompd_addr_t descSegment; - const char* typeName; + const char *typeName; ompd_address_space_context_t *context; bool isvoid; - TType(ompd_address_space_context_t *context, - const char* typeName, - ompd_addr_t _segment=OMPD_SEGMENT_UNSPECIFIED); -public: - TType(bool, ompd_addr_t _segment=OMPD_SEGMENT_UNSPECIFIED): descSegment(_segment), isvoid(true) {} - bool isVoid() const{return isvoid;} - ompd_rc_t getElementOffset (const char* fieldName, ompd_size_t * offset); - ompd_rc_t getElementSize (const char* fieldName, ompd_size_t * size); - ompd_rc_t getBitfieldMask (const char* fieldName, uint64_t * bitfieldmask); - ompd_rc_t getSize (ompd_size_t * size); + TType(ompd_address_space_context_t *context, const char *typeName, + ompd_addr_t _segment = OMPD_SEGMENT_UNSPECIFIED); + +public: + TType(bool, ompd_addr_t _segment = OMPD_SEGMENT_UNSPECIFIED) + : descSegment(_segment), isvoid(true) {} + bool isVoid() const { return isvoid; } + ompd_rc_t getElementOffset(const char *fieldName, ompd_size_t *offset); + ompd_rc_t getElementSize(const char *fieldName, ompd_size_t *size); + ompd_rc_t getBitfieldMask(const char *fieldName, uint64_t *bitfieldmask); + ompd_rc_t getSize(ompd_size_t *size); friend TValue; friend TTypeFactory; }; @@ -63,92 +62,99 @@ static TType nullType(true); * the according error code and which operation raised the error. */ -class TError -{ -protected: +class TError { +protected: ompd_rc_t errorCode; - TError():errorCode(ompd_rc_ok){} - TError(const ompd_rc_t& error):errorCode(error){} + TError() : errorCode(ompd_rc_ok) {} + TError(const ompd_rc_t &error) : errorCode(error) {} + public: - virtual std::string toString(){return std::string("TError messages not implemented yet");} + virtual std::string toString() { + return std::string("TError messages not implemented yet"); + } friend TValue; friend TBaseValue; }; /** * class TValue - * This class encapsules the access to target values by using OMPD + * This class encapsules the access to target values by using OMPD * callback functions. The member functions are designed to concatinate * the operations that are needed to access values from structures * e.g., _a[6]->_b._c would read like : - * TValue(ctx, "_a").cast("A",2).getArrayElement(6).access("_b").cast("B").access("_c") + * TValue(ctx, + * "_a").cast("A",2).getArrayElement(6).access("_b").cast("B").access("_c") */ -class TValue -{ +class TValue { protected: - TError errorState; - TType* type; + TType *type; int pointerLevel; -// const char* valueName; + // const char* valueName; ompd_address_space_context_t *context; ompd_thread_context_t *tcontext; ompd_address_t symbolAddr; - //size_t fieldSize; + // size_t fieldSize; ompd_size_t fieldSize; -public: + +public: static const ompd_callbacks_t *callbacks; static ompd_target_type_sizes_t type_sizes; - TValue():errorState(ompd_rc_error){} + TValue() : errorState(ompd_rc_error) {} /** * Create a target value object from symbol name */ - TValue(ompd_address_space_context_t *_context, - const char* _valueName, - ompd_addr_t segment=OMPD_SEGMENT_UNSPECIFIED): - TValue(_context, NULL, _valueName, segment) {} + TValue(ompd_address_space_context_t *_context, const char *_valueName, + ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED) + : TValue(_context, NULL, _valueName, segment) {} - TValue(ompd_address_space_context_t *context, - ompd_thread_context_t *tcontext, - const char* valueName, - ompd_addr_t segment=OMPD_SEGMENT_UNSPECIFIED); + TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext, + const char *valueName, ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED); /** * Create a target value object from target value address */ - TValue(ompd_address_space_context_t *_context, ompd_address_t _addr): TValue(_context, NULL, _addr) {} - TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext, ompd_address_t addr); -// TValue(ompd_address_space_context_t *context, const struct ompd_handle* th): TValue(context, NULL, th) {} -// TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext, const struct ompd_handle* th); + TValue(ompd_address_space_context_t *_context, ompd_address_t _addr) + : TValue(_context, NULL, _addr) {} + TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext, + ompd_address_t addr); + // TValue(ompd_address_space_context_t *context, const struct ompd_handle* + // th): TValue(context, NULL, th) {} + // TValue(ompd_address_space_context_t *context, ompd_thread_context_t + // *tcontext, const struct ompd_handle* th); /** * Cast the target value object to some type of typeName * - * This call modifies the object and returns a reference to the modified object + * This call modifies the object and returns a reference to the modified + * object */ - TValue& cast(const char* typeName); + TValue &cast(const char *typeName); /** * Cast the target value object to some pointer of type typename * pointerlevel gives the number of * * e.g., char** would be: cast("char",2) * - * This call modifies the object and returns a reference to the modified object + * This call modifies the object and returns a reference to the modified + * object */ - TValue& cast(const char* typeName, int pointerLevel, ompd_addr_t segment=OMPD_SEGMENT_UNSPECIFIED); + TValue &cast(const char *typeName, int pointerLevel, + ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED); /** * Get the target address of the target value */ - ompd_rc_t getAddress(ompd_address_t * addr) const; + ompd_rc_t getAddress(ompd_address_t *addr) const; /** * Get the raw memory copy of the target value */ - ompd_rc_t getRawValue(void* buf, int count); -// ompd_rc_t getAddress(struct ompd_handle* th) const; + ompd_rc_t getRawValue(void *buf, int count); + // ompd_rc_t getAddress(struct ompd_handle* th) const; /** * Get a new target value object for the dereferenced target value - * reduces the pointer level, uses the target value as new target address, keeps the target type + * reduces the pointer level, uses the target value as new target address, + * keeps the target type */ TValue dereference() const; /** @@ -165,16 +171,16 @@ class TValue * Cast to a base type * Get the size by name from the rtl */ - TBaseValue castBase(const char* varName); + TBaseValue castBase(const char *varName); /** * Resolve field access for structs/unions * this supports both "->" and "." operator. */ - TValue access(const char* fieldName) const; + TValue access(const char *fieldName) const; /** * Tests for a field bit in a bitfield */ - ompd_rc_t check(const char* bitfieldName, ompd_word_t* isSet) const; + ompd_rc_t check(const char *bitfieldName, ompd_word_t *isSet) const; /** * Get an array element */ @@ -182,71 +188,67 @@ class TValue /** * Did we raise some error yet? */ - bool gotError() const {return errorState.errorCode != ompd_rc_ok; } + bool gotError() const { return errorState.errorCode != ompd_rc_ok; } /** * Get the error code */ - ompd_rc_t getError() const {return errorState.errorCode; } + ompd_rc_t getError() const { return errorState.errorCode; } /** * Did we raise some error yet? */ - std::string getErrorMessage() {return errorState.toString();} + std::string getErrorMessage() { return errorState.toString(); } }; -class TBaseValue : public TValue -{ +class TBaseValue : public TValue { protected: -// ompd_target_prim_types_t baseType=ompd_type_invalid; + // ompd_target_prim_types_t baseType=ompd_type_invalid; ompd_size_t baseTypeSize = 0; - TBaseValue(const TValue&, ompd_target_prim_types_t baseType); - TBaseValue(const TValue&, ompd_size_t baseTypeSize); + TBaseValue(const TValue &, ompd_target_prim_types_t baseType); + TBaseValue(const TValue &, ompd_size_t baseTypeSize); -public: -// ompd_rc_t getValue(struct ompd_handle* buf, int count); - ompd_rc_t getValue(void* buf, int count); - template - ompd_rc_t getValue(T& buf); +public: + // ompd_rc_t getValue(struct ompd_handle* buf, int count); + ompd_rc_t getValue(void *buf, int count); + template ompd_rc_t getValue(T &buf); friend TValue; }; -template -ompd_rc_t TBaseValue::getValue(T& buf) -{ - assert (sizeof(T) >= baseTypeSize); +template ompd_rc_t TBaseValue::getValue(T &buf) { + assert(sizeof(T) >= baseTypeSize); ompd_rc_t ret = getValue(&buf, 1); - if (sizeof(T) > baseTypeSize) - { - switch (baseTypeSize){ - case 1: - buf = (T)*((int8_t*)&buf); - break; - case 2: - buf = (T)*((int16_t*)&buf); - break; - case 4: - buf = (T)*((int32_t*)&buf); - break; - case 8: - buf = (T)*((int64_t*)&buf); - break; + if (sizeof(T) > baseTypeSize) { + switch (baseTypeSize) { + case 1: + buf = (T) * ((int8_t *)&buf); + break; + case 2: + buf = (T) * ((int16_t *)&buf); + break; + case 4: + buf = (T) * ((int32_t *)&buf); + break; + case 8: + buf = (T) * ((int64_t *)&buf); + break; } - } + } return ret; } - -#define EXTERN_C extern "C" +#define EXTERN_C extern "C" #else #define EXTERN_C #endif -//EXTERN_C int getNumberOfOMPThreads(ompd_address_space_context_t *context); -//EXTERN_C int32_t getOmpThreadID(ompd_address_space_context_t *context); -//EXTERN_C uint64_t getSystemThreadID(ompd_address_space_context_t *context, ompd_thread_handle_t t); -//EXTERN_C ompd_thread_handle_t getOmpThreadHandle(ompd_address_space_context_t *context); -//EXTERN_C void getThreadState(ompd_address_space_context_t *context, ompd_thread_handle_t t, ompt_state_t *state, +// EXTERN_C int getNumberOfOMPThreads(ompd_address_space_context_t *context); +// EXTERN_C int32_t getOmpThreadID(ompd_address_space_context_t *context); +// EXTERN_C uint64_t getSystemThreadID(ompd_address_space_context_t *context, +// ompd_thread_handle_t t); +// EXTERN_C ompd_thread_handle_t getOmpThreadHandle(ompd_address_space_context_t +// *context); +// EXTERN_C void getThreadState(ompd_address_space_context_t *context, +// ompd_thread_handle_t t, ompt_state_t *state, // ompt_wait_id_t *wait_id); - #endif /*SRC_TARGET_VALUE_H_*/ diff --git a/libompd/src/omp-debug.cpp b/libompd/src/omp-debug.cpp index 3d38c8917..59a53e9c1 100644 --- a/libompd/src/omp-debug.cpp +++ b/libompd/src/omp-debug.cpp @@ -16,19 +16,19 @@ #include "omp-debug.h" #include "ompd.h" // #include -#include -#include +#include "TargetValue.h" #include +#include #include +#include #include #include -#include "TargetValue.h" const ompd_callbacks_t *callbacks = NULL; ompd_target_type_sizes_t type_sizes; uint64_t ompd_state; -//void* operator new(std::size_t size) /*throw (std::bad_alloc)*/ +// void* operator new(std::size_t size) /*throw (std::bad_alloc)*/ /*{ void* res; ompd_rc_t ret = callbacks->dmemory_alloc(size, &res); @@ -36,7 +36,7 @@ uint64_t ompd_state; return res; throw std::bad_alloc(); }*/ -//void* operator new[](std::size_t size) /*throw (std::bad_alloc)*/ +// void* operator new[](std::size_t size) /*throw (std::bad_alloc)*/ /*{ void* res; ompd_rc_t ret = callbacks->dmemory_alloc(size, &res); @@ -57,13 +57,11 @@ void operator delete[](void* addr) throw () throw std::bad_alloc(); }*/ - /* --- OMPD functions ------------------------------------------------------- */ /* --- 3 Initialization ----------------------------------------------------- */ -ompd_rc_t ompd_initialize (const ompd_callbacks_t *table, ompd_word_t version) -{ +ompd_rc_t ompd_initialize(const ompd_callbacks_t *table, ompd_word_t version) { ompd_rc_t ret = table ? ompd_rc_ok : ompd_rc_bad_input; callbacks = table; TValue::callbacks = table; @@ -71,16 +69,14 @@ ompd_rc_t ompd_initialize (const ompd_callbacks_t *table, ompd_word_t version) return ret; } -ompd_rc_t ompd_finalize ( void ){ - return ompd_rc_ok; -} +ompd_rc_t ompd_finalize(void) { return ompd_rc_ok; } - -ompd_rc_t ompd_process_initialize ( - ompd_address_space_context_t *context, /* IN: debugger handle for the target */ - ompd_address_space_handle_t **addrhandle /* OUT: ompd handle for the target */ - ) -{ +ompd_rc_t +ompd_process_initialize(ompd_address_space_context_t + *context, /* IN: debugger handle for the target */ + ompd_address_space_handle_t * + *addrhandle /* OUT: ompd handle for the target */ + ) { if (!context) return ompd_rc_bad_input; if (!addrhandle) @@ -90,16 +86,17 @@ ompd_rc_t ompd_process_initialize ( ompd_rc_t ret = initTypeSizes(context); if (ret != ompd_rc_ok) return ret; - ret = TValue(context, "ompd_rtl_version"). - castBase(ompd_type_int). - getValue(rtl_version); - if ((ret == ompd_rc_ok && rtl_version<5) || ret == ompd_rc_target_read_error) + ret = TValue(context, "ompd_rtl_version") + .castBase(ompd_type_int) + .getValue(rtl_version); + if ((ret == ompd_rc_ok && rtl_version < 5) || + ret == ompd_rc_target_read_error) return ompd_rc_incompatible; if (ret != ompd_rc_ok) return ret; - ret = TValue(context, "ompd_state"). - castBase(ompd_type_long_long). - getValue(ompd_state); + ret = TValue(context, "ompd_state") + .castBase(ompd_type_long_long) + .getValue(ompd_state); if (ret != ompd_rc_ok) return ret; *addrhandle = new ompd_address_space_handle_t; @@ -111,10 +108,10 @@ ompd_rc_t ompd_process_initialize ( return ompd_rc_ok; } -ompd_rc_t ompd_release_address_space_handle ( - ompd_address_space_handle_t *addr_handle /* IN: handle for the address space */ - ) -{ +ompd_rc_t ompd_release_address_space_handle( + ompd_address_space_handle_t + *addr_handle /* IN: handle for the address space */ + ) { if (!addr_handle) return ompd_rc_bad_input; @@ -122,7 +119,7 @@ ompd_rc_t ompd_release_address_space_handle ( return ompd_rc_ok; } -#if 0 // no device support yet +#if 0 // no device support yet ompd_rc_t ompd_device_initialize ( ompd_address_space_context_t *context, /* IN: */ ompd_device_identifier_t id, /* IN: object defined by native device API */ @@ -180,7 +177,7 @@ ompd_rc_t ompd_device_initialize ( return ompd_rc_ok; } #endif // no device support - + /* --- 4 Handle Management -------------------------------------------------- */ /* --- 4.1 Thread Handles --------------------------------------------------- */ @@ -189,10 +186,9 @@ ompd_rc_t ompd_device_initialize ( ompd_rc_t ompd_get_thread_in_parallel( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - int nth_handle, /* OUT: number of handles in the array */ + int nth_handle, /* OUT: number of handles in the array */ ompd_thread_handle_t **thread_handle /* OUT: handle */ - ) -{ + ) { if (!parallel_handle) return ompd_rc_stale_handle; if (!parallel_handle->ah) @@ -208,18 +204,19 @@ ompd_rc_t ompd_get_thread_in_parallel( ompd_address_t taddr; - ret = TValue(context, parallel_handle->th). /* t */ - cast("kmp_base_team_t",0). - access("t_threads"). /*t.t_threads*/ - cast("kmp_info_t",2). - getArrayElement(nth_handle). /*t.t_threads[nth_handle]*/ - access("th"). /*t.t_threads[i]->th*/ - getAddress(&taddr); + ret = TValue(context, parallel_handle->th) /* t */ + .cast("kmp_base_team_t", 0) + .access("t_threads") /*t.t_threads*/ + .cast("kmp_info_t", 2) + .getArrayElement(nth_handle) /*t.t_threads[nth_handle]*/ + .access("th") /*t.t_threads[i]->th*/ + .getAddress(&taddr); - if ( ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) return ret; - ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), (void**)(thread_handle)); - if ( ret != ompd_rc_ok ) + ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), + (void **)(thread_handle)); + if (ret != ompd_rc_ok) return ret; (*thread_handle)->th = taddr; @@ -229,21 +226,18 @@ ompd_rc_t ompd_get_thread_in_parallel( ompd_rc_t ompd_release_thread_handle( ompd_thread_handle_t *thread_handle /* IN: OpenMP parallel handle */ - ) -{ + ) { if (!thread_handle) return ompd_rc_stale_handle; - ompd_rc_t ret = callbacks->dmemory_free((void*)(thread_handle)); - if ( ret != ompd_rc_ok ) + ompd_rc_t ret = callbacks->dmemory_free((void *)(thread_handle)); + if (ret != ompd_rc_ok) return ret; return ompd_rc_ok; } -ompd_rc_t ompd_thread_handle_compare ( - ompd_thread_handle_t *thread_handle_1, - ompd_thread_handle_t *thread_handle_2, - int *cmp_value -){ +ompd_rc_t ompd_thread_handle_compare(ompd_thread_handle_t *thread_handle_1, + ompd_thread_handle_t *thread_handle_2, + int *cmp_value) { if (!thread_handle_1) return ompd_rc_stale_handle; if (!thread_handle_2) @@ -276,10 +270,9 @@ ompd_rc_t ompd_get_thread_handle_string_id ( /* parallel_handle is of type (kmp_base_team_t)*/ ompd_rc_t ompd_get_current_parallel_handle( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ - ) -{ + ) { if (!thread_handle) return ompd_rc_stale_handle; if (!thread_handle->ah) @@ -290,29 +283,28 @@ ompd_rc_t ompd_get_current_parallel_handle( assert(callbacks && "Callback table not initialized!"); ompd_address_t taddr, lwt; - - TValue teamdata = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ - cast("kmp_base_info_t"). - access("th_team"). /*__kmp_threads[t]->th.th_team*/ - cast("kmp_team_p", 1). - access("t"); /*__kmp_threads[t]->th.th_team->t*/ - - ompd_rc_t ret = teamdata. - getAddress(&taddr); - if ( ret != ompd_rc_ok ) + + TValue teamdata = TValue(context, thread_handle->th) /*__kmp_threads[t]->th*/ + .cast("kmp_base_info_t") + .access("th_team") /*__kmp_threads[t]->th.th_team*/ + .cast("kmp_team_p", 1) + .access("t"); /*__kmp_threads[t]->th.th_team->t*/ + + ompd_rc_t ret = teamdata.getAddress(&taddr); + if (ret != ompd_rc_ok) return ret; lwt.segment = OMPD_SEGMENT_UNSPECIFIED; - ret = teamdata. - cast("kmp_base_team_t",0). - access("ompt_serialized_team_info"). - castBase(). - getValue(lwt.address); - if ( ret != ompd_rc_ok ) + ret = teamdata.cast("kmp_base_team_t", 0) + .access("ompt_serialized_team_info") + .castBase() + .getValue(lwt.address); + if (ret != ompd_rc_ok) return ret; - ret = callbacks->dmemory_alloc(sizeof(ompd_parallel_handle_t), (void**)(parallel_handle)); - if ( ret != ompd_rc_ok ) + ret = callbacks->dmemory_alloc(sizeof(ompd_parallel_handle_t), + (void **)(parallel_handle)); + if (ret != ompd_rc_ok) return ret; (*parallel_handle)->ah = thread_handle->ah; @@ -323,9 +315,9 @@ ompd_rc_t ompd_get_current_parallel_handle( ompd_rc_t ompd_get_enclosing_parallel_handle( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ - ) -{ + ompd_parallel_handle_t * + *enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ) { if (!parallel_handle) return ompd_rc_stale_handle; if (!parallel_handle->ah) @@ -336,45 +328,43 @@ ompd_rc_t ompd_get_enclosing_parallel_handle( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - ompd_address_t taddr=parallel_handle->th, lwt; - + ompd_address_t taddr = parallel_handle->th, lwt; + ompd_rc_t ret = ompd_rc_stale_handle; TValue lwtValue = TValue(context, parallel_handle->lwt); if (lwtValue.getError() == ompd_rc_ok) // lwt == 0x0 - { // if we are in lwt, get parent - ret = lwtValue. - cast("ompt_lw_taskteam_t",0). - access("parent"). - cast("ompt_lw_taskteam_t",1). - dereference(). - getAddress(&lwt); + { // if we are in lwt, get parent + ret = lwtValue.cast("ompt_lw_taskteam_t", 0) + .access("parent") + .cast("ompt_lw_taskteam_t", 1) + .dereference() + .getAddress(&lwt); } - if ( ret != ompd_rc_ok ) - { // no lwt or parent==0x0 - - TValue teamdata = TValue(context, parallel_handle->th). /*__kmp_threads[t]->th*/ - cast("kmp_base_team_t",0). /*t*/ - access("t_parent"). /*t.t_parent*/ - cast("kmp_team_p",1). - access("t"); /*t.t_parent->t*/ - - ret = teamdata. - getAddress(&taddr); - if ( ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) { // no lwt or parent==0x0 + + TValue teamdata = + TValue(context, parallel_handle->th) /*__kmp_threads[t]->th*/ + .cast("kmp_base_team_t", 0) /*t*/ + .access("t_parent") /*t.t_parent*/ + .cast("kmp_team_p", 1) + .access("t"); /*t.t_parent->t*/ + + ret = teamdata.getAddress(&taddr); + if (ret != ompd_rc_ok) return ret; lwt.segment = OMPD_SEGMENT_UNSPECIFIED; - ret = teamdata. - cast("kmp_base_team_t",0). - access("ompt_serialized_team_info"). - castBase(). - getValue(lwt.address); - if ( ret != ompd_rc_ok ) + ret = teamdata.cast("kmp_base_team_t", 0) + .access("ompt_serialized_team_info") + .castBase() + .getValue(lwt.address); + if (ret != ompd_rc_ok) return ret; } - ret = callbacks->dmemory_alloc(sizeof(ompd_parallel_handle_t), (void**)(enclosing_parallel_handle)); - if ( ret != ompd_rc_ok ) + ret = callbacks->dmemory_alloc(sizeof(ompd_parallel_handle_t), + (void **)(enclosing_parallel_handle)); + if (ret != ompd_rc_ok) return ret; (*enclosing_parallel_handle)->th = taddr; (*enclosing_parallel_handle)->lwt = lwt; @@ -384,9 +374,9 @@ ompd_rc_t ompd_get_enclosing_parallel_handle( ompd_rc_t ompd_get_task_parallel_handle( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_parallel_handle_t **enclosing_parallel_handle /* OUT: OpenMP parallel handle */ - ) -{ + ompd_parallel_handle_t * + *enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -398,20 +388,21 @@ ompd_rc_t ompd_get_task_parallel_handle( assert(callbacks && "Callback table not initialized!"); ompd_address_t taddr; - + ompd_rc_t ret; - ret = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). /*td*/ - access("td_team"). /*td.td_team*/ - cast("kmp_team_p",1). - access("t"). /*td.td_team->t*/ - getAddress(&taddr); + ret = TValue(context, task_handle->th) + .cast("kmp_taskdata_t") /*td*/ + .access("td_team") /*td.td_team*/ + .cast("kmp_team_p", 1) + .access("t") /*td.td_team->t*/ + .getAddress(&taddr); - if ( ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) return ret; - ret = callbacks->dmemory_alloc(sizeof(ompd_parallel_handle_t), (void**)(enclosing_parallel_handle)); - if ( ret != ompd_rc_ok ) + ret = callbacks->dmemory_alloc(sizeof(ompd_parallel_handle_t), + (void **)(enclosing_parallel_handle)); + if (ret != ompd_rc_ok) return ret; (*enclosing_parallel_handle)->ah = task_handle->ah; @@ -422,22 +413,19 @@ ompd_rc_t ompd_get_task_parallel_handle( ompd_rc_t ompd_release_parallel_handle( ompd_parallel_handle_t *parallel_handle /* IN: OpenMP parallel handle */ - ) -{ + ) { if (!parallel_handle) return ompd_rc_stale_handle; - ompd_rc_t ret = callbacks->dmemory_free((void*)(parallel_handle)); - if ( ret != ompd_rc_ok ) + ompd_rc_t ret = callbacks->dmemory_free((void *)(parallel_handle)); + if (ret != ompd_rc_ok) return ret; return ompd_rc_ok; } - -ompd_rc_t ompd_parallel_handle_compare ( - ompd_parallel_handle_t *parallel_handle_1, - ompd_parallel_handle_t *parallel_handle_2, - int *cmp_value -){ +ompd_rc_t +ompd_parallel_handle_compare(ompd_parallel_handle_t *parallel_handle_1, + ompd_parallel_handle_t *parallel_handle_2, + int *cmp_value) { if (!parallel_handle_1) return ompd_rc_stale_handle; if (!parallel_handle_2) @@ -445,7 +433,8 @@ ompd_rc_t ompd_parallel_handle_compare ( if (parallel_handle_1->th.address - parallel_handle_2->th.address) *cmp_value = parallel_handle_1->th.address - parallel_handle_2->th.address; else - *cmp_value = parallel_handle_1->lwt.address - parallel_handle_2->lwt.address; + *cmp_value = + parallel_handle_1->lwt.address - parallel_handle_2->lwt.address; return ompd_rc_ok; } @@ -468,16 +457,14 @@ ompd_rc_t ompd_get_parallel_handle_string_id ( } #endif - /* --- 4.3 Task Handles ----------------------------------------------------- */ /* task_handle is of type (kmp_taskdata_t) */ ompd_rc_t ompd_get_current_task__handle( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ - ) -{ + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ + ) { if (!thread_handle) return ompd_rc_stale_handle; if (!thread_handle->ah) @@ -488,32 +475,32 @@ ompd_rc_t ompd_get_current_task__handle( assert(callbacks && "Callback table not initialized!"); ompd_address_t taddr, lwt; - - TValue taskdata = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ - cast("kmp_base_info_t"). - access("th_current_task"). /*__kmp_threads[t]->th.th_current_task*/ - cast("kmp_taskdata_t", 1); - - ompd_rc_t ret = taskdata. - dereference(). - getAddress(&taddr); - if ( ret != ompd_rc_ok ) + + TValue taskdata = + TValue(context, thread_handle->th) /*__kmp_threads[t]->th*/ + .cast("kmp_base_info_t") + .access("th_current_task") /*__kmp_threads[t]->th.th_current_task*/ + .cast("kmp_taskdata_t", 1); + + ompd_rc_t ret = taskdata.dereference().getAddress(&taddr); + if (ret != ompd_rc_ok) return ret; lwt.segment = OMPD_SEGMENT_UNSPECIFIED; - ret = taskdata. - access("td_team"). /*td.td_team*/ - cast("kmp_team_p",1). - access("t"). /*td.td_team->t*/ - cast("kmp_base_team_t",0). - access("ompt_serialized_team_info"). - castBase(). - getValue(lwt.address); - if ( ret != ompd_rc_ok ) + ret = taskdata + .access("td_team") /*td.td_team*/ + .cast("kmp_team_p", 1) + .access("t") /*td.td_team->t*/ + .cast("kmp_base_team_t", 0) + .access("ompt_serialized_team_info") + .castBase() + .getValue(lwt.address); + if (ret != ompd_rc_ok) return ret; - ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(task_handle)); - if ( ret != ompd_rc_ok ) + ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), + (void **)(task_handle)); + if (ret != ompd_rc_ok) return ret; (*task_handle)->th = taddr; @@ -522,11 +509,10 @@ ompd_rc_t ompd_get_current_task__handle( return ompd_rc_ok; } -ompd_rc_t ompd_get_generating_ancestor_task_handle( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ - ) -{ +ompd_rc_t ompd_get_generating_ancestor_task_handle( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -536,48 +522,45 @@ ompd_rc_t ompd_get_generating_ancestor_task_handle( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - ompd_address_t taddr=task_handle->th, lwt; - + ompd_address_t taddr = task_handle->th, lwt; + ompd_rc_t ret = ompd_rc_stale_handle; TValue lwtValue = TValue(context, task_handle->lwt); if (lwtValue.getError() == ompd_rc_ok) // lwt == 0x0 - { // if we are in lwt, get parent - ret = lwtValue. - cast("ompt_lw_taskteam_t",0). - access("parent"). - cast("ompt_lw_taskteam_t",1). - dereference(). - getAddress(&lwt); + { // if we are in lwt, get parent + ret = lwtValue.cast("ompt_lw_taskteam_t", 0) + .access("parent") + .cast("ompt_lw_taskteam_t", 1) + .dereference() + .getAddress(&lwt); } - if ( ret != ompd_rc_ok ) - { // no lwt or parent==0x0 - - TValue taskdata = TValue(context, task_handle->th). /*__kmp_threads[t]->th*/ - cast("kmp_taskdata_t"). /*td*/ - access("td_parent"). /*td->td_parent*/ - cast("kmp_taskdata_t", 1); - - ret = taskdata. - dereference(). - getAddress(&taddr); - if ( ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) { // no lwt or parent==0x0 + + TValue taskdata = TValue(context, task_handle->th) /*__kmp_threads[t]->th*/ + .cast("kmp_taskdata_t") /*td*/ + .access("td_parent") /*td->td_parent*/ + .cast("kmp_taskdata_t", 1); + + ret = taskdata.dereference().getAddress(&taddr); + if (ret != ompd_rc_ok) return ret; lwt.segment = OMPD_SEGMENT_UNSPECIFIED; - ret = taskdata. - access("td_team"). /*td.td_team*/ - cast("kmp_team_p",1). - access("t"). /*td.td_team->t*/ - cast("kmp_base_team_t",0). - access("ompt_serialized_team_info"). - castBase(). - getValue(lwt.address); - if ( ret != ompd_rc_ok ) + ret = taskdata + .access("td_team") /*td.td_team*/ + .cast("kmp_team_p", 1) + .access("t") /*td.td_team->t*/ + .cast("kmp_base_team_t", 0) + .access("ompt_serialized_team_info") + .castBase() + .getValue(lwt.address); + if (ret != ompd_rc_ok) return ret; } - ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(parent_task_handle)); - if ( ret != ompd_rc_ok ) + ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), + (void **)(parent_task_handle)); + if (ret != ompd_rc_ok) return ret; (*parent_task_handle)->th = taddr; @@ -586,11 +569,10 @@ ompd_rc_t ompd_get_generating_ancestor_task_handle( return ret; } -ompd_rc_t ompd_get_scheduling_ancestor_task_handle( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ - ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ - ) -{ +ompd_rc_t ompd_get_scheduling_ancestor_task_handle( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -601,20 +583,22 @@ ompd_rc_t ompd_get_scheduling_ancestor_task_handle( assert(callbacks && "Callback table not initialized!"); ompd_address_t taddr; - - ompd_rc_t ret = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). /*td*/ - access("ompt_task_info"). // td->ompt_task_info - cast("ompt_task_info_t"). - access("scheduling_parent"). // td->ompd_task_info.scheduling_parent - cast("kmp_taskdata_t", 1). - dereference(). - getAddress(&taddr); - if ( ret != ompd_rc_ok ) + ompd_rc_t ret = + TValue(context, task_handle->th) + .cast("kmp_taskdata_t") /*td*/ + .access("ompt_task_info") // td->ompt_task_info + .cast("ompt_task_info_t") + .access("scheduling_parent") // td->ompd_task_info.scheduling_parent + .cast("kmp_taskdata_t", 1) + .dereference() + .getAddress(&taddr); + + if (ret != ompd_rc_ok) return ret; - ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(parent_task_handle)); - if ( ret != ompd_rc_ok ) + ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), + (void **)(parent_task_handle)); + if (ret != ompd_rc_ok) return ret; (*parent_task_handle)->th = taddr; @@ -624,10 +608,9 @@ ompd_rc_t ompd_get_scheduling_ancestor_task_handle( ompd_rc_t ompd_get_task_in_parallel( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - int nth_handle, /* OUT: number of the task handle */ + int nth_handle, /* OUT: number of the task handle */ ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ - ) -{ + ) { int i; if (!parallel_handle) return ompd_rc_stale_handle; @@ -638,20 +621,22 @@ ompd_rc_t ompd_get_task_in_parallel( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - + ompd_rc_t ret; ompd_address_t taddr; - ret = TValue(context, parallel_handle->th). /* t */ - cast("kmp_base_team_t",0). - access("t_implicit_task_taskdata"). /*t.t_implicit_task_taskdata*/ - cast("kmp_taskdata_t", 1). - getArrayElement(nth_handle). /*t.t_implicit_task_taskdata[nth_handle]*/ - getAddress(&taddr); + ret = TValue(context, parallel_handle->th) /* t */ + .cast("kmp_base_team_t", 0) + .access("t_implicit_task_taskdata") /*t.t_implicit_task_taskdata*/ + .cast("kmp_taskdata_t", 1) + .getArrayElement( + nth_handle) /*t.t_implicit_task_taskdata[nth_handle]*/ + .getAddress(&taddr); - if ( ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) return ret; - ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), (void**)(task_handle)); - if ( ret != ompd_rc_ok ) + ret = callbacks->dmemory_alloc(sizeof(ompd_task_handle_t), + (void **)(task_handle)); + if (ret != ompd_rc_ok) return ret; (*task_handle)->th = taddr; @@ -661,21 +646,18 @@ ompd_rc_t ompd_get_task_in_parallel( ompd_rc_t ompd_release_task_handle( ompd_task_handle_t *task_handle /* IN: OpenMP task handle */ - ) -{ + ) { if (!task_handle) return ompd_rc_stale_handle; - ompd_rc_t ret = callbacks->dmemory_free((void*)(task_handle)); - if ( ret != ompd_rc_ok ) + ompd_rc_t ret = callbacks->dmemory_free((void *)(task_handle)); + if (ret != ompd_rc_ok) return ret; return ompd_rc_ok; } -ompd_rc_t ompd_task_handle_compare ( - ompd_task_handle_t *task_handle_1, - ompd_task_handle_t *task_handle_2, - int *cmp_value -){ +ompd_rc_t ompd_task_handle_compare(ompd_task_handle_t *task_handle_1, + ompd_task_handle_t *task_handle_2, + int *cmp_value) { if (!task_handle_1) return ompd_rc_stale_handle; if (!task_handle_2) @@ -705,14 +687,13 @@ ompd_rc_t ompd_get_task_handle_string_id ( } #endif - /* --- 5 Process and Thread Settings ---------------------------------------- */ -ompd_rc_t ompd_get_num_procs( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_word_t *val /* OUT: number of processes */ - ) -{ +ompd_rc_t +ompd_get_num_procs(ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + ompd_word_t *val /* OUT: number of processes */ + ) { if (!addr_handle) return ompd_rc_stale_handle; ompd_address_space_context_t *context = addr_handle->context; @@ -724,18 +705,18 @@ ompd_rc_t ompd_get_num_procs( assert(callbacks && "Callback table not initialized!"); int nth; - ret = TValue(context, "__kmp_avail_proc"). - castBase("__kmp_avail_proc"). - getValue(nth); + ret = TValue(context, "__kmp_avail_proc") + .castBase("__kmp_avail_proc") + .getValue(nth); *val = nth; return ret; } -ompd_rc_t ompd_get_thread_limit( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_word_t *val /* OUT: max number of threads */ - ) -{ +ompd_rc_t +ompd_get_thread_limit(ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + ompd_word_t *val /* OUT: max number of threads */ + ) { if (!addr_handle) return ompd_rc_stale_handle; ompd_address_space_context_t *context = addr_handle->context; @@ -747,9 +728,8 @@ ompd_rc_t ompd_get_thread_limit( assert(callbacks && "Callback table not initialized!"); int nth; - ret = TValue(context, "__kmp_max_nth"). - castBase("__kmp_max_nth"). - getValue(nth); + ret = + TValue(context, "__kmp_max_nth").castBase("__kmp_max_nth").getValue(nth); *val = nth; return ret; } @@ -759,9 +739,8 @@ ompd_rc_t ompd_get_thread_limit( ompd_rc_t ompd_get_num_threads( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_word_t *val /* OUT: number of threads */ - ) -{ + ompd_word_t *val /* OUT: number of threads */ + ) { if (!parallel_handle) return ompd_rc_stale_handle; if (!parallel_handle->ah) @@ -771,18 +750,17 @@ ompd_rc_t ompd_get_num_threads( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - + ompd_rc_t ret = ompd_rc_ok; - if (parallel_handle->lwt.address!=0) + if (parallel_handle->lwt.address != 0) *val = 1; - else - { + else { uint32_t res; - ret = TValue(context, parallel_handle->th). - cast("kmp_base_team_t",0). /*t*/ - access("t_nproc"). /*t.t_nproc*/ - castBase(). - getValue(res); + ret = TValue(context, parallel_handle->th) + .cast("kmp_base_team_t", 0) /*t*/ + .access("t_nproc") /*t.t_nproc*/ + .castBase() + .getValue(res); *val = res; } return ret; @@ -790,9 +768,8 @@ ompd_rc_t ompd_get_num_threads( ompd_rc_t ompd_get_level( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_word_t *val /* OUT: nesting level */ - ) -{ + ompd_word_t *val /* OUT: nesting level */ + ) { if (!parallel_handle) return ompd_rc_stale_handle; if (!parallel_handle->ah) @@ -802,23 +779,22 @@ ompd_rc_t ompd_get_level( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - + uint32_t res; - ompd_rc_t ret = TValue(context, parallel_handle->th). - cast("kmp_base_team_t",0). /*t*/ - access("t_level"). /*t.t_level*/ - castBase(). - getValue(res); + ompd_rc_t ret = TValue(context, parallel_handle->th) + .cast("kmp_base_team_t", 0) /*t*/ + .access("t_level") /*t.t_level*/ + .castBase() + .getValue(res); *val = res; return ret; } ompd_rc_t ompd_get_active_level( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_word_t *val /* OUT: active nesting level */ - ) -{ + ompd_word_t *val /* OUT: active nesting level */ + ) { if (!parallel_handle) return ompd_rc_stale_handle; if (!parallel_handle->ah) @@ -828,14 +804,14 @@ ompd_rc_t ompd_get_active_level( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - + uint32_t res; - ompd_rc_t ret = TValue(context, parallel_handle->th). - cast("kmp_base_team_t",0). /*t*/ - access("t_active_level"). /*t.t_active_level*/ - castBase(). - getValue(res); + ompd_rc_t ret = TValue(context, parallel_handle->th) + .cast("kmp_base_team_t", 0) /*t*/ + .access("t_active_level") /*t.t_active_level*/ + .castBase() + .getValue(res); *val = res; return ret; } @@ -844,9 +820,8 @@ ompd_rc_t ompd_get_active_level( ompd_rc_t ompd_get_parallel_data( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ - ompd_address_t *data /* OUT: OpenMP parallel id */ - ) -{ + ompd_address_t *data /* OUT: OpenMP parallel id */ + ) { if (!parallel_handle) return ompd_rc_stale_handle; if (!parallel_handle->ah) @@ -858,23 +833,23 @@ ompd_rc_t ompd_get_parallel_data( return ompd_rc_needs_state_tracking; assert(callbacks && "Callback table not initialized!"); - + TValue teamInfo; - if(parallel_handle->lwt.address!=0) - teamInfo = TValue(context, parallel_handle->lwt). - cast("ompt_lw_taskteam_t",0); /*lwt*/ + if (parallel_handle->lwt.address != 0) + teamInfo = TValue(context, parallel_handle->lwt) + .cast("ompt_lw_taskteam_t", 0); /*lwt*/ else - teamInfo = TValue(context, parallel_handle->th). - cast("kmp_base_team_t",0); /*t*/ - ompd_rc_t ret = teamInfo. - access("ompt_team_info"). /*t.ompt_team_info*/ - cast("ompt_team_info_t",0). - access("parallel_data"). /*t.ompt_team_info.parallel_id*/ - getAddress(data); + teamInfo = + TValue(context, parallel_handle->th).cast("kmp_base_team_t", 0); /*t*/ + ompd_rc_t ret = teamInfo + .access("ompt_team_info") /*t.ompt_team_info*/ + .cast("ompt_team_info_t", 0) + .access("parallel_data") /*t.ompt_team_info.parallel_id*/ + .getAddress(data); return ret; } -#if 0 // there is no such thing as a parallel function +#if 0 // there is no such thing as a parallel function ompd_rc_t ompd_get_parallel_function( ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ @@ -914,13 +889,12 @@ ompd_rc_t ompd_get_parallel_function( /* --- 7.1 Operating System Thread Inquiry ---------------------------------- */ -ompd_rc_t ompd_get_thread_handle ( - ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ - ompd_thread_id_kind_t kind, - ompd_size_t sizeof_thread_id, - const void* thread_id, - ompd_thread_handle_t **thread_handle) -{ +ompd_rc_t +ompd_get_thread_handle(ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, const void *thread_id, + ompd_thread_handle_t **thread_handle) { if (!addr_handle) return ompd_rc_stale_handle; ompd_address_space_context_t *context = addr_handle->context; @@ -931,86 +905,87 @@ ompd_rc_t ompd_get_thread_handle ( assert(callbacks && "Callback table not initialized!"); ompd_thread_context_t *tcontext; - ret = callbacks->get_thread_context_for_thread_id(context, kind, sizeof_thread_id, thread_id, &tcontext); - if ( ret != ompd_rc_ok ) + ret = callbacks->get_thread_context_for_thread_id( + context, kind, sizeof_thread_id, thread_id, &tcontext); + if (ret != ompd_rc_ok) return ret; - + int tId; - if (kind == ompd_thread_id_cudalogical) - { - ompd_cudathread_coord_t* p = (ompd_cudathread_coord_t*)thread_id; + if (kind == ompd_thread_id_cudalogical) { + ompd_cudathread_coord_t *p = (ompd_cudathread_coord_t *)thread_id; // omptarget_nvptx_threadPrivateContext->topTaskDescr[p->threadIdx.x]->data.items.threadId - ret = TValue(context, tcontext, "omptarget_nvptx_threadPrivateContext", OMPD_SEGMENT_CUDA_PTX_SHARED). - cast("omptarget_nvptx_ThreadPrivateContext", 1, OMPD_SEGMENT_CUDA_PTX_SHARED). - access("topTaskDescr"). - cast("omptarget_nvptx_TaskDescr", 1, OMPD_SEGMENT_CUDA_PTX_GLOBAL). - getArrayElement(p->threadIdx.x). - access("data__items__threadId"). - castBase(ompd_type_short). - getValue(tId); - - if ( ret != ompd_rc_ok ) + ret = + TValue(context, tcontext, "omptarget_nvptx_threadPrivateContext", + OMPD_SEGMENT_CUDA_PTX_SHARED) + .cast("omptarget_nvptx_ThreadPrivateContext", 1, + OMPD_SEGMENT_CUDA_PTX_SHARED) + .access("topTaskDescr") + .cast("omptarget_nvptx_TaskDescr", 1, OMPD_SEGMENT_CUDA_PTX_GLOBAL) + .getArrayElement(p->threadIdx.x) + .access("data__items__threadId") + .castBase(ompd_type_short) + .getValue(tId); + + if (ret != ompd_rc_ok) return ret; if (tId != p->threadIdx.x) return ompd_rc_stale_handle; - } - else - { - ret = TValue(context, tcontext, "__kmp_gtid"). - castBase("__kmp_gtid"). - getValue(tId); - if ( ret != ompd_rc_ok ) + } else { + ret = TValue(context, tcontext, "__kmp_gtid") + .castBase("__kmp_gtid") + .getValue(tId); + if (ret != ompd_rc_ok) return ret; - + if (tId < 0) // thread is no omp worker return ompd_rc_unavailable; - TValue th = TValue(context, "__kmp_threads"). // __kmp_threads - cast("kmp_info_t",2). - getArrayElement(tId). /*__kmp_threads[t]*/ - access("th"); /*__kmp_threads[t]->th*/ + TValue th = TValue(context, "__kmp_threads") // __kmp_threads + .cast("kmp_info_t", 2) + .getArrayElement(tId) /*__kmp_threads[t]*/ + .access("th"); /*__kmp_threads[t]->th*/ ompd_address_t taddr; ret = th.getAddress(&taddr); - if ( ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) return ret; - ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), (void**)(thread_handle)); - if ( ret != ompd_rc_ok ) + ret = callbacks->dmemory_alloc(sizeof(ompd_thread_handle_t), + (void **)(thread_handle)); + if (ret != ompd_rc_ok) return ret; (*thread_handle)->ah = addr_handle; (*thread_handle)->th = taddr; #ifndef NDEBUG - if ( ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) return ret; pthread_t oshandle; - TBaseValue ds_handle = th.cast("kmp_base_info_t"). - access("th_info"). /*__kmp_threads[t]->th.th_info*/ - cast("kmp_desc_t"). - access("ds"). /*__kmp_threads[t]->th.th_info.ds*/ - cast("kmp_desc_base_t"). - access("ds_thread"). /*__kmp_threads[t]->th.th_info.ds.ds_thread*/ - castBase(); - - assert( ompd_rc_ok == ds_handle.getValue(oshandle) && oshandle == *(pthread_t*)(thread_id) && "Callback table not initialized!"); + TBaseValue ds_handle = + th.cast("kmp_base_info_t") + .access("th_info") /*__kmp_threads[t]->th.th_info*/ + .cast("kmp_desc_t") + .access("ds") /*__kmp_threads[t]->th.th_info.ds*/ + .cast("kmp_desc_base_t") + .access("ds_thread") /*__kmp_threads[t]->th.th_info.ds.ds_thread*/ + .castBase(); + + assert(ompd_rc_ok == ds_handle.getValue(oshandle) && + oshandle == *(pthread_t *)(thread_id) && + "Callback table not initialized!"); #endif } return ret; } -ompd_rc_t ompd_get_thread_id ( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_thread_id_kind_t kind, - ompd_size_t sizeof_thread_id, - void *thread_id - ) -{ - if (kind!=ompd_thread_id_pthread) +ompd_rc_t ompd_get_thread_id( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_thread_id_kind_t kind, ompd_size_t sizeof_thread_id, void *thread_id) { + if (kind != ompd_thread_id_pthread) return ompd_rc_bad_input; if (!thread_handle) return ompd_rc_stale_handle; @@ -1021,31 +996,30 @@ ompd_rc_t ompd_get_thread_id ( return ompd_rc_stale_handle; ompd_size_t size; ompd_rc_t ret = tf.getType(context, "kmp_thread_t").getSize(&size); - if ( ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) return ret; - if (sizeof_thread_id!=size) + if (sizeof_thread_id != size) return ompd_rc_bad_input; assert(callbacks && "Callback table not initialized!"); - - ret = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ - cast("kmp_base_info_t"). - access("th_info"). /*__kmp_threads[t]->th.th_info*/ - cast("kmp_desc_t"). - access("ds"). /*__kmp_threads[t]->th.th_info.ds*/ - cast("kmp_desc_base_t"). - access("ds_thread"). /*__kmp_threads[t]->th.th_info.ds.ds_thread*/ - cast("kmp_thread_t"). - getRawValue(thread_id,1); + + ret = TValue(context, thread_handle->th) /*__kmp_threads[t]->th*/ + .cast("kmp_base_info_t") + .access("th_info") /*__kmp_threads[t]->th.th_info*/ + .cast("kmp_desc_t") + .access("ds") /*__kmp_threads[t]->th.th_info.ds*/ + .cast("kmp_desc_base_t") + .access("ds_thread") /*__kmp_threads[t]->th.th_info.ds.ds_thread*/ + .cast("kmp_thread_t") + .getRawValue(thread_id, 1); return ret; } ompd_rc_t ompd_get_thread_num( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_word_t *val /* OUT: number of the thread within the team */ - ) -{ -// __kmp_threads[8]->th.th_info.ds.ds_tid + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_word_t *val /* OUT: number of the thread within the team */ + ) { + // __kmp_threads[8]->th.th_info.ds.ds_tid if (!thread_handle) return ompd_rc_stale_handle; if (!thread_handle->ah) @@ -1055,28 +1029,27 @@ ompd_rc_t ompd_get_thread_num( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - - ompd_rc_t ret = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ - cast("kmp_base_info_t"). - access("th_info"). /*__kmp_threads[t]->th.th_info*/ - cast("kmp_desc_t"). - access("ds"). /*__kmp_threads[t]->th.th_info.ds*/ - cast("kmp_desc_base_t"). - access("ds_tid"). /*__kmp_threads[t]->th.th_info.ds.ds_tid*/ - castBase(). - getValue(*val); + + ompd_rc_t ret = + TValue(context, thread_handle->th) /*__kmp_threads[t]->th*/ + .cast("kmp_base_info_t") + .access("th_info") /*__kmp_threads[t]->th.th_info*/ + .cast("kmp_desc_t") + .access("ds") /*__kmp_threads[t]->th.th_info.ds*/ + .cast("kmp_desc_base_t") + .access("ds_tid") /*__kmp_threads[t]->th.th_info.ds.ds_tid*/ + .castBase() + .getValue(*val); return ret; } - /* --- 7.2 OMPT Thread State Inquiry Analogue ------------------------------- */ -ompd_rc_t ompd_get_state ( - ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ - ompd_word_t *state, /* OUT: State of this thread */ - ompd_wait_id_t *wait_id /* OUT: Wait ID */ - ) -{ +ompd_rc_t ompd_get_state( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_word_t *state, /* OUT: State of this thread */ + ompd_wait_id_t *wait_id /* OUT: Wait ID */ + ) { if (!thread_handle) return ompd_rc_stale_handle; if (!thread_handle->ah) @@ -1088,36 +1061,36 @@ ompd_rc_t ompd_get_state ( return ompd_rc_needs_state_tracking; assert(callbacks && "Callback table not initialized!"); - - TValue ompt_thread_info = TValue(context, thread_handle->th). /*__kmp_threads[t]->th*/ - cast("kmp_base_info_t"). - access("ompt_thread_info"). /*__kmp_threads[t]->th.ompt_thread_info*/ - cast("ompt_thread_info_t"); + + TValue ompt_thread_info = + TValue(context, thread_handle->th) /*__kmp_threads[t]->th*/ + .cast("kmp_base_info_t") + .access("ompt_thread_info") /*__kmp_threads[t]->th.ompt_thread_info*/ + .cast("ompt_thread_info_t"); if (ompt_thread_info.gotError()) return ompt_thread_info.getError(); - ompd_rc_t ret = ompt_thread_info. - access("state"). /*__kmp_threads[t]->th.ompt_thread_info.state*/ - castBase(). - getValue(*state); - if ( ret != ompd_rc_ok ) + ompd_rc_t ret = + ompt_thread_info + .access("state") /*__kmp_threads[t]->th.ompt_thread_info.state*/ + .castBase() + .getValue(*state); + if (ret != ompd_rc_ok) return ret; - ret = ompt_thread_info. - access("wait_id"). /*__kmp_threads[t]->th.ompt_thread_info.state*/ - castBase(). - getValue(*wait_id); + ret = ompt_thread_info + .access("wait_id") /*__kmp_threads[t]->th.ompt_thread_info.state*/ + .castBase() + .getValue(*wait_id); return ret; -} - +} /* --- 8 Task Inquiry ------------------------------------------------------- */ /* --- 8.1 Task Settings ---------------------------------------------------- */ -ompd_rc_t ompd_get_max_threads( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: max number of threads */ - ) -{ +ompd_rc_t ompd_get_max_threads( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: max number of threads */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1127,23 +1100,22 @@ ompd_rc_t ompd_get_max_threads( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - - ompd_rc_t ret = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). // td - access("td_icvs"). // td->td_icvs - cast("kmp_internal_control_t", 0). - access("nproc"). // td->td_icvs.dynamic - castBase(). - getValue(*val); + + ompd_rc_t ret = TValue(context, task_handle->th) + .cast("kmp_taskdata_t") // td + .access("td_icvs") // td->td_icvs + .cast("kmp_internal_control_t", 0) + .access("nproc") // td->td_icvs.dynamic + .castBase() + .getValue(*val); return ret; } ompd_rc_t ompd_in_parallel( // Why do we need a task context for _in_parallel? - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: max number of threads */ - ) -{ + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: max number of threads */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1155,27 +1127,26 @@ ompd_rc_t ompd_in_parallel( // Why do we need a task context for _in_parallel? assert(callbacks && "Callback table not initialized!"); - ret = TValue(context, "__kmp_root"). // __kmp_root - cast("kmp_root_t",2). - dereference(). // (*__kmp_root) - access("r"). // (*__kmp_root)->r - cast("kmp_base_root_t"). - access("r_in_parallel"). // (*__kmp_root)->r.r_in_parallel - castBase(). - getValue(*val); - if ( ret != ompd_rc_ok ) + ret = TValue(context, "__kmp_root") // __kmp_root + .cast("kmp_root_t", 2) + .dereference() // (*__kmp_root) + .access("r") // (*__kmp_root)->r + .cast("kmp_base_root_t") + .access("r_in_parallel") // (*__kmp_root)->r.r_in_parallel + .castBase() + .getValue(*val); + if (ret != ompd_rc_ok) return ret; - if ( *val ) - *val=1; + if (*val) + *val = 1; return ret; } -ompd_rc_t ompd_in_final( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: max number of threads */ - ) -{ +ompd_rc_t +ompd_in_final(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: max number of threads */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1185,21 +1156,20 @@ ompd_rc_t ompd_in_final( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - - ompd_rc_t ret = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). // td - access("td_flags"). // td->td_icvs - cast("kmp_tasking_flags_t"). - check("final", val); // td->td_icvs.max_active_levels + + ompd_rc_t ret = TValue(context, task_handle->th) + .cast("kmp_taskdata_t") // td + .access("td_flags") // td->td_icvs + .cast("kmp_tasking_flags_t") + .check("final", val); // td->td_icvs.max_active_levels return ret; } -ompd_rc_t ompd_get_dynamic( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: max number of threads */ - ) -{ +ompd_rc_t +ompd_get_dynamic(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: max number of threads */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1209,23 +1179,22 @@ ompd_rc_t ompd_get_dynamic( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - - ompd_rc_t ret = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). // td - access("td_icvs"). // td->td_icvs - cast("kmp_internal_control_t", 0). - access("dynamic"). // td->td_icvs.dynamic - castBase(). - getValue(*val); + + ompd_rc_t ret = TValue(context, task_handle->th) + .cast("kmp_taskdata_t") // td + .access("td_icvs") // td->td_icvs + .cast("kmp_internal_control_t", 0) + .access("dynamic") // td->td_icvs.dynamic + .castBase() + .getValue(*val); return ret; } -ompd_rc_t ompd_get_nested( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: max number of threads */ - ) -{ +ompd_rc_t +ompd_get_nested(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: max number of threads */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1235,23 +1204,22 @@ ompd_rc_t ompd_get_nested( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - - ompd_rc_t ret = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). // td - access("td_icvs"). // td->td_icvs - cast("kmp_internal_control_t", 0). - access("nested"). // td->td_icvs.nested - castBase(). - getValue(*val); + + ompd_rc_t ret = TValue(context, task_handle->th) + .cast("kmp_taskdata_t") // td + .access("td_icvs") // td->td_icvs + .cast("kmp_internal_control_t", 0) + .access("nested") // td->td_icvs.nested + .castBase() + .getValue(*val); return ret; } ompd_rc_t ompd_get_max_active_levels( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: max number of threads */ - ) -{ + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: max number of threads */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1261,24 +1229,24 @@ ompd_rc_t ompd_get_max_active_levels( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - - ompd_rc_t ret = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). // td - access("td_icvs"). // td->td_icvs - cast("kmp_internal_control_t", 0). - access("max_active_levels"). // td->td_icvs.max_active_levels - castBase(). - getValue(*val); + + ompd_rc_t ret = + TValue(context, task_handle->th) + .cast("kmp_taskdata_t") // td + .access("td_icvs") // td->td_icvs + .cast("kmp_internal_control_t", 0) + .access("max_active_levels") // td->td_icvs.max_active_levels + .castBase() + .getValue(*val); return ret; } -ompd_rc_t ompd_get_schedule( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *kind, /* OUT: Kind of OpenMP schedule*/ - ompd_word_t *modifier /* OUT: Schedunling modifier */ - ) -{ +ompd_rc_t +ompd_get_schedule(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *kind, /* OUT: Kind of OpenMP schedule*/ + ompd_word_t *modifier /* OUT: Schedunling modifier */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1288,31 +1256,31 @@ ompd_rc_t ompd_get_schedule( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - - TValue sched = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). // td - access("td_icvs"). // td->td_icvs - cast("kmp_internal_control_t", 0). - access("sched"). // td->td_icvs.sched - cast("kmp_r_sched_t", 0); - - ompd_rc_t ret = sched.access("r_sched_type"). // td->td_icvs.sched.r_sched_type - castBase(). - getValue(*kind); - if ( ret != ompd_rc_ok ) + + TValue sched = TValue(context, task_handle->th) + .cast("kmp_taskdata_t") // td + .access("td_icvs") // td->td_icvs + .cast("kmp_internal_control_t", 0) + .access("sched") // td->td_icvs.sched + .cast("kmp_r_sched_t", 0); + + ompd_rc_t ret = sched + .access("r_sched_type") // td->td_icvs.sched.r_sched_type + .castBase() + .getValue(*kind); + if (ret != ompd_rc_ok) return ret; - ret = sched.access("chunk"). // td->td_icvs.sched.r_sched_type - castBase(). - getValue(*modifier); + ret = sched + .access("chunk") // td->td_icvs.sched.r_sched_type + .castBase() + .getValue(*modifier); return ret; - } -ompd_rc_t ompd_get_proc_bind( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *bind /* OUT: Kind of proc-binding */ - ) -{ +ompd_rc_t +ompd_get_proc_bind(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *bind /* OUT: Kind of proc-binding */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1322,23 +1290,22 @@ ompd_rc_t ompd_get_proc_bind( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - - ompd_rc_t ret = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). // td - access("td_icvs"). // td->td_icvs - cast("kmp_internal_control_t", 0). - access("proc_bind"). // td->td_icvs.proc_bind - castBase(). - getValue(*bind); + + ompd_rc_t ret = TValue(context, task_handle->th) + .cast("kmp_taskdata_t") // td + .access("td_icvs") // td->td_icvs + .cast("kmp_internal_control_t", 0) + .access("proc_bind") // td->td_icvs.proc_bind + .castBase() + .getValue(*bind); return ret; } -ompd_rc_t ompd_is_implicit( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_word_t *val /* OUT: max number of threads */ - ) -{ +ompd_rc_t +ompd_is_implicit(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: max number of threads */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1348,24 +1315,23 @@ ompd_rc_t ompd_is_implicit( return ompd_rc_stale_handle; assert(callbacks && "Callback table not initialized!"); - - ompd_rc_t ret = TValue(context, task_handle->th). - cast("kmp_taskdata_t"). // td - access("td_flags"). // td->td_flags - cast("kmp_tasking_flags_t"). - check("tasktype", val); // td->td_flags.tasktype - *val^=1; // tasktype: explicit = 1, implicit = 0 => invert the value + + ompd_rc_t ret = TValue(context, task_handle->th) + .cast("kmp_taskdata_t") // td + .access("td_flags") // td->td_flags + .cast("kmp_tasking_flags_t") + .check("tasktype", val); // td->td_flags.tasktype + *val ^= 1; // tasktype: explicit = 1, implicit = 0 => invert the value return ret; } /* --- 8.2 OMPT Task Inquiry Analogues -------------------------------------- */ ompd_rc_t ompd_get_task_frame( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_address_t *sp_exit, /* OUT: next frame is user code */ - ompd_address_t *sp_reentry /* OUT: previous frame is user code */ - ) -{ + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_address_t *sp_exit, /* OUT: next frame is user code */ + ompd_address_t *sp_reentry /* OUT: previous frame is user code */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1377,42 +1343,41 @@ ompd_rc_t ompd_get_task_frame( return ompd_rc_needs_state_tracking; assert(callbacks && "Callback table not initialized!"); - + TValue taskInfo; - if(task_handle->lwt.address!=0) - taskInfo = TValue(context, task_handle->lwt). - cast("ompt_lw_taskteam_t",0); /*lwt*/ + if (task_handle->lwt.address != 0) + taskInfo = + TValue(context, task_handle->lwt).cast("ompt_lw_taskteam_t", 0); /*lwt*/ else - taskInfo = TValue(context, task_handle->th). - cast("kmp_taskdata_t",0); /*t*/ - TValue frame = taskInfo. - access("ompt_task_info"). // td->ompt_task_info - cast("ompt_task_info_t"). - access("frame"). // td->ompd_task_info.frame - cast("ompt_frame_t", 0); + taskInfo = TValue(context, task_handle->th).cast("kmp_taskdata_t", 0); /*t*/ + TValue frame = taskInfo + .access("ompt_task_info") // td->ompt_task_info + .cast("ompt_task_info_t") + .access("frame") // td->ompd_task_info.frame + .cast("ompt_frame_t", 0); sp_reentry->segment = OMPD_SEGMENT_UNSPECIFIED; - ompd_rc_t ret = frame. - access("enter_frame"). // td->ompt_task_info.frame.enter_frame - castBase(). - getValue(sp_reentry->address); + ompd_rc_t ret = + frame + .access("enter_frame") // td->ompt_task_info.frame.enter_frame + .castBase() + .getValue(sp_reentry->address); - if ( ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) return ret; sp_exit->segment = OMPD_SEGMENT_UNSPECIFIED; - ret = frame. - access("exit_frame"). // td->ompt_task_info.frame.exit_frame - castBase(). - getValue(sp_exit->address); + ret = frame + .access("exit_frame") // td->ompt_task_info.frame.exit_frame + .castBase() + .getValue(sp_exit->address); return ret; } -ompd_rc_t ompd_get_task_data( - ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ - ompd_address_t *task_data /* OUT: OpenMP task ID */ - ) -{ +ompd_rc_t +ompd_get_task_data(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_address_t *task_data /* OUT: OpenMP task ID */ + ) { if (!task_handle) return ompd_rc_stale_handle; if (!task_handle->ah) @@ -1424,19 +1389,18 @@ ompd_rc_t ompd_get_task_data( return ompd_rc_needs_state_tracking; assert(callbacks && "Callback table not initialized!"); - + TValue taskInfo; - if(task_handle->lwt.address!=0) - taskInfo = TValue(context, task_handle->lwt). - cast("ompt_lw_taskteam_t",0); /*lwt*/ + if (task_handle->lwt.address != 0) + taskInfo = + TValue(context, task_handle->lwt).cast("ompt_lw_taskteam_t", 0); /*lwt*/ else - taskInfo = TValue(context, task_handle->th). - cast("kmp_taskdata_t",0); /*t*/ - ompd_rc_t ret = taskInfo. - access("ompt_task_info"). // td->ompt_task_info - cast("ompt_task_info_t"). - access("task_data"). // td->ompt_task_info.task_data - getAddress(task_data); + taskInfo = TValue(context, task_handle->th).cast("kmp_taskdata_t", 0); /*t*/ + ompd_rc_t ret = taskInfo + .access("ompt_task_info") // td->ompt_task_info + .cast("ompt_task_info_t") + .access("task_data") // td->ompt_task_info.task_data + .getAddress(task_data); return ret; } @@ -1490,64 +1454,58 @@ ompd_rc_t ompd_get_task_function( /* --- 9 OMPD Version and Compatibility Information ------------------------- */ -ompd_rc_t ompd_get_api_version ( - int *version - ) -{ +ompd_rc_t ompd_get_api_version(int *version) { *version = OMPD_VERSION; return ompd_rc_ok; } -ompd_rc_t ompd_get_api_version_string( - const char **string /* OUT: OMPD version string */ - ) -{ -/* static char version_string[256]={0}; - if(version_string[0]=='\0') - sprintf(version_string, "LLVM OpenMP %i.%i Debugging Library implemnting TR %i%c",OMPD_IMPLEMENTS_OPENMP, OMPD_IMPLEMENTS_OPENMP_SUBVERSION, OMPD_TR_VERSION, OMPD_TR_SUBVERSION);*/ - static const char version_string[] = "LLVM OpenMP " STR(OMPD_IMPLEMENTS_OPENMP) "." STR(OMPD_IMPLEMENTS_OPENMP_SUBVERSION) " Debugging Library implemnting TR " STR(OMPD_TR_VERSION) "" STR(OMPD_TR_SUBVERSION) ; +ompd_rc_t +ompd_get_api_version_string(const char **string /* OUT: OMPD version string */ + ) { + /* static char version_string[256]={0}; + if(version_string[0]=='\0') + sprintf(version_string, "LLVM OpenMP %i.%i Debugging Library implemnting + TR %i%c",OMPD_IMPLEMENTS_OPENMP, OMPD_IMPLEMENTS_OPENMP_SUBVERSION, + OMPD_TR_VERSION, OMPD_TR_SUBVERSION);*/ + static const char version_string[] = + "LLVM OpenMP " STR(OMPD_IMPLEMENTS_OPENMP) "." STR( + OMPD_IMPLEMENTS_OPENMP_SUBVERSION) " Debugging Library implemnting " + "TR " STR(OMPD_TR_VERSION) "" STR( + OMPD_TR_SUBVERSION); *string = version_string; return ompd_rc_ok; } /* --- 12 Display Control Variables ----------------------------------------- */ -ompd_rc_t ompd_get_display_control_vars ( - ompd_address_space_handle_t *handle, - const char * const **control_var_values -) -{ - static const char * const control_vars[] = {NULL}; +ompd_rc_t +ompd_get_display_control_vars(ompd_address_space_handle_t *handle, + const char *const **control_var_values) { + static const char *const control_vars[] = {NULL}; *control_var_values = control_vars; return ompd_rc_ok; } -ompd_rc_t ompd_release_display_control_vars ( - const char * const **control_var_values -) -{ +ompd_rc_t +ompd_release_display_control_vars(const char *const **control_var_values) { return ompd_rc_ok; } - - - /* --- Helper functions ----------------------------------------------------- */ -ompd_rc_t initTypeSizes(ompd_address_space_context_t *context) -{ - static int inited=0; +ompd_rc_t initTypeSizes(ompd_address_space_context_t *context) { + static int inited = 0; static ompd_rc_t ret; if (inited) return ret; ret = callbacks->tsizeof_prim(context, &type_sizes); - if (ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) return ret; - if (! (type_sizes.sizeof_pointer > 0) ) + if (!(type_sizes.sizeof_pointer > 0)) return ompd_rc_error; ret = callbacks->tsizeof_prim(context, &TValue::type_sizes); - if (ret != ompd_rc_ok ) + if (ret != ompd_rc_ok) return ret; - inited=1; + inited = 1; return ret; } diff --git a/libompd/src/omp-debug.h b/libompd/src/omp-debug.h index cebf5a337..f7ff8a3da 100644 --- a/libompd/src/omp-debug.h +++ b/libompd/src/omp-debug.h @@ -10,83 +10,76 @@ #ifndef SRC_OMPD_INTEL_H_ #define SRC_OMPD_INTEL_H_ -#ifdef __cplusplus +#ifdef __cplusplus #include //#include -//void* operator new(std::size_t size) /*throw (std::bad_alloc)*/; -//void* operator new[](std::size_t size) /*throw (std::bad_alloc)*/; -//void operator delete(void* addr) throw (); -//void operator delete[](void* addr) throw (); +// void* operator new(std::size_t size) /*throw (std::bad_alloc)*/; +// void* operator new[](std::size_t size) /*throw (std::bad_alloc)*/; +// void operator delete(void* addr) throw (); +// void operator delete[](void* addr) throw (); extern "C" { #endif - #define OMPD_IMPLEMENTS_OPENMP 3 #define OMPD_IMPLEMENTS_OPENMP_SUBVERSION 1 #define OMPD_TR_VERSION 6 #define OMPD_TR_SUBVERSION 'j' -#define OMPD_VERSION (OMPD_IMPLEMENTS_OPENMP << 24) + (OMPD_IMPLEMENTS_OPENMP_SUBVERSION << 16) + (OMPD_TR_VERSION << 8) + OMPD_TR_SUBVERSION +#define OMPD_VERSION \ + (OMPD_IMPLEMENTS_OPENMP << 24) + (OMPD_IMPLEMENTS_OPENMP_SUBVERSION << 16) + \ + (OMPD_TR_VERSION << 8) + OMPD_TR_SUBVERSION #define STR_HELPER(x) #x #define STR(x) STR_HELPER(x) - + #include "ompd.h" /****************************************************************************** * General helper functions */ ompd_rc_t initTypeSizes(ompd_address_space_context_t *context); -//uint32_t getThreadLevel(ompd_context_t *context, int t); +// uint32_t getThreadLevel(ompd_context_t *context, int t); /*int getNumberOfOMPThreads(ompd_context_t *context); uint64_t getSystemThreadID(ompd_context_t *context, int t); int64_t getOmpThreadID(ompd_context_t *context);*/ - -#ifdef __cplusplus +#ifdef __cplusplus } #endif - typedef struct _ompd_address_space_context_s ompd_address_space_context_t; -typedef struct _ompd_process_handle_s -{ - ompd_address_space_context_t* context; +typedef struct _ompd_process_handle_s { + ompd_address_space_context_t *context; } ompd_process_handle_t; -typedef struct _ompd_address_space_handle_s -{ - ompd_address_space_context_t* context; +typedef struct _ompd_address_space_handle_s { + ompd_address_space_context_t *context; ompd_device_kind_t kind; ompd_device_identifier_t id; } ompd_address_space_handle_t; typedef struct _ompd_device_handle_s { - ompd_address_space_handle_t* ah; + ompd_address_space_handle_t *ah; ompd_address_t th; /* target handle */ } ompd_device_handle_t; -typedef struct _ompd_thread_handle_s -{ - ompd_address_space_handle_t* ah; +typedef struct _ompd_thread_handle_s { + ompd_address_space_handle_t *ah; ompd_address_t th; /* target handle */ } ompd_thread_handle_t; -typedef struct _ompd_parallel_handle_s -{ - ompd_address_space_handle_t* ah; - ompd_address_t th; /* target handle */ +typedef struct _ompd_parallel_handle_s { + ompd_address_space_handle_t *ah; + ompd_address_t th; /* target handle */ ompd_address_t lwt; /* lwt handle */ } ompd_parallel_handle_t; -typedef struct _ompd_task_handle_s -{ - ompd_address_space_handle_t* ah; - ompd_address_t th; /* target handle */ +typedef struct _ompd_task_handle_s { + ompd_address_space_handle_t *ah; + ompd_address_t th; /* target handle */ ompd_address_t lwt; /* lwt handle */ } ompd_task_handle_t; - #endif /* SRC_OMPD_INTEL_H_ */ diff --git a/libompd/src/ompd_test.c b/libompd/src/ompd_test.c index cff8da96a..92609a66a 100644 --- a/libompd/src/ompd_test.c +++ b/libompd/src/ompd_test.c @@ -11,14 +11,13 @@ * It can be used as a template to implement (runtime-specific) OMPD DLLs. */ -#include #include "ompd_test.h" #include "assert.h" +#include static ompd_callbacks_t *callbacks = NULL; -ompd_rc_t ompd_initialize (ompd_callbacks_t *table) -{ +ompd_rc_t ompd_initialize(ompd_callbacks_t *table) { ompd_rc_t ret = table ? ompd_rc_ok : ompd_rc_bad_input; callbacks = table; return ret; @@ -31,13 +30,9 @@ ompd_rc_t ompd_initialize (ompd_callbacks_t *table) * debugger. The test routines start with "test_CB_". */ -void test_print_header() -{ - printf("\n*** OMPD Test ***\n"); -} +void test_print_header() { printf("\n*** OMPD Test ***\n"); } -void test_CB_dmemory_alloc() -{ +void test_CB_dmemory_alloc() { assert(callbacks && "Invalid callbacks table"); test_print_header(); @@ -59,23 +54,20 @@ void test_CB_dmemory_alloc() printf("Failed!\n"); } -void test_CB_tsizeof_prim() -{ +void test_CB_tsizeof_prim() { assert(callbacks && "Invalid callbacks table"); test_print_header(); ompd_rc_t ret; ompd_target_type_sizes_t sizes; ret = callbacks->tsizeof_prim((ompd_context_t *)1, &sizes); - if (ret == ompd_rc_ok) - { + if (ret == ompd_rc_ok) { printf("%-20s %du\n", "Size of char:", sizes.sizeof_char); printf("%-20s %du\n", "Size of short:", sizes.sizeof_short); printf("%-20s %du\n", "Size of int:", sizes.sizeof_int); printf("%-20s %du\n", "Size of long:", sizes.sizeof_long); printf("%-20s %du\n", "Size of long long:", sizes.sizeof_long_long); printf("%-20s %du\n", "Size of pointer:", sizes.sizeof_pointer); - } - else + } else printf("Failed getting primitive sizes\n"); } diff --git a/libompd/src/ompd_test.h b/libompd/src/ompd_test.h index 009ed7741..bb0f5e636 100644 --- a/libompd/src/ompd_test.h +++ b/libompd/src/ompd_test.h @@ -8,7 +8,7 @@ #ifndef SRC_OMPD_TEST_H_ #define SRC_OMPD_TEST_H_ -#ifdef __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -23,7 +23,7 @@ void test_print_header(); void test_CB_dmemory_alloc(); void test_CB_tsizeof_prim(); -#ifdef __cplusplus +#ifdef __cplusplus } #endif #endif /* SRC_OMPD_TEST_H_ */ From 5307609bed994ac694b6c47b0e143f0424566590 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Sun, 11 Feb 2018 09:31:46 +0100 Subject: [PATCH 35/46] Use class overload of new operator to not overload the new operator of the tool. --- libompd/src/omp-debug.cpp | 32 +------------------- libompd/src/omp-debug.h | 61 +++++++++++++++++++++++++++------------ 2 files changed, 43 insertions(+), 50 deletions(-) diff --git a/libompd/src/omp-debug.cpp b/libompd/src/omp-debug.cpp index 59a53e9c1..8d6c527f4 100644 --- a/libompd/src/omp-debug.cpp +++ b/libompd/src/omp-debug.cpp @@ -8,7 +8,7 @@ * protze@llnl.gov */ /******************************************************************************* - * This implements an OMPD DLL the Intel runtime library. + * This implements an OMPD DLL for the LLVM OpenMP runtime library. */ #define NDEBUG 1 @@ -24,39 +24,9 @@ #include #include -const ompd_callbacks_t *callbacks = NULL; ompd_target_type_sizes_t type_sizes; uint64_t ompd_state; -// void* operator new(std::size_t size) /*throw (std::bad_alloc)*/ -/*{ - void* res; - ompd_rc_t ret = callbacks->dmemory_alloc(size, &res); - if (ret==ompd_rc_ok) - return res; - throw std::bad_alloc(); -}*/ -// void* operator new[](std::size_t size) /*throw (std::bad_alloc)*/ -/*{ - void* res; - ompd_rc_t ret = callbacks->dmemory_alloc(size, &res); - if (ret==ompd_rc_ok) - return res; - throw std::bad_alloc(); -} -void operator delete(void* addr) throw () -{ - ompd_rc_t ret = callbacks->dmemory_free(addr); - if (ret!=ompd_rc_ok) - throw std::bad_alloc(); -} -void operator delete[](void* addr) throw () -{ - ompd_rc_t ret = callbacks->dmemory_free(addr); - if (ret!=ompd_rc_ok) - throw std::bad_alloc(); -}*/ - /* --- OMPD functions ------------------------------------------------------- */ /* --- 3 Initialization ----------------------------------------------------- */ diff --git a/libompd/src/omp-debug.h b/libompd/src/omp-debug.h index f7ff8a3da..223df2432 100644 --- a/libompd/src/omp-debug.h +++ b/libompd/src/omp-debug.h @@ -7,17 +7,13 @@ * Contact: ilaguna@llnl.gov * protze@llnl.gov */ -#ifndef SRC_OMPD_INTEL_H_ -#define SRC_OMPD_INTEL_H_ +#ifndef SRC_OMP_DEBUG_H_ +#define SRC_OMP_DEBUG_H_ #ifdef __cplusplus #include -//#include -// void* operator new(std::size_t size) /*throw (std::bad_alloc)*/; -// void* operator new[](std::size_t size) /*throw (std::bad_alloc)*/; -// void operator delete(void* addr) throw (); -// void operator delete[](void* addr) throw (); +#include extern "C" { #endif @@ -39,47 +35,74 @@ extern "C" { * General helper functions */ ompd_rc_t initTypeSizes(ompd_address_space_context_t *context); -// uint32_t getThreadLevel(ompd_context_t *context, int t); -/*int getNumberOfOMPThreads(ompd_context_t *context); -uint64_t getSystemThreadID(ompd_context_t *context, int t); -int64_t getOmpThreadID(ompd_context_t *context);*/ #ifdef __cplusplus } -#endif + +static const ompd_callbacks_t *callbacks = NULL; + +class ompdAllocatable { +public: + static void *operator new(std::size_t sz) { + void *res; + ompd_rc_t ret = callbacks->dmemory_alloc(sz, &res); + if (ret == ompd_rc_ok) + return res; + throw std::bad_alloc(); + } + static void *operator new[](std::size_t sz) { + void *res; + ompd_rc_t ret = callbacks->dmemory_alloc(sz, &res); + if (ret == ompd_rc_ok) + return res; + throw std::bad_alloc(); + } + void operator delete(void *addr) throw() { + ompd_rc_t ret = callbacks->dmemory_free(addr); + if (ret != ompd_rc_ok) + throw std::bad_alloc(); + } + void operator delete[](void *addr) throw() { + ompd_rc_t ret = callbacks->dmemory_free(addr); + if (ret != ompd_rc_ok) + throw std::bad_alloc(); + } +}; typedef struct _ompd_address_space_context_s ompd_address_space_context_t; -typedef struct _ompd_process_handle_s { +typedef struct _ompd_process_handle_s : public ompdAllocatable { ompd_address_space_context_t *context; } ompd_process_handle_t; -typedef struct _ompd_address_space_handle_s { +typedef struct _ompd_address_space_handle_s : public ompdAllocatable { ompd_address_space_context_t *context; ompd_device_kind_t kind; ompd_device_identifier_t id; } ompd_address_space_handle_t; -typedef struct _ompd_device_handle_s { +typedef struct _ompd_device_handle_s : public ompdAllocatable { ompd_address_space_handle_t *ah; ompd_address_t th; /* target handle */ } ompd_device_handle_t; -typedef struct _ompd_thread_handle_s { +typedef struct _ompd_thread_handle_s : public ompdAllocatable { ompd_address_space_handle_t *ah; ompd_address_t th; /* target handle */ } ompd_thread_handle_t; -typedef struct _ompd_parallel_handle_s { +typedef struct _ompd_parallel_handle_s : public ompdAllocatable { ompd_address_space_handle_t *ah; ompd_address_t th; /* target handle */ ompd_address_t lwt; /* lwt handle */ } ompd_parallel_handle_t; -typedef struct _ompd_task_handle_s { +typedef struct _ompd_task_handle_s : public ompdAllocatable { ompd_address_space_handle_t *ah; ompd_address_t th; /* target handle */ ompd_address_t lwt; /* lwt handle */ } ompd_task_handle_t; -#endif /* SRC_OMPD_INTEL_H_ */ +#endif + +#endif /* SRC_OMP_DEBUG_H_ */ From cc25dceb10be47a08fe787bf6a4c1de22c94afe2 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Mon, 12 Feb 2018 11:07:40 +0100 Subject: [PATCH 36/46] Add missing ompd.h file, add runtime version function --- libompd/src/omp-debug.cpp | 44 +- libompd/src/omp-debug.h | 2 + libompd/src/ompd.h | 911 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 948 insertions(+), 9 deletions(-) create mode 100644 libompd/src/ompd.h diff --git a/libompd/src/omp-debug.cpp b/libompd/src/omp-debug.cpp index 8d6c527f4..18356e071 100644 --- a/libompd/src/omp-debug.cpp +++ b/libompd/src/omp-debug.cpp @@ -14,6 +14,7 @@ #define NDEBUG 1 #include "omp-debug.h" +#include "omp.h" #include "ompd.h" // #include #include "TargetValue.h" @@ -78,6 +79,37 @@ ompd_process_initialize(ompd_address_space_context_t return ompd_rc_ok; } +ompd_rc_t +ompd_get_openmp_version(ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + ompd_word_t *version) { + if (!addr_handle) + return ompd_rc_stale_handle; + ompd_address_space_context_t *context = addr_handle->context; + ompd_rc_t ret; + + if (!context) + return ompd_rc_stale_handle; + + assert(callbacks && "Callback table not initialized!"); + + ret = TValue(context, "__kmp_openmp_version") + .castBase(ompd_type_int) + .getValue(*version); + return ret; +} + +ompd_rc_t ompd_get_openmp_version_string( + ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + const char **string) { + if (!addr_handle) + return ompd_rc_bad_input; + static const char *omp_version = ""; + *string = omp_version; + return ompd_rc_ok; +} + ompd_rc_t ompd_release_address_space_handle( ompd_address_space_handle_t *addr_handle /* IN: handle for the address space */ @@ -1424,7 +1456,7 @@ ompd_rc_t ompd_get_task_function( /* --- 9 OMPD Version and Compatibility Information ------------------------- */ -ompd_rc_t ompd_get_api_version(int *version) { +ompd_rc_t ompd_get_api_version(ompd_word_t *version) { *version = OMPD_VERSION; return ompd_rc_ok; } @@ -1432,16 +1464,10 @@ ompd_rc_t ompd_get_api_version(int *version) { ompd_rc_t ompd_get_api_version_string(const char **string /* OUT: OMPD version string */ ) { - /* static char version_string[256]={0}; - if(version_string[0]=='\0') - sprintf(version_string, "LLVM OpenMP %i.%i Debugging Library implemnting - TR %i%c",OMPD_IMPLEMENTS_OPENMP, OMPD_IMPLEMENTS_OPENMP_SUBVERSION, - OMPD_TR_VERSION, OMPD_TR_SUBVERSION);*/ static const char version_string[] = "LLVM OpenMP " STR(OMPD_IMPLEMENTS_OPENMP) "." STR( - OMPD_IMPLEMENTS_OPENMP_SUBVERSION) " Debugging Library implemnting " - "TR " STR(OMPD_TR_VERSION) "" STR( - OMPD_TR_SUBVERSION); + OMPD_IMPLEMENTS_OPENMP_SUBVERSION) " Debugging Library implmenting " + "TR " STR(OMPD_TR_VERSION) "" STR(OMPD_TR_SUBVERSION); *string = version_string; return ompd_rc_ok; } diff --git a/libompd/src/omp-debug.h b/libompd/src/omp-debug.h index 223df2432..a4cd8f785 100644 --- a/libompd/src/omp-debug.h +++ b/libompd/src/omp-debug.h @@ -15,6 +15,8 @@ #include #include +#define OMPD_DLL_VERSION 201811; + extern "C" { #endif diff --git a/libompd/src/ompd.h b/libompd/src/ompd.h new file mode 100644 index 000000000..25514bcc6 --- /dev/null +++ b/libompd/src/ompd.h @@ -0,0 +1,911 @@ +/* + * ompd.h + * + * Created on: Dec 22, 2014 + * Author: Ignacio Laguna + * Joachim Protze + * Contact: ilaguna@llnl.gov + * protze@llnl.gov + */ +#ifndef SRC_OMPD_H_ +#define SRC_OMPD_H_ + +/****************************************************************************** + * This header file defines the OMPD interface: an interface to help debuggers + * to inspect state associated with OpenMP programming abstractions in a target + * process. The interface is implemented in a dynamically loaded library (DLL) + * that the debugger loads into its address space. + * + * Name conventions: + * - All named entities start with the prefix "ompd_" (for OpenMP debugging) + * - Type entities end with the suffix "_t" (for type) + * - Function types end with the suffix "_fn_t" (for function type) + * - Return code entities have "_rc_" in it + * - Abstractions referring to the target have the prefix "t" (e.g., + * "tmemory" for memory in the target, or "tsymbol" for symbol in the target) + * - Abstractions referring to the debugger have the prefix "d" (e.g., + * "dmemory" for memory in the debugger) + * + * Comment conventions: + * - Input function parameters denoted by "IN:" + * - Output function parameters denoted by "OUT:" + */ + +#include +//#include "omp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * General types and data structures + */ + +/** + * Basic types. + */ +typedef uint64_t ompd_addr_t; /* unsigned integer large enough */ + /* to hold a target address or a */ + /* target segment value */ +typedef int64_t ompd_word_t; /* signed version of ompd_addr_t */ +typedef uint64_t ompd_seg_t; +typedef uint64_t ompd_wait_id_t; /* identifies what a thread is */ + /* waiting for */ +typedef uint64_t ompd_size_t; /* For sizes (e.g., size_t) */ + +typedef struct ompd_address_t { + ompd_seg_t segment; /* target architecture specific */ + /* segment value */ + ompd_addr_t address; /* target address in the segment */ +} ompd_address_t; + +#define OMPD_SEGMENT_UNSPECIFIED ((ompd_seg_t)0) +#define OMPD_SEGMENT_TEXT ((ompd_seg_t)1) +#define OMPD_SEGMENT_DATA ((ompd_seg_t)2) + +/** + * The following definitions match with ptx information stored in DWARF + */ +#define OMPD_SEGMENT_CUDA_PTX_UNSPECIFIED ((ompd_seg_t)0) +#define OMPD_SEGMENT_CUDA_PTX_CODE ((ompd_seg_t)1) +#define OMPD_SEGMENT_CUDA_PTX_REG ((ompd_seg_t)2) +#define OMPD_SEGMENT_CUDA_PTX_SREG ((ompd_seg_t)3) +#define OMPD_SEGMENT_CUDA_PTX_CONST ((ompd_seg_t)4) +#define OMPD_SEGMENT_CUDA_PTX_GLOBAL ((ompd_seg_t)5) +#define OMPD_SEGMENT_CUDA_PTX_LOCAL ((ompd_seg_t)6) +#define OMPD_SEGMENT_CUDA_PTX_PARAM ((ompd_seg_t)7) +#define OMPD_SEGMENT_CUDA_PTX_SHARED ((ompd_seg_t)8) +#define OMPD_SEGMENT_CUDA_PTX_SURF ((ompd_seg_t)9) +#define OMPD_SEGMENT_CUDA_PTX_TEX ((ompd_seg_t)10) +#define OMPD_SEGMENT_CUDA_PTX_TEXSAMPLER ((ompd_seg_t)11) +#define OMPD_SEGMENT_CUDA_PTX_GENERIC ((ompd_seg_t)12) +#define OMPD_SEGMENT_CUDA_PTX_IPARAM ((ompd_seg_t)13) +#define OMPD_SEGMENT_CUDA_PTX_OPARAM ((ompd_seg_t)14) +#define OMPD_SEGMENT_CUDA_PTX_FRAME ((ompd_seg_t)15) +#define OMPD_SEGMENT_CUDA_PTX_MAX ((ompd_seg_t)16) + +#if 0 // types removed in Austin F2F +/* + * Definition of OMPD states, taken from OMPT + */ +#define FOREACH_OMPD_STATE(macro) \ + \ + /* first */ \ + macro(ompd_state_first, 0x71) /* initial enumeration state */ \ + \ + /* work states (0..15) */ \ + macro(ompd_state_work_serial, 0x00) /* working outside parallel */ \ + macro(ompd_state_work_parallel, 0x01) /* working within parallel */ \ + macro(ompd_state_work_reduction, 0x02) /* performing a reduction */ \ + \ + /* idle (16..31) */ \ + macro(ompd_state_idle, 0x10) /* waiting for work */ \ + \ + /* overhead states (32..63) */ \ + macro(ompd_state_overhead, 0x20) /* overhead excluding wait states */ \ + \ + /* barrier wait states (64..79) */ \ + macro(ompd_state_wait_barrier, 0x40) /* waiting at a barrier */ \ + macro(ompd_state_wait_barrier_implicit, 0x41) /* implicit barrier */ \ + macro(ompd_state_wait_barrier_explicit, 0x42) /* explicit barrier */ \ + \ + /* task wait states (80..95) */ \ + macro(ompd_state_wait_taskwait, 0x50) /* waiting at a taskwait */ \ + macro(ompd_state_wait_taskgroup, 0x51) /* waiting at a taskgroup */ \ + \ + /* mutex wait states (96..111) */ \ + macro(ompd_state_wait_lock, 0x60) /* waiting for lock */ \ + macro(ompd_state_wait_nest_lock, 0x61) /* waiting for nest lock */ \ + macro(ompd_state_wait_critical, 0x62) /* waiting for critical */ \ + macro(ompd_state_wait_atomic, 0x63) /* waiting for atomic */ \ + macro(ompd_state_wait_ordered, 0x64) /* waiting for ordered */ \ + macro(ompd_state_wait_single, \ + 0x6F) /* waiting for single region (non-standard!) */ \ + \ + /* misc (112..127) */ \ + macro(ompd_state_undefined, 0x70) /* undefined thread state */ + +typedef enum ompd_state_t { +#define ompd_state_macro(state, code) state = code, + FOREACH_OMPD_STATE(ompd_state_macro) +#undef ompd_state_macro +} ompd_state_t; + +typedef enum ompd_sched_t { + ompd_sched_static = 1, + ompd_sched_dynamic = 2, + ompd_sched_guided = 3, + ompd_sched_auto = 4, + ompd_sched_vendor_lo = 5, + ompd_sched_vendor_hi = 0x7fffffff +} ompd_sched_t; + +typedef enum ompd_proc_bind_t { + ompd_proc_bind_false = 0, + ompd_proc_bind_true = 1, + ompd_proc_bind_master = 2, + ompd_proc_bind_close = 3, + ompd_proc_bind_spread = 4 +} ompd_proc_bind_t; +#endif + +typedef uint64_t ompd_device_identifier_t; + +typedef enum ompd_device_kind_t { + ompd_device_kind_host = 1, + ompd_device_kind_cuda = 2 +} ompd_device_kind_t; + +/** + * Context handle. + * This is used by the debugger to identify a target process (or core file). + * This will be cast to concrete types within the debugger. The callbacks use + * context handles to specify the debugger where to look up (since the debugger + * can be handling different contexts at the same time, e.g., processes and/or + * core files). Without context handles the debugger would not know the target + * of a callback request. + */ + +typedef struct _ompd_address_space_context_s ompd_address_space_context_t; +typedef struct _ompd_thread_context_s ompd_thread_context_t; + +/** + * OpenMP abstractions handles. + * Each operation in the OMPD interface must explicitly specify a handle for the + * context of the operation. OMPD uses context handles for OpenMP entities, such + * as threads, parallel regions, and tasks. A handle for an entity is constant + * while the entity itself is live. + */ + +typedef struct _ompd_device_handle_s ompd_device_handle_t; +typedef struct _ompd_thread_handle_s ompd_thread_handle_t; +typedef struct _ompd_parallel_handle_s ompd_parallel_handle_t; +typedef struct _ompd_task_handle_s ompd_task_handle_t; +typedef struct _ompd_address_space_handle_s ompd_address_space_handle_t; + +/** + * Other handles. + */ +#define OMPD_THREAD_ID_PTHREAD 0 +#define OMPD_THREAD_ID_LWP 1 +#define OMPD_THREAD_ID_WINTHREAD 2 +#define OMPD_THREAD_ID_CUDALOGICAL 3 +#define OMPD_THREAD_ID_MAX 4 + +typedef enum ompd_thread_id_kind_t { + ompd_thread_id_pthread = 0, + ompd_thread_id_lwp = 1, + ompd_thread_id_winthread = 2, + ompd_thread_id_cudalogical = 3 +} ompd_thread_id_kind_t; + +/** + * Logical coordinates of OMP target device threads + */ +typedef struct ompd_dim3_t { + ompd_word_t x; + ompd_word_t y; + ompd_word_t z; +} ompd_dim3_t; + +typedef struct ompd_cudathread_coord_t { + ompd_addr_t cudaDevId; + ompd_addr_t cudaContext; + ompd_addr_t warpSize; + ompd_addr_t gridId; + ompd_addr_t kernelId; // TODO (MJM) - for some reason, cuda-gdb doesn't work + // with grids too well. + ompd_dim3_t gridDim; + ompd_dim3_t blockDim; + ompd_dim3_t blockIdx; + ompd_dim3_t threadIdx; +} ompd_cudathread_coord_t; + +/** + * Return codes. + * Each OMPD operation returns a code. + */ +typedef enum ompd_rc_t { + ompd_rc_ok = 0, /* operation was successful */ + ompd_rc_unavailable = 1, /* info is not available (in this context) */ + ompd_rc_stale_handle = 2, /* handle is no longer valid */ + ompd_rc_bad_input = 3, /* bad input parameters (other than handle) */ + ompd_rc_error = 4, /* error */ + ompd_rc_unsupported = 5, /* operation is not supported */ + ompd_rc_needs_state_tracking = 6, /* needs runtime state tracking enabled */ + ompd_rc_incompatible = 7, /* target is not compatible with this OMPD */ + ompd_rc_target_read_error = 8, /* error reading from the target */ + ompd_rc_target_write_error = 9, /* error writing from the target */ + ompd_rc_nomem = 10 /* unable to allocate memory */ +} ompd_rc_t; + +/** + * Primitive types. + */ +typedef enum ompd_target_prim_types_t { + ompd_type_invalid = -1, + ompd_type_char = 0, + ompd_type_short = 1, + ompd_type_int = 2, + ompd_type_long = 3, + ompd_type_long_long = 4, + ompd_type_pointer = 5, + ompd_type_max +} ompd_target_prim_types_t; + +/** + * Primitive type sizes. + * These types are used by OMPD to interrogate the debugger about the size of + * primitive types in the target. + */ +typedef struct ompd_target_type_sizes_t { + uint8_t sizeof_char; + uint8_t sizeof_short; + uint8_t sizeof_int; + uint8_t sizeof_long; + uint8_t sizeof_long_long; + uint8_t sizeof_pointer; +} ompd_device_type_sizes_t; + +/****************************************************************************** + * Debugger callback signatures. + * These callback function signatures are used by OMPD to obtain state + * information of a target process, in particular to interrogate about info + * that is dependent on a particular OpenMP runtime library. Typical queries are + * sizes of primitive types in the target, symbols lookup, lookup of offsets of + * fields in a type/structure, and read/write to memory in the target. + */ + +/** + * Allocate memory in the debugger's address space. + */ +typedef ompd_rc_t (*ompd_dmemory_alloc_fn_t)( + ompd_size_t bytes, /* IN: bytes of the primitive type */ + void **ptr /* OUT: pointer of the allocated memory */ + ); + +/** + * Free memory in the debugger's address space. + */ +typedef ompd_rc_t (*ompd_dmemory_free_fn_t)( + void *ptr /* IN: pointer of memory to deallocate */ + ); + +/** + * Get thread specific context. + */ +typedef ompd_rc_t (*ompd_get_thread_context_for_thread_id_fn_t)( + ompd_address_space_context_t *context, ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, const void *thread_id, + ompd_thread_context_t **thread_context); + +#if 0 +/** + * Get containing (host) process context for address_space_context + */ +typedef ompd_rc_t (*ompd_get_process_context_for_context_fn_t) ( + ompd_address_space_context_t* + address_space_context, /* IN: OMP device/process addr space */ + ompd_address_space_context_t** + containing_address_space_context /* OUT: Containing omp process addr space */ +); +#endif + +/** + * Look up the sizes of primitive types in the target + */ +typedef ompd_rc_t (*ompd_tsizeof_prim_fn_t)( + ompd_address_space_context_t + *context, /* IN: debugger handle for the target */ + ompd_target_type_sizes_t *sizes /* OUT: type sizes */ + ); + +/** + * Look up the address of a global symbol in the target + */ +typedef ompd_rc_t (*ompd_tsymbol_addr_fn_t)( + ompd_address_space_context_t + *context, /* IN: debugger handle for the target */ + ompd_thread_context_t + *tcontext, /* IN: debugger handle for a target thread might be NULL */ + const char *symbol_name, /* IN: global symbol name */ + ompd_address_t *symbol_addr /* OUT: symbol address */ + ); + +/** + * Read memory from the target + */ +typedef ompd_rc_t (*ompd_tmemory_read_fn_t)( + ompd_address_space_context_t + *context, /* IN: debugger handle for the target */ + ompd_thread_context_t + *tcontext, /* IN: debugger handle for a target thread might be NULL */ + ompd_address_t addr, /* IN: address in the target */ + ompd_word_t nbytes, /* IN: number of items to read */ + void *buffer /* OUT: output buffer */ + ); + +/** + * Write memory from the target + */ +typedef ompd_rc_t (*ompd_tmemory_write_fn_t)( + ompd_address_space_context_t + *context, /* IN: debugger handle for the target */ + ompd_thread_context_t + *tcontext, /* IN: debugger handle for a target thread might be NULL */ + ompd_address_t addr, /* IN: address in the target */ + ompd_word_t nbytes, /* IN: number of items to write */ + const void *buffer /* IN: output buffer */ + ); + +typedef ompd_rc_t (*ompd_target_host_fn_t)( + ompd_address_space_context_t *address_space_context, /* IN */ + const void *input, /* IN */ + int unit_size, /* IN */ + int count, /* IN: number of primitive type */ + /* items to process */ + void *output /* OUT */ + ); + +/** + * This is used by the OMPD library to have the debugger print a string. + * The OMPD should not print directly. + */ +typedef ompd_rc_t (*ompd_print_string_fn_t)( + const char *str /* IN: message to print */ + ); + +/** + * Callbacks table. + */ +typedef struct ompd_callbacks_t { + /* Debugger interface */ + ompd_dmemory_alloc_fn_t dmemory_alloc; + ompd_dmemory_free_fn_t dmemory_free; + ompd_print_string_fn_t print_string; + + /* Target interface */ + ompd_tsizeof_prim_fn_t tsizeof_prim; + ompd_tsymbol_addr_fn_t tsymbol_addr; + ompd_tmemory_read_fn_t read_tmemory; + ompd_tmemory_write_fn_t write_tmemory; + + ompd_target_host_fn_t target_to_host; + ompd_target_host_fn_t host_to_target; + + ompd_get_thread_context_for_thread_id_fn_t get_thread_context_for_thread_id; + // ompd_get_process_context_for_context_fn_t get_containing_process_context; + +} ompd_callbacks_t; + +/****************************************************************************** + * Call signatures from the debugger to the OMPD DLL. + */ + +/* --- 4 Initialization ----------------------------------------------------- */ + +/** + * The OMPD function ompd_get_version_string returns a descriptive string + * describing an implementation of the OMPD library. The function + * ompd_get_version_compatibility returns an integer code used to indicate the + * revision of the OMPD specification supported by an implementation of OMPD. + */ + +ompd_rc_t ompd_get_api_version(ompd_word_t *version); + +ompd_rc_t +ompd_get_api_version_string(const char **string /* OUT: OMPD version string */ + ); + +/** + * Initialize OMPD. + * This provides the DLL the pointers to the debugger's functions to obtain + * information about the OpenMP runtime library. The debugger promises to + * maintain the functions valid for as long as needed. + */ +ompd_rc_t +ompd_initialize(const ompd_callbacks_t *table, /* IN: callbacks table */ + ompd_word_t version); + +ompd_rc_t +ompd_process_initialize(ompd_address_space_context_t + *context, /* IN: debugger handle for the target */ + ompd_address_space_handle_t * + *addrhandle /* OUT: ompd handle for the target */ + ); + +ompd_rc_t +ompd_get_openmp_version(ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + ompd_word_t *version); + +ompd_rc_t ompd_get_openmp_version_string( + ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + const char **string); + +ompd_rc_t ompd_release_address_space_handle( + ompd_address_space_handle_t + *addr_handle /* IN: handle for the address space */ + ); + +ompd_rc_t ompd_device_initialize( + ompd_address_space_context_t + *context, /* IN: debugger handle for the device */ + ompd_device_identifier_t id, /* IN: object defined by native device API */ + ompd_device_kind_t kind, /* IN: */ + ompd_address_space_handle_t * + *addrhandle /* OUT: ompd handle for the device */ + ); + +ompd_rc_t ompd_finalize(void); +/* --- 4 Handle Management -------------------------------------------------- */ + +/* --- 4.1 Thread Handles --------------------------------------------------- */ + +/** + * Retrieve handles for all OpenMP threads. + * + * The ompd_get_threads operation enables the debugger to obtain handles for all + * OpenMP threads. A successful invocation of ompd_get_threads returns a pointer + * to a vector of handles in thread_handle_array and returns the number of + * handles in num_handles. This call yields meaningful results only if all + * OpenMP threads are stopped; otherwise, the OpenMP runtime may be creating + * and/or destroying threads during or after the call, rendering useless the + * vector of handles returned. + */ +#if 0 +ompd_rc_t ompd_get_threads ( + ompd_address_space_handle_t *addr_handle, /* IN: handle for the address space */ + ompd_thread_handle_t ***thread_handle_array, /* OUT: array of handles */ + int *num_handles /* OUT: number of handles in the array */ + ); +#endif +/** + * Retrieve handles for OpenMP threads in a parallel region. + * + * The ompd_get_thread_in_parallel operation enables the debugger to obtain + * handles for all OpenMP threads associated with a parallel region. A + * successful invocation of ompd_get_thread_in_parallel returns a pointer to a + * vector of handles in thread_handle_array and returns the number of handles in + * num_handles. This call yields meaningful results only if all OpenMP threads + * in the parallel region are stopped; otherwise, the OpenMP runtime may be + * creating and/or destroying threads during or after the call, rendering + * useless the vector of handles returned. + */ +ompd_rc_t ompd_get_thread_in_parallel( + ompd_parallel_handle_t *parallel_handle, /* IN */ + int nth_thread, /* IN: number of the thread in team */ + ompd_thread_handle_t **thread_handle /* OUT: handle */ + ); + +#if 0 +ompd_rc_t ompd_get_master_thread_in_parallel ( + ompd_parallel_handle_t *parallel_handle, /* IN */ + ompd_thread_handle_t **thread_handle); +#endif + +ompd_rc_t ompd_release_thread_handle(ompd_thread_handle_t *thread_handle); + +ompd_rc_t ompd_thread_handle_compare(ompd_thread_handle_t *thread_handle_1, + ompd_thread_handle_t *thread_handle_2, + int *cmp_value); + +#if 0 +ompd_rc_t ompd_get_thread_handle_string_id ( + ompd_thread_handle_t *thread_handle, + char **string_id +); +#endif + +/* --- 4.2 Parallel Region Handles------------------------------------------- */ + +/** + * Retrieve the handle for the innermost patallel region for an OpenMP thread. + * + * The operation ompd_get_current_parallel_handle enables the debugger to obtain + * the handle for the innermost parallel region associated with an OpenMP + * thread. This call is meaningful only if the thread whose handle is provided + * is stopped. + */ + +ompd_rc_t ompd_get_current_parallel_handle( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_parallel_handle_t **parallel_handle /* OUT: OpenMP parallel handle */ + ); + +/** + * Retrieve the handle for an enclosing parallel region. + * + * The ompd_get_enclosing_parallel_handle operation enables the debugger to + * obtain the handle for the parallel region enclosing the parallel region + * specified by parallel_handle. This call is meaningful only if at least one + * thread in the parallel region is stopped. + */ + +ompd_rc_t ompd_get_enclosing_parallel_handle( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_parallel_handle_t * + *enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ); + +/** + * Retrieve the handle for the enclosing parallel region or a task region. + * + * The ompd_get_task_parallel_handle operation enables the debugger to + * obtain the handle for the parallel region enclosing the task region + * specified by task_handle. This call is meaningful only if at least one + * thread in the parallel region is stopped. + */ + +ompd_rc_t ompd_get_task_parallel_handle( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_parallel_handle_t * + *enclosing_parallel_handle /* OUT: OpenMP parallel handle */ + ); + +ompd_rc_t ompd_release_parallel_handle(ompd_parallel_handle_t *parallel_handle); + +ompd_rc_t +ompd_parallel_handle_compare(ompd_parallel_handle_t *parallel_handle_1, + ompd_parallel_handle_t *parallel_handle_2, + int *cmp_value); + +#if 0 +ompd_rc_t ompd_get_parallel_handle_string_id ( + ompd_parallel_handle_t *parallel_handle, + char **string_id +); +#endif + +/* --- 4.3 Task Handles ----------------------------------------------------- */ + +/** + * Retrieve the handle for the innermost task for an OpenMP thread. + * + * The debugger uses the operation ompd_get_current_task__handle to obtain the + * handle + * for the innermost task region associated with an OpenMP thread. This call is + * meaningful only if the thread whose handle is provided is stopped. + */ +ompd_rc_t ompd_get_current_task__handle( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ + ); + +/** + * Retrieve the handle for an enclosing task. + * + * The debugger uses ompd_get_ancestor_task_handle to obtain the handle for the + * task region enclosing the task region specified by task_handle. This call is + * meaningful only if the thread executing the task specified by task_handle is + * stopped. + */ +#if 0 +ompd_rc_t ompd_get_ancestor_task_handle( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ); +#endif + +ompd_rc_t ompd_get_generating_ancestor_task_handle( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ); + +ompd_rc_t ompd_get_scheduling_ancestor_task_handle( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_task_handle_t **parent_task_handle /* OUT: OpenMP task handle */ + ); + +/** + * Retrieve implicit task handle for a parallel region. + * + * The ompd_get_implicit_task_in_parallel operation enables the debugger to + * obtain handles for implicit tasks associated with a parallel region. This + * call is meaningful only if all threads associated with the parallel region + * are stopped. + */ +ompd_rc_t ompd_get_task_in_parallel( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + int nth_handle, /* IN: number of the task handle */ + ompd_task_handle_t **task_handle /* OUT: OpenMP task handle */ + ); + +ompd_rc_t ompd_release_task_handle(ompd_task_handle_t *task_handle); + +ompd_rc_t ompd_task_handle_compare(ompd_task_handle_t *task_handle_1, + ompd_task_handle_t *task_handle_2, + int *cmp_value); + +#if 0 +ompd_rc_t ompd_get_task_handle_string_id ( + ompd_task_handle_t *task_handle, + char **string_id +); +#endif + +/* --- 5o Process and Thread Settings ---------------------------------------- + */ + +/** + * The functions ompd_get_num_procs and ompd_get_thread_limit are third-party + * versions of the OpenMP runtime functions omp_get_num_procs and + * omp_get_thread_limit. + */ + +ompd_rc_t +ompd_get_num_procs(ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + ompd_word_t *val /* OUT: number of processes */ + ); + +ompd_rc_t +ompd_get_thread_limit(ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + ompd_word_t *val /* OUT: max number of threads */ + ); + +/* --- 6 Parallel Region Inqueries ------------------------------------------ */ +/* --- 6.1 Settings --------------------------------------------------------- */ + +/** + * Determine the number of threads associated with a parallel region. + */ +ompd_rc_t ompd_get_num_threads( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_word_t *val /* OUT: number of threads */ + ); + +/** + * Determine the nesting depth of a particular parallel region instance. + */ +ompd_rc_t ompd_get_level( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_word_t *val /* OUT: nesting level */ + ); + +/** + * Determine the number of enclosing active parallel regions. + * + * ompd_get_active_level returns the number of nested, active parallel regions + * enclosing the parallel region specified by its handle. + */ +ompd_rc_t ompd_get_active_level( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_word_t *val /* OUT: active nesting level */ + ); + +/* --- 6.2 OMPT Parallel Region Inquiry Analogues ------------------------- */ + +/** + * The functions ompd_get_parallel_id and ompd_get_parallel_function are + * third-party variants of their OMPT counterparts. The only difference between + * the OMPD and OMPT versions is that the OMPD must supply a parallel region + * handle to provide a context for these inquiries. + */ +ompd_rc_t ompd_get_parallel_data( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_address_t *data /* OUT: OpenMP parallel id */ + ); + +#if 0 +ompd_rc_t ompd_get_parallel_function( + ompd_parallel_handle_t *parallel_handle, /* IN: OpenMP parallel handle */ + ompd_address_t *parallel_addr /* OUT: first instruction in the parallel region */ + ); +#endif + +/* --- 7 Thread Inquiry ----------------------------------------------------- */ +/* --- 7.1 Operating System Thread Inquiry ---------------------------------- */ + +/** + * Obtain an OpenMP thread handle and the internal OS thread handle for the + * selected (context) thread. + * If the function returns ompd_rc_ok then the operating system thread + * corresponds to an OpenMP thread and the thread_handle is initialized. The + * value of thread_handle ans os_thread is meaningful only to the OpenMP runtime + * system. + */ +ompd_rc_t ompd_get_thread_handle( + ompd_address_space_handle_t + *addr_handle, /* IN: handle for the address space */ + ompd_thread_id_kind_t kind, + ompd_size_t sizeof_thread_id, const void *thread_id, + ompd_thread_handle_t **thread_handle /* OUT: OpenMP thread handle*/ + ); + +/** + * Obtain the OS thread handle for an OpenMP thread handle. + * this might change over time in case virtual openmp threads migrate between + * OS threads. + */ +ompd_rc_t ompd_get_thread_id( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_thread_id_kind_t kind, ompd_size_t sizeof_thread_id, void *thread_id); + +ompd_rc_t ompd_get_thread_data( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_address_t *data /* OUT: OpenMP thread data */ + ); + +ompd_rc_t ompd_get_thread_num( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_word_t *val /* OUT: number of the thread within the team */ + ); + +/* --- 7.2 OMPT Thread State Inquiry Analogue ------------------------------- */ + +/** + * Get the state of a thread. This can use OMPT state data structure to define + * different states of threads (e.g., idle, working, or barrier, etc) and what + * entity cased this state (e.g., address of a lock); + * + * The function ompd_get_state is a third-party version of ompt_get_state. The + * only difference between the OMPD and OMPT counterparts is that the OMPD + * version must supply a thread handle to provide a context for this inquiry. + */ +ompd_rc_t ompd_get_state( + ompd_thread_handle_t *thread_handle, /* IN: OpenMP thread handle*/ + ompd_word_t *state, /* OUT: State of this thread */ + ompd_wait_id_t *wait_id /* OUT: Wait ID */ + ); + +/* --- 8 Task Inquiry ------------------------------------------------------- */ + +/* --- 8.1 Task Function Entry Point ---------------------------------------- */ + +/** + * The ompd_get_task_function returns the entry point of the code that + * corresponds to the body of code executed by the task. + */ + +#if 0 +ompd_rc_t ompd_get_task_function( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_address_t *entry_point /* OUT: first instruction in the task region */ + ); +#endif + +/* --- 8.2 Task Settings ---------------------------------------------------- */ + +/** + * Retrieve information from OpenMP tasks. These inquiry functions have no + * counterparts in the OMPT interface as a first-party tool can call OpenMP + * runtime inquiry functions directly. The only difference between the OMPD + * inquiry operations and their counterparts in the OpenMP runtime is that the + * OMPD version must supply a task handle to provide a context for each inquiry. + */ + +ompd_rc_t ompd_get_max_threads( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: max number of threads */ + ); + +ompd_rc_t +ompd_in_parallel(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: Is OpenMP in parallel? */ + ); + +ompd_rc_t +ompd_in_final(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: Is OpenMP in final? */ + ); + +ompd_rc_t +ompd_get_dynamic(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: ? */ + ); + +ompd_rc_t +ompd_get_nested(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_word_t *val /* OUT: Is this task nested? */ + ); + +ompd_rc_t ompd_get_max_active_levels( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_word_t *val /* OUT: max active levels */ + ); + +ompd_rc_t +ompd_get_schedule(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *kind, /* OUT: Kind of OpenMP schedule*/ + ompd_word_t *modifier /* OUT: Schedunling modifier */ + ); + +ompd_rc_t +ompd_get_proc_bind(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *bind /* OUT: Kind of proc-binding */ + ); + +ompd_rc_t +ompd_is_implicit(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_word_t *val /* OUT: implicit=1, explicit=0 */ + ); + +/* --- 8.3 OMPT Task Inquiry Analogues -------------------------------------- */ + +/** + * The functions defined here are third-party versions of ompt_get_task_frame + * and ompt_get_task_data. The only difference between the OMPD and OMPT + * counterparts is that the OMPD version must supply a task handle to provide a + * context for these inquiries. + */ + +/** + * sp_exit + * + * This value is set once, the first time that a task exits the runtime to begin + * executing user code. This field points to the stack frame of the runtime + * procedure that called the user code. This value is NULL until just before the + * task exits the runtime. + * + * sp_reentry + * + * This value is set each time that current task re-enters the runtime to create + * new (implicit or explicit) tasks. This field points to the stack frame of the + * runtime procedure called by a task to re-enter the runtime. This value is + * NULL + * until just after the task re-enters the runtime. + */ + +ompd_rc_t ompd_get_task_frame( + ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ + ompd_address_t *sp_exit, /* OUT: next frame is user code */ + ompd_address_t *sp_reentry /* OUT: previous frame is user code */ + ); + +ompd_rc_t +ompd_get_task_data(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ + ompd_address_t *task_data /* OUT: OpenMP task ID */ + ); + +/* --- 13 Display Control Variables ----------------------------------------- */ + +/** + * Using the ompd_display_control_vars function, the debugger can extract a + * string that contains a sequence of name/value pairs of control variables + * whose settings are (a) user controllable, and (b) important to the operation + * or performance of an OpenMP runtime system. The control variables exposed + * through this interface will include all of the OMP environment variables, + * settings that may come from vendor or platform- specific environment + * variables (e.g., the IBM XL compiler has an environment variable that + * controls spinning vs. blocking behavior), and other settings that affect + * the operation or functioning of an OpenMP runtime system (e.g., numactl + * settings that cause threads to be bound to cores). + */ + +ompd_rc_t +ompd_get_display_control_vars(ompd_address_space_handle_t *handle, /* IN */ + const char *const **control_var_values /* OUT */ + ); + +ompd_rc_t ompd_release_display_control_vars( + const char *const **control_var_values /* IN */ + ); + +#ifdef __cplusplus +} +#endif +#endif /* SRC_OMPD_H_ */ From e43831430ca1ffeb5a9260d81003d734ce06ebb0 Mon Sep 17 00:00:00 2001 From: Ignacio Laguna Peralta Date: Tue, 13 Feb 2018 15:31:56 -0800 Subject: [PATCH 37/46] Adding sourc code of GDB wrapper in libompd directory --- libompd/gdb-wrapper/CMakeLists.txt | 60 ++ libompd/gdb-wrapper/Callbacks.cpp | 362 ++++++++++++ libompd/gdb-wrapper/Callbacks.h | 108 ++++ libompd/gdb-wrapper/ChildProcess.cpp | 104 ++++ libompd/gdb-wrapper/ChildProcess.h | 49 ++ libompd/gdb-wrapper/CudaGdb.cpp | 36 ++ libompd/gdb-wrapper/CudaGdb.h | 28 + libompd/gdb-wrapper/Debug.cpp | 6 + libompd/gdb-wrapper/Debug.h | 54 ++ libompd/gdb-wrapper/GdbProcess.cpp | 94 ++++ libompd/gdb-wrapper/GdbProcess.h | 78 +++ libompd/gdb-wrapper/InputChecker.cpp | 37 ++ libompd/gdb-wrapper/InputChecker.h | 25 + libompd/gdb-wrapper/InputOutputManager.cpp | 221 ++++++++ libompd/gdb-wrapper/InputOutputManager.h | 62 +++ libompd/gdb-wrapper/OMPDCommand.cpp | 608 +++++++++++++++++++++ libompd/gdb-wrapper/OMPDCommand.h | 278 ++++++++++ libompd/gdb-wrapper/OMPDContext.cpp | 163 ++++++ libompd/gdb-wrapper/OMPDContext.h | 129 +++++ libompd/gdb-wrapper/OutputString.cpp | 27 + libompd/gdb-wrapper/OutputString.h | 24 + libompd/gdb-wrapper/ProcessSpawn.cpp | 115 ++++ libompd/gdb-wrapper/ProcessSpawn.h | 67 +++ libompd/gdb-wrapper/StringParser.cpp | 496 +++++++++++++++++ libompd/gdb-wrapper/StringParser.h | 148 +++++ libompd/gdb-wrapper/driver.py | 26 + libompd/gdb-wrapper/gdb_wrapper.cpp | 145 +++++ libompd/gdb-wrapper/odb.cpp | 22 + libompd/gdb-wrapper/regex_test.cpp | 42 ++ libompd/gdb-wrapper/regex_test_v2.cpp | 115 ++++ 30 files changed, 3729 insertions(+) create mode 100644 libompd/gdb-wrapper/CMakeLists.txt create mode 100644 libompd/gdb-wrapper/Callbacks.cpp create mode 100644 libompd/gdb-wrapper/Callbacks.h create mode 100644 libompd/gdb-wrapper/ChildProcess.cpp create mode 100644 libompd/gdb-wrapper/ChildProcess.h create mode 100644 libompd/gdb-wrapper/CudaGdb.cpp create mode 100644 libompd/gdb-wrapper/CudaGdb.h create mode 100644 libompd/gdb-wrapper/Debug.cpp create mode 100644 libompd/gdb-wrapper/Debug.h create mode 100644 libompd/gdb-wrapper/GdbProcess.cpp create mode 100644 libompd/gdb-wrapper/GdbProcess.h create mode 100644 libompd/gdb-wrapper/InputChecker.cpp create mode 100644 libompd/gdb-wrapper/InputChecker.h create mode 100644 libompd/gdb-wrapper/InputOutputManager.cpp create mode 100644 libompd/gdb-wrapper/InputOutputManager.h create mode 100644 libompd/gdb-wrapper/OMPDCommand.cpp create mode 100644 libompd/gdb-wrapper/OMPDCommand.h create mode 100644 libompd/gdb-wrapper/OMPDContext.cpp create mode 100644 libompd/gdb-wrapper/OMPDContext.h create mode 100644 libompd/gdb-wrapper/OutputString.cpp create mode 100644 libompd/gdb-wrapper/OutputString.h create mode 100644 libompd/gdb-wrapper/ProcessSpawn.cpp create mode 100644 libompd/gdb-wrapper/ProcessSpawn.h create mode 100644 libompd/gdb-wrapper/StringParser.cpp create mode 100644 libompd/gdb-wrapper/StringParser.h create mode 100755 libompd/gdb-wrapper/driver.py create mode 100644 libompd/gdb-wrapper/gdb_wrapper.cpp create mode 100644 libompd/gdb-wrapper/odb.cpp create mode 100644 libompd/gdb-wrapper/regex_test.cpp create mode 100644 libompd/gdb-wrapper/regex_test_v2.cpp diff --git a/libompd/gdb-wrapper/CMakeLists.txt b/libompd/gdb-wrapper/CMakeLists.txt new file mode 100644 index 000000000..c3ea2824c --- /dev/null +++ b/libompd/gdb-wrapper/CMakeLists.txt @@ -0,0 +1,60 @@ +project (odb) + +set (cppfiles + InputOutputManager.cpp + ChildProcess.cpp +# ProcessSpawn.cpp + StringParser.cpp + CudaGdb.cpp + Debug.cpp + GdbProcess.cpp + Callbacks.cpp + OMPDCommand.cpp + OMPDContext.cpp + OutputString.cpp) + +# Let's find GDB first. +find_package(GDB REQUIRED) +if (GDB_FOUND) + MESSAGE( STATUS "GDB_PATH: " ${GDB_COMMAND} ) + add_definitions (-DGDB_PATH="${GDB_COMMAND}") +endif (GDB_FOUND) + +find_package(CudaGDB QUIET) +if (CUDA_GDB_FOUND) + MESSAGE( STATUS "CUDA_GDB_PATH: " ${CUDA_GDB_COMMAND} ) + add_definitions (-DCUDA_GDB_PATH="${CUDA_GDB_COMMAND}") +endif (CUDA_GDB_FOUND) + +add_executable (odb-bin ${cppfiles} odb.cpp) +set_target_properties (odb-bin PROPERTIES OUTPUT_NAME odb) +add_library (odb ${cppfiles}) + +if (ODB_LINUX) +target_link_libraries (odb-bin dl) +target_link_libraries (odb dl) +endif (ODB_LINUX) + +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} +# ${CMAKE_CURRENT_SOURCE_DIR}/../src/ + ${CMAKE_BINARY_DIR}/include +) + +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + add_definitions (-DDEBUG) +endif (CMAKE_BUILD_TYPE STREQUAL "Debug") + +# Find readline library +find_package(Readline REQUIRED) +include_directories(${Readline_INCLUDE_DIRS}) +set(LIBS ${LIBS} ${Readline_LIBRARY}) + +target_link_libraries(odb-bin ${LIBS}) + +install(TARGETS odb odb-bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib/static + RUNTIME DESTINATION bin ) diff --git a/libompd/gdb-wrapper/Callbacks.cpp b/libompd/gdb-wrapper/Callbacks.cpp new file mode 100644 index 000000000..e15e7e795 --- /dev/null +++ b/libompd/gdb-wrapper/Callbacks.cpp @@ -0,0 +1,362 @@ +/* + * Callbacks.cpp + * + * Created on: Dec 23, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "Callbacks.h" +#include "OMPDContext.h" +#include "GdbProcess.h" +#include "CudaGdb.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ompd_gdb; +using namespace std; + +static ompd_callbacks_t cb; +static GdbProcessPtr gdb(nullptr); +static StringParser parser; + +unsigned int prim_sizes[ompd_type_max]; + +void init_sizes(); + +void initializeCallbacks(const GdbProcessPtr &proc) +{ + // Copy pointer of GDB process + gdb = proc; + + // Initialize static table + cb.dmemory_alloc = CB_dmemory_alloc; + cb.dmemory_free = CB_dmemory_free; + cb.print_string = CB_print_string; + cb.get_thread_context_for_osthread = CB_thread_context; + cb.get_containing_process_context = CB_process_context; + cb.tsizeof_prim = CB_tsizeof_prim; + cb.tsymbol_addr = CB_tsymbol_addr; + cb.read_tmemory = CB_read_tmemory; + cb.write_tmemory = CB_write_tmemory; + cb.host_to_target = CB_host_to_target; + cb.target_to_host = CB_target_to_host; +} + +ompd_callbacks_t * getCallbacksTable() +{ + return &cb; +} + +ompd_rc_t CB_dmemory_alloc ( + ompd_size_t bytes, + void **ptr) +{ + void *allocPtr = malloc(bytes); + if (allocPtr != NULL) + *ptr = allocPtr; + else + return ompd_rc_error; + return ompd_rc_ok; +} + +ompd_rc_t CB_dmemory_free ( + void *ptr) +{ + if (!ptr) + return ompd_rc_error; + free(ptr); + return ompd_rc_ok; +} + +ompd_rc_t CB_thread_context ( + ompd_address_space_context_t *context, + ompd_osthread_kind_t kind, + ompd_size_t sizeof_osthread, + const void* osthread, + ompd_thread_context_t **tcontext + ) +{ + ompd_rc_t ret = context ? ompd_rc_ok : ompd_rc_stale_handle; + if (kind == ompd_osthread_cudalogical) { + *tcontext = ((OMPDContext*)context)->getContextForThread((CudaThread*)osthread); + } + else { + *tcontext = ((OMPDContext*)context)->getContextForThread((pthread_t*)osthread); + } + return ret; +} + +ompd_rc_t CB_process_context ( + ompd_address_space_context_t* context, + ompd_address_space_context_t** containing_process_context + ) +{ + ompd_rc_t ret = context ? ompd_rc_ok : ompd_rc_stale_handle; + OMPDContext* ompc = (OMPDContext*)context; + + if (OMPDCudaContext* cuda_c = dynamic_cast(ompc)) { + *containing_process_context = cuda_c->host_cp->getGlobalOmpdContext(); + } + else if (OMPDHostContext* host_c = dynamic_cast(ompc)) { + *containing_process_context = host_c->cp->getGlobalOmpdContext(); + } + else { + assert(0 && "Unable to find process context!"); + } + + return ret; +} + +void init_sizes(){ + prim_sizes[ompd_type_char] = getSizeOf("char"); + prim_sizes[ompd_type_short] = getSizeOf("short"); + prim_sizes[ompd_type_int] = getSizeOf("int"); + prim_sizes[ompd_type_long] = getSizeOf("long"); + prim_sizes[ompd_type_long_long] = getSizeOf("long long"); + prim_sizes[ompd_type_pointer] = getSizeOf("void *"); +} + +ompd_rc_t CB_tsizeof_prim( + ompd_address_space_context_t *context, + ompd_target_type_sizes_t *sizes) +{ + ompd_rc_t ret = context ? ompd_rc_ok : ompd_rc_stale_handle; + static int inited = 0; + if(!inited) + { + inited=1; + init_sizes(); + } + memcpy(sizes, prim_sizes, sizeof(prim_sizes[0])*ompd_type_max); + + return ret; +} + +/* Returns zero if the type doesn't exist */ +unsigned int getSizeOf(const char *str) +{ + assert(gdb.get() != nullptr && "Invalid GDB process!"); + string command("print sizeof(" + string(str) + ")"); + gdb->writeInput(command.c_str()); + char val[8]; + string gdbOut = gdb->readOutput(); + parser.matchRegularValue(gdbOut.c_str(), val); + if (strlen(val) == 0) // type not found + return 0; + + int intVal = atoi(val); + return static_cast(intVal); +} + +ompd_rc_t CB_tsymbol_addr( + ompd_address_space_context_t *context, + ompd_thread_context_t *tcontext, + const char *symbol_name, + ompd_address_t *symbol_addr) +{ + ompd_rc_t ret = context ? ompd_rc_ok : ompd_rc_stale_handle; + assert(gdb.get() != nullptr && "Invalid GDB process!"); + + if (tcontext) + ((OMPDContext*)tcontext)->setThisGdbContext(); + + string command("p &" + string(symbol_name)); + gdb->writeInput(command.c_str()); + char addr[64]; // long enough to hold an address + addr[0] = '\0'; + parser.matchAddressValue(gdb->readOutput().c_str(), addr); + + if (strlen(addr) > 0) + symbol_addr->address = (ompd_taddr_t) strtoull (addr, NULL, 0); + else if (strlen(addr) == 0) + ret = ompd_rc_error; + + return ret; +} + +ompd_rc_t CB_num_os_threads ( + ompd_address_space_context_t *context, + ompd_size_t *num_os_threads) +{ + ompd_rc_t ret = context ? ompd_rc_ok : ompd_rc_stale_handle; + assert(gdb.get() != nullptr && "Invalid GDB process!"); + + auto threads = getThreadIDsFromDebugger(); + if (threads.size() == 0) + return ompd_rc_error; + + *num_os_threads = threads.size(); + + return ret; +} + +map getCudaContextIDsFromDebugger() +{ + string command("info cuda contexts"); + gdb->writeInput(command.c_str()); + string gdbOut = gdb->readOutput(); + return parser.matchCudaContextsInfo(gdbOut.c_str()); +} + +map> getCudaKernelIDsFromDebugger() +{ + string command("info cuda kernels"); + gdb->writeInput(command.c_str()); + string gdbOut = gdb->readOutput(); + return parser.matchCudaKernelsInfo(gdbOut.c_str()); +} + +vector getCudaKernelThreadsFromDebugger( + uint64_t ctx, uint64_t dev, uint64_t gid, uint64_t kernel +) +{ + vector ret; + + gdb->writeInput("set cuda coalescing on"); + gdb->readOutput(); + + stringstream command; + command << "cuda kernel " << kernel; + gdb->writeInput(command.str().c_str()); gdb->readOutput(); + + gdb->writeInput("info cuda threads"); + string gdbOut = gdb->readOutput(); + ret = parser.matchCudaThreadsInfo(ctx, dev, kernel, gid, gdbOut.c_str()); + + return ret; +} + +/* + * Run 'info threads' command in gdb and return vector thread IDs. + * Returns a pair . + */ +vector getThreadIDsFromDebugger() +{ + string command("info threads"); + gdb->writeInput(command.c_str()); + string gdbOut = gdb->readOutput(); + return parser.matchThreadsInfo(gdbOut.c_str()); +} + +uint64_t evalGdbExpression(string command) +{ + char value[256]; + gdb->writeInput(command.c_str()); + string gdbOut = gdb->readOutput(); + parser.matchRegularValue(gdbOut.c_str(), value); + return strtoll(value, NULL, 0); +} + + +template +inline void set_mem_strings(vector& str, T* dest) +{ + for (size_t i=0; i < str.size(); ++i) + dest[i]=(T)strtoll(str[i].c_str(), NULL, 0); +} + +ompd_rc_t CB_write_tmemory ( + ompd_address_space_context_t *context, + ompd_thread_context_t *tcontext, + ompd_address_t addr, + ompd_tword_t nbytes, + const void *buffer) +{ + return ompd_rc_unsupported; +} + +ompd_rc_t CB_read_tmemory ( + ompd_address_space_context_t *context, + ompd_thread_context_t *tcontext, + ompd_address_t addr, + ompd_tword_t nbytes, + void *buffer) +{ + if (!context) + return ompd_rc_stale_handle; + assert(gdb.get() != nullptr && "Invalid GDB process!"); + + if (!(nbytes > 0)) + return ompd_rc_error; + + if (tcontext) { + ((OMPDContext*)tcontext)->setThisGdbContext(); + } + else { + OMPDContext* ompc = (OMPDContext*)context; + + if (OMPDHostContext* host_c = dynamic_cast(ompc)) { + host_c->cp->getFirstThreadContext()->setThisGdbContext(); + } + } + + // Get bytes of memory from gdb + stringstream command; + string cast; + + switch (addr.segment) { + default: + cast = "xb 0x"; break; + case OMPD_SEGMENT_CUDA_PTX_GLOBAL: + cast = "xb (@global unsigned char*) 0x"; break; + case OMPD_SEGMENT_CUDA_PTX_LOCAL: + cast = "xb (@local unsigned char*) 0x"; break; + case OMPD_SEGMENT_CUDA_PTX_SHARED: + cast = "xb (@shared unsigned char*) 0x"; break; + } + command << "x/" << nbytes << cast << std::hex << addr.address; + + gdb->writeInput(command.str().c_str()); + vector words; + string out = gdb->readOutput(); + words = parser.matchMemoryValues(out.c_str()); + assert((size_t)nbytes == words.size() && "Read more or less words from gdb"); + + set_mem_strings(words,(uint8_t*)buffer); + + return ompd_rc_ok; +} + +ompd_rc_t CB_target_to_host ( + ompd_address_space_context_t *address_space_context, /* IN */ + const void *input, /* IN */ + int unit_size, /* IN */ + int count, /* IN: number of primitive type */ + /* items to process */ + void *output /* OUT */ +) +{ + memmove(output, input, unit_size); + return ompd_rc_ok; +} + +ompd_rc_t CB_host_to_target ( + ompd_address_space_context_t *address_space_context, /* IN */ + const void *input, /* IN */ + int unit_size, /* IN */ + int count, /* IN: number of primitive type */ + /* items to process */ + void *output /* OUT */ +) +{ + memmove(output, input, unit_size); + return ompd_rc_ok; +} + + +ompd_rc_t CB_print_string ( + const char *string + ) +{ + printf("%s", string); + return ompd_rc_ok; +} + diff --git a/libompd/gdb-wrapper/Callbacks.h b/libompd/gdb-wrapper/Callbacks.h new file mode 100644 index 000000000..d93c74580 --- /dev/null +++ b/libompd/gdb-wrapper/Callbacks.h @@ -0,0 +1,108 @@ +/* + * Callbacks.h + * + * Created on: Dec 23, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#ifndef GDB_CALLBACKS_H_ +#define GDB_CALLBACKS_H_ + +/****************************************************************************** + * This header file defines the callback functions that are provided by the + * debugger to OMPD. In this case, we implement them using GDB. Other debuggers + * will have different implementations. + */ + +#include "ompd.h" +#include "GdbProcess.h" +#include "StringParser.h" +#include "CudaGdb.h" +#include +#include +#include + +/****************************************************************************** + * Helper functions + */ +void initializeCallbacks(const ompd_gdb::GdbProcessPtr &proc); +ompd_callbacks_t * getCallbacksTable(); +unsigned int getSizeOf(const char *str); +std::vector getThreadIDsFromDebugger(); +uint64_t evalGdbExpression(std::string command); + +std::map getCudaContextIDsFromDebugger(); +std::map> getCudaKernelIDsFromDebugger(); +std::vector getCudaKernelThreadsFromDebugger(uint64_t, uint64_t, uint64_t, uint64_t); + +/****************************************************************************** + * Callbacks + */ + +ompd_rc_t CB_dmemory_alloc ( + ompd_size_t bytes, + void **ptr); + +ompd_rc_t CB_dmemory_free ( + void *ptr); + +ompd_rc_t CB_thread_context ( + ompd_address_space_context_t *context, + ompd_osthread_kind_t kind, + ompd_size_t sizeof_osthread, + const void* osthread, + ompd_thread_context_t **tcontext); + +ompd_rc_t CB_process_context ( + ompd_address_space_context_t* context, + ompd_address_space_context_t** containing_process_context); + +ompd_rc_t CB_tsizeof_prim ( + ompd_address_space_context_t *context, + ompd_target_type_sizes_t *sizes); + +ompd_rc_t CB_tsymbol_addr ( + ompd_address_space_context_t *context, + ompd_thread_context_t *tcontext, + const char *symbol_name, + ompd_address_t *symbol_addr); + +ompd_rc_t CB_read_tmemory ( + ompd_address_space_context_t *context, + ompd_thread_context_t *tcontext, + const ompd_address_t addr, + ompd_tword_t nbytes, + void *buffer + ); + +ompd_rc_t CB_write_tmemory ( + ompd_address_space_context_t *context, + ompd_thread_context_t *tcontext, + const ompd_address_t addr, + ompd_tword_t nbytes, + const void *buffer + ); + +ompd_rc_t CB_target_to_host ( + ompd_address_space_context_t *address_space_context, /* IN */ + const void *input, /* IN */ + int base_type, /* IN */ + int count, /* IN: number of primitive type */ + /* items to process */ + void *output /* OUT */ + ); + +ompd_rc_t CB_host_to_target ( + ompd_address_space_context_t *address_space_context, /* IN */ + const void *input, /* IN */ + int base_type, /* IN */ + int count, /* IN: number of primitive type */ + /* items to process */ + void *output /* OUT */ + ); + +ompd_rc_t CB_print_string ( + const char *string + ); + +#endif /* GDB_CALLBACKS_H_ */ diff --git a/libompd/gdb-wrapper/ChildProcess.cpp b/libompd/gdb-wrapper/ChildProcess.cpp new file mode 100644 index 000000000..b5f699843 --- /dev/null +++ b/libompd/gdb-wrapper/ChildProcess.cpp @@ -0,0 +1,104 @@ +/* + * ChildProcess.cpp + * + * Created on: Jul 19, 2016 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "ChildProcess.h" + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace ompd_gdb; + +ChildProcess::ChildProcess(const char **argv) +{ + if ( (pipe(fd1) < 0) || (pipe(fd2) < 0) ) + cerr << "ERROR: pipe error\n"; + + if ( (childPid = fork()) < 0 ) + cerr << "ERROR: fork error\n"; + + else if (childPid == 0) // Child process + { + close(fd1[1]); + close(fd2[0]); + + if (fd1[0] != STDIN_FILENO) + { + if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO) + cerr << "ERROR: dup2 error to stdin\n" << endl; + close(fd1[0]); + } + + if (fd2[1] != STDOUT_FILENO) + { + if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO) + cerr << "ERROR: dup2 error to stdout\n" << endl; + close(fd2[1]); + } + + //int result = execv(argv[0], const_cast(argv)); + int result = execv((const char*)argv[0], (char * const *)argv); + + // On successful execution we should not see the following message + printf( "ERROR: could not start program '%s' return code %i\n", + argv[0] , result); + exit(EXIT_FAILURE); + } + else // Parent process + { + close(fd1[0]); + close(fd2[1]); + } +} + +std::size_t ChildProcess::readSome(char *str, std::size_t s) +{ + ssize_t rv; + if ( (rv = read(fd2[0], str, s)) < 0 ) + cerr << "ERROR: read error from pipe" << endl; + + return rv; +} + +// FIXME +// Call write in a loop? +void ChildProcess::writeSome(const char *str) +{ + if ( write(fd1[1], str, strlen(str) ) != strlen(str) ) + cerr << "ERROR: Write error from pipe" << endl; +} + +/** Close child pipe */ +void ChildProcess::sendEOF() +{ + kill(childPid, SIGKILL); + wait(); + int c1 = close(fd1[1]); + int c2 = close(fd2[0]); + if (!c1 || !c2) + cerr << "ERROR: closing pipes to gdb process failed.\n"; +} + +/** Send child a signal */ +void ChildProcess::sendSignal(int sig) +{ + kill(childPid, sig); +} + +/** Wait for child to finish */ +int ChildProcess::wait() +{ + int status; + waitpid(childPid, &status, 0); + //cout << "Status " << status << "\n"; + return status; +} diff --git a/libompd/gdb-wrapper/ChildProcess.h b/libompd/gdb-wrapper/ChildProcess.h new file mode 100644 index 000000000..dc8446e7e --- /dev/null +++ b/libompd/gdb-wrapper/ChildProcess.h @@ -0,0 +1,49 @@ +/* + * ChildProcess.h + * + * Created on: Jul 19, 2016 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#ifndef OMPD_GDB_CHILDPROCESS_H_ +#define OMPD_GDB_CHILDPROCESS_H_ + +#include + +namespace ompd_gdb { + +class ChildProcess { +private: + //Pipe writePipe; + //Pipe readPipe; + int fd1[2]; + int fd2[2]; +public: + int childPid = -1; + //std::unique_ptr> writeBuf = nullptr; + //std::unique_ptr> readBuf = nullptr; + //std::ostream stdin; + //std::istream stdout; + + //ChildProcess(char* const argv[]); + ChildProcess(const char **argv); + + /** Read and write some characters **/ + std::size_t readSome(char *str, std::size_t s); + void writeSome(const char *str); + + /** Close child pipe */ + void sendEOF(); + + /** Send child a signal */ + void sendSignal(int sig); + + /** Wait for child to finish */ + int wait(); +}; + +} + + + +#endif /* OMPD_GDB_CHILDPROCESS_H_ */ diff --git a/libompd/gdb-wrapper/CudaGdb.cpp b/libompd/gdb-wrapper/CudaGdb.cpp new file mode 100644 index 000000000..b75e508cd --- /dev/null +++ b/libompd/gdb-wrapper/CudaGdb.cpp @@ -0,0 +1,36 @@ +/* + * CudaGdb.cpp + * + * Created on: Apr 11, 2017 + * Author: Marty McFadden + * Contact: mmcfadden8@llnl.gov + */ +#include "CudaGdb.h" +#include "Callbacks.h" +#include +#include +#include +#include + +using namespace std; + +CudaGdb::CudaGdb() +{ + map contexts = getCudaContextIDsFromDebugger(); + map> kernels = getCudaKernelIDsFromDebugger(); + + if (contexts.size() == 0 || kernels.size() == 0) { + cerr << "No CUDA Contexts(" << contexts.size() << ") or kernels(" << kernels.size() << "%d) present\n"; + return; + } + + for (auto i : kernels) { + int dev_id = i.second.first; + int grid_id = i.second.second; + int kernel_id = i.first; + uint64_t ctx_id = contexts[dev_id]; + vector t = getCudaKernelThreadsFromDebugger(ctx_id, dev_id, grid_id, kernel_id); + + threads.insert(threads.end(), t.begin(), t.end()); + } +} diff --git a/libompd/gdb-wrapper/CudaGdb.h b/libompd/gdb-wrapper/CudaGdb.h new file mode 100644 index 000000000..b690257b6 --- /dev/null +++ b/libompd/gdb-wrapper/CudaGdb.h @@ -0,0 +1,28 @@ +/* + * CudaGdb.h + * + * Created on: Apr 11, 2017 + * Author: Marty McFadden + * Contact: mmcfadden8@llnl.gov + * + * This header file defines the container for all threads running on Cuda devices + */ +#ifndef CUDA_GDB_H_ +#define CUDA_GDB_H_ +#include +#include +#include +#include "ompd.h" + +struct CudaThread { + ompd_cudathread_coord_t coord; +}; + +class CudaGdb +{ +public: + CudaGdb(); + std::vector threads; +}; + +#endif /* CUDA_GDB_H_*/ diff --git a/libompd/gdb-wrapper/Debug.cpp b/libompd/gdb-wrapper/Debug.cpp new file mode 100644 index 000000000..786fad601 --- /dev/null +++ b/libompd/gdb-wrapper/Debug.cpp @@ -0,0 +1,6 @@ +#include "Debug.h" + + std::ostream& GdbColor::operator<<(std::ostream& os, GdbColor::Code code) { + return os << "\033[" << static_cast(code) << "m"; + } + diff --git a/libompd/gdb-wrapper/Debug.h b/libompd/gdb-wrapper/Debug.h new file mode 100644 index 000000000..0166fc4f7 --- /dev/null +++ b/libompd/gdb-wrapper/Debug.h @@ -0,0 +1,54 @@ +#include +#include + +#ifndef GDB_DEBUG_H_ +#define GDB_DEBUG_H_ + +extern int display_gdb_output; + +namespace GdbColor { + enum Code { + FG_RED = 31, + FG_GREEN = 32, + FG_BLUE = 34, + FG_DEFAULT = 39, + BG_RED = 41, + BG_GREEN = 42, + BG_BLUE = 44, + BG_DEFAULT = 49 + }; + std::ostream& operator<<(std::ostream& os, Code code); +} + + +//class ColorOut: public std::ostream +class ColorOut +{ +private: + std::ostream& out; + GdbColor::Code color; +public: + ColorOut(std::ostream& _out, GdbColor::Code _color):out(_out), color(_color){} + + ~ColorOut() {} + + template + const ColorOut& operator<< (const T& val) const + { + out << "\x1b[" << std::to_string(color) << ";49m" << val << "\x1b[39;49m"; //GdbColor::FG_DEFAULT; + return *this; + } + /* don't color stream manipulators */ + const ColorOut& operator<< (std::ostream& (*pf)(std::ostream&)) const + { + out << pf; + return *this; + } +}; + +static ColorOut dout(std::cout, GdbColor::FG_RED); +static ColorOut sout(std::cout, GdbColor::FG_GREEN); +static ColorOut hout(std::cout, GdbColor::FG_BLUE); + + +#endif /*GDB_DEBUG_H_*/ diff --git a/libompd/gdb-wrapper/GdbProcess.cpp b/libompd/gdb-wrapper/GdbProcess.cpp new file mode 100644 index 000000000..98c318735 --- /dev/null +++ b/libompd/gdb-wrapper/GdbProcess.cpp @@ -0,0 +1,94 @@ +/* + * GdbProcess.cpp + * + * Created on: Dec 27, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "ChildProcess.h" +#include "GdbProcess.h" +#include "Debug.h" +#include +#include +#include +#include + +using namespace ompd_gdb; +using namespace std; + +#ifdef DEBUG +int display_gdb_output = true; +#else +int display_gdb_output = false; +#endif + +/** + * This function gets all the parameters passed via the argv array + */ +void GdbProcess::getArgvParameters(int argc, char **argv, const char **newArgv) +{ + newArgv[0] = gdbPath; + for (int i=1; i < argc; ++i) + newArgv[i] = argv[i]; + newArgv[argc] = (const char*)0; +} + +GdbProcess::GdbProcess(int argc, char **argv) +{ + // Prepare GDB path and input parameters of GDB + const char **newArgv = (const char **)malloc(sizeof(char *) * (argc+1)); + getArgvParameters(argc, argv, newArgv); + + //gdbProc = GdbProc(new ProcessSpawn(prog)); + gdbProc = GdbProc(new ChildProcess(newArgv)); + + // Print initial gdb output in stdout + cout << readOutput(); + free(newArgv); +} + +string GdbProcess::readOutput() const +{ + string ret(""); + char str[256]; // read in 256-byte chunks + str[0] = '\0'; + while (true) + { + //gdbProc->stdout.readsome(str, 255); + size_t c = gdbProc->readSome(str, 255); + //int c = gdbProc->stdout.gcount(); // number of characters read + str[c] = '\0'; + if (c > 0) // if we read something, add it to the returning string + ret += str; + if (parser.hasGDBPrompt(str)) + break; // Stop when gdb prompt is found + str[0] = '\0'; + } + + if (display_gdb_output) + dout << "READING FROM GDB:===" << ret << "===" << endl; + + return ret; +} + +void GdbProcess::writeInput(const char *str) const +{ + if (display_gdb_output) + dout << "SENDING TO GDB:===" << str << "===" << std::endl; + gdbProc->writeSome(str); + gdbProc->writeSome("\n"); +} +void GdbProcess::finalize() +{ + gdbProc->sendEOF(); +} +void GdbProcess::kill(int sig) +{ + gdbProc->sendSignal(sig); +} + +int GdbProcess::wait() +{ + return gdbProc->wait(); +} diff --git a/libompd/gdb-wrapper/GdbProcess.h b/libompd/gdb-wrapper/GdbProcess.h new file mode 100644 index 000000000..945df46f2 --- /dev/null +++ b/libompd/gdb-wrapper/GdbProcess.h @@ -0,0 +1,78 @@ +/* + * GdbProcess.h + * + * Created on: Dec 27, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#ifndef GDB_GDBPROCESS_H_ +#define GDB_GDBPROCESS_H_ + + +#include "ChildProcess.h" +//#include "ProcessSpawn.h" +#include "StringParser.h" +#include +#include + +namespace ompd_gdb { + +/** + * This class allows sending commands to a gdb process and receiving its output. + * It assumes that the main process spawns a gdb process and that a pipe is + * used for communication. + */ +class GdbProcess +{ +private: + +#if defined(CUDA_GDB_PATH) + const char *gdbPath = CUDA_GDB_PATH; +#elif defined(GDB_PATH) + const char *gdbPath = GDB_PATH; +#else + const char *gdbPath = "/usr/bin/gdb"; +#endif + + void getArgvParameters(int argc, char **argv, const char **newArgv); + + //typedef std::unique_ptr GdbProc; + typedef std::unique_ptr GdbProc; + GdbProc gdbProc = nullptr; + StringParser parser; + +public: + GdbProcess(int argc, char **argv); + + /** + * Read data from the process until a gdb prompt is seen (i.e., "(gdb) "). + * NOTE: this call may block if the gdb prompt is not seen. + */ + std::string readOutput() const; + + /** + * Send data to a gdb process (usually in the form of a command that is + * terminated by a new line character ('\n'). + */ + void writeInput(const char* str) const; + + /** + * Finalize GDB. + */ + void finalize(); + /** + * Send GDB a signal. + */ + void kill(int sig); + + /** + * Wait for GDB to finalize + */ + int wait(); +}; + +typedef std::shared_ptr GdbProcessPtr; + +} + +#endif /* GDB_GDBPROCESS_H_ */ diff --git a/libompd/gdb-wrapper/InputChecker.cpp b/libompd/gdb-wrapper/InputChecker.cpp new file mode 100644 index 000000000..19ad27c68 --- /dev/null +++ b/libompd/gdb-wrapper/InputChecker.cpp @@ -0,0 +1,37 @@ +/* + * InputChecker.cpp + * + * Created on: Jan 7, 2015 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "InputChecker.h" +#include +#include + +using namespace std; +using namespace ompd_gdb; + +void InputChecker::printUsage() +{ + cerr << "Usage:\n\tgdb_wrapper ID\n"; + cerr << "ID: process ID (integer)\n"; + exit(EXIT_FAILURE); +} + +void InputChecker::parseParameters(int argc, char **argv) +{ + // Check input is correct + if (argc != 2) + printUsage(); + else + { + int pid = atoi(argv[1]); + if (pid == 0 || pid < 0) + { + cerr << "ERROR: incorrect PID!\n"; + printUsage(); + } + } +} diff --git a/libompd/gdb-wrapper/InputChecker.h b/libompd/gdb-wrapper/InputChecker.h new file mode 100644 index 000000000..b2534a7d4 --- /dev/null +++ b/libompd/gdb-wrapper/InputChecker.h @@ -0,0 +1,25 @@ +/* + * InputChecker.h + * + * Created on: Jan 7, 2015 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#ifndef GDB_INPUTCHECKER_H_ +#define GDB_INPUTCHECKER_H_ + +namespace ompd_gdb { + +class InputChecker +{ +public: + static void printUsage(); + static void parseParameters(int argc, char**argv); +}; + +} + + + + +#endif /* GDB_INPUTCHECKER_H_ */ diff --git a/libompd/gdb-wrapper/InputOutputManager.cpp b/libompd/gdb-wrapper/InputOutputManager.cpp new file mode 100644 index 000000000..3bedaf54f --- /dev/null +++ b/libompd/gdb-wrapper/InputOutputManager.cpp @@ -0,0 +1,221 @@ +/* + * InputOutputManager.cpp + * + * Created on: Jan 7, 2015 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "InputOutputManager.h" +#include "InputChecker.h" +#include "StringParser.h" +#include "GdbProcess.h" +#include "OMPDCommand.h" +#include "OMPDContext.h" +#include "Callbacks.h" +#include "OutputString.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ompd_gdb; +using namespace std; + +/* --- Initialize ----------------------------------------------------------- */ + +static GdbProcessPtr gdbProc(nullptr); +static OutputString out; +OMPDHostContextPool * host_contextPool; + +/** + * FIXME: Pass cout as output stream. Do not use boolean input + */ +InputOutputManager::InputOutputManager(int argc, char **argv, bool _out) +: output(_out) +{ + // Initial steps + initializeErrorHandlers(); + gdbProc = GdbProcessPtr(new GdbProcess(argc, argv)); + initializeCallbacks(gdbProc); + host_contextPool=new OMPDHostContextPool(gdbProc); + commandFactory = OMPDCommandFactoryPtr(new OMPDCommandFactory); +} + +void InputOutputManager::initializeErrorHandlers() +{ + // Register signal handlers + signal(SIGINT, sigForwardGdb); + signal(SIGTSTP, sigForwardGdb); + signal(SIGSTOP, sigForwardGdb); + +// child(gdb) died + signal(SIGCHLD, sigChildKilled); +} + +/** + * FIXME: signal handlers should be defined in a separate file + */ +void sigHandler(int signo) +{ + cerr << "Got a signal. Exiting...\n"; + terminateGDB(); + exit(EXIT_FAILURE); +} + +/** + * FIXME: signal handlers should be defined in a separate file + */ +void sigChildKilled(int signo) +{ + cerr << "GDB process finished. Shutting down...\n"; + gdbProc->wait(); // We do not care about the return value of wait call + exit(EXIT_SUCCESS); +} + +/** + * FIXME: signal handlers should be defined in a separate file + */ +void sigForwardGdb(int signo) +{ + if (gdbProc.get()) + { + gdbProc->kill(signo); + } +} + +/* --- Finalize ------------------------------------------------------------- */ + +//InputOutputManager::~InputOutputManager() +//{ +// terminateGDB(); +//} + +void InputOutputManager::finalize() +{ + terminateGDB(); +} + +/** + * FIXME: this function should be within a namespace scope + */ +void terminateGDB() +{ + if (gdbProc.get()) + { + gdbProc->finalize(); + stringstream msg; + msg << "Waiting to terminate GDB..." << endl; + msg << "GDB exit status: "; + msg << gdbProc->wait() << endl; + out << msg.str().c_str(); + } +} + +/* --- Process -------------------------------------------------------------- */ + +/* This is the main loop that takes input commands from users + * The logic is the following: + * (1) If the command is the quit command, it terminates the loop and the + * function returns + * (2) If it is an ODB command, it process it internally + * (3) If it is a gdb command, it send the command to the gdb process + */ +void InputOutputManager::run() +{ + // Alternate between reading GDB's output and reading user's input. + bool readOutput = false; + //char userInput[256]; +// gdbProc->writeInput(""); + //cout << StringParser::GDB_PROMPT; + while(true) { + if (readOutput) + if (output) + { + string deb = readFromDebugger(); + // Eliminate gdb prompt + parser.eliminateGDBPromptInplace(deb); + cout << deb; + } + + // Read command from the user + //userInput[0] = '\0'; + //cin.getline(userInput,255); + + // Using readline library + char *userInput = readline(StringParser::GDB_PROMPT); + + // If the line has any text in it, save it on the history + if (userInput && *userInput) + add_history(userInput); + + // if quit command was sent, terminate + //if ((cin.rdstate() & cin.eofbit) || parser.isQuitCommand(userInput)) + if (!userInput || parser.isQuitCommand(userInput)) + { + if (userInput) + free(userInput); + break; + } + else + { + if (parser.isOMPDCommand(userInput)) // process OMPD command if sent + { + processOMPDCommand(userInput); + // print GDB prompt since it is consumed by the processing routine + //if (output) + // cout << StringParser::GDB_PROMPT; + readOutput = false; // we don't read output + if (userInput) + free(userInput); + continue; + } + //gdbProc->writeInput(userInput); + writeToDebugger(userInput); // send user command to GDB + } + readOutput = true; + } +} + +/** + * FIXME: create class to manage OMPD (or ODB) commands + * FIXME: Commands should be renamed to ODB? + */ +void InputOutputManager::processOMPDCommand(const char *str) +{ + vector params; + tokenize(str, params, " \t"); + + OMPDCommand *command; + if (params.size() > 1) + { + if (params.size() > 2) + { + auto i=params.begin(); + i+=2; + std::vector extraArgs(i, params.end()); + command = commandFactory->create(params[1].c_str(), extraArgs); + } + else + command = commandFactory->create(params[1].c_str()); + } + else + command = commandFactory->create("None"); // in case no command is passed + + command->execute(); +} + +string InputOutputManager::readFromDebugger() +{ + return gdbProc->readOutput(); +} + +void InputOutputManager::writeToDebugger(const char* str) +{ + gdbProc->writeInput(str); +} diff --git a/libompd/gdb-wrapper/InputOutputManager.h b/libompd/gdb-wrapper/InputOutputManager.h new file mode 100644 index 000000000..f35a0e7e6 --- /dev/null +++ b/libompd/gdb-wrapper/InputOutputManager.h @@ -0,0 +1,62 @@ +/* + * InputOutputManager.h + * + * Created on: Jan 7, 2015 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#ifndef GDB_INPUTOUTPUTMANAGER_H_ +#define GDB_INPUTOUTPUTMANAGER_H_ + +#include "InputChecker.h" +#include "StringParser.h" +#include "GdbProcess.h" +#include "OMPDCommand.h" + +#include +#include + +namespace ompd_gdb { + +class InputOutputManager +{ +private: + StringParser parser; + OMPDCommandFactoryPtr commandFactory = nullptr; + bool output; + + void initializeErrorHandlers(); + void processOMPDCommand(const char *str); + +public: + InputOutputManager(int argc, char **argv, bool output); + //~InputOutputManager(); + + /** + * Run the manager (the main loop). + */ + void run(); + + /** + * Read output from the debugger + */ + std::string readFromDebugger(); + + /** + * Write input to the debugger + */ + void writeToDebugger(const char* str); + + void finalize(); + +}; + +} + +void terminateGDB(); +void sigHandler(int signo); +void sigChildKilled(int signo); +void sigForwardGdb(int signo); + + +#endif /* GDB_INPUTOUTPUTMANAGER_H_ */ diff --git a/libompd/gdb-wrapper/OMPDCommand.cpp b/libompd/gdb-wrapper/OMPDCommand.cpp new file mode 100644 index 000000000..b1a82e67f --- /dev/null +++ b/libompd/gdb-wrapper/OMPDCommand.cpp @@ -0,0 +1,608 @@ +/* + * OMPDCommand.cpp + * + * Created on: Dec 28, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#include +#include "OMPDCommand.h" +#include "OMPDContext.h" +#include "Callbacks.h" +#include "OutputString.h" +#include "Debug.h" +#include "ompd.h" +#include "ompd_test.h" +#include "CudaGdb.h" + +#include +#include +#include +#include + +using namespace ompd_gdb; +using namespace std; + +const char * ompd_state_names[256]; +extern OMPDHostContextPool * host_contextPool; + +/* --- OMPDCommandFactory --------------------------------------------------- */ + +OMPDCommandFactory::OMPDCommandFactory() +{ + functions = OMPDFunctionsPtr(new OMPDFunctions); + +#define ompd_state_macro(state, code) ompd_state_names[code] = #state; + FOREACH_OMPD_STATE(ompd_state_macro) +#undef ompd_state_macro + + // Load OMPD DLL and get a handle +#ifdef ODB_LINUX + functions->ompdLibHandle = dlopen("libompd_intel.so", RTLD_LAZY); +#elif defined(ODB_MACOS) + functions->ompdLibHandle = dlopen("libompd_intel.dylib", RTLD_LAZY); +#else +#error Unsupported platform! +#endif + if (!functions->ompdLibHandle) + { + stringstream msg; + msg << "ERROR: could not open OMPD library.\n" << dlerror() << "\n"; + out << msg.str().c_str(); + functions->ompdLibHandle = nullptr; + exit(1); + return; + } + else + { + cerr << "OMPD library loaded\n"; + } + dlerror(); // Clear any existing error + + /* Look up OMPD API function in the library + * The Macro generates function pointer lookups for all implemented API function listed in OMPDCommand.h:41 + */ +#define OMPD_FIND_API_FUNCTION(FN) functions-> FN = \ + (FN##_fn_t) findFunctionInLibrary(#FN);\ + +FOREACH_OMPD_API_FN(OMPD_FIND_API_FUNCTION) +#undef OMPD_FIND_API_FUNCTION + + //functions->test_CB_tsizeof_prim = + // (void (*)()) findFunctionInLibrary("test_CB_tsizeof_prim"); + //functions->test_CB_dmemory_alloc = + // (void (*)()) findFunctionInLibrary("test_CB_dmemory_alloc"); + + // Initialize OMPD library + ompd_callbacks_t *table = getCallbacksTable(); + assert(table && "Invalid callbacks table"); + ompd_rc_t ret = functions->ompd_initialize(table); + if (ret != ompd_rc_ok) + { + out << "ERROR: could not initialize OMPD\n"; + } + + ret = functions->ompd_process_initialize(host_contextPool->getGlobalOmpdContext(), + /*&prochandle, */&addrhandle); + if (ret != ompd_rc_ok) + { + out << "ERROR: could not initialize target process\n"; + } +} + +OMPDCommandFactory::~OMPDCommandFactory() +{ + ompd_rc_t ret; +// ret = functions->ompd_process_finalize(prochandle); +// if (ret != ompd_rc_ok) +// { +// out << "ERROR: could not finalize target process\n"; +// } + ret = functions->ompd_release_address_space_handle(addrhandle); + if (ret != ompd_rc_ok) + { + out << "ERROR: could not finalize target address space\n"; + } +} + +void * OMPDCommandFactory::findFunctionInLibrary(const char *fun) const +{ + if (!functions->ompdLibHandle) + return nullptr; + + void *ret = dlsym(functions->ompdLibHandle, fun); + char *err = dlerror(); + if (err) + { + stringstream msg; + msg << "ERROR: could not find ompd_initialize: " << err << "\n"; + out << msg.str().c_str(); + return nullptr; + } + return ret; +} + +OMPDCommand* OMPDCommandFactory::create(const char *str, const vector& extraArgs) const +{ + if (strcmp(str, "test") == 0) + return new OMPDTestCallbacks(functions, addrhandle, extraArgs); + else if (strcmp(str, "threads") == 0) + return new OMPDThreads(functions, addrhandle, extraArgs); + else if (strcmp(str, "levels") == 0) + return new OMPDLevels(functions, addrhandle, extraArgs); + else if (strcmp(str, "callback") == 0) + return new OMPDCallback(functions, addrhandle, extraArgs); + else if (strcmp(str, "api") == 0) + return new OMPDApi(functions, addrhandle, extraArgs); + else if (strcmp(str, "testapi") == 0) + return new OMPDTest(functions, addrhandle, extraArgs); + + return new OMPDNull; +} + +/* --- OMPDNull ------------------------------------------------------------- */ + +void OMPDNull::staticExecute() +{ + hout << "Null odb command\n"; +} + +void OMPDNull::execute() const +{ + staticExecute(); +} + +const char* OMPDNull::toString() const +{ + return "NULL"; +} + +/* --- OMPDTestCallbacks ---------------------------------------------------- */ + +void OMPDTestCallbacks::execute() const +{ + // If any function is null, execute a null command + if (!functions->test_CB_tsizeof_prim || + !functions->test_CB_dmemory_alloc) + { + OMPDNull::staticExecute(); + return; + } + + // Call all test functions in OMPD + functions->test_CB_tsizeof_prim(); + functions->test_CB_dmemory_alloc(); +} + +const char* OMPDTestCallbacks::toString() const +{ + return "odb test"; +} + +/* --- OMPDThreads ---------------------------------------------------------- */ + +void OMPDThreads::execute() const +{ + printf("\nHOST THREADS\n"); + printf("Debugger_handle Thread_handle System_thread\n"); + printf("--------------------------------------------------\n"); + + auto thread_ids = getThreadIDsFromDebugger(); + for(auto i: thread_ids) { + ompd_thread_handle_t* thread_handle; + ompd_rc_t ret = functions->ompd_get_thread_handle( + addrhandle, ompd_osthread_pthread, sizeof(i.second), + &(i.second), &thread_handle); + if (ret == ompd_rc_ok) + { + ompd_state_t state; + ompd_wait_id_t wait_id; + ret = functions->ompd_get_state(thread_handle, &state, &wait_id); + printf(" %-12u %p 0x%lx\t%i\t%lx\n", + (unsigned int)i.first, thread_handle, i.second, state, wait_id); + } + else + { + printf(" %-12u %-12s %-12s\n", (unsigned int)i.first, "-", "-"); + } + } + + CudaGdb cuda; + int omp_cuda_threads = 0; + vector cuda_ContextPools; + map device_initialized; + map address_spaces; + + for(auto i: cuda.threads) { + if (!device_initialized[i.coord.cudaContext]) { + OMPDCudaContextPool* cpool; + cpool = new OMPDCudaContextPool(&i); + ompd_rc_t result; + + device_initialized[i.coord.cudaContext] = true; + result = functions->ompd_device_initialize( + cpool->getGlobalOmpdContext(), + i.coord.cudaContext, + ompd_device_kind_cuda, + &cpool->ompd_device_handle); + + if (result != ompd_rc_ok) + continue; + + address_spaces[i.coord.cudaContext] = cpool->ompd_device_handle; + } + + ompd_thread_handle_t* thread_handle; + ompd_rc_t ret = functions->ompd_get_thread_handle( + address_spaces[i.coord.cudaContext], + ompd_osthread_cudalogical, + sizeof(i.coord), &i.coord, + &thread_handle); + + if (ret == ompd_rc_ok) + omp_cuda_threads++; + } + + if (cuda.threads.size() != 0) { + cout << cuda.threads.size() << " CUDA Threads Found, " + << omp_cuda_threads << " OMP Threads\n"; + } +} + +const char* OMPDThreads::toString() const +{ + return "odb threads"; +} + + +/* --- OMPDLevels ----------------------------------------------------------- */ + +void OMPDLevels::execute() const +{ +/* ompd_size_t num_os_threads; + ompd_rc_t ret = CB_num_os_threads(contextPool->getGlobalOmpdContext(), &num_os_threads); + assert(ret==ompd_rc_ok && "Error calling OMPD!"); + ompd_osthread_t* osThreads = (ompd_osthread_t*) + malloc(sizeof(ompd_osthread_t)*num_os_threads); + ret = CB_get_os_threads (contextPool->getGlobalOmpdContext(), &num_os_threads, &osThreads); + assert(ret==ompd_rc_ok && "Error calling OMPD!"); + + printf("\n"); + printf("Thread_handle Nesting_level\n"); + printf("-------------------------------\n"); + for (size_t i=0; i < num_os_threads; ++i) + { + ompd_thread_handle_t thread_handle; + ret = functions->ompd_get_thread_handle( + contextPool->getGlobalOmpdContext(), &(osThreads[i]), &thread_handle); + if (ret == ompd_rc_ok) + { + ompd_tword_t level=0; + ret = functions->ompd_nesting_level( + contextPool->getGlobalOmpdContext(), &thread_handle, &level); + printf("%-12u %ld\n", (unsigned int)thread_handle, level); + } + }*/ +} + +const char* OMPDLevels::toString() const +{ + return "odb levels"; +} + + +/* --- OMPDCallback ----------------------------------------------------------- */ + +ompd_target_prim_types_t get_prim_type_from_string(const string& str) +{ + const char * names[ompd_type_max] = { + "CHAR", + "SHORT", + "INT", + "LONG", + "LONG_LONG", + "POINTER" + }; + for (int i = 0; 0\" to get more help on the usage" << endl; + return; + } + +/*ompd_rc_t CB_read_tmemory ( + ompd_context_t *context, + ompd_taddr_t addr, + ompd_tword_t bufsize, + void *buffer + );*/ + if (extraArgs[0] == "read_tmemory") + { + if(extraArgs.size()<4) + { + hout << "Usage: odb callback read_tmemory " << endl; + return; + } + long long temp=0; + ompd_taddr_t addr = (ompd_taddr_t)strtoll(extraArgs[1].c_str(), NULL, 0); + int cnt = atoi(extraArgs[2].c_str()); + ret = CB_read_tmemory( + host_contextPool->getGlobalOmpdContext(), NULL, {0,addr}, cnt, &temp); + if (ret != ompd_rc_ok) + return; + sout << "0x" << hex << temp << endl; + } + +/*ompd_rc_t CB_tsymbol_addr ( + ompd_context_t *context, + const char *symbol_name, + ompd_taddr_t *symbol_addr);*/ + + if (extraArgs[0] == "tsymbol_addr") + { + if(extraArgs.size()<2) + { + hout << "Usage: odb callback tsymbol_addr " << endl; + return; + } + ompd_address_t temp={0,0}; + ret = CB_tsymbol_addr( + host_contextPool->getGlobalOmpdContext(), NULL, extraArgs[1].c_str(), &temp); + if (ret != ompd_rc_ok) + return; + sout << "0x" << hex << temp.address << endl; + } + +} + +const char* OMPDCallback ::toString() const +{ + return "odb callback"; +} + +void OMPDApi::execute() const +{ + ompd_rc_t ret; + + if (extraArgs.empty() || extraArgs[0] == "help") + { + hout << "API functions available: read_tmemory, ttype, ttype_sizeof, ttype_offset, tsymbol_addr" << endl + << "Use \"odb api \" to get more help on the usage" << endl; + return; + } + +//ompd_rc_t ompd_get_threads ( +// ompd_context_t *context, /* IN: debugger handle for the target */ +// ompd_thread_handle_t **thread_handle_array, /* OUT: array of handles */ +// ompd_size_t *num_handles /* OUT: number of handles in the array */ +// ); + + if (extraArgs[0] == "get_threads") + { + if(extraArgs.size()>1) + { + hout << "Usage: odb api get_threads" << endl; + return; + } + ompd_thread_handle_t ** thread_handle_array; + int num_handles; + + + ret = functions->ompd_get_threads ( + addrhandle, &thread_handle_array, &num_handles); + if (ret != ompd_rc_ok) + return; + sout << num_handles << " OpenMP threads:" << endl; + for (int i=0; i odbGetThreadHandles(ompd_address_space_handle_t* addrhandle, OMPDFunctionsPtr functions) +{ + ompd_rc_t ret; + auto thread_ids = getThreadIDsFromDebugger(); + vector thread_handles; + for(auto i: thread_ids) + { + ompd_thread_handle_t* thread_handle; + ret = functions->ompd_get_thread_handle( + addrhandle, ompd_osthread_pthread, sizeof(i.second) ,&(i.second), &thread_handle); + if (ret!=ompd_rc_ok) + continue; + thread_handles.push_back(thread_handle); + } + return thread_handles; +} + +vector odbGetParallelRegions(OMPDFunctionsPtr functions, ompd_thread_handle_t* &th) +{ + ompd_rc_t ret; + ompd_parallel_handle_t * parallel_handle; + vector parallel_handles; + ret = functions->ompd_get_top_parallel_region( + th, ¶llel_handle); + while(ret == ompd_rc_ok) + { + parallel_handles.push_back(parallel_handle); + ret = functions->ompd_get_enclosing_parallel_handle( + parallel_handle, ¶llel_handle); + } + return parallel_handles; +} + +bool odbCheckParallelIDs(OMPDFunctionsPtr functions, vector phs) +{ + bool res=true; +// ompd_rc_t ret; + int i=0; + uint64_t ompt_res, ompd_res; +// ((OMPDContext*)context)->setThisGdbContext(); + for (auto ph : phs) + { + stringstream ss; + ss << "p ompt_get_parallel_id(" << i << ")"; + ompt_res = evalGdbExpression(ss.str()); + /*ret = */functions->ompd_get_parallel_id(ph, &ompd_res); + sout << " parallelid ompt: " << ompt_res << " ompd: " << ompd_res << endl; + i++; + if (ompt_res != ompd_res) res=false; + } + return res; +} + +bool odbCheckParallelNumThreads(OMPDFunctionsPtr functions, vector phs) +{ + bool res=true; +// ompd_rc_t ret; + int i=0; + uint64_t ompt_res, ompd_res; +// ((OMPDContext*)context)->setThisGdbContext(); + for (auto ph : phs) + { + stringstream ss; + ss << "p ompt_get_num_threads(" << i << ")"; + ompt_res = evalGdbExpression(ss.str()); + /*ret = */functions->ompd_get_parallel_id(ph, &ompd_res); + sout << " parallelid ompt: " << ompt_res << " ompd: " << ompd_res << endl; + i++; + if (ompt_res != ompd_res) res=false; + } + return res; +} + +bool odbCheckTaskIDs(OMPDFunctionsPtr functions, vector ths) +{ + bool res=true; +// ompd_rc_t ret; + int i=0; + uint64_t ompt_res, ompd_res; +// ((OMPDContext*)context)->setThisGdbContext(); + for (auto th : ths) + { + stringstream ss; + ss << "p ompt_get_task_id(" << i << ")"; + ompt_res = evalGdbExpression(ss.str()); + /*ret =*/ functions->ompd_get_task_id(th, &ompd_res); + sout << " taskid ompt: " << ompt_res << " ompd: " << ompd_res << endl; + i++; + if (ompt_res != ompd_res) res=false; + } + return res; +} + +vector odbGetTaskRegions(OMPDFunctionsPtr functions, ompd_thread_handle_t* th) +{ + ompd_rc_t ret; + ompd_task_handle_t * task_handle; + vector task_handles; + ret = functions->ompd_get_top_task_region( + th, &task_handle); + while(ret == ompd_rc_ok) + { + task_handles.push_back(task_handle); + ret = functions->ompd_get_ancestor_task_region( + task_handle, &task_handle); + } + return task_handles; +} + +vector odbGetImplicitTasks(OMPDFunctionsPtr functions, ompd_parallel_handle_t* ph) +{ +// ompd_rc_t ret; + ompd_task_handle_t** task_handles; + int num_tasks; + vector return_handles; + /*ret = */functions->ompd_get_implicit_task_in_parallel( + ph, &task_handles, &num_tasks); + for(int i=0; i1) + { + hout << "Usage: odb testapi threads" << endl; + return; + } + + + auto thread_handles = odbGetThreadHandles(addrhandle, functions); + for(auto thr_h: thread_handles) + { + auto parallel_h = odbGetParallelRegions(functions, thr_h); + auto task_h = odbGetTaskRegions(functions, thr_h); + + sout << "Thread handle: 0x" << hex << thr_h << endl << "Parallel: "; + for(auto ph: parallel_h) + { + sout << "Parallel handle: 0x" << hex << ph << endl; + sout << "implicit Tasks: "; + auto implicit_task_h = odbGetImplicitTasks(functions, ph); + for(auto ith: implicit_task_h) + { + uint64_t tid; + functions->ompd_get_task_id( + ith, &tid); + sout << "0x" << hex << ith << " (" << tid << "), "; + functions->ompd_release_task_handle(ith); + } + sout << endl; + } + sout << endl << "Tasks: "; + for(auto th: task_h){ + sout << "0x" << hex << th << ", "; + } + sout << endl; + pthread_t osthread; + functions->ompd_get_osthread(thr_h, ompd_osthread_pthread, sizeof(pthread_t), &osthread); + host_contextPool->getThreadContext(&osthread)->setThisGdbContext(); + odbCheckParallelIDs(functions, parallel_h); + odbCheckTaskIDs(functions, task_h); + for(auto ph: parallel_h) + functions->ompd_release_parallel_handle(ph); + for(auto th: task_h) + functions->ompd_release_task_handle(th); + functions->ompd_release_thread_handle(thr_h); + } + } + + +} + +const char* OMPDTest::toString() const +{ + return "odb api"; +} diff --git a/libompd/gdb-wrapper/OMPDCommand.h b/libompd/gdb-wrapper/OMPDCommand.h new file mode 100644 index 000000000..04e8bf912 --- /dev/null +++ b/libompd/gdb-wrapper/OMPDCommand.h @@ -0,0 +1,278 @@ +/* + * OMPDCommand.h + * + * Created on: Dec 28, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#ifndef GDB_OMPDCOMMAND_H_ +#define GDB_OMPDCOMMAND_H_ + +/******************************************************************************* + * These classes implement ompd commands for GDB. + * Commands start with the "ompd" word followed by the command name. Thus, each + * command comprises two words only in this format: "ompd [COMMAND]". + * + * There is a command factory that must be instantiated to create commands. + * Instantiating the factory class allows loading the DLLs that provide + * OMPD function calls (and looking up these functions). + * + * All commands are derived from the OMPDCommand class. There is a null command + * (OMPDNull) that is used when an invalid command is entered or when a regular + * command cannot be executed (for any reason). + */ + +#include "OutputString.h" +#include +#include +#include +#include +#include +#include "ompd.h" +#include "ompd_typedefs.h" +#include "ompd_test.h" + + +/* + * The macro is used to create code to register all implemented ompd + * API functions with the CommandFactory + * For new implemented API function just add a new OMPD_DO line + */ + + +#define FOREACH_OMPD_CALLBACK_FN(macro) \ +macro(ompd_dmemory_alloc) \ +macro(ompd_dmemory_free) \ +macro(ompd_tsizeof_prim) \ +macro(ompd_tsymbol_addr) \ +macro(ompd_ttype) \ +macro(ompd_ttype_sizeof) \ +macro(ompd_ttype_offset) \ +macro(ompd_tmemory_access) \ +macro(ompd_print_string) + +#define FOREACH_OMPD_API_FN(macro) \ +macro(ompd_process_initialize) \ +macro(ompd_device_initialize) \ +macro(ompd_release_address_space_handle) \ +macro(ompd_initialize) \ +macro(ompd_finalize) \ +macro(ompd_get_threads) \ +macro(ompd_get_thread_in_parallel) \ +macro(ompd_release_thread_handle) \ +macro(ompd_thread_handle_compare) \ +macro(ompd_get_top_parallel_region) \ +macro(ompd_get_enclosing_parallel_handle) \ +macro(ompd_get_task_enclosing_parallel_handle) \ +macro(ompd_release_parallel_handle) \ +macro(ompd_parallel_handle_compare) \ +macro(ompd_get_top_task_region) \ +macro(ompd_get_ancestor_task_region) \ +macro(ompd_get_implicit_task_in_parallel) \ +macro(ompd_release_task_handle) \ +macro(ompd_task_handle_compare) \ +macro(ompd_get_num_procs) \ +macro(ompd_get_thread_limit) \ +macro(ompd_get_num_threads) \ +macro(ompd_get_level) \ +macro(ompd_get_active_level) \ +macro(ompd_get_parallel_id) \ +macro(ompd_get_parallel_function) \ +macro(ompd_get_thread_handle) \ +macro(ompd_get_osthread) \ +macro(ompd_get_state) \ +macro(ompd_get_max_threads) \ +macro(ompd_get_thread_num) \ +macro(ompd_in_parallel) \ +macro(ompd_in_final) \ +macro(ompd_get_dynamic) \ +macro(ompd_get_nested) \ +macro(ompd_get_max_active_levels) \ +macro(ompd_get_schedule) \ +macro(ompd_get_proc_bind) \ +macro(ompd_get_task_frame) \ +macro(ompd_get_task_id) \ +macro(ompd_get_version) \ +macro(ompd_get_version_string) \ + + +namespace ompd_gdb { + +/** + * Function pointers of OMPD function calls. These functions are used by the + * OMPD commands that our gdb warper supports. + */ +typedef struct +{ + /* Handle of OMPD DLL */ + void *ompdLibHandle = nullptr; + + + /* Test function calls (only from the ompd_test library) */ + void (*test_CB_dmemory_alloc)() = nullptr; + void (*test_CB_tsizeof_prim)() = nullptr; + + /* OMPD API function pointer + * The Macro generates function pointer for all implemented API function listed in OMPDCommand.h:41 + */ +#define OMPD_API_FUNCTION_POINTER_MEMBER(FN) FN##_fn_t FN = nullptr; +FOREACH_OMPD_API_FN(OMPD_API_FUNCTION_POINTER_MEMBER) +#undef OMPD_API_FUNCTION_POINTER_MEMBER + +/* ompd_rc_t (*ompd_initialize) (ompd_callbacks_t *) = nullptr; + ompd_get_thread_handle_fn_t ompd_get_thread_handle = nullptr; + ompd_nesting_level_fn_t ompd_nesting_level = nullptr; + ompd_read_tmemory_fn_t ompd_read_tmemory = nullptr; +*/ + +} OMPDFunctions; + +typedef std::shared_ptr OMPDFunctionsPtr; + +class OMPDCommand; + +class OMPDCommandFactory +{ +private: + void * findFunctionInLibrary(const char *fun) const; + OMPDFunctionsPtr functions = nullptr; +// ompd_process_handle_t* prochandle = nullptr; + ompd_address_space_handle_t* addrhandle = nullptr; + OutputString out; + +public: + OMPDCommandFactory(); + ~OMPDCommandFactory(); +// OMPDCommand* create(const char *str) const; + OMPDCommand* create(const char *str, const std::vector& extraArgs=std::vector()) const; +}; + +typedef std::unique_ptr OMPDCommandFactoryPtr; + +/** + * Abstract class for OMPD command of the type: "ompd [COMMAND]" + */ +class OMPDCommand +{ +protected: + OMPDFunctionsPtr functions = nullptr; + ompd_address_space_handle_t* addrhandle = nullptr; + std::vector extraArgs; +public: + OMPDCommand(): extraArgs(){} + OMPDCommand(const std::vector& args): extraArgs(args){} + OMPDCommand(const OMPDFunctionsPtr &f, ompd_address_space_handle_t* ah, const std::vector& args) : functions(f), addrhandle(ah), extraArgs(args) {}; + virtual ~OMPDCommand(){} + virtual void execute() const = 0; + virtual const char* toString() const = 0; +}; + +/** + * Null command. + * This command doesn't do anything useful. It should be called when an invalid + * ompd command is requested by the user. + */ +class OMPDNull : public OMPDCommand +{ +public: + ~OMPDNull(){}; + void execute() const; + static void staticExecute(); + const char* toString() const; +}; + +/** + * COMMAND: "ompd test" + * This command tests all the debugger callbacks and print useful information + * about them. This is to be used when we want to test that callbacks are + * functioning properly. + */ +class OMPDTestCallbacks : public OMPDCommand +{ +public: + ~OMPDTestCallbacks(){}; + void execute() const; + const char* toString() const; +protected: + OMPDTestCallbacks(const OMPDFunctionsPtr &f, ompd_address_space_handle_t* ah, const std::vector& args) : OMPDCommand(f, ah, args){}; + + friend OMPDCommandFactory; +}; + + +class OMPDSpaces : public OMPDCommand +{ +public: + ~OMPDSpaces(){}; + void execute() const; + const char* toString() const; +protected: + OMPDSpaces(const OMPDFunctionsPtr &f, ompd_address_space_handle_t* ah, const std::vector& args) : OMPDCommand(f, ah, args){}; + + friend OMPDCommandFactory; +}; + +class OMPDThreads : public OMPDCommand +{ +public: + ~OMPDThreads(){}; + void execute() const; + const char* toString() const; +protected: + OMPDThreads(const OMPDFunctionsPtr &f, ompd_address_space_handle_t* ah, const std::vector& args) : OMPDCommand(f, ah, args){}; + + friend OMPDCommandFactory; +}; + + +class OMPDLevels : public OMPDCommand +{ +public: + ~OMPDLevels(){}; + void execute() const; + const char* toString() const; +protected: + OMPDLevels(const OMPDFunctionsPtr &f, ompd_address_space_handle_t* ah, const std::vector& args) : OMPDCommand(f, ah, args){}; + + friend OMPDCommandFactory; +}; + +class OMPDCallback : public OMPDCommand +{ +public: + ~OMPDCallback(){}; + void execute() const; + const char* toString() const; +protected: + OMPDCallback(const OMPDFunctionsPtr &f, ompd_address_space_handle_t* ah, const std::vector& args) : OMPDCommand(f, ah, args){}; + + friend OMPDCommandFactory; +}; + +class OMPDApi : public OMPDCommand +{ +public: + ~OMPDApi(){}; + void execute() const; + const char* toString() const; +protected: + OMPDApi(const OMPDFunctionsPtr &f, ompd_address_space_handle_t* ah, const std::vector& args) : OMPDCommand(f, ah, args){}; + + friend OMPDCommandFactory; +}; + +class OMPDTest : public OMPDCommand +{ +public: + ~OMPDTest(){}; + void execute() const; + const char* toString() const; +protected: + OMPDTest(const OMPDFunctionsPtr &f, ompd_address_space_handle_t* ah, const std::vector& args) : OMPDCommand(f, ah, args){}; + + friend OMPDCommandFactory; +}; + +} + +#endif /* GDB_OMPDCOMMAND_H_ */ diff --git a/libompd/gdb-wrapper/OMPDContext.cpp b/libompd/gdb-wrapper/OMPDContext.cpp new file mode 100644 index 000000000..9b92e0d13 --- /dev/null +++ b/libompd/gdb-wrapper/OMPDContext.cpp @@ -0,0 +1,163 @@ +/* + * OMPDContext.cpp + * + * Created on: Apr 24, 2015 + * Author: Joachim Protze + * Contact: protze1@llnl.gov + */ + +#include "OMPDContext.h" +#include "CudaGdb.h" +#include +#include +#include +#include +#include + +using namespace ompd_gdb; +using namespace std; + +static StringParser parser; +// +// Host context +OMPDHostContextPool* OMPDHostContext::cp=NULL; +OMPDHostContextPool* OMPDCudaContext::host_cp=NULL; +GdbProcessPtr OMPDContextPool::gdb=NULL; + +OMPDHostContextPool::OMPDHostContextPool(GdbProcessPtr gdb) +{ + contexts.resize( 1 ); + contexts[0] = new OMPDHostContext(0); + OMPDHostContext::cp = this; + OMPDContextPool::gdb = gdb; + cachedthread = nullptr; +} + +OMPDContext* OMPDHostContextPool::getThreadContext(gdb_thread_id& thr_id) +{ + if ( contexts.size() < thr_id + 1 ) { + contexts.resize( thr_id + 1, nullptr ); + contexts[thr_id] = new OMPDHostContext{thr_id}; + } + else if (contexts[thr_id] == nullptr) { + contexts[thr_id] = new OMPDHostContext{thr_id}; + } + cachedthread = contexts[thr_id]; + return contexts[thr_id]; +} + +OMPDContext* OMPDHostContextPool::getFirstThreadContext() +{ + if (cachedthread == nullptr) { + auto threads = getThreadIDsFromDebugger(); + cachedthread = getThreadContext(threads[0].first); + } + return cachedthread; +} + +OMPDContext* OMPDHostContextPool::getThreadContext(pthread_t* osthread) +{ + for(auto threads : getThreadIDsFromDebugger()) + if (threads.second == *(uint64_t *)(osthread)) + return getThreadContext(threads.first); + return NULL; +} + +ompd_thread_context_t* OMPDHostContextPool::getThreadOmpdContext(gdb_thread_id& thr_id) +{ + return (ompd_thread_context_t*)getThreadContext(thr_id); +} + +ompd_thread_context_t* OMPDHostContextPool::getThreadOmpdContext(pthread_t* osthread) +{ + return (ompd_thread_context_t*)getThreadContext(osthread); +} + +ompd_address_space_context_t* OMPDHostContextPool::getGlobalOmpdContext() +{ + return (ompd_address_space_context_t*)contexts[0]; +} + +ompd_thread_context_t* OMPDHostContextPool::getCurrentOmpdContext() +{ + OMPDContextPool::gdb->writeInput("thread"); + string gdbOut = OMPDContextPool::gdb->readOutput(); + int thread_id = parser.matchThreadID(gdbOut.c_str()); + if ((unsigned int)thread_id >= contexts.size()) + return (ompd_thread_context_t*)contexts[0]; + return (ompd_thread_context_t*)contexts[thread_id]; +} + +// Cuda specialization +OMPDCudaContextPool::OMPDCudaContextPool(CudaThread* cthread) +{ + OMPDCudaContext::host_cp = OMPDHostContext::cp; // Assumes Host Context always there first + + contexts.insert( pair (0, new OMPDCudaContext{this, cthread}) ); +} + +OMPDContext* OMPDCudaContextPool::getThreadContext(CudaThread* thr_id) +{ + if (contexts.find(thr_id) == contexts.end()) + contexts.insert ( pair (thr_id, new OMPDCudaContext{this, thr_id}) ); + return contexts.find(thr_id)->second; +} + +ompd_thread_context_t* OMPDCudaContextPool::getThreadOmpdContext(CudaThread* cuda_thread) +{ + return (ompd_thread_context_t*)getThreadContext(cuda_thread); +} + +ompd_address_space_context_t* OMPDCudaContextPool::getGlobalOmpdContext() +{ + return (ompd_address_space_context_t*)contexts.find(0)->second; +} + +bool OMPDHostContext::setThisGdbContext() +{ + bool ret = false; + + stringstream command; + command << "thread " << (this->thread); + OMPDContextPool::gdb->writeInput(command.str().c_str()); + string gdbOut = OMPDContextPool::gdb->readOutput(); + if (gdbOut.find("not known")==0) + ret = true; + return ret; +} + +ompd_thread_context_t* OMPDHostContext::getContextForThread(pthread_t* _osthread) +{ + return cp->getThreadOmpdContext(_osthread); +} + + +ompd_thread_context_t * OMPDHostContext::getContextForThread(gdb_thread_id& thr_id) +{ + return cp->getThreadOmpdContext(thr_id); +} + +bool OMPDCudaContext::setThisGdbContext() +{ + bool ret = false; + stringstream command; + command +#ifdef HACK_FOR_CUDA_GDB + << "cuda device " << this->cudathread->coord.cudaDevId + << " grid " << this->cudathread->coord.gridId +#else + << "cuda kernel " << this->cudathread->coord.kernelId +#endif + << " block " << this->cudathread->coord.blockIdx.x + << " thread " << this->cudathread->coord.threadIdx.x; + OMPDContextPool::gdb->writeInput(command.str().c_str()); + string gdbOut = OMPDContextPool::gdb->readOutput(); + if (gdbOut.find("not known")==0) + ret = true; + return ret; +} + +ompd_thread_context_t * OMPDCudaContext::getContextForThread(CudaThread* cthread_id) +{ + return cp->getThreadOmpdContext(cthread_id); +} diff --git a/libompd/gdb-wrapper/OMPDContext.h b/libompd/gdb-wrapper/OMPDContext.h new file mode 100644 index 000000000..be3142439 --- /dev/null +++ b/libompd/gdb-wrapper/OMPDContext.h @@ -0,0 +1,129 @@ +/* + * OMPDContext.h + * + * Created on: Apr 24, 2015 + * Author: Joachim Protze + * Contact: protze1@llnl.gov + */ +#ifndef GDB_OMPDCONTEXT_H_ +#define GDB_OMPDCONTEXT_H_ + +/******************************************************************************* + * This class implements the ompd context handle for GDB. + * The context provides information about the process, the selected thread + * and other information that reflects the current state of the debuggers + * context. + */ + +#include "ompd.h" +#include "ompd_test.h" +#include "GdbProcess.h" +#include "Callbacks.h" +#include "CudaGdb.h" + +#include +#include +#include +#include +#include +#include + +typedef uint32_t gdb_thread_id; + +namespace ompd_gdb { + +class OMPDContext; +class OMPDHostContext; +class OMPDCudaContext; + +class OMPDContextPool +{ +public: + static GdbProcessPtr gdb; + virtual ompd_address_space_context_t* getGlobalOmpdContext() = 0; +}; + +class OMPDContext +{ +friend class OMPDHostContextPool; +friend class OMPDCudaContextPool; +public: + virtual bool setThisGdbContext() = 0; + + virtual ompd_thread_context_t* getContextForThread(gdb_thread_id& thr_handle) { return nullptr; } + virtual ompd_thread_context_t* getContextForThread(CudaThread* cuda_thr) { return nullptr; } + virtual ompd_thread_context_t* getContextForThread(pthread_t* osthread) { return nullptr; } +}; + +class OMPDHostContextPool: public OMPDContextPool +{ +private: + std::vector contexts; + OMPDContext* cachedthread; // Arbitrarily picked first thread + +public: + OMPDContext* getThreadContext(gdb_thread_id& thr_handle); + OMPDContext* getThreadContext(pthread_t* osthread); + ompd_thread_context_t* getThreadOmpdContext(gdb_thread_id& thr_handle); + ompd_thread_context_t* getThreadOmpdContext(pthread_t* osthread); + ompd_address_space_context_t* getGlobalOmpdContext(); + ompd_thread_context_t* getCurrentOmpdContext(); + OMPDContext* getFirstThreadContext(void); + OMPDHostContextPool(GdbProcessPtr gdb); +}; + +class OMPDHostContext: public OMPDContext +{ +friend class OMPDHostContextPool; + +private: + gdb_thread_id thread; + +public: + static OMPDHostContextPool* cp; + + OMPDHostContext(gdb_thread_id t): thread(t) {} + + bool setThisGdbContext(); + +/** + * Get a context for given os thread handle + */ + ompd_thread_context_t* getContextForThread(gdb_thread_id& thr_handle); + ompd_thread_context_t* getContextForThread(pthread_t* osthread); +}; + +class OMPDCudaContext; + +// We allocate a separate pool per Cuda Device (CUDA Context) +class OMPDCudaContextPool: public OMPDContextPool +{ +private: + std::map contexts; + +public: + ompd_address_space_handle_t *ompd_device_handle; + OMPDContext* getThreadContext(CudaThread* cuda_thread); + ompd_thread_context_t* getThreadOmpdContext(CudaThread* cuda_thread); + ompd_address_space_context_t* getGlobalOmpdContext(); + OMPDCudaContextPool(CudaThread* cuda_thread); +}; + +class OMPDCudaContext: public OMPDContext +{ +friend class OMPDCudaContextPool; +private: + OMPDCudaContext(OMPDCudaContextPool* _cp, CudaThread* cuda_thread): + cp(_cp), cudathread(cuda_thread) {} + +public: + static OMPDHostContextPool* host_cp; // Only one Host Context Pool + OMPDCudaContextPool* cp; // One per cuda device + CudaThread *cudathread; + + bool setThisGdbContext(); /* Make this context active in gdb */ + ompd_thread_context_t* getContextForThread(CudaThread* cuda_thr); +}; +} + +#endif /* GDB_OMPDCONTEXT_H_ */ diff --git a/libompd/gdb-wrapper/OutputString.cpp b/libompd/gdb-wrapper/OutputString.cpp new file mode 100644 index 000000000..bd45dcd61 --- /dev/null +++ b/libompd/gdb-wrapper/OutputString.cpp @@ -0,0 +1,27 @@ +/* + * OutputString.cpp + * + * Created on: Jan 9, 2015 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "OutputString.h" +#include +#include + +using namespace ompd_gdb; +using namespace std; + +OutputString::OutputString() +{ + char * val = getenv("OBD_DO_NOT_USE_STDOUT"); + useSTDOUT = val ? false : true; +} + +void OutputString::operator <<(const char *str) const +{ + if (useSTDOUT) + cout << str; +} + diff --git a/libompd/gdb-wrapper/OutputString.h b/libompd/gdb-wrapper/OutputString.h new file mode 100644 index 000000000..73cf3a8ef --- /dev/null +++ b/libompd/gdb-wrapper/OutputString.h @@ -0,0 +1,24 @@ +/* + * OutputString.h + * + * Created on: Jan 9, 2015 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#ifndef GDB_OUTPUTSTRING_H_ +#define GDB_OUTPUTSTRING_H_ + +namespace ompd_gdb { + +class OutputString +{ +private: + bool useSTDOUT = true; +public: + OutputString(); + void operator << (const char *str) const; +}; + +} + +#endif /* GDB_OUTPUTSTRING_H_ */ diff --git a/libompd/gdb-wrapper/ProcessSpawn.cpp b/libompd/gdb-wrapper/ProcessSpawn.cpp new file mode 100644 index 000000000..a7560780a --- /dev/null +++ b/libompd/gdb-wrapper/ProcessSpawn.cpp @@ -0,0 +1,115 @@ +/* + * ProcessSpawn.cpp + * + * Created on: Dec 17, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "ProcessSpawn.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ompd_gdb; +using namespace __gnu_cxx; + +/* + * ---------------------------------------------------------------------------- + * Pipe class methods + * ---------------------------------------------------------------------------- + */ +Pipe::Pipe() +{ + if (pipe(fd)) + throw std::runtime_error("Couldn't create a pipe!"); +} + +const int Pipe::readFd() const +{ + return fd[0]; +} + +const int Pipe::writeFd() const +{ + return fd[1]; +} + + +void Pipe::close() +{ + ::close(fd[0]); + ::close(fd[1]); +} + +Pipe::~Pipe() +{ + close(); +} + +/* + * ---------------------------------------------------------------------------- + * ProcessSpawn class methods + * ---------------------------------------------------------------------------- + */ +ProcessSpawn::ProcessSpawn(const char* const argv[]): stdin(NULL), stdout(NULL) +{ + childPid = fork(); + if (childPid == -1) + throw std::runtime_error("Couldn't start child process!"); + + if (childPid == 0) // Child process + { + dup2(writePipe.readFd(), STDIN_FILENO); + dup2(readPipe.writeFd(), STDOUT_FILENO); + dup2(readPipe.writeFd(), STDERR_FILENO); + writePipe.close(); + readPipe.close(); + + int result = execv(argv[0], const_cast(argv)); + // on successful exec we are not here anymore, so something went wrong + printf( "ERROR: could not start program '%s' return code %i\n", argv[0] , result); + exit(EXIT_FAILURE); + } + else // Parent process + { + close(writePipe.readFd()); + close(readPipe.writeFd()); + writeBuf = std::unique_ptr> + (new stdio_filebuf(writePipe.writeFd(), std::ios::out)); + readBuf = std::unique_ptr> + (new stdio_filebuf(readPipe.readFd(), std::ios::in)); + stdin.rdbuf(writeBuf.get()); + stdout.rdbuf(readBuf.get()); + } +} + + +void ProcessSpawn::sendEOF() +{ + writeBuf->close(); +} + + +void ProcessSpawn::sendSignal(int signal) +{ + kill(childPid, signal); +} + + +int ProcessSpawn::wait() +{ + int status; + waitpid(childPid, &status, 0); + return status; +} + diff --git a/libompd/gdb-wrapper/ProcessSpawn.h b/libompd/gdb-wrapper/ProcessSpawn.h new file mode 100644 index 000000000..6a219af0f --- /dev/null +++ b/libompd/gdb-wrapper/ProcessSpawn.h @@ -0,0 +1,67 @@ +/* + * ProcessSpawn.h + * + * Created on: Dec 17, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#ifndef PROCESSSPAWN_H_ +#define PROCESSSPAWN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ompd_gdb { +using namespace __gnu_cxx; + +/** + * Implements methods to handle a pipe: reading, writing and closing. + */ +class Pipe { +private: + int fd[2]; +public: + Pipe(); + const int readFd() const; + const int writeFd() const; + void close(); + ~Pipe(); +}; + +/** + * Spawns a process (a child) and implements methods to write and read from a + * pipe that is used to communicate with the child process. + */ +class ProcessSpawn { +private: + Pipe writePipe; + Pipe readPipe; +public: + int childPid = -1; + std::unique_ptr> writeBuf = nullptr; + std::unique_ptr> readBuf = nullptr; + std::ostream stdin; + std::istream stdout; + + ProcessSpawn(const char* const argv[]); + + /** Close child pipe */ + void sendEOF(); + + /** Send child a signal */ + void sendSignal(int sig); + + /** Wait for child to finish */ + int wait(); +}; + +} + +#endif /* PROCESSSPAWN_H_ */ diff --git a/libompd/gdb-wrapper/StringParser.cpp b/libompd/gdb-wrapper/StringParser.cpp new file mode 100644 index 000000000..0df120459 --- /dev/null +++ b/libompd/gdb-wrapper/StringParser.cpp @@ -0,0 +1,496 @@ +/* + * StringParser.cpp + * + * Created on: Dec 26, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "StringParser.h" +#include +#include +#include +#include +#include +#include +#include +#include "ompd.h" + +using namespace ompd_gdb; +using namespace std; + +StringParser::StringParser() +{ + // Compile regular expressions + int ret = 0; + + // To check if gdb prompt is present + ret = regcomp(&rePROMPT, "[(](cuda-)?gdb[)][ ]$", REG_EXTENDED); + assert(!ret && "Could not compile regex rePROMPT!"); + + // To check if quit command was invoked + ret = regcomp(&reQUIT, "^[ \t]*(quit){1}[ \t]*$", REG_EXTENDED); + assert(!ret && "Could not compile regex reQUIT!"); + + // To check if OMPD command was invoked + ret = regcomp(&reOMPD_COMMAND, "^[ \t]*(odb){1}[ \t]*", REG_EXTENDED); + assert(!ret && "Could not compile regex reOMPD_COMMAND!"); + + // To check to a regular value given by GDB (e.g., "$1 = 4") + ret = regcomp(&reREGULAR_VALUE, + //"^(\\$){1}[0-9]+[ ](=){1}[ ][0-9a-zA-Z]+\n", REG_EXTENDED); + "^(\\$){1}[0-9]+[ ](=){1}[ ][0-9a-zA-Z]+", REG_EXTENDED); + assert(!ret && "Could not compile regex reREGULAR_VALUE!"); + + /* To check a he address value, e.g. 0x0FFAA */ + ret = regcomp(&reADDRESS_VALUE, + "(0){1}[xX]{1}[0-9a-fA-F]+", REG_EXTENDED); + assert(!ret && "Could not compile regex reADDRESS_VALUE!"); + + // Match output of gdb when reading memory (e.g '$ x/32xb' for 32 bytes) + ret = regcomp(&reMEMORY_VALUES, + "[0-9]+", REG_EXTENDED); + assert(!ret && "Could not compile regex reMEMORY_VALUES!"); + +/* // Match output of gdb when reading memory (e.g '$ x/32xb' for 32 bytes) + ret = regcomp(&reMEMORY_VALUES, + "(0){1}[xX]{1}[0-9a-fA-F]+", REG_EXTENDED); + assert(!ret && "Could not compile regex reMEMORY_VALUES!");*/ + + /* Match thread ids in the output of "info threads"*/ + ret = regcomp(&reTHREAD_ID, "^(\\*)?[ \t]+[0-9]+[ \t]+", REG_EXTENDED); + assert(!ret && "Could not compile regex reTHREAD_ID!"); + + /* Match thread ids in the output of "info cuda contexts"*/ + ret = regcomp(&reCONTEXT_ID, "([0-9]+)[ \t]+active", REG_EXTENDED); + assert(!ret && "Could not compile regex reCONTEXT_ID!"); + + /* Match thread ids in the output of "info cuda kernels"*/ + ret = regcomp(&reKERNELS_ID, "([0-9]+)[ \t-]+([0-9]+)[ \t-]+([0-9]+)", REG_EXTENDED); + assert(!ret && "Could not compile regex reKERNELS_ID!"); + + /* Match thread ids in the output of "info cuda threads"*/ + ret = regcomp(&reBLOCKS_ID, "([0-9]+).*[ \t]+([0-9]+)[ \t]0x", REG_EXTENDED); + assert(!ret && "Could not compile regex reBLOCKS_ID!"); + + /* Match thread id in the output of "thread" + [Current thread is 1 (Thread 0x2aaaad394d60 (LWP 17641))] */ + ret = regcomp(&reTHREAD, "^\[Current thread is [0-9]+ ", REG_EXTENDED); + assert(!ret && "Could not compile regex reTHREAD!"); +} + +bool StringParser::regexpMatches(const char *str, const regex_t *re) const +{ + int ret = regexec(re, str, 0, NULL, 0); + if (!ret) + return true; + return false; +} + +bool StringParser::isOMPDCommand(const char *str) const +{ + return regexpMatches(str, &reOMPD_COMMAND); +} + +bool StringParser::isQuitCommand(const char *str) const +{ + return regexpMatches(str, &reQUIT); +} + +bool StringParser::hasGDBPrompt(const char *str) const +{ + return regexpMatches(str, &rePROMPT); +} + +void StringParser::matchRegularValue(const char *str, char *value) const +{ + bool match = regexpMatches(str, &reREGULAR_VALUE); + if (!match) // regular value not found + { + value[0] = '\0'; + return; + } + + vector tokens; + tokenize(str, tokens, "\n"); + vector v; + tokenize(tokens[0], v, " "); // get first line and tokenize by space + strcpy(value, v[2].c_str()); + value[strlen( v[2].c_str() )] = '\0'; +} + +void StringParser::matchAddressValue(const char *str, char *addr) const +{ + size_t nmatch = 1; + regmatch_t pmatch[1]; + + int ret = regexec(&reADDRESS_VALUE, str, nmatch, pmatch, 0); + if (ret) // if address not found + { + addr[0] = '\0'; + return; + } + + int size = pmatch[0].rm_eo - pmatch[0].rm_so; + //char dst[size]; + strncpy (addr, (str + pmatch[0].rm_so), size); + addr[size] = '\0'; + //return dst; +} + +vector StringParser::matchMemoryValues(const char *str) const +{ + vector ret; + + // split by \n (tokenize by lines) + string inputStr(str); + vector lines; + tokenize(inputStr, lines, "\n"); + + for (size_t i=0; i < lines.size()-1; ++i) + { + vector addresses; + tokenize(lines[i], addresses, ":"); + if (addresses.size() == 0) // error if no ':' character is found + return ret; + + int regRet = regexec(&reMEMORY_VALUES, addresses[1].c_str(), 0, NULL, 0); + + if (!regRet) + { + tokenize(addresses[1], ret, " \t"); + /*vector hexValues; + tokenize(addresses[1], hexValues, " \t"); + for (size_t k=0, e = hexValues.size(); k < e; ++k) + ret.push_back(hexValues[k]);*/ + } + else + return ret; // error if no match is found + } + + return ret; +} + +/** + * This function parses the following command in gdb: + * ---------------------------------------------------------------------------- + * (gdb) info cuda threads + * + * (cuda-gdb) info cuda threads + * BlockIdx ThreadIdx To BlockIdx ThreadIdx Count Virtual PC Filename Line + * Kernel 0 + * * (0,0,0) (0,0,0) (0,0,0) (31,0,0) 32 0x00001000086ba1b8 n/a 0 + * (0,0,0) (32,0,0) (0,0,0) (32,0,0) 1 0x00001000086b27a8 n/a 0 + * (cuda-gdb) + * ---------------------------------------------------------------------------- + * + * Returns vector of blocks of vector of threads + */ +vector StringParser::matchCudaThreadsInfo( + uint64_t ctx, uint64_t dev, uint64_t kernel, + uint64_t grid, const char *str +) const +{ + string inputStr(str); + vector lines; + tokenize(inputStr, lines, "\n"); + map threadcounts; + vector ret; + + // Do not parse the first two lines and the last line + for (size_t i=2; i < lines.size()-1; ++i) + { + string block_num; + string threadcnt; + size_t nmatch = 3; + regmatch_t pmatch[3]; + + int regRet = regexec(&reBLOCKS_ID, lines[i].c_str(), nmatch, pmatch, 0); + if (regRet) + return ret; + + block_num = lines[i].substr(pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so); + threadcnt = lines[i].substr(pmatch[2].rm_so, pmatch[2].rm_eo - pmatch[2].rm_so); + + threadcounts[atoi(block_num.c_str())] += atoi(threadcnt.c_str()); + } + + ompd_cudathread_coord_t coord; + + //coord.gridDim = _gdim_; // TODO (needed by TotalView, not GDB) + //coord.blockDim = _bdim_; // TODO (needed by TotalView, not GDB) + //coord.warpSize = _wsize_; // TODO (needed by TotalView, not GDB) + + coord.gridId = grid; + coord.cudaContext = ctx; + coord.cudaDevId = dev; + coord.kernelId = kernel; + + for (int b = 0; b < threadcounts.size(); ++b) { + coord.blockIdx.x = b; + coord.blockIdx.y = 0; + coord.blockIdx.z = 0; + for (int t = 0; t < threadcounts[b]; ++t) { + coord.threadIdx.x = t; + coord.threadIdx.y = 0; + coord.threadIdx.z = 0; + ret.push_back(CudaThread{coord}); + } + } + + return ret; +} + +/** + * This function parses the following command in gdb: + * ---------------------------------------------------------------------------- + * (cuda-gdb) info cuda kernels + * Kernel Parent Dev Grid Status SMs Mask GridDim BlockDim Invocation + * 3 - 3 7 Active 0x00000001 (1,1,1) (160,1,1) __omp_offloading_50_ + * 2 - 2 7 Active 0x00000001 (1,1,1) (128,1,1) __omp_offloading_50_ + * 1 - 1 7 Active 0x00000001 (1,1,1) (96,1,1) __omp_offloading_50_ + * * 0 - 0 7 Active 0x00000001 (1,1,1) (64,1,1) __omp_offloading_50_ + * ---------------------------------------------------------------------------- + * + * It returns a map of kernel ID to pairs. + */ +map> StringParser::matchCudaKernelsInfo(const char *str) const +{ + // split by \n (tokenize by lines) + string inputStr(str); + vector lines; + tokenize(inputStr, lines, "\n"); + + map> ret; + + // Do not parse the first two lines and the last line + for (size_t i=1; i < lines.size()-1; ++i) + { + string kid; + string dev; + string gid; + size_t nmatch = 4; + regmatch_t pmatch[4]; + + int regRet = regexec(&reKERNELS_ID, lines[i].c_str(), nmatch, pmatch, 0); + if (regRet) + return ret; + + kid = lines[i].substr(pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so); + dev = lines[i].substr(pmatch[2].rm_so, pmatch[2].rm_eo - pmatch[2].rm_so); + gid = lines[i].substr(pmatch[3].rm_so, pmatch[3].rm_eo - pmatch[3].rm_so); + ret[atoi(kid.c_str())] = make_pair(atoi(dev.c_str()), atoi(gid.c_str())); + } + + return ret; +} + + +/** + * This function parses the following command in gdb: + * ---------------------------------------------------------------------------- + * (gdb) info cuda contexts + * Context Dev State + * 0x00001000080038f0 0 active + * 0x00001000100038f0 1 active + * 0x00001000140038f0 2 active + * * 0x00001000180038f0 3 active + * ---------------------------------------------------------------------------- + * + * It returns a map of device ID (int) -> Cuda Context ID (uint64_t) + */ +map StringParser::matchCudaContextsInfo(const char *str) const +{ + map ret; + + // split by \n (tokenize by lines) + string inputStr(str); + vector lines; + tokenize(inputStr, lines, "\n"); + + // Do not parse the first and the last lines + for (size_t i=1; i < lines.size()-1; ++i) + { + char ctx[64]; // long enough to hold a cuda context + matchAddressValue(lines[i].c_str(), ctx); + if (strlen(ctx) == 0) + return ret; + + string device_id; + size_t nmatch = 2; + regmatch_t pmatch[2]; + + int regRet = regexec(&reCONTEXT_ID, lines[i].c_str(), nmatch, pmatch, 0); + if (regRet) + return ret; + + device_id = lines[i].substr(pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so); + ret[atoi(device_id.c_str())] = strtoll(string(ctx).c_str(), NULL, 0); + } + + return ret; +} + +/** + * This function parses the following command in gdb: + * ---------------------------------------------------------------------------- + * (gdb) info threads + * Id Target Id Frame + * 4 Thread 0x2aaaaba87700 (LWP 45661) "target" 0x00002aaaab19aa3d in nanosleep () from /lib64/libc.so.6 + * 3 Thread 0x2aaaab886700 (LWP 45660) "target" 0x00002aaaab19aa3d in nanosleep () from /lib64/libc.so.6 + * 2 Thread 0x2aaaab685700 (LWP 45659) "target" 0x00002aaaab19aa3d in nanosleep () from /lib64/libc.so.6 + * * 1 Thread 0x2aaaab483040 (LWP 45655) "target" 0x00002aaaab19aa3d in nanosleep () from /lib64/libc.so.6 + * ---------------------------------------------------------------------------- + * + * It returns a vector of pairs containing the gdb Id (unsigned int) and the + * thread Id (first string that contains a hex value) for each thread. + * A pair, for example, is: <4, "0x2aaaaba87700">. + */ +vector StringParser::matchThreadsInfo(const char *str) const +{ + vector ret; + + // split by \n (tokenize by lines) + string inputStr(str); + vector lines; + tokenize(inputStr, lines, "\n"); + + // Do not parse the first and the last lines + for (size_t i=1; i < lines.size()-1; ++i) + { + char addr[64]; // long enough to hold an address + matchAddressValue(lines[i].c_str(), addr); + if (strlen(addr) == 0) + return ret; + //ret.push_back( string(addr) ); + + // Match thread ID + string id; + size_t nmatch = 1; + regmatch_t pmatch[1]; + int regRet = regexec(&reTHREAD_ID, lines[i].c_str(), nmatch, pmatch, 0); + if (!regRet) + { + int size = pmatch[0].rm_eo - pmatch[0].rm_so; + char IDStr[size+1]; + IDStr[0] = '\0'; + strncpy (IDStr, (lines[i].c_str() + pmatch[0].rm_so), size); + + vector t; + tokenize(IDStr, t, " \t"); + id = t.size() == 1 ? t[0] : t[1]; + } + else + return ret; + + ret.push_back( + ThreadID(static_cast(atoi(id.c_str())), strtoll(string(addr).c_str(), NULL, 0) )); + } + + return ret; +} + +int StringParser::matchThreadID(const char *str) const +{ + size_t nmatch = 1; + regmatch_t pmatch[1]; + + int ret = regexec(&reTHREAD, str, nmatch, pmatch, 0); + if (ret) // if thread not found + { + return -1; + } + + return atoi(str + pmatch[0].rm_so); +} + +/* + * Eliminates the GDB prompt from input string. + * It assumes that the the string contains lines (separated by '\n') + * and that GDB prompt is in the last line. + */ +void StringParser::eliminateGDBPrompt(char *newStr, const char *oldStr) const +{ + assert(oldStr && "Invalid input string"); + size_t s = strlen(oldStr); + if (s==0) // if empty string, just return an empty string + { + newStr[0] = '\0'; + return; + } + + // Iterate from end to begin, and find the first '\n' char + size_t end = 0; + for (long long i=(static_cast(s)-1); i >= 0; --i) + { + if (oldStr[i] == '\n') + { + end = i; + break; + } + } + + // Couldn't find a '\n' char; it means the string contains a single line. + // Thus we eliminate this line. + if (end == 0) + { + newStr[0] = '\0'; + return; + } + + strncpy(newStr, oldStr, end+1); + newStr[end+1] = '\0'; +} + +void StringParser::eliminateGDBPromptInplace(string &input) const +{ + size_t s = input.size(); + if (s==0) // if empty string, just return + return; + + // Iterate from end to begin, and find the first '\n' char + size_t end = 0; + for (long long i=(static_cast(s)-1); i >= 0; --i) + { + if (input[i] == '\n') + { + end = i; + break; + } + } + + // Couldn't find a '\n' char; it means the string contains a single line. + // Thus we eliminate this line. + if (end == 0) + { + input.resize(0); + return; + } + + input.resize(end+1); +} + +/****************************************************************************** + * String utilities + */ + +void ompd_gdb::tokenize(const std::string &str, + std::vector &tokens, + const std::string &delimiters) +{ + // Skip delimiters at beginning. + std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first "non-delimiter". + std::string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (std::string::npos != pos || std::string::npos != lastPos) + { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } +} + diff --git a/libompd/gdb-wrapper/StringParser.h b/libompd/gdb-wrapper/StringParser.h new file mode 100644 index 000000000..bc779c809 --- /dev/null +++ b/libompd/gdb-wrapper/StringParser.h @@ -0,0 +1,148 @@ +/* + * StringParser.h + * + * Created on: Dec 26, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ +#ifndef GDB_STRINGPARSER_H_ +#define GDB_STRINGPARSER_H_ + +#include +#include +#include +#include +#include "CudaGdb.h" + +namespace ompd_gdb { + +/******************************************************************************* + * This class implements regular expressions to parse GDB output. + * Member functions are useful in parsing commands from users and the output of + * GDB. It assumes that GDB has a particular prompt. + * + * It is also useful in parsing utility commands to make use of OMPD. These + * commands are defined by: "ompd COMMAND". + */ + +class StringParser +{ +private: + regex_t reQUIT; + regex_t rePROMPT; + regex_t reOMPD_COMMAND; + regex_t reREGULAR_VALUE; + regex_t reADDRESS_VALUE; + regex_t reMEMORY_VALUES; + regex_t reTHREAD_ID; + regex_t reCONTEXT_ID; + regex_t reKERNELS_ID; + regex_t reBLOCKS_ID; + regex_t reTHREAD; + + bool regexpMatches(const char *str, const regex_t *re) const; + +public: + +#if defined(CUDA_GDB_PATH) + static constexpr const char *GDB_PROMPT = "(cuda-gdb) "; +#else + static constexpr const char *GDB_PROMPT = "(gdb) "; +#endif + + StringParser(); + + /** + * Return true if string has an OMPD command of the form: "ompd COMMAND". + */ + bool isOMPDCommand(const char *str) const; + + /** + * Returns true if the "quit" command is in the string. + */ + bool isQuitCommand(const char *str) const; + + /** + * Return true if the string contains the gdb prompt. + */ + bool hasGDBPrompt(const char *str) const; + + /** + * Eliminate GBD prompt (i.e., (gdb)) from string + */ + void eliminateGDBPrompt(char *newStr, const char *oldStr) const; + void eliminateGDBPromptInplace(std::string &input) const; + + /** + * Matches values given by GDB of the form: + * $[digit] = [alphanumeric] + * where the second elements (alphanumeric) is returned. + */ + void matchRegularValue(const char *str, char *value) const; + + /** + * Matches values given by GDB of the form: + * text [address] text + * where [address] is a memory address in hex format + */ + void matchAddressValue(const char *str, char *addr) const; + + /** + * Matches GDB output from command: + * x/Nxb, where N is a number of bytes + * Returns a vector of bytes in hex format: "0x00". + */ + std::vector matchMemoryValues(const char *str) const; + + /** + * Matches GDB output from the command: + * "info cuda threads" + */ + std::vector matchCudaThreadsInfo(uint64_t ctx, uint64_t dev, + uint64_t kernel, uint64_t grid, const char *str) const; + + /** + * Matches GDB output from the command: + * "info cuda kernels" + * Returns cuda context IDs (one per device) + */ + std::map> matchCudaKernelsInfo(const char *str) const; + + /** + * Matches GDB output from the command: + * "info cuda contexts" + * Returns cuda context IDs (one per device) + */ + std::map matchCudaContextsInfo(const char *str) const; + + typedef std::pair ThreadID; + + /** + * Matches GDB output from the command: + * "info threads" + * Returns system thread IDs + */ + std::vector matchThreadsInfo(const char *str) const; + + /** + * Matches GDB output from the command: + * "thread" + * Returns the ID of the currently selected thread + */ + int matchThreadID(const char *str) const; +}; + +/****************************************************************************** + * String utilities + */ + +/** + * Tokenize a string + */ +void tokenize(const std::string &str, + std::vector &tokens, + const std::string &delimiters); + +} + +#endif /* GDB_STRINGPARSER_H_ */ diff --git a/libompd/gdb-wrapper/driver.py b/libompd/gdb-wrapper/driver.py new file mode 100755 index 000000000..00df9fce5 --- /dev/null +++ b/libompd/gdb-wrapper/driver.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python + +import sys +import os +from time import sleep +from subprocess import Popen + +def main(): + program = sys.argv[1] +# os.environ['LD_LIBRARY_PATH'] = "/Users/lagunaperalt1/projects/OMPD/ompd_code/src" +# os.environ['LD_LIBRARY_PATH'] = "/g/g90/laguna/projects/OMPD/ompd_code/OMPD/src" + + p = Popen(program) + pid = p.pid + print "Process ID of test:", pid + print "Waiting a few seconds before attaching GDB..." + sleep(2) + + # Run gdb wrapper + gdb = Popen(["./odb", str(pid)]) + + # Wait until programs end + gdb.communicate() + p.terminate() + +main() diff --git a/libompd/gdb-wrapper/gdb_wrapper.cpp b/libompd/gdb-wrapper/gdb_wrapper.cpp new file mode 100644 index 000000000..6637bc967 --- /dev/null +++ b/libompd/gdb-wrapper/gdb_wrapper.cpp @@ -0,0 +1,145 @@ +/* + * gdb_wrapper.cpp + * + * Created on: Dec 21, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "InputChecker.h" +#include "StringParser.h" +#include "GdbProcess.h" +#include "Callbacks.h" +#include "OMPDCommand.h" +#include "ompd.h" +#include "ompd_test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace ompd_gdb; + +/* --- Global static variables ---------------------------------------------- */ +static StringParser parser; +static GdbProcessPtr gdbProc(nullptr); +static OMPDCommandFactoryPtr commandFactory(nullptr); + +/* --- Initialization routines ---------------------------------------------- */ +//static void parseInputParameters(int argc, char **argv); +static void initializeErrorHandlers(); +static void sigHandler(int signo); +//static void printUsage(); +/* --- Processing routines -------------------------------------------------- */ +static void processOMPDCommand(const char *str); +/* --- Finalization routines ------------------------------------------------ */ +static void terminateGDB(); + +int main(int argc, char **argv) +{ + // Initial steps + InputChecker::parseParameters(argc, argv); + gdbProc = GdbProcessPtr(new GdbProcess(argv)); + commandFactory = OMPDCommandFactoryPtr(new OMPDCommandFactory); + initializeErrorHandlers(); + initializeCallbacks(gdbProc); + + // Main loop. + // Alternate between reading GDB's output and reading user's input. + bool readOutput = true; + char userInput[256]; + while(true) { + if (readOutput) + cout << gdbProc->readOutput(); + + // Read command from the user + userInput[0] = '\0'; + std::cin.getline(userInput,255); + if (parser.isQuitCommand(userInput)) // if quit command was sent, terminate + break; + else + { + if (parser.isOMPDCommand(userInput)) // process OMPD command if sent + { + processOMPDCommand(userInput); + // print GDB prompt since it is consumed by the processing routine + cout << StringParser::GDB_PROMPT; + readOutput = false; // we don't read output + continue; + } + gdbProc->writeInput(userInput); // send user command to GDB + } + readOutput = true; + } + + // Clean up everything before ending + terminateGDB(); + return EXIT_SUCCESS; +} + +/*void parseInputParameters(int argc, char**argv) +{ + // Check input is correct + if (argc != 2) + printUsage(); + else + { + int pid = atoi(argv[1]); + if (pid == 0 || pid < 0) + { + cerr << "ERROR: incorrect PID!\n"; + printUsage(); + } + } +} + +void printUsage() +{ + cerr << "Usage:\n\tgdb_wrapper ID\n"; + cerr << "ID: process ID (integer)\n"; + exit(EXIT_FAILURE); +}*/ + +void initializeErrorHandlers() +{ + // Register signal handlers + signal(SIGINT, sigHandler); + signal(SIGTSTP, sigHandler); + signal(SIGSTOP, sigHandler); +} + +void sigHandler(int signo) +{ + cerr << "Got a signal. Exiting...\n"; + terminateGDB(); + exit(EXIT_FAILURE); +} + +void terminateGDB() +{ + gdbProc->finalize(); + cout << "Waiting to terminate GDB..." << endl; + cout << "GDB exit status: "; + cout << gdbProc->wait() << endl; +} + +void processOMPDCommand(const char *str) +{ + vector params; + tokenize(str, params, " \t"); + + OMPDCommand *command; + if (params.size() > 1) + command = commandFactory->create(params[1].c_str()); + else + command = commandFactory->create("None"); // in case no command is passed + + command->execute(); +} diff --git a/libompd/gdb-wrapper/odb.cpp b/libompd/gdb-wrapper/odb.cpp new file mode 100644 index 000000000..7de406ff6 --- /dev/null +++ b/libompd/gdb-wrapper/odb.cpp @@ -0,0 +1,22 @@ +/* + * odb.cpp + * + * Created on: Jan 7, 2015 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include "InputOutputManager.h" +#include +#include + +using namespace ompd_gdb; + +int main(int argc, char **argv) +{ + InputOutputManager ioManager(argc, argv, true); + ioManager.run(); + ioManager.finalize(); + return EXIT_SUCCESS; +} + diff --git a/libompd/gdb-wrapper/regex_test.cpp b/libompd/gdb-wrapper/regex_test.cpp new file mode 100644 index 000000000..1c191803f --- /dev/null +++ b/libompd/gdb-wrapper/regex_test.cpp @@ -0,0 +1,42 @@ +/* + * regex_test.cpp + * + * Created on: Dec 28, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include +#include +#include + +using namespace std; + +int main() +{ + + int ret; + regex_t REEXP; + + //const char *str = "some text here 0x103ed7064 more text here\n(gdb) "; + const char *str = " 1 Thread 0x2aaaab483040 (LWP 91928) \"target\" 0x00002aaaab19aa3d in nanosleep () from /lib64/libc.so.6"; + + ret = regcomp(&REEXP, "^(\\*)?[ \t]+[0-9]+[ \t]+", REG_EXTENDED); + assert(!ret && "Could not compile regex!"); + + size_t nmatch = 1; + regmatch_t pmatch[1]; + + ret = regexec(&REEXP, str, nmatch, pmatch, 0); + if (!ret) + { + cout << "It matches!!\n"; + cout << "start: " << pmatch[0].rm_so << " end: " << pmatch[0].rm_eo << "\n"; + } + else + { + cout << "Did not match.\n"; + } + + return 0; +} diff --git a/libompd/gdb-wrapper/regex_test_v2.cpp b/libompd/gdb-wrapper/regex_test_v2.cpp new file mode 100644 index 000000000..1b3b14168 --- /dev/null +++ b/libompd/gdb-wrapper/regex_test_v2.cpp @@ -0,0 +1,115 @@ +/* + * regex_test.cpp + * + * Created on: Dec 28, 2014 + * Author: Ignacio Laguna + * Contact: ilaguna@llnl.gov + */ + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +void tokenize(const std::string &str, + std::vector &tokens, + const std::string &delimiters) +{ + // Skip delimiters at beginning. + std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first "non-delimiter". + std::string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (std::string::npos != pos || std::string::npos != lastPos) + { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } +} + +const char input1[] = + "0x1000010c8 : 0xd0 0x4f 0x10 0x00 0x01 0x00 0x00 0x00\n" + "0x1000010d0 : 0xd0 0x4d 0x10 0x00 0x01 0x00 0x00 0x00\n" + "0x1000010d8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n" + "0x1000010e0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n" + "0x1000010e8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n" + "0x1000010f0: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n" + "0x1000010f8: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n" + "0x100001100: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00\n" + "(gdb) "; + +const char input2[] = + "0x1000010c8 : 0xd0 0x4f 0x10\n" + "0x1000010d0 : 0xa0 0x5c 0x20\n" + "(gdb) "; + +regex_t REEXP; + +vector parseBytesFromDebuggerOutput(const char input[]) +{ + vector ret; + + // split by \n (tokenize by lines) + string inputStr(input); + vector lines; + tokenize(inputStr, lines, "\n"); + + for (size_t i=0; i < lines.size()-1; ++i) + { + vector addresses; + tokenize(lines[i], addresses, ":"); + if (addresses.size() == 0) // error if no ':' character is found + return ret; + + int regRet = regexec(&REEXP, addresses[1].c_str(), 0, NULL, 0); + + if (!regRet) + { + vector hexValues; + tokenize(addresses[1], hexValues, " \t"); + for (size_t k=hexValues.size()-1; k > 0; --k) + ret.push_back(hexValues[k]); + ret.push_back(hexValues[0]); + } + else + return ret; // error if no match is found + } + + return ret; +} + +int main() +{ + + /** ---- Initialization --------------------------------------------------- */ + int ret; + ret = regcomp(&REEXP, "^[ \t]*((0){1}[xX]{1}[0-9a-fA-F]{2})+[ \t]*", REG_EXTENDED); + assert(!ret && "Could not compile regex!"); + + /** ---- Processing ------------------------------------------------------- */ + + vector ret1 = parseBytesFromDebuggerOutput(input1); + cout << "Address: "; + for (size_t i=0; i < ret1.size(); ++i) + cout << ret1[i] << "-"; + cout << "\n"; + + vector ret2 = parseBytesFromDebuggerOutput(input2); + cout << "Address: "; + for (size_t i=0; i < ret2.size(); ++i) + cout << ret2[i] << "-"; + cout << "\n"; + + + + return 0; +} From a27804551f0949181a1c4e3ffcd48f4bf89b13d9 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Tue, 15 May 2018 08:56:18 +0200 Subject: [PATCH 38/46] Allow the use of omp.h from the build directory. --- libompd/src/CMakeLists.txt | 1 + runtime/CMakeLists.txt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/libompd/src/CMakeLists.txt b/libompd/src/CMakeLists.txt index a2662ad31..cee158b67 100644 --- a/libompd/src/CMakeLists.txt +++ b/libompd/src/CMakeLists.txt @@ -6,6 +6,7 @@ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} + ${LIBOMP_INCLUDE_DIR} ) INSTALL( TARGETS ompd diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 3770a7cb9..9e828bb10 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -400,3 +400,7 @@ endif() add_subdirectory(src) add_subdirectory(test) + +# make these variables available for tools/libompd: +set(LIBOMP_LIBRARY_DIR ${LIBOMP_LIBRARY_DIR} PARENT_SCOPE) +set(LIBOMP_INCLUDE_DIR ${LIBOMP_INCLUDE_DIR} PARENT_SCOPE) From 7288d8d9e44e9967e7fe405eb0929737a676f040 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Tue, 15 May 2018 16:55:18 +0200 Subject: [PATCH 39/46] Initialize LIBOMP_INCLUDE_DIR to be used in higher scopes --- runtime/src/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/src/CMakeLists.txt b/runtime/src/CMakeLists.txt index b831adb0c..7db4363e6 100644 --- a/runtime/src/CMakeLists.txt +++ b/runtime/src/CMakeLists.txt @@ -161,6 +161,7 @@ if(NOT LIBOMP_LIBRARY_DIR) else() set(LIBOMP_LIBRARY_DIR ${LIBOMP_LIBRARY_DIR} PARENT_SCOPE) endif() +set(LIBOMP_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) # Add symbolic links to libomp if(NOT WIN32) From ae6b0516c474b3b4334b09ae768b2fb1eca43c29 Mon Sep 17 00:00:00 2001 From: Marty McFadden Date: Tue, 15 May 2018 08:17:07 -0700 Subject: [PATCH 40/46] making ompd dependent upon omp being built first --- libompd/src/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libompd/src/CMakeLists.txt b/libompd/src/CMakeLists.txt index cee158b67..53a7e3e2c 100644 --- a/libompd/src/CMakeLists.txt +++ b/libompd/src/CMakeLists.txt @@ -1,8 +1,12 @@ project (libompd) +message( "LIBOMP_INCLUDE_DIR = ${LIBOMP_INCLUDE_DIR}" ) add_library (ompd SHARED TargetValue.cpp omp-debug.cpp) +add_dependencies(ompd omp) # ensure generated import library is created first + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +message( "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}" ) include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} From 5e504d96857530bd314e49177f9d942eeb823dc1 Mon Sep 17 00:00:00 2001 From: Nina Loeseke Date: Wed, 27 Jun 2018 15:47:22 +0200 Subject: [PATCH 41/46] Fix location as it was changed in cmake file --- runtime/src/ompd-specific.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/ompd-specific.cpp b/runtime/src/ompd-specific.cpp index 89892e00c..ea10f8b88 100644 --- a/runtime/src/ompd-specific.cpp +++ b/runtime/src/ompd-specific.cpp @@ -23,7 +23,7 @@ OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) #undef ompd_declare_sizeof const char * * ompd_dll_locations=NULL; -const char * ompd_my_dll_locations[2] = {"libompd_intel.so",NULL}; +const char * ompd_my_dll_locations[2] = {"libompd.so",NULL}; uint64_t ompd_state=0; int ompd_rtl_version = 7; From fe32571b10a33df84b43392f07a0657882787ba2 Mon Sep 17 00:00:00 2001 From: "protze@itc.rwth-aachen.de" Date: Wed, 18 Jul 2018 18:13:43 +0200 Subject: [PATCH 42/46] Access the task routine to provide a task function for OMPD --- libompd/src/CMakeLists.txt | 2 -- libompd/src/omp-debug.cpp | 20 +++++++++----------- runtime/src/ompd-specific.h | 3 +++ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/libompd/src/CMakeLists.txt b/libompd/src/CMakeLists.txt index 53a7e3e2c..0fb4e6b0f 100644 --- a/libompd/src/CMakeLists.txt +++ b/libompd/src/CMakeLists.txt @@ -1,12 +1,10 @@ project (libompd) -message( "LIBOMP_INCLUDE_DIR = ${LIBOMP_INCLUDE_DIR}" ) add_library (ompd SHARED TargetValue.cpp omp-debug.cpp) add_dependencies(ompd omp) # ensure generated import library is created first set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -message( "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}" ) include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/libompd/src/omp-debug.cpp b/libompd/src/omp-debug.cpp index 18356e071..a603d5d08 100644 --- a/libompd/src/omp-debug.cpp +++ b/libompd/src/omp-debug.cpp @@ -1407,7 +1407,7 @@ ompd_get_task_data(ompd_task_handle_t *task_handle, /* IN: OpenMP task handle*/ return ret; } -#if 0 // the runtime currently does not have task function information +#if 1 // the runtime currently does not have task function information ompd_rc_t ompd_get_task_function( ompd_task_handle_t *task_handle, /* IN: OpenMP task handle */ ompd_address_t *task_addr /* OUT: first instruction in the task region */ @@ -1439,17 +1439,15 @@ ompd_rc_t ompd_get_task_function( task_addr->segment = OMPD_SEGMENT_UNSPECIFIED; TValue taskInfo; if(task_handle->lwt.address!=0) - taskInfo = TValue(context, task_handle->lwt). - cast("ompt_lw_taskteam_t",0); /*lwt*/ + return ompd_rc_bad_input; // We need to decide what we do here. else - taskInfo = TValue(context, task_handle->th). - cast("kmp_taskdata_t",0); /*t*/ - ret = taskInfo. - access("ompt_task_info"). /*td->ompt_task_info*/ - cast("ompt_task_info_t"). - access("function"). /*td->ompt_task_info.function*/ - castBase(). - getValue(task_addr->address); + ret = TValue(context, task_handle->th). + cast("kmp_taskdata_t",0). /*t*/ + getArrayElement(1). /* see kmp.h: #define KMP_TASKDATA_TO_TASK(taskdata) (kmp_task_t *)(taskdata + 1) */ + cast("kmp_task_t",0). /* (kmp_task_t *) */ + access("routine"). /*td->ompt_task_info*/ + castBase(). + getValue(task_addr->address); return ret; } #endif diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index d0f32422f..7b999bc9b 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -69,6 +69,8 @@ OMPD_ACCESS(kmp_taskdata_t, td_icvs) \ OMPD_ACCESS(kmp_taskdata_t, td_parent) \ OMPD_ACCESS(kmp_taskdata_t, td_team) \ \ +OMPD_ACCESS(kmp_task_t, routine) \ +\ OMPD_ACCESS(kmp_team_p, t) \ \ OMPD_ACCESS(ompt_task_info_t, frame) \ @@ -110,6 +112,7 @@ OMPD_BITFIELD(kmp_tasking_flags_t, native) \ #define OMPD_FOREACH_SIZEOF(OMPD_SIZEOF) \ OMPD_SIZEOF(kmp_info_t) \ OMPD_SIZEOF(kmp_taskdata_t) \ +OMPD_SIZEOF(kmp_task_t) \ OMPD_SIZEOF(kmp_tasking_flags_t) \ OMPD_SIZEOF(kmp_thread_t) \ OMPD_SIZEOF(ompt_data_t) \ From b34cb8c10a6004e4149821e0e4051e4aef91a8fd Mon Sep 17 00:00:00 2001 From: Nina Loeseke Date: Fri, 3 Aug 2018 11:16:05 +0200 Subject: [PATCH 43/46] Various fixes for the OMPD library - types of the type_sizes struct were changed to char. The cast to (int*) broke everything - Remove the use of new - Fix the order of setting ompd_status and posting ompd_dll_locations_valid --- libompd/src/TargetValue.cpp | 2 +- libompd/src/omp-debug.cpp | 17 +++++++++++++---- libompd/src/ompd.h | 2 +- runtime/src/ompd-specific.cpp | 8 ++++---- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/libompd/src/TargetValue.cpp b/libompd/src/TargetValue.cpp index 5afb2ab47..43a394f83 100644 --- a/libompd/src/TargetValue.cpp +++ b/libompd/src/TargetValue.cpp @@ -9,7 +9,7 @@ const ompd_callbacks_t *TValue::callbacks = NULL; ompd_target_type_sizes_t TValue::type_sizes; inline int ompd_sizeof(ompd_target_prim_types_t t) { - return (((int *)&TValue::type_sizes)[(int)t]); + return (((char *)&TValue::type_sizes)[(int)t]); } TType &TTypeFactory::getType(ompd_address_space_context_t *context, diff --git a/libompd/src/omp-debug.cpp b/libompd/src/omp-debug.cpp index a603d5d08..325872273 100644 --- a/libompd/src/omp-debug.cpp +++ b/libompd/src/omp-debug.cpp @@ -70,7 +70,11 @@ ompd_process_initialize(ompd_address_space_context_t .getValue(ompd_state); if (ret != ompd_rc_ok) return ret; - *addrhandle = new ompd_address_space_handle_t; + ret = callbacks->dmemory_alloc(sizeof(ompd_address_space_handle_t), + (void **)(addrhandle)); + if (ret != ompd_rc_ok) + return ret; +// *addrhandle = new ompd_address_space_handle_t; if (!addrhandle) return ompd_rc_error; (*addrhandle)->context = context; @@ -117,8 +121,9 @@ ompd_rc_t ompd_release_address_space_handle( if (!addr_handle) return ompd_rc_bad_input; - delete addr_handle; - return ompd_rc_ok; + ompd_rc_t ret = callbacks->dmemory_free((void *)(addr_handle)); +// delete addr_handle; + return ret; } #if 0 // no device support yet @@ -166,7 +171,11 @@ ompd_rc_t ompd_device_initialize ( continue; if (cuda_ctx == id) { - *addrhandle = new ompd_address_space_handle_t; + ret = callbacks->dmemory_alloc(sizeof(ompd_address_space_handle_t), + (void **)(addrhandle)); + if (ret != ompd_rc_ok) + return ret; +// *addrhandle = new ompd_address_space_handle_t; if (!addrhandle) return ompd_rc_error; (*addrhandle)->context = context; diff --git a/libompd/src/ompd.h b/libompd/src/ompd.h index 25514bcc6..2c97f09f4 100644 --- a/libompd/src/ompd.h +++ b/libompd/src/ompd.h @@ -266,7 +266,7 @@ typedef struct ompd_target_type_sizes_t { uint8_t sizeof_long; uint8_t sizeof_long_long; uint8_t sizeof_pointer; -} ompd_device_type_sizes_t; +} ompd_target_type_sizes_t; /****************************************************************************** * Debugger callback signatures. diff --git a/runtime/src/ompd-specific.cpp b/runtime/src/ompd-specific.cpp index ea10f8b88..a79e0d309 100644 --- a/runtime/src/ompd-specific.cpp +++ b/runtime/src/ompd-specific.cpp @@ -64,9 +64,6 @@ OMPD_FOREACH_ACCESS(ompd_init_sizeof_member) OMPD_FOREACH_SIZEOF(ompd_init_sizeof) #undef ompd_init_sizeof - ompd_dll_locations=ompd_my_dll_locations; - ompd_dll_locations_valid (); - const char *ompd_env_var = getenv("OMP_OMPD"); if (ompd_env_var && !strcmp(ompd_env_var, "on")) { @@ -77,6 +74,9 @@ OMPD_FOREACH_SIZEOF(ompd_init_sizeof) } ompd_initialized = 1; + ompd_dll_locations=ompd_my_dll_locations; + ompd_dll_locations_valid (); + } /*void omp_ompd_enable ( void ) @@ -90,7 +90,7 @@ OMPD_FOREACH_SIZEOF(ompd_init_sizeof) #endif }*/ -void ompd_dll_locations_valid ( void ){ +void __attribute__((noinline)) ompd_dll_locations_valid ( void ){ /* naive way of implementing hard to opt-out empty function we might want to use a separate object file? */ asm (""); From b2b4f8463289baf5b3d2e2bf7c69a44d5a8a28ce Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Tue, 31 Jul 2018 19:02:49 +0200 Subject: [PATCH 44/46] Change the storage of ompd_dll_locations to also work with optimized non-debug build. --- runtime/src/ompd-specific.cpp | 6 ++++-- runtime/src/ompd-specific.h | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/runtime/src/ompd-specific.cpp b/runtime/src/ompd-specific.cpp index a79e0d309..3cb33f8e6 100644 --- a/runtime/src/ompd-specific.cpp +++ b/runtime/src/ompd-specific.cpp @@ -22,8 +22,7 @@ OMPD_FOREACH_BITFIELD(ompd_declare_bitfield) OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) #undef ompd_declare_sizeof -const char * * ompd_dll_locations=NULL; -const char * ompd_my_dll_locations[2] = {"libompd.so",NULL}; +volatile const char * * ompd_dll_locations=NULL; uint64_t ompd_state=0; int ompd_rtl_version = 7; @@ -64,6 +63,9 @@ OMPD_FOREACH_ACCESS(ompd_init_sizeof_member) OMPD_FOREACH_SIZEOF(ompd_init_sizeof) #undef ompd_init_sizeof + volatile static const char * ompd_my_dll_locations[2] = {"libompd.so",NULL}; + + const char *ompd_env_var = getenv("OMP_OMPD"); if (ompd_env_var && !strcmp(ompd_env_var, "on")) { diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index 7b999bc9b..dc92c38b7 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -7,17 +7,17 @@ #ifdef OMPD_SUPPORT void ompd_init(); -extern const char * * ompd_dll_locations; +extern volatile const char * * ompd_dll_locations; extern int ompd_rtl_version; #ifdef __cplusplus extern "C" { #endif -void ompd_dll_locations_valid ( void ); -void ompd_bp_parallel_begin ( void ); -void ompd_bp_parallel_end ( void ); -void ompd_bp_task_begin ( void ); -void ompd_bp_task_end ( void ); +void __attribute__ ((noinline)) ompd_dll_locations_valid ( void ); +void __attribute__ ((noinline)) ompd_bp_parallel_begin ( void ); +void __attribute__ ((noinline)) ompd_bp_parallel_end ( void ); +void __attribute__ ((noinline)) ompd_bp_task_begin ( void ); +void __attribute__ ((noinline)) ompd_bp_task_end ( void ); #ifdef __cplusplus } /* extern "C" */ #endif From 6b435dc00c1923438ed2a2ceb861d43c8ad954a8 Mon Sep 17 00:00:00 2001 From: Nina Loeseke Date: Mon, 13 Aug 2018 16:23:01 +0200 Subject: [PATCH 45/46] Work-around for release-build --- runtime/src/ompd-specific.cpp | 11 ++++++++--- runtime/src/ompd-specific.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/runtime/src/ompd-specific.cpp b/runtime/src/ompd-specific.cpp index 3cb33f8e6..b3cc4b618 100644 --- a/runtime/src/ompd-specific.cpp +++ b/runtime/src/ompd-specific.cpp @@ -1,4 +1,5 @@ #include "ompd-specific.h" +#include #ifdef OMPD_SUPPORT @@ -22,7 +23,8 @@ OMPD_FOREACH_BITFIELD(ompd_declare_bitfield) OMPD_FOREACH_SIZEOF(ompd_declare_sizeof) #undef ompd_declare_sizeof -volatile const char * * ompd_dll_locations=NULL; +volatile char * * ompd_dll_locations=NULL; +volatile static char * ompd_my_dll_locations[2] = {(char*)"libompd.so",NULL}; uint64_t ompd_state=0; int ompd_rtl_version = 7; @@ -63,7 +65,6 @@ OMPD_FOREACH_ACCESS(ompd_init_sizeof_member) OMPD_FOREACH_SIZEOF(ompd_init_sizeof) #undef ompd_init_sizeof - volatile static const char * ompd_my_dll_locations[2] = {"libompd.so",NULL}; const char *ompd_env_var = getenv("OMP_OMPD"); @@ -76,7 +77,11 @@ OMPD_FOREACH_SIZEOF(ompd_init_sizeof) } ompd_initialized = 1; - ompd_dll_locations=ompd_my_dll_locations; +// ompd_dll_locations=ompd_my_dll_locations; + ompd_dll_locations = (volatile char**) malloc(sizeof(char*)*2); + ompd_dll_locations[0] = ompd_my_dll_locations[0]; + ompd_dll_locations[1] = ompd_my_dll_locations[1]; + asm (""); ompd_dll_locations_valid (); } diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index dc92c38b7..47531f110 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -7,7 +7,7 @@ #ifdef OMPD_SUPPORT void ompd_init(); -extern volatile const char * * ompd_dll_locations; +extern volatile char * * ompd_dll_locations; extern int ompd_rtl_version; #ifdef __cplusplus From c5306cfcc32b4af140910a47ab110cb7a45d0627 Mon Sep 17 00:00:00 2001 From: Joachim Protze Date: Tue, 14 Aug 2018 10:01:19 +0200 Subject: [PATCH 46/46] Add new ompd_bp_thread_begin function to be called after OpenMP thread is initialized --- runtime/src/kmp_runtime.cpp | 6 ++++++ runtime/src/ompd-specific.cpp | 11 +++++++++++ runtime/src/ompd-specific.h | 2 ++ 3 files changed, 19 insertions(+) diff --git a/runtime/src/kmp_runtime.cpp b/runtime/src/kmp_runtime.cpp index e175e429d..7100841a4 100644 --- a/runtime/src/kmp_runtime.cpp +++ b/runtime/src/kmp_runtime.cpp @@ -3833,6 +3833,9 @@ int __kmp_register_root(int initial_thread) { ompt_set_thread_state(root_thread, omp_state_work_serial); } #endif +#if OMPD_SUPPORT + ompd_bp_thread_begin(); +#endif KMP_MB(); __kmp_release_bootstrap_lock(&__kmp_forkjoin_lock); @@ -5590,6 +5593,9 @@ void *__kmp_launch_thread(kmp_info_t *this_thr) { } } #endif +#if OMPD_SUPPORT + ompd_bp_thread_begin(); +#endif #if OMPT_SUPPORT if (ompt_enabled.enabled) { diff --git a/runtime/src/ompd-specific.cpp b/runtime/src/ompd-specific.cpp index b3cc4b618..9baf6151f 100644 --- a/runtime/src/ompd-specific.cpp +++ b/runtime/src/ompd-specific.cpp @@ -124,5 +124,16 @@ void ompd_bp_task_end ( void ){ asm (""); } +void ompd_bp_thread_begin ( void ){ + /* naive way of implementing hard to opt-out empty function + we might want to use a separate object file? */ + asm (""); +} +void ompd_bp_thread_end ( void ){ + /* naive way of implementing hard to opt-out empty function + we might want to use a separate object file? */ + asm (""); +} + #endif /* OMPD_SUPPORT */ diff --git a/runtime/src/ompd-specific.h b/runtime/src/ompd-specific.h index 47531f110..596147705 100644 --- a/runtime/src/ompd-specific.h +++ b/runtime/src/ompd-specific.h @@ -18,6 +18,8 @@ void __attribute__ ((noinline)) ompd_bp_parallel_begin ( void ); void __attribute__ ((noinline)) ompd_bp_parallel_end ( void ); void __attribute__ ((noinline)) ompd_bp_task_begin ( void ); void __attribute__ ((noinline)) ompd_bp_task_end ( void ); +void __attribute__ ((noinline)) ompd_bp_thread_begin ( void ); +void __attribute__ ((noinline)) ompd_bp_thread_end ( void ); #ifdef __cplusplus } /* extern "C" */ #endif