|
PAPI
5.0.1.0
|
00001 /* This file performs the following test: start, stop and timer functionality 00002 00003 - It attempts to use the following two counters. It may use less depending on 00004 hardware counter resource limitations. These are counted in the default counting 00005 domain and default granularity, depending on the platform. Usually this is 00006 the user domain (PAPI_DOM_USER) and thread context (PAPI_GRN_THR). 00007 + PAPI_FP_INS 00008 + PAPI_TOT_CYC 00009 - Get us. 00010 - Start counters 00011 - Do flops 00012 - Stop and read counters 00013 - Get us. 00014 */ 00015 00016 #include "papi_test.h" 00017 00018 #define MAX_CYCLE_ERROR 30 00019 00020 int 00021 main( int argc, char **argv ) 00022 { 00023 int retval, num_tests = 1, tmp; 00024 int EventSet1 = PAPI_NULL; 00025 int PAPI_event, mask1; 00026 int num_events; 00027 long long **values; 00028 long long elapsed_us, elapsed_cyc, elapsed_virt_us, elapsed_virt_cyc; 00029 char event_name[PAPI_MAX_STR_LEN], add_event_str[PAPI_MAX_STR_LEN]; 00030 double cycles_error; 00031 00032 /* Set TESTS_QUIET variable */ 00033 tests_quiet( argc, argv ); 00034 00035 /* Init the PAPI library */ 00036 retval = PAPI_library_init( PAPI_VER_CURRENT ); 00037 if ( retval != PAPI_VER_CURRENT ) { 00038 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00039 } 00040 00041 /* add PAPI_TOT_CYC and one of the events in 00042 PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, 00043 depending on the availability of the event 00044 on the platform */ 00045 EventSet1 = add_two_events( &num_events, &PAPI_event, &mask1 ); 00046 00047 retval = PAPI_event_code_to_name( PAPI_event, event_name ); 00048 if ( retval != PAPI_OK ) { 00049 test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); 00050 } 00051 sprintf( add_event_str, "PAPI_add_event[%s]", event_name ); 00052 00053 values = allocate_test_space( num_tests, num_events ); 00054 00055 /* warm up the processor to pull it out of idle state */ 00056 do_flops( NUM_FLOPS*10 ); 00057 00058 /* Gather before stats */ 00059 elapsed_us = PAPI_get_real_usec( ); 00060 elapsed_cyc = PAPI_get_real_cyc( ); 00061 elapsed_virt_us = PAPI_get_virt_usec( ); 00062 elapsed_virt_cyc = PAPI_get_virt_cyc( ); 00063 00064 /* Start PAPI */ 00065 retval = PAPI_start( EventSet1 ); 00066 if ( retval != PAPI_OK ) { 00067 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00068 } 00069 00070 /* our work code */ 00071 do_flops( NUM_FLOPS ); 00072 00073 /* Stop PAPI */ 00074 retval = PAPI_stop( EventSet1, values[0] ); 00075 if ( retval != PAPI_OK ) { 00076 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00077 } 00078 00079 /* Calculate total values */ 00080 elapsed_virt_us = PAPI_get_virt_usec( ) - elapsed_virt_us; 00081 elapsed_virt_cyc = PAPI_get_virt_cyc( ) - elapsed_virt_cyc; 00082 elapsed_us = PAPI_get_real_usec( ) - elapsed_us; 00083 elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; 00084 00085 remove_test_events( &EventSet1, mask1 ); 00086 00087 if ( !TESTS_QUIET ) { 00088 printf( "Test case 0: start, stop.\n" ); 00089 printf( "-----------------------------------------------\n" ); 00090 tmp = PAPI_get_opt( PAPI_DEFDOM, NULL ); 00091 printf( "Default domain is: %d (%s)\n", tmp, 00092 stringify_all_domains( tmp ) ); 00093 tmp = PAPI_get_opt( PAPI_DEFGRN, NULL ); 00094 printf( "Default granularity is: %d (%s)\n", tmp, 00095 stringify_granularity( tmp ) ); 00096 printf( "Using %d iterations of c += a*b\n", NUM_FLOPS ); 00097 printf( "-------------------------------------------------------------------------\n" ); 00098 00099 printf( "Test type : \t 1\n" ); 00100 00101 sprintf( add_event_str, "%-12s : \t", event_name ); 00102 00103 /* cycles is first, other event second */ 00104 printf( TAB1, add_event_str, values[0][1] ); 00105 00106 /* If cycles is there, it's always the first event */ 00107 if ( mask1 & MASK_TOT_CYC ) { 00108 printf( TAB1, "PAPI_TOT_CYC : \t", values[0][0] ); 00109 } 00110 printf( TAB1, "Real usec : \t", elapsed_us ); 00111 printf( TAB1, "Real cycles : \t", elapsed_cyc ); 00112 printf( TAB1, "Virt usec : \t", elapsed_virt_us ); 00113 printf( TAB1, "Virt cycles : \t", elapsed_virt_cyc ); 00114 00115 printf( "-------------------------------------------------------------------------\n" ); 00116 00117 printf( "Verification: PAPI_TOT_CYC should be roughly real_cycles\n" ); 00118 printf( "NOTE: Not true if dynamic frequency scaling is enabled.\n" ); 00119 printf( "Verification: PAPI_FP_INS should be roughly %d\n", 2*NUM_FLOPS ); 00120 } 00121 /* Check that TOT_CYC and real_cycles roughly match */ 00122 cycles_error=100.0*((double)values[0][0] - (double)elapsed_cyc)/((double)elapsed_cyc); 00123 if ((cycles_error > MAX_CYCLE_ERROR) || (cycles_error < -MAX_CYCLE_ERROR)) { 00124 printf("PAPI_TOT_CYC Error of %.2f%%\n",cycles_error); 00125 test_fail( __FILE__, __LINE__, "Cycles validation", 0 ); 00126 } 00127 /* Check that FP_INS is reasonable */ 00128 if (abs(values[0][1] - (2*NUM_FLOPS)) > (2*NUM_FLOPS)) { 00129 printf("%s Error of %.2f%%\n", event_name, (100.0 * (double)(values[0][1] - (2*NUM_FLOPS)))/(2*NUM_FLOPS)); 00130 test_fail( __FILE__, __LINE__, "FLOPS validation", 0 ); 00131 } 00132 if (abs(values[0][1] - (2*NUM_FLOPS)) > (NUM_FLOPS/2)) { 00133 printf("%s Error of %.2f%%\n", event_name, (100.0 * (double)(values[0][1] - (2*NUM_FLOPS)))/(2*NUM_FLOPS)); 00134 test_warn( __FILE__, __LINE__, "FLOPS validation", 0 ); 00135 } 00136 00137 test_pass( __FILE__, values, num_tests ); 00138 00139 return 0; 00140 }