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