PAPI  5.7.0.0
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 */
63 
65  if ( retval != PAPI_OK )
66  test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval );
67 
69 
70  do_flops( MAX_FLOPS - n ); /* prework for balance */
71 
73 
75 
77  if ( retval != PAPI_OK )
78  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
79 
80  do_flops( n );
81 
83  if ( retval != PAPI_OK )
84  test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
85 
86  flops = ( values[0] )[0];
87 
89 
91 
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); */
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 
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:29
#define PAPI_OK
Definition: fpapi.h:105
int PAPI_stop(int EventSet, long long *values)
Definition: papi.c:2314
int mask1
Definition: zero_fork.c:48
int PAPI_event[2]
Definition: data_range.c:30
#define PAPI_ENOMEM
Definition: fpapi.h:107
void test_pass(const char *filename)
Definition: test_utils.c:432
#define PAPI_EINVAL
Definition: fpapi.h:106
Hardware info structure.
Definition: papi.h:781
int num_events1
Definition: zero_fork.c:49
#define PAPI_VER_CURRENT
Definition: fpapi.h:14
#define PAPI_EBUG
Definition: fpapi.h:111
int retval
Definition: zero_fork.c:53
#define NUM_FLOPS
Definition: sdsc-mpx.c:24
void test_skip(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:561
#define PAPI_ECMP
Definition: fpapi.h:109
int PAPI_thread_init(unsigned long int(*id_fn)(void))
Definition: papi.c:123
int PAPI_library_init(int version)
Definition: papi.c:500
long long elapsed_cyc
Definition: zero_fork.c:50
const PAPI_hw_info_t * hw_info
Definition: val_omp.c:42
int TESTS_QUIET
Definition: test_utils.c:18
int add_two_events(int *num_events, int *papi_event, int *mask)
Definition: test_utils.c:617
void free_test_space(long long **values, int num_tests)
Definition: test_utils.c:70
#define PAPI_NULL
Definition: fpapi.h:13
int main(int argc, char **argv)
Definition: val_omp.c:117
int PAPI_event_code_to_name(int EventCode, char *out)
Definition: papi.c:915
long long Thread(int n)
Definition: val_omp.c:45
int num_tests
Definition: zero_fork.c:53
void do_flops(int n)
Definition: multiplex.c:23
long long PAPI_get_real_usec(void)
Definition: papi.c:6264
int PAPI_unregister_thread(void)
Definition: papi.c:244
int tests_quiet(int argc, char **argv)
Definition: test_utils.c:376
void test_fail(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:468
int rand()
long long PAPI_get_real_cyc(void)
Definition: papi.c:6217
int PAPI_start(int EventSet)
Definition: papi.c:2096
const int MAX_FLOPS
Definition: val_omp.c:39
const PAPI_hw_info_t * PAPI_get_hardware_info(void)
Definition: papi.c:6185
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
long long elapsed_us
Definition: zero_fork.c:50
long long ** allocate_test_space(int num_tests, int num_events)
Definition: test_utils.c:46
void exit()
int remove_test_events(int *EventSet, int mask)
Definition: test_utils.c:201
int EventSet1
Definition: zero_fork.c:47
int i
Definition: fileop.c:140
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43