PAPI  5.3.2.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
prof_utils.c
Go to the documentation of this file.
1 /*
2 * File: prof_utils.c
3 * CVS: $Id$
4 * Author: Dan Terpstra
5 * terpstra@cs.utk.edu
6 * Mods: <your name here>
7 * <your email address>
8 */
9 
10 /* This file contains utility functions useful for all profiling tests
11  It can be used by:
12  - profile.c,
13  - sprofile.c,
14  - profile_pthreads.c,
15  - profile_twoevents.c,
16  - earprofile.c,
17  - future profiling tests.
18 */
19 
20 #include "papi_test.h"
21 #include "prof_utils.h"
22 
23 /* variables global to profiling tests */
24 long long **values;
28 void *profbuf[5];
29 
30 /* This function does the generic initialization stuff found at the top of most
31  profile tests (most tests in general). This includes:
32  - setting the QUIET flag;
33  - initing the PAPI library;
34  - setting the debug level;
35  - getting hardware and executable info.
36  It assumes that prginfo is global to the parent routine.
37 */
38 void
39 prof_init( int argc, char **argv, const PAPI_exe_info_t ** prginfo )
40 {
41  int retval;
42 
43  tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */
44 
45  if ( ( retval =
47  test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
48 
49  if ( ( *prginfo = PAPI_get_executable_info( ) ) == NULL )
50  test_fail( __FILE__, __LINE__, "PAPI_get_executable_info", 1 );
51 }
52 
53 /* Many profiling tests count one of {FP_INS, FP_OPS, TOT_INS} and TOT_CYC.
54  This function creates an event set containing the appropriate pair of events.
55  It also initializes the global event_name string to the event selected.
56  Assumed globals: EventSet, PAPI_event, event_name.
57 */
58 int
60 {
61  int retval;
62  int num_events, mask;
63 
64  /* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or
65  PAPI_TOT_INS, depends on the availability of the event on the
66  platform */
67  EventSet =
68  add_two_nonderived_events( &num_events, &PAPI_event, &mask );
69 
70  values = allocate_test_space( num_tests, num_events );
71 
72  if ( ( retval =
74  test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval );
75 
76  return ( mask );
77 }
78 
79 /* This function displays info from the prginfo structure in a standardized format.
80 */
81 void
82 prof_print_address( char *title, const PAPI_exe_info_t * prginfo )
83 {
84  printf( "%s\n", title );
85  printf
86  ( "----------------------------------------------------------------\n" );
87  printf( "Text start: %p, Text end: %p, Text length: %#x\n",
88  prginfo->address_info.text_start, prginfo->address_info.text_end,
89  ( unsigned int ) ( prginfo->address_info.text_end -
90  prginfo->address_info.text_start ) );
91  printf( "Data start: %p, Data end: %p\n", prginfo->address_info.data_start,
92  prginfo->address_info.data_end );
93  printf( "BSS start : %p, BSS end : %p\n", prginfo->address_info.bss_start,
94  prginfo->address_info.bss_end );
95 
96  printf
97  ( "----------------------------------------------------------------\n" );
98 }
99 
100 /* This function displays profining information useful for several profile tests.
101  It (probably inappropriately) assumes use of a common THRESHOLD. This should
102  probably be a passed parameter.
103  Assumed globals: event_name, start, stop.
104 */
105 void
106 prof_print_prof_info( caddr_t start, caddr_t end, int threshold,
107  char *event_name )
108 {
109  printf( "Profiling event : %s\n", event_name );
110  printf( "Profile Threshold: %d\n", threshold );
111  printf( "Profile Iters : %d\n",
112  ( getenv( "NUM_ITERS" ) ? atoi( getenv( "NUM_ITERS" ) ) :
113  NUM_ITERS ) );
114  printf( "Profile Range : %p to %p\n", start, end );
115  printf
116  ( "----------------------------------------------------------------\n" );
117  printf( "\n" );
118 }
119 
120 /* Most profile tests begin by counting the eventset with no profiling enabled.
121  This function does that work. It assumes that the 'work' routine is do_both().
122  A better implementation would pass a pointer to the work function.
123  Assumed globals: EventSet, values, event_name.
124 */
125 void
127 {
128  int retval;
129 
130  if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
131  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
132 
133  do_flops( getenv( "NUM_ITERS" ) ? atoi( getenv( "NUM_ITERS" ) ) :
134  NUM_ITERS );
135 
136  if ( ( retval = PAPI_stop( EventSet, values[0] ) ) != PAPI_OK )
137  test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
138 
139  printf( "Test type : \t%s\n", "No profiling" );
140  printf( TAB1, event_name, ( values[0] )[0] );
141  printf( TAB1, "PAPI_TOT_CYC", ( values[0] )[1] );
142 }
143 
144 /* This routine allocates and initializes up to 5 equal sized profiling buffers.
145  They need to be freed when profiling is completed.
146  The number and size are passed parameters.
147  The profbuf[] array of void * pointers is an assumed global.
148  It should be cast to the required type by the parent routine.
149 */
150 void
151 prof_alloc( int num, unsigned long blength )
152 {
153  int i;
154 
155  for ( i = 0; i < num; i++ ) {
156  profbuf[i] = malloc( blength );
157  if ( profbuf[i] == NULL ) {
158  test_fail( __FILE__, __LINE__, "malloc", PAPI_ESYS );
159  }
160  memset( profbuf[i], 0x00, blength );
161  }
162 }
163 
164 /* Given the profiling type (16, 32, or 64) this function returns the
165  bucket size in bytes. NOTE: the bucket size does not ALWAYS correspond
166  to the expected value, esp on architectures like Cray with weird data types.
167  This is necessary because the posix_profile routine in extras.c relies on
168  the data types and sizes produced by the compiler.
169 */
170 int
171 prof_buckets( int bucket )
172 {
173  int bucket_size;
174  switch ( bucket ) {
176  bucket_size = sizeof ( short );
177  break;
179  bucket_size = sizeof ( int );
180  break;
182  bucket_size = sizeof ( unsigned long long );
183  break;
184  default:
185  bucket_size = 0;
186  break;
187  }
188  return ( bucket_size );
189 }
190 
191 /* A standardized header printing routine. No assumed globals.
192 */
193 void
194 prof_head( unsigned long blength, int bucket, int num_buckets, char *header )
195 {
196  int bucket_size = prof_buckets( bucket );
197  printf
198  ( "\n------------------------------------------------------------\n" );
199  printf( "PAPI_profil() hash table, Bucket size: %d bits.\n",
200  bucket_size * 8 );
201  printf( "Number of buckets: %d.\nLength of buffer: %ld bytes.\n",
202  num_buckets, blength );
203  printf( "------------------------------------------------------------\n" );
204  printf( "%s\n", header );
205 }
206 
207 /* This function prints a standardized profile output based on the bucket size.
208  A row consisting of an address and 'n' data elements is displayed for each
209  address with at least one non-zero bucket.
210  Assumes global profbuf[] array pointers.
211 */
212 void
213 prof_out( caddr_t start, int n, int bucket, int num_buckets,
214  unsigned int scale )
215 {
216  int i, j;
217  unsigned short buf_16;
218  unsigned int buf_32;
219  unsigned long long buf_64;
220  unsigned short **buf16 = ( unsigned short ** ) profbuf;
221  unsigned int **buf32 = ( unsigned int ** ) profbuf;
222  unsigned long long **buf64 = ( unsigned long long ** ) profbuf;
223 
224  if ( !TESTS_QUIET ) {
225  /* printf("%#lx\n",(unsigned long) start + (unsigned long) (2 * i)); */
226  /* printf("start: %p; i: %#x; scale: %#x; i*scale: %#x; i*scale >>15: %#x\n", start, i, scale, i*scale, (i*scale)>>15); */
227  switch ( bucket ) {
229  for ( i = 0; i < num_buckets; i++ ) {
230  for ( j = 0, buf_16 = 0; j < n; j++ )
231  buf_16 |= ( buf16[j] )[i];
232  if ( buf_16 ) {
233 /* On 32bit builds with gcc 4.3 gcc complained about casting caddr_t => long long
234  * Thus the unsigned long to long long cast */
235  printf( "%#-16llx",
236  (long long) (unsigned long)start +
237  ( ( ( long long ) i * scale ) >> 15 ) );
238  for ( j = 0, buf_16 = 0; j < n; j++ )
239  printf( "\t%d", ( buf16[j] )[i] );
240  printf( "\n" );
241  }
242  }
243  break;
245  for ( i = 0; i < num_buckets; i++ ) {
246  for ( j = 0, buf_32 = 0; j < n; j++ )
247  buf_32 |= ( buf32[j] )[i];
248  if ( buf_32 ) {
249  printf( "%#-16llx",
250  (long long) (unsigned long)start +
251  ( ( ( long long ) i * scale ) >> 15 ) );
252  for ( j = 0, buf_32 = 0; j < n; j++ )
253  printf( "\t%d", ( buf32[j] )[i] );
254  printf( "\n" );
255  }
256  }
257  break;
259  for ( i = 0; i < num_buckets; i++ ) {
260  for ( j = 0, buf_64 = 0; j < n; j++ )
261  buf_64 |= ( buf64[j] )[i];
262  if ( buf_64 ) {
263  printf( "%#-16llx",
264  (long long) (unsigned long)start +
265  ( ( ( long long ) i * scale ) >> 15 ) );
266  for ( j = 0, buf_64 = 0; j < n; j++ )
267  printf( "\t%lld", ( buf64[j] )[i] );
268  printf( "\n" );
269  }
270  }
271  break;
272  }
273  printf
274  ( "------------------------------------------------------------\n\n" );
275  }
276 }
277 
278 /* This function checks to make sure that some buffer value somewhere is nonzero.
279  If all buffers are empty, zero is returned. This usually indicates a profiling
280  failure. Assumes global profbuf[].
281 */
282 int
283 prof_check( int n, int bucket, int num_buckets )
284 {
285  int i, j;
286  int retval = 0;
287  unsigned short **buf16 = ( unsigned short ** ) profbuf;
288  unsigned int **buf32 = ( unsigned int ** ) profbuf;
289  unsigned long long **buf64 = ( unsigned long long ** ) profbuf;
290 
291  switch ( bucket ) {
293  for ( i = 0; i < num_buckets; i++ )
294  for ( j = 0; j < n; j++ )
295  retval = retval || buf16[j][i];
296  break;
298  for ( i = 0; i < num_buckets; i++ )
299  for ( j = 0; j < n; j++ )
300  retval = retval || buf32[j][i];
301  break;
303  for ( i = 0; i < num_buckets; i++ )
304  for ( j = 0; j < n; j++ )
305  retval = retval || buf64[j][i];
306  break;
307  }
308  return ( retval );
309 }
310 
311 /* Computes the length (in bytes) of the buffer required for profiling.
312  'plength' is the profile length, or address range to be profiled.
313  By convention, it is assumed that there are half as many buckets as addresses.
314  The scale factor is a fixed point fraction in which 0xffff = ~1
315  0x8000 = 1/2
316  0x4000 = 1/4, etc.
317  Thus, the number of profile buckets is (plength/2) * (scale/65536),
318  and the length (in bytes) of the profile buffer is buckets * bucket size.
319  */
320 unsigned long
321 prof_size( unsigned long plength, unsigned scale, int bucket, int *num_buckets )
322 {
323  unsigned long blength;
324  long long llength = ( ( long long ) plength * scale );
325  int bucket_size = prof_buckets( bucket );
326  *num_buckets = ( int ) ( llength / 65536 / 2 );
327  blength = ( unsigned long ) ( *num_buckets * bucket_size );
328  return ( blength );
329 }
char event_name[2][PAPI_MAX_STR_LEN]
Definition: data_range.c:23
int atoi()
memset(eventId, 0, size)
int PAPI_stop(int EventSet, long long *values)
Definition: papi.c:2232
int PAPI_event[2]
Definition: data_range.c:24
void prof_print_address(char *title, const PAPI_exe_info_t *prginfo)
Definition: prof_utils.c:82
char * getenv()
void prof_head(unsigned long blength, int bucket, int num_buckets, char *header)
Definition: prof_utils.c:194
#define PAPI_NULL
Definition: fpapi.h:13
caddr_t text_end
Definition: papi.h:693
#define NUM_ITERS
Definition: multiplex.c:19
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43
start
Definition: iozone.c:22736
#define TAB1
Definition: papi_test.h:112
int num_events
get the executable&#39;s info
Definition: papi.h:702
return PAPI_OK
Definition: linux-nvml.c:458
caddr_t bss_start
Definition: papi.h:696
tests_quiet(argc, argv)
#define printf
Definition: papi_test.h:125
int int argc
Definition: iozone.c:1609
int TESTS_QUIET
Definition: test_utils.c:11
char ** argv
Definition: iozone.c:1610
void do_no_profile(void)
Definition: prof_utils.c:126
unsigned long prof_size(unsigned long plength, unsigned scale, int bucket, int *num_buckets)
Definition: prof_utils.c:321
test_fail(__FILE__, __LINE__,"PAPI_library_init", retval)
int PAPI_library_init(int version)
Definition: papi.c:495
int i
Definition: fileop.c:140
void prof_out(caddr_t start, int n, int bucket, int num_buckets, unsigned int scale)
Definition: prof_utils.c:213
const PAPI_exe_info_t * PAPI_get_executable_info(void)
Definition: papi.c:5988
caddr_t text_start
Definition: papi.h:692
PAPI_address_map_t address_info
Definition: papi.h:704
void int num
Definition: iozone.c:22151
#define PAPI_PROFIL_BUCKET_64
Definition: fpapi.h:81
#define PAPI_PROFIL_BUCKET_16
Definition: fpapi.h:79
void * profbuf[5]
Definition: prof_utils.c:28
#define PAPI_VER_CURRENT
Definition: fpapi.h:14
long long
Definition: iozone.c:19827
int PAPI_event_code_to_name(int EventCode, char *out)
Definition: papi.c:924
#define PAPI_ESYS
Definition: fpapi.h:108
int threshold
int num_tests
Definition: zero_fork.c:46
caddr_t data_start
Definition: papi.h:694
void do_flops(int n)
Definition: multiplex.c:23
int EventSet
int prof_buckets(int bucket)
Definition: prof_utils.c:171
void prof_init(int argc, char **argv, const PAPI_exe_info_t **prginfo)
Definition: prof_utils.c:39
int
Definition: iozone.c:18528
caddr_t bss_end
Definition: papi.h:697
void prof_print_prof_info(caddr_t start, caddr_t end, int threshold, char *event_name)
Definition: prof_utils.c:106
caddr_t data_end
Definition: papi.h:695
int prof_check(int n, int bucket, int num_buckets)
Definition: prof_utils.c:283
int prof_events(int num_tests)
Definition: prof_utils.c:59
int add_two_nonderived_events(int *num_events, int *papi_event, int *mask)
Definition: test_utils.c:723
#define PAPI_PROFIL_BUCKET_32
Definition: fpapi.h:80
int PAPI_start(int EventSet)
Definition: papi.c:2026
long j
Definition: iozone.c:19135
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
ssize_t retval
Definition: libasync.c:338
long long ** allocate_test_space(int num_tests, int num_events)
Definition: test_utils.c:107
void prof_alloc(int num, unsigned long blength)
Definition: prof_utils.c:151
int n
Definition: mendes-alt.c:164