Subversion Repositories shark

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
2
<HTML>
3
<HEAD>
4
<!-- This HTML file has been created by texi2html 1.52
5
     from fftw.texi on 18 May 1999 -->
6
 
7
<TITLE>FFTW - Calling FFTW from Fortran</TITLE>
8
</HEAD>
9
<BODY TEXT="#000000" BGCOLOR="#FFFFFF">
10
Go to the <A HREF="fftw_1.html">first</A>, <A HREF="fftw_4.html">previous</A>, <A HREF="fftw_6.html">next</A>, <A HREF="fftw_10.html">last</A> section, <A HREF="fftw_toc.html">table of contents</A>.
11
<P><HR><P>
12
 
13
 
14
<H1><A NAME="SEC62">Calling FFTW from Fortran</A></H1>
15
 
16
<P>
17
<A NAME="IDX290"></A>
18
The standard FFTW libraries include special wrapper functions that allow
19
Fortran programs to call FFTW subroutines.  This chapter describes how
20
those functions may be employed to use FFTW from Fortran.  We assume
21
here that the reader is already familiar with the usage of FFTW in C, as
22
described elsewhere in this manual.
23
 
24
 
25
<P>
26
In general, it is not possible to call C functions directly from
27
Fortran, due to Fortran's inability to pass arguments by value and also
28
because Fortran compilers typically expect identifiers to be mangled
29
<A NAME="IDX291"></A>
30
somehow for linking.  However, if C functions are written in a special
31
way, they <EM>are</EM> callable from Fortran, and we have employed this
32
technique to create Fortran-callable "wrapper" functions around the
33
main FFTW routines.  These wrapper functions are included in the FFTW
34
libraries by default, unless a Fortran compiler isn't found on your
35
system or <CODE>--disable-fortran</CODE> is included in the <CODE>configure</CODE>
36
flags.
37
 
38
 
39
<P>
40
As a result, calling FFTW from Fortran requires little more than
41
appending <SAMP>`<CODE>_f77</CODE>'</SAMP> to the function names and then linking
42
normally with the FFTW libraries.  There are a few wrinkles, however, as
43
we shall discuss below.
44
 
45
 
46
 
47
 
48
<H2><A NAME="SEC63">Wrapper Routines</A></H2>
49
 
50
<P>
51
All of the uniprocessor and multi-threaded transform routines have
52
Fortran-callable wrappers, except for the wisdom import/export functions
53
(since it is not possible to exchange string and file arguments portably
54
with Fortran).  The name of the wrapper routine is the same as that of
55
the corresponding C routine, but with <CODE>fftw/fftwnd/rfftw/rfftwnd</CODE>
56
replaced by <CODE>fftw_f77/fftwnd_f77/rfftw_f77/rfftwnd_f77</CODE>.  For
57
example, in Fortran, instead of calling <CODE>fftw_one</CODE> you would call
58
<CODE>fftw_f77_one</CODE>.<A NAME="DOCF8" HREF="fftw_foot.html#FOOT8">(8)</A>
59
<A NAME="IDX292"></A>
60
For the most part, all of the arguments to the functions are the same,
61
with the following exceptions:
62
 
63
 
64
 
65
<UL>
66
 
67
<LI>
68
 
69
Any function that returns a value (e.g. <CODE>fftw_create_plan</CODE>) is
70
converted into a subroutine.  The return value is converted into an
71
additional (first) parameter of the wrapper subroutine.  (The reason for
72
this is that some Fortran implementations seem to have trouble with C
73
function return values.)
74
 
75
<LI>
76
 
77
<A NAME="IDX293"></A>
78
When performing one-dimensional <CODE>FFTW_IN_PLACE</CODE> transforms, you
79
don't have the option of passing <CODE>NULL</CODE> for the <CODE>out</CODE> argument
80
(since there is no way to pass <CODE>NULL</CODE> from Fortran).  Therefore,
81
when performing such transforms, you <EM>must</EM> allocate and pass a
82
contiguous scratch array of the same size as the transform.  Note that
83
for in-place multi-dimensional (<CODE>(r)fftwnd</CODE>) transforms, the
84
<CODE>out</CODE> argument is ignored, so you can pass anything for that
85
parameter.
86
 
87
<LI>
88
 
89
<A NAME="IDX294"></A>
90
The wrapper routines expect multi-dimensional arrays to be in
91
column-major order, which is the ordinary format of Fortran arrays.
92
They do this transparently and costlessly simply by reversing the order
93
of the dimensions passed to FFTW, but this has one important consequence
94
for multi-dimensional real-complex transforms, discussed below.
95
 
96
<LI>
97
 
98
<CODE>plan</CODE> variables (what would be of type <CODE>fftw_plan</CODE>,
99
<CODE>rfftwnd_plan</CODE>, etcetera, in C), must be declared as a type that is
100
the same size as a pointer (address) on your machine.  (Fortran has no
101
generic pointer type.)  The Fortran <CODE>integer</CODE> type is usually the
102
same size as a pointer, but you need to be wary (especially on 64-bit
103
machines).  (You could also use <CODE>integer*4</CODE> on a 32-bit machine and
104
<CODE>integer*8</CODE> on a 64-bit machine.)  Ugh.  (<CODE>g77</CODE> has a special
105
type, <CODE>integer(kind=7)</CODE>, that is defined to be the same size as a
106
pointer.)
107
 
108
</UL>
109
 
110
<P>
111
<A NAME="IDX295"></A>
112
In general, you should take care to use Fortran data types that
113
correspond to (i.e. are the same size as) the C types used by FFTW.  If
114
your C and Fortran compilers are made by the same vendor, the
115
correspondence is usually straightforward (i.e. <CODE>integer</CODE>
116
corresponds to <CODE>int</CODE>, <CODE>real</CODE> corresponds to <CODE>float</CODE>,
117
etcetera).  Such simple correspondences are assumed in the examples
118
below.  The examples also assume that FFTW was compiled in
119
double precision (the default).
120
 
121
 
122
 
123
 
124
<H2><A NAME="SEC64">FFTW Constants in Fortran</A></H2>
125
 
126
<P>
127
When creating plans in FFTW, a number of constants are used to specify
128
options, such as <CODE>FFTW_FORWARD</CODE> or <CODE>FFTW_USE_WISDOM</CODE>.  The
129
same constants must be used with the wrapper routines, but of course the
130
C header files where the constants are defined can't be incorporated
131
directly into Fortran code.
132
 
133
 
134
<P>
135
Instead, we have placed Fortran equivalents of the FFTW constant
136
definitions in the file <CODE>fortran/fftw_f77.i</CODE> of the FFTW package.
137
If your Fortran compiler supports a preprocessor, you can use that to
138
incorporate this file into your code whenever you need to call FFTW.
139
Otherwise, you will have to paste the constant definitions in directly.
140
They are:
141
 
142
 
143
 
144
<PRE>
145
      integer FFTW_FORWARD,FFTW_BACKWARD
146
      parameter (FFTW_FORWARD=-1,FFTW_BACKWARD=1)
147
 
148
      integer FFTW_REAL_TO_COMPLEX,FFTW_COMPLEX_TO_REAL
149
      parameter (FFTW_REAL_TO_COMPLEX=-1,FFTW_COMPLEX_TO_REAL=1)
150
 
151
      integer FFTW_ESTIMATE,FFTW_MEASURE
152
      parameter (FFTW_ESTIMATE=0,FFTW_MEASURE=1)
153
 
154
      integer FFTW_OUT_OF_PLACE,FFTW_IN_PLACE,FFTW_USE_WISDOM
155
      parameter (FFTW_OUT_OF_PLACE=0)
156
      parameter (FFTW_IN_PLACE=8,FFTW_USE_WISDOM=16)
157
 
158
      integer FFTW_THREADSAFE
159
      parameter (FFTW_THREADSAFE=128)
160
</PRE>
161
 
162
<P>
163
<A NAME="IDX296"></A>
164
In C, you combine different flags (like <CODE>FFTW_USE_WISDOM</CODE> and
165
<CODE>FFTW_MEASURE</CODE>) using the <SAMP>`<CODE>|</CODE>'</SAMP> operator; in Fortran you
166
should just use <SAMP>`<CODE>+</CODE>'</SAMP>.
167
 
168
 
169
 
170
 
171
<H2><A NAME="SEC65">Fortran Examples</A></H2>
172
 
173
<P>
174
In C you might have something like the following to transform a
175
one-dimensional complex array:
176
 
177
 
178
 
179
<PRE>
180
        fftw_complex in[N], *out[N];
181
        fftw_plan plan;
182
 
183
        plan = fftw_create_plan(N,FFTW_FORWARD,FFTW_ESTIMATE);
184
        fftw_one(plan,in,out);
185
        fftw_destroy_plan(plan);
186
</PRE>
187
 
188
<P>
189
In Fortran, you use the following to accomplish the same thing:
190
 
191
 
192
 
193
<PRE>
194
        double complex in, out
195
        dimension in(N), out(N)
196
        integer plan
197
 
198
        call fftw_f77_create_plan(plan,N,FFTW_FORWARD,FFTW_ESTIMATE)
199
        call fftw_f77_one(plan,in,out)
200
        call fftw_f77_destroy_plan(plan)
201
</PRE>
202
 
203
<P>
204
<A NAME="IDX297"></A>
205
<A NAME="IDX298"></A>
206
<A NAME="IDX299"></A>
207
 
208
 
209
<P>
210
Notice how all routines are called as Fortran subroutines, and the plan
211
is returned via the first argument to <CODE>fftw_f77_create_plan</CODE>.  To
212
do the same thing, but using 8 threads in parallel
213
(see Section <A HREF="fftw_4.html#SEC48">Multi-threaded FFTW</A>), you would simply replace the call to
214
<CODE>fftw_f77_one</CODE> with:
215
 
216
 
217
 
218
<PRE>
219
        call fftw_f77_threads_one(8,plan,in,out)
220
</PRE>
221
 
222
<P>
223
<A NAME="IDX300"></A>
224
 
225
 
226
<P>
227
To transform a three-dimensional array in-place with C, you might do:
228
 
229
 
230
 
231
<PRE>
232
        fftw_complex arr[L][M][N];
233
        fftwnd_plan plan;
234
        int n[3] = {L,M,N};
235
 
236
        plan = fftwnd_create_plan(3,n,FFTW_FORWARD,
237
                                  FFTW_ESTIMATE | FFTW_IN_PLACE);
238
        fftwnd_one(plan, arr, 0);
239
        fftwnd_destroy_plan(plan);
240
</PRE>
241
 
242
<P>
243
In Fortran, you would use this instead:
244
 
245
 
246
 
247
<PRE>
248
        double complex arr
249
        dimension arr(L,M,N)
250
        integer n
251
        dimension n(3)
252
        integer plan
253
 
254
        n(1) = L
255
        n(2) = M
256
        n(3) = N
257
        call fftwnd_f77_create_plan(plan,3,n,FFTW_FORWARD,
258
       +                            FFTW_ESTIMATE + FFTW_IN_PLACE)
259
        call fftwnd_f77_one(plan, arr, 0)
260
        call fftwnd_f77_destroy_plan(plan)
261
</PRE>
262
 
263
<P>
264
<A NAME="IDX301"></A>
265
<A NAME="IDX302"></A>
266
<A NAME="IDX303"></A>
267
 
268
 
269
<P>
270
Instead of calling <CODE>fftwnd_f77_create_plan(plan,3,n,...)</CODE>, we could
271
also have called <CODE>fftw3d_f77_create_plan(plan,L,M,N,...)</CODE>.
272
<A NAME="IDX304"></A>
273
 
274
 
275
<P>
276
Note that we pass the array dimensions in the "natural" order; also
277
note that the last argument to <CODE>fftwnd_f77</CODE> is ignored since the
278
transform is <CODE>FFTW_IN_PLACE</CODE>.
279
 
280
 
281
<P>
282
To transform a one-dimensional real array in Fortran, you might do:
283
 
284
 
285
 
286
<PRE>
287
        double precision in, out
288
        dimension in(N), out(N)
289
        integer plan
290
 
291
        call rfftw_f77_create_plan(plan,N,FFTW_REAL_TO_COMPLEX,
292
       +                           FFTW_ESTIMATE)
293
        call rfftw_f77_one(plan,in,out)
294
        call rfftw_f77_destroy_plan(plan)
295
</PRE>
296
 
297
<P>
298
<A NAME="IDX305"></A>
299
<A NAME="IDX306"></A>
300
<A NAME="IDX307"></A>
301
 
302
 
303
<P>
304
To transform a two-dimensional real array, out of place, you might use
305
the following:
306
 
307
 
308
 
309
<PRE>
310
        double precision in
311
        double complex out
312
        dimension in(M,N), out(M/2 + 1, N)
313
        integer plan
314
 
315
        call rfftw2d_f77_create_plan(plan,M,N,FFTW_REAL_TO_COMPLEX,
316
       +                             FFTW_ESTIMATE)
317
        call rfftwnd_f77_one_real_to_complex(plan, in, out)
318
        call rfftwnd_f77_destroy_plan(plan)
319
</PRE>
320
 
321
<P>
322
<A NAME="IDX308"></A>
323
<A NAME="IDX309"></A>
324
<A NAME="IDX310"></A>
325
 
326
 
327
<P>
328
<B>Important:</B> Notice that it is the <EM>first</EM> dimension of the
329
complex output array that is cut in half in Fortran, rather than the
330
last dimension as in C.  This is a consequence of the wrapper routines
331
reversing the order of the array dimensions passed to FFTW so that the
332
Fortran program can use its ordinary column-major order.
333
<A NAME="IDX311"></A>
334
<A NAME="IDX312"></A>
335
 
336
 
337
<P><HR><P>
338
Go to the <A HREF="fftw_1.html">first</A>, <A HREF="fftw_4.html">previous</A>, <A HREF="fftw_6.html">next</A>, <A HREF="fftw_10.html">last</A> section, <A HREF="fftw_toc.html">table of contents</A>.
339
</BODY>
340
</HTML>