cannam@167: /* cannam@167: * Copyright (c) 2001 Matteo Frigo cannam@167: * Copyright (c) 2001 Massachusetts Institute of Technology cannam@167: * cannam@167: * This program is free software; you can redistribute it and/or modify cannam@167: * it under the terms of the GNU General Public License as published by cannam@167: * the Free Software Foundation; either version 2 of the License, or cannam@167: * (at your option) any later version. cannam@167: * cannam@167: * This program is distributed in the hope that it will be useful, cannam@167: * but WITHOUT ANY WARRANTY; without even the implied warranty of cannam@167: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the cannam@167: * GNU General Public License for more details. cannam@167: * cannam@167: * You should have received a copy of the GNU General Public License cannam@167: * along with this program; if not, write to the Free Software cannam@167: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA cannam@167: * cannam@167: */ cannam@167: cannam@167: #ifndef __BENCH_USER_H__ cannam@167: #define __BENCH_USER_H__ cannam@167: cannam@167: #ifdef __cplusplus cannam@167: extern "C" { cannam@167: #endif /* __cplusplus */ cannam@167: cannam@167: /* benchmark program definitions for user code */ cannam@167: #include "config.h" cannam@167: #include cannam@167: cannam@167: #if HAVE_STDDEF_H cannam@167: #include cannam@167: #endif cannam@167: cannam@167: #if HAVE_STDLIB_H cannam@167: #include cannam@167: #endif cannam@167: cannam@167: #if defined(BENCHFFT_SINGLE) cannam@167: typedef float bench_real; cannam@167: #elif defined(BENCHFFT_LDOUBLE) cannam@167: typedef long double bench_real; cannam@167: #elif defined(BENCHFFT_QUAD) cannam@167: typedef __float128 bench_real; cannam@167: #else cannam@167: typedef double bench_real; cannam@167: #endif cannam@167: cannam@167: typedef bench_real bench_complex[2]; cannam@167: cannam@167: #define c_re(c) ((c)[0]) cannam@167: #define c_im(c) ((c)[1]) cannam@167: cannam@167: #undef DOUBLE_PRECISION cannam@167: #define DOUBLE_PRECISION (sizeof(bench_real) == sizeof(double)) cannam@167: #undef SINGLE_PRECISION cannam@167: #define SINGLE_PRECISION (!DOUBLE_PRECISION && sizeof(bench_real) == sizeof(float)) cannam@167: #undef LDOUBLE_PRECISION cannam@167: #define LDOUBLE_PRECISION (!DOUBLE_PRECISION && sizeof(bench_real) == sizeof(long double)) cannam@167: cannam@167: #undef QUAD_PRECISION cannam@167: #ifdef BENCHFFT_QUAD cannam@167: #define QUAD_PRECISION (!LDOUBLE_PRECISION && sizeof(bench_real) == sizeof(__float128)) cannam@167: #else cannam@167: #define QUAD_PRECISION 0 cannam@167: #endif cannam@167: cannam@167: typedef enum { PROBLEM_COMPLEX, PROBLEM_REAL, PROBLEM_R2R } problem_kind_t; cannam@167: cannam@167: typedef enum { cannam@167: R2R_R2HC, R2R_HC2R, R2R_DHT, cannam@167: R2R_REDFT00, R2R_REDFT01, R2R_REDFT10, R2R_REDFT11, cannam@167: R2R_RODFT00, R2R_RODFT01, R2R_RODFT10, R2R_RODFT11 cannam@167: } r2r_kind_t; cannam@167: cannam@167: typedef struct { cannam@167: int n; cannam@167: int is; /* input stride */ cannam@167: int os; /* output stride */ cannam@167: } bench_iodim; cannam@167: cannam@167: typedef struct { cannam@167: int rnk; cannam@167: bench_iodim *dims; cannam@167: } bench_tensor; cannam@167: cannam@167: bench_tensor *mktensor(int rnk); cannam@167: void tensor_destroy(bench_tensor *sz); cannam@167: size_t tensor_sz(const bench_tensor *sz); cannam@167: bench_tensor *tensor_compress(const bench_tensor *sz); cannam@167: int tensor_unitstridep(bench_tensor *t); cannam@167: int tensor_rowmajorp(bench_tensor *t); cannam@167: int tensor_real_rowmajorp(bench_tensor *t, int sign, int in_place); cannam@167: bench_tensor *tensor_append(const bench_tensor *a, const bench_tensor *b); cannam@167: bench_tensor *tensor_copy(const bench_tensor *sz); cannam@167: bench_tensor *tensor_copy_sub(const bench_tensor *sz, int start_dim, int rnk); cannam@167: bench_tensor *tensor_copy_swapio(const bench_tensor *sz); cannam@167: void tensor_ibounds(bench_tensor *t, int *lbp, int *ubp); cannam@167: void tensor_obounds(bench_tensor *t, int *lbp, int *ubp); cannam@167: cannam@167: /* cannam@167: Definition of rank -infinity. cannam@167: This definition has the property that if you want rank 0 or 1, cannam@167: you can simply test for rank <= 1. This is a common case. cannam@167: cannam@167: A tensor of rank -infinity has size 0. cannam@167: */ cannam@167: #define BENCH_RNK_MINFTY INT_MAX cannam@167: #define BENCH_FINITE_RNK(rnk) ((rnk) != BENCH_RNK_MINFTY) cannam@167: cannam@167: typedef struct { cannam@167: problem_kind_t kind; cannam@167: r2r_kind_t *k; cannam@167: bench_tensor *sz; cannam@167: bench_tensor *vecsz; cannam@167: int sign; cannam@167: int in_place; cannam@167: int destroy_input; cannam@167: int split; cannam@167: void *in, *out; cannam@167: void *inphys, *outphys; cannam@167: int iphyssz, ophyssz; cannam@167: char *pstring; cannam@167: void *userinfo; /* user can store whatever */ cannam@167: int scrambled_in, scrambled_out; /* hack for MPI */ cannam@167: cannam@167: /* internal hack so that we can use verifier in FFTW test program */ cannam@167: void *ini, *outi; /* if nonzero, point to imag. parts for dft */ cannam@167: cannam@167: /* another internal hack to avoid passing around too many parameters */ cannam@167: double setup_time; cannam@167: } bench_problem; cannam@167: cannam@167: extern int verbose; cannam@167: cannam@167: extern int no_speed_allocation; cannam@167: cannam@167: extern int always_pad_real; cannam@167: cannam@167: #define LIBBENCH_TIMER 0 cannam@167: #define USER_TIMER 1 cannam@167: #define BENCH_NTIMERS 2 cannam@167: extern void timer_start(int which_timer); cannam@167: extern double timer_stop(int which_timer); cannam@167: cannam@167: extern int can_do(bench_problem *p); cannam@167: extern void setup(bench_problem *p); cannam@167: extern void doit(int iter, bench_problem *p); cannam@167: extern void done(bench_problem *p); cannam@167: extern void main_init(int *argc, char ***argv); cannam@167: extern void cleanup(void); cannam@167: extern void verify(const char *param, int rounds, double tol); cannam@167: extern void useropt(const char *arg); cannam@167: cannam@167: extern void verify_problem(bench_problem *p, int rounds, double tol); cannam@167: cannam@167: extern void problem_alloc(bench_problem *p); cannam@167: extern void problem_free(bench_problem *p); cannam@167: extern void problem_zero(bench_problem *p); cannam@167: extern void problem_destroy(bench_problem *p); cannam@167: cannam@167: extern int power_of_two(int n); cannam@167: extern int log_2(int n); cannam@167: cannam@167: cannam@167: #define CASSIGN(out, in) (c_re(out) = c_re(in), c_im(out) = c_im(in)) cannam@167: cannam@167: bench_tensor *verify_pack(const bench_tensor *sz, int s); cannam@167: cannam@167: typedef struct { cannam@167: double l; cannam@167: double i; cannam@167: double s; cannam@167: } errors; cannam@167: cannam@167: void verify_dft(bench_problem *p, int rounds, double tol, errors *e); cannam@167: void verify_rdft2(bench_problem *p, int rounds, double tol, errors *e); cannam@167: void verify_r2r(bench_problem *p, int rounds, double tol, errors *e); cannam@167: cannam@167: /**************************************************************/ cannam@167: /* routines to override */ cannam@167: cannam@167: extern void after_problem_ccopy_from(bench_problem *p, bench_real *ri, bench_real *ii); cannam@167: extern void after_problem_ccopy_to(bench_problem *p, bench_real *ro, bench_real *io); cannam@167: extern void after_problem_hccopy_from(bench_problem *p, bench_real *ri, bench_real *ii); cannam@167: extern void after_problem_hccopy_to(bench_problem *p, bench_real *ro, bench_real *io); cannam@167: extern void after_problem_rcopy_from(bench_problem *p, bench_real *ri); cannam@167: extern void after_problem_rcopy_to(bench_problem *p, bench_real *ro); cannam@167: extern void bench_exit(int status); cannam@167: extern double bench_cost_postprocess(double cost); cannam@167: cannam@167: /************************************************************** cannam@167: * malloc cannam@167: **************************************************************/ cannam@167: extern void *bench_malloc(size_t size); cannam@167: extern void bench_free(void *ptr); cannam@167: extern void bench_free0(void *ptr); cannam@167: cannam@167: /************************************************************** cannam@167: * alloca cannam@167: **************************************************************/ cannam@167: #ifdef HAVE_ALLOCA_H cannam@167: #include cannam@167: #endif cannam@167: cannam@167: /************************************************************** cannam@167: * assert cannam@167: **************************************************************/ cannam@167: extern void bench_assertion_failed(const char *s, int line, const char *file); cannam@167: #define BENCH_ASSERT(ex) \ cannam@167: (void)((ex) || (bench_assertion_failed(#ex, __LINE__, __FILE__), 0)) cannam@167: cannam@167: #define UNUSED(x) (void)x cannam@167: cannam@167: /*************************************** cannam@167: * Documentation strings cannam@167: ***************************************/ cannam@167: struct bench_doc { cannam@167: const char *key; cannam@167: const char *val; cannam@167: const char *(*f)(void); cannam@167: }; cannam@167: cannam@167: extern struct bench_doc bench_doc[]; cannam@167: cannam@167: #ifdef CC cannam@167: #define CC_DOC BENCH_DOC("cc", CC) cannam@167: #elif defined(BENCH_CC) cannam@167: #define CC_DOC BENCH_DOC("cc", BENCH_CC) cannam@167: #else cannam@167: #define CC_DOC /* none */ cannam@167: #endif cannam@167: cannam@167: #ifdef CXX cannam@167: #define CXX_DOC BENCH_DOC("cxx", CXX) cannam@167: #elif defined(BENCH_CXX) cannam@167: #define CXX_DOC BENCH_DOC("cxx", BENCH_CXX) cannam@167: #else cannam@167: #define CXX_DOC /* none */ cannam@167: #endif cannam@167: cannam@167: #ifdef F77 cannam@167: #define F77_DOC BENCH_DOC("f77", F77) cannam@167: #elif defined(BENCH_F77) cannam@167: #define F77_DOC BENCH_DOC("f77", BENCH_F77) cannam@167: #else cannam@167: #define F77_DOC /* none */ cannam@167: #endif cannam@167: cannam@167: #ifdef F90 cannam@167: #define F90_DOC BENCH_DOC("f90", F90) cannam@167: #elif defined(BENCH_F90) cannam@167: #define F90_DOC BENCH_DOC("f90", BENCH_F90) cannam@167: #else cannam@167: #define F90_DOC /* none */ cannam@167: #endif cannam@167: cannam@167: #define BEGIN_BENCH_DOC \ cannam@167: struct bench_doc bench_doc[] = { \ cannam@167: CC_DOC \ cannam@167: CXX_DOC \ cannam@167: F77_DOC \ cannam@167: F90_DOC cannam@167: cannam@167: #define BENCH_DOC(key, val) { key, val, 0 }, cannam@167: #define BENCH_DOCF(key, f) { key, 0, f }, cannam@167: cannam@167: #define END_BENCH_DOC \ cannam@167: {0, 0, 0}}; cannam@167: cannam@167: #ifdef __cplusplus cannam@167: } /* extern "C" */ cannam@167: #endif /* __cplusplus */ cannam@167: cannam@167: #endif /* __BENCH_USER_H__ */