cannam@127
|
1 /*
|
cannam@127
|
2 * Copyright (c) 2001 Matteo Frigo
|
cannam@127
|
3 * Copyright (c) 2001 Massachusetts Institute of Technology
|
cannam@127
|
4 *
|
cannam@127
|
5 * This program is free software; you can redistribute it and/or modify
|
cannam@127
|
6 * it under the terms of the GNU General Public License as published by
|
cannam@127
|
7 * the Free Software Foundation; either version 2 of the License, or
|
cannam@127
|
8 * (at your option) any later version.
|
cannam@127
|
9 *
|
cannam@127
|
10 * This program is distributed in the hope that it will be useful,
|
cannam@127
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
cannam@127
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
cannam@127
|
13 * GNU General Public License for more details.
|
cannam@127
|
14 *
|
cannam@127
|
15 * You should have received a copy of the GNU General Public License
|
cannam@127
|
16 * along with this program; if not, write to the Free Software
|
cannam@127
|
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
cannam@127
|
18 *
|
cannam@127
|
19 */
|
cannam@127
|
20
|
cannam@127
|
21 #ifndef __BENCH_USER_H__
|
cannam@127
|
22 #define __BENCH_USER_H__
|
cannam@127
|
23
|
cannam@127
|
24 #ifdef __cplusplus
|
cannam@127
|
25 extern "C" {
|
cannam@127
|
26 #endif /* __cplusplus */
|
cannam@127
|
27
|
cannam@127
|
28 /* benchmark program definitions for user code */
|
cannam@127
|
29 #include "config.h"
|
cannam@127
|
30 #include <limits.h>
|
cannam@127
|
31
|
cannam@127
|
32 #if HAVE_STDDEF_H
|
cannam@127
|
33 #include <stddef.h>
|
cannam@127
|
34 #endif
|
cannam@127
|
35
|
cannam@127
|
36 #if HAVE_STDLIB_H
|
cannam@127
|
37 #include <stdlib.h>
|
cannam@127
|
38 #endif
|
cannam@127
|
39
|
cannam@127
|
40 #if defined(BENCHFFT_SINGLE)
|
cannam@127
|
41 typedef float bench_real;
|
cannam@127
|
42 #elif defined(BENCHFFT_LDOUBLE)
|
cannam@127
|
43 typedef long double bench_real;
|
cannam@127
|
44 #elif defined(BENCHFFT_QUAD)
|
cannam@127
|
45 typedef __float128 bench_real;
|
cannam@127
|
46 #else
|
cannam@127
|
47 typedef double bench_real;
|
cannam@127
|
48 #endif
|
cannam@127
|
49
|
cannam@127
|
50 typedef bench_real bench_complex[2];
|
cannam@127
|
51
|
cannam@127
|
52 #define c_re(c) ((c)[0])
|
cannam@127
|
53 #define c_im(c) ((c)[1])
|
cannam@127
|
54
|
cannam@127
|
55 #undef DOUBLE_PRECISION
|
cannam@127
|
56 #define DOUBLE_PRECISION (sizeof(bench_real) == sizeof(double))
|
cannam@127
|
57 #undef SINGLE_PRECISION
|
cannam@127
|
58 #define SINGLE_PRECISION (!DOUBLE_PRECISION && sizeof(bench_real) == sizeof(float))
|
cannam@127
|
59 #undef LDOUBLE_PRECISION
|
cannam@127
|
60 #define LDOUBLE_PRECISION (!DOUBLE_PRECISION && sizeof(bench_real) == sizeof(long double))
|
cannam@127
|
61
|
cannam@127
|
62 #undef QUAD_PRECISION
|
cannam@127
|
63 #ifdef BENCHFFT_QUAD
|
cannam@127
|
64 #define QUAD_PRECISION (!LDOUBLE_PRECISION && sizeof(bench_real) == sizeof(__float128))
|
cannam@127
|
65 #else
|
cannam@127
|
66 #define QUAD_PRECISION 0
|
cannam@127
|
67 #endif
|
cannam@127
|
68
|
cannam@127
|
69 typedef enum { PROBLEM_COMPLEX, PROBLEM_REAL, PROBLEM_R2R } problem_kind_t;
|
cannam@127
|
70
|
cannam@127
|
71 typedef enum {
|
cannam@127
|
72 R2R_R2HC, R2R_HC2R, R2R_DHT,
|
cannam@127
|
73 R2R_REDFT00, R2R_REDFT01, R2R_REDFT10, R2R_REDFT11,
|
cannam@127
|
74 R2R_RODFT00, R2R_RODFT01, R2R_RODFT10, R2R_RODFT11
|
cannam@127
|
75 } r2r_kind_t;
|
cannam@127
|
76
|
cannam@127
|
77 typedef struct {
|
cannam@127
|
78 int n;
|
cannam@127
|
79 int is; /* input stride */
|
cannam@127
|
80 int os; /* output stride */
|
cannam@127
|
81 } bench_iodim;
|
cannam@127
|
82
|
cannam@127
|
83 typedef struct {
|
cannam@127
|
84 int rnk;
|
cannam@127
|
85 bench_iodim *dims;
|
cannam@127
|
86 } bench_tensor;
|
cannam@127
|
87
|
cannam@127
|
88 bench_tensor *mktensor(int rnk);
|
cannam@127
|
89 void tensor_destroy(bench_tensor *sz);
|
cannam@127
|
90 int tensor_sz(const bench_tensor *sz);
|
cannam@127
|
91 bench_tensor *tensor_compress(const bench_tensor *sz);
|
cannam@127
|
92 int tensor_unitstridep(bench_tensor *t);
|
cannam@127
|
93 int tensor_rowmajorp(bench_tensor *t);
|
cannam@127
|
94 int tensor_real_rowmajorp(bench_tensor *t, int sign, int in_place);
|
cannam@127
|
95 bench_tensor *tensor_append(const bench_tensor *a, const bench_tensor *b);
|
cannam@127
|
96 bench_tensor *tensor_copy(const bench_tensor *sz);
|
cannam@127
|
97 bench_tensor *tensor_copy_sub(const bench_tensor *sz, int start_dim, int rnk);
|
cannam@127
|
98 bench_tensor *tensor_copy_swapio(const bench_tensor *sz);
|
cannam@127
|
99 void tensor_ibounds(bench_tensor *t, int *lbp, int *ubp);
|
cannam@127
|
100 void tensor_obounds(bench_tensor *t, int *lbp, int *ubp);
|
cannam@127
|
101
|
cannam@127
|
102 /*
|
cannam@127
|
103 Definition of rank -infinity.
|
cannam@127
|
104 This definition has the property that if you want rank 0 or 1,
|
cannam@127
|
105 you can simply test for rank <= 1. This is a common case.
|
cannam@127
|
106
|
cannam@127
|
107 A tensor of rank -infinity has size 0.
|
cannam@127
|
108 */
|
cannam@127
|
109 #define BENCH_RNK_MINFTY INT_MAX
|
cannam@127
|
110 #define BENCH_FINITE_RNK(rnk) ((rnk) != BENCH_RNK_MINFTY)
|
cannam@127
|
111
|
cannam@127
|
112 typedef struct {
|
cannam@127
|
113 problem_kind_t kind;
|
cannam@127
|
114 r2r_kind_t *k;
|
cannam@127
|
115 bench_tensor *sz;
|
cannam@127
|
116 bench_tensor *vecsz;
|
cannam@127
|
117 int sign;
|
cannam@127
|
118 int in_place;
|
cannam@127
|
119 int destroy_input;
|
cannam@127
|
120 int split;
|
cannam@127
|
121 void *in, *out;
|
cannam@127
|
122 void *inphys, *outphys;
|
cannam@127
|
123 int iphyssz, ophyssz;
|
cannam@127
|
124 char *pstring;
|
cannam@127
|
125 void *userinfo; /* user can store whatever */
|
cannam@127
|
126 int scrambled_in, scrambled_out; /* hack for MPI */
|
cannam@127
|
127
|
cannam@127
|
128 /* internal hack so that we can use verifier in FFTW test program */
|
cannam@127
|
129 void *ini, *outi; /* if nonzero, point to imag. parts for dft */
|
cannam@127
|
130
|
cannam@127
|
131 /* another internal hack to avoid passing around too many parameters */
|
cannam@127
|
132 double setup_time;
|
cannam@127
|
133 } bench_problem;
|
cannam@127
|
134
|
cannam@127
|
135 extern int verbose;
|
cannam@127
|
136
|
cannam@127
|
137 extern int no_speed_allocation;
|
cannam@127
|
138
|
cannam@127
|
139 extern int always_pad_real;
|
cannam@127
|
140
|
cannam@127
|
141 #define LIBBENCH_TIMER 0
|
cannam@127
|
142 #define USER_TIMER 1
|
cannam@127
|
143 #define BENCH_NTIMERS 2
|
cannam@127
|
144 extern void timer_start(int which_timer);
|
cannam@127
|
145 extern double timer_stop(int which_timer);
|
cannam@127
|
146
|
cannam@127
|
147 extern int can_do(bench_problem *p);
|
cannam@127
|
148 extern void setup(bench_problem *p);
|
cannam@127
|
149 extern void doit(int iter, bench_problem *p);
|
cannam@127
|
150 extern void done(bench_problem *p);
|
cannam@127
|
151 extern void main_init(int *argc, char ***argv);
|
cannam@127
|
152 extern void cleanup(void);
|
cannam@127
|
153 extern void verify(const char *param, int rounds, double tol);
|
cannam@127
|
154 extern void useropt(const char *arg);
|
cannam@127
|
155
|
cannam@127
|
156 extern void verify_problem(bench_problem *p, int rounds, double tol);
|
cannam@127
|
157
|
cannam@127
|
158 extern void problem_alloc(bench_problem *p);
|
cannam@127
|
159 extern void problem_free(bench_problem *p);
|
cannam@127
|
160 extern void problem_zero(bench_problem *p);
|
cannam@127
|
161 extern void problem_destroy(bench_problem *p);
|
cannam@127
|
162
|
cannam@127
|
163 extern int power_of_two(int n);
|
cannam@127
|
164 extern int log_2(int n);
|
cannam@127
|
165
|
cannam@127
|
166
|
cannam@127
|
167 #define CASSIGN(out, in) (c_re(out) = c_re(in), c_im(out) = c_im(in))
|
cannam@127
|
168
|
cannam@127
|
169 bench_tensor *verify_pack(const bench_tensor *sz, int s);
|
cannam@127
|
170
|
cannam@127
|
171 typedef struct {
|
cannam@127
|
172 double l;
|
cannam@127
|
173 double i;
|
cannam@127
|
174 double s;
|
cannam@127
|
175 } errors;
|
cannam@127
|
176
|
cannam@127
|
177 void verify_dft(bench_problem *p, int rounds, double tol, errors *e);
|
cannam@127
|
178 void verify_rdft2(bench_problem *p, int rounds, double tol, errors *e);
|
cannam@127
|
179 void verify_r2r(bench_problem *p, int rounds, double tol, errors *e);
|
cannam@127
|
180
|
cannam@127
|
181 /**************************************************************/
|
cannam@127
|
182 /* routines to override */
|
cannam@127
|
183
|
cannam@127
|
184 extern void after_problem_ccopy_from(bench_problem *p, bench_real *ri, bench_real *ii);
|
cannam@127
|
185 extern void after_problem_ccopy_to(bench_problem *p, bench_real *ro, bench_real *io);
|
cannam@127
|
186 extern void after_problem_hccopy_from(bench_problem *p, bench_real *ri, bench_real *ii);
|
cannam@127
|
187 extern void after_problem_hccopy_to(bench_problem *p, bench_real *ro, bench_real *io);
|
cannam@127
|
188 extern void after_problem_rcopy_from(bench_problem *p, bench_real *ri);
|
cannam@127
|
189 extern void after_problem_rcopy_to(bench_problem *p, bench_real *ro);
|
cannam@127
|
190 extern void bench_exit(int status);
|
cannam@127
|
191 extern double bench_cost_postprocess(double cost);
|
cannam@127
|
192
|
cannam@127
|
193 /**************************************************************
|
cannam@127
|
194 * malloc
|
cannam@127
|
195 **************************************************************/
|
cannam@127
|
196 extern void *bench_malloc(size_t size);
|
cannam@127
|
197 extern void bench_free(void *ptr);
|
cannam@127
|
198 extern void bench_free0(void *ptr);
|
cannam@127
|
199
|
cannam@127
|
200 /**************************************************************
|
cannam@127
|
201 * alloca
|
cannam@127
|
202 **************************************************************/
|
cannam@127
|
203 #ifdef HAVE_ALLOCA_H
|
cannam@127
|
204 #include <alloca.h>
|
cannam@127
|
205 #endif
|
cannam@127
|
206
|
cannam@127
|
207 /**************************************************************
|
cannam@127
|
208 * assert
|
cannam@127
|
209 **************************************************************/
|
cannam@127
|
210 extern void bench_assertion_failed(const char *s, int line, const char *file);
|
cannam@127
|
211 #define BENCH_ASSERT(ex) \
|
cannam@127
|
212 (void)((ex) || (bench_assertion_failed(#ex, __LINE__, __FILE__), 0))
|
cannam@127
|
213
|
cannam@127
|
214 #define UNUSED(x) (void)x
|
cannam@127
|
215
|
cannam@127
|
216 /***************************************
|
cannam@127
|
217 * Documentation strings
|
cannam@127
|
218 ***************************************/
|
cannam@127
|
219 struct bench_doc {
|
cannam@127
|
220 const char *key;
|
cannam@127
|
221 const char *val;
|
cannam@127
|
222 const char *(*f)(void);
|
cannam@127
|
223 };
|
cannam@127
|
224
|
cannam@127
|
225 extern struct bench_doc bench_doc[];
|
cannam@127
|
226
|
cannam@127
|
227 #ifdef CC
|
cannam@127
|
228 #define CC_DOC BENCH_DOC("cc", CC)
|
cannam@127
|
229 #elif defined(BENCH_CC)
|
cannam@127
|
230 #define CC_DOC BENCH_DOC("cc", BENCH_CC)
|
cannam@127
|
231 #else
|
cannam@127
|
232 #define CC_DOC /* none */
|
cannam@127
|
233 #endif
|
cannam@127
|
234
|
cannam@127
|
235 #ifdef CXX
|
cannam@127
|
236 #define CXX_DOC BENCH_DOC("cxx", CXX)
|
cannam@127
|
237 #elif defined(BENCH_CXX)
|
cannam@127
|
238 #define CXX_DOC BENCH_DOC("cxx", BENCH_CXX)
|
cannam@127
|
239 #else
|
cannam@127
|
240 #define CXX_DOC /* none */
|
cannam@127
|
241 #endif
|
cannam@127
|
242
|
cannam@127
|
243 #ifdef F77
|
cannam@127
|
244 #define F77_DOC BENCH_DOC("f77", F77)
|
cannam@127
|
245 #elif defined(BENCH_F77)
|
cannam@127
|
246 #define F77_DOC BENCH_DOC("f77", BENCH_F77)
|
cannam@127
|
247 #else
|
cannam@127
|
248 #define F77_DOC /* none */
|
cannam@127
|
249 #endif
|
cannam@127
|
250
|
cannam@127
|
251 #ifdef F90
|
cannam@127
|
252 #define F90_DOC BENCH_DOC("f90", F90)
|
cannam@127
|
253 #elif defined(BENCH_F90)
|
cannam@127
|
254 #define F90_DOC BENCH_DOC("f90", BENCH_F90)
|
cannam@127
|
255 #else
|
cannam@127
|
256 #define F90_DOC /* none */
|
cannam@127
|
257 #endif
|
cannam@127
|
258
|
cannam@127
|
259 #define BEGIN_BENCH_DOC \
|
cannam@127
|
260 struct bench_doc bench_doc[] = { \
|
cannam@127
|
261 CC_DOC \
|
cannam@127
|
262 CXX_DOC \
|
cannam@127
|
263 F77_DOC \
|
cannam@127
|
264 F90_DOC
|
cannam@127
|
265
|
cannam@127
|
266 #define BENCH_DOC(key, val) { key, val, 0 },
|
cannam@127
|
267 #define BENCH_DOCF(key, f) { key, 0, f },
|
cannam@127
|
268
|
cannam@127
|
269 #define END_BENCH_DOC \
|
cannam@127
|
270 {0, 0, 0}};
|
cannam@127
|
271
|
cannam@127
|
272 #ifdef __cplusplus
|
cannam@127
|
273 } /* extern "C" */
|
cannam@127
|
274 #endif /* __cplusplus */
|
cannam@127
|
275
|
cannam@127
|
276 #endif /* __BENCH_USER_H__ */
|