PAPI  5.3.0.0
sdsc2.c
Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Test example for multiplex 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  *
00008  * This example verifies the PAPI_reset function for 
00009  * multiplexed events
00010  */
00011 
00012 #include "papi_test.h"
00013 #include <stdio.h>
00014 #include <math.h>
00015 
00016 #define REPEATS 5
00017 #define MAXEVENTS 9
00018 #define SLEEPTIME 100
00019 #define MINCOUNTS 100000
00020 
00021 static double dummy3( double x, int iters );
00022 
00023 int
00024 main( int argc, char **argv )
00025 {
00026     PAPI_event_info_t info;
00027     int i, j, retval;
00028     int iters = NUM_FLOPS;
00029     double x = 1.1, y, dtmp;
00030     long long t1, t2;
00031     long long values[MAXEVENTS];
00032     int sleep_time = SLEEPTIME;
00033 #ifdef STARTSTOP
00034     long long dummies[MAXEVENTS];
00035 #endif
00036     double valsample[MAXEVENTS][REPEATS];
00037     double valsum[MAXEVENTS];
00038     double avg[MAXEVENTS];
00039     double spread[MAXEVENTS];
00040     int nevents = MAXEVENTS;
00041     int eventset = PAPI_NULL;
00042     int events[MAXEVENTS];
00043     int fails;
00044 
00045     events[0] = PAPI_FP_INS;
00046     events[1] = PAPI_TOT_INS;
00047     events[2] = PAPI_INT_INS;
00048     events[3] = PAPI_TOT_CYC;
00049     events[4] = PAPI_STL_CCY;
00050     events[5] = PAPI_BR_INS;
00051     events[6] = PAPI_SR_INS;
00052     events[7] = PAPI_LD_INS;
00053     events[8] = PAPI_TOT_IIS;
00054 
00055     for ( i = 0; i < MAXEVENTS; i++ ) {
00056         values[i] = 0;
00057         valsum[i] = 0;
00058     }
00059 
00060     if ( argc > 1 ) {
00061         if ( !strcmp( argv[1], "TESTS_QUIET" ) )
00062             tests_quiet( argc, argv );
00063         else {
00064             sleep_time = atoi( argv[1] );
00065             if ( sleep_time <= 0 )
00066                 sleep_time = SLEEPTIME;
00067         }
00068     }
00069 
00070     if ( !TESTS_QUIET ) {
00071         printf( "\nAccuracy check of multiplexing routines.\n" );
00072         printf( "Investigating the variance of multiplexed measurements.\n\n" );
00073     }
00074 
00075     if ( ( retval =
00076            PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT )
00077         test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
00078 
00079 #ifdef MPX
00080     init_multiplex(  );
00081 #endif
00082 
00083     if ( ( retval = PAPI_create_eventset( &eventset ) ) )
00084         test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
00085 #ifdef MPX
00086 
00087     /* In Component PAPI, EventSets must be assigned a component index
00088        before you can fiddle with their internals.
00089        0 is always the cpu component */
00090     retval = PAPI_assign_eventset_component( eventset, 0 );
00091     if ( retval != PAPI_OK )
00092         test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component",
00093                    retval );
00094 
00095     if ( ( retval = PAPI_set_multiplex( eventset ) ) ) {
00096             if ( retval == PAPI_ENOSUPP) {
00097                test_skip(__FILE__, __LINE__, "Multiplex not supported", 1);
00098         }
00099        
00100         test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval );
00101     }
00102 #endif
00103 
00104     /* What does this code even do? */
00105     nevents = MAXEVENTS;
00106     for ( i = 0; i < nevents; i++ ) {
00107         if ( ( retval = PAPI_add_event( eventset, events[i] ) ) ) {
00108            for ( j = i; j < MAXEVENTS-1; j++ ) {
00109                 events[j] = events[j + 1];
00110            }
00111            nevents--;
00112            i--;
00113         }
00114     }
00115     if ( nevents < 2 )
00116         test_skip( __FILE__, __LINE__, "Not enough events left...", 0 );
00117 
00118     /* Find a reasonable number of iterations (each 
00119      * event active 20 times) during the measurement
00120      */
00121     t2 = 10000 * 20 * nevents;  /* Target: 10000 usec/multiplex, 20 repeats */
00122     if ( t2 > 30e6 )
00123         test_skip( __FILE__, __LINE__, "This test takes too much time",
00124                    retval );
00125 
00126     /* Measure one run */
00127     t1 = PAPI_get_real_usec(  );
00128     y = dummy3( x, iters );
00129     t1 = PAPI_get_real_usec(  ) - t1;
00130 
00131     if ( t2 > t1 )           /* Scale up execution time to match t2 */
00132         iters = iters * ( int ) ( t2 / t1 );
00133     else if ( t1 > 30e6 )    /* Make sure execution time is < 30s per repeated test */
00134         test_skip( __FILE__, __LINE__, "This test takes too much time",
00135                    retval );
00136 
00137     if ( ( retval = PAPI_start( eventset ) ) )
00138         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00139 
00140     for ( i = 1; i <= REPEATS; i++ ) {
00141         x = 1.0;
00142 
00143 #ifndef STARTSTOP
00144         if ( ( retval = PAPI_reset( eventset ) ) )
00145             test_fail( __FILE__, __LINE__, "PAPI_reset", retval );
00146 #else
00147         if ( ( retval = PAPI_stop( eventset, dummies ) ) )
00148             test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00149         if ( ( retval = PAPI_start( eventset ) ) )
00150             test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00151 #endif
00152 
00153         if ( !TESTS_QUIET )
00154             printf( "\nTest %d (of %d):\n", i, REPEATS );
00155         t1 = PAPI_get_real_usec(  );
00156         y = dummy3( x, iters );
00157         PAPI_read( eventset, values );
00158         t2 = PAPI_get_real_usec(  );
00159 
00160         if ( !TESTS_QUIET ) {
00161             printf( "\n(calculated independent of PAPI)\n" );
00162             printf( "\tOperations= %.1f Mflop", y * 1e-6 );
00163             printf( "\t(%g Mflop/s)\n\n", ( y / ( double ) ( t2 - t1 ) ) );
00164             printf( "PAPI measurements:\n" );
00165         }
00166         for ( j = 0; j < nevents; j++ ) {
00167             PAPI_get_event_info( events[j], &info );
00168             if ( !TESTS_QUIET ) {
00169                 printf( "%20s = ", info.short_descr );
00170                 printf( LLDFMT, values[j] );
00171                 printf( "\n" );
00172             }
00173             dtmp = ( double ) values[j];
00174             valsum[j] += dtmp;
00175             valsample[j][i - 1] = dtmp;
00176         }
00177         if ( !TESTS_QUIET )
00178             printf( "\n" );
00179     }
00180 
00181     if ( ( retval = PAPI_stop( eventset, values ) ) )
00182         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00183 
00184     if ( !TESTS_QUIET ) {
00185         printf( "\n\nEstimated variance relative to average counts:\n" );
00186         for ( j = 0; j < nevents; j++ )
00187             printf( "   Event %.2d", j );
00188         printf( "\n" );
00189     }
00190 
00191     fails = nevents;
00192     /* Due to limited precision of floating point cannot really use
00193        typical standard deviation compuation for large numbers with
00194        very small variations. Instead compute the std devation
00195        problems with precision.
00196      */
00197     for ( j = 0; j < nevents; j++ ) {
00198         avg[j] = valsum[j] / REPEATS;
00199         spread[j] = 0;
00200         for ( i = 0; i < REPEATS; ++i ) {
00201             double diff = ( valsample[j][i] - avg[j] );
00202             spread[j] += diff * diff;
00203         }
00204         spread[j] = sqrt( spread[j] / REPEATS ) / avg[j];
00205         if ( !TESTS_QUIET )
00206             printf( "%9.2g  ", spread[j] );
00207         /* Make sure that NaN get counted as errors */
00208         if ( spread[j] < MPX_TOLERANCE )
00209             --fails;
00210         else if ( valsum[j] < MINCOUNTS )   /* Neglect inprecise results with low counts */
00211             --fails;
00212     }
00213 
00214     if ( !TESTS_QUIET ) {
00215         printf( "\n\n" );
00216         for ( j = 0; j < nevents; j++ ) {
00217             PAPI_get_event_info( events[j], &info );
00218             printf( "Event %.2d: mean=%10.0f, sdev/mean=%7.2g nrpt=%2d -- %s\n",
00219                     j, avg[j], spread[j], REPEATS, info.short_descr );
00220         }
00221         printf( "\n\n" );
00222     }
00223 
00224     if ( fails )
00225         test_fail( __FILE__, __LINE__, "Values outside threshold", fails );
00226     else
00227         test_pass( __FILE__, NULL, 0 );
00228 
00229     return 0;
00230 }
00231 
00232 static double
00233 dummy3( double x, int iters )
00234 {
00235     int i;
00236     double w, y, z, a, b, c, d, e, f, g, h;
00237     double one;
00238     one = 1.0;
00239     w = x;
00240     y = x;
00241     z = x;
00242     a = x;
00243     b = x;
00244     c = x;
00245     d = x;
00246     e = x;
00247     f = x;
00248     g = x;
00249     h = x;
00250     for ( i = 1; i <= iters; i++ ) {
00251         w = w * 1.000000000001 + one;
00252         y = y * 1.000000000002 + one;
00253         z = z * 1.000000000003 + one;
00254         a = a * 1.000000000004 + one;
00255         b = b * 1.000000000005 + one;
00256         c = c * 0.999999999999 + one;
00257         d = d * 0.999999999998 + one;
00258         e = e * 0.999999999997 + one;
00259         f = f * 0.999999999996 + one;
00260         g = h * 0.999999999995 + one;
00261         h = h * 1.000000000006 + one;
00262     }
00263     return 2.0 * ( a + b + c + d + e + f + w + x + y + z + g + h );
00264 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines