PAPI 7.1.0.0
Loading...
Searching...
No Matches
calibrate.c
Go to the documentation of this file.
1/*
2 Calibrate.c
3 A program to perform one or all of three tests to count flops.
4 Test 1. Inner Product: 2*n operations
5 for i = 1:n; a = a + x(i)*y(i); end
6 Test 2. Matrix Vector Product: 2*n^2 operations
7 for i = 1:n; for j = 1:n; x(i) = x(i) + a(i,j)*y(j); end; end;
8 Test 3. Matrix Matrix Multiply: 2*n^3 operations
9 for i = 1:n; for j = 1:n; for k = 1:n; c(i,j) = c(i,j) + a(i,k)*b(k,j); end; end; end;
10
11 Supply a command line argument of 1, 2, or 3 to perform each test, or
12 no argument to perform all three.
13
14 Each test initializes PAPI and presents a header with processor information.
15 Then it performs 500 iterations, printing result lines containing:
16 n, measured counts, theoretical counts, (measured - theory), % error
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include "papi.h"
24#include "papi_test.h"
25
26#define INDEX1 100
27#define INDEX5 500
28
29#define MAX_WARN 10
30#define MAX_ERROR 80
31#define MAX_DIFF 14
32
33/*
34 Extract and display hardware information for this processor.
35 (Re)Initialize PAPI_flops() and begin counting floating ops.
36*/
37static void
38headerlines( const char *title, int quiet )
39{
40
41 if ( !quiet ) {
42 printf( "\n%s:\n%8s %12s %12s %8s %8s\n", title, "i", "papi", "theory",
43 "diff", "%error" );
44 printf( "-------------------------------------------------------------------------\n" );
45 }
46}
47
48/*
49 Read PAPI_flops.
50 Format and display results.
51 Compute error without using floating ops.
52*/
53#if defined(mips)
54#define FMA 1
55#elif (defined(sparc) && defined(sun))
56#define FMA 1
57#else
58#define FMA 0
59#endif
60
61static void
62resultline( int i, int j, int EventSet, int fail, int quiet )
63{
64 float ferror = 0;
65 long long flpins = 0;
66 long long papi, theory;
67 int diff, retval;
68 char err_str[PAPI_MAX_STR_LEN];
69
70 retval = PAPI_stop( EventSet, &flpins );
71 if ( retval != PAPI_OK )
72 test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
73
74 i++; /* convert to 1s base */
75 theory = 2;
76 while ( j-- )
77 theory *= i; /* theoretical ops */
78 papi = flpins << FMA;
79
80 diff = ( int ) ( papi - theory );
81
82 ferror = ( ( float ) abs( diff ) ) / ( ( float ) theory ) * 100;
83
84 if (!quiet) {
85 printf( "%8d %12lld %12lld %8d %10.4f\n", i, papi, theory, diff, ferror );
86 }
87
88 if ( ferror > MAX_WARN && abs( diff ) > MAX_DIFF && i > 20 ) {
89 sprintf( err_str, "Calibrate: difference exceeds %d percent", MAX_WARN );
90 test_warn( __FILE__, __LINE__, err_str, 0 );
91 }
92 if (fail) {
93 if ( ferror > MAX_ERROR && abs( diff ) > MAX_DIFF && i > 20 ) {
94 sprintf( err_str, "Calibrate: error exceeds %d percent", MAX_ERROR );
95 test_fail( __FILE__, __LINE__, err_str, PAPI_EMISC );
96 }
97 }
98}
99
100
101static void
102print_help( char **argv )
103{
104 printf( "Usage: %s [-ivmdh] [-e event]\n", argv[0] );
105 printf( "Options:\n\n" );
106 printf( "\t-i Inner Product test.\n" );
107 printf( "\t-v Matrix-Vector multiply test.\n" );
108 printf( "\t-m Matrix-Matrix multiply test.\n" );
109 printf( "\t-d Double precision data. Default is float.\n" );
110 printf( "\t-e event Use <event> as PAPI event instead of PAPI_FP_OPS\n" );
111 printf( "\t-f Suppress failures\n" );
112 printf( "\t-h Print this help message\n" );
113 printf( "\n" );
114 printf( "This test measures floating point operations for the specified test.\n" );
115 printf( "Operations can be performed in single or double precision.\n" );
116 printf( "Default operation is all three tests in single precision.\n" );
117}
118
119static float
120inner_single( int n, float *x, float *y )
121{
122 float aa = 0.0;
123 int i;
124
125 for ( i = 0; i <= n; i++ )
126 aa = aa + x[i] * y[i];
127 return ( aa );
128}
129
130static double
131inner_double( int n, double *x, double *y )
132{
133 double aa = 0.0;
134 int i;
135
136 for ( i = 0; i <= n; i++ )
137 aa = aa + x[i] * y[i];
138 return ( aa );
139}
140
141static void
142vector_single( int n, float *a, float *x, float *y )
143{
144 int i, j;
145
146 for ( i = 0; i <= n; i++ )
147 for ( j = 0; j <= n; j++ )
148 y[i] = y[i] + a[i * n + j] * x[i];
149}
150
151static void
152vector_double( int n, double *a, double *x, double *y )
153{
154 int i, j;
155
156 for ( i = 0; i <= n; i++ )
157 for ( j = 0; j <= n; j++ )
158 y[i] = y[i] + a[i * n + j] * x[i];
159}
160
161static void
162matrix_single( int n, float *c, float *a, float *b )
163{
164 int i, j, k;
165
166 for ( i = 0; i <= n; i++ )
167 for ( j = 0; j <= n; j++ )
168 for ( k = 0; k <= n; k++ )
169 c[i * n + j] = c[i * n + j] + a[i * n + k] * b[k * n + j];
170}
171
172static void
173matrix_double( int n, double *c, double *a, double *b )
174{
175 int i, j, k;
176
177 for ( i = 0; i <= n; i++ )
178 for ( j = 0; j <= n; j++ )
179 for ( k = 0; k <= n; k++ )
180 c[i * n + j] = c[i * n + j] + a[i * n + k] * b[k * n + j];
181}
182
183static void
184reset_flops( const char *title, int EventSet )
185{
186 int retval;
187 char err_str[PAPI_MAX_STR_LEN];
188
190 if ( retval != PAPI_OK ) {
191 sprintf( err_str, "%s: PAPI_start", title );
192 test_fail( __FILE__, __LINE__, err_str, retval );
193 }
194}
195
196int
197main( int argc, char *argv[] )
198{
199 extern void dummy( void * );
200
201 float aa, *a=NULL, *b=NULL, *c=NULL, *x=NULL, *y=NULL;
202 double aad, *ad=NULL, *bd=NULL, *cd=NULL, *xd=NULL, *yd=NULL;
203 int i, j, n;
204 int inner = 0;
205 int vector = 0;
206 int matrix = 0;
207 int double_precision = 0;
208 int fail = 1;
209 int retval = PAPI_OK;
210 char papi_event_str[PAPI_MIN_STR_LEN] = "PAPI_FP_OPS";
211 int papi_event;
212 int EventSet = PAPI_NULL;
213 int quiet;
214
215 /* Parse the input arguments */
216 for ( i = 0; i < argc; i++ ) {
217 if ( strstr( argv[i], "-i" ) )
218 inner = 1;
219 else if ( strstr( argv[i], "-f" ) )
220 fail = 0;
221 else if ( strstr( argv[i], "-v" ) )
222 vector = 1;
223 else if ( strstr( argv[i], "-m" ) )
224 matrix = 1;
225 else if ( strstr( argv[i], "-e" ) ) {
226 if ( ( argv[i + 1] == NULL ) || ( strlen( argv[i + 1] ) == 0 ) ) {
227 print_help( argv );
228 exit( 1 );
229 }
230 strncpy( papi_event_str, argv[i + 1], sizeof ( papi_event_str ) - 1);
231 papi_event_str[sizeof ( papi_event_str )-1] = '\0';
232 i++;
233 } else if ( strstr( argv[i], "-d" ) )
234 double_precision = 1;
235 else if ( strstr( argv[i], "-h" ) ) {
236 print_help( argv );
237 exit( 1 );
238 }
239 }
240
241 /* if no options specified, set all tests to TRUE */
242 if ( inner + vector + matrix == 0 )
243 inner = vector = matrix = 1;
244
245
246 /* Set TESTS_QUIET variable */
247 quiet = tests_quiet( argc, argv );
248
249 if ( !quiet ) {
250 printf( "Initializing..." );
251 }
252
253 /* Initialize PAPI */
255 if ( retval != PAPI_VER_CURRENT ) {
256 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
257 }
258
259 /* Translate name */
260 retval = PAPI_event_name_to_code( papi_event_str, &papi_event );
261 if ( retval != PAPI_OK ) {
262 test_fail( __FILE__, __LINE__, "PAPI_event_name_to_code", retval );
263 }
264
265 if ( PAPI_query_event( papi_event ) != PAPI_OK ) {
266 test_skip( __FILE__, __LINE__, "PAPI_query_event", PAPI_ENOEVNT );
267 }
268
269 if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK ) {
270 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
271 }
272
273 if ( ( retval = PAPI_add_event( EventSet, papi_event ) ) != PAPI_OK ) {
274 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
275 }
276
277 if (!quiet) printf( "\n" );
278
279 retval = PAPI_OK;
280
281 /* Inner Product test */
282 if ( inner ) {
283 /* Allocate the linear arrays */
284 if (double_precision) {
285 xd = malloc( INDEX5 * sizeof(double) );
286 yd = malloc( INDEX5 * sizeof(double) );
287 if ( !( xd && yd ) )
289 }
290 else {
291 x = malloc( INDEX5 * sizeof(float) );
292 y = malloc( INDEX5 * sizeof(float) );
293 if ( !( x && y ) )
295 }
296
297 if ( retval == PAPI_OK ) {
298 headerlines( "Inner Product Test", quiet );
299
300 /* step through the different array sizes */
301 for ( n = 0; n < INDEX5; n++ ) {
302 if ( n < INDEX1 || ( ( n + 1 ) % 50 ) == 0 ) {
303
304 /* Initialize the needed arrays at this size */
305 if ( double_precision ) {
306 for ( i = 0; i <= n; i++ ) {
307 xd[i] = ( double ) rand( ) * ( double ) 1.1;
308 yd[i] = ( double ) rand( ) * ( double ) 1.1;
309 }
310 } else {
311 for ( i = 0; i <= n; i++ ) {
312 x[i] = ( float ) rand( ) * ( float ) 1.1;
313 y[i] = ( float ) rand( ) * ( float ) 1.1;
314 }
315 }
316
317 /* reset PAPI flops count */
318 reset_flops( "Inner Product Test", EventSet );
319
320 /* do the multiplication */
321 if ( double_precision ) {
322 aad = inner_double( n, xd, yd );
323 dummy( ( void * ) &aad );
324 } else {
325 aa = inner_single( n, x, y );
326 dummy( ( void * ) &aa );
327 }
328 resultline( n, 1, EventSet, fail, quiet );
329 }
330 }
331 }
332 if (double_precision) {
333 free( xd );
334 free( yd );
335 } else {
336 free( x );
337 free( y );
338 }
339 }
340
341 /* Matrix Vector test */
342 if ( vector && retval != PAPI_ENOMEM ) {
343 /* Allocate the needed arrays */
344 if (double_precision) {
345 ad = malloc( INDEX5 * INDEX5 * sizeof(double) );
346 xd = malloc( INDEX5 * sizeof(double) );
347 yd = malloc( INDEX5 * sizeof(double) );
348 if ( !( ad && xd && yd ) )
350 } else {
351 a = malloc( INDEX5 * INDEX5 * sizeof(float) );
352 x = malloc( INDEX5 * sizeof(float) );
353 y = malloc( INDEX5 * sizeof(float) );
354 if ( !( a && x && y ) )
356 }
357
358 if ( retval == PAPI_OK ) {
359 headerlines( "Matrix Vector Test", quiet );
360
361 /* step through the different array sizes */
362 for ( n = 0; n < INDEX5; n++ ) {
363 if ( n < INDEX1 || ( ( n + 1 ) % 50 ) == 0 ) {
364
365 /* Initialize the needed arrays at this size */
366 if ( double_precision ) {
367 for ( i = 0; i <= n; i++ ) {
368 yd[i] = 0.0;
369 xd[i] = ( double ) rand( ) * ( double ) 1.1;
370 for ( j = 0; j <= n; j++ )
371 ad[i * n + j] =
372 ( double ) rand( ) * ( double ) 1.1;
373 }
374 } else {
375 for ( i = 0; i <= n; i++ ) {
376 y[i] = 0.0;
377 x[i] = ( float ) rand( ) * ( float ) 1.1;
378 for ( j = 0; j <= n; j++ )
379 a[i * n + j] =
380 ( float ) rand( ) * ( float ) 1.1;
381 }
382 }
383
384 /* reset PAPI flops count */
385 reset_flops( "Matrix Vector Test", EventSet );
386
387 /* compute the resultant vector */
388 if ( double_precision ) {
389 vector_double( n, ad, xd, yd );
390 dummy( ( void * ) yd );
391 } else {
392 vector_single( n, a, x, y );
393 dummy( ( void * ) y );
394 }
395 resultline( n, 2, EventSet, fail, quiet );
396 }
397 }
398 }
399 if (double_precision) {
400 free( ad );
401 free( xd );
402 free( yd );
403 } else {
404 free( a );
405 free( x );
406 free( y );
407 }
408 }
409
410 /* Matrix Multiply test */
411 if ( matrix && retval != PAPI_ENOMEM ) {
412 /* Allocate the needed arrays */
413 if (double_precision) {
414 ad = malloc( INDEX5 * INDEX5 * sizeof(double) );
415 bd = malloc( INDEX5 * INDEX5 * sizeof(double) );
416 cd = malloc( INDEX5 * INDEX5 * sizeof(double) );
417 if ( !( ad && bd && cd ) )
419 } else {
420 a = malloc( INDEX5 * INDEX5 * sizeof(float) );
421 b = malloc( INDEX5 * INDEX5 * sizeof(float) );
422 c = malloc( INDEX5 * INDEX5 * sizeof(float) );
423 if ( !( a && b && c ) )
425 }
426
427
428 if ( retval == PAPI_OK ) {
429 headerlines( "Matrix Multiply Test", quiet );
430
431 /* step through the different array sizes */
432 for ( n = 0; n < INDEX5; n++ ) {
433 if ( n < INDEX1 || ( ( n + 1 ) % 50 ) == 0 ) {
434
435 /* Initialize the needed arrays at this size */
436 if ( double_precision ) {
437 for ( i = 0; i <= n * n + n; i++ ) {
438 cd[i] = 0.0;
439 ad[i] = ( double ) rand( ) * ( double ) 1.1;
440 bd[i] = ( double ) rand( ) * ( double ) 1.1;
441 }
442 } else {
443 for ( i = 0; i <= n * n + n; i++ ) {
444 c[i] = 0.0;
445 a[i] = ( float ) rand( ) * ( float ) 1.1;
446 b[i] = ( float ) rand( ) * ( float ) 1.1;
447 }
448 }
449
450 /* reset PAPI flops count */
451 reset_flops( "Matrix Multiply Test", EventSet );
452
453 /* compute the resultant matrix */
454 if ( double_precision ) {
455 matrix_double( n, cd, ad, bd );
456 dummy( ( void * ) c );
457 } else {
458 matrix_single( n, c, a, b );
459 dummy( ( void * ) c );
460 }
461 resultline( n, 3, EventSet, fail, quiet );
462 }
463 }
464 }
465 if (double_precision) {
466 free( ad );
467 free( bd );
468 free( cd );
469 } else {
470 free( a );
471 free( b );
472 free( c );
473 }
474 }
475
476 /* exit with status code */
477 if ( retval == PAPI_ENOMEM ) {
478 test_fail( __FILE__, __LINE__, "malloc", retval );
479 }
480
481 test_pass( __FILE__ );
482
483 return 0;
484}
485
int i
double aa[N]
Definition: byte_profile.c:35
static void reset_flops(const char *title, int EventSet)
Definition: calibrate.c:184
#define MAX_DIFF
Definition: calibrate.c:31
static void matrix_single(int n, float *c, float *a, float *b)
Definition: calibrate.c:162
#define INDEX1
Definition: calibrate.c:26
#define INDEX5
Definition: calibrate.c:27
static void matrix_double(int n, double *c, double *a, double *b)
Definition: calibrate.c:173
static void resultline(int i, int j, int EventSet, int fail, int quiet)
Definition: calibrate.c:62
#define MAX_ERROR
Definition: calibrate.c:30
static float inner_single(int n, float *x, float *y)
Definition: calibrate.c:120
#define MAX_WARN
Definition: calibrate.c:29
static void headerlines(const char *title, int quiet)
Definition: calibrate.c:38
#define FMA
Definition: calibrate.c:58
static double inner_double(int n, double *x, double *y)
Definition: calibrate.c:131
static void vector_single(int n, float *a, float *x, float *y)
Definition: calibrate.c:142
static void vector_double(int n, double *a, double *x, double *y)
Definition: calibrate.c:152
add PAPI preset or native hardware event to an event set
Create a new empty PAPI EventSet.
Convert a name to a numeric hardware event code.
initialize the PAPI library.
Query if PAPI event exists.
Start counting hardware events in an event set.
Stop counting hardware events in an event set.
void dummy(void *array)
Definition: do_loops.c:306
#define PAPI_VER_CURRENT
Definition: f90papi.h:54
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_MIN_STR_LEN
Definition: f90papi.h:208
#define PAPI_NULL
Definition: f90papi.h:78
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_EMISC
Definition: f90papi.h:122
#define PAPI_ENOMEM
Definition: f90papi.h:16
static int EventSet
Definition: init_fini.c:8
static double a[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:38
static double b[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:39
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
Return codes and api definitions.
static void print_help(void)
Definition: papi_cost.c:85
int tests_quiet(int argc, char **argv)
Definition: test_utils.c:376
void PAPI_NORETURN test_fail(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:491
void PAPI_NORETURN test_pass(const char *filename)
Definition: test_utils.c:432
void test_warn(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:547
void PAPI_NORETURN test_skip(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:584
int main()
Definition: pernode.c:20
int quiet
Definition: rapl_overflow.c:19
int
Definition: sde_internal.h:89
volatile double y
volatile double x
int retval
Definition: zero_fork.c:53