comparison src/fftw-3.3.3/doc/legacy-fortran.texi @ 10:37bf6b4a2645

Add FFTW3
author Chris Cannam
date Wed, 20 Mar 2013 15:35:50 +0000
parents
children
comparison
equal deleted inserted replaced
9:c0fb53affa76 10:37bf6b4a2645
1 @node Calling FFTW from Legacy Fortran, Upgrading from FFTW version 2, Calling FFTW from Modern Fortran, Top
2 @chapter Calling FFTW from Legacy Fortran
3 @cindex Fortran interface
4
5 This chapter describes the interface to FFTW callable by Fortran code
6 in older compilers not supporting the Fortran 2003 C interoperability
7 features (@pxref{Calling FFTW from Modern Fortran}). This interface
8 has the major disadvantage that it is not type-checked, so if you
9 mistake the argument types or ordering then your program will not have
10 any compiler errors, and will likely crash at runtime. So, greater
11 care is needed. Also, technically interfacing older Fortran versions
12 to C is nonstandard, but in practice we have found that the techniques
13 used in this chapter have worked with all known Fortran compilers for
14 many years.
15
16 The legacy Fortran interface differs from the C interface only in the
17 prefix (@samp{dfftw_} instead of @samp{fftw_} in double precision) and
18 a few other minor details. This Fortran interface is included in the
19 FFTW libraries by default, unless a Fortran compiler isn't found on
20 your system or @code{--disable-fortran} is included in the
21 @code{configure} flags. We assume here that the reader is already
22 familiar with the usage of FFTW in C, as described elsewhere in this
23 manual.
24
25 The MPI parallel interface to FFTW is @emph{not} currently available
26 to legacy Fortran.
27
28 @menu
29 * Fortran-interface routines::
30 * FFTW Constants in Fortran::
31 * FFTW Execution in Fortran::
32 * Fortran Examples::
33 * Wisdom of Fortran?::
34 @end menu
35
36 @c -------------------------------------------------------
37 @node Fortran-interface routines, FFTW Constants in Fortran, Calling FFTW from Legacy Fortran, Calling FFTW from Legacy Fortran
38 @section Fortran-interface routines
39
40 Nearly all of the FFTW functions have Fortran-callable equivalents.
41 The name of the legacy Fortran routine is the same as that of the
42 corresponding C routine, but with the @samp{fftw_} prefix replaced by
43 @samp{dfftw_}.@footnote{Technically, Fortran 77 identifiers are not
44 allowed to have more than 6 characters, nor may they contain
45 underscores. Any compiler that enforces this limitation doesn't
46 deserve to link to FFTW.} The single and long-double precision
47 versions use @samp{sfftw_} and @samp{lfftw_}, respectively, instead of
48 @samp{fftwf_} and @samp{fftwl_}; quadruple precision (@code{real*16})
49 is available on some systems as @samp{fftwq_} (@pxref{Precision}).
50 (Note that @code{long double} on x86 hardware is usually at most
51 80-bit extended precision, @emph{not} quadruple precision.)
52
53 For the most part, all of the arguments to the functions are the same,
54 with the following exceptions:
55
56 @itemize @bullet
57
58 @item
59 @code{plan} variables (what would be of type @code{fftw_plan} in C),
60 must be declared as a type that is at least as big as a pointer
61 (address) on your machine. We recommend using @code{integer*8} everywhere,
62 since this should always be big enough.
63 @cindex portability
64
65 @item
66 Any function that returns a value (e.g. @code{fftw_plan_dft}) is
67 converted into a @emph{subroutine}. The return value is converted into
68 an additional @emph{first} parameter of this subroutine.@footnote{The
69 reason for this is that some Fortran implementations seem to have
70 trouble with C function return values, and vice versa.}
71
72 @item
73 @cindex column-major
74 The Fortran routines expect multi-dimensional arrays to be in
75 @emph{column-major} order, which is the ordinary format of Fortran
76 arrays (@pxref{Multi-dimensional Array Format}). They do this
77 transparently and costlessly simply by reversing the order of the
78 dimensions passed to FFTW, but this has one important consequence for
79 multi-dimensional real-complex transforms, discussed below.
80
81 @item
82 Wisdom import and export is somewhat more tricky because one cannot
83 easily pass files or strings between C and Fortran; see @ref{Wisdom of
84 Fortran?}.
85
86 @item
87 Legacy Fortran cannot use the @code{fftw_malloc} dynamic-allocation routine.
88 If you want to exploit the SIMD FFTW (@pxref{SIMD alignment and fftw_malloc}), you'll
89 need to figure out some other way to ensure that your arrays are at
90 least 16-byte aligned.
91
92 @item
93 @tindex fftw_iodim
94 @cindex guru interface
95 Since Fortran 77 does not have data structures, the @code{fftw_iodim}
96 structure from the guru interface (@pxref{Guru vector and transform
97 sizes}) must be split into separate arguments. In particular, any
98 @code{fftw_iodim} array arguments in the C guru interface become three
99 integer array arguments (@code{n}, @code{is}, and @code{os}) in the
100 Fortran guru interface, all of whose lengths should be equal to the
101 corresponding @code{rank} argument.
102
103 @item
104 The guru planner interface in Fortran does @emph{not} do any automatic
105 translation between column-major and row-major; you are responsible
106 for setting the strides etcetera to correspond to your Fortran arrays.
107 However, as a slight bug that we are preserving for backwards
108 compatibility, the @samp{plan_guru_r2r} in Fortran @emph{does} reverse the
109 order of its @code{kind} array parameter, so the @code{kind} array
110 of that routine should be in the reverse of the order of the iodim
111 arrays (see above).
112
113 @end itemize
114
115 In general, you should take care to use Fortran data types that
116 correspond to (i.e. are the same size as) the C types used by FFTW.
117 In practice, this correspondence is usually straightforward
118 (i.e. @code{integer} corresponds to @code{int}, @code{real}
119 corresponds to @code{float}, etcetera). The native Fortran
120 double/single-precision complex type should be compatible with
121 @code{fftw_complex}/@code{fftwf_complex}. Such simple correspondences
122 are assumed in the examples below.
123 @cindex portability
124
125 @c -------------------------------------------------------
126 @node FFTW Constants in Fortran, FFTW Execution in Fortran, Fortran-interface routines, Calling FFTW from Legacy Fortran
127 @section FFTW Constants in Fortran
128
129 When creating plans in FFTW, a number of constants are used to specify
130 options, such as @code{FFTW_MEASURE} or @code{FFTW_ESTIMATE}. The
131 same constants must be used with the wrapper routines, but of course the
132 C header files where the constants are defined can't be incorporated
133 directly into Fortran code.
134
135 Instead, we have placed Fortran equivalents of the FFTW constant
136 definitions in the file @code{fftw3.f}, which can be found in the same
137 directory as @code{fftw3.h}. If your Fortran compiler supports a
138 preprocessor of some sort, you should be able to @code{include} or
139 @code{#include} this file; otherwise, you can paste it directly into
140 your code.
141
142 @cindex flags
143 In C, you combine different flags (like @code{FFTW_PRESERVE_INPUT} and
144 @code{FFTW_MEASURE}) using the @samp{@code{|}} operator; in Fortran
145 you should just use @samp{@code{+}}. (Take care not to add in the
146 same flag more than once, though. Alternatively, you can use the
147 @code{ior} intrinsic function standardized in Fortran 95.)
148
149 @c -------------------------------------------------------
150 @node FFTW Execution in Fortran, Fortran Examples, FFTW Constants in Fortran, Calling FFTW from Legacy Fortran
151 @section FFTW Execution in Fortran
152
153 In C, in order to use a plan, one normally calls @code{fftw_execute},
154 which executes the plan to perform the transform on the input/output
155 arrays passed when the plan was created (@pxref{Using Plans}). The
156 corresponding subroutine call in legacy Fortran is:
157 @example
158 call dfftw_execute(plan)
159 @end example
160 @findex dfftw_execute
161
162 However, we have had reports that this causes problems with some
163 recent optimizing Fortran compilers. The problem is, because the
164 input/output arrays are not passed as explicit arguments to
165 @code{dfftw_execute}, the semantics of Fortran (unlike C) allow the
166 compiler to assume that the input/output arrays are not changed by
167 @code{dfftw_execute}. As a consequence, certain compilers end up
168 optimizing out or repositioning the call to @code{dfftw_execute},
169 assuming incorrectly that it does nothing.
170
171 There are various workarounds to this, but the safest and simplest
172 thing is to not use @code{dfftw_execute} in Fortran. Instead, use the
173 functions described in @ref{New-array Execute Functions}, which take
174 the input/output arrays as explicit arguments. For example, if the
175 plan is for a complex-data DFT and was created for the arrays
176 @code{in} and @code{out}, you would do:
177 @example
178 call dfftw_execute_dft(plan, in, out)
179 @end example
180 @findex dfftw_execute_dft
181
182 There are a few things to be careful of, however:
183
184 @itemize @bullet
185
186 @item
187 You must use the correct type of execute function, matching the way
188 the plan was created. Complex DFT plans should use
189 @code{dfftw_execute_dft}, Real-input (r2c) DFT plans should use use
190 @code{dfftw_execute_dft_r2c}, and real-output (c2r) DFT plans should
191 use @code{dfftw_execute_dft_c2r}. The various r2r plans should use
192 @code{dfftw_execute_r2r}.
193
194 @item
195 You should normally pass the same input/output arrays that were used when
196 creating the plan. This is always safe.
197
198 @item
199 @emph{If} you pass @emph{different} input/output arrays compared to
200 those used when creating the plan, you must abide by all the
201 restrictions of the new-array execute functions (@pxref{New-array
202 Execute Functions}). The most difficult of these, in Fortran, is the
203 requirement that the new arrays have the same alignment as the
204 original arrays, because there seems to be no way in legacy Fortran to obtain
205 guaranteed-aligned arrays (analogous to @code{fftw_malloc} in C). You
206 can, of course, use the @code{FFTW_UNALIGNED} flag when creating the
207 plan, in which case the plan does not depend on the alignment, but
208 this may sacrifice substantial performance on architectures (like x86)
209 with SIMD instructions (@pxref{SIMD alignment and fftw_malloc}).
210 @ctindex FFTW_UNALIGNED
211
212 @end itemize
213
214 @c -------------------------------------------------------
215 @node Fortran Examples, Wisdom of Fortran?, FFTW Execution in Fortran, Calling FFTW from Legacy Fortran
216 @section Fortran Examples
217
218 In C, you might have something like the following to transform a
219 one-dimensional complex array:
220
221 @example
222 fftw_complex in[N], out[N];
223 fftw_plan plan;
224
225 plan = fftw_plan_dft_1d(N,in,out,FFTW_FORWARD,FFTW_ESTIMATE);
226 fftw_execute(plan);
227 fftw_destroy_plan(plan);
228 @end example
229
230 In Fortran, you would use the following to accomplish the same thing:
231
232 @example
233 double complex in, out
234 dimension in(N), out(N)
235 integer*8 plan
236
237 call dfftw_plan_dft_1d(plan,N,in,out,FFTW_FORWARD,FFTW_ESTIMATE)
238 call dfftw_execute_dft(plan, in, out)
239 call dfftw_destroy_plan(plan)
240 @end example
241 @findex dfftw_plan_dft_1d
242 @findex dfftw_execute_dft
243 @findex dfftw_destroy_plan
244
245 Notice how all routines are called as Fortran subroutines, and the
246 plan is returned via the first argument to @code{dfftw_plan_dft_1d}.
247 Notice also that we changed @code{fftw_execute} to
248 @code{dfftw_execute_dft} (@pxref{FFTW Execution in Fortran}). To do
249 the same thing, but using 8 threads in parallel (@pxref{Multi-threaded
250 FFTW}), you would simply prefix these calls with:
251
252 @example
253 integer iret
254 call dfftw_init_threads(iret)
255 call dfftw_plan_with_nthreads(8)
256 @end example
257 @findex dfftw_init_threads
258 @findex dfftw_plan_with_nthreads
259
260 (You might want to check the value of @code{iret}: if it is zero, it
261 indicates an unlikely error during thread initialization.)
262
263 To transform a three-dimensional array in-place with C, you might do:
264
265 @example
266 fftw_complex arr[L][M][N];
267 fftw_plan plan;
268
269 plan = fftw_plan_dft_3d(L,M,N, arr,arr,
270 FFTW_FORWARD, FFTW_ESTIMATE);
271 fftw_execute(plan);
272 fftw_destroy_plan(plan);
273 @end example
274
275 In Fortran, you would use this instead:
276
277 @example
278 double complex arr
279 dimension arr(L,M,N)
280 integer*8 plan
281
282 call dfftw_plan_dft_3d(plan, L,M,N, arr,arr,
283 & FFTW_FORWARD, FFTW_ESTIMATE)
284 call dfftw_execute_dft(plan, arr, arr)
285 call dfftw_destroy_plan(plan)
286 @end example
287 @findex dfftw_plan_dft_3d
288
289 Note that we pass the array dimensions in the ``natural'' order in both C
290 and Fortran.
291
292 To transform a one-dimensional real array in Fortran, you might do:
293
294 @example
295 double precision in
296 dimension in(N)
297 double complex out
298 dimension out(N/2 + 1)
299 integer*8 plan
300
301 call dfftw_plan_dft_r2c_1d(plan,N,in,out,FFTW_ESTIMATE)
302 call dfftw_execute_dft_r2c(plan, in, out)
303 call dfftw_destroy_plan(plan)
304 @end example
305 @findex dfftw_plan_dft_r2c_1d
306 @findex dfftw_execute_dft_r2c
307
308 To transform a two-dimensional real array, out of place, you might use
309 the following:
310
311 @example
312 double precision in
313 dimension in(M,N)
314 double complex out
315 dimension out(M/2 + 1, N)
316 integer*8 plan
317
318 call dfftw_plan_dft_r2c_2d(plan,M,N,in,out,FFTW_ESTIMATE)
319 call dfftw_execute_dft_r2c(plan, in, out)
320 call dfftw_destroy_plan(plan)
321 @end example
322 @findex dfftw_plan_dft_r2c_2d
323
324 @strong{Important:} Notice that it is the @emph{first} dimension of the
325 complex output array that is cut in half in Fortran, rather than the
326 last dimension as in C. This is a consequence of the interface routines
327 reversing the order of the array dimensions passed to FFTW so that the
328 Fortran program can use its ordinary column-major order.
329 @cindex column-major
330 @cindex r2c/c2r multi-dimensional array format
331
332 @c -------------------------------------------------------
333 @node Wisdom of Fortran?, , Fortran Examples, Calling FFTW from Legacy Fortran
334 @section Wisdom of Fortran?
335
336 In this section, we discuss how one can import/export FFTW wisdom
337 (saved plans) to/from a Fortran program; we assume that the reader is
338 already familiar with wisdom, as described in @ref{Words of
339 Wisdom-Saving Plans}.
340
341 @cindex portability
342 The basic problem is that is difficult to (portably) pass files and
343 strings between Fortran and C, so we cannot provide a direct Fortran
344 equivalent to the @code{fftw_export_wisdom_to_file}, etcetera,
345 functions. Fortran interfaces @emph{are} provided for the functions
346 that do not take file/string arguments, however:
347 @code{dfftw_import_system_wisdom}, @code{dfftw_import_wisdom},
348 @code{dfftw_export_wisdom}, and @code{dfftw_forget_wisdom}.
349 @findex dfftw_import_system_wisdom
350 @findex dfftw_import_wisdom
351 @findex dfftw_export_wisdom
352 @findex dfftw_forget_wisdom
353
354
355 So, for example, to import the system-wide wisdom, you would do:
356
357 @example
358 integer isuccess
359 call dfftw_import_system_wisdom(isuccess)
360 @end example
361
362 As usual, the C return value is turned into a first parameter;
363 @code{isuccess} is non-zero on success and zero on failure (e.g. if
364 there is no system wisdom installed).
365
366 If you want to import/export wisdom from/to an arbitrary file or
367 elsewhere, you can employ the generic @code{dfftw_import_wisdom} and
368 @code{dfftw_export_wisdom} functions, for which you must supply a
369 subroutine to read/write one character at a time. The FFTW package
370 contains an example file @code{doc/f77_wisdom.f} demonstrating how to
371 implement @code{import_wisdom_from_file} and
372 @code{export_wisdom_to_file} subroutines in this way. (These routines
373 cannot be compiled into the FFTW library itself, lest all FFTW-using
374 programs be required to link with the Fortran I/O library.)