|
PAPI
5.0.1.0
|
00001 /* 00002 * $Id$ 00003 * 00004 * Test example for branch accuracy and functionality, originally 00005 * provided by Timothy Kaiser, SDSC. It was modified to fit the 00006 * PAPI test suite by Nils Smeds, <smeds@pdc.kth.se>. 00007 * and Phil Mucci <mucci@cs.utk.edu> 00008 * This example verifies the accuracy of branch events 00009 */ 00010 00011 #include "papi_test.h" 00012 #include <stdio.h> 00013 #include <math.h> 00014 00015 #define MAXEVENTS 4 00016 #define SLEEPTIME 100 00017 #define MINCOUNTS 100000 00018 00019 static double dummy3( double x, int iters ); 00020 00021 int 00022 main( int argc, char **argv ) 00023 { 00024 PAPI_event_info_t info; 00025 int i, j, retval; 00026 int iters = 10000000; 00027 double x = 1.1, y; 00028 long long t1, t2; 00029 long long values[MAXEVENTS], refvalues[MAXEVENTS]; 00030 int sleep_time = SLEEPTIME; 00031 double spread[MAXEVENTS]; 00032 int nevents = MAXEVENTS; 00033 int eventset = PAPI_NULL; 00034 int events[MAXEVENTS]; 00035 00036 events[0] = PAPI_BR_NTK; 00037 events[1] = PAPI_BR_PRC; 00038 events[2] = PAPI_BR_INS; 00039 events[3] = PAPI_BR_MSP; 00040 /* 00041 events[3]=PAPI_BR_CN; 00042 events[4]=PAPI_BR_UCN;*/ 00043 /*events[5]=PAPI_BR_TKN; */ 00044 00045 00046 for ( i = 0; i < MAXEVENTS; i++ ) { 00047 values[i] = 0; 00048 } 00049 00050 if ( argc > 1 ) { 00051 if ( !strcmp( argv[1], "TESTS_QUIET" ) ) 00052 tests_quiet( argc, argv ); 00053 else { 00054 sleep_time = atoi( argv[1] ); 00055 if ( sleep_time <= 0 ) 00056 sleep_time = SLEEPTIME; 00057 } 00058 } 00059 00060 if ( !TESTS_QUIET ) { 00061 printf( "\nAccuracy check of branch presets.\n" ); 00062 printf( "Comparing a measurement with separate measurements.\n\n" ); 00063 } 00064 00065 if ( ( retval = 00066 PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT ) 00067 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00068 00069 if ( ( retval = PAPI_create_eventset( &eventset ) ) ) 00070 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00071 00072 #ifdef MPX 00073 if ( ( retval = PAPI_multiplex_init( ) ) ) 00074 test_fail( __FILE__, __LINE__, "PAPI_multiplex_init", retval ); 00075 00076 if ( ( retval = PAPI_set_multiplex( eventset ) ) ) 00077 test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval ); 00078 #endif 00079 00080 nevents = 0; 00081 00082 for ( i = 0; i < MAXEVENTS; i++ ) { 00083 if ( PAPI_query_event( events[i] ) != PAPI_OK ) 00084 continue; 00085 if ( PAPI_add_event( eventset, events[i] ) == PAPI_OK ) { 00086 events[nevents] = events[i]; 00087 nevents++; 00088 } 00089 } 00090 00091 if ( nevents < 1 ) 00092 test_skip( __FILE__, __LINE__, "Not enough events left...", 0 ); 00093 00094 /* Find a reasonable number of iterations (each 00095 * event active 20 times) during the measurement 00096 */ 00097 t2 = 10000 * 20 * nevents; /* Target: 10000 usec/multiplex, 20 repeats */ 00098 if ( t2 > 30e6 ) 00099 test_skip( __FILE__, __LINE__, "This test takes too much time", 00100 retval ); 00101 00102 /* Measure one run */ 00103 t1 = PAPI_get_real_usec( ); 00104 y = dummy3( x, iters ); 00105 t1 = PAPI_get_real_usec( ) - t1; 00106 00107 if ( t2 > t1 ) /* Scale up execution time to match t2 */ 00108 iters = iters * ( int ) ( t2 / t1 ); 00109 else if ( t1 > 30e6 ) /* Make sure execution time is < 30s per repeated test */ 00110 test_skip( __FILE__, __LINE__, "This test takes too much time", 00111 retval ); 00112 00113 x = 1.0; 00114 00115 if ( !TESTS_QUIET ) 00116 printf( "\nFirst run: Together.\n" ); 00117 00118 t1 = PAPI_get_real_usec( ); 00119 if ( ( retval = PAPI_start( eventset ) ) ) 00120 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00121 y = dummy3( x, iters ); 00122 if ( ( retval = PAPI_stop( eventset, values ) ) ) 00123 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00124 t2 = PAPI_get_real_usec( ); 00125 00126 if ( !TESTS_QUIET ) { 00127 printf( "\tOperations= %.1f Mflop", y * 1e-6 ); 00128 printf( "\t(%g Mflop/s)\n\n", ( y / ( double ) ( t2 - t1 ) ) ); 00129 printf( "PAPI grouped measurement:\n" ); 00130 } 00131 for ( j = 0; j < nevents; j++ ) { 00132 PAPI_get_event_info( events[j], &info ); 00133 if ( !TESTS_QUIET ) { 00134 printf( "%20s = ", info.short_descr ); 00135 printf( LLDFMT, values[j] ); 00136 printf( "\n" ); 00137 } 00138 } 00139 if ( !TESTS_QUIET ) 00140 printf( "\n" ); 00141 00142 00143 if ( ( retval = PAPI_remove_events( eventset, events, nevents ) ) ) 00144 test_fail( __FILE__, __LINE__, "PAPI_remove_events", retval ); 00145 if ( ( retval = PAPI_destroy_eventset( &eventset ) ) ) 00146 test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval ); 00147 eventset = PAPI_NULL; 00148 if ( ( retval = PAPI_create_eventset( &eventset ) ) ) 00149 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00150 00151 for ( i = 0; i < nevents; i++ ) { 00152 00153 if ( ( retval = PAPI_cleanup_eventset( eventset ) ) ) 00154 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00155 if ( ( retval = PAPI_add_event( eventset, events[i] ) ) ) 00156 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00157 00158 x = 1.0; 00159 00160 if ( !TESTS_QUIET ) 00161 printf( "\nReference measurement %d (of %d):\n", i + 1, nevents ); 00162 00163 t1 = PAPI_get_real_usec( ); 00164 if ( ( retval = PAPI_start( eventset ) ) ) 00165 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00166 y = dummy3( x, iters ); 00167 if ( ( retval = PAPI_stop( eventset, &refvalues[i] ) ) ) 00168 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00169 t2 = PAPI_get_real_usec( ); 00170 00171 if ( !TESTS_QUIET ) { 00172 printf( "\tOperations= %.1f Mflop", y * 1e-6 ); 00173 printf( "\t(%g Mflop/s)\n\n", ( y / ( double ) ( t2 - t1 ) ) ); 00174 } 00175 PAPI_get_event_info( events[i], &info ); 00176 if ( !TESTS_QUIET ) { 00177 printf( "PAPI results:\n%20s = ", info.short_descr ); 00178 printf( LLDFMT, refvalues[i] ); 00179 printf( "\n" ); 00180 } 00181 } 00182 if ( !TESTS_QUIET ) 00183 printf( "\n" ); 00184 00185 00186 if ( !TESTS_QUIET ) { 00187 printf( "\n\nRelative accuracy:\n" ); 00188 for ( j = 0; j < nevents; j++ ) 00189 printf( " Event %.2d", j ); 00190 printf( "\n" ); 00191 } 00192 00193 for ( j = 0; j < nevents; j++ ) { 00194 spread[j] = abs( ( int ) ( refvalues[j] - values[j] ) ); 00195 if ( values[j] ) 00196 spread[j] /= ( double ) values[j]; 00197 if ( !TESTS_QUIET ) 00198 printf( "%10.3g ", spread[j] ); 00199 /* Make sure that NaN get counted as errors */ 00200 if ( spread[j] < MPX_TOLERANCE ) 00201 i--; 00202 else if ( refvalues[j] < MINCOUNTS ) /* Neglect inprecise results with low counts */ 00203 i--; 00204 } 00205 if ( !TESTS_QUIET ) 00206 printf( "\n\n" ); 00207 00208 if ( i ) 00209 test_fail( __FILE__, __LINE__, "Values outside threshold", i ); 00210 else 00211 test_pass( __FILE__, NULL, 0 ); 00212 00213 return 0; 00214 } 00215 00216 static double 00217 dummy3( double x, int iters ) 00218 { 00219 int i; 00220 double w, y, z, a, b, c, d, e, f, g, h; 00221 double one; 00222 one = 1.0; 00223 w = x; 00224 y = x; 00225 z = x; 00226 a = x; 00227 b = x; 00228 c = x; 00229 d = x; 00230 e = x; 00231 f = x; 00232 g = x; 00233 h = x; 00234 for ( i = 1; i <= iters; i++ ) { 00235 w = w * 1.000000000001 + one; 00236 y = y * 1.000000000002 + one; 00237 z = z * 1.000000000003 + one; 00238 a = a * 1.000000000004 + one; 00239 b = b * 1.000000000005 + one; 00240 c = c * 0.999999999999 + one; 00241 d = d * 0.999999999998 + one; 00242 e = e * 0.999999999997 + one; 00243 f = f * 0.999999999996 + one; 00244 g = h * 0.999999999995 + one; 00245 h = h * 1.000000000006 + one; 00246 } 00247 return 2.0 * ( a + b + c + d + e + f + w + x + y + z + g + h ); 00248 }