Blame src/ctests/matrix-hl.c

Packit Service a1973e
/****************************************************************************
Packit Service a1973e
 *C
Packit Service a1973e
 *C     matrix-hl.f
Packit Service a1973e
 *C     An example of matrix-matrix multiplication and using PAPI high level
Packit Service a1973e
 *C     to look at the performance. written by Kevin London
Packit Service a1973e
 *C     March 2000
Packit Service a1973e
 *C     Added to c tests to check stop
Packit Service a1973e
 *C****************************************************************************
Packit Service a1973e
 */
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
#include <stdio.h>
Packit Service a1973e
#include <stdlib.h>
Packit Service a1973e
Packit Service a1973e
#include "papi.h"
Packit Service a1973e
#include "papi_test.h"
Packit Service a1973e
Packit Service a1973e
#include "do_loops.h"
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
main( int argc, char **argv )
Packit Service a1973e
{
Packit Service a1973e
Packit Service a1973e
#define NROWS1 175
Packit Service a1973e
#define NCOLS1 225
Packit Service a1973e
#define NROWS2 NCOLS1
Packit Service a1973e
#define NCOLS2 150
Packit Service a1973e
	double p[NROWS1][NCOLS1], q[NROWS2][NCOLS2], r[NROWS1][NCOLS2];
Packit Service a1973e
	int i, j, k, num_events, retval;
Packit Service a1973e
	/*     PAPI standardized event to be monitored */
Packit Service a1973e
	int event[2];
Packit Service a1973e
	/*     PAPI values of the counters */
Packit Service a1973e
	long long values[2], tmp;
Packit Service a1973e
	int quiet;
Packit Service a1973e
Packit Service a1973e
	quiet = tests_quiet( argc, argv );
Packit Service a1973e
Packit Service a1973e
	/*     Setup default values */
Packit Service a1973e
	num_events = 0;
Packit Service a1973e
Packit Service a1973e
	/*     See how many hardware events at one time are supported
Packit Service a1973e
	 *     This also initializes the PAPI library */
Packit Service a1973e
	num_events = PAPI_num_counters(  );
Packit Service a1973e
	if ( num_events < 2 ) {
Packit Service a1973e
		if (!quiet) printf( "This example program requries the architecture to "
Packit Service a1973e
				"support 2 simultaneous hardware events...shutting down.\n" );
Packit Service a1973e
		test_skip( __FILE__, __LINE__, "PAPI_num_counters", 1 );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( !quiet )
Packit Service a1973e
		printf( "Number of hardware counters supported: %d\n", num_events );
Packit Service a1973e
Packit Service a1973e
	if ( PAPI_query_event( PAPI_FP_OPS ) == PAPI_OK )
Packit Service a1973e
		event[0] = PAPI_FP_OPS;
Packit Service a1973e
	else if ( PAPI_query_event( PAPI_FP_INS ) == PAPI_OK )
Packit Service a1973e
		event[0] = PAPI_FP_INS;
Packit Service a1973e
	else
Packit Service a1973e
		event[0] = PAPI_TOT_INS;
Packit Service a1973e
Packit Service a1973e
	/*     Time used */
Packit Service a1973e
	event[1] = PAPI_TOT_CYC;
Packit Service a1973e
Packit Service a1973e
	/*     matrix 1: read in the matrix values */
Packit Service a1973e
	for ( i = 0; i < NROWS1; i++ )
Packit Service a1973e
		for ( j = 0; j < NCOLS1; j++ )
Packit Service a1973e
			p[i][j] = i * j * 1.0;
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < NROWS2; i++ )
Packit Service a1973e
		for ( j = 0; j < NCOLS2; j++ )
Packit Service a1973e
			q[i][j] = i * j * 1.0;
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < NROWS1; i++ )
Packit Service a1973e
		for ( j = 0; j < NCOLS2; j++ )
Packit Service a1973e
			r[i][j] = i * j * 1.0;
Packit Service a1973e
Packit Service a1973e
	/*     Set up the counters */
Packit Service a1973e
	num_events = 2;
Packit Service a1973e
	retval = PAPI_start_counters( event, num_events );
Packit Service a1973e
	if ( retval != PAPI_OK )
Packit Service a1973e
		test_fail( __FILE__, __LINE__, "PAPI_start_counters", retval );
Packit Service a1973e
Packit Service a1973e
	/*     Clear the counter values */
Packit Service a1973e
	retval = PAPI_read_counters( values, num_events );
Packit Service a1973e
	if ( retval != PAPI_OK )
Packit Service a1973e
		test_fail( __FILE__, __LINE__, "PAPI_read_counters", retval );
Packit Service a1973e
Packit Service a1973e
	/*     Compute the matrix-matrix multiplication  */
Packit Service a1973e
	for ( i = 0; i < NROWS1; i++ )
Packit Service a1973e
		for ( j = 0; j < NCOLS2; j++ )
Packit Service a1973e
			for ( k = 0; k < NCOLS1; k++ )
Packit Service a1973e
				r[i][j] = r[i][j] + p[i][k] * q[k][j];
Packit Service a1973e
Packit Service a1973e
	/*     Stop the counters and put the results in the array values  */
Packit Service a1973e
	retval = PAPI_stop_counters( values, num_events );
Packit Service a1973e
	if ( retval != PAPI_OK )
Packit Service a1973e
		test_fail( __FILE__, __LINE__, "PAPI_stop_counters", retval );
Packit Service a1973e
Packit Service a1973e
	/*  Make sure the compiler does not optimize away the multiplication
Packit Service a1973e
	 *  with dummy(r);
Packit Service a1973e
	 */
Packit Service a1973e
	dummy( r );
Packit Service a1973e
Packit Service a1973e
	if ( !quiet ) {
Packit Service a1973e
		if ( event[0] == PAPI_TOT_INS ) {
Packit Service a1973e
			printf( TAB1, "TOT Instructions:", values[0] );
Packit Service a1973e
		} else {
Packit Service a1973e
			printf( TAB1, "FP Instructions:", values[0] );
Packit Service a1973e
		}
Packit Service a1973e
		printf( TAB1, "Cycles:", values[1] );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/*  
Packit Service a1973e
	 *  Intel Core overreports flops by 50% when using -O
Packit Service a1973e
	 *  Use -O2 or -O3 to produce the expected # of flops
Packit Service a1973e
	 */
Packit Service a1973e
Packit Service a1973e
	if ( event[0] == PAPI_FP_INS ) {
Packit Service a1973e
		/*     Compare measured FLOPS to expected value */
Packit Service a1973e
		tmp =
Packit Service a1973e
			2 * ( long long ) ( NROWS1 ) * ( long long ) ( NCOLS2 ) *
Packit Service a1973e
			( long long ) ( NCOLS1 );
Packit Service a1973e
		if ( abs( ( int ) values[0] - ( int ) tmp ) > ( double ) tmp * 0.05 ) {
Packit Service a1973e
			/*     Maybe we are counting FMAs? */
Packit Service a1973e
			tmp = tmp / 2;
Packit Service a1973e
			if ( abs( ( int ) values[0] - ( int ) tmp ) >
Packit Service a1973e
				 ( double ) tmp * 0.05 ) {
Packit Service a1973e
				printf( "\n" TAB1, "Expected operation count: ", 2 * tmp );
Packit Service a1973e
				printf( TAB1, "Or possibly (using FMA):  ", tmp );
Packit Service a1973e
				printf( TAB1, "Instead I got:            ", values[0] );
Packit Service a1973e
				test_fail( __FILE__, __LINE__,
Packit Service a1973e
						   "Unexpected FLOP count (check vector operations)",
Packit Service a1973e
						   1 );
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
	test_pass( __FILE__ );
Packit Service a1973e
Packit Service a1973e
	return 0;
Packit Service a1973e
Packit Service a1973e
}