source: CIVL/examples/omp/dataracebench-1.3.2/micro-benchmarks/utilities/polybench.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: 8.9 KB
Line 
1/**
2 * polybench.c: This file is part of the PolyBench/C 3.2 test suite.
3 *
4 *
5 * Contact: Louis-Noel Pouchet <pouchet@cse.ohio-state.edu>
6 * Web address: http://polybench.sourceforge.net
7 * License: /LICENSE.OSU.txt
8 */
9#include <stdio.h>
10#include <string.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <assert.h>
14#include <time.h>
15#include <sys/time.h>
16#include <sys/resource.h>
17#include <sched.h>
18#include <math.h>
19#ifdef _OPENMP
20# include <omp.h>
21#endif
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
72#ifdef POLYBENCH_CYCLE_ACCURATE_TIMER
73static
74unsigned long long int rdtsc()
75{
76 unsigned long long int ret = 0;
77 unsigned int cycles_lo;
78 unsigned int cycles_hi;
79 __asm__ volatile ("RDTSC" : "=a" (cycles_lo), "=d" (cycles_hi));
80 ret = (unsigned long long int)cycles_hi << 32 | cycles_lo;
81
82 return ret;
83}
84#endif
85
86void polybench_flush_cache()
87{
88 int cs = POLYBENCH_CACHE_SIZE_KB * 1024 / sizeof(double);
89 double* flush = (double*) calloc (cs, sizeof(double));
90 int i;
91 double tmp = 0.0;
92#ifdef _OPENMP
93#pragma omp parallel for reduction(+:tmp)
94#endif
95 for (i = 0; i < cs; i++)
96 tmp += flush[i];
97 assert (tmp <= 10.0);
98 free (flush);
99}
100
101
102#ifdef POLYBENCH_LINUX_FIFO_SCHEDULER
103void polybench_linux_fifo_scheduler()
104{
105 /* Use FIFO scheduler to limit OS interference. Program must be run
106 as root, and this works only for Linux kernels. */
107 struct sched_param schedParam;
108 schedParam.sched_priority = sched_get_priority_max (SCHED_FIFO);
109 sched_setscheduler (0, SCHED_FIFO, &schedParam);
110}
111
112
113void polybench_linux_standard_scheduler()
114{
115 /* Restore to standard scheduler policy. */
116 struct sched_param schedParam;
117 schedParam.sched_priority = sched_get_priority_max (SCHED_OTHER);
118 sched_setscheduler (0, SCHED_OTHER, &schedParam);
119}
120#endif
121
122#ifdef POLYBENCH_PAPI
123
124static
125void test_fail(char *file, int line, char *call, int retval)
126{
127 char buf[128];
128
129 memset(buf, '\0', sizeof(buf));
130 if (retval != 0)
131 fprintf (stdout,"%-40s FAILED\nLine # %d\n", file, line);
132 else
133 {
134 fprintf (stdout,"%-40s SKIPPED\n", file);
135 fprintf (stdout,"Line # %d\n", line);
136 }
137 if (retval == PAPI_ESYS)
138 {
139 sprintf (buf, "System error in %s", call);
140 perror (buf);
141 }
142 else if (retval > 0)
143 fprintf (stdout,"Error: %s\n", call);
144 else if (retval == 0)
145 fprintf (stdout,"Error: %s\n", call);
146 else
147 {
148 char errstring[PAPI_MAX_STR_LEN];
149 PAPI_perror (retval, errstring, PAPI_MAX_STR_LEN);
150 fprintf (stdout,"Error in %s: %s\n", call, errstring);
151 }
152 fprintf (stdout,"\n");
153 if (PAPI_is_initialized ())
154 PAPI_shutdown ();
155 exit (1);
156}
157
158
159void polybench_papi_init()
160{
161# ifdef _OPENMP
162#pragma omp parallel
163 {
164#pragma omp master
165 {
166 if (omp_get_max_threads () < polybench_papi_counters_threadid)
167 polybench_papi_counters_threadid = omp_get_max_threads () - 1;
168 }
169#pragma omp barrier
170
171 if (omp_get_thread_num () == polybench_papi_counters_threadid)
172 {
173# endif
174 int retval;
175 polybench_papi_eventset = PAPI_NULL;
176 if ((retval = PAPI_library_init (PAPI_VER_CURRENT)) != PAPI_VER_CURRENT)
177 test_fail (__FILE__, __LINE__, "PAPI_library_init", retval);
178 if ((retval = PAPI_create_eventset (&polybench_papi_eventset))
179 != PAPI_OK)
180 test_fail (__FILE__, __LINE__, "PAPI_create_eventset", retval);
181 int k;
182 for (k = 0; _polybench_papi_eventlist[k]; ++k)
183 {
184 if ((retval =
185 PAPI_event_name_to_code (_polybench_papi_eventlist[k],
186 &(polybench_papi_eventlist[k])))
187 != PAPI_OK)
188 test_fail (__FILE__, __LINE__, "PAPI_event_name_to_code", retval);
189 }
190 polybench_papi_eventlist[k] = 0;
191
192
193# ifdef _OPENMP
194 }
195 }
196#pragma omp barrier
197# endif
198}
199
200
201void polybench_papi_close()
202{
203# ifdef _OPENMP
204#pragma omp parallel
205 {
206 if (omp_get_thread_num () == polybench_papi_counters_threadid)
207 {
208# endif
209 int retval;
210 if ((retval = PAPI_destroy_eventset (&polybench_papi_eventset))
211 != PAPI_OK)
212 test_fail (__FILE__, __LINE__, "PAPI_destroy_eventset", retval);
213 if (PAPI_is_initialized ())
214 PAPI_shutdown ();
215# ifdef _OPENMP
216 }
217 }
218#pragma omp barrier
219# endif
220}
221
222int polybench_papi_start_counter(int evid)
223{
224# ifndef POLYBENCH_NO_FLUSH_CACHE
225 polybench_flush_cache();
226# endif
227
228# ifdef _OPENMP
229# pragma omp parallel
230 {
231 if (omp_get_thread_num () == polybench_papi_counters_threadid)
232 {
233# endif
234
235 int retval = 1;
236 char descr[PAPI_MAX_STR_LEN];
237 PAPI_event_info_t evinfo;
238 PAPI_event_code_to_name (polybench_papi_eventlist[evid], descr);
239 if (PAPI_add_event (polybench_papi_eventset,
240 polybench_papi_eventlist[evid]) != PAPI_OK)
241 test_fail (__FILE__, __LINE__, "PAPI_add_event", 1);
242 if (PAPI_get_event_info (polybench_papi_eventlist[evid], &evinfo)
243 != PAPI_OK)
244 test_fail (__FILE__, __LINE__, "PAPI_get_event_info", retval);
245 if ((retval = PAPI_start (polybench_papi_eventset)) != PAPI_OK)
246 test_fail (__FILE__, __LINE__, "PAPI_start", retval);
247# ifdef _OPENMP
248 }
249 }
250#pragma omp barrier
251# endif
252 return 0;
253}
254
255
256void polybench_papi_stop_counter(int evid)
257{
258# ifdef _OPENMP
259# pragma omp parallel
260 {
261 if (omp_get_thread_num () == polybench_papi_counters_threadid)
262 {
263# endif
264 int retval;
265 long_long values[1];
266 values[0] = 0;
267 if ((retval = PAPI_read (polybench_papi_eventset, &values[0]))
268 != PAPI_OK)
269 test_fail (__FILE__, __LINE__, "PAPI_read", retval);
270
271 if ((retval = PAPI_stop (polybench_papi_eventset, NULL)) != PAPI_OK)
272 test_fail (__FILE__, __LINE__, "PAPI_stop", retval);
273
274 polybench_papi_values[evid] = values[0];
275
276 if ((retval = PAPI_remove_event
277 (polybench_papi_eventset,
278 polybench_papi_eventlist[evid])) != PAPI_OK)
279 test_fail (__FILE__, __LINE__, "PAPI_remove_event", retval);
280# ifdef _OPENMP
281 }
282 }
283#pragma omp barrier
284# endif
285}
286
287
288void polybench_papi_print()
289{
290 int verbose = 0;
291# ifdef _OPENMP
292# pragma omp parallel
293 {
294 if (omp_get_thread_num() == polybench_papi_counters_threadid)
295 {
296#ifdef POLYBENCH_PAPI_VERBOSE
297 verbose = 1;
298#endif
299 if (verbose)
300 printf ("On thread %d:\n", polybench_papi_counters_threadid);
301#endif
302 int evid;
303 for (evid = 0; polybench_papi_eventlist[evid] != 0; ++evid)
304 {
305 if (verbose)
306 printf ("%s=", _polybench_papi_eventlist[evid]);
307 printf ("%llu ", polybench_papi_values[evid]);
308 if (verbose)
309 printf ("\n");
310 }
311 printf ("\n");
312# ifdef _OPENMP
313 }
314 }
315#pragma omp barrier
316# endif
317}
318
319#endif
320/* ! POLYBENCH_PAPI */
321
322void polybench_prepare_instruments()
323{
324#ifndef POLYBENCH_NO_FLUSH_CACHE
325 polybench_flush_cache ();
326#endif
327#ifdef POLYBENCH_LINUX_FIFO_SCHEDULER
328 polybench_linux_fifo_scheduler ();
329#endif
330}
331
332
333void polybench_timer_start()
334{
335 polybench_prepare_instruments ();
336#ifndef POLYBENCH_CYCLE_ACCURATE_TIMER
337 polybench_t_start = rtclock ();
338#else
339 polybench_c_start = rdtsc ();
340#endif
341}
342
343
344void polybench_timer_stop()
345{
346#ifndef POLYBENCH_CYCLE_ACCURATE_TIMER
347 polybench_t_end = rtclock ();
348#else
349 polybench_c_end = rdtsc ();
350#endif
351#ifdef POLYBENCH_LINUX_FIFO_SCHEDULER
352 polybench_linux_standard_scheduler ();
353#endif
354}
355
356
357void polybench_timer_print()
358{
359#ifdef POLYBENCH_GFLOPS
360 if (__polybench_program_total_flops == 0)
361 {
362 printf ("[PolyBench][WARNING] Program flops not defined, use polybench_set_program_flops(value)\n");
363 printf ("%0.6lf\n", polybench_t_end - polybench_t_start);
364 }
365 else
366 printf ("%0.2lf\n",
367 (__polybench_program_total_flops /
368 (double)(polybench_t_end - polybench_t_start)) / 1000000000);
369#else
370# ifndef POLYBENCH_CYCLE_ACCURATE_TIMER
371 printf ("%0.6f\n", polybench_t_end - polybench_t_start);
372# else
373 printf ("%Ld\n", polybench_c_end - polybench_c_start);
374# endif
375#endif
376}
377
378
379
380static
381void *
382xmalloc (size_t num)
383{
384 void* nnew = NULL;
385 int ret = posix_memalign (&nnew, 32, num);
386 if (! nnew || ret)
387 {
388 fprintf (stderr, "[PolyBench] posix_memalign: cannot allocate memory");
389 exit (1);
390 }
391 return nnew;
392}
393
394
395void* polybench_alloc_data(unsigned long long int n, int elt_size)
396{
397 /// FIXME: detect overflow!
398 size_t val = n;
399 val *= elt_size;
400 void* ret = xmalloc (val);
401
402 return ret;
403}
Note: See TracBrowser for help on using the repository browser.