Using ctest/inherit.c as a starting point, I modified the code to include all call to attach before the call to PAPI_start
- Code: Select all
if ( ( retval = PAPI_attach(EventSet, MACRO_PID) ) != PAPI_OK)
test_fail_exit( __FILE__, __LINE__, "PAPI_attach", retval );
For now I compile it with the current PID of the running application.
If I specify a single-thread application, then valid values are reported.
If I specify a multi-thread application, then it reports 0 values.
If I specify an application that has a sequential stage followed by a parallel stage, followed by another sequential stage, then in the example below I see the counter increase run during the sequential stage, stop during the parallel stage, and resume again in the sequential stage.
Am I using these two options incorrectly?
Is there a way to externally track all events created by a multi-threaded application?
Working Example Code:
- Code: Select all
#include <stdio.h>
#include <unistd.h>
#if defined(_AIX) || defined (__FreeBSD__) || defined (__APPLE__)
#include <sys/wait.h> /* ARGH! */
#else
#include <wait.h>
#endif
#include "papi_test.h"
/*
Build Instructions:
- place in src/ctest/ directory
- run make -C ../
Testing Instructions:
run the command below from the src/ctest/ directory
<launch application command> 2>&1 > /dev/null & gcc -I.. -I../testlib -I.. -g -DSTATIC_PAPI_EVENTS_TABLE -DPEINCLUDE="libpfm4/include/perfmon/perf_event.h" -D_REENTRANT -D_GNU_SOURCE -DUSE_COMPILER_TLS -Wall -Ilibpfm4/include -Wextra -DPAPI_NO_MEMORY_MANAGEMENT -O0 inherit_attach.c ../testlib/libtestlib.a ../libpapi.a -DPID_VALUE=$! -o inherit_attach && ./inherit_attach
#sequential test:
yes 2>&1 > /dev/null & gcc -I.. -I../testlib -I.. -g -DSTATIC_PAPI_EVENTS_TABLE -DPEINCLUDE="libpfm4/include/perfmon/perf_event.h" -D_REENTRANT -D_GNU_SOURCE -DUSE_COMPILER_TLS -Wall -Ilibpfm4/include -Wextra -DPAPI_NO_MEMORY_MANAGEMENT -O0 inherit_attach.c ../testlib/libtestlib.a ../libpapi.a -DPID_VALUE=$! -o inherit_attach && ./inherit_attach
Note: If the build command does not work for you, construct a new one by the following:
1) Log the output of the make command
2) Copy the line that compiles inherit.c
3) change references to inherit to inherity_attach
4) Add -DPID_VALUE=$! before the -o flag
*/
int
main( int argc, char **argv )
{
int retval, pid, EventSet = PAPI_NULL;
long long int values[] = {0};
PAPI_option_t opt;
tests_quiet( argc, argv );
pid = PID_VALUE ;
if ( ( retval = PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT )
test_fail_exit( __FILE__, __LINE__, "PAPI_library_init", retval );
if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK )
test_fail_exit( __FILE__, __LINE__, "PAPI_create_eventset", retval );
if ( ( retval = PAPI_assign_eventset_component( EventSet, 0 ) ) != PAPI_OK )
test_fail_exit( __FILE__, __LINE__, "PAPI_assign_eventset_component", retval );
memset( &opt, 0x0, sizeof ( PAPI_option_t ) );
opt.inherit.inherit = PAPI_INHERIT_ALL;
opt.inherit.eventset = EventSet;
if ( ( retval = PAPI_set_opt( PAPI_INHERIT, &opt ) ) != PAPI_OK ) {
if ( retval == PAPI_ECMP) {
test_skip( __FILE__, __LINE__, "Inherit not supported by current component.\n", retval );
} else {
test_fail_exit( __FILE__, __LINE__, "PAPI_set_opt", retval );
}
}
if ( ( retval = PAPI_query_event( PAPI_TOT_CYC ) ) != PAPI_OK )
test_fail_exit( __FILE__, __LINE__, "PAPI_query_event", retval );
if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_CYC ) ) != PAPI_OK )
test_fail_exit( __FILE__, __LINE__, "PAPI_add_event", retval );
if ( ( retval = PAPI_attach(EventSet, pid) ) != PAPI_OK)
test_fail_exit( __FILE__, __LINE__, "PAPI_attach", retval );
if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
test_fail_exit( __FILE__, __LINE__, "PAPI_start", retval );
long long int lastValue = -1;
while (1) {
if ( ( retval = PAPI_read( EventSet, values ) ) != PAPI_OK ) {
printf("PAPI_Read Error %d\n", retval);
} else if (lastValue != values[0]) {
lastValue = values[0];
printf( "PAPI_TOT_CYC: \t%lld\n", values[0] );
}
}
return 1;
}