PAPI  5.0.1.0
low-level.c
Go to the documentation of this file.
00001 /*  This examples show the essentials in using the PAPI low-level
00002     interface. The program consists of 3 examples where the work
00003     done over some work-loops. The example tries to illustrate
00004     some simple mistakes that are easily made and how a correct
00005     code would accomplish the same thing.
00006 
00007     Example 1: The total count over two work loops (Loops 1 and 2) 
00008     are supposed to be measured. Due to a mis-understanding of the
00009     semantics of the API the total count gets wrong.
00010     The example also illustrates that it is legal to read both
00011     running and stopped counters.
00012 
00013     Example 2: The total count over two work loops (Loops 1 and 3)
00014     is supposed to be measured while discarding the counts made in
00015     loop 2. Instead the counts in loop1 are counted twice and the
00016     counts in loop2 are added to the total number of counts.
00017 
00018     Example 3: One correct way of accomplishing the result aimed for
00019     in example 2.
00020 */
00021 
00022 #include "papi_test.h"
00023 
00024 extern int TESTS_QUIET;                /* Declared in test_utils.c */
00025 
00026 int
00027 main( int argc, char **argv )
00028 {
00029     int retval;
00030 #define NUM_EVENTS 2
00031     long long values[NUM_EVENTS], dummyvalues[NUM_EVENTS];
00032     int Events[NUM_EVENTS];
00033     int EventSet = PAPI_NULL;
00034 
00035     tests_quiet( argc, argv );  /* Set TESTS_QUIET variable */
00036 
00037 
00038     if ( ( retval =
00039            PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT )
00040         test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
00041 
00042     /* query and set up the right events to monitor */
00043     if ( PAPI_query_event( PAPI_FP_INS ) == PAPI_OK ) {
00044         Events[0] = PAPI_FP_INS;
00045         Events[1] = PAPI_TOT_CYC;
00046     } else {
00047         Events[0] = PAPI_TOT_INS;
00048         Events[1] = PAPI_TOT_CYC;
00049     }
00050 
00051     if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK )
00052         test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
00053 
00054     if ( ( retval =
00055            PAPI_add_events( EventSet, ( int * ) Events,
00056                             NUM_EVENTS ) ) < PAPI_OK )
00057         test_fail( __FILE__, __LINE__, "PAPI_add_events", retval );
00058 
00059     if ( !TESTS_QUIET ) {
00060         printf( "\n   Incorrect usage of read and accum.\n" );
00061         printf( "   Some cycles are counted twice\n" );
00062     }
00063     if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00064         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00065 
00066     /* Loop 1 */
00067     do_flops( NUM_FLOPS );
00068 
00069     if ( ( retval = PAPI_read( EventSet, values ) ) != PAPI_OK )
00070         test_fail( __FILE__, __LINE__, "PAPI_read", retval );
00071 
00072     if ( !TESTS_QUIET )
00073         printf( TWO12, values[0], values[1], "(Counters continuing...)\n" );
00074 
00075     /* Loop 2 */
00076     do_flops( NUM_FLOPS );
00077 
00078     /* Using PAPI_accum here is incorrect. The result is that Loop 1 *
00079      * is being counted twice                                        */
00080     if ( ( retval = PAPI_accum( EventSet, values ) ) != PAPI_OK )
00081         test_fail( __FILE__, __LINE__, "PAPI_accum", retval );
00082 
00083     if ( !TESTS_QUIET )
00084         printf( TWO12, values[0], values[1], "(Counters being accumulated)\n" );
00085 
00086     /* Loop 3 */
00087     do_flops( NUM_FLOPS );
00088 
00089     if ( ( retval = PAPI_stop( EventSet, dummyvalues ) ) != PAPI_OK )
00090         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00091 
00092     if ( ( retval = PAPI_read( EventSet, dummyvalues ) ) != PAPI_OK )
00093         test_fail( __FILE__, __LINE__, "PAPI_read", retval );
00094 
00095     if ( !TESTS_QUIET ) {
00096         printf( TWO12, dummyvalues[0], dummyvalues[1],
00097                 "(Reading stopped counters)\n" );
00098 
00099         printf( TWO12, values[0], values[1], "" );
00100 
00101         printf( "\n   Incorrect usage of read and accum.\n" );
00102         printf( "   Another incorrect use\n" );
00103     }
00104     if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00105         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00106 
00107     /* Loop 1 */
00108     do_flops( NUM_FLOPS );
00109 
00110     if ( ( retval = PAPI_read( EventSet, values ) ) != PAPI_OK )
00111         test_fail( __FILE__, __LINE__, "PAPI_read", retval );
00112 
00113     if ( !TESTS_QUIET )
00114         printf( TWO12, values[0], values[1], "(Counters continuing...)\n" );
00115 
00116     /* Loop 2 */
00117     /* Code that should not be counted */
00118     do_flops( NUM_FLOPS );
00119 
00120     if ( ( retval = PAPI_read( EventSet, dummyvalues ) ) != PAPI_OK )
00121         test_fail( __FILE__, __LINE__, "PAPI_read", retval );
00122 
00123     if ( !TESTS_QUIET )
00124         printf( TWO12, dummyvalues[0], dummyvalues[1],
00125                 "(Intermediate counts...)\n" );
00126 
00127     /* Loop 3 */
00128     do_flops( NUM_FLOPS );
00129 
00130     /* Since PAPI_read does not reset the counters it's use above after    *
00131      * loop 2 is incorrect. Instead Loop1 will in effect be counted twice. *
00132      * and the counts in loop 2 are included in the total counts           */
00133     if ( ( retval = PAPI_accum( EventSet, values ) ) != PAPI_OK )
00134         test_fail( __FILE__, __LINE__, "PAPI_accum", retval );
00135     if ( !TESTS_QUIET )
00136         printf( TWO12, values[0], values[1], "" );
00137 
00138     if ( ( retval = PAPI_stop( EventSet, dummyvalues ) ) != PAPI_OK )
00139         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00140 
00141     if ( !TESTS_QUIET ) {
00142         printf( "\n   Correct usage of read and accum.\n" );
00143         printf( "   PAPI_reset and PAPI_accum used to skip counting\n" );
00144         printf( "   a section of the code.\n" );
00145     }
00146     if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00147         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00148 
00149     do_flops( NUM_FLOPS );
00150 
00151     if ( ( retval = PAPI_read( EventSet, values ) ) != PAPI_OK )
00152         test_fail( __FILE__, __LINE__, "PAPI_read", retval );
00153     if ( !TESTS_QUIET )
00154         printf( TWO12, values[0], values[1], "(Counters continuing)\n" );
00155 
00156     /* Code that should not be counted */
00157     do_flops( NUM_FLOPS );
00158 
00159     if ( ( retval = PAPI_reset( EventSet ) ) != PAPI_OK )
00160         test_fail( __FILE__, __LINE__, "PAPI_reset", retval );
00161 
00162     if ( !TESTS_QUIET )
00163         printf( "%12s %12s  (Counters reset)\n", "", "" );
00164 
00165     do_flops( NUM_FLOPS );
00166 
00167     if ( ( retval = PAPI_accum( EventSet, values ) ) != PAPI_OK )
00168         test_fail( __FILE__, __LINE__, "PAPI_accum", retval );
00169 
00170     if ( !TESTS_QUIET )
00171         printf( TWO12, values[0], values[1], "" );
00172 
00173     if ( !TESTS_QUIET ) {
00174         printf( "----------------------------------\n" );
00175         printf( "Verification: The last line in each experiment should be\n" );
00176         printf( "approximately twice the value of the first line.\n" );
00177         printf
00178             ( "The third case illustrates one possible way to accomplish this.\n" );
00179     }
00180     test_pass( __FILE__, NULL, 0 );
00181     exit( 1 );
00182 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines