|
PAPI
5.0.1.0
|
00001 /* This file performs the following test: profile for pthreads */ 00002 00003 #include <pthread.h> 00004 #include "papi_test.h" 00005 00006 extern int TESTS_QUIET; /* Declared in test_utils.c */ 00007 00008 #define THR 1000000 00009 #define FLOPS 100000000 00010 00011 unsigned int length; 00012 caddr_t my_start, my_end; 00013 00014 void * 00015 Thread( void *arg ) 00016 { 00017 int retval, num_tests = 1, i; 00018 int EventSet1 = PAPI_NULL, mask1, PAPI_event; 00019 int num_events1; 00020 long long **values; 00021 long long elapsed_us, elapsed_cyc; 00022 unsigned short *profbuf; 00023 char event_name[PAPI_MAX_STR_LEN]; 00024 00025 retval = PAPI_register_thread( ); 00026 if ( retval != PAPI_OK ) 00027 test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval ); 00028 profbuf = ( unsigned short * ) malloc( length * sizeof ( unsigned short ) ); 00029 if ( profbuf == NULL ) 00030 exit( 1 ); 00031 memset( profbuf, 0x00, length * sizeof ( unsigned short ) ); 00032 00033 /* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or 00034 PAPI_TOT_INS, depends on the availability of the event on the 00035 platform */ 00036 EventSet1 = 00037 add_two_nonderived_events( &num_events1, &PAPI_event, &mask1 ); 00038 00039 values = allocate_test_space( num_tests, num_events1 ); 00040 00041 if ( ( retval = 00042 PAPI_event_code_to_name( PAPI_event, event_name ) ) != PAPI_OK ) 00043 test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); 00044 00045 elapsed_us = PAPI_get_real_usec( ); 00046 00047 elapsed_cyc = PAPI_get_real_cyc( ); 00048 00049 retval = PAPI_profil( profbuf, length, my_start, 65536, 00050 EventSet1, PAPI_event, THR, PAPI_PROFIL_POSIX ); 00051 if ( retval ) 00052 test_fail( __FILE__, __LINE__, "PAPI_profil", retval ); 00053 00054 if ( ( retval = PAPI_start( EventSet1 ) ) != PAPI_OK ) 00055 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00056 00057 do_flops( *( int * ) arg ); 00058 00059 if ( ( retval = PAPI_stop( EventSet1, values[0] ) ) != PAPI_OK ) 00060 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00061 00062 elapsed_us = PAPI_get_real_usec( ) - elapsed_us; 00063 00064 elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; 00065 00066 /* to remove the profile flag */ 00067 retval = PAPI_profil( profbuf, length, my_start, 65536, 00068 EventSet1, PAPI_event, 0, PAPI_PROFIL_POSIX ); 00069 if ( retval ) 00070 test_fail( __FILE__, __LINE__, "PAPI_profil", retval ); 00071 00072 00073 remove_test_events( &EventSet1, mask1 ); 00074 00075 if ( !TESTS_QUIET ) { 00076 if ( mask1 == 0x3 ) { 00077 printf( "Thread 0x%x PAPI_TOT_INS : \t%lld\n", 00078 ( int ) pthread_self( ), ( values[0] )[0] ); 00079 } else { 00080 printf( "Thread 0x%x PAPI_FP_INS : \t%lld\n", 00081 ( int ) pthread_self( ), ( values[0] )[0] ); 00082 } 00083 printf( "Thread 0x%x PAPI_TOT_CYC: \t%lld\n", ( int ) pthread_self( ), 00084 ( values[0] )[1] ); 00085 printf( "Thread 0x%x Real usec : \t%lld\n", ( int ) pthread_self( ), 00086 elapsed_us ); 00087 printf( "Thread 0x%x Real cycles : \t%lld\n", ( int ) pthread_self( ), 00088 elapsed_cyc ); 00089 00090 printf( "Test case: PAPI_profil() for pthreads\n" ); 00091 printf( "----Profile buffer for Thread 0x%x---\n", 00092 ( int ) pthread_self( ) ); 00093 for ( i = 0; i < ( int ) length; i++ ) { 00094 if ( profbuf[i] ) 00095 printf( "0x%lx\t%d\n", ( unsigned long ) ( my_start + 2 * i ), 00096 profbuf[i] ); 00097 } 00098 } 00099 for ( i = 0; i < ( int ) length; i++ ) 00100 if ( profbuf[i] ) 00101 break; 00102 00103 if ( i >= ( int ) length ) 00104 test_fail( __FILE__, __LINE__, "No information in buffers", 1 ); 00105 free_test_space( values, num_tests ); 00106 00107 retval = PAPI_unregister_thread( ); 00108 if ( retval != PAPI_OK ) 00109 test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval ); 00110 return ( NULL ); 00111 } 00112 00113 int 00114 main( int argc, char **argv ) 00115 { 00116 pthread_t id[NUM_THREADS]; 00117 int flops[NUM_THREADS]; 00118 int i, rc, retval; 00119 pthread_attr_t attr; 00120 long long elapsed_us, elapsed_cyc; 00121 const PAPI_exe_info_t *prginfo = NULL; 00122 00123 tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */ 00124 00125 if ( ( retval = 00126 PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT ) 00127 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00128 if ( ( retval = 00129 PAPI_thread_init( ( unsigned 00130 long ( * )( void ) ) ( pthread_self ) ) ) != 00131 PAPI_OK ) { 00132 if ( retval == PAPI_ECMP ) 00133 test_skip( __FILE__, __LINE__, "PAPI_thread_init", retval ); 00134 else 00135 test_fail( __FILE__, __LINE__, "PAPI_thread_init", retval ); 00136 } 00137 if ( ( prginfo = PAPI_get_executable_info( ) ) == NULL ) { 00138 retval = 1; 00139 test_fail( __FILE__, __LINE__, "PAPI_get_executable_info", retval ); 00140 } 00141 my_start = prginfo->address_info.text_start; 00142 my_end = prginfo->address_info.text_end; 00143 length = ( unsigned int ) ( my_end - my_start ); 00144 00145 elapsed_us = PAPI_get_real_usec( ); 00146 00147 elapsed_cyc = PAPI_get_real_cyc( ); 00148 00149 pthread_attr_init( &attr ); 00150 #ifdef PTHREAD_CREATE_UNDETACHED 00151 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_UNDETACHED ); 00152 #endif 00153 #ifdef PTHREAD_SCOPE_SYSTEM 00154 retval = pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); 00155 if ( retval != 0 ) 00156 test_skip( __FILE__, __LINE__, "pthread_attr_setscope", retval ); 00157 #endif 00158 00159 for ( i = 0; i < NUM_THREADS; i++ ) { 00160 flops[i] = FLOPS * ( i + 1 ); 00161 rc = pthread_create( &id[i], &attr, Thread, ( void * ) &flops[i] ); 00162 if ( rc ) 00163 return ( FAILURE ); 00164 } 00165 for ( i = 0; i < NUM_THREADS; i++ ) 00166 pthread_join( id[i], NULL ); 00167 00168 pthread_attr_destroy( &attr ); 00169 00170 elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; 00171 00172 elapsed_us = PAPI_get_real_usec( ) - elapsed_us; 00173 00174 if ( !TESTS_QUIET ) { 00175 printf( "Master real usec : \t%lld\n", elapsed_us ); 00176 printf( "Master real cycles : \t%lld\n", elapsed_cyc ); 00177 } 00178 00179 test_pass( __FILE__, NULL, 0 ); 00180 pthread_exit( NULL ); 00181 exit( 1 ); 00182 }