Blame src/ctests/sdsc-mpx.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 accuracy of 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 14
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
void
Packit 577717
check_values( int eventset, int *events, int nevents, long long *values,
Packit 577717
			  long long *refvalues )
Packit 577717
{
Packit 577717
	double spread[MAXEVENTS];
Packit 577717
	int i = nevents, j = 0;
Packit 577717
Packit 577717
	if ( !TESTS_QUIET ) {
Packit 577717
		printf( "\nRelative accuracy:\n" );
Packit 577717
		for ( j = 0; j < nevents; j++ )
Packit 577717
			printf( "   Event %.2d", j + 1 );
Packit 577717
		printf( "\n" );
Packit 577717
	}
Packit 577717
Packit 577717
	for ( j = 0; j < nevents; j++ ) {
Packit 577717
	  spread[j] = abs( (int) ( refvalues[j] - values[j] ) );
Packit 577717
		if ( values[j] )
Packit 577717
			spread[j] /= ( double ) values[j];
Packit 577717
		if ( !TESTS_QUIET )
Packit 577717
			printf( "%10.3g ", spread[j] );
Packit 577717
		/* Make sure that NaN get counted as errors */
Packit 577717
		if ( spread[j] < MPX_TOLERANCE ) {
Packit 577717
			i--;
Packit 577717
		}
Packit 577717
		else if ( refvalues[j] < MINCOUNTS ) {	/* Neglect inprecise results with low counts */
Packit 577717
			i--;
Packit 577717
		}
Packit 577717
                else {
Packit 577717
                  char buff[BUFSIZ];
Packit 577717
		if (!TESTS_QUIET) {
Packit 577717
		  printf("reference = %lld,  value = %lld,  diff = %lld\n",
Packit 577717
			 refvalues[j],values[j],refvalues[j] - values[j]  );
Packit 577717
		}
Packit 577717
		  sprintf(buff,"Error on %d, spread %lf > threshold %lf AND count %lld > minimum size threshold %d\n",j,spread[j],MPX_TOLERANCE,
Packit 577717
			 refvalues[j],MINCOUNTS);
Packit 577717
Packit 577717
		  test_fail( __FILE__, __LINE__, buff, 1 );
Packit 577717
		}
Packit 577717
	}
Packit 577717
	if (!TESTS_QUIET) printf( "\n\n" );
Packit 577717
#if 0
Packit 577717
	if ( !TESTS_QUIET ) {
Packit 577717
		for ( j = 0; j < nevents; j++ ) {
Packit 577717
			PAPI_get_event_info( events[j], &info );
Packit 577717
			printf( "Event %.2d: ref=", j );
Packit 577717
			printf( LLDFMT10, refvalues[j] );
Packit 577717
			printf( ", diff/ref=%7.2g  -- %s\n", spread[j], info.short_descr );
Packit 577717
			printf( "\n" );
Packit 577717
		}
Packit 577717
		printf( "\n" );
Packit 577717
	}
Packit 577717
#else
Packit 577717
	( void ) eventset;
Packit 577717
	( void ) events;
Packit 577717
#endif
Packit 577717
Packit 577717
Packit 577717
}
Packit 577717
Packit 577717
void
Packit 577717
ref_measurements( int iters, int *eventset, int *events, int nevents,
Packit 577717
				  long long *refvalues )
Packit 577717
{
Packit 577717
	PAPI_event_info_t info;
Packit 577717
	int i, retval;
Packit 577717
	double x = 1.1, y;
Packit 577717
	long long t1, t2;
Packit 577717
Packit 577717
	if (!TESTS_QUIET) printf( "PAPI reference measurements:\n" );
Packit 577717
Packit 577717
	if ( ( retval = PAPI_create_eventset( eventset ) ) )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
Packit 577717
Packit 577717
	for ( i = 0; i < nevents; i++ ) {
Packit 577717
		if ( ( retval = PAPI_add_event( *eventset, events[i] ) ) )
Packit 577717
			test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
Packit 577717
Packit 577717
		x = 1.0;
Packit 577717
Packit 577717
		t1 = PAPI_get_real_usec(  );
Packit 577717
		if ( ( retval = PAPI_start( *eventset ) ) )
Packit 577717
			test_fail( __FILE__, __LINE__, "PAPI_start", retval );
Packit 577717
		y = do_flops3( x, iters, 1 );
Packit 577717
		if ( ( retval = PAPI_stop( *eventset, &refvalues[i] ) ) )
Packit 577717
			test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
Packit 577717
		t2 = PAPI_get_real_usec(  );
Packit 577717
Packit 577717
		if (!TESTS_QUIET) {
Packit 577717
		   printf( "\tOperations= %.1f Mflop", y * 1e-6 );
Packit 577717
		   printf( "\t(%g Mflop/s)\n\n", ( ( float ) y / ( t2 - t1 ) ) );
Packit 577717
		}
Packit 577717
Packit 577717
		PAPI_get_event_info( events[i], &info );
Packit 577717
		if (!TESTS_QUIET) {
Packit 577717
			printf( "%20s = ", info.short_descr );
Packit 577717
			printf( LLDFMT, refvalues[i] );
Packit 577717
			printf( "\n" );
Packit 577717
		}
Packit 577717
Packit 577717
		if ( ( retval = PAPI_cleanup_eventset( *eventset ) ) )
Packit 577717
			test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
Packit 577717
	}
Packit 577717
	if ( ( retval = PAPI_destroy_eventset( eventset ) ) )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
Packit 577717
	*eventset = PAPI_NULL;
Packit 577717
}
Packit 577717
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;
Packit 577717
	long long t1, t2;
Packit 577717
	long long values[MAXEVENTS], refvalues[MAXEVENTS];
Packit 577717
	int sleep_time = SLEEPTIME;
Packit 577717
	int nevents = MAXEVENTS;
Packit 577717
	int eventset = PAPI_NULL;
Packit 577717
	int events[MAXEVENTS];
Packit 577717
	int quiet;
Packit 577717
Packit 577717
	quiet = tests_quiet( argc, argv );
Packit 577717
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
	events[9] = PAPI_FAD_INS;
Packit 577717
	events[10] = PAPI_BR_TKN;
Packit 577717
	events[11] = PAPI_BR_MSP;
Packit 577717
	events[12] = PAPI_L1_ICA;
Packit 577717
	events[13] = PAPI_L1_DCA;
Packit 577717
Packit 577717
	for ( i = 0; i < MAXEVENTS; i++ ) {
Packit 577717
		values[i] = 0;
Packit 577717
	}
Packit 577717
Packit 577717
Packit 577717
	if ( !quiet ) {
Packit 577717
		printf( "\nAccuracy check of multiplexing routines.\n" );
Packit 577717
		printf( "Comparing a multiplex measurement with separate measurements.\n\n" );
Packit 577717
	}
Packit 577717
Packit 577717
	/* Initialize PAPI */
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
	/* Iterate through event list and remove those that aren't suitable */
Packit 577717
	nevents = MAXEVENTS;
Packit 577717
	for ( i = 0; i < nevents; i++ ) {
Packit 577717
		if (( PAPI_get_event_info( events[i], &info ) == PAPI_OK ) &&
Packit 577717
		    (info.count && (strcmp( info.derived, "NOT_DERIVED")==0))) {
Packit 577717
			if (!quiet) printf( "Added %s\n", info.symbol );
Packit 577717
		}
Packit 577717
		else {
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 to multiplex...", 0 );
Packit 577717
	}
Packit 577717
Packit 577717
	if (!quiet) printf( "Using %d events\n\n", nevents );
Packit 577717
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
Packit 577717
	/* Find a reasonable number of iterations (each
Packit 577717
	 * event active 20 times) during the measurement
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
	/* Warmup? */
Packit 577717
	y = do_flops3( x, iters, 1 );
Packit 577717
Packit 577717
	/* Measure time of one run */
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
	if (t1==0) {
Packit 577717
		test_fail(__FILE__, __LINE__,
Packit 577717
			"do_flops3 takes no time to run!\n", retval);
Packit 577717
	}
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
		if (!quiet) {
Packit 577717
			printf( "Modified iteration count to %d\n\n", iters );
Packit 577717
		}
Packit 577717
	}
Packit 577717
Packit 577717
	if (!quiet) fprintf(stdout,"y=%lf\n",y);
Packit 577717
Packit 577717
	/* Now loop through the items one at a time */
Packit 577717
Packit 577717
	ref_measurements( iters, &eventset, events, nevents, refvalues );
Packit 577717
Packit 577717
	/* Now check multiplexed */
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
	/* 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
	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
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	if ( ( retval = PAPI_add_events( eventset, events, nevents ) ) )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_add_events", retval );
Packit 577717
Packit 577717
	if (!quiet) printf( "\nPAPI multiplexed measurements:\n" );
Packit 577717
	x = 1.0;
Packit 577717
	t1 = PAPI_get_real_usec(  );
Packit 577717
	if ( ( retval = PAPI_start( eventset ) ) )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_start", retval );
Packit 577717
	y = do_flops3( x, iters, 1 );
Packit 577717
	if ( ( retval = PAPI_stop( eventset, values ) ) )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
Packit 577717
	t2 = PAPI_get_real_usec(  );
Packit 577717
Packit 577717
	for ( j = 0; j < nevents; j++ ) {
Packit 577717
		PAPI_get_event_info( events[j], &info );
Packit 577717
		if ( !quiet ) {
Packit 577717
			printf( "%20s = ", info.short_descr );
Packit 577717
			printf( LLDFMT, values[j] );
Packit 577717
			printf( "\n" );
Packit 577717
		}
Packit 577717
	}
Packit 577717
Packit 577717
	check_values( eventset, events, nevents, values, refvalues );
Packit 577717
Packit 577717
	if ( ( retval = PAPI_remove_events( eventset, events, nevents ) ) )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_remove_events", retval );
Packit 577717
	if ( ( retval = PAPI_cleanup_eventset( eventset ) ) )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
Packit 577717
	if ( ( retval = PAPI_destroy_eventset( &eventset ) ) )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
Packit 577717
	eventset = PAPI_NULL;
Packit 577717
Packit 577717
	/* Now loop through the items one at a time */
Packit 577717
Packit 577717
	ref_measurements( iters, &eventset, events, nevents, refvalues );
Packit 577717
Packit 577717
	check_values( eventset, events, nevents, values, refvalues );
Packit 577717
Packit 577717
	test_pass( __FILE__ );
Packit 577717
Packit 577717
	return 0;
Packit 577717
}
Packit 577717
Packit 577717