fftw.h | fftw.h | |||
---|---|---|---|---|
/* fftw/fftw.h. Generated by configure. */ | ||||
/* -*- C -*- */ | ||||
/* | /* | |||
* Copyright (c) 1997 Massachusetts Institute of Technology | * Copyright (c) 1997-1999, 2003 Massachusetts Institute of Technology | |||
* | ||||
* Permission is hereby granted, free of charge, to any person obtaining | ||||
* a copy of this software and associated documentation files (the | ||||
* "Software"), to use, copy, modify, and distribute the Software without | ||||
* restriction, provided the Software, including any modified copies made | ||||
* under this license, is not distributed for a fee, subject to | ||||
* the following conditions: | ||||
* | * | |||
* The above copyright notice and this permission notice shall be | * This program is free software; you can redistribute it and/or modify | |||
* included in all copies or substantial portions of the Software. | * 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. | ||||
* | * | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | * This program is distributed in the hope that it will be useful, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* IN NO EVENT SHALL THE MASSACHUSETTS INSTITUTE OF TECHNOLOGY BE LIABLE | * GNU General Public License for more details. | |||
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | ||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
* | * | |||
* Except as contained in this notice, the name of the Massachusetts | * You should have received a copy of the GNU General Public License | |||
* Institute of Technology shall not be used in advertising or otherwise | * along with this program; if not, write to the Free Software | |||
* to promote the sale, use or other dealings in this Software without | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US | |||
* prior written authorization from the Massachusetts Institute of | A | |||
* Technology. | ||||
* | * | |||
*/ | */ | |||
/* fftw.h -- system-wide definitions */ | /* fftw.h -- system-wide definitions */ | |||
/* $Id: fftw.h,v 1.52 1997/08/26 22:59:02 fftw Exp $ */ | /* $Id: fftw.h.in,v 1.57 2003/03/16 23:43:46 stevenj Exp $ */ | |||
#ifndef FFTW_H | #ifndef FFTW_H | |||
#define FFTW_H | #define FFTW_H | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <stdio.h> | #include <stdio.h> | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
extern "C" { | extern "C" { | |||
#endif /* __cplusplus */ | #endif /* __cplusplus */ | |||
/* Define for using single precision */ | ||||
/* | ||||
* If you can, use configure --enable-float instead of changing this | ||||
* flag directly | ||||
*/ | ||||
/* #undef FFTW_ENABLE_FLOAT */ | ||||
/* our real numbers */ | /* our real numbers */ | |||
typedef double FFTW_REAL; | #ifdef FFTW_ENABLE_FLOAT | |||
typedef float fftw_real; | ||||
#else | ||||
typedef double fftw_real; | ||||
#endif | ||||
/********************************************* | /********************************************* | |||
* Complex numbers and operations | * Complex numbers and operations | |||
*********************************************/ | *********************************************/ | |||
typedef struct { | typedef struct { | |||
FFTW_REAL re, im; | fftw_real re, im; | |||
} FFTW_COMPLEX; | } fftw_complex; | |||
#define c_re(c) ((c).re) | #define c_re(c) ((c).re) | |||
#define c_im(c) ((c).im) | #define c_im(c) ((c).im) | |||
typedef enum { | typedef enum { | |||
FFTW_FORWARD = -1, FFTW_BACKWARD = 1 | FFTW_FORWARD = -1, FFTW_BACKWARD = 1 | |||
} fftw_direction; | } fftw_direction; | |||
/* backward compatibility with FFTW-1.3 */ | ||||
typedef fftw_complex FFTW_COMPLEX; | ||||
typedef fftw_real FFTW_REAL; | ||||
#ifndef FFTW_1_0_COMPATIBILITY | #ifndef FFTW_1_0_COMPATIBILITY | |||
#define FFTW_1_0_COMPATIBILITY 1 | #define FFTW_1_0_COMPATIBILITY 0 | |||
#endif | #endif | |||
#if FFTW_1_0_COMPATIBILITY | #if FFTW_1_0_COMPATIBILITY | |||
/* backward compatibility with FFTW-1.0 */ | /* backward compatibility with FFTW-1.0 */ | |||
#define REAL FFTW_REAL | #define REAL fftw_real | |||
#define COMPLEX FFTW_COMPLEX | #define COMPLEX fftw_complex | |||
#endif | #endif | |||
/********************************************* | /********************************************* | |||
* Success or failure status | * Success or failure status | |||
*********************************************/ | *********************************************/ | |||
typedef enum { | typedef enum { | |||
FFTW_SUCCESS = 0, FFTW_FAILURE = -1 | FFTW_SUCCESS = 0, FFTW_FAILURE = -1 | |||
} fftw_status; | } fftw_status; | |||
/********************************************* | /********************************************* | |||
* Codelets | * Codelets | |||
*********************************************/ | *********************************************/ | |||
/* | typedef void (fftw_notw_codelet) | |||
* There are two kinds of codelets: | (const fftw_complex *, fftw_complex *, int, int); | |||
* | typedef void (fftw_twiddle_codelet) | |||
* NO_TWIDDLE computes the FFT of a certain size, operating | (fftw_complex *, const fftw_complex *, int, | |||
* out-of-place (i.e., take an input and produce a | int, int); | |||
* separate output) | typedef void (fftw_generic_codelet) | |||
* | (fftw_complex *, const fftw_complex *, int, | |||
* TWIDDLE like no_twiddle, but operating in place. Moreover, | int, int, int); | |||
* multiplies the input by twiddle factors. | typedef void (fftw_real2hc_codelet) | |||
*/ | (const fftw_real *, fftw_real *, fftw_real *, | |||
int, int, int); | ||||
typedef void (notw_codelet) (const FFTW_COMPLEX *, FFTW_COMPLEX *, int, int | typedef void (fftw_hc2real_codelet) | |||
); | (const fftw_real *, const fftw_real *, | |||
typedef void (twiddle_codelet) (FFTW_COMPLEX *, const FFTW_COMPLEX *, int, | fftw_real *, int, int, int); | |||
int, int); | typedef void (fftw_hc2hc_codelet) | |||
typedef void (generic_codelet) (FFTW_COMPLEX *, const FFTW_COMPLEX *, int, | (fftw_real *, const fftw_complex *, | |||
int, int, int); | int, int, int); | |||
typedef void (fftw_rgeneric_codelet) | ||||
(fftw_real *, const fftw_complex *, int, | ||||
int, int, int); | ||||
/********************************************* | /********************************************* | |||
* Configurations | * Configurations | |||
*********************************************/ | *********************************************/ | |||
/* | /* | |||
* A configuration is a database of all known codelets | * A configuration is a database of all known codelets | |||
*/ | */ | |||
typedef struct { | enum fftw_node_type { | |||
int size; /* size of the problem */ | FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC, FFTW_RADER, | |||
int signature; /* unique codelet id */ | FFTW_REAL2HC, FFTW_HC2REAL, FFTW_HC2HC, FFTW_RGENERIC | |||
notw_codelet *codelet; /* | }; | |||
* pointer to the codelet that solves | ||||
* the problem | ||||
*/ | ||||
} config_notw; | ||||
extern config_notw fftw_config_notw[]; | ||||
extern config_notw fftwi_config_notw[]; | ||||
/* description of a codelet */ | ||||
typedef struct { | typedef struct { | |||
int size; /* size of the problem */ | const char *name; /* name of the codelet */ | |||
int signature; /* unique codelet id */ | void (*codelet) (); /* pointer to the codelet itself */ | |||
twiddle_codelet *codelet; | int size; /* size of the codelet */ | |||
} config_twiddle; | fftw_direction dir; /* direction */ | |||
enum fftw_node_type type; /* TWIDDLE or NO_TWIDDLE */ | ||||
int signature; /* unique id */ | ||||
int ntwiddle; /* number of twiddle factors */ | ||||
const int *twiddle_order; /* | ||||
* array that determines the order | ||||
* in which the codelet expects | ||||
* the twiddle factors | ||||
*/ | ||||
} fftw_codelet_desc; | ||||
extern config_twiddle fftw_config_twiddle[]; | /* On Win32, you need to do funny things to access global variables | |||
extern config_twiddle fftwi_config_twiddle[]; | in shared libraries. Thanks to Andrew Sterian for this hack. */ | |||
#ifdef HAVE_WIN32 | ||||
# if defined(BUILD_FFTW_DLL) | ||||
# define DL_IMPORT(type) __declspec(dllexport) type | ||||
# elif defined(USE_FFTW_DLL) | ||||
# define DL_IMPORT(type) __declspec(dllimport) type | ||||
# else | ||||
# define DL_IMPORT(type) type | ||||
# endif | ||||
#else | ||||
# define DL_IMPORT(type) type | ||||
#endif | ||||
extern generic_codelet fftw_twiddle_generic; | extern DL_IMPORT(const char *) fftw_version; | |||
extern generic_codelet fftwi_twiddle_generic; | ||||
extern char *fftw_version; | ||||
/***************************** | /***************************** | |||
* Plans | * Plans | |||
*****************************/ | *****************************/ | |||
/* | /* | |||
* A plan is a sequence of reductions to compute a FFT of | * A plan is a sequence of reductions to compute a FFT of | |||
* a given size. At each step, the FFT algorithm can: | * a given size. At each step, the FFT algorithm can: | |||
* | * | |||
* 1) apply a notw codelet, or | * 1) apply a notw codelet, or | |||
* 2) recurse and apply a twiddle codelet, or | * 2) recurse and apply a twiddle codelet, or | |||
* 3) apply the generic codelet. | * 3) apply the generic codelet. | |||
*/ | */ | |||
enum fftw_node_type { | ||||
FFTW_NOTW, FFTW_TWIDDLE, FFTW_GENERIC | ||||
}; | ||||
/* structure that contains twiddle factors */ | /* structure that contains twiddle factors */ | |||
typedef struct fftw_twiddle_struct { | typedef struct fftw_twiddle_struct { | |||
int n; | int n; | |||
int r; | const fftw_codelet_desc *cdesc; | |||
int m; | fftw_complex *twarray; | |||
FFTW_COMPLEX *twarray; | ||||
struct fftw_twiddle_struct *next; | struct fftw_twiddle_struct *next; | |||
int refcnt; | int refcnt; | |||
} fftw_twiddle; | } fftw_twiddle; | |||
typedef struct fftw_rader_data_struct { | ||||
struct fftw_plan_struct *plan; | ||||
fftw_complex *omega; | ||||
int g, ginv; | ||||
int p, flags, refcount; | ||||
struct fftw_rader_data_struct *next; | ||||
fftw_codelet_desc *cdesc; | ||||
} fftw_rader_data; | ||||
typedef void (fftw_rader_codelet) | ||||
(fftw_complex *, const fftw_complex *, int, | ||||
int, int, fftw_rader_data *); | ||||
/* structure that holds all the data needed for a given step */ | /* structure that holds all the data needed for a given step */ | |||
typedef struct fftw_plan_node_struct { | typedef struct fftw_plan_node_struct { | |||
enum fftw_node_type type; | enum fftw_node_type type; | |||
union { | union { | |||
/* nodes of type FFTW_NOTW */ | /* nodes of type FFTW_NOTW */ | |||
struct { | struct { | |||
int size; | int size; | |||
notw_codelet *codelet; | fftw_notw_codelet *codelet; | |||
const fftw_codelet_desc *codelet_desc; | ||||
} notw; | } notw; | |||
/* nodes of type FFTW_TWIDDLE */ | /* nodes of type FFTW_TWIDDLE */ | |||
struct { | struct { | |||
int size; | int size; | |||
twiddle_codelet *codelet; | fftw_twiddle_codelet *codelet; | |||
fftw_twiddle *tw; | fftw_twiddle *tw; | |||
struct fftw_plan_node_struct *recurse; | struct fftw_plan_node_struct *recurse; | |||
const fftw_codelet_desc *codelet_desc; | ||||
} twiddle; | } twiddle; | |||
/* nodes of type FFTW_GENERIC */ | /* nodes of type FFTW_GENERIC */ | |||
struct { | struct { | |||
int size; | int size; | |||
generic_codelet *codelet; | fftw_generic_codelet *codelet; | |||
fftw_twiddle *tw; | fftw_twiddle *tw; | |||
struct fftw_plan_node_struct *recurse; | struct fftw_plan_node_struct *recurse; | |||
} generic; | } generic; | |||
/* nodes of type FFTW_RADER */ | ||||
struct { | ||||
int size; | ||||
fftw_rader_codelet *codelet; | ||||
fftw_rader_data *rader_data; | ||||
fftw_twiddle *tw; | ||||
struct fftw_plan_node_struct *recurse; | ||||
} rader; | ||||
/* nodes of type FFTW_REAL2HC */ | ||||
struct { | ||||
int size; | ||||
fftw_real2hc_codelet *codelet; | ||||
const fftw_codelet_desc *codelet_desc; | ||||
} real2hc; | ||||
/* nodes of type FFTW_HC2REAL */ | ||||
struct { | ||||
int size; | ||||
fftw_hc2real_codelet *codelet; | ||||
const fftw_codelet_desc *codelet_desc; | ||||
} hc2real; | ||||
/* nodes of type FFTW_HC2HC */ | ||||
struct { | ||||
int size; | ||||
fftw_direction dir; | ||||
fftw_hc2hc_codelet *codelet; | ||||
fftw_twiddle *tw; | ||||
struct fftw_plan_node_struct *recurse; | ||||
const fftw_codelet_desc *codelet_desc; | ||||
} hc2hc; | ||||
/* nodes of type FFTW_RGENERIC */ | ||||
struct { | ||||
int size; | ||||
fftw_direction dir; | ||||
fftw_rgeneric_codelet *codelet; | ||||
fftw_twiddle *tw; | ||||
struct fftw_plan_node_struct *recurse; | ||||
} rgeneric; | ||||
} nodeu; | } nodeu; | |||
int refcnt; | int refcnt; | |||
} fftw_plan_node; | } fftw_plan_node; | |||
typedef enum { | ||||
FFTW_NORMAL_RECURSE = 0, | ||||
FFTW_VECTOR_RECURSE = 1 | ||||
} fftw_recurse_kind; | ||||
struct fftw_plan_struct { | struct fftw_plan_struct { | |||
int n; | int n; | |||
int refcnt; | ||||
fftw_direction dir; | fftw_direction dir; | |||
fftw_plan_node *root; | ||||
double cost; | ||||
int flags; | int flags; | |||
enum fftw_node_type wisdom_type; | ||||
int wisdom_signature; | int wisdom_signature; | |||
enum fftw_node_type wisdom_type; | ||||
struct fftw_plan_struct *next; | struct fftw_plan_struct *next; | |||
int refcnt; | fftw_plan_node *root; | |||
double cost; | ||||
fftw_recurse_kind recurse_kind; | ||||
int vector_size; | ||||
}; | }; | |||
/* a plan is just an array of instructions */ | ||||
typedef struct fftw_plan_struct *fftw_plan; | typedef struct fftw_plan_struct *fftw_plan; | |||
/* flags for the planner */ | /* flags for the planner */ | |||
#define FFTW_ESTIMATE (0) | #define FFTW_ESTIMATE (0) | |||
#define FFTW_MEASURE (1) | #define FFTW_MEASURE (1) | |||
#define FFTW_OUT_OF_PLACE (0) | ||||
#define FFTW_IN_PLACE (8) | #define FFTW_IN_PLACE (8) | |||
#define FFTW_USE_WISDOM (16) | #define FFTW_USE_WISDOM (16) | |||
#define FFTW_THREADSAFE (128) /* guarantee plan is read-only so that the | ||||
same plan can be used in parallel by | ||||
multiple threads */ | ||||
#define FFTWND_FORCE_BUFFERED (256) /* internal flag, forces buffering | ||||
in fftwnd transforms */ | ||||
#define FFTW_NO_VECTOR_RECURSE (512) /* internal flag, prevents use | ||||
of vector recursion */ | ||||
extern fftw_plan fftw_create_plan_specific(int n, fftw_direction dir, | ||||
int flags, | ||||
fftw_complex *in, int istride, | ||||
fftw_complex *out, int ostride); | ||||
#define FFTW_HAS_PLAN_SPECIFIC | ||||
extern fftw_plan fftw_create_plan(int n, fftw_direction dir, int flags); | extern fftw_plan fftw_create_plan(int n, fftw_direction dir, int flags); | |||
extern fftw_twiddle *fftw_create_twiddle(int n, int r, int m); | ||||
extern void fftw_destroy_twiddle(fftw_twiddle * tw); | ||||
extern void fftw_print_plan(fftw_plan plan); | extern void fftw_print_plan(fftw_plan plan); | |||
extern void fftw_destroy_plan(fftw_plan plan); | extern void fftw_destroy_plan(fftw_plan plan); | |||
extern void fftw_naive(int n, FFTW_COMPLEX *in, FFTW_COMPLEX *out); | extern void fftw(fftw_plan plan, int howmany, fftw_complex *in, int istride | |||
extern void fftwi_naive(int n, FFTW_COMPLEX *in, FFTW_COMPLEX *out); | , | |||
void fftw(fftw_plan plan, int howmany, FFTW_COMPLEX *in, int istride, | int idist, fftw_complex *out, int ostride, int odist); | |||
int idist, FFTW_COMPLEX *out, int ostride, int odist); | extern void fftw_one(fftw_plan plan, fftw_complex *in, fftw_complex *out); | |||
extern double fftw_measure_runtime(fftw_plan plan); | extern void fftw_die(const char *s); | |||
extern void fftw_die(char *s); | ||||
extern void *fftw_malloc(size_t n); | extern void *fftw_malloc(size_t n); | |||
extern void fftw_free(void *p); | extern void fftw_free(void *p); | |||
extern void fftw_check_memory_leaks(void); | extern void fftw_check_memory_leaks(void); | |||
extern void fftw_strided_copy(int, FFTW_COMPLEX *, int, FFTW_COMPLEX *); | extern void fftw_print_max_memory_usage(void); | |||
extern void fftw_executor_simple(int, const FFTW_COMPLEX *, FFTW_COMPLEX *, | ||||
fftw_plan_node *, int, int); | typedef void *(*fftw_malloc_type_function) (size_t n); | |||
extern void *(*fftw_malloc_hook) (size_t n); | typedef void (*fftw_free_type_function) (void *p); | |||
extern void (*fftw_free_hook) (void *p); | typedef void (*fftw_die_type_function) (const char *errString); | |||
extern DL_IMPORT(fftw_malloc_type_function) fftw_malloc_hook; | ||||
extern DL_IMPORT(fftw_free_type_function) fftw_free_hook; | ||||
extern DL_IMPORT(fftw_die_type_function) fftw_die_hook; | ||||
extern size_t fftw_sizeof_fftw_real(void); | ||||
/* Wisdom: */ | /* Wisdom: */ | |||
#define FFTW_HAS_WISDOM /* define this symbol so that we know we are using | /* | |||
a version of FFTW with wisdom */ | * define this symbol so that users know we are using a version of FFTW | |||
* with wisdom | ||||
*/ | ||||
#define FFTW_HAS_WISDOM | ||||
extern void fftw_forget_wisdom(void); | extern void fftw_forget_wisdom(void); | |||
extern void fftw_export_wisdom(void (*emitter)(char c, void *), void *data) | extern void fftw_export_wisdom(void (*emitter) (char c, void *), void *data | |||
; | ); | |||
extern fftw_status fftw_import_wisdom(int (*g)(void *), void *data); | extern fftw_status fftw_import_wisdom(int (*g) (void *), void *data); | |||
extern void fftw_export_wisdom_to_file(FILE *output_file); | extern void fftw_export_wisdom_to_file(FILE *output_file); | |||
extern fftw_status fftw_import_wisdom_from_file(FILE *input_file); | extern fftw_status fftw_import_wisdom_from_file(FILE *input_file); | |||
extern char *fftw_export_wisdom_to_string(void); | extern char *fftw_export_wisdom_to_string(void); | |||
extern fftw_status fftw_import_wisdom_from_string(const char *input_string) ; | extern fftw_status fftw_import_wisdom_from_string(const char *input_string) ; | |||
/* | /* | |||
* define symbol so we know this function is available (it is not in | * define symbol so we know this function is available (it is not in | |||
* older FFTWs) | * older FFTWs) | |||
*/ | */ | |||
#define FFTW_HAS_FPRINT_PLAN | #define FFTW_HAS_FPRINT_PLAN | |||
extern void fftw_fprint_plan(FILE * f, fftw_plan plan); | extern void fftw_fprint_plan(FILE *f, fftw_plan plan); | |||
/* Returns 1 if FFTW is working. Otherwise, its value is undefined: */ | ||||
#define is_fftw_working() 1 | ||||
/***************************** | /***************************** | |||
* N-dimensional code | * N-dimensional code | |||
*****************************/ | *****************************/ | |||
typedef struct { | typedef struct { | |||
int is_in_place; /* 1 if for in-place FFT's, 0 otherwise */ | int is_in_place; /* 1 if for in-place FFTs, 0 otherwise */ | |||
int rank; /* | int rank; /* | |||
* the rank (number of dimensions) of the | * the rank (number of dimensions) of the | |||
* array to be FFT'ed | * array to be FFTed | |||
*/ | */ | |||
int *n; /* | int *n; /* | |||
* the dimensions of the array to the | * the dimensions of the array to the | |||
* FFT'ed | * FFTed | |||
*/ | */ | |||
fftw_direction dir; | ||||
int *n_before; /* | int *n_before; /* | |||
* n_before[i] = product of n[j] for j < i | * n_before[i] = product of n[j] for j < i | |||
*/ | */ | |||
int *n_after; /* n_after[i] = product of n[j] for j > i */ | int *n_after; /* n_after[i] = product of n[j] for j > i */ | |||
fftw_plan *plans; /* fftw plans for each dimension */ | ||||
FFTW_COMPLEX *work; /* | ||||
* work array for FFT when doing | ||||
* "in-place" FFT | ||||
*/ | ||||
} fftwnd_aux_data; | ||||
typedef fftwnd_aux_data *fftwnd_plan; | ||||
/* Initializing the FFTWND Auxiliary Data */ | ||||
fftwnd_plan fftw2d_create_plan(int nx, int ny, fftw_direction dir, int flag | ||||
s); | ||||
fftwnd_plan fftw3d_create_plan(int nx, int ny, int nz, | ||||
fftw_direction dir, int flags); | ||||
fftwnd_plan fftwnd_create_plan(int rank, const int *n, fftw_direction dir, | ||||
int flags); | ||||
/* Freeing the FFTWND Auxiliary Data */ | ||||
void fftwnd_destroy_plan(fftwnd_plan plan); | ||||
/* Computing the N-Dimensional FFT */ | ||||
void fftwnd(fftwnd_plan plan, int howmany, | ||||
FFTW_COMPLEX *in, int istride, int idist, | ||||
FFTW_COMPLEX *out, int ostride, int odist); | ||||
/************************************************************************** | ||||
**/ | ||||
/********************************** Timers ******************************** | ||||
**/ | ||||
/************************************************************************** | ||||
**/ | ||||
/* | ||||
* Here, you can use all the nice timers available in your machine. | ||||
*/ | ||||
/* | ||||
* | ||||
Things you should define to include your own clock: | ||||
fftw_time -- the data type used to store a time | ||||
extern fftw_time fftw_get_time(void); | ||||
-- a function returning the current time. (We have | ||||
implemented this as a macro in most cases.) | ||||
extern fftw_time fftw_time_diff(fftw_time t1, fftw_time t2); | ||||
-- returns the time difference (t1 - t2). | ||||
If t1 < t2, it may simply return zero (although this | ||||
is not required). (We have implemented this as a macro | ||||
in most cases.) | ||||
extern double fftw_time_to_sec(fftw_time t); | ||||
-- returns the time t expressed in seconds, as a double. | ||||
(Implemented as a macro in most cases.) | ||||
FFTW_TIME_MIN -- a double-precision macro holding the minimum | ||||
time interval (in seconds) for accurate time measurements. | ||||
This should probably be at least 100 times the precision of | ||||
your clock (we use even longer intervals, to be conservative). | ||||
This will determine how long the planner takes to measure | ||||
the speeds of different possible plans. | ||||
Bracket all of your definitions with an appropriate #ifdef so that | ||||
they will be enabled on your machine. If you do add your own | ||||
high-precision timer code, let us know (at fftw@theory.lcs.mit.edu). | ||||
Only declarations should go in this file. Any function definitions | ||||
that you need should go into timer.c. | ||||
*/ | ||||
/* define a symbol so that we know that we have the fftw_time_diff | ||||
function/macro (it did not exist prior to FFTW 1.2) */ | ||||
#define FFTW_HAS_TIME_DIFF | ||||
#ifdef SOLARIS | ||||
/* we use the nanosecond virtual timer */ | ||||
#include <sys/time.h> | ||||
typedef hrtime_t fftw_time; | ||||
#define fftw_get_time() gethrtime() | ||||
#define fftw_time_diff(t1,t2) ((t1) - (t2)) | ||||
#define fftw_time_to_sec(t) ((double) t / 1.0e9) | ||||
/* | fftw_plan *plans; /* 1d fftw plans for each dimension */ | |||
* a measurement is valid if it runs for at least | ||||
* FFTW_TIME_MIN seconds. | ||||
*/ | ||||
#define FFTW_TIME_MIN (1.0e-4) /* for Solaris nanosecond timer */ | ||||
#endif /* SOLARIS */ | ||||
#if defined(MAC) || defined(macintosh) | ||||
/* Use Macintosh Time Manager routines (maximum resolution is about 20 | ||||
microseconds). */ | ||||
typedef struct fftw_time_struct { | ||||
unsigned long hi,lo; | ||||
} fftw_time; | ||||
extern fftw_time get_Mac_microseconds(void); | ||||
#define fftw_get_time() get_Mac_microseconds() | ||||
/* define as a function instead of a macro: */ | ||||
extern fftw_time fftw_time_diff(fftw_time t1, fftw_time t2); | ||||
#define fftw_time_to_sec(t) ((t).lo * 1.0e-6 + 4294967295.0e-6 * (t).hi) | ||||
/* very conservative, since timer should be accurate to 20e-6: */ | ||||
/* (although this seems not to be the case in practice) */ | ||||
#define FFTW_TIME_MIN (5.0e-2) /* for MacOS Time Manager timer */ | ||||
#endif /* Macintosh */ | ||||
#ifdef __WIN32__ | ||||
#include <time.h> | ||||
typedef unsigned long fftw_time; | ||||
extern unsigned long GetPerfTime(void); | ||||
extern double GetPerfSec(double ticks); | ||||
#define fftw_get_time() GetPerfTime() | ||||
#define fftw_time_diff(t1,t2) ((t1) - (t2)) | ||||
#define fftw_time_to_sec(t) GetPerfSec(t) | ||||
#define FFTW_TIME_MIN (5.0e-2) /* for Win32 timer */ | ||||
#endif /* __WIN32__ */ | ||||
#if defined(_CRAYMPP) /* Cray MPP system */ | ||||
double SECONDR(void); /* | int nbuffers, nwork; | |||
* I think you have to link with -lsci to | fftw_complex *work; /* | |||
* get this | * work array big enough to hold | |||
* nbuffers+1 of the largest dimension | ||||
* (has nwork elements) | ||||
*/ | */ | |||
} fftwnd_data; | ||||
typedef double fftw_time; | typedef fftwnd_data *fftwnd_plan; | |||
#define fftw_get_time() SECONDR() | ||||
#define fftw_time_diff(t1,t2) ((t1) - (t2)) | ||||
#define fftw_time_to_sec(t) (t) | ||||
#define FFTW_TIME_MIN (1.0e-1) /* for Cray MPP SECONDR timer */ | ||||
#endif /* _CRAYMPP */ | ||||
/*********************************************** | ||||
* last resort: good old Unix clock() | ||||
***********************************************/ | ||||
#ifndef FFTW_TIME_MIN | ||||
#include <time.h> | ||||
typedef clock_t fftw_time; | ||||
#ifndef CLOCKS_PER_SEC | /* Initializing the FFTWND plan: */ | |||
#ifdef sun | extern fftwnd_plan fftw2d_create_plan(int nx, int ny, fftw_direction dir, | |||
/* stupid sunos4 prototypes */ | int flags); | |||
#define CLOCKS_PER_SEC 1000000 | extern fftwnd_plan fftw3d_create_plan(int nx, int ny, int nz, | |||
extern long clock(void); | fftw_direction dir, int flags); | |||
#else /* not sun, we don't know CLOCKS_PER_SEC */ | extern fftwnd_plan fftwnd_create_plan(int rank, const int *n, | |||
#error Please define CLOCKS_PER_SEC | fftw_direction dir, | |||
#endif | int flags); | |||
#endif | ||||
#define fftw_get_time() clock() | extern fftwnd_plan fftw2d_create_plan_specific(int nx, int ny, | |||
#define fftw_time_diff(t1,t2) ((t1) - (t2)) | fftw_direction dir, | |||
#define fftw_time_to_sec(t) (((double) (t)) / CLOCKS_PER_SEC) | int flags, | |||
fftw_complex *in, int istride, | ||||
fftw_complex *out, int ostride); | ||||
extern fftwnd_plan fftw3d_create_plan_specific(int nx, int ny, int nz, | ||||
fftw_direction dir, int flags, | ||||
fftw_complex *in, int istride, | ||||
fftw_complex *out, int ostride); | ||||
extern fftwnd_plan fftwnd_create_plan_specific(int rank, const int *n, | ||||
fftw_direction dir, | ||||
int flags, | ||||
fftw_complex *in, int istride, | ||||
fftw_complex *out, int ostride); | ||||
/* | /* Freeing the FFTWND plan: */ | |||
* ***VERY*** conservative constant: this says that a | extern void fftwnd_destroy_plan(fftwnd_plan plan); | |||
* measurement must run for 200ms in order to be valid. | ||||
* You had better check the manual of your machine | ||||
* to discover if it can do better than this | ||||
*/ | ||||
#define FFTW_TIME_MIN (2.0e-1) /* for default clock() timer */ | ||||
#endif /* UNIX clock() */ | /* Printing the plan: */ | |||
extern void fftwnd_fprint_plan(FILE *f, fftwnd_plan p); | ||||
extern void fftwnd_print_plan(fftwnd_plan p); | ||||
#define FFTWND_HAS_PRINT_PLAN | ||||
/************************************************************************** | /* Computing the N-Dimensional FFT */ | |||
**/ | extern void fftwnd(fftwnd_plan plan, int howmany, | |||
fftw_complex *in, int istride, int idist, | ||||
fftw_complex *out, int ostride, int odist); | ||||
extern void fftwnd_one(fftwnd_plan p, fftw_complex *in, fftw_complex *out); | ||||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} /* extern "C" */ | } /* extern "C" */ | |||
#endif /* __cplusplus */ | ||||
#endif /* __cplusplus */ | ||||
#endif /* FFTW_H */ | #endif /* FFTW_H */ | |||
End of changes. 57 change blocks. | ||||
286 lines changed or deleted | 249 lines changed or added | |||