|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Test example for multiplex functionality, originally
|
|
Packit |
577717 |
* provided by Timothy Kaiser, SDSC. It was modified to fit the
|
|
Packit |
577717 |
* PAPI test suite by Nils Smeds, <smeds@pdc.kth.se>.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* This example verifies the PAPI_reset function for
|
|
Packit |
577717 |
* multiplexed events
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include <math.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "papi.h"
|
|
Packit |
577717 |
#include "papi_test.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "testcode.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define REPEATS 5
|
|
Packit |
577717 |
#define MAXEVENTS 9
|
|
Packit |
577717 |
#define SLEEPTIME 100
|
|
Packit |
577717 |
#define MINCOUNTS 100000
|
|
Packit |
577717 |
#define MPX_TOLERANCE 0.20
|
|
Packit |
577717 |
#define NUM_FLOPS 20000000
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
main( int argc, char **argv )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
PAPI_event_info_t info;
|
|
Packit |
577717 |
int i, j, retval;
|
|
Packit |
577717 |
int iters = NUM_FLOPS;
|
|
Packit |
577717 |
double x = 1.1, y, dtmp;
|
|
Packit |
577717 |
long long t1, t2;
|
|
Packit |
577717 |
long long values[MAXEVENTS];
|
|
Packit |
577717 |
int sleep_time = SLEEPTIME;
|
|
Packit |
577717 |
#ifdef STARTSTOP
|
|
Packit |
577717 |
long long dummies[MAXEVENTS];
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
double valsample[MAXEVENTS][REPEATS];
|
|
Packit |
577717 |
double valsum[MAXEVENTS];
|
|
Packit |
577717 |
double avg[MAXEVENTS];
|
|
Packit |
577717 |
double spread[MAXEVENTS];
|
|
Packit |
577717 |
int nevents = MAXEVENTS;
|
|
Packit |
577717 |
int eventset = PAPI_NULL;
|
|
Packit |
577717 |
int events[MAXEVENTS];
|
|
Packit |
577717 |
int fails;
|
|
Packit |
577717 |
int quiet;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Set the quiet variable */
|
|
Packit |
577717 |
quiet = tests_quiet( argc, argv );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Parse command line */
|
|
Packit |
577717 |
if ( argc > 1 ) {
|
|
Packit |
577717 |
if ( !strcmp( argv[1], "TESTS_QUIET" ) ) {
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
sleep_time = atoi( argv[1] );
|
|
Packit |
577717 |
if ( sleep_time <= 0 )
|
|
Packit |
577717 |
sleep_time = SLEEPTIME;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
events[0] = PAPI_FP_INS;
|
|
Packit |
577717 |
events[1] = PAPI_TOT_INS;
|
|
Packit |
577717 |
events[2] = PAPI_INT_INS;
|
|
Packit |
577717 |
events[3] = PAPI_TOT_CYC;
|
|
Packit |
577717 |
events[4] = PAPI_STL_CCY;
|
|
Packit |
577717 |
events[5] = PAPI_BR_INS;
|
|
Packit |
577717 |
events[6] = PAPI_SR_INS;
|
|
Packit |
577717 |
events[7] = PAPI_LD_INS;
|
|
Packit |
577717 |
events[8] = PAPI_TOT_IIS;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < MAXEVENTS; i++ ) {
|
|
Packit |
577717 |
values[i] = 0;
|
|
Packit |
577717 |
valsum[i] = 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( !quiet ) {
|
|
Packit |
577717 |
printf( "\nAccuracy check of multiplexing routines.\n" );
|
|
Packit |
577717 |
printf( "Investigating the variance of multiplexed measurements.\n\n" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_library_init( PAPI_VER_CURRENT );
|
|
Packit |
577717 |
if (retval != PAPI_VER_CURRENT ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef MPX
|
|
Packit |
577717 |
retval = PAPI_multiplex_init( );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__,
|
|
Packit |
577717 |
"PAPI multiplex init fail\n", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = PAPI_create_eventset( &eventset ) ) ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef MPX
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* In Component PAPI, EventSets must be assigned a component index
|
|
Packit |
577717 |
before you can fiddle with their internals.
|
|
Packit |
577717 |
0 is always the cpu component */
|
|
Packit |
577717 |
retval = PAPI_assign_eventset_component( eventset, 0 );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component",
|
|
Packit |
577717 |
retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = PAPI_set_multiplex( eventset ) ) ) {
|
|
Packit |
577717 |
if ( retval == PAPI_ENOSUPP) {
|
|
Packit |
577717 |
test_skip(__FILE__, __LINE__, "Multiplex not supported", 1);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Iterate through event list and remove those that aren't available */
|
|
Packit |
577717 |
nevents = MAXEVENTS;
|
|
Packit |
577717 |
for ( i = 0; i < nevents; i++ ) {
|
|
Packit |
577717 |
if ( ( retval = PAPI_add_event( eventset, events[i] ) ) ) {
|
|
Packit |
577717 |
for ( j = i; j < MAXEVENTS-1; j++ ) {
|
|
Packit |
577717 |
events[j] = events[j + 1];
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
nevents--;
|
|
Packit |
577717 |
i--;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Skip test if not enough events available */
|
|
Packit |
577717 |
if ( nevents < 2 ) {
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "Not enough events left...", 0 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Find a reasonable number of iterations (each
|
|
Packit |
577717 |
* event active 20 times) during the measurement
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Target: 10000 usec/multiplex, 20 repeats */
|
|
Packit |
577717 |
t2 = 10000 * 20 * nevents;
|
|
Packit |
577717 |
if ( t2 > 30e6 ) {
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "This test takes too much time",
|
|
Packit |
577717 |
retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Measure time of one iteration */
|
|
Packit |
577717 |
t1 = PAPI_get_real_usec( );
|
|
Packit |
577717 |
y = do_flops3( x, iters, 1 );
|
|
Packit |
577717 |
t1 = PAPI_get_real_usec( ) - t1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Scale up execution time to match t2 */
|
|
Packit |
577717 |
if ( t2 > t1 ) {
|
|
Packit |
577717 |
iters = iters * ( int ) ( t2 / t1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* Make sure execution time is < 30s per repeated test */
|
|
Packit |
577717 |
else if ( t1 > 30e6 ) {
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "This test takes too much time",
|
|
Packit |
577717 |
retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = PAPI_start( eventset ) ) ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_start", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 1; i <= REPEATS; i++ ) {
|
|
Packit |
577717 |
x = 1.0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifndef STARTSTOP
|
|
Packit |
577717 |
if ( ( retval = PAPI_reset( eventset ) ) )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_reset", retval );
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if ( ( retval = PAPI_stop( eventset, dummies ) ) )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
|
|
Packit |
577717 |
if ( ( retval = PAPI_start( eventset ) ) )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_start", retval );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( !quiet ) {
|
|
Packit |
577717 |
printf( "\nTest %d (of %d):\n", i, REPEATS );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
t1 = PAPI_get_real_usec( );
|
|
Packit |
577717 |
y = do_flops3( x, iters, 1 );
|
|
Packit |
577717 |
PAPI_read( eventset, values );
|
|
Packit |
577717 |
t2 = PAPI_get_real_usec( );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( !quiet ) {
|
|
Packit |
577717 |
printf( "\n(calculated independent of PAPI)\n" );
|
|
Packit |
577717 |
printf( "\tOperations= %.1f Mflop", y * 1e-6 );
|
|
Packit |
577717 |
printf( "\t(%g Mflop/s)\n\n",
|
|
Packit |
577717 |
( y / ( double ) ( t2 - t1 ) ) );
|
|
Packit |
577717 |
printf( "PAPI measurements:\n" );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( j = 0; j < nevents; j++ ) {
|
|
Packit |
577717 |
PAPI_get_event_info( events[j], &info );
|
|
Packit |
577717 |
printf( "%20s = ", info.short_descr );
|
|
Packit |
577717 |
printf( "%lld", values[j] );
|
|
Packit |
577717 |
printf( "\n" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
printf( "\n" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Calculate values */
|
|
Packit |
577717 |
for ( j = 0; j < nevents; j++ ) {
|
|
Packit |
577717 |
dtmp = ( double ) values[j];
|
|
Packit |
577717 |
valsum[j] += dtmp;
|
|
Packit |
577717 |
valsample[j][i - 1] = dtmp;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( retval = PAPI_stop( eventset, values ) ) )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( !quiet ) {
|
|
Packit |
577717 |
printf( "\n\nEstimated variance relative "
|
|
Packit |
577717 |
"to average counts:\n" );
|
|
Packit |
577717 |
for ( j = 0; j < nevents; j++ )
|
|
Packit |
577717 |
printf( " Event %.2d", j );
|
|
Packit |
577717 |
printf( "\n" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
fails = nevents;
|
|
Packit |
577717 |
/* Due to limited precision of floating point cannot really use
|
|
Packit |
577717 |
typical standard deviation compuation for large numbers with
|
|
Packit |
577717 |
very small variations. Instead compute the std devation
|
|
Packit |
577717 |
problems with precision.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
for ( j = 0; j < nevents; j++ ) {
|
|
Packit |
577717 |
avg[j] = valsum[j] / REPEATS;
|
|
Packit |
577717 |
spread[j] = 0;
|
|
Packit |
577717 |
for ( i = 0; i < REPEATS; ++i ) {
|
|
Packit |
577717 |
double diff = ( valsample[j][i] - avg[j] );
|
|
Packit |
577717 |
spread[j] += diff * diff;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
spread[j] = sqrt( spread[j] / REPEATS ) / avg[j];
|
|
Packit |
577717 |
if ( !quiet )
|
|
Packit |
577717 |
printf( "%9.2g ", spread[j] );
|
|
Packit |
577717 |
/* Make sure that NaN get counted as errors */
|
|
Packit |
577717 |
if ( spread[j] < MPX_TOLERANCE ) {
|
|
Packit |
577717 |
--fails;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/* Neglect inprecise results with low counts */
|
|
Packit |
577717 |
else if ( valsum[j] < MINCOUNTS ) {
|
|
Packit |
577717 |
--fails;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( !quiet ) {
|
|
Packit |
577717 |
printf( "\n\n" );
|
|
Packit |
577717 |
for ( j = 0; j < nevents; j++ ) {
|
|
Packit |
577717 |
PAPI_get_event_info( events[j], &info );
|
|
Packit |
577717 |
printf( "Event %.2d: mean=%10.0f, "
|
|
Packit |
577717 |
"sdev/mean=%7.2g nrpt=%2d -- %s\n",
|
|
Packit |
577717 |
j, avg[j], spread[j],
|
|
Packit |
577717 |
REPEATS, info.short_descr );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
printf( "\n\n" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( fails ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__,
|
|
Packit |
577717 |
"Values outside threshold", fails );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
test_pass( __FILE__ );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|