|
PAPI
5.0.1.0
|
00001 /* 00002 * File: profile.c 00003 * CVS: $Id$ 00004 * Author: Philip Mucci 00005 * mucci@cs.utk.edu 00006 * Mods: Dan Terpstra 00007 * terpstra@cs.utk.edu 00008 * Mods: Maynard Johnson 00009 * maynardj@us.ibm.com 00010 * Mods: <your name here> 00011 * <your email address> 00012 */ 00013 00014 /* This file performs the following test: profiling and program info option call 00015 00016 - This tests the SVR4 profiling interface of PAPI. These are counted 00017 in the default counting domain and default granularity, depending on 00018 the platform. Usually this is the user domain (PAPI_DOM_USER) and 00019 thread context (PAPI_GRN_THR). 00020 00021 The Eventset contains: 00022 + PAPI_FP_INS (to profile) 00023 + PAPI_TOT_CYC 00024 00025 - Set up profile 00026 - Start eventset 1 00027 - Do both (flops and reads) 00028 - Stop eventset 1 00029 */ 00030 00031 #include "papi_test.h" 00032 #include "prof_utils.h" 00033 #define PROFILE_ALL 00034 00035 static int do_profile( caddr_t start, unsigned long plength, unsigned scale, 00036 int thresh, int bucket ); 00037 00038 int 00039 main( int argc, char **argv ) 00040 { 00041 int num_tests = 6; 00042 long length; 00043 int mask; 00044 int retval; 00045 int mythreshold = THRESHOLD; 00046 const PAPI_exe_info_t *prginfo; 00047 caddr_t start, end; 00048 00049 prof_init( argc, argv, &prginfo ); 00050 mask = prof_events( num_tests ); 00051 00052 #ifdef PROFILE_ALL 00053 /* use these lines to profile entire code address space */ 00054 start = prginfo->address_info.text_start; 00055 end = prginfo->address_info.text_end; 00056 #else 00057 /* use these lines to profile only do_flops address space */ 00058 start = ( caddr_t ) do_flops; 00059 end = ( caddr_t ) fdo_flops; 00060 /* Itanium and ppc64 processors return function descriptors instead of function addresses. 00061 You must dereference the descriptor to get the address. 00062 */ 00063 #if defined(ITANIUM1) || defined(ITANIUM2) || defined(__powerpc64__) 00064 start = ( caddr_t ) ( ( ( struct fdesc * ) start )->ip ); 00065 end = ( caddr_t ) ( ( ( struct fdesc * ) end )->ip ); 00066 #endif 00067 #endif 00068 00069 #if defined(linux) 00070 { 00071 char *tmp = getenv( "THRESHOLD" ); 00072 if ( tmp ) 00073 mythreshold = atoi( tmp ); 00074 } 00075 #endif 00076 00077 length = end - start; 00078 if ( length < 0 ) 00079 test_fail( __FILE__, __LINE__, "Profile length < 0!", ( int ) length ); 00080 00081 prof_print_address 00082 ( "Test case profile: POSIX compatible profiling with hardware counters.\n", 00083 prginfo ); 00084 prof_print_prof_info( start, end, mythreshold, event_name ); 00085 retval = 00086 do_profile( start, ( unsigned long ) length, FULL_SCALE, mythreshold, 00087 PAPI_PROFIL_BUCKET_16 ); 00088 if ( retval == PAPI_OK ) 00089 retval = 00090 do_profile( start, ( unsigned long ) length, FULL_SCALE, 00091 mythreshold, PAPI_PROFIL_BUCKET_32 ); 00092 if ( retval == PAPI_OK ) 00093 retval = 00094 do_profile( start, ( unsigned long ) length, FULL_SCALE, 00095 mythreshold, PAPI_PROFIL_BUCKET_64 ); 00096 00097 remove_test_events( &EventSet, mask ); 00098 test_pass( __FILE__, values, num_tests ); 00099 exit( 1 ); 00100 } 00101 00102 static int 00103 do_profile( caddr_t start, unsigned long plength, unsigned scale, int thresh, 00104 int bucket ) 00105 { 00106 int i, retval; 00107 unsigned long blength; 00108 int num_buckets; 00109 00110 char *profstr[5] = { "PAPI_PROFIL_POSIX", 00111 "PAPI_PROFIL_RANDOM", 00112 "PAPI_PROFIL_WEIGHTED", 00113 "PAPI_PROFIL_COMPRESS", 00114 "PAPI_PROFIL_<all>" 00115 }; 00116 00117 int profflags[5] = { PAPI_PROFIL_POSIX, 00118 PAPI_PROFIL_POSIX | PAPI_PROFIL_RANDOM, 00119 PAPI_PROFIL_POSIX | PAPI_PROFIL_WEIGHTED, 00120 PAPI_PROFIL_POSIX | PAPI_PROFIL_COMPRESS, 00121 PAPI_PROFIL_POSIX | PAPI_PROFIL_WEIGHTED | 00122 PAPI_PROFIL_RANDOM | PAPI_PROFIL_COMPRESS 00123 }; 00124 00125 do_no_profile( ); 00126 blength = prof_size( plength, scale, bucket, &num_buckets ); 00127 prof_alloc( 5, blength ); 00128 00129 for ( i = 0; i < 5; i++ ) { 00130 if ( !TESTS_QUIET ) 00131 printf( "Test type : \t%s\n", profstr[i] ); 00132 00133 #ifndef SWPROFILE 00134 if ( ( retval = 00135 PAPI_profil( profbuf[i], ( unsigned int ) blength, start, scale, 00136 EventSet, PAPI_event, thresh, 00137 profflags[i] | bucket ) ) != PAPI_OK ) { 00138 if (retval==PAPI_ENOSUPP) { 00139 char warning[BUFSIZ]; 00140 00141 sprintf(warning,"PAPI_profil %s not supported", 00142 profstr[i]); 00143 test_warn( __FILE__, __LINE__, warning, 1 ); 00144 } 00145 else { 00146 test_fail( __FILE__, __LINE__, "PAPI_profil", retval ); 00147 } 00148 } 00149 #else 00150 if ( ( retval = 00151 PAPI_profil( profbuf[i], ( unsigned int ) blength, start, scale, 00152 EventSet, PAPI_event, thresh, 00153 profflags[i] | bucket | PAPI_PROFIL_FORCE_SW ) ) != 00154 PAPI_OK ) { 00155 test_fail( __FILE__, __LINE__, "PAPI_profil", retval ); 00156 } 00157 #endif 00158 00159 if ( retval != PAPI_OK ) 00160 break; 00161 00162 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00163 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00164 00165 do_flops( getenv( "NUM_FLOPS" ) ? atoi( getenv( "NUM_FLOPS" ) ) : 00166 NUM_FLOPS ); 00167 00168 if ( ( retval = PAPI_stop( EventSet, values[1] ) ) != PAPI_OK ) 00169 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00170 00171 if ( !TESTS_QUIET ) { 00172 printf( TAB1, event_name, ( values[1] )[0] ); 00173 printf( TAB1, "PAPI_TOT_CYC", ( values[1] )[1] ); 00174 } 00175 if ( ( retval = 00176 PAPI_profil( profbuf[i], ( unsigned int ) blength, start, scale, 00177 EventSet, PAPI_event, 0, 00178 profflags[i] ) ) != PAPI_OK ) 00179 test_fail( __FILE__, __LINE__, "PAPI_profil", retval ); 00180 } 00181 00182 if ( retval == PAPI_OK ) { 00183 prof_head( blength, bucket, num_buckets, 00184 "address\t\t\tflat\trandom\tweight\tcomprs\tall\n" ); 00185 prof_out( start, 5, bucket, num_buckets, scale ); 00186 retval = prof_check( 5, bucket, num_buckets ); 00187 } 00188 00189 for ( i = 0; i < 5; i++ ) { 00190 free( profbuf[i] ); 00191 } 00192 00193 return ( retval ); 00194 }