Subversion Repositories shark

Rev

Rev 107 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
107 pj 1
/*
2
 * Copyright (c) 1997-1999 Massachusetts Institute of Technology
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 2 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 */
19
 
20
/* fftw.h -- system-wide definitions */
21
/* $Id: fftw-int.h,v 1.1 2003-03-24 11:14:54 pj Exp $ */
22
 
23
#ifndef FFTW_INT_H
24
#define FFTW_INT_H
25
#include <conffftw.h>
26
#include <fftw.h>
27
 
28
#ifdef __cplusplus
29
extern "C" {
30
#else
31
#endif                          /* __cplusplus */
32
 
33
/****************************************************************************/
34
/*                            Private Functions                             */
35
/****************************************************************************/
36
 
37
extern fftw_twiddle *fftw_create_twiddle(int n, const fftw_codelet_desc *d);
38
extern void fftw_destroy_twiddle(fftw_twiddle *tw);
39
 
40
extern void fftw_strided_copy(int, fftw_complex *, int, fftw_complex *);
41
extern void fftw_executor_simple(int, const fftw_complex *, fftw_complex *,
42
                                 fftw_plan_node *, int, int);
43
 
44
extern fftwnd_plan fftwnd_create_plan_aux(int rank, const int *n,
45
                                          fftw_direction dir, int flags);
46
extern fftw_plan *fftwnd_new_plan_array(int rank);
47
extern fftw_plan *fftwnd_create_plans_generic(fftw_plan *plans,
48
                                              int rank, const int *n,
49
                                              fftw_direction dir, int flags);
50
extern fftw_plan *fftwnd_create_plans_specific(fftw_plan *plans,
51
                                               int rank, const int *n,
52
                                               const int *n_after,
53
                                               fftw_direction dir, int flags,
54
                                               fftw_complex *in, int istride,
55
                                               fftw_complex *out, int ostride);
56
extern int fftwnd_work_size(int rank, const int *n, int flags, int ncopies);
57
 
58
extern void fftwnd_aux(fftwnd_plan p, int cur_dim,
59
                       fftw_complex *in, int istride,
60
                       fftw_complex *out, int ostride,
61
                       fftw_complex *work);
62
extern void fftwnd_aux_howmany(fftwnd_plan p, int cur_dim,
63
                               int howmany,
64
                               fftw_complex *in, int istride, int idist,
65
                               fftw_complex *out, int ostride, int odist,
66
                               fftw_complex *work);
67
 
68
/* wisdom prototypes */
69
enum fftw_wisdom_category {
70
     FFTW_WISDOM, RFFTW_WISDOM
71
};
72
 
73
extern int fftw_wisdom_lookup(int n, int flags, fftw_direction dir,
74
                              enum fftw_wisdom_category category,
75
                              int istride, int ostride,
76
                              enum fftw_node_type *type,
77
                              int *signature, int replace_p);
78
extern void fftw_wisdom_add(int n, int flags, fftw_direction dir,
79
                            enum fftw_wisdom_category cat,
80
                            int istride, int ostride,
81
                            enum fftw_node_type type,
82
                            int signature);
83
 
84
/* Private planner functions: */
85
extern double fftw_estimate_node(fftw_plan_node *p);
86
extern fftw_plan_node *fftw_make_node_notw(int size,
87
                                        const fftw_codelet_desc *config);
88
extern fftw_plan_node *fftw_make_node_real2hc(int size,
89
                                        const fftw_codelet_desc *config);
90
extern fftw_plan_node *fftw_make_node_hc2real(int size,
91
                                        const fftw_codelet_desc *config);
92
extern fftw_plan_node *fftw_make_node_twiddle(int n,
93
                                         const fftw_codelet_desc *config,
94
                                              fftw_plan_node *recurse,
95
                                              int flags);
96
extern fftw_plan_node *fftw_make_node_hc2hc(int n,
97
                                            fftw_direction dir,
98
                                         const fftw_codelet_desc *config,
99
                                            fftw_plan_node *recurse,
100
                                            int flags);
101
extern fftw_plan_node *fftw_make_node_generic(int n, int size,
102
                                              fftw_generic_codelet *codelet,
103
                                              fftw_plan_node *recurse,
104
                                              int flags);
105
extern fftw_plan_node *fftw_make_node_rgeneric(int n, int size,
106
                                               fftw_direction dir,
107
                                               fftw_rgeneric_codelet * codelet,
108
                                               fftw_plan_node *recurse,
109
                                               int flags);
110
extern int fftw_factor(int n);
111
extern fftw_plan_node *fftw_make_node(void);
112
extern fftw_plan fftw_make_plan(int n, fftw_direction dir,
113
                                fftw_plan_node *root, int flags,
114
                                enum fftw_node_type wisdom_type,
115
                                int wisdom_signature);
116
extern void fftw_use_plan(fftw_plan p);
117
extern void fftw_use_node(fftw_plan_node *p);
118
extern void fftw_destroy_plan_internal(fftw_plan p);
119
extern fftw_plan fftw_pick_better(fftw_plan p1, fftw_plan p2);
120
extern fftw_plan fftw_lookup(fftw_plan *table, int n, int flags);
121
extern void fftw_insert(fftw_plan *table, fftw_plan this_plan, int n);
122
extern void fftw_make_empty_table(fftw_plan *table);
123
extern void fftw_destroy_table(fftw_plan *table);
124
extern void fftw_complete_twiddle(fftw_plan_node *p, int n);
125
 
126
extern fftw_plan_node *fftw_make_node_rader(int n, int size,
127
                                            fftw_direction dir,
128
                                            fftw_plan_node *recurse,
129
                                            int flags);
130
extern fftw_rader_data *fftw_rader_top;
131
 
132
/****************************************************************************/
133
/*                           Floating Point Types                           */
134
/****************************************************************************/
135
 
136
/*
137
 * We use these definitions to make it easier for people to change
138
 * FFTW to use long double and similar types. You shouldn't have to
139
 * change this just to use float or double.
140
 */
141
 
142
/*
143
 * Change this if your floating-point constants need to be expressed
144
 * in a special way.  For example, if fftw_real is long double, you
145
 * will need to append L to your fp constants to make them of the
146
 * same precision.  Do this by changing "x" below to "x##L".
147
 */
148
#define FFTW_KONST(x) ((fftw_real) x)
149
 
150
#define FFTW_TRIG_SIN sin
151
#define FFTW_TRIG_COS cos
152
typedef double FFTW_TRIG_REAL;  /* the argument type for sin and cos */
153
 
154
#define FFTW_K2PI FFTW_KONST(6.2831853071795864769252867665590057683943388)
155
 
156
/****************************************************************************/
157
/*                               gcc/x86 hacks                              */
158
/****************************************************************************/
159
 
160
/*
161
 * gcc 2.[78].x and x86 specific hacks.  These macros align the stack
162
 * pointer so that the double precision temporary variables in the
163
 * codelets will be aligned to a multiple of 8 bytes (*way* faster on
164
 * pentium and pentiumpro)
165
 */
166
#ifdef __GNUC__
167
#ifdef __i386__
168
#ifdef FFTW_ENABLE_I386_HACKS
169
#ifndef FFTW_ENABLE_FLOAT
170
#define FFTW_USING_I386_HACKS
171
#define HACK_ALIGN_STACK_EVEN() {                        \
172
     if ((((long) (__builtin_alloca(0))) & 0x7)) __builtin_alloca(4);    \
173
}
174
 
175
#define HACK_ALIGN_STACK_ODD() {                         \
176
     if (!(((long) (__builtin_alloca(0))) & 0x7)) __builtin_alloca(4);   \
177
}
178
 
179
#ifdef FFTW_DEBUG_ALIGNMENT
180
#define ASSERT_ALIGNED_DOUBLE() {                        \
181
     double __foo;                                       \
182
     if ((((long) &__foo) & 0x7)) abort();                \
183
}
184
#endif
185
 
186
#endif
187
#endif
188
#endif
189
#endif
190
 
191
#ifndef HACK_ALIGN_STACK_EVEN
192
#define HACK_ALIGN_STACK_EVEN()
193
#endif
194
#ifndef HACK_ALIGN_STACK_ODD
195
#define HACK_ALIGN_STACK_ODD()
196
#endif
197
#ifndef ASSERT_ALIGNED_DOUBLE
198
#define ASSERT_ALIGNED_DOUBLE()
199
#endif
200
 
201
/****************************************************************************/
202
/*                                  Timers                                  */
203
/****************************************************************************/
204
 
205
/*
206
 * Here, you can use all the nice timers available in your machine.
207
 */
208
 
209
/*
210
 *
211
 Things you should define to include your own clock:
212
 
213
 fftw_time -- the data type used to store a time
214
 
215
 extern fftw_time fftw_get_time(void);
216
 -- a function returning the current time.  (We have
217
 implemented this as a macro in most cases.)
218
 
219
 extern fftw_time fftw_time_diff(fftw_time t1, fftw_time t2);
220
 -- returns the time difference (t1 - t2).
221
 If t1 < t2, it may simply return zero (although this
222
 is not required).  (We have implemented this as a macro
223
 in most cases.)
224
 
225
 extern double fftw_time_to_sec(fftw_time t);
226
 -- returns the time t expressed in seconds, as a double.
227
 (Implemented as a macro in most cases.)
228
 
229
 FFTW_TIME_MIN -- a double-precision macro holding the minimum
230
 time interval (in seconds) for accurate time measurements.
231
 This should probably be at least 100 times the precision of
232
 your clock (we use even longer intervals, to be conservative).
233
 This will determine how long the planner takes to measure
234
 the speeds of different possible plans.
235
 
236
 Bracket all of your definitions with an appropriate #ifdef so that
237
 they will be enabled on your machine.  If you do add your own
238
 high-precision timer code, let us know (at fftw@theory.lcs.mit.edu).
239
 
240
 Only declarations should go in this file.  Any function definitions
241
 that you need should go into timer.c.
242
 */
243
 
244
/*
245
 * define a symbol so that we know that we have the fftw_time_diff
246
 * function/macro (it did not exist prior to FFTW 1.2)
247
 */
248
#define FFTW_HAS_TIME_DIFF
249
 
250
/**********************************************
251
 *              SOLARIS
252
 **********************************************/
253
#if defined(HAVE_GETHRTIME)
254
 
255
/* we use the nanosecond virtual timer */
256
#ifdef HAVE_SYS_TIME_H
257
#include <sys/time.h>
258
#endif
259
 
260
typedef hrtime_t fftw_time;
261
 
262
#define fftw_get_time() gethrtime()
263
#define fftw_time_diff(t1,t2) ((t1) - (t2))
264
#define fftw_time_to_sec(t) ((double) t / 1.0e9)
265
 
266
/*
267
 * a measurement is valid if it runs for at least
268
 * FFTW_TIME_MIN seconds.
269
 */
270
#define FFTW_TIME_MIN (1.0e-4)  /* for Solaris nanosecond timer */
271
#define FFTW_TIME_REPEAT 8
272
 
273
/**********************************************
274
 *        Pentium time stamp counter
275
 **********************************************/
276
#elif defined(__GNUC__) && defined(__i386__) && defined(FFTW_ENABLE_PENTIUM_TIMER)
277
 
278
/*
279
 * Use internal Pentium register (time stamp counter). Resolution
280
 * is 1/FFTW_CYCLES_PER_SEC seconds (e.g. 5 ns for Pentium 200 MHz).
281
 * (This code was contributed by Wolfgang Reimer)
282
 */
283
 
284
#ifndef FFTW_CYCLES_PER_SEC
285
#error "Must define FFTW_CYCLES_PER_SEC in fftw/config.h to use the Pentium cycle counter"
286
#endif
287
 
288
typedef unsigned long long fftw_time;
289
 
290
static __inline__ fftw_time read_tsc()
291
{
292
     struct {
293
          long unsigned lo, hi;
294
     } counter;
295
     long unsigned sav_eax, sav_edx;
296
   __asm__("movl %%eax,%0":"=m"(sav_eax));
297
   __asm__("movl %%edx,%0":"=m"(sav_edx));
298
     __asm__("rdtsc");
299
   __asm__("movl %%eax,%0":"=m"(counter.lo));
300
   __asm__("movl %%edx,%0":"=m"(counter.hi));
301
   __asm__("movl %0,%%eax": : "m"(sav_eax):"eax");
302
   __asm__("movl %0,%%edx": : "m"(sav_edx):"edx");
303
     return *(fftw_time *) & counter;
304
}
305
 
306
#define fftw_get_time()  read_tsc()
307
#define fftw_time_diff(t1,t2) ((t1) - (t2))
308
#define fftw_time_to_sec(t) (((double) (t)) / FFTW_CYCLES_PER_SEC)
309
#define FFTW_TIME_MIN (1.0e-4)  /* for Pentium TSC register */
310
 
311
/************* generic systems having gettimeofday ************/
312
#elif defined(HAVE_GETTIMEOFDAY) || defined(HAVE_BSDGETTIMEOFDAY)
313
#ifdef HAVE_SYS_TIME_H
314
#include <sys/time.h>
315
#endif
316
#ifdef HAVE_UNISTD_H
317
#include <unistd.h>
318
#endif
319
#define FFTW_USE_GETTIMEOFDAY
320
 
321
typedef struct timeval fftw_time;
322
 
323
extern fftw_time fftw_gettimeofday_get_time(void);
324
extern fftw_time fftw_gettimeofday_time_diff(fftw_time t1, fftw_time t2);
325
#define fftw_get_time() fftw_gettimeofday_get_time()
326
#define fftw_time_diff(t1, t2) fftw_gettimeofday_time_diff(t1, t2)
327
#define fftw_time_to_sec(t) ((double)(t).tv_sec + (double)(t).tv_usec * 1.0E-6)
328
 
329
#ifndef FFTW_TIME_MIN
330
/* this should be fine on any system claiming a microsecond timer */
331
#define FFTW_TIME_MIN (1.0e-2)
332
#endif
333
 
334
/**********************************************
335
 *              MACINTOSH
336
 **********************************************/
337
#elif defined(HAVE_MAC_TIMER)
338
 
339
/*
340
 * By default, use the microsecond-timer in the Mac Time Manager.
341
 * Alternatively, by changing the following #if 1 to #if 0, you
342
 * can use the nanosecond timer available *only* on PCI PowerMacs.
343
 */
344
#ifndef HAVE_MAC_PCI_TIMER      /* use time manager */
345
 
346
/*
347
 * Use Macintosh Time Manager routines (maximum resolution is about 20
348
 * microseconds).
349
 */
350
typedef struct fftw_time_struct {
351
     unsigned long hi, lo;
352
} fftw_time;
353
 
354
extern fftw_time get_Mac_microseconds(void);
355
 
356
#define fftw_get_time() get_Mac_microseconds()
357
 
358
/* define as a function instead of a macro: */
359
extern fftw_time fftw_time_diff(fftw_time t1, fftw_time t2);
360
 
361
#define fftw_time_to_sec(t) ((t).lo * 1.0e-6 + 4294967295.0e-6 * (t).hi)
362
 
363
/* very conservative, since timer should be accurate to 20e-6: */
364
/* (although this seems not to be the case in practice) */
365
#define FFTW_TIME_MIN (5.0e-2)  /* for MacOS Time Manager timer */
366
 
367
#else                           /* use nanosecond timer */
368
 
369
/* Use the nanosecond timer available on PCI PowerMacs. */
370
 
371
#include <DriverServices.h>
372
 
373
typedef AbsoluteTime fftw_time;
374
#define fftw_get_time() UpTime()
375
#define fftw_time_diff(t1,t2) SubAbsoluteFromAbsolute(t1,t2)
376
#define fftw_time_to_sec(t) (AbsoluteToNanoseconds(t).lo * 1.0e-9)
377
 
378
/* Extremely conservative minimum time: */
379
/* for MacOS PCI PowerMac nanosecond timer */
380
#define FFTW_TIME_MIN (5.0e-3)
381
 
382
#endif                          /* use nanosecond timer */
383
 
384
/**********************************************
385
 *              WINDOWS
386
 **********************************************/
387
#elif defined(HAVE_WIN32_TIMER)
388
 
389
#include <time.h>
390
 
391
typedef unsigned long fftw_time;
392
extern unsigned long GetPerfTime(void);
393
extern double GetPerfSec(double ticks);
394
 
395
#define fftw_get_time() GetPerfTime()
396
#define fftw_time_diff(t1,t2) ((t1) - (t2))
397
#define fftw_time_to_sec(t) GetPerfSec(t)
398
 
399
#define FFTW_TIME_MIN (5.0e-2)  /* for Win32 timer */
400
 
401
/**********************************************
402
 *              CRAY
403
 **********************************************/
404
#elif defined(_CRAYMPP)         /* Cray MPP system */
405
 
406
double SECONDR(void);           /*
407
                                 * I think you have to link with -lsci to
408
                                 * get this
409
                                 */
410
 
411
typedef double fftw_time;
412
#define fftw_get_time() SECONDR()
413
#define fftw_time_diff(t1,t2) ((t1) - (t2))
414
#define fftw_time_to_sec(t) (t)
415
 
416
#define FFTW_TIME_MIN (1.0e-1)  /* for Cray MPP SECONDR timer */
417
 
418
 
419
 
420
/**********************************************
421
 *              HARTIK
422
 **********************************************/
423
#elif defined(_HARTIK)          /* Hartik RT system */
424
 
425
#include <kernel/kern.h>
426
 
427
typedef  TIME fftw_time;
428
 
429
#define fftw_get_time() sys_gettime(NULL)
430
#define fftw_time_diff(t1,t2) ((t1) - (t2))
431
#define fftw_time_to_sec(t) ((double) t / 1.0e6)
432
 
433
/*
434
 * a measurement is valid if it runs for at least
435
 * FFTW_TIME_MIN seconds.
436
 */
437
#define FFTW_TIME_MIN (1.0e-6)
438
#define FFTW_TIME_REPEAT 8
439
 
440
/**********************************************
441
 *          VANILLA UNIX/ISO C SYSTEMS
442
 **********************************************/
443
/* last resort: use good old Unix clock() */
444
#else
445
 
446
#include <time.h>
447
 
448
typedef clock_t fftw_time;
449
 
450
#ifndef CLOCKS_PER_SEC
451
#ifdef sun
452
/* stupid sunos4 prototypes */
453
#define CLOCKS_PER_SEC 1000000
454
extern long clock(void);
455
#else                           /* not sun, we don't know CLOCKS_PER_SEC */
456
#error Please define CLOCKS_PER_SEC
457
#endif
458
#endif
459
 
460
#define fftw_get_time() clock()
461
#define fftw_time_diff(t1,t2) ((t1) - (t2))
462
#define fftw_time_to_sec(t) (((double) (t)) / CLOCKS_PER_SEC)
463
 
464
/*
465
 * ***VERY*** conservative constant: this says that a
466
 * measurement must run for 200ms in order to be valid.
467
 * You had better check the manual of your machine
468
 * to discover if it can do better than this
469
 */
470
#define FFTW_TIME_MIN (2.0e-1)  /* for default clock() timer */
471
 
472
#endif                          /* UNIX clock() */
473
 
474
/* take FFTW_TIME_REPEAT measurements... */
475
#ifndef FFTW_TIME_REPEAT
476
#define FFTW_TIME_REPEAT 4
477
#endif
478
 
479
/* but do not run for more than TIME_LIMIT seconds while measuring one FFT */
480
#ifndef FFTW_TIME_LIMIT
481
#define FFTW_TIME_LIMIT 2.0
482
#endif
483
 
484
#ifdef __cplusplus
485
}                               /* extern "C" */
486
 
487
#endif                          /* __cplusplus */
488
 
489
#endif                          /* FFTW_INT_H */