int main( int argc, char **argv ) { int EventSet = PAPI_NULL; long long *values; int num_flops, retval, i, j; int *events, mythreshold; char **names; const PAPI_hw_info_t *hw_info = NULL; int num_events, *ovt; char name[PAPI_MAX_STR_LEN]; const PAPI_component_info_t *comp_info = NULL; int using_perfmon = 0; int using_aix = 0; int numcmp, cid; 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", retval ); } numcmp = PAPI_num_components( ); for ( cid = 0; cid < numcmp; cid++ ) { comp_info = PAPI_get_component_info( cid ); if ( comp_info == NULL ) { test_fail( __FILE__, __LINE__, "PAPI_get_component_info", retval ); } if ( strstr( comp_info->name, "perfmon.c" ) ) { using_perfmon = 1; } if ( strstr( comp_info->name, "aix.c" ) ) { using_aix = 1; } } /* add PAPI_TOT_CYC and one of the events in */ /* PAPI_FP_INS, PAPI_FP_OPS PAPI_TOT_INS, */ /* depending on the availability of the event*/ /* on the platform */ EventSet = enum_add_native_events( &num_events, &events, 1 , 1); if (!TESTS_QUIET) printf("Trying %d events\n",num_events); names = ( char ** ) calloc( ( unsigned int ) num_events, sizeof ( char * ) ); for ( i = 0; i < num_events; i++ ) { if ( PAPI_event_code_to_name( events[i], name ) != PAPI_OK ) { test_fail( __FILE__, __LINE__,"PAPI_event_code_to_name", retval); } else { names[i] = strdup( name ); if (!TESTS_QUIET) printf("%i: %s\n",i,names[i]); } } values = ( long long * ) calloc( ( unsigned int ) ( num_events * ( num_events + 1 ) ), sizeof ( long long ) ); ovt = ( int * ) calloc( ( unsigned int ) num_events, sizeof ( int ) ); #if defined(linux) { char *tmp = getenv( "THRESHOLD" ); if ( tmp ) { mythreshold = atoi( tmp ); } else if (hw_info->mhz!=0) { mythreshold = ( int ) hw_info->mhz * 20000; if (!TESTS_QUIET) printf("Using a threshold of %d (20,000 * MHz)\n",mythreshold); } else { if (!TESTS_QUIET) printf("Using default threshold of %d\n",THRESHOLD); mythreshold = THRESHOLD; } } #else mythreshold = THRESHOLD; #endif num_flops = NUM_FLOPS * 2; /* initial test to make sure they all work */ if (!TESTS_QUIET) printf("Testing that the events all work with no overflow\n"); retval = PAPI_start( EventSet ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_start", retval ); } do_flops( num_flops ); retval = PAPI_stop( EventSet, values ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); } /* done with initial test */ /* keep adding events? */ for ( i = 0; i < num_events; i++ ) { /* Enable overflow */ if (!TESTS_QUIET) printf("Testing with overflow set on %s\n", names[i]); retval = PAPI_overflow( EventSet, events[i], mythreshold, 0, handler ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_overflow", retval ); } retval = PAPI_start( EventSet ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_start", retval ); } do_flops( num_flops ); retval = PAPI_stop( EventSet, values + ( i + 1 ) * num_events ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); } /* Disable overflow */ retval = PAPI_overflow( EventSet, events[i], 0, 0, handler ); if ( retval != PAPI_OK ) { test_fail( __FILE__, __LINE__, "PAPI_overflow", retval ); } ovt[i] = total; total = 0; } if ( !TESTS_QUIET ) { printf("\nResults in Matrix-view:\n"); printf( "Test Overflow on %d counters with %d events.\n", num_events,num_events ); printf( "-----------------------------------------------\n" ); printf( "Threshold for overflow is: %d\n", mythreshold ); printf( "Using %d iterations of c += a*b\n", num_flops ); printf( "-----------------------------------------------\n" ); printf( "Test type : " ); for ( i = 0; i < num_events + 1; i++ ) { printf( "%16d", i ); } printf( "\n" ); for ( j = 0; j < num_events; j++ ) { printf( "%-27s : ", names[j] ); for ( i = 0; i < num_events + 1; i++ ) { printf( "%16lld", *( values + j + num_events * i ) ); } printf( "\n" ); } printf( "Overflows : %16s", "" ); for ( i = 0; i < num_events; i++ ) { printf( "%16d", ovt[i] ); } printf( "\n" ); printf( "-----------------------------------------------\n" ); } /* validation */ if ( !TESTS_QUIET ) { printf("\nResults broken out for validation\n"); } if (!TESTS_QUIET) { for ( j = 0; j < num_events+1; j++ ) { if (j==0) { printf("Test results, no overflow:\n\t"); } else { printf("Overflow of event %d, %s\n\t",j-1,names[j-1]); } for(i=0; i < num_events; i++) { if (i==j-1) { printf("*%lld* ",values[(num_events*j)+i]); } else { printf("%lld ",values[(num_events*j)+i]); } } printf("\n"); if (j!=0) { printf("\tOverflow should be %lld / %d = %lld\n", values[(num_events*j)+(j-1)], mythreshold, values[(num_events*j)+(j-1)]/mythreshold); printf("\tOverflow was %d\n",ovt[j-1]); } } } for ( j = 0; j < num_events; j++ ) { //printf("Validation: %lld / %d != %d (%lld)\n", // *( values + j + num_events * (j+1) ) , // mythreshold, // ovt[j], // *(values+j+num_events*(j+1))/mythreshold); if ( *( values + j + num_events * ( j + 1 ) ) / mythreshold != ovt[j] ) { char error_string[BUFSIZ]; if ( using_perfmon ) test_warn( __FILE__, __LINE__, "perfmon substrate handles overflow differently than perf_events", 1 ); else if ( using_aix ) test_warn( __FILE__, __LINE__, "AIX (pmapi) substrate handles overflow differently than various other substrates", 1 ); else { sprintf( error_string, "Overflow value differs from expected %lld / %d != %d (%lld)", *( values + j + num_events * ( j + 1 ) ), mythreshold, ovt[j], *( values + j + num_events * ( j + 1 ) ) / mythreshold ); test_fail( __FILE__, __LINE__, error_string, 1 ); } } } retval = PAPI_cleanup_eventset( EventSet ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); retval = PAPI_destroy_eventset( &EventSet ); if ( retval != PAPI_OK ) test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval ); free( ovt ); for ( i = 0; i < num_events; i++ ) free( names[i] ); free( names ); free( events ); free( values ); test_pass( __FILE__, NULL, 0 ); exit( 1 ); }
int main(int argc, char **argv) { int EventSet=PAPI_NULL; long long *values; int num_flops, retval, i, j; int *events, mythreshold; char **names; const PAPI_hw_info_t *hw_info = NULL; int num_events, *ovt; char name[PAPI_MAX_STR_LEN]; 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 = enum_add_native_events(&num_events, &events); names = (char **)calloc(num_events, sizeof(char *)); for(i=0;i<num_events;i++){ if (PAPI_event_code_to_name(events[i], name) != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_event_code_to_name", retval); else names[i] = strdup(name); } values = (long long *)calloc(num_events*(num_events+1), sizeof(long long)); ovt = (int *)calloc(num_events, sizeof(int)); #if defined(linux) { char *tmp = getenv("THRESHOLD"); if (tmp) mythreshold = atoi(tmp); else mythreshold = hw_info->mhz*10000*2; } #else mythreshold = THRESHOLD; #endif num_flops = NUM_FLOPS*2; retval = PAPI_start(EventSet); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_start", retval); do_flops(num_flops); retval = PAPI_stop(EventSet, values); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_stop", retval); for(i=0;i<num_events;i++){ retval = PAPI_overflow(EventSet, events[i], mythreshold, 0, handler); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_overflow", retval); retval = PAPI_start(EventSet); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_start", retval); do_flops(num_flops); retval = PAPI_stop(EventSet, values+(i+1)*num_events); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_stop", retval); retval = PAPI_overflow(EventSet, events[i], 0, 0, handler); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_overflow", retval); ovt[i] = total; total=0; } if (!TESTS_QUIET) { printf("Test Overflow on %d counters with %d events.\n", num_events, num_events); printf("---------------------------------------------------------------\n"); printf("Threshold for overflow is: %d\n", mythreshold); printf("Using %d iterations of c += a*b\n", num_flops); printf("-----------------------------------------------\n"); printf("Test type : "); for(i=0;i<num_events+1;i++) printf("%16d", i); printf("\n"); for(j=0;j<num_events;j++){ printf("%-27s : ", names[j]); for(i=0;i<num_events+1;i++) printf("%16lld", *(values+j+num_events*i)); printf("\n"); } printf("Overflows : %16s", ""); for(i=0;i<num_events;i++) printf("%16d", ovt[i]); printf("\n"); printf("-----------------------------------------------\n"); } retval = PAPI_cleanup_eventset(EventSet); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_cleanup_eventset", retval); retval = PAPI_destroy_eventset(&EventSet); if (retval != PAPI_OK) test_fail(__FILE__, __LINE__, "PAPI_destroy_eventset", retval); free(ovt); for(i=0;i<num_events;i++) free(names[i]); free(names); free(events); free(values); test_pass(__FILE__, NULL, 0); exit(1); }