From b3538b5e687f6d5d573a8911a70db03d37d32962 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Tue, 21 Jan 2020 09:57:25 -0800 Subject: [PATCH 01/14] Fixing CSV output bug Only node 0 was getting written. --- src/apex/profiler_listener.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/apex/profiler_listener.cpp b/src/apex/profiler_listener.cpp index 263303d2..7efb022e 100644 --- a/src/apex/profiler_listener.cpp +++ b/src/apex/profiler_listener.cpp @@ -662,7 +662,7 @@ std::unordered_set free_profiles; << endl;; } csv_output << "\"task\",\"num calls\",\"total cycles\",\"total " - << "microseconds\""; + << "microseconds\"" << std::endl; std::string re("PAPI_"); std::string tmpstr(apex_options::papi_metrics()); size_t index = 0; @@ -727,7 +727,7 @@ std::unordered_set free_profiles; total_ss << std::fixed << ((uint64_t)total_hpx_threads); screen_output << total_ss.str() << std::endl; //} - if (apex_options::use_screen_output()) { + if (apex_options::use_screen_output() && node_id == 0) { cout << screen_output.str(); data.output = screen_output.str(); } @@ -736,6 +736,7 @@ std::unordered_set free_profiles; stringstream csvname; csvname << apex_options::output_file_path(); csvname << filesystem_separator() << "apex." << node_id << ".csv"; + // std::cout << "Writing: " << csvname.str() << std::endl; csvfile.open(csvname.str(), ios::out); csvfile << csv_output.str(); csvfile.close(); @@ -1278,9 +1279,9 @@ if (rc != 0) cout << "PAPI error! " << name << ": " << PAPI_strerror(rc) << endl push_profiler((unsigned int)thread_instance::get_id(), main_timer); // output to screen? - if ((apex_options::use_screen_output() || + if ((apex_options::use_screen_output() && node_id == 0) || apex_options::use_taskgraph_output() || - apex_options::use_csv_output()) && node_id == 0) + apex_options::use_csv_output()) { size_t ignored = 0; { // we need to lock in case another thread appears From 5ecde67f82727b859b2323c4f8143c4919c37a4e Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Tue, 21 Jan 2020 09:58:30 -0800 Subject: [PATCH 02/14] Adding MPI OTF2 test to make sure event unification works correctly --- src/unit_tests/C++/CMakeLists.txt | 26 +++++++++++++++++++ .../C++/apex_hpx_annotated_functions.cpp | 22 ++++++++++++++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/unit_tests/C++/CMakeLists.txt b/src/unit_tests/C++/CMakeLists.txt index 0dfac138..6106ff95 100644 --- a/src/unit_tests/C++/CMakeLists.txt +++ b/src/unit_tests/C++/CMakeLists.txt @@ -95,3 +95,29 @@ endif (OPENMP_FOUND) #target_link_libraries (apex_fibonacci_std_async_cpp apex_pthread_wrapper) #add_dependencies (apex_fibonacci_std_async_cpp apex_pthread_wrapper) + + + +# Make sure the compiler can find include files from our Apex library. +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MPI_COMPILE_FLAGS}") +include_directories (. ${APEX_SOURCE_DIR}/src/apex ${MPI_CXX_INCLUDE_PATH}) + +# Make sure the linker can find the Apex library once it is built. +link_directories (${APEX_BINARY_DIR}/src/apex) + +# Add executable called "apex_hpx_annotated_functions_mpi" that is built from the source file +# "apex_hpx_annotated_functions.cpp". The extensions are automatically found. +add_executable (apex_hpx_annotated_functions_mpi apex_hpx_annotated_functions.cpp) +add_dependencies (apex_hpx_annotated_functions_mpi apex) +add_dependencies (examples apex_hpx_annotated_functions_mpi) + +# Link the executable to the Apex library. +target_link_libraries (apex_hpx_annotated_functions_mpi apex ${MPI_CXX_LINK_FLAGS} ${MPI_CXX_LIBRARIES} ${LIBS} stdc++ m) +if (BUILD_STATIC_EXECUTABLES) + set_target_properties(apex_hpx_annotated_functions_mpi PROPERTIES LINK_SEARCH_START_STATIC 1 LINK_SEARCH_END_STATIC 1) +endif() + +INSTALL(TARGETS apex_hpx_annotated_functions_mpi + RUNTIME DESTINATION bin OPTIONAL +) + diff --git a/src/unit_tests/C++/apex_hpx_annotated_functions.cpp b/src/unit_tests/C++/apex_hpx_annotated_functions.cpp index eeac17d3..e2eec27b 100644 --- a/src/unit_tests/C++/apex_hpx_annotated_functions.cpp +++ b/src/unit_tests/C++/apex_hpx_annotated_functions.cpp @@ -5,13 +5,18 @@ #include #include #include "apex_api.hpp" +#if defined(APEX_HAVE_MPI) +#include +#endif uint32_t test_numthreads = 0; int threads_per_core = 8; __thread uint64_t guid = 0; const int num_iterations = 10; +int comm_rank = 0; +int comm_size = 1; -#ifdef DEBUG +#ifdef DEBUG__ #define __DEBUG_PRINT__ 1 #endif @@ -50,7 +55,9 @@ static void init_guid(int tid) { void innerLoop(int *tid) { std::shared_ptr tt_ptr = apex::new_task(__func__); - apex::update_task(tt_ptr, "foo"); + + const char * new_label = ((comm_rank % 2 == 0) ? "foo" : "bar"); + apex::update_task(tt_ptr, new_label); apex::start(tt_ptr); /* do some computation */ @@ -90,7 +97,15 @@ void* someThread(void* tmp) int main (int argc, char** argv) { /* initialize APEX */ + #if defined(APEX_HAVE_MPI) + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank); + MPI_Comm_size(MPI_COMM_WORLD, &comm_size); + std::cout << "APP: rank " << comm_rank << " of " << comm_size << std::endl; + apex::init("apex::start unit test", comm_rank, comm_size); + #else apex::init("apex::start unit test", 0, 1); + #endif /* important, to make sure we get correct profiles at the end */ apex::apex_options::use_screen_output(true); /* start a timer */ @@ -134,6 +149,9 @@ int main (int argc, char** argv) { } } apex::cleanup(); + #if defined(APEX_HAVE_MPI) + MPI_Finalize(); + #endif return 0; } From c25b735f84917dd2c0a0fa0edad270c20c568d89 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Fri, 24 Jan 2020 09:14:38 -0800 Subject: [PATCH 03/14] Expanding the C++ demo to make it more useful --- src/examples/DemoCpp/demo.cpp | 137 +++++++++++++++++++++++++++------- 1 file changed, 110 insertions(+), 27 deletions(-) diff --git a/src/examples/DemoCpp/demo.cpp b/src/examples/DemoCpp/demo.cpp index aa772f71..94f01b16 100644 --- a/src/examples/DemoCpp/demo.cpp +++ b/src/examples/DemoCpp/demo.cpp @@ -3,39 +3,122 @@ #include #include -using namespace apex; using namespace std; +/* First method for timers: using a scoped timer object. + * This is the simplest method for timing C++ */ + +void scopedTimerExample1(void) { + /* This function is timed with a scoped timer using the function name */ + apex::scoped_timer(__func__); + usleep(2000); + return; +} + +void scopedTimerExample2(void) { + /* This function is timed with a scoped timer using the function address */ + apex::scoped_timer((apex_function_address)&scopedTimerExample2); + usleep(2000); + return; +} + +/* Second method for timers: using a task wrapper. + * The benefit of this case is that the timer can be yielded and resumed */ + +void taskWrapperExample1(void) { + /* This function is timed with a task_wrapper that is explicitly started/stopped */ + std::shared_ptr wrapper = apex::new_task(__func__); + apex::start(wrapper); + usleep(2000); + apex::yield(wrapper); + usleep(2000); + apex::start(wrapper); + usleep(2000); + apex::stop(wrapper); + return; +} + +void taskWrapperExample2(void) { + /* This function is timed with a task_wrapper that is explicitly started/stopped */ + std::shared_ptr wrapper = + apex::new_task((apex_function_address)&taskWrapperExample2); + apex::start(wrapper); + usleep(2000); + apex::yield(wrapper); + usleep(2000); + apex::start(wrapper); + usleep(2000); + apex::stop(wrapper); + return; +} + +/* Third example, using simple profiler objects */ + +void profilerExample1(void) { + /* This function is timed with a profiler object */ + auto * profiler = apex::start(__func__); + usleep(2000); + apex::stop(profiler); +} + +void profilerExample2(void) { + /* This function is timed with a profiler object */ + auto * profiler = apex::start((apex_function_address)&profilerExample2); + usleep(2000); + apex::stop(profiler); +} + void* someThread(void* tmp) { - int* tid = (int*)tmp; - char name[32]; - sprintf(name, "worker-thread#%d", *tid); - register_thread(name); - profiler* p = start((apex_function_address)someThread); - sample_value("/threadqueue{locality#0/total}/length", 2.0); - char counter[64]; - sprintf(counter, "/threadqueue{locality#0/%s}/length", name); - sample_value(counter, 2.0); - stop(p); - exit_thread(); - return NULL; + int* tid = (int*)tmp; + char name[32]; + sprintf(name, "worker-thread#%d", *tid); + /* Tell APEX that there is a new thread */ + apex::register_thread(name); + /* Time this thread */ + apex::profiler* p = apex::start((apex_function_address)someThread); + /* Sample a counter */ + apex::sample_value("test_counter_1", 2.0); + char counter[64]; + /* Sample another counter */ + sprintf(counter, "test_counter_%s", name); + apex::sample_value(counter, 2.0); + /* Stop timing the thread */ + apex::stop(p); + apex::exit_thread(); + return NULL; } int main (int argc, char** argv) { - init(argv[0], 0, 1); - cout << "APEX Version : " << version() << endl; - apex_options::print_options(); - profiler* p = start((apex_function_address)(main)); - pthread_t thread[2]; - int tid = 0; - pthread_create(&(thread[0]), NULL, someThread, &tid); - int tid2 = 1; - pthread_create(&(thread[1]), NULL, someThread, &tid2); - pthread_join(thread[0], NULL); - pthread_join(thread[1], NULL); - stop(p); - finalize(); - return 0; + /* Initialize APEX */ + apex::init(argv[0], 0, 1); + /* Get some version and verbose option information */ + cout << "APEX Version : " << apex::version() << endl; + apex::apex_options::print_options(); + apex::apex_options::use_screen_output(true); + /* Start a timer for the main function, using its address (requires binutils) */ + apex::profiler* p = apex::start((apex_function_address)(main)); + /* Launch two threads */ + pthread_t thread[2]; + int tid = 0; + pthread_create(&(thread[0]), NULL, someThread, &tid); + int tid2 = 1; + pthread_create(&(thread[1]), NULL, someThread, &tid2); + /* Join the 2 threads */ + pthread_join(thread[0], NULL); + pthread_join(thread[1], NULL); + + /* test some other timers */ + scopedTimerExample1(); + scopedTimerExample2(); + taskWrapperExample1(); + taskWrapperExample2(); + profilerExample1(); + profilerExample2(); + + /* Stop the main timer and exit */ + apex::stop(p); + apex::finalize(); + return 0; } From 821b85976baad9f6a61260045e31cf5b3118d0bd Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Wed, 29 Jan 2020 12:37:03 -0800 Subject: [PATCH 04/14] Fixing performance bug with a lock being held tooo long when processing profile objects from the queues. --- src/apex/profiler_listener.cpp | 58 ++++++++++++++++------- src/unit_tests/C++/apex_pthread_flood.cpp | 2 +- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/apex/profiler_listener.cpp b/src/apex/profiler_listener.cpp index 7efb022e..94d4f85a 100644 --- a/src/apex/profiler_listener.cpp +++ b/src/apex/profiler_listener.cpp @@ -1070,10 +1070,14 @@ node_color * get_node_color(double v,double vmin,double vmax) #ifdef APEX_HAVE_HPX bool schedule_another_task = false; { - std::unique_lock queue_lock(queue_mtx); - for (auto a_queue : allqueues) { + size_t num_queues = 0; + { + std::unique_lock queue_lock(queue_mtx); + num_queues = allqueues.size(); + } + for (size_t q = 0 ; q < num_queues ; q++) { int i = 0; - while(!_done && a_queue->try_dequeue(p)) { + while(!_done && allqueues[q]->try_dequeue(p)) { process_profile(p, 0); if (++i > 1000) { schedule_another_task = true; @@ -1083,10 +1087,14 @@ node_color * get_node_color(double v,double vmin,double vmax) } } if (apex_options::use_taskgraph_output()) { - std::unique_lock queue_lock(queue_mtx); - for (auto a_queue : dependency_queues) { + size_t num_queues = 0; + { + std::unique_lock queue_lock(queue_mtx); + num_queues = dependency_queues.size(); + } + for (size_t q = 0 ; q < num_queues ; q++) { int i = 0; - while(!_done && a_queue->try_dequeue(td)) { + while(!_done && dependency_queues[q]->try_dequeue(td)) { process_dependency(td); if (++i > 1000) { schedule_another_task = true; @@ -1104,17 +1112,25 @@ node_color * get_node_color(double v,double vmin,double vmax) "profiler_listener::process_profiles: main loop"); } { - std::unique_lock queue_lock(queue_mtx); - for (auto a_queue : allqueues) { - while(!_done && a_queue->try_dequeue(p)) { + size_t num_queues = 0; + { + std::unique_lock queue_lock(queue_mtx); + num_queues = allqueues.size(); + } + for (size_t q = 0 ; q < num_queues ; q++) { + while(!_done && allqueues[q]->try_dequeue(p)) { process_profile(p, 0); } } } if (apex_options::use_taskgraph_output()) { - std::unique_lock queue_lock(queue_mtx); - for (auto a_queue : dependency_queues) { - while(!_done && a_queue->try_dequeue(td)) { + size_t num_queues = 0; + { + std::unique_lock queue_lock(queue_mtx); + num_queues = dependency_queues.size(); + } + for (size_t q = 0 ; q < num_queues ; q++) { + while(!_done && dependency_queues[q]->try_dequeue(td)) { process_dependency(td); } } @@ -1285,9 +1301,13 @@ if (rc != 0) cout << "PAPI error! " << name << ": " << PAPI_strerror(rc) << endl { size_t ignored = 0; { // we need to lock in case another thread appears - std::unique_lock queue_lock(queue_mtx); - for (auto a_queue : allqueues) { - ignored += a_queue->size_approx(); + size_t num_queues = 0; + { + std::unique_lock queue_lock(queue_mtx); + num_queues = allqueues.size(); + } + for (size_t q = 0 ; q < num_queues ; q++) { + ignored += allqueues[q]->size_approx(); } } if (ignored > 100000) { @@ -1299,8 +1319,12 @@ if (rc != 0) cout << "PAPI error! " << name << ": " << PAPI_strerror(rc) << endl * so just process the queue. Anyway, it shouldn't get backed up that * much without suggesting there is a bigger problem. */ { - std::unique_lock queue_lock(queue_mtx); - for (unsigned int i=0; i queue_lock(queue_mtx); + num_queues = allqueues.size(); + } + for (unsigned int i=0 ; i < num_queues ; ++i) { if (apex_options::use_tau()) { tau_listener::Tau_start_wrapper( "profiler_listener::concurrent_cleanup"); diff --git a/src/unit_tests/C++/apex_pthread_flood.cpp b/src/unit_tests/C++/apex_pthread_flood.cpp index c0c73927..ca6afd89 100644 --- a/src/unit_tests/C++/apex_pthread_flood.cpp +++ b/src/unit_tests/C++/apex_pthread_flood.cpp @@ -15,7 +15,7 @@ #ifdef APEX_HAVE_TAU #define FLOOD_LEVEL 15 // TAU has a limit of 128 threads. #else -#define FLOOD_LEVEL 1000 +#define FLOOD_LEVEL 100 #endif inline int foo (int i) { From 141cf3e02d057b72bfcd0f606016b64189b51e61 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Sun, 23 Feb 2020 14:16:46 -0800 Subject: [PATCH 05/14] Cleaning up apex::reset behavior --- src/apex/apex_types.h | 1 + src/apex/profile.hpp | 2 ++ src/apex/profiler_listener.cpp | 8 ++++++-- src/unit_tests/C++/apex_dump.cpp | 7 ++++++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/apex/apex_types.h b/src/apex/apex_types.h index 3aa14241..8aa01156 100644 --- a/src/apex/apex_types.h +++ b/src/apex/apex_types.h @@ -183,6 +183,7 @@ typedef struct _profile double maximum; /*!< Maximum value seen by the timer or counter */ apex_profile_type type; /*!< Whether this is a timer or a counter */ double papi_metrics[8]; /*!< Array of accumulated PAPI hardware metrics */ + int times_reset; /*!< How many times was this timer reset */ } apex_profile; /** Rather than use void pointers everywhere, be explicit about diff --git a/src/apex/profile.hpp b/src/apex/profile.hpp index c861ec9c..58ed0489 100644 --- a/src/apex/profile.hpp +++ b/src/apex/profile.hpp @@ -61,6 +61,7 @@ class profile { _profile.sum_squares = 0.0; _profile.minimum = 0.0; _profile.maximum = 0.0; + _profile.times_reset++; }; double get_calls() { return _profile.calls; } double get_mean() { return (_profile.accumulated / _profile.calls); } @@ -68,6 +69,7 @@ class profile { double * get_papi_metrics() { return (_profile.papi_metrics); } double get_minimum() { return (_profile.minimum); } double get_maximum() { return (_profile.maximum); } + int get_times_reset() { return (_profile.times_reset); } double get_variance() { double mean = get_mean(); double variance = ((_profile.sum_squares / _profile.calls) - (mean * mean)); diff --git a/src/apex/profiler_listener.cpp b/src/apex/profiler_listener.cpp index 7efb022e..9d4ae06c 100644 --- a/src/apex/profiler_listener.cpp +++ b/src/apex/profiler_listener.cpp @@ -508,7 +508,11 @@ std::unordered_set free_profiles; } } #endif - if(p->get_calls() < 1) { + if(p->get_calls() == 0 && p->get_times_reset() > 0) { + screen_output << "Not called since reset." << endl; + return; + } + if(p->get_calls() < 1 && p->get_times_reset() == 0) { p->get_profile()->calls = 1; } if (p->get_calls() < 999999) { @@ -1275,7 +1279,7 @@ if (rc != 0) cout << "PAPI error! " << name << ": " << PAPI_strerror(rc) << endl while(consumer_task_running.test_and_set(memory_order_acq_rel)) { } // stop the main timer, and process that profile? - main_timer->stop(); + main_timer->stop(true); push_profiler((unsigned int)thread_instance::get_id(), main_timer); // output to screen? diff --git a/src/unit_tests/C++/apex_dump.cpp b/src/unit_tests/C++/apex_dump.cpp index 0d679490..cf3861ec 100644 --- a/src/unit_tests/C++/apex_dump.cpp +++ b/src/unit_tests/C++/apex_dump.cpp @@ -20,8 +20,11 @@ int main (int argc, char** argv) { profiler * p = start("bar"); stop(p); } + // dump and reset everything + cout << "\n\n *** Should see 30 calls to foo, and 40 calls to bar...\n\n" << endl; dump(true); + usleep(100); // Call "foo" 3 times for(int i = 0; i < 3; ++i) { @@ -42,9 +45,10 @@ int main (int argc, char** argv) { stop(p); } // dump and reset nothing + cout << "\n\n *** Should see 3 calls to foo, and 4 calls to bar, and 100 calls to Test Timer...\n\n" << endl; dump(false); // Reset "Test Timer" - reset("Test Timer"); + reset("foo"); usleep(100); // Call "Test Timer" 25 times for(int i = 0; i < 25; ++i) { @@ -53,6 +57,7 @@ int main (int argc, char** argv) { } // The profile should show "Test Timer" was called 25 times. stop(main_profiler); + cout << "\n\n *** Should see 0 calls to foo, and 4 calls to bar, and 100+ calls to Test Timer...\n\n" << endl; finalize(); apex_profile * profile = get_profile("Test Timer"); if (profile) { From d2648d8433296ae3f5f56c1e0501f3c5f29ce60d Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Wed, 26 Feb 2020 13:18:15 -0800 Subject: [PATCH 06/14] Updating to latest perfstubs API --- CMakeLists.txt | 4 +-- src/apex/perftool_implementation.cpp | 46 ++++++++++++++-------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b0dc2d98..91db5eb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -677,7 +677,7 @@ git_external(perfstubs find_file( PERFSTUBS_HEADER - NAMES perfstubs_api/Tool.h + NAMES perfstubs_api/tool.h PATHS ${PROJECT_SOURCE_DIR}/perfstubs) if(PERFSTUBS_HEADER) @@ -817,7 +817,7 @@ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/pkgconfig/apex.pc.in ${CMAKE_BINARY_DIR}/pkgconfig/apex.pc @ONLY) INSTALL_FILES(/lib/pkgconfig FILES pkgconfig/apex.pc) -if (APEX_USE_WEAK_SYMBOLS) +if (APEX_USE_WEAK_SYMBOLS) add_definitions(-DAPEX_USE_WEAK_SYMBOLS) else() find_library(DYNAMICLIB dl) diff --git a/src/apex/perftool_implementation.cpp b/src/apex/perftool_implementation.cpp index 4ab1d985..62292863 100644 --- a/src/apex/perftool_implementation.cpp +++ b/src/apex/perftool_implementation.cpp @@ -4,7 +4,7 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "perfstubs/perfstubs_api/Tool.h" +#include "perfstubs/perfstubs_api/tool.h" #include #include "apex.h" #include "thread_instance.hpp" @@ -15,54 +15,54 @@ std::mutex my_mutex; extern "C" { // library function declarations - void perftool_init(void) { + void ps_initialize(void) { apex_init("PerfStubs API", 0, 1); } - void perftool_register_thread(void) { + void ps_register_thread(void) { apex_register_thread("PerfStubs Thread"); } - void perftool_exit(void) { + void ps_finalize(void) { apex_exit_thread(); } - void perftool_dump(void) { + void ps_dump_data(void) { apex_dump(false); } // measurement function declarations - void* perftool_timer_create(const char *timer_name) { + void* ps_timer_create(const char *timer_name) { return strdup(timer_name); } - void perftool_timer_start(const void *timer) { + void ps_timer_start(const void *timer) { apex_start(APEX_NAME_STRING, const_cast(timer)); } - void perftool_timer_stop(const void *timer) { + void ps_timer_stop(const void *timer) { apex_stop(apex::thread_instance::instance().get_current_profiler()); } - void perftool_dynamic_phase_start(const char *iteration_prefix, + void ps_dynamic_phase_start(const char *iteration_prefix, int iteration_number) { std::stringstream ss; ss << iteration_prefix << " " << iteration_number; apex_start(APEX_NAME_STRING, (void*)const_cast(ss.str().c_str())); } - void perftool_dynamic_phase_stop(const char *iteration_prefix, + void ps_dynamic_phase_stop(const char *iteration_prefix, int iteration_number) { apex_stop(apex::thread_instance::instance().get_current_profiler()); } - void* perftool_create_counter(const char *counter_name) { + void* ps_create_counter(const char *counter_name) { return (void*)(strdup(counter_name)); } - void perftool_sample_counter(const void *counter, double value) { + void ps_sample_counter(const void *counter, double value) { apex_sample_value((const char *)(counter), value); } - void perftool_metadata(const char *name, const char *value) { + void ps_set_metadata(const char *name, const char *value) { // do nothing } // data query function declarations - void perftool_get_timer_data(perftool_timer_data_t *timer_data) { - memset(timer_data, 0, sizeof(perftool_timer_data_t)); + void ps_get_timer_data(ps_tool_timer_data_t *timer_data) { + memset(timer_data, 0, sizeof(ps_tool_timer_data_t)); } - void perftool_free_timer_data(perftool_timer_data_t *timer_data) { + void ps_free_timer_data(ps_tool_timer_data_t *timer_data) { if (timer_data == nullptr) { return; @@ -83,12 +83,12 @@ extern "C" { timer_data->values = nullptr; } } - void perftool_get_counter_data(perftool_counter_data_t *counter_data) { - memset(counter_data, 0, sizeof(perftool_counter_data_t)); + void ps_get_counter_data(ps_tool_counter_data_t *counter_data) { + memset(counter_data, 0, sizeof(ps_tool_counter_data_t)); } - void perftool_free_counter_data(perftool_counter_data_t *counter_data) { + void ps_free_counter_data(ps_tool_counter_data_t *counter_data) { if (counter_data == nullptr) - { + { return; } if (counter_data->counter_names != nullptr) @@ -122,10 +122,10 @@ extern "C" { counter_data->value_sumsqr = nullptr; } } - void perftool_get_metadata(perftool_metadata_t *metadata) { - memset(metadata, 0, sizeof(perftool_metadata_t)); + void ps_get_metadata(ps_tool_metadata_t *metadata) { + memset(metadata, 0, sizeof(ps_tool_metadata_t)); } - void perftool_free_metadata(perftool_metadata_t *metadata) { + void ps_free_metadata(ps_tool_metadata_t *metadata) { if (metadata == nullptr) { return; From 9fbad9e68d8a2a1070bf30702fba5d2c0598082c Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Wed, 26 Feb 2020 14:21:13 -0800 Subject: [PATCH 07/14] Fixing mismatched apex_init() declaration --- src/apex/apex.cpp | 8 ++++---- src/apex/apex.h | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/apex/apex.cpp b/src/apex/apex.cpp index b6d98cc0..b61c2776 100644 --- a/src/apex/apex.cpp +++ b/src/apex/apex.cpp @@ -1818,16 +1818,16 @@ using namespace apex; extern "C" { - int apex_init(const char * thread_name, unsigned long int comm_rank, - unsigned long int comm_size) { + int apex_init(const char * thread_name, const uint64_t comm_rank, + const uint64_t comm_size) { return init(thread_name, comm_rank, comm_size); } - int apex_init_(unsigned long int comm_rank, unsigned long int comm_size) { + int apex_init_(const uint64_t comm_rank, const uint64_t comm_size) { return init("FORTRAN thread", comm_rank, comm_size); } - int apex_init__(unsigned long int comm_rank, unsigned long int comm_size) { + int apex_init__(const uint64_t comm_rank, const uint64_t comm_size) { return init("FORTRAN thread", comm_rank, comm_size); } diff --git a/src/apex/apex.h b/src/apex/apex.h index c06be722..49e5e168 100644 --- a/src/apex/apex.h +++ b/src/apex/apex.h @@ -26,6 +26,7 @@ #include "apex_types.h" #include "apex_export.h" #include "stdbool.h" +#include "stdint.h" #ifdef __cplusplus extern "C" { @@ -53,8 +54,8 @@ extern "C" { \return APEX_NOERROR on success, or APEX_ERROR on failure. \sa @ref apex_finalize */ -APEX_EXPORT int apex_init(const char * thread_name, const unsigned int - comm_rank, const unsigned int comm_size); +APEX_EXPORT int apex_init(const char * thread_name, const uint64_t comm_rank, + const uint64_t comm_size); /** \brief Dump output from APEX. From c8bd6827de2ed1dbfc77f8d35b9b2a1e35a79212 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Tue, 3 Mar 2020 20:56:43 -0800 Subject: [PATCH 08/14] Adding counters to CSV output. --- src/apex/profiler_listener.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/apex/profiler_listener.cpp b/src/apex/profiler_listener.cpp index 658d82dd..7129abdc 100644 --- a/src/apex/profiler_listener.cpp +++ b/src/apex/profiler_listener.cpp @@ -569,6 +569,12 @@ std::unordered_set free_profiles; screen_output << endl; csv_output << endl; } else { + csv_output << "\"" << action_name << "\","; + csv_output << llround(p->get_calls()) << ","; + csv_output << std::llround(p->get_minimum()) << ","; + csv_output << std::llround(p->get_mean()) << ","; + csv_output << std::llround(p->get_maximum()) << ","; + csv_output << std::llround(p->get_stddev()) << endl; if (action_name.find('%') == string::npos && p->get_minimum() > 10000) { screen_output << string_format(FORMAT_SCIENTIFIC, p->get_minimum()) << " " ; } else { @@ -627,12 +633,6 @@ std::unordered_set free_profiles; screen_output << "Available CPU time: " << total_main << " seconds" << endl << endl; map::const_iterator it; -#if APEX_HAVE_PAPI - for (int i = 0 ; i < num_papi_counters ; i++) { - csv_output << ",\"" << metric_names[i] << "\""; - } -#endif - csv_output << endl; double total_accumulated = 0.0; unordered_map::const_iterator it2; std::vector id_vector; @@ -645,6 +645,8 @@ std::unordered_set free_profiles; id_vector.push_back(task_id); } } + csv_output << "\"counter\",\"num samples\",\"minimum\",\"mean\"" + << "\"maximum\",\"stddev\"" << endl; if (id_vector.size() > 0) { screen_output << "Counter : " << "#samples | minimum | mean | maximum | stddev " << endl; @@ -665,8 +667,14 @@ std::unordered_set free_profiles; << "------------------------------------------------------" << endl << endl;; } - csv_output << "\"task\",\"num calls\",\"total cycles\",\"total " - << "microseconds\"" << std::endl; + csv_output << "\n\n\"task\",\"num calls\",\"total cycles\",\"total " + << "microseconds\""; +#if APEX_HAVE_PAPI + for (int i = 0 ; i < num_papi_counters ; i++) { + csv_output << ",\"" << metric_names[i] << "\""; + } +#endif + csv_output << endl; std::string re("PAPI_"); std::string tmpstr(apex_options::papi_metrics()); size_t index = 0; From 8ba5090ad1a2b2945c7e0037b6a11afc1a2fe64d Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Wed, 4 Mar 2020 11:35:41 -0800 Subject: [PATCH 09/14] Do write out the APEX_MAIN timer at exit. --- src/apex/profiler_listener.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/apex/profiler_listener.cpp b/src/apex/profiler_listener.cpp index 7129abdc..b06f112b 100644 --- a/src/apex/profiler_listener.cpp +++ b/src/apex/profiler_listener.cpp @@ -475,9 +475,10 @@ std::unordered_set free_profiles; * a thread_instance object that is NOT a worker. */ thread_instance::instance(false); string action_name = task_id.get_name(); + /* if (action_name.compare(APEX_MAIN) == 0) { return; // don't write out apex main timer - } + } */ string shorter(action_name); size_t maxlength = 41; if (timer) maxlength = 52; From e23a94185d58148b633a14cae308ca4717f50886 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Mon, 9 Mar 2020 16:17:34 -0700 Subject: [PATCH 10/14] Fixing location of perfstubs git repo so that checkouts happen correctly --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91db5eb2..dcef0afa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -670,7 +670,7 @@ else() endif() ### Set up perfstubs stuff -git_external(perfstubs +git_external(perfstubs.git https://github.com/khuck/perfstubs.git master VERBOSE) @@ -678,10 +678,10 @@ git_external(perfstubs find_file( PERFSTUBS_HEADER NAMES perfstubs_api/tool.h - PATHS ${PROJECT_SOURCE_DIR}/perfstubs) + PATHS ${PROJECT_SOURCE_DIR}/perfstubs.git) if(PERFSTUBS_HEADER) - message(INFO " Found perfstubs at ${PROJECT_SOURCE_DIR}/perfstubs") + message(INFO " Found perfstubs at ${PROJECT_SOURCE_DIR}/perfstubs.git") include_directories(${PROJECT_SOURCE_DIR}) else() message(FATAL_ERROR " perfstubs not found. This should have been checked out automatically. " From 622468ba6dc71a75c4e062ac1bde58651dbc84cd Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Mon, 9 Mar 2020 16:21:26 -0700 Subject: [PATCH 11/14] Fixing location of perfstubs headers --- CMakeLists.txt | 2 +- src/apex/perftool_implementation.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dcef0afa..0035e327 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -682,7 +682,7 @@ find_file( if(PERFSTUBS_HEADER) message(INFO " Found perfstubs at ${PROJECT_SOURCE_DIR}/perfstubs.git") - include_directories(${PROJECT_SOURCE_DIR}) + include_directories(${PROJECT_SOURCE_DIR}/perfstubs.git) else() message(FATAL_ERROR " perfstubs not found. This should have been checked out automatically. " "Try manually check out https://github.com/khuck/perfstubs.git to ${PROJECT_SOURCE_DIR}") diff --git a/src/apex/perftool_implementation.cpp b/src/apex/perftool_implementation.cpp index 62292863..61513c8f 100644 --- a/src/apex/perftool_implementation.cpp +++ b/src/apex/perftool_implementation.cpp @@ -4,7 +4,7 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#include "perfstubs/perfstubs_api/tool.h" +#include "perfstubs_api/tool.h" #include #include "apex.h" #include "thread_instance.hpp" From f6f1cf2f3699d120fbd3add7466b90b25aace0b5 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Mon, 9 Mar 2020 16:28:38 -0700 Subject: [PATCH 12/14] Fixing git checkout for good this time --- CMakeLists.txt | 10 +++++----- cmake/Modules/GitExternal.cmake | 28 ++++++++++++++-------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0035e327..a8b9dfde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -654,7 +654,7 @@ include(GitExternal) git_external(concurrentqueue https://github.com/cameron314/concurrentqueue.git master - VERBOSE) + VERBOSE NO_UPDATE) find_file( CONCURRENTQUEUE_HEADER @@ -670,7 +670,7 @@ else() endif() ### Set up perfstubs stuff -git_external(perfstubs.git +git_external(perfstubs https://github.com/khuck/perfstubs.git master VERBOSE) @@ -678,11 +678,11 @@ git_external(perfstubs.git find_file( PERFSTUBS_HEADER NAMES perfstubs_api/tool.h - PATHS ${PROJECT_SOURCE_DIR}/perfstubs.git) + PATHS ${PROJECT_SOURCE_DIR}/perfstubs) if(PERFSTUBS_HEADER) - message(INFO " Found perfstubs at ${PROJECT_SOURCE_DIR}/perfstubs.git") - include_directories(${PROJECT_SOURCE_DIR}/perfstubs.git) + message(INFO " Found perfstubs at ${PROJECT_SOURCE_DIR}/perfstubs") + include_directories(${PROJECT_SOURCE_DIR}/perfstubs) else() message(FATAL_ERROR " perfstubs not found. This should have been checked out automatically. " "Try manually check out https://github.com/khuck/perfstubs.git to ${PROJECT_SOURCE_DIR}") diff --git a/cmake/Modules/GitExternal.cmake b/cmake/Modules/GitExternal.cmake index 9eb87d6f..862e779f 100644 --- a/cmake/Modules/GitExternal.cmake +++ b/cmake/Modules/GitExternal.cmake @@ -19,12 +19,12 @@ # # [optional] Flags which control behaviour # NO_UPDATE -# When set, GitExternal will not change a repo that has already been checked out. -# The purpose of this is to allow one to set a default branch to be checked out, -# but stop GitExternal from changing back to that branch if the user has checked +# When set, GitExternal will not change a repo that has already been checked out. +# The purpose of this is to allow one to set a default branch to be checked out, +# but stop GitExternal from changing back to that branch if the user has checked # out and is working on another. -# VERBOSE -# When set, displays information about git commands that are executed +# VERBOSE +# When set, displays information about git commands that are executed # find_package(Git) @@ -101,15 +101,15 @@ function(GIT_EXTERNAL DIR REPO TAG) endif() # update tag -# GIT_EXTERNAL_MESSAGE("git rebase FETCH_HEAD") -# execute_process(COMMAND ${GIT_EXECUTABLE} rebase FETCH_HEAD -# RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE OUTPUT -# WORKING_DIRECTORY "${DIR}") -# if(RESULT) -# message(STATUS "git rebase failed, aborting ${DIR} merge") -# execute_process(COMMAND ${GIT_EXECUTABLE} rebase --abort -# WORKING_DIRECTORY "${DIR}") -# endif() + GIT_EXTERNAL_MESSAGE("git rebase FETCH_HEAD") + execute_process(COMMAND ${GIT_EXECUTABLE} rebase FETCH_HEAD + RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE OUTPUT + WORKING_DIRECTORY "${DIR}") + if(RESULT) + message(STATUS "git rebase failed, aborting ${DIR} merge") + execute_process(COMMAND ${GIT_EXECUTABLE} rebase --abort + WORKING_DIRECTORY "${DIR}") + endif() endif() else() From ac38902cf25084c76ca12add286f965043ddf871 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Mon, 16 Mar 2020 09:16:11 -0700 Subject: [PATCH 13/14] Ignoring the perfstubs directory git clean will wipe out the perfstubs directory without this change to .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 51f72e78..2e0e3ca5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,10 @@ build_* test doc/webdocs/site install* -rapidjson *.swp regression* *.sh *DS_Store concurrentqueue +perfstubs +rapidjson From b31729da716846ef0f3aba0163e78601ddeae1d2 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Fri, 20 Mar 2020 14:11:28 -0700 Subject: [PATCH 14/14] Changing location of papi on test build system --- etc/buildbot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/buildbot.sh b/etc/buildbot.sh index 9bd45e08..e71a4f97 100755 --- a/etc/buildbot.sh +++ b/etc/buildbot.sh @@ -39,7 +39,7 @@ yes_otf=" -DUSE_OTF2=TRUE -DOTF2_ROOT=/usr/local/otf2/2.1" yes_ompt=" -DUSE_OMPT=TRUE -DOMPT_ROOT=/usr/local/ompt/5.0" #yes_mpi=" -DUSE_MPI=TRUE -DCMAKE_C_COMPILER=mpicc -DCMAKE_CXX_COMPILER=mpicxx" yes_mpi=" -DUSE_MPI=TRUE" -yes_papi=" -DUSE_PAPI=TRUE -DPAPI_ROOT=/usr/local/papi/5.5.0" +yes_papi=" -DUSE_PAPI=TRUE -DPAPI_ROOT=/usr" yes_tau=" -DUSE_TAU=TRUE -DTAU_ROOT=/usr/local/tau/git -DTAU_ARCH=x86_64 -DTAU_OPTIONS=-pthread" # set defaults