void *Thread(void *arg) { int retval, num_tests = 1; int EventSet1=PAPI_NULL; int mask1, papi_event; int num_events1; long long **values; long long elapsed_us, elapsed_cyc; char event_name[PAPI_MAX_STR_LEN]; /* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, depends on the availability of the event on the platform */ EventSet1 = add_two_nonderived_events(&num_events1, &papi_event, hw_info, &mask1); expected[EventSet1] = *(int *)arg / mythreshold; myid[EventSet1] = PAPI_thread_id(); values = allocate_test_space(num_tests, num_events1); elapsed_us = PAPI_get_real_usec(); elapsed_cyc = PAPI_get_real_cyc(); if ((retval = PAPI_overflow(EventSet1, papi_event, mythreshold, 0, handler)) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_overflow", retval); /* start_timer(1); */ if ((retval = PAPI_start(EventSet1)) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_start", retval); do_stuff(); if ((retval = PAPI_stop(EventSet1, values[0])) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_stop", retval); elapsed_us = PAPI_get_real_usec() - elapsed_us; elapsed_cyc = PAPI_get_real_cyc() - elapsed_cyc; if ((retval = PAPI_overflow(EventSet1, papi_event, 0, 0, NULL)) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_overflow", retval); remove_test_events(&EventSet1, mask1); if ((retval = PAPI_event_code_to_name(papi_event, event_name)) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_event_code_to_name", retval); if (!TESTS_QUIET) { printf("Thread 0x%x %s : \t%lld\n", (int) pthread_self(), event_name, (values[0])[0]); printf("Thread 0x%x PAPI_TOT_CYC: \t%lld\n", (int) pthread_self(), (values[0])[1]); printf("Thread 0x%x Real usec : \t%lld\n", (int) pthread_self(), elapsed_us); printf("Thread 0x%x Real cycles : \t%lld\n", (int) pthread_self(), elapsed_cyc); } free_test_space(values, num_tests); pthread_exit(NULL); return (NULL); }
int main(int argc, char **argv) { int num_tests = 6; long length; int mask; int retval; int mythreshold=THRESHOLD; const PAPI_hw_info_t *hw_info; const PAPI_exe_info_t *prginfo; caddr_t start, end; prof_init(argc, argv, &hw_info, &prginfo); mask = prof_events(num_tests,hw_info); #ifdef PROFILE_ALL /* use these lines to profile entire code address space */ start = prginfo->address_info.text_start; end = prginfo->address_info.text_end; #else /* use these lines to profile only do_flops address space */ start = (caddr_t)do_flops; end = (caddr_t)fdo_flops; /* Itanium and ppc64 processors return function descriptors instead of function addresses. You must dereference the descriptor to get the address. */ #if defined(ITANIUM1) || defined(ITANIUM2) || defined(__powerpc64__) start = (caddr_t)(((struct fdesc *)start)->ip); end = (caddr_t)(((struct fdesc *)end)->ip); #endif #endif #if defined(linux) { char *tmp = getenv("THRESHOLD"); if (tmp) mythreshold = atoi(tmp); } #endif length = end - start; if (length < 0) test_fail(__FILE__, __LINE__, "Profile length < 0!", length); prof_print_address("Test case profile: POSIX compatible profiling with hardware counters.\n",prginfo); prof_print_prof_info(start,end,mythreshold,event_name); retval = do_profile(start, length, FULL_SCALE, mythreshold, PAPI_PROFIL_BUCKET_16); if (retval) retval = do_profile(start, length, FULL_SCALE, mythreshold, PAPI_PROFIL_BUCKET_32); if (retval) retval = do_profile(start, length, FULL_SCALE, mythreshold, PAPI_PROFIL_BUCKET_64); remove_test_events(&EventSet, mask); if (retval) test_pass(__FILE__, values, num_tests); else test_fail(__FILE__, __LINE__, "No information in buffers", 1); exit(1); }
void Thread( int t, int n ) { int retval, num_tests = 1; int EventSet1 = PAPI_NULL; int PAPI_event, mask1; int num_events1; long long **values; long long elapsed_us, elapsed_cyc; char event_name[PAPI_MAX_STR_LEN]; /* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, depending on the availability of the event on the platform */ EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 ); retval = PAPI_event_code_to_name( PAPI_event, event_name ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); values = allocate_test_space( num_tests, num_events1 ); retval = PAPI_start( EventSet1 ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_start", retval ); elapsed_us = PAPI_get_real_usec( ); elapsed_cyc = PAPI_get_real_cyc( ); do_flops( n ); elapsed_us = PAPI_get_real_usec( ) - elapsed_us; elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; retval = PAPI_stop( EventSet1, values[0] ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); remove_test_events( &EventSet1, mask1 ); if ( !TESTS_QUIET ) { printf( "Thread %#x %-12s : \t%lld\n", t, event_name, values[0][1] ); printf( "Thread %#x PAPI_TOT_CYC : \t%lld\n", t, values[0][0] ); } free_test_space( values, num_tests ); if ( !TESTS_QUIET ) { printf( "Thread %#x Real usec : \t%lld\n", t, elapsed_us ); printf( "Thread %#x Real cycles : \t%lld\n", t, elapsed_cyc ); } PAPI_unregister_thread( ); }
void Thread( int n ){ int retval, num_tests = 1; int EventSet1 = PAPI_NULL; int PAPI_event, mask1; int num_events1; long long **values; long long elapsed_us, elapsed_cyc, L1_DCM; char event_name[PAPI_MAX_STR_LEN]; printf( "Thread %#x started\n", omp_get_thread_num( ) ); num_events1 = 2; EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 ); retval = PAPI_event_code_to_name( PAPI_event, event_name ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); values = allocate_test_space( num_tests, num_events1 ); elapsed_us = PAPI_get_real_usec( ); elapsed_cyc = PAPI_get_real_cyc( ); retval = PAPI_start( EventSet1 ); do_flops( n ); retval = PAPI_stop( EventSet1, values[0] ); elapsed_us = PAPI_get_real_usec( ) - elapsed_us; elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; remove_test_events( &EventSet1, mask1 ); if ( !TESTS_QUIET ) { printf( "Thread %#x %-12s : \t%lld\n", omp_get_thread_num( ), event_name, values[0][1] ); printf( "Thread %#x PAPI_TOT_CYC: \t%lld\n", omp_get_thread_num( ), values[0][0] ); printf( "Thread %#x Real usec : \t%lld\n", omp_get_thread_num( ), elapsed_us ); printf( "Thread %#x Real cycles : \t%lld\n", omp_get_thread_num( ), elapsed_cyc ); } free_test_space( values, num_tests ); PAPI_unregister_thread( ); printf( "Thread %#x finished\n", omp_get_thread_num( ) ); }
void Thread( int n ) { int retval, num_tests = 1, tmp; int EventSet1 = PAPI_NULL; int mask1 = 0x5; int num_events1; long long **values; long long elapsed_us, elapsed_cyc; EventSet1 = add_test_events( &num_events1, &mask1 ); /* num_events1 is greater than num_events2 so don't worry. */ values = allocate_test_space( num_tests, num_events1 ); elapsed_us = PAPI_get_real_usec( ); elapsed_cyc = PAPI_get_real_cyc( ); retval = PAPI_start( EventSet1 ); if ( retval >= PAPI_OK ) exit( 1 ); do_flops( n ); retval = PAPI_stop( EventSet1, values[0] ); if ( retval >= PAPI_OK ) exit( 1 ); elapsed_us = PAPI_get_real_usec( ) - elapsed_us; elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; remove_test_events( &EventSet1, mask1 ); printf( "Thread %#x PAPI_FP_INS : \t%lld\n", pthread_self( ), ( values[0] )[0] ); printf( "Thread %#x PAPI_TOT_CYC: \t%lld\n", pthread_self( ), ( values[0] )[1] ); printf( "Thread %#x Real usec : \t%lld\n", pthread_self( ), elapsed_us ); printf( "Thread %#x Real cycles : \t%lld\n", pthread_self( ), elapsed_cyc ); free_test_space( values, num_tests ); }
void * Thread( void *arg ) { int retval, num_tests = 1, i; int EventSet1 = PAPI_NULL, mask1, PAPI_event; int num_events1; long long **values; long long elapsed_us, elapsed_cyc; unsigned short *profbuf; char event_name[PAPI_MAX_STR_LEN]; retval = PAPI_register_thread( ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval ); profbuf = ( unsigned short * ) malloc( length * sizeof ( unsigned short ) ); if ( profbuf == NULL ) exit( 1 ); memset( profbuf, 0x00, length * sizeof ( unsigned short ) ); /* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, depends on the availability of the event on the platform */ EventSet1 = add_two_nonderived_events( &num_events1, &PAPI_event, &mask1 ); values = allocate_test_space( num_tests, num_events1 ); if ( ( retval = PAPI_event_code_to_name( PAPI_event, event_name ) ) != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); elapsed_us = PAPI_get_real_usec( ); elapsed_cyc = PAPI_get_real_cyc( ); retval = PAPI_profil( profbuf, length, my_start, 65536, EventSet1, PAPI_event, THR, PAPI_PROFIL_POSIX ); if ( retval ) test_fail( __FILE__, __LINE__, "PAPI_profil", retval ); if ( ( retval = PAPI_start( EventSet1 ) ) != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_start", retval ); do_flops( *( int * ) arg ); if ( ( retval = PAPI_stop( EventSet1, values[0] ) ) != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); elapsed_us = PAPI_get_real_usec( ) - elapsed_us; elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; /* to remove the profile flag */ retval = PAPI_profil( profbuf, length, my_start, 65536, EventSet1, PAPI_event, 0, PAPI_PROFIL_POSIX ); if ( retval ) test_fail( __FILE__, __LINE__, "PAPI_profil", retval ); remove_test_events( &EventSet1, mask1 ); if ( !TESTS_QUIET ) { if ( mask1 == 0x3 ) { printf( "Thread 0x%x PAPI_TOT_INS : \t%lld\n", ( int ) pthread_self( ), ( values[0] )[0] ); } else { printf( "Thread 0x%x PAPI_FP_INS : \t%lld\n", ( int ) pthread_self( ), ( values[0] )[0] ); } printf( "Thread 0x%x PAPI_TOT_CYC: \t%lld\n", ( int ) pthread_self( ), ( values[0] )[1] ); printf( "Thread 0x%x Real usec : \t%lld\n", ( int ) pthread_self( ), elapsed_us ); printf( "Thread 0x%x Real cycles : \t%lld\n", ( int ) pthread_self( ), elapsed_cyc ); printf( "Test case: PAPI_profil() for pthreads\n" ); printf( "----Profile buffer for Thread 0x%x---\n", ( int ) pthread_self( ) ); for ( i = 0; i < ( int ) length; i++ ) { if ( profbuf[i] ) printf( "0x%lx\t%d\n", ( unsigned long ) ( my_start + 2 * i ), profbuf[i] ); } } for ( i = 0; i < ( int ) length; i++ ) if ( profbuf[i] ) break; if ( i >= ( int ) length ) test_fail( __FILE__, __LINE__, "No information in buffers", 1 ); free_test_space( values, num_tests ); retval = PAPI_unregister_thread( ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval ); return ( NULL ); }
int main(int argc, char **argv) { int i, num_events, num_tests = 6, mask = 0x1; int EventSet = PAPI_NULL; unsigned short **buf = (unsigned short **)profbuf; unsigned long length, blength; int num_buckets; PAPI_sprofil_t sprof[3]; int retval; const PAPI_hw_info_t *hw_info; const PAPI_exe_info_t *prginfo; caddr_t start, end; prof_init(argc, argv, &hw_info, &prginfo); start = prginfo->address_info.text_start; end = prginfo->address_info.text_end; if (start > end) test_fail(__FILE__, __LINE__, "Profile length < 0!", PAPI_ESBSTR); length = end - start; prof_print_address("Test case sprofile: POSIX compatible profiling over multiple regions.\n",prginfo); blength = prof_size(length, FULL_SCALE, PAPI_PROFIL_BUCKET_16, &num_buckets); prof_alloc(3, blength); /* First half */ sprof[0].pr_base = buf[0]; sprof[0].pr_size = blength; sprof[0].pr_off = (caddr_t) DO_FLOPS; #if defined(linux) && defined(__ia64__) if (!TESTS_QUIET) fprintf(stderr, "do_flops is at %p %p\n", &do_flops, sprof[0].pr_off); #endif sprof[0].pr_scale = FULL_SCALE; /* Second half */ sprof[1].pr_base = buf[1]; sprof[1].pr_size = blength; sprof[1].pr_off = (caddr_t) DO_READS; #if defined(linux) && defined(__ia64__) if (!TESTS_QUIET) fprintf(stderr, "do_reads is at %p %p\n", &do_reads, sprof[1].pr_off); #endif sprof[1].pr_scale = FULL_SCALE; /* Overflow bin */ sprof[2].pr_base = buf[2]; sprof[2].pr_size = 1; sprof[2].pr_off = 0; sprof[2].pr_scale = 0x2; EventSet = add_test_events(&num_events, &mask); values = allocate_test_space(num_tests, num_events); if ((retval = PAPI_sprofil(sprof, 3, EventSet, PAPI_TOT_CYC, THRESHOLD, PAPI_PROFIL_POSIX | PAPI_PROFIL_BUCKET_16)) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_sprofil", retval); do_stuff(); if ((retval = PAPI_start(EventSet)) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_start", retval); do_stuff(); if ((retval = PAPI_stop(EventSet, values[1])) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_stop", retval); /* clear the profile flag before removing the event */ if ((retval = PAPI_sprofil(sprof, 3, EventSet, PAPI_TOT_CYC, 0, PAPI_PROFIL_POSIX | PAPI_PROFIL_BUCKET_16)) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_sprofil", retval); remove_test_events(&EventSet, mask); if (!TESTS_QUIET) { printf("Test case: PAPI_sprofil()\n"); printf("---------Buffer 1--------\n"); for (i = 0; i < length / 2; i++) { if (buf[0][i]) printf("0x%lx\t%d\n", DO_FLOPS + 2 * i, buf[0][i]); } printf("---------Buffer 2--------\n"); for (i = 0; i < length / 2; i++) { if (buf[1][i]) printf("0x%lx\t%d\n", DO_READS + 2 * i, buf[1][i]); } printf("-------------------------\n"); printf("%u samples fell outside the regions.\n", *buf[2]); } retval = prof_check(2, PAPI_PROFIL_BUCKET_16, num_buckets); for (i=0;i<3;i++) { free(profbuf[i]); } if (retval == 0) test_fail(__FILE__, __LINE__, "No information in buffers", 1); test_pass(__FILE__, values, num_tests); exit(1); }
int main(int argc, char **argv) { int retval, num_tests = 5, num_events, tmp; long long **values; int EventSet=PAPI_NULL; int PAPI_event, mask; char event_name[PAPI_MAX_STR_LEN], add_event_str[PAPI_MAX_STR_LEN]; const PAPI_hw_info_t *hw_info; tests_quiet(argc, argv); /* Set TESTS_QUIET variable */ retval = PAPI_library_init(PAPI_VER_CURRENT); if (retval != PAPI_VER_CURRENT) test_fail(__FILE__, __LINE__, "PAPI_library_init", retval); hw_info = PAPI_get_hardware_info(); if (hw_info == NULL) test_fail(__FILE__, __LINE__, "PAPI_get_hardware_info", 2); /* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, depending on the availability of the event on the platform */ EventSet = add_two_events(&num_events, &PAPI_event, hw_info, &mask); retval = PAPI_event_code_to_name(PAPI_event, event_name); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_event_code_to_name", retval); sprintf(add_event_str, "PAPI_add_event[%s]", event_name); values = allocate_test_space(num_tests, num_events); retval = PAPI_start(EventSet); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_start", retval); do_flops(NUM_FLOPS); retval = PAPI_read(EventSet, values[0]); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_read", retval); retval = PAPI_reset(EventSet); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_reset", retval); do_flops(NUM_FLOPS); retval = PAPI_read(EventSet, values[1]); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_read", retval); do_flops(NUM_FLOPS); retval = PAPI_read(EventSet, values[2]); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_read", retval); do_flops(NUM_FLOPS); retval = PAPI_stop(EventSet, values[3]); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_stop", retval); retval = PAPI_read(EventSet, values[4]); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_read", retval); remove_test_events(&EventSet, mask); if (!TESTS_QUIET) { printf("Test case 1: Non-overlapping start, stop, read.\n"); printf("-----------------------------------------------\n"); tmp = PAPI_get_opt(PAPI_DEFDOM, NULL); printf("Default domain is: %d (%s)\n", tmp, stringify_all_domains(tmp)); tmp = PAPI_get_opt(PAPI_DEFGRN, NULL); printf("Default granularity is: %d (%s)\n", tmp, stringify_granularity(tmp)); printf("Using %d iterations of c += a*b\n", NUM_FLOPS); printf ("-------------------------------------------------------------------------\n"); printf("Test type : 1 2 3 4 5\n"); sprintf(add_event_str, "%s:", event_name); printf(TAB5, add_event_str, (values[0])[0], (values[1])[0], (values[2])[0], (values[3])[0], (values[4])[0]); printf(TAB5, "PAPI_TOT_CYC:", (values[0])[1], (values[1])[1], (values[2])[1], (values[3])[1], (values[4])[1]); printf ("-------------------------------------------------------------------------\n"); printf("Verification:\n"); printf("Row 1 Column 1 at least %d\n", NUM_FLOPS); printf("%% difference between %s 1 & 2: %.2f\n",add_event_str,100.0*(float)(values[0])[0]/(float)(values[1])[0]); printf("%% difference between %s 1 & 2: %.2f\n","PAPI_TOT_CYC",100.0*(float)(values[0])[1]/(float)(values[1])[1]); printf("Column 1 approximately equals column 2\n"); printf("Column 3 approximately equals 2 * column 2\n"); printf("Column 4 approximately equals 3 * column 2\n"); printf("Column 4 exactly equals column 5\n"); } { long long min, max; min = (long long) (values[1][0] * .9); max = (long long) (values[1][0] * 1.1); if (values[0][0] > max || values[0][0] < min || values[2][0] > (2 * max) || values[2][0] < (2 * min) || values[3][0] > (3 * max) || values[3][0] < (3 * min) || values[3][0] != values[4][0] || values[0][0] < (long long)NUM_FLOPS) { /* printf("min: "); printf(LLDFMT, min); printf("max: "); printf(LLDFMT, max); printf("1st: "); printf(LLDFMT, values[0][0]); printf("2nd: "); printf(LLDFMT, values[1][0]); printf("3rd: "); printf(LLDFMT, values[2][0]); printf("4th: "); printf(LLDFMT, values[3][0]); printf("5th: "); printf(LLDFMT, values[4][0]); printf("\n"); */ test_fail(__FILE__, __LINE__, event_name, 1); } min = (long long) (values[1][1] * .8); max = (long long) (values[1][1] * 1.2); if (values[0][1] > max || values[0][1] < min || values[2][1] > (2 * max) || values[2][1] < (2 * min) || values[3][1] > (3 * max) || values[3][1] < (3 * min) || values[3][1] != values[4][1]) { test_fail(__FILE__, __LINE__, "PAPI_TOT_CYC", 1); } } test_pass(__FILE__, values, num_tests); exit(1); }
int main( int argc, char **argv ) { long length; int mask; int retval; const PAPI_exe_info_t *prginfo; caddr_t start, end; prof_init( argc, argv, &prginfo ); hw_info = PAPI_get_hardware_info( ); if ( hw_info == NULL ) test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 ); mask = MASK_TOT_CYC | MASK_TOT_INS | MASK_FP_OPS | MASK_L2_TCM; #if defined(__powerpc__) if ( strcmp( hw_info->model_string, "POWER6" ) == 0 ) mask = MASK_TOT_CYC | MASK_FP_INS; else mask = MASK_TOT_CYC | MASK_TOT_INS | MASK_FP_INS; #endif #if defined(ITANIUM2) mask = MASK_TOT_CYC | MASK_FP_OPS | MASK_L2_TCM | MASK_L1_DCM; #endif EventSet = add_test_events( &num_events, &mask, 0 ); values = allocate_test_space( 1, num_events ); /* profile the cleara and my_main address space */ start = ( caddr_t ) cleara; end = ( caddr_t ) my_dummy; /* Itanium and PowerPC64 processors return function descriptors instead * of function addresses. You must dereference the descriptor to get the address. */ #if defined(ITANIUM1) || defined(ITANIUM2) || defined(__powerpc64__) start = ( caddr_t ) ( ( ( struct fdesc * ) start )->ip ); end = ( caddr_t ) ( ( ( struct fdesc * ) end )->ip ); #endif /* call dummy so it doesn't get optimized away */ retval = my_dummy( 1 ); length = end - start; if ( length < 0 ) test_fail( __FILE__, __LINE__, "Profile length < 0!", ( int ) length ); prof_print_address ( "Test case byte_profile: Multi-event profiling at byte resolution.\n", prginfo ); prof_print_prof_info( start, end, THRESHOLD, event_name ); retval = do_profile( start, ( unsigned ) length, FULL_SCALE * 2, THRESHOLD, PAPI_PROFIL_BUCKET_32, mask ); remove_test_events( &EventSet, mask ); if ( retval ) test_pass( __FILE__, values, 1 ); else test_fail( __FILE__, __LINE__, "No information in buffers", 1 ); return 1; }
int main( int argc, char **argv ) { int status, retval, num_tests = 2, tmp; int EventSet1 = PAPI_NULL, EventSet2 = PAPI_NULL; int PAPI_event, PAPI_event2, mask1, mask2; int num_events1, num_events2; long long **values; long long elapsed_us, elapsed_cyc, elapsed_virt_us, elapsed_virt_cyc; char event_name[PAPI_MAX_STR_LEN], add_event_str[PAPI_MAX_STR_LEN]; const PAPI_component_info_t *cmpinfo; pid_t pid, pid2; double ratio1,ratio2; /* Set TESTS_QUIET variable */ tests_quiet( argc, argv ); /* Initialize the library */ retval = PAPI_library_init( PAPI_VER_CURRENT ); if ( retval != PAPI_VER_CURRENT ) { test_fail_exit( __FILE__, __LINE__, "PAPI_library_init", retval ); } /* get the component info and check if we support attach */ if ( ( cmpinfo = PAPI_get_component_info( 0 ) ) == NULL ) { test_fail_exit( __FILE__, __LINE__, "PAPI_get_component_info", 0 ); } if ( cmpinfo->attach == 0 ) { test_skip( __FILE__, __LINE__, "Platform does not support attaching", 0 ); } /* fork off first child */ pid = fork( ); if ( pid < 0 ) { test_fail_exit( __FILE__, __LINE__, "fork()", PAPI_ESYS ); } if ( pid == 0 ) { exit( wait_for_attach_and_loop( 1 ) ); } /* fork off second child, does twice as much */ pid2 = fork( ); if ( pid2 < 0 ) { test_fail_exit( __FILE__, __LINE__, "fork()", PAPI_ESYS ); } if ( pid2 == 0 ) { exit( wait_for_attach_and_loop( 2 ) ); } /* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, depending on the availability of the event on the platform */ EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 ); EventSet2 = add_two_events( &num_events2, &PAPI_event2, &mask2 ); if ( cmpinfo->attach_must_ptrace ) { if ( ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) { perror( "ptrace(PTRACE_ATTACH)" ); return 1 ; } if ( waitpid( pid, &status, 0 ) == -1 ) { perror( "waitpid()" ); exit( 1 ); } if ( WIFSTOPPED( status ) == 0 ) { test_fail( __FILE__, __LINE__, "Child process didnt return true to WIFSTOPPED", 0 ); } if ( ptrace( PTRACE_ATTACH, pid2, NULL, NULL ) == -1 ) { perror( "ptrace(PTRACE_ATTACH)" ); return 1; } if ( waitpid( pid2, &status, 0 ) == -1 ) { perror( "waitpid()" ); exit( 1 ); } if ( WIFSTOPPED( status ) == 0 ) { test_fail( __FILE__, __LINE__, "Child process didnt return true to WIFSTOPPED", 0 ); } } retval = PAPI_attach( EventSet1, ( unsigned long ) pid ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_attach", retval ); } retval = PAPI_attach( EventSet2, ( unsigned long ) pid2 ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_attach", retval ); } retval = PAPI_event_code_to_name( PAPI_event, event_name ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); } sprintf( add_event_str, "PAPI_add_event[%s]", event_name ); /* num_events1 is greater than num_events2 so don't worry. */ values = allocate_test_space( num_tests, num_events1 ); /* Gather before values */ elapsed_us = PAPI_get_real_usec( ); elapsed_cyc = PAPI_get_real_cyc( ); elapsed_virt_us = PAPI_get_virt_usec( ); elapsed_virt_cyc = PAPI_get_virt_cyc( ); /* Wait for the SIGSTOP. */ if ( cmpinfo->attach_must_ptrace ) { if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) { perror( "ptrace(PTRACE_CONT)" ); return 1; } if ( waitpid( pid, &status, 0 ) == -1 ) { perror( "waitpid()" ); exit( 1 ); } if ( WIFSTOPPED( status ) == 0 ) { test_fail( __FILE__, __LINE__, "Child process didn't return true to WIFSTOPPED", 0 ); } if ( WSTOPSIG( status ) != SIGSTOP ) { test_fail( __FILE__, __LINE__, "Child process didn't stop on SIGSTOP", 0 ); } if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) { perror( "ptrace(PTRACE_CONT)" ); return 1; } if ( waitpid( pid2, &status, 0 ) == -1 ) { perror( "waitpid()" ); exit( 1 ); } if ( WIFSTOPPED( status ) == 0 ) { test_fail( __FILE__, __LINE__, "Child process didn't return true to WIFSTOPPED", 0 ); } if ( WSTOPSIG( status ) != SIGSTOP ) { test_fail( __FILE__, __LINE__, "Child process didn't stop on SIGSTOP", 0 ); } } /* start first child */ retval = PAPI_start( EventSet1 ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_start", retval ); } /* start second child */ retval = PAPI_start( EventSet2 ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_start", retval ); } /* Wait for the SIGSTOP. */ if ( cmpinfo->attach_must_ptrace ) { if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) { perror( "ptrace(PTRACE_ATTACH)" ); return 1; } if ( waitpid( pid, &status, 0 ) == -1 ) { perror( "waitpid()" ); exit( 1 ); } if ( WIFSTOPPED( status ) == 0 ) { test_fail( __FILE__, __LINE__, "Child process didn't return true to WIFSTOPPED", 0 ); } if ( WSTOPSIG( status ) != SIGSTOP ) { test_fail( __FILE__, __LINE__, "Child process didn't stop on SIGSTOP", 0 ); } if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) { perror( "ptrace(PTRACE_ATTACH)" ); return 1; } if ( waitpid( pid2, &status, 0 ) == -1 ) { perror( "waitpid()" ); exit( 1 ); } if ( WIFSTOPPED( status ) == 0 ) { test_fail( __FILE__, __LINE__, "Child process didn't return true to WIFSTOPPED", 0 ); } if ( WSTOPSIG( status ) != SIGSTOP ) { test_fail( __FILE__, __LINE__, "Child process didn't stop on SIGSTOP", 0 ); } } elapsed_virt_us = PAPI_get_virt_usec( ) - elapsed_virt_us; elapsed_virt_cyc = PAPI_get_virt_cyc( ) - elapsed_virt_cyc; elapsed_us = PAPI_get_real_usec( ) - elapsed_us; elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; /* stop first child */ retval = PAPI_stop( EventSet1, values[0] ); if ( retval != PAPI_OK ) { printf( "Warning: PAPI_stop returned error %d, probably ok.\n", retval ); } /* stop second child */ retval = PAPI_stop( EventSet2, values[1] ); if ( retval != PAPI_OK ) { printf( "Warning: PAPI_stop returned error %d, probably ok.\n", retval ); } remove_test_events( &EventSet1, mask1 ); remove_test_events( &EventSet2, mask2 ); if ( cmpinfo->attach_must_ptrace ) { if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) { perror( "ptrace(PTRACE_CONT)" ); return 1; } if ( ptrace( PTRACE_CONT, pid2, NULL, NULL ) == -1 ) { perror( "ptrace(PTRACE_CONT)" ); return 1; } } if ( waitpid( pid, &status, 0 ) == -1 ) { perror( "waitpid()" ); exit( 1 ); } if ( WIFEXITED( status ) == 0 ) { test_fail( __FILE__, __LINE__, "Child process didn't return true to WIFEXITED", 0 ); } if ( waitpid( pid2, &status, 0 ) == -1 ) { perror( "waitpid()" ); exit( 1 ); } if ( WIFEXITED( status ) == 0 ) { test_fail( __FILE__, __LINE__, "Child process didn't return true to WIFEXITED", 0 ); } /* This code isn't necessary as we know the child has exited, */ /* it *may* return an error if the component so chooses. You */ /* should use read() instead. */ printf( "Test case: multiple 3rd party attach start, stop.\n" ); printf( "-----------------------------------------------\n" ); tmp = PAPI_get_opt( PAPI_DEFDOM, NULL ); printf( "Default domain is: %d (%s)\n", tmp, stringify_all_domains( tmp ) ); tmp = PAPI_get_opt( PAPI_DEFGRN, NULL ); printf( "Default granularity is: %d (%s)\n", tmp, stringify_granularity( tmp ) ); printf( "Using %d iterations of c += a*b\n", NUM_FLOPS ); printf( "-------------------------------------------------------------------------\n" ); sprintf( add_event_str, "(PID %jd) %-12s : \t", ( intmax_t ) pid, event_name ); printf( TAB1, add_event_str, values[0][1] ); sprintf( add_event_str, "(PID %jd) PAPI_TOT_CYC : \t", ( intmax_t ) pid ); printf( TAB1, add_event_str, values[0][0] ); sprintf( add_event_str, "(PID %jd) %-12s : \t", ( intmax_t ) pid2, event_name ); printf( TAB1, add_event_str,values[1][1] ); sprintf( add_event_str, "(PID %jd) PAPI_TOT_CYC : \t", ( intmax_t ) pid2 ); printf( TAB1, add_event_str, values[1][0] ); printf( TAB1, "Real usec : \t", elapsed_us ); printf( TAB1, "Real cycles : \t", elapsed_cyc ); printf( TAB1, "Virt usec : \t", elapsed_virt_us ); printf( TAB1, "Virt cycles : \t", elapsed_virt_cyc ); printf ( "-------------------------------------------------------------------------\n" ); printf("Verification: pid %d results should be twice pid %d\n",pid2,pid ); ratio1=(double)values[1][0]/(double)values[0][0]; ratio2=(double)values[1][1]/(double)values[0][1]; printf("\t%lld/%lld = %lf\n",values[1][0],values[0][0],ratio1); if ((ratio1 >2.15 ) || (ratio1 < 1.85)) { printf("Ratio out of range, should be ~2.0 not %lf\n",ratio1); test_fail( __FILE__, __LINE__, "Error: Counter ratio not two", 0 ); } printf("\t%lld/%lld = %lf\n",values[1][1],values[0][1],ratio2); if ((ratio2 >2.75 ) || (ratio2 < 1.25)) { printf("Ratio out of range, should be ~2.0, not %lf\n",ratio2); test_fail( __FILE__, __LINE__, "Known issue: Counter ratio not two", 0 ); } test_pass( __FILE__, values, num_tests ); return 0; }
int main( int argc, char **argv ) { int retval, num_tests = 30, tmp; int EventSet1 = PAPI_NULL; int EventSet2 = PAPI_NULL; int EventSet3 = PAPI_NULL; int mask1 = MASK1; int mask2 = MASK2; int mask3 = MASK3; int num_events1; int num_events2; int num_events3; long long **values; int i, j; long long min[3]; long long max[3]; long long sum[3]; tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */ retval = PAPI_library_init( PAPI_VER_CURRENT ); if ( retval != PAPI_VER_CURRENT ) test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); /* Make sure that required resources are available */ /* Skip (don't fail!) if they are not */ retval = PAPI_query_event( EVT1 ); if ( retval != PAPI_OK ) test_skip( __FILE__, __LINE__, EVT1_STR, retval ); retval = PAPI_query_event( EVT2 ); if ( retval != PAPI_OK ) test_skip( __FILE__, __LINE__, EVT2_STR, retval ); retval = PAPI_query_event( EVT3 ); if ( retval != PAPI_OK ) test_skip( __FILE__, __LINE__, EVT3_STR, retval ); EventSet1 = add_test_events( &num_events1, &mask1, 1 ); EventSet2 = add_test_events( &num_events2, &mask2, 1 ); EventSet3 = add_test_events( &num_events3, &mask3, 1 ); values = allocate_test_space( num_tests, 1 ); /* Warm me up */ do_l1misses( ITERS ); do_misses( 1, 1024 * 1024 * 4 ); for ( i = 0; i < 10; i++ ) { retval = PAPI_start( EventSet1 ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_start", retval ); do_l1misses( ITERS ); do_misses( 1, 1024 * 1024 * 4 ); retval = PAPI_stop( EventSet1, values[( i * 3 ) + 0] ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); retval = PAPI_start( EventSet2 ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_start", retval ); do_l1misses( ITERS ); do_misses( 1, 1024 * 1024 * 4 ); retval = PAPI_stop( EventSet2, values[( i * 3 ) + 1] ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); retval = PAPI_start( EventSet3 ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_start", retval ); do_l1misses( ITERS ); do_misses( 1, 1024 * 1024 * 4 ); retval = PAPI_stop( EventSet3, values[( i * 3 ) + 2] ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); } remove_test_events( &EventSet1, mask1 ); remove_test_events( &EventSet2, mask2 ); remove_test_events( &EventSet3, mask3 ); for ( j = 0; j < 3; j++ ) { min[j] = 65535; max[j] = sum[j] = 0; } for ( i = 0; i < 10; i++ ) { for ( j = 0; j < 3; j++ ) { if ( min[j] > values[( i * 3 ) + j][0] ) min[j] = values[( i * 3 ) + j][0]; if ( max[j] < values[( i * 3 ) + j][0] ) max[j] = values[( i * 3 ) + j][0]; sum[j] += values[( i * 3 ) + j][0]; } } if ( !TESTS_QUIET ) { printf( "Test case 10: start, stop for derived event %s.\n", CACHE_LEVEL ); printf( "--------------------------------------------------------\n" ); tmp = PAPI_get_opt( PAPI_DEFDOM, NULL ); printf( "Default domain is: %d (%s)\n", tmp, stringify_all_domains( tmp ) ); tmp = PAPI_get_opt( PAPI_DEFGRN, NULL ); printf( "Default granularity is: %d (%s)\n", tmp, stringify_granularity( tmp ) ); printf( "Using %d iterations of c += a*b\n", ITERS ); printf( "Repeated 10 times\n" ); printf ( "-------------------------------------------------------------------------\n" ); /* for (i=0;i<10;i++) { printf("Test type : %12s%13s%13s\n", "1", "2", "3"); printf(TAB3, EVT1_STR, values[(i*3)+0][0], (long long)0, (long long)0); printf(TAB3, EVT2_STR, (long long)0, values[(i*3)+1][0], (long long)0); printf(TAB3, EVT3_STR, (long long)0, (long long)0, values[(i*3)+2][0]); printf ("-------------------------------------------------------------------------\n"); } */ printf( "Test type : %12s%13s%13s\n", "min", "max", "sum" ); printf( TAB3, EVT1_STR, min[0], max[0], sum[0] ); printf( TAB3, EVT2_STR, min[1], max[1], sum[1] ); printf( TAB3, EVT3_STR, min[2], max[2], sum[2] ); printf ( "-------------------------------------------------------------------------\n" ); printf( "Verification:\n" ); #if defined(sun) && defined(sparc) printf( TAB1, "Sum 1 approximately equals sum 2 - sum 3 or", ( sum[1] - sum[2] ) ); #else printf( TAB1, "Sum 1 approximately equals sum 2 + sum 3 or", ( sum[1] + sum[2] ) ); #endif } { long long tmin, tmax; #if defined(sun) && defined(sparc) tmax = ( long long ) ( sum[1] - sum[2] ); #else tmax = ( long long ) ( sum[1] + sum[2] ); #endif printf( "percent error: %f\n", ( float ) ( abs( ( int ) ( tmax - sum[0] ) ) * 100 / sum[0] ) ); tmin = ( long long ) ( ( double ) tmax * 0.8 ); tmax = ( long long ) ( ( double ) tmax * 1.2 ); if ( sum[0] > tmax || sum[0] < tmin ) test_fail( __FILE__, __LINE__, CACHE_LEVEL, 1 ); } test_pass( __FILE__, values, num_tests ); exit( 1 ); }