PAPI  5.3.2.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
val_omp.c
Go to the documentation of this file.
1 /* This file performs the following test: each OMP thread measures flops
2 for its provided tasks, and compares this to expected flop counts, each
3 thread having been provided with a random amount of work, such that the
4 time and order that they complete their measurements varies.
5 Specifically tested is the case where the value returned for some threads
6 actually corresponds to that for another thread reading its counter values
7 at the same time.
8 
9  - It is based on zero_omp.c but ignored much of its functionality.
10  - It attempts to use the following two counters. It may use less
11 depending on hardware counter resource limitations. These are counted
12 in the default counting domain and default granularity, depending on
13 the platform. Usually this is the user domain (PAPI_DOM_USER) and
14 thread context (PAPI_GRN_THR).
15 
16  + PAPI_FP_INS
17  + PAPI_TOT_CYC
18 
19 Each thread inside the Thread routine:
20  - Do prework (MAX_FLOPS - flops)
21  - Get cyc.
22  - Get us.
23  - Start counters
24  - Do flops
25  - Stop and read counters
26  - Get us.
27  - Get cyc.
28  - Return flops
29 */
30 
31 #include "papi_test.h"
32 
33 #ifdef _OPENMP
34 #include <omp.h>
35 #else
36 #error "This compiler does not understand OPENMP"
37 #endif
38 
39 const int MAX_FLOPS = NUM_FLOPS;
40 
41 extern int TESTS_QUIET; /* Declared in test_utils.c */
42 const PAPI_hw_info_t *hw_info = NULL;
43 
44 long long
45 Thread( int n )
46 {
47  int retval, num_tests = 1;
48  int EventSet1 = PAPI_NULL;
49  int PAPI_event, mask1;
50  int num_events1;
51  long long flops;
52  long long **values;
53  long long elapsed_us, elapsed_cyc;
55 
56  /* printf("Thread(n=%d) %#x started\n", n, omp_get_thread_num()); */
57  num_events1 = 2;
58 
59  /* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or
60  PAPI_TOT_INS, depending on the availability of the event on the
61  platform */
62  EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 );
63 
64  retval = PAPI_event_code_to_name( PAPI_event, event_name );
65  if ( retval != PAPI_OK )
66  test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval );
67 
68  values = allocate_test_space( num_tests, num_events1 );
69 
70  do_flops( MAX_FLOPS - n ); /* prework for balance */
71 
72  elapsed_us = PAPI_get_real_usec( );
73 
74  elapsed_cyc = PAPI_get_real_cyc( );
75 
76  retval = PAPI_start( EventSet1 );
77  if ( retval != PAPI_OK )
78  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
79 
80  do_flops( n );
81 
82  retval = PAPI_stop( EventSet1, values[0] );
83  if ( retval != PAPI_OK )
84  test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
85 
86  flops = ( values[0] )[0];
87 
88  elapsed_us = PAPI_get_real_usec( ) - elapsed_us;
89 
90  elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc;
91 
92  remove_test_events( &EventSet1, mask1 );
93 
94  if ( !TESTS_QUIET ) {
95  /*printf("Thread %#x %-12s : \t%lld\t%d\n", omp_get_thread_num(), event_name,
96  (values[0])[0], n); */
97 #if 0
98  printf( "Thread %#x PAPI_TOT_CYC: \t%lld\n", omp_get_thread_num( ),
99  values[0][0] );
100  printf( "Thread %#x Real usec : \t%lld\n", omp_get_thread_num( ),
101  elapsed_us );
102  printf( "Thread %#x Real cycles : \t%lld\n", omp_get_thread_num( ),
103  elapsed_cyc );
104 #endif
105  }
106 
107  /* It is illegal for the threads to exit in OpenMP */
108  /* test_pass(__FILE__,0,0); */
109  free_test_space( values, num_tests );
110 
112  /* printf("Thread %#x finished\n", omp_get_thread_num()); */
113  return flops;
114 }
115 
116 int
117 main( int argc, char **argv )
118 {
119  int tid, retval;
120  int maxthr = omp_get_max_threads( );
121  int flopper = 0;
122  long long *flops = calloc( maxthr, sizeof ( long long ) );
123  long long *flopi = calloc( maxthr, sizeof ( long long ) );
124 
125  tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */
126 
127  if ( maxthr < 2 )
128  test_skip( __FILE__, __LINE__, "omp_get_num_threads < 2", PAPI_EINVAL );
129 
130  if ( ( flops == NULL ) || ( flopi == NULL ) )
131  test_fail( __FILE__, __LINE__, "calloc", PAPI_ENOMEM );
132 
134  if ( retval != PAPI_VER_CURRENT )
135  test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
136 
137  hw_info = PAPI_get_hardware_info( );
138  if ( hw_info == NULL )
139  test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 );
140 
141  retval =
142  PAPI_thread_init( ( unsigned
143  long ( * )( void ) ) ( omp_get_thread_num ) );
144  if ( retval != PAPI_OK )
145  if ( retval == PAPI_ECMP )
146  test_skip( __FILE__, __LINE__, "PAPI_thread_init", retval );
147  else
148  test_fail( __FILE__, __LINE__, "PAPI_thread_init", retval );
149 
150  flopper = Thread( 65536 ) / 65536;
151  printf( "flopper=%d\n", flopper );
152 
153  for ( int i = 0; i < 100000; i++ )
154 #pragma omp parallel private(tid)
155  {
156  tid = omp_get_thread_num( );
157  flopi[tid] = rand( ) * 3;
158  flops[tid] = Thread( ( flopi[tid] / flopper ) % MAX_FLOPS );
159 #pragma omp barrier
160 #pragma omp master
161  if ( flops[tid] < flopi[tid] ) {
162  printf( "test iteration=%d\n", i );
163  for ( int j = 0; j < omp_get_num_threads( ); j++ ) {
164  printf( "Thread %#x Value %6lld %c %6lld", j, flops[j],
165  ( flops[j] < flopi[j] ) ? '<' : '=', flopi[j] );
166  for ( int k = 0; k < omp_get_num_threads( ); k++ )
167  if ( ( k != j ) && ( flops[k] == flops[j] ) )
168  printf( " == Thread %#x!", k );
169  printf( "\n" );
170  }
171  test_fail( __FILE__, __LINE__, "value returned for thread",
172  PAPI_EBUG );
173  }
174  }
175 
176  test_pass( __FILE__, NULL, 0 );
177  exit( 0 );
178 }
char event_name[2][PAPI_MAX_STR_LEN]
Definition: data_range.c:23
int PAPI_stop(int EventSet, long long *values)
Definition: papi.c:2232
#define NUM_FLOPS
int mask1
Definition: zero_fork.c:41
#define PAPI_ENOMEM
Definition: fpapi.h:107
int PAPI_event[2]
Definition: data_range.c:24
Hardware info structure.
Definition: papi.h:775
#define PAPI_NULL
Definition: fpapi.h:13
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43
void test_skip(char *file, int line, char *call, int retval)
Definition: test_utils.c:614
int num_events1
Definition: zero_fork.c:42
return PAPI_OK
Definition: linux-nvml.c:458
tests_quiet(argc, argv)
return PAPI_EINVAL
Definition: linux-nvml.c:408
#define printf
Definition: papi_test.h:125
test_pass(__FILE__, NULL, 0)
int int argc
Definition: iozone.c:1609
int TESTS_QUIET
Definition: test_utils.c:11
char ** argv
Definition: iozone.c:1610
test_fail(__FILE__, __LINE__,"PAPI_library_init", retval)
int PAPI_thread_init(unsigned long int(*id_fn)(void))
Definition: papi.c:118
int PAPI_library_init(int version)
Definition: papi.c:495
int i
Definition: fileop.c:140
long long elapsed_cyc
Definition: zero_fork.c:43
int k
Definition: iozone.c:19136
#define PAPI_ECMP
Definition: fpapi.h:109
void *long long tid
Definition: iozone.c:18586
int add_two_events(int *num_events, int *papi_event, int *mask)
Definition: test_utils.c:680
#define PAPI_VER_CURRENT
Definition: fpapi.h:14
void free_test_space(long long **values, int num_tests)
Definition: test_utils.c:131
void * Thread(void *arg)
int PAPI_event_code_to_name(int EventCode, char *out)
Definition: papi.c:924
int num_tests
Definition: zero_fork.c:46
void do_flops(int n)
Definition: multiplex.c:23
#define PAPI_EBUG
Definition: fpapi.h:111
long long PAPI_get_real_usec(void)
Definition: papi.c:6138
int PAPI_unregister_thread(void)
Definition: papi.c:239
int rand()
long long PAPI_get_real_cyc(void)
Definition: papi.c:6091
int PAPI_start(int EventSet)
Definition: papi.c:2026
const int MAX_FLOPS
Definition: val_omp.c:39
long j
Definition: iozone.c:19135
const PAPI_hw_info_t * PAPI_get_hardware_info(void)
Definition: papi.c:6059
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
ssize_t retval
Definition: libasync.c:338
long long elapsed_us
Definition: zero_fork.c:43
long long ** allocate_test_space(int num_tests, int num_events)
Definition: test_utils.c:107
static const PAPI_hw_info_t * hw_info
Definition: byte_profile.c:23
int main(int argc, char **argv)
List all appio events codes and names.
void exit()
int remove_test_events(int *EventSet, int mask)
Definition: test_utils.c:277
int EventSet1
Definition: zero_fork.c:40
int n
Definition: mendes-alt.c:164