|
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 |
}
|