Blame src/ctests/overflow_allcounters.c

Packit 577717
/*
Packit 577717
* File:    overflow_allcounters.c
Packit 577717
* Author:  Haihang You
Packit 577717
*          you@cs.utk.edu
Packit 577717
* Mods:    Vince Weaver
Packit 577717
*          vweaver1@eecs.utk.edu
Packit 577717
*/
Packit 577717
Packit 577717
/* This file performs the following test: overflow all counters
Packit 577717
   to test availability of overflow of all counters
Packit 577717
Packit 577717
   - Start eventset 1
Packit 577717
   - Do flops
Packit 577717
   - Stop and measure eventset 1
Packit 577717
   - Set up overflow on eventset 1
Packit 577717
   - Start eventset 1
Packit 577717
   - Do flops
Packit 577717
   - Stop eventset 1
Packit 577717
*/
Packit 577717
Packit 577717
#include <stdio.h>
Packit 577717
#include <stdlib.h>
Packit 577717
#include <string.h>
Packit 577717
Packit 577717
#include "papi.h"
Packit 577717
#include "papi_test.h"
Packit 577717
Packit 577717
#include "do_loops.h"
Packit 577717
Packit 577717
#define OVER_FMT	"handler(%d ) Overflow at %p! bit=%#llx \n"
Packit 577717
#define OUT_FMT		"%-12s : %16lld%16lld\n"
Packit 577717
Packit 577717
static int total = 0;				   /* total overflows */
Packit 577717
Packit 577717
Packit 577717
void
Packit 577717
handler( int EventSet, void *address, long long overflow_vector, void *context )
Packit 577717
{
Packit 577717
Packit 577717
	( void ) context;
Packit 577717
Packit 577717
	if ( !TESTS_QUIET ) {
Packit 577717
	   printf( OVER_FMT, EventSet, address, overflow_vector );
Packit 577717
	}
Packit 577717
	total++;
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
main( int argc, char **argv )
Packit 577717
{
Packit 577717
	int EventSet = PAPI_NULL;
Packit 577717
	long long *values;
Packit 577717
	int num_flops, retval, i, j;
Packit 577717
	int *events, mythreshold;
Packit 577717
	char **names;
Packit 577717
	const PAPI_hw_info_t *hw_info = NULL;
Packit 577717
	int num_events, *ovt;
Packit 577717
	char name[PAPI_MAX_STR_LEN];
Packit 577717
	int using_perfmon = 0;
Packit 577717
	int using_aix = 0;
Packit 577717
	int cid;
Packit 577717
	int quiet;
Packit 577717
	long long value;
Packit 577717
Packit 577717
	/* Set TESTS_QUIET variable */
Packit 577717
	quiet = tests_quiet( argc, argv );
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
	hw_info = PAPI_get_hardware_info(  );
Packit 577717
	if ( hw_info == NULL ) {
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", retval );
Packit 577717
	}
Packit 577717
Packit 577717
        cid = PAPI_get_component_index("perfmon");
Packit 577717
	if (cid>=0) using_perfmon = 1;
Packit 577717
Packit 577717
        cid = PAPI_get_component_index("aix");
Packit 577717
	if (cid>=0) using_aix = 1;
Packit 577717
Packit 577717
	/* add PAPI_TOT_CYC and one of the events in */
Packit 577717
	/* PAPI_FP_INS, PAPI_FP_OPS PAPI_TOT_INS,    */
Packit 577717
        /* depending on the availability of the event*/
Packit 577717
	/* on the platform */
Packit 577717
	EventSet = enum_add_native_events( &num_events, &events, 1 , 1, 0);
Packit 577717
Packit 577717
	if (num_events==0) {
Packit 577717
		if (!quiet) printf("No events found\n");
Packit 577717
		test_skip(__FILE__,__LINE__,"No events found",0);
Packit 577717
	}
Packit 577717
Packit 577717
	if (!quiet) printf("Trying %d events\n",num_events);
Packit 577717
Packit 577717
	names = ( char ** ) calloc( ( unsigned int ) num_events,
Packit 577717
				    sizeof ( char * ) );
Packit 577717
Packit 577717
	for ( i = 0; i < num_events; i++ ) {
Packit 577717
	   if ( PAPI_event_code_to_name( events[i], name ) != PAPI_OK ) {
Packit 577717
	      test_fail( __FILE__, __LINE__,"PAPI_event_code_to_name", retval);
Packit 577717
	   }
Packit 577717
	   else {
Packit 577717
	      names[i] = strdup( name );
Packit 577717
	      if (!quiet) printf("%i: %s\n",i,names[i]);
Packit 577717
	   }
Packit 577717
	}
Packit 577717
Packit 577717
	values = ( long long * )
Packit 577717
		calloc( ( unsigned int ) ( num_events * ( num_events + 1 ) ),
Packit 577717
				sizeof ( long long ) );
Packit 577717
	ovt = ( int * ) calloc( ( unsigned int ) num_events, sizeof ( int ) );
Packit 577717
Packit 577717
#if defined(linux)
Packit 577717
	{
Packit 577717
		char *tmp = getenv( "THRESHOLD" );
Packit 577717
		if ( tmp ) {
Packit 577717
			mythreshold = atoi( tmp );
Packit 577717
		}
Packit 577717
		else if (hw_info->cpu_max_mhz!=0) {
Packit 577717
		   mythreshold = ( int ) hw_info->cpu_max_mhz * 20000;
Packit 577717
		  if (!quiet) printf("Using a threshold of %d (20,000 * MHz)\n",mythreshold);
Packit 577717
Packit 577717
		}
Packit 577717
		else {
Packit 577717
		  if (!quiet) printf("Using default threshold of %d\n",THRESHOLD);
Packit 577717
		   mythreshold = THRESHOLD;
Packit 577717
		}
Packit 577717
	}
Packit 577717
#else
Packit 577717
	mythreshold = THRESHOLD;
Packit 577717
#endif
Packit 577717
Packit 577717
	num_flops = NUM_FLOPS * 2;
Packit 577717
Packit 577717
	   /* initial test to make sure they all work */
Packit 577717
	if (!quiet) printf("Testing that the events all work with no overflow\n");
Packit 577717
Packit 577717
       	retval = PAPI_start( EventSet );
Packit 577717
	if ( retval != PAPI_OK ) {
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_start", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	do_flops( num_flops );
Packit 577717
Packit 577717
	retval = PAPI_stop( EventSet, values );
Packit 577717
	if ( retval != PAPI_OK ) {
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	/* done with initial test */
Packit 577717
Packit 577717
	/* keep adding events? */
Packit 577717
	for ( i = 0; i < num_events; i++ ) {
Packit 577717
Packit 577717
	      /* Enable overflow */
Packit 577717
	   if (!quiet) printf("Testing with overflow set on %s\n",
Packit 577717
				   names[i]);
Packit 577717
Packit 577717
	   retval = PAPI_overflow( EventSet, events[i],
Packit 577717
					mythreshold, 0, handler );
Packit 577717
	   if ( retval != PAPI_OK ) {
Packit 577717
	      test_fail( __FILE__, __LINE__, "PAPI_overflow", retval );
Packit 577717
	   }
Packit 577717
Packit 577717
       	   retval = PAPI_start( EventSet );
Packit 577717
	   if ( retval != PAPI_OK ) {
Packit 577717
	      test_fail( __FILE__, __LINE__, "PAPI_start", retval );
Packit 577717
	   }
Packit 577717
Packit 577717
	   do_flops( num_flops );
Packit 577717
Packit 577717
	   retval = PAPI_stop( EventSet, values + ( i + 1 ) * num_events );
Packit 577717
	   if ( retval != PAPI_OK ) {
Packit 577717
	      test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
Packit 577717
	   }
Packit 577717
Packit 577717
	      /* Disable overflow */
Packit 577717
	   retval = PAPI_overflow( EventSet, events[i], 0, 0, handler );
Packit 577717
	   if ( retval != PAPI_OK ) {
Packit 577717
	      test_fail( __FILE__, __LINE__, "PAPI_overflow", retval );
Packit 577717
	   }
Packit 577717
	   ovt[i] = total;
Packit 577717
	   total = 0;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( !quiet ) {
Packit 577717
Packit 577717
	   printf("\nResults in Matrix-view:\n");
Packit 577717
	   printf( "Test Overflow on %d counters with %d events.\n", 
Packit 577717
		   num_events,num_events );
Packit 577717
	   printf( "-----------------------------------------------\n" );
Packit 577717
	   printf( "Threshold for overflow is: %d\n", mythreshold );
Packit 577717
	   printf( "Using %d iterations of c += a*b\n", num_flops );
Packit 577717
	   printf( "-----------------------------------------------\n" );
Packit 577717
Packit 577717
	   printf( "Test type                   : " );
Packit 577717
	   for ( i = 0; i < num_events + 1; i++ ) {
Packit 577717
	       printf( "%16d", i );
Packit 577717
	   }
Packit 577717
	   printf( "\n" );
Packit 577717
	   for ( j = 0; j < num_events; j++ ) {
Packit 577717
	       printf( "%-27s : ", names[j] );
Packit 577717
	       for ( i = 0; i < num_events + 1; i++ ) {
Packit 577717
		   printf( "%16lld", *( values + j + num_events * i ) );
Packit 577717
	       }
Packit 577717
	       printf( "\n" );
Packit 577717
	   }
Packit 577717
	   printf( "Overflows                   : %16s", "" );
Packit 577717
	   for ( i = 0; i < num_events; i++ ) {
Packit 577717
	       printf( "%16d", ovt[i] );
Packit 577717
	   }
Packit 577717
	   printf( "\n" );
Packit 577717
	   printf( "-----------------------------------------------\n" );
Packit 577717
	}
Packit 577717
Packit 577717
	/* validation */
Packit 577717
Packit 577717
	if ( !quiet ) {
Packit 577717
	   printf("\nResults broken out for validation\n");
Packit 577717
	}
Packit 577717
Packit 577717
	if (!quiet) {
Packit 577717
Packit 577717
	for ( j = 0; j < num_events+1; j++ ) {
Packit 577717
	  if (j==0) {
Packit 577717
             printf("Test results, no overflow:\n\t");
Packit 577717
	  }
Packit 577717
	  else {
Packit 577717
	    printf("Overflow of event %d, %s\n\t",j-1,names[j-1]);
Packit 577717
	  }
Packit 577717
	  for(i=0; i < num_events; i++) {
Packit 577717
	    if (i==j-1) {
Packit 577717
	      printf("*%lld* ",values[(num_events*j)+i]);
Packit 577717
	    }
Packit 577717
	    else {
Packit 577717
	      printf("%lld ",values[(num_events*j)+i]);
Packit 577717
	    }
Packit 577717
	  }
Packit 577717
          printf("\n");
Packit 577717
	  if (j!=0) {
Packit 577717
	     printf("\tOverflow should be %lld / %d = %lld\n",
Packit 577717
		 values[(num_events*j)+(j-1)],
Packit 577717
		 mythreshold,
Packit 577717
		 values[(num_events*j)+(j-1)]/mythreshold);
Packit 577717
	     printf("\tOverflow was %d\n",ovt[j-1]);
Packit 577717
	  }
Packit 577717
	}
Packit 577717
	}
Packit 577717
Packit 577717
	for ( j = 0; j < num_events; j++ ) {
Packit 577717
		//printf("Validation: %lld / %d != %d (%lld)\n",
Packit 577717
		//       *( values + j + num_events * (j+1) ) ,
Packit 577717
		//       mythreshold,
Packit 577717
		//       ovt[j],
Packit 577717
		//       *(values+j+num_events*(j+1))/mythreshold);
Packit 577717
Packit 577717
		value = values[j+num_events*(j+1)];
Packit 577717
Packit 577717
		if ( value / mythreshold != ovt[j] ) {
Packit 577717
			char error_string[BUFSIZ];
Packit 577717
Packit 577717
			if ( using_perfmon )
Packit 577717
				test_warn( __FILE__, __LINE__,
Packit 577717
						   "perfmon component handles overflow differently than perf_events",
Packit 577717
						   1 );
Packit 577717
			else if ( using_aix )
Packit 577717
				test_warn( __FILE__, __LINE__,
Packit 577717
						   "AIX (pmapi) component handles overflow differently than various other components",
Packit 577717
						   1 );
Packit 577717
			else {
Packit 577717
				sprintf( error_string,
Packit 577717
					"Overflow value differs from expected %lld / %d should be %lld, we got %d",
Packit 577717
					value , mythreshold,
Packit 577717
					value / mythreshold,
Packit 577717
					ovt[j] );
Packit 577717
				test_fail( __FILE__, __LINE__, error_string, 1 );
Packit 577717
			}
Packit 577717
		}
Packit 577717
	}
Packit 577717
Packit 577717
	retval = PAPI_cleanup_eventset( EventSet );
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
Packit 577717
Packit 577717
	retval = PAPI_destroy_eventset( &EventSet );
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
Packit 577717
Packit 577717
	free( ovt );
Packit 577717
	for ( i = 0; i < num_events; i++ )
Packit 577717
		free( names[i] );
Packit 577717
	free( names );
Packit 577717
	free( events );
Packit 577717
	free( values );
Packit 577717
Packit 577717
	test_pass( __FILE__ );
Packit 577717
Packit 577717
	return 0;
Packit 577717
}