source: CIVL/examples/omp/dataracebench-1.3.2/micro-benchmarks-fortran/utilities/fpolybench.c

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100755
File size: 9.2 KB
Line 
1/**
2 * polybench.c: This file is part of the PolyBench/Fortran 1.0 test suite.
3 *
4 *
5 * Contact: Louis-Noel Pouchet <pouchet@cse.ohio-state.edu>
6 * Web address: http://polybench.sourceforge.net
7 */
8#include <stdio.h>
9#include <string.h>
10#include <stdlib.h>
11#include <unistd.h>
12#include <assert.h>
13#include <time.h>
14#include <sys/time.h>
15#include <sys/resource.h>
16#include <sched.h>
17#include <math.h>
18#ifdef _OPENMP
19# include <omp.h>
20#endif
21#include "fpolybench.h"
22
23/* By default, collect PAPI counters on thread 0. */
24#ifndef POLYBENCH_THREAD_MONITOR
25# define POLYBENCH_THREAD_MONITOR 0
26#endif
27
28/* Total LLC cache size. By default 32+MB.. */
29#ifndef POLYBENCH_CACHE_SIZE_KB
30# define POLYBENCH_CACHE_SIZE_KB 32770
31#endif
32
33
34int polybench_papi_counters_threadid = POLYBENCH_THREAD_MONITOR;
35double polybench_program_total_flops = 0;
36
37#ifdef POLYBENCH_PAPI
38# include <papi.h>
39# define POLYBENCH_MAX_NB_PAPI_COUNTERS 96
40 char* _polybench_papi_eventlist[] = {
41#include "papi_counters.list"
42 NULL
43 };
44 int polybench_papi_eventset;
45 int polybench_papi_eventlist[POLYBENCH_MAX_NB_PAPI_COUNTERS];
46 long_long polybench_papi_values[POLYBENCH_MAX_NB_PAPI_COUNTERS];
47
48#endif
49
50
51/* Timer code (gettimeofday). */
52double polybench_t_start, polybench_t_end;
53/* Timer code (RDTSC). */
54unsigned long long int polybench_c_start, polybench_c_end;
55
56static
57double rtclock()
58{
59#ifdef POLYBENCH_TIME
60 struct timeval Tp;
61 int stat;
62 stat = gettimeofday (&Tp, NULL);
63 if (stat != 0)
64 printf ("Error return from gettimeofday: %d", stat);
65 return (Tp.tv_sec + Tp.tv_usec * 1.0e-6);
66#else
67 return 0;
68#endif
69}
70
71
72static
73unsigned long long int rdtsc()
74{
75 unsigned long long int ret = 0;
76 unsigned int cycles_lo;
77 unsigned int cycles_hi;
78
79#ifdef POLYBENCH_CYCLE_ACCURATE_TIMER
80 __asm__ volatile ("RDTSC" : "=a" (cycles_lo), "=d" (cycles_hi));
81 ret = (unsigned long long int)cycles_hi << 32 | cycles_lo;
82#endif
83
84 return ret;
85}
86
87void polybench_flush_cache()
88{
89 int cs = POLYBENCH_CACHE_SIZE_KB * 1024 / sizeof(double);
90 double* flush = (double*) calloc (cs, sizeof(double));
91 int i;
92 double tmp = 0.0;
93#ifdef _OPENMP
94#pragma omp parallel for
95#endif
96 for (i = 0; i < cs; i++)
97 tmp += flush[i];
98 assert (tmp <= 10.0);
99 free (flush);
100}
101
102
103#ifdef POLYBENCH_LINUX_FIFO_SCHEDULER
104void polybench_linux_fifo_scheduler()
105{
106 /* Use FIFO scheduler to limit OS interference. Program must be run
107 as root, and this works only for Linux kernels. */
108 struct sched_param schedParam;
109 schedParam.sched_priority = sched_get_priority_max (SCHED_FIFO);
110 sched_setscheduler (0, SCHED_FIFO, &schedParam);
111}
112
113
114void polybench_linux_standard_scheduler()
115{
116 /* Restore to standard scheduler policy. */
117 struct sched_param schedParam;
118 schedParam.sched_priority = sched_get_priority_max (SCHED_OTHER);
119 sched_setscheduler (0, SCHED_OTHER, &schedParam);
120}
121#endif
122
123#ifdef POLYBENCH_PAPI
124int
125polybench_setup_papi_event_(int *papi_evid)
126{
127 if (polybench_papi_eventlist[*papi_evid] == 0)
128 return PAPI_EVENT_END;
129
130 if(polybench_papi_start_counter(*papi_evid))
131 return PAPI_START_FAIL;
132
133 return PAPI_START_SUCCESS;
134}
135
136static
137void test_fail(char *file, int line, char *call, int retval)
138{
139 char buf[128];
140
141 memset(buf, '\0', sizeof(buf));
142 if (retval != 0)
143 fprintf (stdout,"%-40s FAILED\nLine # %d\n", file, line);
144 else
145 {
146 fprintf (stdout,"%-40s SKIPPED\n", file);
147 fprintf (stdout,"Line # %d\n", line);
148 }
149 if (retval == PAPI_ESYS)
150 {
151 sprintf (buf, "System error in %s", call);
152 perror (buf);
153 }
154 else if (retval > 0)
155 fprintf (stdout,"Error: %s\n", call);
156 else if (retval == 0)
157 fprintf (stdout,"Error: %s\n", call);
158 else
159 {
160 char errstring[PAPI_MAX_STR_LEN];
161 PAPI_perror (retval, errstring, PAPI_MAX_STR_LEN);
162 fprintf (stdout,"Error in %s: %s\n", call, errstring);
163 }
164 fprintf (stdout,"\n");
165 if (PAPI_is_initialized ())
166 PAPI_shutdown ();
167 exit (1);
168}
169
170
171void polybench_papi_init_()
172{
173# ifdef _OPENMP
174#pragma omp parallel
175 {
176#pragma omp master
177 {
178 if (omp_get_max_threads () < polybench_papi_counters_threadid)
179 polybench_papi_counters_threadid = omp_get_max_threads () - 1;
180 }
181#pragma omp barrier
182
183 if (omp_get_thread_num () == polybench_papi_counters_threadid)
184 {
185# endif
186 int retval;
187 polybench_papi_eventset = PAPI_NULL;
188 if ((retval = PAPI_library_init (PAPI_VER_CURRENT)) != PAPI_VER_CURRENT)
189 test_fail (__FILE__, __LINE__, "PAPI_library_init", retval);
190 if ((retval = PAPI_create_eventset (&polybench_papi_eventset))
191 != PAPI_OK)
192 test_fail (__FILE__, __LINE__, "PAPI_create_eventset", retval);
193 int k;
194 for (k = 0; _polybench_papi_eventlist[k]; ++k)
195 {
196 if ((retval =
197 PAPI_event_name_to_code (_polybench_papi_eventlist[k],
198 &(polybench_papi_eventlist[k])))
199 != PAPI_OK)
200 test_fail (__FILE__, __LINE__, "PAPI_event_name_to_code", retval);
201 }
202 polybench_papi_eventlist[k] = 0;
203
204
205# ifdef _OPENMP
206 }
207 }
208#pragma omp barrier
209# endif
210}
211
212
213void polybench_papi_close_()
214{
215# ifdef _OPENMP
216#pragma omp parallel
217 {
218 if (omp_get_thread_num () == polybench_papi_counters_threadid)
219 {
220# endif
221 int retval;
222 if ((retval = PAPI_destroy_eventset (&polybench_papi_eventset))
223 != PAPI_OK)
224 test_fail (__FILE__, __LINE__, "PAPI_destroy_eventset", retval);
225 if (PAPI_is_initialized ())
226 PAPI_shutdown ();
227# ifdef _OPENMP
228 }
229 }
230#pragma omp barrier
231# endif
232}
233
234int polybench_papi_start_counter(int evid)
235{
236# ifndef POLYBENCH_NO_FLUSH_CACHE
237 polybench_flush_cache();
238# endif
239
240# ifdef _OPENMP
241# pragma omp parallel
242 {
243 if (omp_get_thread_num () == polybench_papi_counters_threadid)
244 {
245# endif
246
247 int retval = 1;
248 char descr[PAPI_MAX_STR_LEN];
249 PAPI_event_info_t evinfo;
250 PAPI_event_code_to_name (polybench_papi_eventlist[evid], descr);
251 if (PAPI_add_event (polybench_papi_eventset,
252 polybench_papi_eventlist[evid]) != PAPI_OK)
253 test_fail (__FILE__, __LINE__, "PAPI_add_event", 1);
254 if (PAPI_get_event_info (polybench_papi_eventlist[evid], &evinfo)
255 != PAPI_OK)
256 test_fail (__FILE__, __LINE__, "PAPI_get_event_info", retval);
257 if ((retval = PAPI_start (polybench_papi_eventset)) != PAPI_OK)
258 test_fail (__FILE__, __LINE__, "PAPI_start", retval);
259# ifdef _OPENMP
260 }
261 }
262#pragma omp barrier
263# endif
264 return 0;
265}
266
267
268void polybench_papi_stop_counter_(int *papi_evid)
269{
270 int evid = *papi_evid;
271# ifdef _OPENMP
272# pragma omp parallel
273 {
274 if (omp_get_thread_num () == polybench_papi_counters_threadid)
275 {
276# endif
277 int retval;
278 long_long values[1];
279 values[0] = 0;
280 if ((retval = PAPI_read (polybench_papi_eventset, &values[0]))
281 != PAPI_OK)
282 test_fail (__FILE__, __LINE__, "PAPI_read", retval);
283
284 if ((retval = PAPI_stop (polybench_papi_eventset, NULL)) != PAPI_OK)
285 test_fail (__FILE__, __LINE__, "PAPI_stop", retval);
286
287 polybench_papi_values[evid] = values[0];
288
289 if ((retval = PAPI_remove_event
290 (polybench_papi_eventset,
291 polybench_papi_eventlist[evid])) != PAPI_OK)
292 test_fail (__FILE__, __LINE__, "PAPI_remove_event", retval);
293# ifdef _OPENMP
294 }
295 }
296#pragma omp barrier
297# endif
298}
299
300
301void polybench_papi_print_()
302{
303 int verbose = 0;
304# ifdef _OPENMP
305# pragma omp parallel
306 {
307 if (omp_get_thread_num() == polybench_papi_counters_threadid)
308 {
309#ifdef POLYBENCH_PAPI_VERBOSE
310 verbose = 1;
311#endif
312 if (verbose)
313 printf ("On thread %d:\n", polybench_papi_counters_threadid);
314#endif
315 int evid;
316 for (evid = 0; polybench_papi_eventlist[evid] != 0; ++evid)
317 {
318 if (verbose)
319 printf ("%s=", _polybench_papi_eventlist[evid]);
320 printf ("%llu ", polybench_papi_values[evid]);
321 if (verbose)
322 printf ("\n");
323 }
324 printf ("\n");
325# ifdef _OPENMP
326 }
327 }
328#pragma omp barrier
329# endif
330}
331
332#endif
333/* ! POLYBENCH_PAPI */
334
335void polybench_prepare_instruments_()
336{
337#ifndef POLYBENCH_NO_FLUSH_CACHE
338 polybench_flush_cache ();
339#endif
340#ifdef POLYBENCH_LINUX_FIFO_SCHEDULER
341 polybench_linux_fifo_scheduler ();
342#endif
343}
344
345
346void polybench_timer_start_()
347{
348 polybench_prepare_instruments_ ();
349#ifndef POLYBENCH_CYCLE_ACCURATE_TIMER
350 polybench_t_start = rtclock ();
351#else
352 polybench_c_start = rdtsc ();
353#endif
354}
355
356
357void polybench_timer_stop_()
358{
359#ifndef POLYBENCH_CYCLE_ACCURATE_TIMER
360 polybench_t_end = rtclock ();
361#else
362 polybench_c_end = rdtsc ();
363#endif
364#ifdef POLYBENCH_LINUX_FIFO_SCHEDULER
365 polybench_linux_standard_scheduler ();
366#endif
367}
368
369
370void polybench_timer_print_()
371{
372#ifdef POLYBENCH_GFLOPS
373 if (__polybench_program_total_flops == 0)
374 {
375 printf ("[PolyBench][WARNING] Program flops not defined, use polybench_set_program_flops(value)\n");
376 printf ("%0.6lf\n", polybench_t_end - polybench_t_start);
377 }
378 else
379 printf ("%0.2lf\n",
380 (__polybench_program_total_flops /
381 (double)(polybench_t_end - polybench_t_start)) / 1000000000);
382#else
383# ifndef POLYBENCH_CYCLE_ACCURATE_TIMER
384 printf ("%0.6f\n", polybench_t_end - polybench_t_start);
385# else
386 printf ("%Ld\n", polybench_c_end - polybench_c_start);
387# endif
388#endif
389}
390
391
392
393static
394void *
395xmalloc (size_t num)
396{
397 void* new = NULL;
398 int ret = posix_memalign (&new, 32, num);
399 if (! new || ret)
400 {
401 fprintf (stderr, "[PolyBench] posix_memalign: cannot allocate memory");
402 exit (1);
403 }
404 return new;
405}
406
407
408void* polybench_alloc_data(int n, int elt_size)
409{
410 void* ret = xmalloc (n * elt_size);
411
412 return ret;
413}
414
415void check_err_(int *err)
416{
417 if(*err != 0) {
418 printf("Allocation Error(%d) !! Exiting .... \n", *err);
419 exit(1);
420 }
421}
Note: See TracBrowser for help on using the repository browser.