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