|
PAPI
5.0.1.0
|
00001 /* 00002 * File: overflow_twoevents.c 00003 * CVS: $Id$ 00004 * Author: min@cs.utk.edu 00005 * Min Zhou 00006 * Mods: Philip Mucci 00007 * mucci@cs.utk.edu 00008 */ 00009 00010 /* This file performs the following test: overflow dispatch on 2 counters. */ 00011 00012 #include "papi_test.h" 00013 00014 #define OVER_FMT "handler(%d) Overflow at %p! vector=0x%llx\n" 00015 #define OUT_FMT "%-12s : %18lld%18lld%18lld\n" 00016 #define VEC_FMT " at vector 0x%llx, event %-12s : %6d\n" 00017 00018 typedef struct 00019 { 00020 long long mask; 00021 int count; 00022 } ocount_t; 00023 00024 /* there are two experiments: batch and interleaf; for each experiment there 00025 are three possible vectors, one counter overflows, the other 00026 counter overflows, both overflow */ 00027 ocount_t overflow_counts[2][3] = 00028 { {{0, 0}, {0, 0}, {0, 0}}, {{0, 0}, {0, 0}, {0, 0}} }; 00029 int total_unknown = 0; 00030 00031 void 00032 handler( int mode, void *address, long long overflow_vector, void *context ) 00033 { 00034 ( void ) context; /*unused */ 00035 int i; 00036 00037 if ( !TESTS_QUIET ) { 00038 fprintf( stderr, OVER_FMT, mode, address, overflow_vector ); 00039 } 00040 00041 /* Look for the overflow_vector entry */ 00042 00043 for ( i = 0; i < 3; i++ ) { 00044 if ( overflow_counts[mode][i].mask == overflow_vector ) { 00045 overflow_counts[mode][i].count++; 00046 return; 00047 } 00048 } 00049 00050 /* Didn't find it so add it. */ 00051 00052 for ( i = 0; i < 3; i++ ) { 00053 if ( overflow_counts[mode][i].mask == ( long long ) 0 ) { 00054 overflow_counts[mode][i].mask = overflow_vector; 00055 overflow_counts[mode][i].count = 1; 00056 return; 00057 } 00058 } 00059 00060 /* Unknown entry!?! */ 00061 00062 total_unknown++; 00063 } 00064 00065 void 00066 handler_batch( int EventSet, void *address, long long overflow_vector, 00067 void *context ) 00068 { 00069 ( void ) EventSet; /*unused */ 00070 handler( 0, address, overflow_vector, context ); 00071 } 00072 00073 void 00074 handler_interleaf( int EventSet, void *address, long long overflow_vector, 00075 void *context ) 00076 { 00077 ( void ) EventSet; /*unused */ 00078 handler( 1, address, overflow_vector, context ); 00079 } 00080 00081 00082 int 00083 main( int argc, char **argv ) 00084 { 00085 int EventSet = PAPI_NULL; 00086 long long ( values[3] )[2]; 00087 int retval; 00088 int PAPI_event, k, idx[4]; 00089 char event_name[3][PAPI_MAX_STR_LEN]; 00090 int num_events1; 00091 int threshold = THRESHOLD; 00092 00093 tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */ 00094 00095 if ( ( retval = 00096 PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT ) 00097 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00098 00099 if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK ) 00100 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00101 00102 /* decide which of PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS to add, 00103 depending on the availability and derived status of the event on 00104 this platform */ 00105 if ( ( PAPI_event = find_nonderived_event( ) ) == 0 ) 00106 test_fail( __FILE__, __LINE__, "no PAPI_event", 0 ); 00107 00108 if ( ( retval = PAPI_add_event( EventSet, PAPI_event ) ) != PAPI_OK ) 00109 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00110 if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_CYC ) ) != PAPI_OK ) 00111 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00112 00113 retval = PAPI_start( EventSet ); 00114 if ( retval != PAPI_OK ) 00115 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00116 00117 do_flops( NUM_FLOPS ); 00118 00119 if ( ( retval = PAPI_stop( EventSet, values[0] ) ) != PAPI_OK ) 00120 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00121 00122 /* Set both overflows after adding both events (batch) */ 00123 if ( ( retval = 00124 PAPI_overflow( EventSet, PAPI_event, threshold, 0, 00125 handler_batch ) ) != PAPI_OK ) 00126 test_fail( __FILE__, __LINE__, "PAPI_overflow", retval ); 00127 if ( ( retval = 00128 PAPI_overflow( EventSet, PAPI_TOT_CYC, threshold, 0, 00129 handler_batch ) ) != PAPI_OK ) 00130 test_fail( __FILE__, __LINE__, "PAPI_overflow", retval ); 00131 00132 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00133 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00134 00135 do_flops( NUM_FLOPS ); 00136 00137 retval = PAPI_stop( EventSet, values[1] ); 00138 if ( retval != PAPI_OK ) 00139 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00140 00141 num_events1 = 1; 00142 retval = 00143 PAPI_get_overflow_event_index( EventSet, 1, &idx[0], &num_events1 ); 00144 if ( retval != PAPI_OK ) 00145 printf( "PAPI_get_overflow_event_index error: %s\n", 00146 PAPI_strerror( retval ) ); 00147 00148 num_events1 = 1; 00149 retval = 00150 PAPI_get_overflow_event_index( EventSet, 2, &idx[1], &num_events1 ); 00151 if ( retval != PAPI_OK ) 00152 printf( "PAPI_get_overflow_event_index error: %s\n", 00153 PAPI_strerror( retval ) ); 00154 00155 if ( ( retval = PAPI_cleanup_eventset( EventSet ) ) != PAPI_OK ) 00156 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00157 00158 /* Add each event and set its overflow (interleaved) */ 00159 if ( ( retval = PAPI_add_event( EventSet, PAPI_event ) ) != PAPI_OK ) 00160 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00161 if ( ( retval = 00162 PAPI_overflow( EventSet, PAPI_event, threshold, 0, 00163 handler_interleaf ) ) != PAPI_OK ) 00164 test_fail( __FILE__, __LINE__, "PAPI_overflow", retval ); 00165 if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_CYC ) ) != PAPI_OK ) 00166 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00167 if ( ( retval = 00168 PAPI_overflow( EventSet, PAPI_TOT_CYC, threshold, 0, 00169 handler_interleaf ) ) != PAPI_OK ) 00170 test_fail( __FILE__, __LINE__, "PAPI_overflow", retval ); 00171 00172 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00173 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00174 00175 do_flops( NUM_FLOPS ); 00176 00177 if ( ( retval = PAPI_stop( EventSet, values[2] ) ) != PAPI_OK ) 00178 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00179 00180 num_events1 = 1; 00181 retval = 00182 PAPI_get_overflow_event_index( EventSet, 1, &idx[2], &num_events1 ); 00183 if ( retval != PAPI_OK ) 00184 printf( "PAPI_get_overflow_event_index error: %s\n", 00185 PAPI_strerror( retval ) ); 00186 00187 num_events1 = 1; 00188 retval = 00189 PAPI_get_overflow_event_index( EventSet, 2, &idx[3], &num_events1 ); 00190 if ( retval != PAPI_OK ) 00191 printf( "PAPI_get_overflow_event_index error: %s\n", 00192 PAPI_strerror( retval ) ); 00193 00194 if ( ( retval = PAPI_cleanup_eventset( EventSet ) ) != PAPI_OK ) 00195 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00196 00197 if ( ( retval = 00198 PAPI_event_code_to_name( PAPI_event, event_name[0] ) ) != PAPI_OK ) 00199 test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); 00200 00201 if ( ( retval = 00202 PAPI_event_code_to_name( PAPI_TOT_CYC, event_name[1] ) ) != PAPI_OK ) 00203 test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); 00204 00205 strcpy( event_name[2], "Unknown" ); 00206 00207 printf 00208 ( "Test case: Overflow dispatch of both events in set with 2 events.\n" ); 00209 printf 00210 ( "---------------------------------------------------------------\n" ); 00211 printf( "Threshold for overflow is: %d\n", threshold ); 00212 printf( "Using %d iterations of c += a*b\n", NUM_FLOPS ); 00213 printf( "-----------------------------------------------\n" ); 00214 00215 printf( "Test type : %18s%18s%18s\n", "1 (no overflow)", "2 (batch)", 00216 "3 (interleaf)" ); 00217 printf( OUT_FMT, event_name[0], ( values[0] )[0], ( values[1] )[0], 00218 ( values[2] )[0] ); 00219 printf( OUT_FMT, event_name[1], ( values[0] )[1], ( values[1] )[1], 00220 ( values[2] )[1] ); 00221 printf( "\n" ); 00222 00223 printf( "Predicted overflows at event %-12s : %6d\n", event_name[0], 00224 ( int ) ( ( values[0] )[0] / threshold ) ); 00225 printf( "Predicted overflows at event %-12s : %6d\n", event_name[1], 00226 ( int ) ( ( values[0] )[1] / threshold ) ); 00227 00228 printf( "\nBatch overflows (add, add, over, over):\n" ); 00229 for ( k = 0; k < 2; k++ ) { 00230 if ( overflow_counts[0][k].mask ) { 00231 printf( VEC_FMT, ( long long ) overflow_counts[0][k].mask, 00232 event_name[idx[k]], overflow_counts[0][k].count ); 00233 } 00234 } 00235 00236 printf( "\nInterleaved overflows (add, over, add, over):\n" ); 00237 for ( k = 0; k < 2; k++ ) { 00238 if ( overflow_counts[1][k].mask ) 00239 printf( VEC_FMT, 00240 ( long long ) overflow_counts[1][k].mask, 00241 event_name[idx[k + 2]], 00242 overflow_counts[1][k].count ); 00243 } 00244 00245 printf( "\nCases 2+3 Unknown overflows: %d\n", total_unknown ); 00246 printf( "-----------------------------------------------\n" ); 00247 00248 if ( overflow_counts[0][0].count == 0 || overflow_counts[0][1].count == 0 ) 00249 test_fail( __FILE__, __LINE__, "a batch counter had no overflows", 1 ); 00250 00251 if ( overflow_counts[1][0].count == 0 || overflow_counts[1][1].count == 0 ) 00252 test_fail( __FILE__, __LINE__, 00253 "an interleaved counter had no overflows", 1 ); 00254 00255 if ( total_unknown > 0 ) 00256 test_fail( __FILE__, __LINE__, "Unknown counter had overflows", 1 ); 00257 00258 test_pass( __FILE__, NULL, 0 ); 00259 exit( 1 ); 00260 }