calibrate.c File Reference

Include dependency graph for calibrate.c:

Go to the source code of this file.

Defines

#define INDEX1   100
#define INDEX5   500
#define MAX_WARN   10
#define MAX_ERROR   80
#define MAX_DIFF   14
#define FMA   0

Functions

static void resultline (int i, int j, int EventSet, int fail)
static void headerlines (char *title, int TESTS_QUIET)
static void print_help (char **argv)
static float inner_single (int n, float *x, float *y)
static double inner_double (int n, double *x, double *y)
static void vector_single (int n, float *a, float *x, float *y)
static void vector_double (int n, double *a, double *x, double *y)
static void matrix_single (int n, float *c, float *a, float *b)
static void matrix_double (int n, double *c, double *a, double *b)
static void reset_flops (char *title, int EventSet)
int main (int argc, char *argv[])

Variables

int TESTS_QUIET

Define Documentation

#define FMA   0

Definition at line 440 of file calibrate.c.

#define INDEX1   100

Definition at line 24 of file calibrate.c.

#define INDEX5   500

Definition at line 25 of file calibrate.c.

#define MAX_DIFF   14

Definition at line 29 of file calibrate.c.

#define MAX_ERROR   80

Definition at line 28 of file calibrate.c.

#define MAX_WARN   10

Definition at line 27 of file calibrate.c.


Function Documentation

static void headerlines ( char *  title,
int  TESTS_QUIET 
) [static]

Definition at line 415 of file calibrate.c.

00416 {
00417     const PAPI_hw_info_t *hwinfo = NULL;
00418 
00419     if ( !TESTS_QUIET ) {
00420         if ( papi_print_header( "", &hwinfo ) != PAPI_OK )
00421             test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 );
00422 
00423         printf( "\n%s:\n%8s %12s %12s %8s %8s\n", title, "i", "papi", "theory",
00424                 "diff", "%error" );
00425         printf
00426             ( "-------------------------------------------------------------------------\n" );
00427     }
00428 }

Here is the call graph for this function:

Here is the caller graph for this function:

static double inner_double ( int  n,
double *  x,
double *  y 
) [static]

Definition at line 65 of file calibrate.c.

00066 {
00067     double aa = 0.0;
00068     int i;
00069 
00070     for ( i = 0; i <= n; i++ )
00071         aa = aa + x[i] * y[i];
00072     return ( aa );
00073 }

Here is the caller graph for this function:

static float inner_single ( int  n,
float *  x,
float *  y 
) [static]

Definition at line 54 of file calibrate.c.

00055 {
00056     float aa = 0.0;
00057     int i;
00058 
00059     for ( i = 0; i <= n; i++ )
00060         aa = aa + x[i] * y[i];
00061     return ( aa );
00062 }

Here is the caller graph for this function:

int main ( int  argc,
char *  argv[] 
)

Definition at line 131 of file calibrate.c.

00132 {
00133     extern void dummy( void * );
00134 
00135     float aa, *a, *b, *c, *x, *y;
00136     double aad, *ad, *bd, *cd, *xd, *yd;
00137     int i, j, n;
00138     int inner = 0;
00139     int vector = 0;
00140     int matrix = 0;
00141     int double_precision = 0;
00142     int fail = 1;
00143     int retval = PAPI_OK;
00144     char papi_event_str[PAPI_MIN_STR_LEN] = "PAPI_FP_OPS";
00145     int papi_event;
00146     int EventSet = PAPI_NULL;
00147 
00148 /* Parse the input arguments */
00149     for ( i = 0; i < argc; i++ ) {
00150         if ( strstr( argv[i], "-i" ) )
00151             inner = 1;
00152         else if ( strstr( argv[i], "-f" ) )
00153             fail = 0;
00154         else if ( strstr( argv[i], "-v" ) )
00155             vector = 1;
00156         else if ( strstr( argv[i], "-m" ) )
00157             matrix = 1;
00158         else if ( strstr( argv[i], "-e" ) ) {
00159             if ( ( argv[i + 1] == NULL ) || ( strlen( argv[i + 1] ) == 0 ) ) {
00160                 print_help( argv );
00161                 exit( 1 );
00162             }
00163             strncpy( papi_event_str, argv[i + 1], sizeof ( papi_event_str ) - 1);
00164             papi_event_str[sizeof ( papi_event_str )-1] = '\0';
00165             i++;
00166         } else if ( strstr( argv[i], "-d" ) )
00167             double_precision = 1;
00168         else if ( strstr( argv[i], "-h" ) ) {
00169             print_help( argv );
00170             exit( 1 );
00171         }
00172     }
00173 
00174     /* if no options specified, set all tests to TRUE */
00175     if ( inner + vector + matrix == 0 )
00176         inner = vector = matrix = 1;
00177 
00178 
00179     tests_quiet( argc, argv );  /* Set TESTS_QUIET variable */
00180 
00181     if ( !TESTS_QUIET )
00182         printf( "Initializing..." );
00183 
00184     /* Initialize PAPI */
00185     retval = PAPI_library_init( PAPI_VER_CURRENT );
00186     if ( retval != PAPI_VER_CURRENT )
00187         test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
00188 
00189     /* Translate name */
00190     retval = PAPI_event_name_to_code( papi_event_str, &papi_event );
00191     if ( retval != PAPI_OK )
00192         test_fail( __FILE__, __LINE__, "PAPI_event_name_to_code", retval );
00193 
00194     if ( PAPI_query_event( papi_event ) != PAPI_OK )
00195         test_skip( __FILE__, __LINE__, "PAPI_query_event", PAPI_ENOEVNT );
00196 
00197     if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK )
00198         test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
00199 
00200     if ( ( retval = PAPI_add_event( EventSet, papi_event ) ) != PAPI_OK )
00201         test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
00202 
00203     printf( "\n" );
00204 
00205     retval = PAPI_OK;
00206 
00207     /* Inner Product test */
00208     if ( inner ) {
00209         /* Allocate the linear arrays */
00210        if (double_precision) {
00211             xd = malloc( INDEX5 * sizeof(double) );
00212             yd = malloc( INDEX5 * sizeof(double) );
00213         if ( !( xd && yd ) )
00214             retval = PAPI_ENOMEM;
00215        }
00216        else {
00217             x = malloc( INDEX5 * sizeof(float) );
00218         y = malloc( INDEX5 * sizeof(float) );
00219         if ( !( x && y ) )
00220             retval = PAPI_ENOMEM;
00221        }
00222 
00223         if ( retval == PAPI_OK ) {
00224             headerlines( "Inner Product Test", TESTS_QUIET );
00225 
00226             /* step through the different array sizes */
00227             for ( n = 0; n < INDEX5; n++ ) {
00228                 if ( n < INDEX1 || ( ( n + 1 ) % 50 ) == 0 ) {
00229 
00230                     /* Initialize the needed arrays at this size */
00231                     if ( double_precision ) {
00232                         for ( i = 0; i <= n; i++ ) {
00233                             xd[i] = ( double ) rand(  ) * ( double ) 1.1;
00234                             yd[i] = ( double ) rand(  ) * ( double ) 1.1;
00235                         }
00236                     } else {
00237                         for ( i = 0; i <= n; i++ ) {
00238                             x[i] = ( float ) rand(  ) * ( float ) 1.1;
00239                             y[i] = ( float ) rand(  ) * ( float ) 1.1;
00240                         }
00241                     }
00242 
00243                     /* reset PAPI flops count */
00244                     reset_flops( "Inner Product Test", EventSet );
00245 
00246                     /* do the multiplication */
00247                     if ( double_precision ) {
00248                         aad = inner_double( n, xd, yd );
00249                         dummy( ( void * ) &aad );
00250                     } else {
00251                         aa = inner_single( n, x, y );
00252                         dummy( ( void * ) &aa );
00253                     }
00254                     resultline( n, 1, EventSet, fail );
00255                 }
00256             }
00257         }
00258         if (double_precision) {
00259             free( xd );
00260             free( yd );
00261         } else {
00262             free( x );
00263             free( y );
00264         }
00265     }
00266 
00267     /* Matrix Vector test */
00268     if ( vector && retval != PAPI_ENOMEM ) {
00269         /* Allocate the needed arrays */
00270       if (double_precision) {
00271             ad = malloc( INDEX5 * INDEX5 * sizeof(double) );
00272             xd = malloc( INDEX5 * sizeof(double) );
00273             yd = malloc( INDEX5 * sizeof(double) );
00274         if ( !( ad && xd && yd ) )
00275             retval = PAPI_ENOMEM;
00276       } else {
00277             a = malloc( INDEX5 * INDEX5 * sizeof(float) );
00278             x = malloc( INDEX5 * sizeof(float) );
00279             y = malloc( INDEX5 * sizeof(float) );
00280         if ( !( a && x && y ) )
00281             retval = PAPI_ENOMEM;
00282       }
00283 
00284         if ( retval == PAPI_OK ) {
00285             headerlines( "Matrix Vector Test", TESTS_QUIET );
00286 
00287             /* step through the different array sizes */
00288             for ( n = 0; n < INDEX5; n++ ) {
00289                 if ( n < INDEX1 || ( ( n + 1 ) % 50 ) == 0 ) {
00290 
00291                     /* Initialize the needed arrays at this size */
00292                     if ( double_precision ) {
00293                         for ( i = 0; i <= n; i++ ) {
00294                             yd[i] = 0.0;
00295                             xd[i] = ( double ) rand(  ) * ( double ) 1.1;
00296                             for ( j = 0; j <= n; j++ )
00297                                 ad[i * n + j] =
00298                                     ( double ) rand(  ) * ( double ) 1.1;
00299                         }
00300                     } else {
00301                         for ( i = 0; i <= n; i++ ) {
00302                             y[i] = 0.0;
00303                             x[i] = ( float ) rand(  ) * ( float ) 1.1;
00304                             for ( j = 0; j <= n; j++ )
00305                                 a[i * n + j] =
00306                                     ( float ) rand(  ) * ( float ) 1.1;
00307                         }
00308                     }
00309 
00310                     /* reset PAPI flops count */
00311                     reset_flops( "Matrix Vector Test", EventSet );
00312 
00313                     /* compute the resultant vector */
00314                     if ( double_precision ) {
00315                         vector_double( n, ad, xd, yd );
00316                         dummy( ( void * ) yd );
00317                     } else {
00318                         vector_single( n, a, x, y );
00319                         dummy( ( void * ) y );
00320                     }
00321                     resultline( n, 2, EventSet, fail );
00322                 }
00323             }
00324         }
00325         if (double_precision) {
00326             free( ad );
00327             free( xd );
00328             free( yd );
00329         } else {
00330             free( a );
00331             free( x );
00332             free( y );
00333         }
00334     }
00335 
00336     /* Matrix Multiply test */
00337     if ( matrix && retval != PAPI_ENOMEM ) {
00338         /* Allocate the needed arrays */
00339       if (double_precision) {
00340             ad = malloc( INDEX5 * INDEX5 * sizeof(double) );
00341             bd = malloc( INDEX5 * INDEX5 * sizeof(double) );
00342             cd = malloc( INDEX5 * INDEX5 * sizeof(double) );
00343         if ( !( ad && bd && cd ) )
00344             retval = PAPI_ENOMEM;
00345       } else {
00346             a = malloc( INDEX5 * INDEX5 * sizeof(float) );
00347             b = malloc( INDEX5 * INDEX5 * sizeof(float) );
00348             c = malloc( INDEX5 * INDEX5 * sizeof(float) );
00349         if ( !( a && b && c ) )
00350             retval = PAPI_ENOMEM;
00351       }
00352 
00353 
00354         if ( retval == PAPI_OK ) {
00355             headerlines( "Matrix Multiply Test", TESTS_QUIET );
00356 
00357             /* step through the different array sizes */
00358             for ( n = 0; n < INDEX5; n++ ) {
00359                 if ( n < INDEX1 || ( ( n + 1 ) % 50 ) == 0 ) {
00360 
00361                     /* Initialize the needed arrays at this size */
00362                     if ( double_precision ) {
00363                         for ( i = 0; i <= n * n + n; i++ ) {
00364                             cd[i] = 0.0;
00365                             ad[i] = ( double ) rand(  ) * ( double ) 1.1;
00366                             bd[i] = ( double ) rand(  ) * ( double ) 1.1;
00367                         }
00368                     } else {
00369                         for ( i = 0; i <= n * n + n; i++ ) {
00370                             c[i] = 0.0;
00371                             a[i] = ( float ) rand(  ) * ( float ) 1.1;
00372                             b[i] = ( float ) rand(  ) * ( float ) 1.1;
00373                         }
00374                     }
00375 
00376                     /* reset PAPI flops count */
00377                     reset_flops( "Matrix Multiply Test", EventSet );
00378 
00379                     /* compute the resultant matrix */
00380                     if ( double_precision ) {
00381                         matrix_double( n, cd, ad, bd );
00382                         dummy( ( void * ) c );
00383                     } else {
00384                         matrix_single( n, c, a, b );
00385                         dummy( ( void * ) c );
00386                     }
00387                     resultline( n, 3, EventSet, fail );
00388                 }
00389             }
00390         }
00391         if (double_precision) {
00392             free( ad );
00393             free( bd );
00394             free( cd );
00395         } else {
00396             free( a );
00397             free( b );
00398             free( c );
00399         }
00400     }
00401 
00402     /* exit with status code */
00403     if ( retval == PAPI_ENOMEM )
00404         test_fail( __FILE__, __LINE__, "malloc", retval );
00405     else
00406         test_pass( __FILE__, NULL, 0 );
00407     exit( 1 );
00408 }

Here is the call graph for this function:

static void matrix_double ( int  n,
double *  c,
double *  a,
double *  b 
) [static]

Definition at line 107 of file calibrate.c.

00108 {
00109     int i, j, k;
00110 
00111     for ( i = 0; i <= n; i++ )
00112         for ( j = 0; j <= n; j++ )
00113             for ( k = 0; k <= n; k++ )
00114                 c[i * n + j] = c[i * n + j] + a[i * n + k] * b[k * n + j];
00115 }

Here is the caller graph for this function:

static void matrix_single ( int  n,
float *  c,
float *  a,
float *  b 
) [static]

Definition at line 96 of file calibrate.c.

00097 {
00098     int i, j, k;
00099 
00100     for ( i = 0; i <= n; i++ )
00101         for ( j = 0; j <= n; j++ )
00102             for ( k = 0; k <= n; k++ )
00103                 c[i * n + j] = c[i * n + j] + a[i * n + k] * b[k * n + j];
00104 }

Here is the caller graph for this function:

static void print_help ( char **  argv  )  [static]

Definition at line 34 of file calibrate.c.

00035 {
00036     printf( "Usage: %s [-ivmdh] [-e event]\n", argv[0] );
00037     printf( "Options:\n\n" );
00038     printf( "\t-i            Inner Product test.\n" );
00039     printf( "\t-v            Matrix-Vector multiply test.\n" );
00040     printf( "\t-m            Matrix-Matrix multiply test.\n" );
00041     printf( "\t-d            Double precision data. Default is float.\n" );
00042     printf
00043         ( "\t-e event      Use <event> as PAPI event instead of PAPI_FP_OPS\n" );
00044     printf( "\t-f            Suppress failures\n" );
00045     printf( "\t-h            Print this help message\n" );
00046     printf( "\n" );
00047     printf
00048         ( "This test measures floating point operations for the specified test.\n" );
00049     printf( "Operations can be performed in single or double precision.\n" );
00050     printf( "Default operation is all three tests in single precision.\n" );
00051 }

Here is the caller graph for this function:

static void reset_flops ( char *  title,
int  EventSet 
) [static]

Definition at line 118 of file calibrate.c.

00119 {
00120     int retval;
00121     char err_str[PAPI_MAX_STR_LEN];
00122 
00123     retval = PAPI_start( EventSet );
00124     if ( retval != PAPI_OK ) {
00125         sprintf( err_str, "%s: PAPI_start", title );
00126         test_fail( __FILE__, __LINE__, err_str, retval );
00127     }
00128 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void resultline ( int  i,
int  j,
int  EventSet,
int  fail 
) [static]

Definition at line 444 of file calibrate.c.

00445 {
00446     float ferror = 0;
00447     long long flpins = 0;
00448     long long papi, theory;
00449     int diff, retval;
00450     char err_str[PAPI_MAX_STR_LEN];
00451 
00452     retval = PAPI_stop( EventSet, &flpins );
00453     if ( retval != PAPI_OK )
00454         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00455 
00456     i++;                     /* convert to 1s base  */
00457     theory = 2;
00458     while ( j-- )
00459         theory *= i;         /* theoretical ops   */
00460     papi = flpins << FMA;
00461 
00462     diff = ( int ) ( papi - theory );
00463 
00464     ferror = ( ( float ) abs( diff ) ) / ( ( float ) theory ) * 100;
00465 
00466     printf( "%8d %12lld %12lld %8d %10.4f\n", i, papi, theory, diff, ferror );
00467 
00468     if ( ferror > MAX_WARN && abs( diff ) > MAX_DIFF && i > 20 ) {
00469         sprintf( err_str, "Calibrate: difference exceeds %d percent", MAX_WARN );
00470         test_warn( __FILE__, __LINE__, err_str, 0 );
00471     }
00472     if (fail) {
00473         if ( ferror > MAX_ERROR && abs( diff ) > MAX_DIFF && i > 20 ) {
00474             sprintf( err_str, "Calibrate: error exceeds %d percent", MAX_ERROR );
00475             test_fail( __FILE__, __LINE__, err_str, PAPI_EMISC );
00476         }
00477     }
00478 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void vector_double ( int  n,
double *  a,
double *  x,
double *  y 
) [static]

Definition at line 86 of file calibrate.c.

00087 {
00088     int i, j;
00089 
00090     for ( i = 0; i <= n; i++ )
00091         for ( j = 0; j <= n; j++ )
00092             y[i] = y[i] + a[i * n + j] * x[i];
00093 }

Here is the caller graph for this function:

static void vector_single ( int  n,
float *  a,
float *  x,
float *  y 
) [static]

Definition at line 76 of file calibrate.c.

00077 {
00078     int i, j;
00079 
00080     for ( i = 0; i <= n; i++ )
00081         for ( j = 0; j <= n; j++ )
00082             y[i] = y[i] + a[i * n + j] * x[i];
00083 }

Here is the caller graph for this function:


Variable Documentation

Definition at line 11 of file test_utils.c.


Generated on 17 Nov 2016 for PAPI by  doxygen 1.6.1