PAPI  5.0.1.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 ( !TESTS_QUIET ) {
00182         printf( "\n\nEstimated variance relative to average counts:\n" );
00183         for ( j = 0; j < nevents; j++ )
00184             printf( "   Event %.2d", j );
00185         printf( "\n" );
00186     }
00187 
00188     fails = nevents;
00189     /* Due to limited precision of floating point cannot really use
00190        typical standard deviation compuation for large numbers with
00191        very small variations. Instead compute the std devation
00192        problems with precision.
00193      */
00194     for ( j = 0; j < nevents; j++ ) {
00195         avg[j] = valsum[j] / REPEATS;
00196         spread[j] = 0;
00197         for ( i = 0; i < REPEATS; ++i ) {
00198             double diff = ( valsample[j][i] - avg[j] );
00199             spread[j] += diff * diff;
00200         }
00201         spread[j] = sqrt( spread[j] / REPEATS ) / avg[j];
00202         if ( !TESTS_QUIET )
00203             printf( "%9.2g  ", spread[j] );
00204         /* Make sure that NaN get counted as errors */
00205         if ( spread[j] < MPX_TOLERANCE )
00206             --fails;
00207         else if ( valsum[j] < MINCOUNTS )   /* Neglect inprecise results with low counts */
00208             --fails;
00209     }
00210 
00211     if ( !TESTS_QUIET ) {
00212         printf( "\n\n" );
00213         for ( j = 0; j < nevents; j++ ) {
00214             PAPI_get_event_info( events[j], &info );
00215             printf( "Event %.2d: mean=%10.0f, sdev/mean=%7.2g nrpt=%2d -- %s\n",
00216                     j, avg[j], spread[j], REPEATS, info.short_descr );
00217         }
00218         printf( "\n\n" );
00219     }
00220 
00221     if ( fails )
00222         test_fail( __FILE__, __LINE__, "Values outside threshold", fails );
00223     else
00224         test_pass( __FILE__, NULL, 0 );
00225 
00226     return 0;
00227 }
00228 
00229 static double
00230 dummy3( double x, int iters )
00231 {
00232     int i;
00233     double w, y, z, a, b, c, d, e, f, g, h;
00234     double one;
00235     one = 1.0;
00236     w = x;
00237     y = x;
00238     z = x;
00239     a = x;
00240     b = x;
00241     c = x;
00242     d = x;
00243     e = x;
00244     f = x;
00245     g = x;
00246     h = x;
00247     for ( i = 1; i <= iters; i++ ) {
00248         w = w * 1.000000000001 + one;
00249         y = y * 1.000000000002 + one;
00250         z = z * 1.000000000003 + one;
00251         a = a * 1.000000000004 + one;
00252         b = b * 1.000000000005 + one;
00253         c = c * 0.999999999999 + one;
00254         d = d * 0.999999999998 + one;
00255         e = e * 0.999999999997 + one;
00256         f = f * 0.999999999996 + one;
00257         g = h * 0.999999999995 + one;
00258         h = h * 1.000000000006 + one;
00259     }
00260     return 2.0 * ( a + b + c + d + e + f + w + x + y + z + g + h );
00261 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines