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