Blame src/ctests/sdsc2.c

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
}