sdsc4.c File Reference

Include dependency graph for sdsc4.c:

Go to the source code of this file.

Defines

#define MAXEVENTS   9
#define REPEATS   (MAXEVENTS * 4)
#define SLEEPTIME   100
#define MINCOUNTS   100000

Functions

static double dummy3 (double x, int iters)
int main (int argc, char **argv)

Define Documentation

#define MAXEVENTS   9

Definition at line 17 of file sdsc4.c.

#define MINCOUNTS   100000

Definition at line 20 of file sdsc4.c.

#define REPEATS   (MAXEVENTS * 4)

Definition at line 18 of file sdsc4.c.

#define SLEEPTIME   100

Definition at line 19 of file sdsc4.c.


Function Documentation

static double dummy3 ( double  x,
int  iters 
) [static]

Definition at line 317 of file sdsc4.c.

00318 {
00319     int i;
00320     double w, y, z, a, b, c, d, e, f, g, h;
00321     double one;
00322     one = 1.0;
00323     w = x;
00324     y = x;
00325     z = x;
00326     a = x;
00327     b = x;
00328     c = x;
00329     d = x;
00330     e = x;
00331     f = x;
00332     g = x;
00333     h = x;
00334     for ( i = 1; i <= iters; i++ ) {
00335         w = w * 1.000000000001 + one;
00336         y = y * 1.000000000002 + one;
00337         z = z * 1.000000000003 + one;
00338         a = a * 1.000000000004 + one;
00339         b = b * 1.000000000005 + one;
00340         c = c * 0.999999999999 + one;
00341         d = d * 0.999999999998 + one;
00342         e = e * 0.999999999997 + one;
00343         f = f * 0.999999999996 + one;
00344         g = h * 0.999999999995 + one;
00345         h = h * 1.000000000006 + one;
00346     }
00347     return 2.0 * ( a + b + c + d + e + f + w + x + y + z + g + h );
00348 }

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 25 of file sdsc4.c.

00026 {
00027     PAPI_event_info_t info;
00028     char name2[PAPI_MAX_STR_LEN];
00029     int i, j, retval, idx, repeats;
00030     int iters = NUM_FLOPS;
00031     double x = 1.1, y, dtmp;
00032     long long t1, t2;
00033     long long values[MAXEVENTS], refvals[MAXEVENTS];
00034     int nsamples[MAXEVENTS], truelist[MAXEVENTS], ntrue;
00035 #ifdef STARTSTOP
00036     long long dummies[MAXEVENTS];
00037 #endif
00038     int sleep_time = SLEEPTIME;
00039     double valsample[MAXEVENTS][REPEATS];
00040     double valsum[MAXEVENTS];
00041     double avg[MAXEVENTS];
00042     double spread[MAXEVENTS];
00043     int nevents = MAXEVENTS, nev1;
00044     int eventset = PAPI_NULL;
00045     int events[MAXEVENTS];
00046     int eventidx[MAXEVENTS];
00047     int eventmap[MAXEVENTS];
00048     int fails;
00049 
00050     events[0] = PAPI_FP_INS;
00051     events[1] = PAPI_TOT_CYC;
00052     events[2] = PAPI_TOT_INS;
00053     events[3] = PAPI_TOT_IIS;
00054     events[4] = PAPI_INT_INS;
00055     events[5] = PAPI_STL_CCY;
00056     events[6] = PAPI_BR_INS;
00057     events[7] = PAPI_SR_INS;
00058     events[8] = PAPI_LD_INS;
00059 
00060     for ( i = 0; i < MAXEVENTS; i++ ) {
00061         values[i] = 0;
00062         valsum[i] = 0;
00063         nsamples[i] = 0;
00064     }
00065 
00066     if ( argc > 1 ) {
00067         if ( !strcmp( argv[1], "TESTS_QUIET" ) )
00068             tests_quiet( argc, argv );
00069         else {
00070             sleep_time = atoi( argv[1] );
00071             if ( sleep_time <= 0 )
00072                 sleep_time = SLEEPTIME;
00073         }
00074     }
00075 
00076     if ( !TESTS_QUIET ) {
00077         printf( "\nFunctional check of multiplexing routines.\n" );
00078         printf( "Adding and removing events from an event set.\n\n" );
00079     }
00080 
00081     if ( ( retval =
00082            PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT )
00083         test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
00084 
00085 #ifdef MPX
00086     init_multiplex(  );
00087 #endif
00088     if ( ( retval = PAPI_create_eventset( &eventset ) ) )
00089         test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
00090 
00091 #ifdef MPX
00092 
00093     /* In Component PAPI, EventSets must be assigned a component index
00094        before you can fiddle with their internals.
00095        0 is always the cpu component */
00096     retval = PAPI_assign_eventset_component( eventset, 0 );
00097     if ( retval != PAPI_OK )
00098         test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component",
00099                    retval );
00100 
00101     if ( ( retval = PAPI_set_multiplex( eventset ) ) ) {
00102             if ( retval == PAPI_ENOSUPP) {
00103            test_skip(__FILE__, __LINE__, "Multiplex not supported", 1);
00104         }
00105        
00106         test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval );
00107     }
00108 #endif
00109 
00110     /* What does this code even do */
00111     nevents = MAXEVENTS;
00112     for ( i = 0; i < nevents; i++ ) {
00113         if ( ( retval = PAPI_add_event( eventset, events[i] ) ) ) {
00114             for ( j = i; j < MAXEVENTS-1; j++ )
00115                 events[j] = events[j + 1];
00116             nevents--;
00117             i--;
00118         }
00119     }
00120     if ( nevents < 3 )
00121         test_skip( __FILE__, __LINE__, "Not enough events left...", 0 );
00122 
00123     /* Find a reasonable number of iterations (each 
00124      * event active 20 times) during the measurement
00125      */
00126     t2 = 10000 * 20 * nevents;  /* Target: 10000 usec/multiplex, 20 repeats */
00127     if ( t2 > 30e6 )
00128         test_skip( __FILE__, __LINE__, "This test takes too much time",
00129                    retval );
00130 
00131     /* Measure one run */
00132     t1 = PAPI_get_real_usec(  );
00133     y = dummy3( x, iters );
00134     t1 = PAPI_get_real_usec(  ) - t1;
00135 
00136     if ( t2 > t1 )           /* Scale up execution time to match t2 */
00137         iters = iters * ( int ) ( t2 / t1 );
00138     else if ( t1 > 30e6 )    /* Make sure execution time is < 30s per repeated test */
00139         test_skip( __FILE__, __LINE__, "This test takes too much time",
00140                    retval );
00141 
00142     j = nevents;
00143     for ( i = 1; i < nevents; i = i + 2 )
00144         eventidx[--j] = i;
00145     for ( i = 0; i < nevents; i = i + 2 )
00146         eventidx[--j] = i;
00147     assert( j == 0 );
00148     for ( i = 0; i < nevents; i++ )
00149         eventmap[i] = i;
00150 
00151     x = 1.0;
00152 
00153     if ( !TESTS_QUIET )
00154         printf( "\nReference run:\n" );
00155 
00156     t1 = PAPI_get_real_usec(  );
00157     if ( ( retval = PAPI_start( eventset ) ) )
00158         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00159     y = dummy3( x, iters );
00160     PAPI_read( eventset, refvals );
00161     t2 = PAPI_get_real_usec(  );
00162 
00163     ntrue = nevents;
00164     PAPI_list_events( eventset, truelist, &ntrue );
00165     if ( !TESTS_QUIET ) {
00166         printf( "\tOperations= %.1f Mflop", y * 1e-6 );
00167         printf( "\t(%g Mflop/s)\n\n", ( y / ( double ) ( t2 - t1 ) ) );
00168         printf( "%20s   %16s   %-15s %-15s\n", "PAPI measurement:",
00169                 "Acquired count", "Expected event", "PAPI_list_events" );
00170     }
00171 
00172     if ( !TESTS_QUIET ) {
00173         for ( j = 0; j < nevents; j++ ) {
00174             PAPI_get_event_info( events[j], &info );
00175             PAPI_event_code_to_name( truelist[j], name2 );
00176             if ( !TESTS_QUIET )
00177                 printf( "%20s = %16lld   %-15s %-15s %s\n", info.short_descr,
00178                         refvals[j], info.symbol, name2, strcmp( info.symbol,
00179                                                                 name2 ) ?
00180                         "*** MISMATCH ***" : "" );
00181         }
00182         printf( "\n" );
00183     }
00184 
00185     nev1 = nevents;
00186     repeats = nevents * 4;
00187     for ( i = 0; i < repeats; i++ ) {
00188         if ( ( i % nevents ) + 1 == nevents )
00189             continue;
00190 
00191         if ( !TESTS_QUIET )
00192             printf( "\nTest %d (of %d):\n", i + 1 - i / nevents, repeats - 4 );
00193 
00194         if ( ( retval = PAPI_stop( eventset, values ) ) )
00195             test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00196 
00197         j = eventidx[i % nevents];
00198 
00199         if ( ( i / nevents ) % 2 == 0 ) {
00200             PAPI_get_event_info( events[j], &info );
00201             if ( !TESTS_QUIET )
00202                 printf( "Removing event[%d]: %s\n", j, info.short_descr );
00203             if ( ( retval = PAPI_remove_event( eventset, events[j] ) ) )
00204                 test_fail( __FILE__, __LINE__, "PAPI_remove_event", retval );
00205             nev1--;
00206             for ( idx = 0; eventmap[idx] != j; idx++ );
00207             for ( j = idx; j < nev1; j++ )
00208                 eventmap[j] = eventmap[j + 1];
00209         } else {
00210             PAPI_get_event_info( events[j], &info );
00211             if ( !TESTS_QUIET )
00212                 printf( "Adding event[%d]: %s\n", j, info.short_descr );
00213             if ( ( retval = PAPI_add_event( eventset, events[j] ) ) )
00214                 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
00215             eventmap[nev1] = j;
00216             nev1++;
00217         }
00218         if ( ( retval = PAPI_start( eventset ) ) )
00219             test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00220 
00221         x = 1.0;
00222 #ifndef STARTSTOP
00223         if ( ( retval = PAPI_reset( eventset ) ) )
00224             test_fail( __FILE__, __LINE__, "PAPI_reset", retval );
00225 #else
00226         if ( ( retval = PAPI_stop( eventset, dummies ) ) )
00227             test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00228         if ( ( retval = PAPI_start( eventset ) ) )
00229             test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00230 #endif
00231 
00232         t1 = PAPI_get_real_usec(  );
00233         y = dummy3( x, iters );
00234         PAPI_read( eventset, values );
00235         t2 = PAPI_get_real_usec(  );
00236 
00237         if ( !TESTS_QUIET ) {
00238             printf( "\n(calculated independent of PAPI)\n" );
00239             printf( "\tOperations= %.1f Mflop", y * 1e-6 );
00240             printf( "\t(%g Mflop/s)\n\n", ( y / ( double ) ( t2 - t1 ) ) );
00241             printf( "%20s   %16s   %-15s %-15s\n", "PAPI measurement:",
00242                     "Acquired count", "Expected event", "PAPI_list_events" );
00243         }
00244 
00245         ntrue = nev1;
00246         PAPI_list_events( eventset, truelist, &ntrue );
00247         for ( j = 0; j < nev1; j++ ) {
00248             idx = eventmap[j];
00249             /* printf("Mapping: Counter %d -> slot %d.\n",j,idx); */
00250             PAPI_get_event_info( events[idx], &info );
00251             PAPI_event_code_to_name( truelist[j], name2 );
00252             if ( !TESTS_QUIET )
00253                 printf( "%20s = %16lld   %-15s %-15s %s\n", info.short_descr,
00254                         values[j], info.symbol, name2, strcmp( info.symbol,
00255                                                                name2 ) ?
00256                         "*** MISMATCH ***" : "" );
00257             dtmp = ( double ) values[j];
00258             valsum[idx] += dtmp;
00259             valsample[idx][nsamples[idx]] = dtmp;
00260             nsamples[idx]++;
00261         }
00262         if ( !TESTS_QUIET )
00263             printf( "\n" );
00264     }
00265 
00266     if ( ( retval = PAPI_stop( eventset, values ) ) )
00267         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00268 
00269     if ( !TESTS_QUIET ) {
00270         printf( "\n\nEstimated variance relative to average counts:\n" );
00271         for ( j = 0; j < nev1; j++ )
00272             printf( "   Event %.2d", j );
00273         printf( "\n" );
00274     }
00275 
00276     fails = nevents;
00277     /* Due to limited precision of floating point cannot really use
00278        typical standard deviation compuation for large numbers with
00279        very small variations. Instead compute the std devation
00280        problems with precision.
00281      */
00282     for ( j = 0; j < nev1; j++ ) {
00283         avg[j] = valsum[j] / nsamples[j];
00284         spread[j] = 0;
00285         for ( i = 0; i < nsamples[j]; ++i ) {
00286             double diff = ( valsample[j][i] - avg[j] );
00287             spread[j] += diff * diff;
00288         }
00289         spread[j] = sqrt( spread[j] / nsamples[j] ) / avg[j];
00290         if ( !TESTS_QUIET )
00291             printf( "%9.2g  ", spread[j] );
00292         /* Make sure that NaN get counted as errors */
00293         if ( spread[j] < MPX_TOLERANCE )
00294             fails--;
00295         else if ( values[j] < MINCOUNTS )   /* Neglect inprecise results with low counts */
00296             fails--;
00297     }
00298     if ( !TESTS_QUIET ) {
00299         printf( "\n\n" );
00300         for ( j = 0; j < nev1; j++ ) {
00301             PAPI_get_event_info( events[j], &info );
00302             printf( "Event %.2d: mean=%10.0f, sdev/mean=%7.2g nrpt=%2d -- %s\n",
00303                     j, avg[j], spread[j], nsamples[j], info.short_descr );
00304         }
00305         printf( "\n\n" );
00306     }
00307 
00308     if ( fails )
00309         test_fail( __FILE__, __LINE__, "Values differ from reference", fails );
00310     else
00311         test_pass( __FILE__, NULL, 0 );
00312 
00313     return 0;
00314 }

Here is the call graph for this function:


Generated on 17 Nov 2016 for PAPI by  doxygen 1.6.1