cannam@95: This is fftw3.info, produced by makeinfo version 4.13 from fftw3.texi. cannam@95: cannam@95: This manual is for FFTW (version 3.3.3, 25 November 2012). cannam@95: cannam@95: Copyright (C) 2003 Matteo Frigo. cannam@95: cannam@95: Copyright (C) 2003 Massachusetts Institute of Technology. cannam@95: cannam@95: Permission is granted to make and distribute verbatim copies of cannam@95: this manual provided the copyright notice and this permission cannam@95: notice are preserved on all copies. cannam@95: cannam@95: Permission is granted to copy and distribute modified versions of cannam@95: this manual under the conditions for verbatim copying, provided cannam@95: that the entire resulting derived work is distributed under the cannam@95: terms of a permission notice identical to this one. cannam@95: cannam@95: Permission is granted to copy and distribute translations of this cannam@95: manual into another language, under the above conditions for cannam@95: modified versions, except that this permission notice may be cannam@95: stated in a translation approved by the Free Software Foundation. cannam@95: cannam@95: INFO-DIR-SECTION Texinfo documentation system cannam@95: START-INFO-DIR-ENTRY cannam@95: * fftw3: (fftw3). FFTW User's Manual. cannam@95: END-INFO-DIR-ENTRY cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) cannam@95: cannam@95: FFTW User Manual cannam@95: **************** cannam@95: cannam@95: Welcome to FFTW, the Fastest Fourier Transform in the West. FFTW is a cannam@95: collection of fast C routines to compute the discrete Fourier transform. cannam@95: This manual documents FFTW version 3.3.3. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Introduction:: cannam@95: * Tutorial:: cannam@95: * Other Important Topics:: cannam@95: * FFTW Reference:: cannam@95: * Multi-threaded FFTW:: cannam@95: * Distributed-memory FFTW with MPI:: cannam@95: * Calling FFTW from Modern Fortran:: cannam@95: * Calling FFTW from Legacy Fortran:: cannam@95: * Upgrading from FFTW version 2:: cannam@95: * Installation and Customization:: cannam@95: * Acknowledgments:: cannam@95: * License and Copyright:: cannam@95: * Concept Index:: cannam@95: * Library Index:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Introduction, Next: Tutorial, Prev: Top, Up: Top cannam@95: cannam@95: 1 Introduction cannam@95: ************** cannam@95: cannam@95: This manual documents version 3.3.3 of FFTW, the _Fastest Fourier cannam@95: Transform in the West_. FFTW is a comprehensive collection of fast C cannam@95: routines for computing the discrete Fourier transform (DFT) and various cannam@95: special cases thereof. cannam@95: * FFTW computes the DFT of complex data, real data, even- or cannam@95: odd-symmetric real data (these symmetric transforms are usually cannam@95: known as the discrete cosine or sine transform, respectively), and cannam@95: the discrete Hartley transform (DHT) of real data. cannam@95: cannam@95: * The input data can have arbitrary length. FFTW employs O(n cannam@95: log n) algorithms for all lengths, including prime numbers. cannam@95: cannam@95: * FFTW supports arbitrary multi-dimensional data. cannam@95: cannam@95: * FFTW supports the SSE, SSE2, AVX, Altivec, and MIPS PS instruction cannam@95: sets. cannam@95: cannam@95: * FFTW includes parallel (multi-threaded) transforms for cannam@95: shared-memory systems. cannam@95: cannam@95: * Starting with version 3.3, FFTW includes distributed-memory cannam@95: parallel transforms using MPI. cannam@95: cannam@95: We assume herein that you are familiar with the properties and uses cannam@95: of the DFT that are relevant to your application. Otherwise, see e.g. cannam@95: `The Fast Fourier Transform and Its Applications' by E. O. Brigham cannam@95: (Prentice-Hall, Englewood Cliffs, NJ, 1988). Our web page cannam@95: (http://www.fftw.org) also has links to FFT-related information online. cannam@95: cannam@95: In order to use FFTW effectively, you need to learn one basic concept cannam@95: of FFTW's internal structure: FFTW does not use a fixed algorithm for cannam@95: computing the transform, but instead it adapts the DFT algorithm to cannam@95: details of the underlying hardware in order to maximize performance. cannam@95: Hence, the computation of the transform is split into two phases. cannam@95: First, FFTW's "planner" "learns" the fastest way to compute the cannam@95: transform on your machine. The planner produces a data structure cannam@95: called a "plan" that contains this information. Subsequently, the plan cannam@95: is "executed" to transform the array of input data as dictated by the cannam@95: plan. The plan can be reused as many times as needed. In typical cannam@95: high-performance applications, many transforms of the same size are cannam@95: computed and, consequently, a relatively expensive initialization of cannam@95: this sort is acceptable. On the other hand, if you need a single cannam@95: transform of a given size, the one-time cost of the planner becomes cannam@95: significant. For this case, FFTW provides fast planners based on cannam@95: heuristics or on previously computed plans. cannam@95: cannam@95: FFTW supports transforms of data with arbitrary length, rank, cannam@95: multiplicity, and a general memory layout. In simple cases, however, cannam@95: this generality may be unnecessary and confusing. Consequently, we cannam@95: organized the interface to FFTW into three levels of increasing cannam@95: generality. cannam@95: * The "basic interface" computes a single transform of cannam@95: contiguous data. cannam@95: cannam@95: * The "advanced interface" computes transforms of multiple or cannam@95: strided arrays. cannam@95: cannam@95: * The "guru interface" supports the most general data layouts, cannam@95: multiplicities, and strides. cannam@95: We expect that most users will be best served by the basic interface, cannam@95: whereas the guru interface requires careful attention to the cannam@95: documentation to avoid problems. cannam@95: cannam@95: Besides the automatic performance adaptation performed by the cannam@95: planner, it is also possible for advanced users to customize FFTW cannam@95: manually. For example, if code space is a concern, we provide a tool cannam@95: that links only the subset of FFTW needed by your application. cannam@95: Conversely, you may need to extend FFTW because the standard cannam@95: distribution is not sufficient for your needs. For example, the cannam@95: standard FFTW distribution works most efficiently for arrays whose size cannam@95: can be factored into small primes (2, 3, 5, and 7), and otherwise it cannam@95: uses a slower general-purpose routine. If you need efficient cannam@95: transforms of other sizes, you can use FFTW's code generator, which cannam@95: produces fast C programs ("codelets") for any particular array size you cannam@95: may care about. For example, if you need transforms of size 513 = 19 x cannam@95: 3^3, you can customize FFTW to support the factor 19 efficiently. cannam@95: cannam@95: For more information regarding FFTW, see the paper, "The Design and cannam@95: Implementation of FFTW3," by M. Frigo and S. G. Johnson, which was an cannam@95: invited paper in `Proc. IEEE' 93 (2), p. 216 (2005). The code cannam@95: generator is described in the paper "A fast Fourier transform compiler", by cannam@95: M. Frigo, in the `Proceedings of the 1999 ACM SIGPLAN Conference on cannam@95: Programming Language Design and Implementation (PLDI), Atlanta, cannam@95: Georgia, May 1999'. These papers, along with the latest version of cannam@95: FFTW, the FAQ, benchmarks, and other links, are available at the FFTW cannam@95: home page (http://www.fftw.org). cannam@95: cannam@95: The current version of FFTW incorporates many good ideas from the cannam@95: past thirty years of FFT literature. In one way or another, FFTW uses cannam@95: the Cooley-Tukey algorithm, the prime factor algorithm, Rader's cannam@95: algorithm for prime sizes, and a split-radix algorithm (with a cannam@95: "conjugate-pair" variation pointed out to us by Dan Bernstein). FFTW's cannam@95: code generator also produces new algorithms that we do not completely cannam@95: understand. The reader is referred to the cited papers for the cannam@95: appropriate references. cannam@95: cannam@95: The rest of this manual is organized as follows. We first discuss cannam@95: the sequential (single-processor) implementation. We start by cannam@95: describing the basic interface/features of FFTW in *note Tutorial::. cannam@95: Next, *note Other Important Topics:: discusses data alignment (*note cannam@95: SIMD alignment and fftw_malloc::), the storage scheme of cannam@95: multi-dimensional arrays (*note Multi-dimensional Array Format::), and cannam@95: FFTW's mechanism for storing plans on disk (*note Words of cannam@95: Wisdom-Saving Plans::). Next, *note FFTW Reference:: provides cannam@95: comprehensive documentation of all FFTW's features. Parallel cannam@95: transforms are discussed in their own chapters: *note Multi-threaded cannam@95: FFTW:: and *note Distributed-memory FFTW with MPI::. Fortran cannam@95: programmers can also use FFTW, as described in *note Calling FFTW from cannam@95: Legacy Fortran:: and *note Calling FFTW from Modern Fortran::. *note cannam@95: Installation and Customization:: explains how to install FFTW in your cannam@95: computer system and how to adapt FFTW to your needs. License and cannam@95: copyright information is given in *note License and Copyright::. cannam@95: Finally, we thank all the people who helped us in *note cannam@95: Acknowledgments::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Tutorial, Next: Other Important Topics, Prev: Introduction, Up: Top cannam@95: cannam@95: 2 Tutorial cannam@95: ********** cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Complex One-Dimensional DFTs:: cannam@95: * Complex Multi-Dimensional DFTs:: cannam@95: * One-Dimensional DFTs of Real Data:: cannam@95: * Multi-Dimensional DFTs of Real Data:: cannam@95: * More DFTs of Real Data:: cannam@95: cannam@95: This chapter describes the basic usage of FFTW, i.e., how to compute the cannam@95: Fourier transform of a single array. This chapter tells the truth, but cannam@95: not the _whole_ truth. Specifically, FFTW implements additional cannam@95: routines and flags that are not documented here, although in many cases cannam@95: we try to indicate where added capabilities exist. For more complete cannam@95: information, see *note FFTW Reference::. (Note that you need to cannam@95: compile and install FFTW before you can use it in a program. For the cannam@95: details of the installation, see *note Installation and cannam@95: Customization::.) cannam@95: cannam@95: We recommend that you read this tutorial in order.(1) At the least, cannam@95: read the first section (*note Complex One-Dimensional DFTs::) before cannam@95: reading any of the others, even if your main interest lies in one of cannam@95: the other transform types. cannam@95: cannam@95: Users of FFTW version 2 and earlier may also want to read *note cannam@95: Upgrading from FFTW version 2::. cannam@95: cannam@95: ---------- Footnotes ---------- cannam@95: cannam@95: (1) You can read the tutorial in bit-reversed order after computing cannam@95: your first transform. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Complex One-Dimensional DFTs, Next: Complex Multi-Dimensional DFTs, Prev: Tutorial, Up: Tutorial cannam@95: cannam@95: 2.1 Complex One-Dimensional DFTs cannam@95: ================================ cannam@95: cannam@95: Plan: To bother about the best method of accomplishing an cannam@95: accidental result. [Ambrose Bierce, `The Enlarged Devil's cannam@95: Dictionary'.] cannam@95: cannam@95: The basic usage of FFTW to compute a one-dimensional DFT of size `N' cannam@95: is simple, and it typically looks something like this code: cannam@95: cannam@95: #include cannam@95: ... cannam@95: { cannam@95: fftw_complex *in, *out; cannam@95: fftw_plan p; cannam@95: ... cannam@95: in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); cannam@95: out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); cannam@95: p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); cannam@95: ... cannam@95: fftw_execute(p); /* repeat as needed */ cannam@95: ... cannam@95: fftw_destroy_plan(p); cannam@95: fftw_free(in); fftw_free(out); cannam@95: } cannam@95: cannam@95: You must link this code with the `fftw3' library. On Unix systems, cannam@95: link with `-lfftw3 -lm'. cannam@95: cannam@95: The example code first allocates the input and output arrays. You cannam@95: can allocate them in any way that you like, but we recommend using cannam@95: `fftw_malloc', which behaves like `malloc' except that it properly cannam@95: aligns the array when SIMD instructions (such as SSE and Altivec) are cannam@95: available (*note SIMD alignment and fftw_malloc::). [Alternatively, we cannam@95: provide a convenient wrapper function `fftw_alloc_complex(N)' which has cannam@95: the same effect.] cannam@95: cannam@95: The data is an array of type `fftw_complex', which is by default a cannam@95: `double[2]' composed of the real (`in[i][0]') and imaginary cannam@95: (`in[i][1]') parts of a complex number. cannam@95: cannam@95: The next step is to create a "plan", which is an object that cannam@95: contains all the data that FFTW needs to compute the FFT. This cannam@95: function creates the plan: cannam@95: cannam@95: fftw_plan fftw_plan_dft_1d(int n, fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: cannam@95: The first argument, `n', is the size of the transform you are trying cannam@95: to compute. The size `n' can be any positive integer, but sizes that cannam@95: are products of small factors are transformed most efficiently cannam@95: (although prime sizes still use an O(n log n) algorithm). cannam@95: cannam@95: The next two arguments are pointers to the input and output arrays of cannam@95: the transform. These pointers can be equal, indicating an "in-place" cannam@95: transform. cannam@95: cannam@95: The fourth argument, `sign', can be either `FFTW_FORWARD' (`-1') or cannam@95: `FFTW_BACKWARD' (`+1'), and indicates the direction of the transform cannam@95: you are interested in; technically, it is the sign of the exponent in cannam@95: the transform. cannam@95: cannam@95: The `flags' argument is usually either `FFTW_MEASURE' or `FFTW_ESTIMATE'. cannam@95: `FFTW_MEASURE' instructs FFTW to run and measure the execution time of cannam@95: several FFTs in order to find the best way to compute the transform of cannam@95: size `n'. This process takes some time (usually a few seconds), cannam@95: depending on your machine and on the size of the transform. cannam@95: `FFTW_ESTIMATE', on the contrary, does not run any computation and just cannam@95: builds a reasonable plan that is probably sub-optimal. In short, if cannam@95: your program performs many transforms of the same size and cannam@95: initialization time is not important, use `FFTW_MEASURE'; otherwise use cannam@95: the estimate. cannam@95: cannam@95: _You must create the plan before initializing the input_, because cannam@95: `FFTW_MEASURE' overwrites the `in'/`out' arrays. (Technically, cannam@95: `FFTW_ESTIMATE' does not touch your arrays, but you should always cannam@95: create plans first just to be sure.) cannam@95: cannam@95: Once the plan has been created, you can use it as many times as you cannam@95: like for transforms on the specified `in'/`out' arrays, computing the cannam@95: actual transforms via `fftw_execute(plan)': cannam@95: void fftw_execute(const fftw_plan plan); cannam@95: cannam@95: The DFT results are stored in-order in the array `out', with the cannam@95: zero-frequency (DC) component in `out[0]'. If `in != out', the cannam@95: transform is "out-of-place" and the input array `in' is not modified. cannam@95: Otherwise, the input array is overwritten with the transform. cannam@95: cannam@95: If you want to transform a _different_ array of the same size, you cannam@95: can create a new plan with `fftw_plan_dft_1d' and FFTW automatically cannam@95: reuses the information from the previous plan, if possible. cannam@95: Alternatively, with the "guru" interface you can apply a given plan to cannam@95: a different array, if you are careful. *Note FFTW Reference::. cannam@95: cannam@95: When you are done with the plan, you deallocate it by calling cannam@95: `fftw_destroy_plan(plan)': cannam@95: void fftw_destroy_plan(fftw_plan plan); cannam@95: If you allocate an array with `fftw_malloc()' you must deallocate it cannam@95: with `fftw_free()'. Do not use `free()' or, heaven forbid, `delete'. cannam@95: cannam@95: FFTW computes an _unnormalized_ DFT. Thus, computing a forward cannam@95: followed by a backward transform (or vice versa) results in the original cannam@95: array scaled by `n'. For the definition of the DFT, see *note What cannam@95: FFTW Really Computes::. cannam@95: cannam@95: If you have a C compiler, such as `gcc', that supports the C99 cannam@95: standard, and you `#include ' _before_ `', then cannam@95: `fftw_complex' is the native double-precision complex type and you can cannam@95: manipulate it with ordinary arithmetic. Otherwise, FFTW defines its cannam@95: own complex type, which is bit-compatible with the C99 complex type. cannam@95: *Note Complex numbers::. (The C++ `' template class may also cannam@95: be usable via a typecast.) cannam@95: cannam@95: To use single or long-double precision versions of FFTW, replace the cannam@95: `fftw_' prefix by `fftwf_' or `fftwl_' and link with `-lfftw3f' or cannam@95: `-lfftw3l', but use the _same_ `' header file. cannam@95: cannam@95: Many more flags exist besides `FFTW_MEASURE' and `FFTW_ESTIMATE'. cannam@95: For example, use `FFTW_PATIENT' if you're willing to wait even longer cannam@95: for a possibly even faster plan (*note FFTW Reference::). You can also cannam@95: save plans for future use, as described by *note Words of Wisdom-Saving cannam@95: Plans::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Complex Multi-Dimensional DFTs, Next: One-Dimensional DFTs of Real Data, Prev: Complex One-Dimensional DFTs, Up: Tutorial cannam@95: cannam@95: 2.2 Complex Multi-Dimensional DFTs cannam@95: ================================== cannam@95: cannam@95: Multi-dimensional transforms work much the same way as one-dimensional cannam@95: transforms: you allocate arrays of `fftw_complex' (preferably using cannam@95: `fftw_malloc'), create an `fftw_plan', execute it as many times as you cannam@95: want with `fftw_execute(plan)', and clean up with cannam@95: `fftw_destroy_plan(plan)' (and `fftw_free'). cannam@95: cannam@95: FFTW provides two routines for creating plans for 2d and 3d cannam@95: transforms, and one routine for creating plans of arbitrary cannam@95: dimensionality. The 2d and 3d routines have the following signature: cannam@95: fftw_plan fftw_plan_dft_2d(int n0, int n1, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: fftw_plan fftw_plan_dft_3d(int n0, int n1, int n2, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: cannam@95: These routines create plans for `n0' by `n1' two-dimensional (2d) cannam@95: transforms and `n0' by `n1' by `n2' 3d transforms, respectively. All cannam@95: of these transforms operate on contiguous arrays in the C-standard cannam@95: "row-major" order, so that the last dimension has the fastest-varying cannam@95: index in the array. This layout is described further in *note cannam@95: Multi-dimensional Array Format::. cannam@95: cannam@95: FFTW can also compute transforms of higher dimensionality. In order cannam@95: to avoid confusion between the various meanings of the the word cannam@95: "dimension", we use the term _rank_ to denote the number of independent cannam@95: indices in an array.(1) For example, we say that a 2d transform has cannam@95: rank 2, a 3d transform has rank 3, and so on. You can plan transforms cannam@95: of arbitrary rank by means of the following function: cannam@95: cannam@95: fftw_plan fftw_plan_dft(int rank, const int *n, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: cannam@95: Here, `n' is a pointer to an array `n[rank]' denoting an `n[0]' by cannam@95: `n[1]' by ... by `n[rank-1]' transform. Thus, for example, the call cannam@95: fftw_plan_dft_2d(n0, n1, in, out, sign, flags); cannam@95: is equivalent to the following code fragment: cannam@95: int n[2]; cannam@95: n[0] = n0; cannam@95: n[1] = n1; cannam@95: fftw_plan_dft(2, n, in, out, sign, flags); cannam@95: `fftw_plan_dft' is not restricted to 2d and 3d transforms, however, cannam@95: but it can plan transforms of arbitrary rank. cannam@95: cannam@95: You may have noticed that all the planner routines described so far cannam@95: have overlapping functionality. For example, you can plan a 1d or 2d cannam@95: transform by using `fftw_plan_dft' with a `rank' of `1' or `2', or even cannam@95: by calling `fftw_plan_dft_3d' with `n0' and/or `n1' equal to `1' (with cannam@95: no loss in efficiency). This pattern continues, and FFTW's planning cannam@95: routines in general form a "partial order," sequences of interfaces cannam@95: with strictly increasing generality but correspondingly greater cannam@95: complexity. cannam@95: cannam@95: `fftw_plan_dft' is the most general complex-DFT routine that we cannam@95: describe in this tutorial, but there are also the advanced and guru cannam@95: interfaces, which allow one to efficiently combine multiple/strided cannam@95: transforms into a single FFTW plan, transform a subset of a larger cannam@95: multi-dimensional array, and/or to handle more general complex-number cannam@95: formats. For more information, see *note FFTW Reference::. cannam@95: cannam@95: ---------- Footnotes ---------- cannam@95: cannam@95: (1) The term "rank" is commonly used in the APL, FORTRAN, and Common cannam@95: Lisp traditions, although it is not so common in the C world. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: One-Dimensional DFTs of Real Data, Next: Multi-Dimensional DFTs of Real Data, Prev: Complex Multi-Dimensional DFTs, Up: Tutorial cannam@95: cannam@95: 2.3 One-Dimensional DFTs of Real Data cannam@95: ===================================== cannam@95: cannam@95: In many practical applications, the input data `in[i]' are purely real cannam@95: numbers, in which case the DFT output satisfies the "Hermitian" redundancy: cannam@95: `out[i]' is the conjugate of `out[n-i]'. It is possible to take cannam@95: advantage of these circumstances in order to achieve roughly a factor cannam@95: of two improvement in both speed and memory usage. cannam@95: cannam@95: In exchange for these speed and space advantages, the user sacrifices cannam@95: some of the simplicity of FFTW's complex transforms. First of all, the cannam@95: input and output arrays are of _different sizes and types_: the input cannam@95: is `n' real numbers, while the output is `n/2+1' complex numbers (the cannam@95: non-redundant outputs); this also requires slight "padding" of the cannam@95: input array for in-place transforms. Second, the inverse transform cannam@95: (complex to real) has the side-effect of _overwriting its input array_, cannam@95: by default. Neither of these inconveniences should pose a serious cannam@95: problem for users, but it is important to be aware of them. cannam@95: cannam@95: The routines to perform real-data transforms are almost the same as cannam@95: those for complex transforms: you allocate arrays of `double' and/or cannam@95: `fftw_complex' (preferably using `fftw_malloc' or cannam@95: `fftw_alloc_complex'), create an `fftw_plan', execute it as many times cannam@95: as you want with `fftw_execute(plan)', and clean up with cannam@95: `fftw_destroy_plan(plan)' (and `fftw_free'). The only differences are cannam@95: that the input (or output) is of type `double' and there are new cannam@95: routines to create the plan. In one dimension: cannam@95: cannam@95: fftw_plan fftw_plan_dft_r2c_1d(int n, double *in, fftw_complex *out, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_dft_c2r_1d(int n, fftw_complex *in, double *out, cannam@95: unsigned flags); cannam@95: cannam@95: for the real input to complex-Hermitian output ("r2c") and cannam@95: complex-Hermitian input to real output ("c2r") transforms. Unlike the cannam@95: complex DFT planner, there is no `sign' argument. Instead, r2c DFTs cannam@95: are always `FFTW_FORWARD' and c2r DFTs are always `FFTW_BACKWARD'. (For cannam@95: single/long-double precision `fftwf' and `fftwl', `double' should be cannam@95: replaced by `float' and `long double', respectively.) cannam@95: cannam@95: Here, `n' is the "logical" size of the DFT, not necessarily the cannam@95: physical size of the array. In particular, the real (`double') array cannam@95: has `n' elements, while the complex (`fftw_complex') array has `n/2+1' cannam@95: elements (where the division is rounded down). For an in-place cannam@95: transform, `in' and `out' are aliased to the same array, which must be cannam@95: big enough to hold both; so, the real array would actually have cannam@95: `2*(n/2+1)' elements, where the elements beyond the first `n' are cannam@95: unused padding. (Note that this is very different from the concept of cannam@95: "zero-padding" a transform to a larger length, which changes the cannam@95: logical size of the DFT by actually adding new input data.) The kth cannam@95: element of the complex array is exactly the same as the kth element of cannam@95: the corresponding complex DFT. All positive `n' are supported; cannam@95: products of small factors are most efficient, but an O(n log n) cannam@95: algorithm is used even for prime sizes. cannam@95: cannam@95: As noted above, the c2r transform destroys its input array even for cannam@95: out-of-place transforms. This can be prevented, if necessary, by cannam@95: including `FFTW_PRESERVE_INPUT' in the `flags', with unfortunately some cannam@95: sacrifice in performance. This flag is also not currently supported cannam@95: for multi-dimensional real DFTs (next section). cannam@95: cannam@95: Readers familiar with DFTs of real data will recall that the 0th (the cannam@95: "DC") and `n/2'-th (the "Nyquist" frequency, when `n' is even) elements cannam@95: of the complex output are purely real. Some implementations therefore cannam@95: store the Nyquist element where the DC imaginary part would go, in cannam@95: order to make the input and output arrays the same size. Such packing, cannam@95: however, does not generalize well to multi-dimensional transforms, and cannam@95: the space savings are miniscule in any case; FFTW does not support it. cannam@95: cannam@95: An alternative interface for one-dimensional r2c and c2r DFTs can be cannam@95: found in the `r2r' interface (*note The Halfcomplex-format DFT::), with cannam@95: "halfcomplex"-format output that _is_ the same size (and type) as the cannam@95: input array. That interface, although it is not very useful for cannam@95: multi-dimensional transforms, may sometimes yield better performance. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Multi-Dimensional DFTs of Real Data, Next: More DFTs of Real Data, Prev: One-Dimensional DFTs of Real Data, Up: Tutorial cannam@95: cannam@95: 2.4 Multi-Dimensional DFTs of Real Data cannam@95: ======================================= cannam@95: cannam@95: Multi-dimensional DFTs of real data use the following planner routines: cannam@95: cannam@95: fftw_plan fftw_plan_dft_r2c_2d(int n0, int n1, cannam@95: double *in, fftw_complex *out, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_dft_r2c_3d(int n0, int n1, int n2, cannam@95: double *in, fftw_complex *out, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_dft_r2c(int rank, const int *n, cannam@95: double *in, fftw_complex *out, cannam@95: unsigned flags); cannam@95: cannam@95: as well as the corresponding `c2r' routines with the input/output cannam@95: types swapped. These routines work similarly to their complex cannam@95: analogues, except for the fact that here the complex output array is cut cannam@95: roughly in half and the real array requires padding for in-place cannam@95: transforms (as in 1d, above). cannam@95: cannam@95: As before, `n' is the logical size of the array, and the cannam@95: consequences of this on the the format of the complex arrays deserve cannam@95: careful attention. Suppose that the real data has dimensions n[0] x cannam@95: n[1] x n[2] x ... x n[d-1] (in row-major order). Then, after an r2c cannam@95: transform, the output is an n[0] x n[1] x n[2] x ... x (n[d-1]/2 + 1) cannam@95: array of `fftw_complex' values in row-major order, corresponding to cannam@95: slightly over half of the output of the corresponding complex DFT. cannam@95: (The division is rounded down.) The ordering of the data is otherwise cannam@95: exactly the same as in the complex-DFT case. cannam@95: cannam@95: For out-of-place transforms, this is the end of the story: the real cannam@95: data is stored as a row-major array of size n[0] x n[1] x n[2] x ... x cannam@95: n[d-1] and the complex data is stored as a row-major array of size cannam@95: n[0] x n[1] x n[2] x ... x (n[d-1]/2 + 1) . cannam@95: cannam@95: For in-place transforms, however, extra padding of the real-data cannam@95: array is necessary because the complex array is larger than the real cannam@95: array, and the two arrays share the same memory locations. Thus, for cannam@95: in-place transforms, the final dimension of the real-data array must be cannam@95: padded with extra values to accommodate the size of the complex cannam@95: data--two values if the last dimension is even and one if it is odd. That cannam@95: is, the last dimension of the real data must physically contain 2 * cannam@95: (n[d-1]/2+1) `double' values (exactly enough to hold the complex data). cannam@95: This physical array size does not, however, change the _logical_ array cannam@95: size--only n[d-1] values are actually stored in the last dimension, and cannam@95: n[d-1] is the last dimension passed to the plan-creation routine. cannam@95: cannam@95: For example, consider the transform of a two-dimensional real array cannam@95: of size `n0' by `n1'. The output of the r2c transform is a cannam@95: two-dimensional complex array of size `n0' by `n1/2+1', where the `y' cannam@95: dimension has been cut nearly in half because of redundancies in the cannam@95: output. Because `fftw_complex' is twice the size of `double', the cannam@95: output array is slightly bigger than the input array. Thus, if we want cannam@95: to compute the transform in place, we must _pad_ the input array so cannam@95: that it is of size `n0' by `2*(n1/2+1)'. If `n1' is even, then there cannam@95: are two padding elements at the end of each row (which need not be cannam@95: initialized, as they are only used for output). cannam@95: cannam@95: These transforms are unnormalized, so an r2c followed by a c2r cannam@95: transform (or vice versa) will result in the original data scaled by cannam@95: the number of real data elements--that is, the product of the (logical) cannam@95: dimensions of the real data. cannam@95: cannam@95: (Because the last dimension is treated specially, if it is equal to cannam@95: `1' the transform is _not_ equivalent to a lower-dimensional r2c/c2r cannam@95: transform. In that case, the last complex dimension also has size `1' cannam@95: (`=1/2+1'), and no advantage is gained over the complex transforms.) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: More DFTs of Real Data, Prev: Multi-Dimensional DFTs of Real Data, Up: Tutorial cannam@95: cannam@95: 2.5 More DFTs of Real Data cannam@95: ========================== cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * The Halfcomplex-format DFT:: cannam@95: * Real even/odd DFTs (cosine/sine transforms):: cannam@95: * The Discrete Hartley Transform:: cannam@95: cannam@95: FFTW supports several other transform types via a unified "r2r" cannam@95: (real-to-real) interface, so called because it takes a real (`double') cannam@95: array and outputs a real array of the same size. These r2r transforms cannam@95: currently fall into three categories: DFTs of real input and cannam@95: complex-Hermitian output in halfcomplex format, DFTs of real input with cannam@95: even/odd symmetry (a.k.a. discrete cosine/sine transforms, DCTs/DSTs), cannam@95: and discrete Hartley transforms (DHTs), all described in more detail by cannam@95: the following sections. cannam@95: cannam@95: The r2r transforms follow the by now familiar interface of creating cannam@95: an `fftw_plan', executing it with `fftw_execute(plan)', and destroying cannam@95: it with `fftw_destroy_plan(plan)'. Furthermore, all r2r transforms cannam@95: share the same planner interface: cannam@95: cannam@95: fftw_plan fftw_plan_r2r_1d(int n, double *in, double *out, cannam@95: fftw_r2r_kind kind, unsigned flags); cannam@95: fftw_plan fftw_plan_r2r_2d(int n0, int n1, double *in, double *out, cannam@95: fftw_r2r_kind kind0, fftw_r2r_kind kind1, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_r2r_3d(int n0, int n1, int n2, cannam@95: double *in, double *out, cannam@95: fftw_r2r_kind kind0, cannam@95: fftw_r2r_kind kind1, cannam@95: fftw_r2r_kind kind2, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_r2r(int rank, const int *n, double *in, double *out, cannam@95: const fftw_r2r_kind *kind, unsigned flags); cannam@95: cannam@95: Just as for the complex DFT, these plan 1d/2d/3d/multi-dimensional cannam@95: transforms for contiguous arrays in row-major order, transforming (real) cannam@95: input to output of the same size, where `n' specifies the _physical_ cannam@95: dimensions of the arrays. All positive `n' are supported (with the cannam@95: exception of `n=1' for the `FFTW_REDFT00' kind, noted in the real-even cannam@95: subsection below); products of small factors are most efficient cannam@95: (factorizing `n-1' and `n+1' for `FFTW_REDFT00' and `FFTW_RODFT00' cannam@95: kinds, described below), but an O(n log n) algorithm is used even for cannam@95: prime sizes. cannam@95: cannam@95: Each dimension has a "kind" parameter, of type `fftw_r2r_kind', cannam@95: specifying the kind of r2r transform to be used for that dimension. (In cannam@95: the case of `fftw_plan_r2r', this is an array `kind[rank]' where cannam@95: `kind[i]' is the transform kind for the dimension `n[i]'.) The kind cannam@95: can be one of a set of predefined constants, defined in the following cannam@95: subsections. cannam@95: cannam@95: In other words, FFTW computes the separable product of the specified cannam@95: r2r transforms over each dimension, which can be used e.g. for partial cannam@95: differential equations with mixed boundary conditions. (For some r2r cannam@95: kinds, notably the halfcomplex DFT and the DHT, such a separable cannam@95: product is somewhat problematic in more than one dimension, however, as cannam@95: is described below.) cannam@95: cannam@95: In the current version of FFTW, all r2r transforms except for the cannam@95: halfcomplex type are computed via pre- or post-processing of cannam@95: halfcomplex transforms, and they are therefore not as fast as they cannam@95: could be. Since most other general DCT/DST codes employ a similar cannam@95: algorithm, however, FFTW's implementation should provide at least cannam@95: competitive performance. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: The Halfcomplex-format DFT, Next: Real even/odd DFTs (cosine/sine transforms), Prev: More DFTs of Real Data, Up: More DFTs of Real Data cannam@95: cannam@95: 2.5.1 The Halfcomplex-format DFT cannam@95: -------------------------------- cannam@95: cannam@95: An r2r kind of `FFTW_R2HC' ("r2hc") corresponds to an r2c DFT (*note cannam@95: One-Dimensional DFTs of Real Data::) but with "halfcomplex" format cannam@95: output, and may sometimes be faster and/or more convenient than the cannam@95: latter. The inverse "hc2r" transform is of kind `FFTW_HC2R'. This cannam@95: consists of the non-redundant half of the complex output for a 1d cannam@95: real-input DFT of size `n', stored as a sequence of `n' real numbers cannam@95: (`double') in the format: cannam@95: cannam@95: r0, r1, r2, r(n/2), i((n+1)/2-1), ..., i2, i1 cannam@95: cannam@95: Here, rk is the real part of the kth output, and ik is the imaginary cannam@95: part. (Division by 2 is rounded down.) For a halfcomplex array cannam@95: `hc[n]', the kth component thus has its real part in `hc[k]' and its cannam@95: imaginary part in `hc[n-k]', with the exception of `k' `==' `0' or cannam@95: `n/2' (the latter only if `n' is even)--in these two cases, the cannam@95: imaginary part is zero due to symmetries of the real-input DFT, and is cannam@95: not stored. Thus, the r2hc transform of `n' real values is a cannam@95: halfcomplex array of length `n', and vice versa for hc2r. cannam@95: cannam@95: Aside from the differing format, the output of cannam@95: `FFTW_R2HC'/`FFTW_HC2R' is otherwise exactly the same as for the cannam@95: corresponding 1d r2c/c2r transform (i.e. `FFTW_FORWARD'/`FFTW_BACKWARD' cannam@95: transforms, respectively). Recall that these transforms are cannam@95: unnormalized, so r2hc followed by hc2r will result in the original data cannam@95: multiplied by `n'. Furthermore, like the c2r transform, an cannam@95: out-of-place hc2r transform will _destroy its input_ array. cannam@95: cannam@95: Although these halfcomplex transforms can be used with the cannam@95: multi-dimensional r2r interface, the interpretation of such a separable cannam@95: product of transforms along each dimension is problematic. For example, cannam@95: consider a two-dimensional `n0' by `n1', r2hc by r2hc transform planned cannam@95: by `fftw_plan_r2r_2d(n0, n1, in, out, FFTW_R2HC, FFTW_R2HC, cannam@95: FFTW_MEASURE)'. Conceptually, FFTW first transforms the rows (of size cannam@95: `n1') to produce halfcomplex rows, and then transforms the columns (of cannam@95: size `n0'). Half of these column transforms, however, are of imaginary cannam@95: parts, and should therefore be multiplied by i and combined with the cannam@95: r2hc transforms of the real columns to produce the 2d DFT amplitudes; cannam@95: FFTW's r2r transform does _not_ perform this combination for you. cannam@95: Thus, if a multi-dimensional real-input/output DFT is required, we cannam@95: recommend using the ordinary r2c/c2r interface (*note Multi-Dimensional cannam@95: DFTs of Real Data::). cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Real even/odd DFTs (cosine/sine transforms), Next: The Discrete Hartley Transform, Prev: The Halfcomplex-format DFT, Up: More DFTs of Real Data cannam@95: cannam@95: 2.5.2 Real even/odd DFTs (cosine/sine transforms) cannam@95: ------------------------------------------------- cannam@95: cannam@95: The Fourier transform of a real-even function f(-x) = f(x) is cannam@95: real-even, and i times the Fourier transform of a real-odd function cannam@95: f(-x) = -f(x) is real-odd. Similar results hold for a discrete Fourier cannam@95: transform, and thus for these symmetries the need for complex cannam@95: inputs/outputs is entirely eliminated. Moreover, one gains a factor of cannam@95: two in speed/space from the fact that the data are real, and an cannam@95: additional factor of two from the even/odd symmetry: only the cannam@95: non-redundant (first) half of the array need be stored. The result is cannam@95: the real-even DFT ("REDFT") and the real-odd DFT ("RODFT"), also known cannam@95: as the discrete cosine and sine transforms ("DCT" and "DST"), cannam@95: respectively. cannam@95: cannam@95: (In this section, we describe the 1d transforms; multi-dimensional cannam@95: transforms are just a separable product of these transforms operating cannam@95: along each dimension.) cannam@95: cannam@95: Because of the discrete sampling, one has an additional choice: is cannam@95: the data even/odd around a sampling point, or around the point halfway cannam@95: between two samples? The latter corresponds to _shifting_ the samples cannam@95: by _half_ an interval, and gives rise to several transform variants cannam@95: denoted by REDFTab and RODFTab: a and b are 0 or 1, and indicate cannam@95: whether the input (a) and/or output (b) are shifted by half a sample (1 cannam@95: means it is shifted). These are also known as types I-IV of the DCT cannam@95: and DST, and all four types are supported by FFTW's r2r interface.(1) cannam@95: cannam@95: The r2r kinds for the various REDFT and RODFT types supported by cannam@95: FFTW, along with the boundary conditions at both ends of the _input_ cannam@95: array (`n' real numbers `in[j=0..n-1]'), are: cannam@95: cannam@95: * `FFTW_REDFT00' (DCT-I): even around j=0 and even around j=n-1. cannam@95: cannam@95: * `FFTW_REDFT10' (DCT-II, "the" DCT): even around j=-0.5 and even cannam@95: around j=n-0.5. cannam@95: cannam@95: * `FFTW_REDFT01' (DCT-III, "the" IDCT): even around j=0 and odd cannam@95: around j=n. cannam@95: cannam@95: * `FFTW_REDFT11' (DCT-IV): even around j=-0.5 and odd around j=n-0.5. cannam@95: cannam@95: * `FFTW_RODFT00' (DST-I): odd around j=-1 and odd around j=n. cannam@95: cannam@95: * `FFTW_RODFT10' (DST-II): odd around j=-0.5 and odd around j=n-0.5. cannam@95: cannam@95: * `FFTW_RODFT01' (DST-III): odd around j=-1 and even around j=n-1. cannam@95: cannam@95: * `FFTW_RODFT11' (DST-IV): odd around j=-0.5 and even around j=n-0.5. cannam@95: cannam@95: cannam@95: Note that these symmetries apply to the "logical" array being cannam@95: transformed; *there are no constraints on your physical input data*. cannam@95: So, for example, if you specify a size-5 REDFT00 (DCT-I) of the data cannam@95: abcde, it corresponds to the DFT of the logical even array abcdedcb of cannam@95: size 8. A size-4 REDFT10 (DCT-II) of the data abcd corresponds to the cannam@95: size-8 logical DFT of the even array abcddcba, shifted by half a sample. cannam@95: cannam@95: All of these transforms are invertible. The inverse of R*DFT00 is cannam@95: R*DFT00; of R*DFT10 is R*DFT01 and vice versa (these are often called cannam@95: simply "the" DCT and IDCT, respectively); and of R*DFT11 is R*DFT11. cannam@95: However, the transforms computed by FFTW are unnormalized, exactly like cannam@95: the corresponding real and complex DFTs, so computing a transform cannam@95: followed by its inverse yields the original array scaled by N, where N cannam@95: is the _logical_ DFT size. For REDFT00, N=2(n-1); for RODFT00, cannam@95: N=2(n+1); otherwise, N=2n. cannam@95: cannam@95: Note that the boundary conditions of the transform output array are cannam@95: given by the input boundary conditions of the inverse transform. Thus, cannam@95: the above transforms are all inequivalent in terms of input/output cannam@95: boundary conditions, even neglecting the 0.5 shift difference. cannam@95: cannam@95: FFTW is most efficient when N is a product of small factors; note cannam@95: that this _differs_ from the factorization of the physical size `n' for cannam@95: REDFT00 and RODFT00! There is another oddity: `n=1' REDFT00 transforms cannam@95: correspond to N=0, and so are _not defined_ (the planner will return cannam@95: `NULL'). Otherwise, any positive `n' is supported. cannam@95: cannam@95: For the precise mathematical definitions of these transforms as used cannam@95: by FFTW, see *note What FFTW Really Computes::. (For people accustomed cannam@95: to the DCT/DST, FFTW's definitions have a coefficient of 2 in front of cannam@95: the cos/sin functions so that they correspond precisely to an even/odd cannam@95: DFT of size N. Some authors also include additional multiplicative cannam@95: factors of sqrt(2) for selected inputs and outputs; this makes the cannam@95: transform orthogonal, but sacrifices the direct equivalence to a cannam@95: symmetric DFT.) cannam@95: cannam@95: Which type do you need? cannam@95: ....................... cannam@95: cannam@95: Since the required flavor of even/odd DFT depends upon your problem, cannam@95: you are the best judge of this choice, but we can make a few comments cannam@95: on relative efficiency to help you in your selection. In particular, cannam@95: R*DFT01 and R*DFT10 tend to be slightly faster than R*DFT11 (especially cannam@95: for odd sizes), while the R*DFT00 transforms are sometimes cannam@95: significantly slower (especially for even sizes).(2) cannam@95: cannam@95: Thus, if only the boundary conditions on the transform inputs are cannam@95: specified, we generally recommend R*DFT10 over R*DFT00 and R*DFT01 over cannam@95: R*DFT11 (unless the half-sample shift or the self-inverse property is cannam@95: significant for your problem). cannam@95: cannam@95: If performance is important to you and you are using only small sizes cannam@95: (say n<200), e.g. for multi-dimensional transforms, then you might cannam@95: consider generating hard-coded transforms of those sizes and types that cannam@95: you are interested in (*note Generating your own code::). cannam@95: cannam@95: We are interested in hearing what types of symmetric transforms you cannam@95: find most useful. cannam@95: cannam@95: ---------- Footnotes ---------- cannam@95: cannam@95: (1) There are also type V-VIII transforms, which correspond to a cannam@95: logical DFT of _odd_ size N, independent of whether the physical size cannam@95: `n' is odd, but we do not support these variants. cannam@95: cannam@95: (2) R*DFT00 is sometimes slower in FFTW because we discovered that cannam@95: the standard algorithm for computing this by a pre/post-processed real cannam@95: DFT--the algorithm used in FFTPACK, Numerical Recipes, and other cannam@95: sources for decades now--has serious numerical problems: it already cannam@95: loses several decimal places of accuracy for 16k sizes. There seem to cannam@95: be only two alternatives in the literature that do not suffer cannam@95: similarly: a recursive decomposition into smaller DCTs, which would cannam@95: require a large set of codelets for efficiency and generality, or cannam@95: sacrificing a factor of 2 in speed to use a real DFT of twice the size. cannam@95: We currently employ the latter technique for general n, as well as a cannam@95: limited form of the former method: a split-radix decomposition when n cannam@95: is odd (N a multiple of 4). For N containing many factors of 2, the cannam@95: split-radix method seems to recover most of the speed of the standard cannam@95: algorithm without the accuracy tradeoff. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: The Discrete Hartley Transform, Prev: Real even/odd DFTs (cosine/sine transforms), Up: More DFTs of Real Data cannam@95: cannam@95: 2.5.3 The Discrete Hartley Transform cannam@95: ------------------------------------ cannam@95: cannam@95: If you are planning to use the DHT because you've heard that it is cannam@95: "faster" than the DFT (FFT), *stop here*. The DHT is not faster than cannam@95: the DFT. That story is an old but enduring misconception that was cannam@95: debunked in 1987. cannam@95: cannam@95: The discrete Hartley transform (DHT) is an invertible linear cannam@95: transform closely related to the DFT. In the DFT, one multiplies each cannam@95: input by cos - i * sin (a complex exponential), whereas in the DHT each cannam@95: input is multiplied by simply cos + sin. Thus, the DHT transforms `n' cannam@95: real numbers to `n' real numbers, and has the convenient property of cannam@95: being its own inverse. In FFTW, a DHT (of any positive `n') can be cannam@95: specified by an r2r kind of `FFTW_DHT'. cannam@95: cannam@95: Like the DFT, in FFTW the DHT is unnormalized, so computing a DHT of cannam@95: size `n' followed by another DHT of the same size will result in the cannam@95: original array multiplied by `n'. cannam@95: cannam@95: The DHT was originally proposed as a more efficient alternative to cannam@95: the DFT for real data, but it was subsequently shown that a specialized cannam@95: DFT (such as FFTW's r2hc or r2c transforms) could be just as fast. In cannam@95: FFTW, the DHT is actually computed by post-processing an r2hc cannam@95: transform, so there is ordinarily no reason to prefer it from a cannam@95: performance perspective.(1) However, we have heard rumors that the DHT cannam@95: might be the most appropriate transform in its own right for certain cannam@95: applications, and we would be very interested to hear from anyone who cannam@95: finds it useful. cannam@95: cannam@95: If `FFTW_DHT' is specified for multiple dimensions of a cannam@95: multi-dimensional transform, FFTW computes the separable product of 1d cannam@95: DHTs along each dimension. Unfortunately, this is not quite the same cannam@95: thing as a true multi-dimensional DHT; you can compute the latter, if cannam@95: necessary, with at most `rank-1' post-processing passes [see e.g. H. cannam@95: Hao and R. N. Bracewell, Proc. IEEE 75, 264-266 (1987)]. cannam@95: cannam@95: For the precise mathematical definition of the DHT as used by FFTW, cannam@95: see *note What FFTW Really Computes::. cannam@95: cannam@95: ---------- Footnotes ---------- cannam@95: cannam@95: (1) We provide the DHT mainly as a byproduct of some internal cannam@95: algorithms. FFTW computes a real input/output DFT of _prime_ size by cannam@95: re-expressing it as a DHT plus post/pre-processing and then using cannam@95: Rader's prime-DFT algorithm adapted to the DHT. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Other Important Topics, Next: FFTW Reference, Prev: Tutorial, Up: Top cannam@95: cannam@95: 3 Other Important Topics cannam@95: ************************ cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * SIMD alignment and fftw_malloc:: cannam@95: * Multi-dimensional Array Format:: cannam@95: * Words of Wisdom-Saving Plans:: cannam@95: * Caveats in Using Wisdom:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: SIMD alignment and fftw_malloc, Next: Multi-dimensional Array Format, Prev: Other Important Topics, Up: Other Important Topics cannam@95: cannam@95: 3.1 SIMD alignment and fftw_malloc cannam@95: ================================== cannam@95: cannam@95: SIMD, which stands for "Single Instruction Multiple Data," is a set of cannam@95: special operations supported by some processors to perform a single cannam@95: operation on several numbers (usually 2 or 4) simultaneously. SIMD cannam@95: floating-point instructions are available on several popular CPUs: cannam@95: SSE/SSE2/AVX on recent x86/x86-64 processors, AltiVec (single precision) cannam@95: on some PowerPCs (Apple G4 and higher), NEON on some ARM models, and cannam@95: MIPS Paired Single (currently only in FFTW 3.2.x). FFTW can be cannam@95: compiled to support the SIMD instructions on any of these systems. cannam@95: cannam@95: A program linking to an FFTW library compiled with SIMD support can cannam@95: obtain a nonnegligible speedup for most complex and r2c/c2r transforms. cannam@95: In order to obtain this speedup, however, the arrays of complex (or cannam@95: real) data passed to FFTW must be specially aligned in memory cannam@95: (typically 16-byte aligned), and often this alignment is more stringent cannam@95: than that provided by the usual `malloc' (etc.) allocation routines. cannam@95: cannam@95: In order to guarantee proper alignment for SIMD, therefore, in case cannam@95: your program is ever linked against a SIMD-using FFTW, we recommend cannam@95: allocating your transform data with `fftw_malloc' and de-allocating it cannam@95: with `fftw_free'. These have exactly the same interface and behavior as cannam@95: `malloc'/`free', except that for a SIMD FFTW they ensure that the cannam@95: returned pointer has the necessary alignment (by calling `memalign' or cannam@95: its equivalent on your OS). cannam@95: cannam@95: You are not _required_ to use `fftw_malloc'. You can allocate your cannam@95: data in any way that you like, from `malloc' to `new' (in C++) to a cannam@95: fixed-size array declaration. If the array happens not to be properly cannam@95: aligned, FFTW will not use the SIMD extensions. cannam@95: cannam@95: Since `fftw_malloc' only ever needs to be used for real and complex cannam@95: arrays, we provide two convenient wrapper routines `fftw_alloc_real(N)' cannam@95: and `fftw_alloc_complex(N)' that are equivalent to cannam@95: `(double*)fftw_malloc(sizeof(double) * N)' and cannam@95: `(fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N)', respectively cannam@95: (or their equivalents in other precisions). cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Multi-dimensional Array Format, Next: Words of Wisdom-Saving Plans, Prev: SIMD alignment and fftw_malloc, Up: Other Important Topics cannam@95: cannam@95: 3.2 Multi-dimensional Array Format cannam@95: ================================== cannam@95: cannam@95: This section describes the format in which multi-dimensional arrays are cannam@95: stored in FFTW. We felt that a detailed discussion of this topic was cannam@95: necessary. Since several different formats are common, this topic is cannam@95: often a source of confusion. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Row-major Format:: cannam@95: * Column-major Format:: cannam@95: * Fixed-size Arrays in C:: cannam@95: * Dynamic Arrays in C:: cannam@95: * Dynamic Arrays in C-The Wrong Way:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Row-major Format, Next: Column-major Format, Prev: Multi-dimensional Array Format, Up: Multi-dimensional Array Format cannam@95: cannam@95: 3.2.1 Row-major Format cannam@95: ---------------------- cannam@95: cannam@95: The multi-dimensional arrays passed to `fftw_plan_dft' etcetera are cannam@95: expected to be stored as a single contiguous block in "row-major" order cannam@95: (sometimes called "C order"). Basically, this means that as you step cannam@95: through adjacent memory locations, the first dimension's index varies cannam@95: most slowly and the last dimension's index varies most quickly. cannam@95: cannam@95: To be more explicit, let us consider an array of rank d whose cannam@95: dimensions are n[0] x n[1] x n[2] x ... x n[d-1] . Now, we specify a cannam@95: location in the array by a sequence of d (zero-based) indices, one for cannam@95: each dimension: (i[0], i[1], ..., i[d-1]). If the array is stored in cannam@95: row-major order, then this element is located at the position i[d-1] + cannam@95: n[d-1] * (i[d-2] + n[d-2] * (... + n[1] * i[0])). cannam@95: cannam@95: Note that, for the ordinary complex DFT, each element of the array cannam@95: must be of type `fftw_complex'; i.e. a (real, imaginary) pair of cannam@95: (double-precision) numbers. cannam@95: cannam@95: In the advanced FFTW interface, the physical dimensions n from which cannam@95: the indices are computed can be different from (larger than) the cannam@95: logical dimensions of the transform to be computed, in order to cannam@95: transform a subset of a larger array. Note also that, in the advanced cannam@95: interface, the expression above is multiplied by a "stride" to get the cannam@95: actual array index--this is useful in situations where each element of cannam@95: the multi-dimensional array is actually a data structure (or another cannam@95: array), and you just want to transform a single field. In the basic cannam@95: interface, however, the stride is 1. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Column-major Format, Next: Fixed-size Arrays in C, Prev: Row-major Format, Up: Multi-dimensional Array Format cannam@95: cannam@95: 3.2.2 Column-major Format cannam@95: ------------------------- cannam@95: cannam@95: Readers from the Fortran world are used to arrays stored in cannam@95: "column-major" order (sometimes called "Fortran order"). This is cannam@95: essentially the exact opposite of row-major order in that, here, the cannam@95: _first_ dimension's index varies most quickly. cannam@95: cannam@95: If you have an array stored in column-major order and wish to cannam@95: transform it using FFTW, it is quite easy to do. When creating the cannam@95: plan, simply pass the dimensions of the array to the planner in cannam@95: _reverse order_. For example, if your array is a rank three `N x M x cannam@95: L' matrix in column-major order, you should pass the dimensions of the cannam@95: array as if it were an `L x M x N' matrix (which it is, from the cannam@95: perspective of FFTW). This is done for you _automatically_ by the FFTW cannam@95: legacy-Fortran interface (*note Calling FFTW from Legacy Fortran::), cannam@95: but you must do it manually with the modern Fortran interface (*note cannam@95: Reversing array dimensions::). cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Fixed-size Arrays in C, Next: Dynamic Arrays in C, Prev: Column-major Format, Up: Multi-dimensional Array Format cannam@95: cannam@95: 3.2.3 Fixed-size Arrays in C cannam@95: ---------------------------- cannam@95: cannam@95: A multi-dimensional array whose size is declared at compile time in C cannam@95: is _already_ in row-major order. You don't have to do anything special cannam@95: to transform it. For example: cannam@95: cannam@95: { cannam@95: fftw_complex data[N0][N1][N2]; cannam@95: fftw_plan plan; cannam@95: ... cannam@95: plan = fftw_plan_dft_3d(N0, N1, N2, &data[0][0][0], &data[0][0][0], cannam@95: FFTW_FORWARD, FFTW_ESTIMATE); cannam@95: ... cannam@95: } cannam@95: cannam@95: This will plan a 3d in-place transform of size `N0 x N1 x N2'. cannam@95: Notice how we took the address of the zero-th element to pass to the cannam@95: planner (we could also have used a typecast). cannam@95: cannam@95: However, we tend to _discourage_ users from declaring their arrays cannam@95: in this way, for two reasons. First, this allocates the array on the cannam@95: stack ("automatic" storage), which has a very limited size on most cannam@95: operating systems (declaring an array with more than a few thousand cannam@95: elements will often cause a crash). (You can get around this cannam@95: limitation on many systems by declaring the array as `static' and/or cannam@95: global, but that has its own drawbacks.) Second, it may not optimally cannam@95: align the array for use with a SIMD FFTW (*note SIMD alignment and cannam@95: fftw_malloc::). Instead, we recommend using `fftw_malloc', as cannam@95: described below. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Dynamic Arrays in C, Next: Dynamic Arrays in C-The Wrong Way, Prev: Fixed-size Arrays in C, Up: Multi-dimensional Array Format cannam@95: cannam@95: 3.2.4 Dynamic Arrays in C cannam@95: ------------------------- cannam@95: cannam@95: We recommend allocating most arrays dynamically, with `fftw_malloc'. cannam@95: This isn't too hard to do, although it is not as straightforward for cannam@95: multi-dimensional arrays as it is for one-dimensional arrays. cannam@95: cannam@95: Creating the array is simple: using a dynamic-allocation routine like cannam@95: `fftw_malloc', allocate an array big enough to store N `fftw_complex' cannam@95: values (for a complex DFT), where N is the product of the sizes of the cannam@95: array dimensions (i.e. the total number of complex values in the cannam@95: array). For example, here is code to allocate a 5 x 12 x 27 rank-3 cannam@95: array: cannam@95: cannam@95: fftw_complex *an_array; cannam@95: an_array = (fftw_complex*) fftw_malloc(5*12*27 * sizeof(fftw_complex)); cannam@95: cannam@95: Accessing the array elements, however, is more tricky--you can't cannam@95: simply use multiple applications of the `[]' operator like you could cannam@95: for fixed-size arrays. Instead, you have to explicitly compute the cannam@95: offset into the array using the formula given earlier for row-major cannam@95: arrays. For example, to reference the (i,j,k)-th element of the array cannam@95: allocated above, you would use the expression `an_array[k + 27 * (j + cannam@95: 12 * i)]'. cannam@95: cannam@95: This pain can be alleviated somewhat by defining appropriate macros, cannam@95: or, in C++, creating a class and overloading the `()' operator. The cannam@95: recent C99 standard provides a way to reinterpret the dynamic array as cannam@95: a "variable-length" multi-dimensional array amenable to `[]', but this cannam@95: feature is not yet widely supported by compilers. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Dynamic Arrays in C-The Wrong Way, Prev: Dynamic Arrays in C, Up: Multi-dimensional Array Format cannam@95: cannam@95: 3.2.5 Dynamic Arrays in C--The Wrong Way cannam@95: ---------------------------------------- cannam@95: cannam@95: A different method for allocating multi-dimensional arrays in C is cannam@95: often suggested that is incompatible with FFTW: _using it will cause cannam@95: FFTW to die a painful death_. We discuss the technique here, however, cannam@95: because it is so commonly known and used. This method is to create cannam@95: arrays of pointers of arrays of pointers of ...etcetera. For example, cannam@95: the analogue in this method to the example above is: cannam@95: cannam@95: int i,j; cannam@95: fftw_complex ***a_bad_array; /* another way to make a 5x12x27 array */ cannam@95: cannam@95: a_bad_array = (fftw_complex ***) malloc(5 * sizeof(fftw_complex **)); cannam@95: for (i = 0; i < 5; ++i) { cannam@95: a_bad_array[i] = cannam@95: (fftw_complex **) malloc(12 * sizeof(fftw_complex *)); cannam@95: for (j = 0; j < 12; ++j) cannam@95: a_bad_array[i][j] = cannam@95: (fftw_complex *) malloc(27 * sizeof(fftw_complex)); cannam@95: } cannam@95: cannam@95: As you can see, this sort of array is inconvenient to allocate (and cannam@95: deallocate). On the other hand, it has the advantage that the cannam@95: (i,j,k)-th element can be referenced simply by `a_bad_array[i][j][k]'. cannam@95: cannam@95: If you like this technique and want to maximize convenience in cannam@95: accessing the array, but still want to pass the array to FFTW, you can cannam@95: use a hybrid method. Allocate the array as one contiguous block, but cannam@95: also declare an array of arrays of pointers that point to appropriate cannam@95: places in the block. That sort of trick is beyond the scope of this cannam@95: documentation; for more information on multi-dimensional arrays in C, cannam@95: see the `comp.lang.c' FAQ (http://c-faq.com/aryptr/dynmuldimary.html). cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Words of Wisdom-Saving Plans, Next: Caveats in Using Wisdom, Prev: Multi-dimensional Array Format, Up: Other Important Topics cannam@95: cannam@95: 3.3 Words of Wisdom--Saving Plans cannam@95: ================================= cannam@95: cannam@95: FFTW implements a method for saving plans to disk and restoring them. cannam@95: In fact, what FFTW does is more general than just saving and loading cannam@95: plans. The mechanism is called "wisdom". Here, we describe this cannam@95: feature at a high level. *Note FFTW Reference::, for a less casual but cannam@95: more complete discussion of how to use wisdom in FFTW. cannam@95: cannam@95: Plans created with the `FFTW_MEASURE', `FFTW_PATIENT', or cannam@95: `FFTW_EXHAUSTIVE' options produce near-optimal FFT performance, but may cannam@95: require a long time to compute because FFTW must measure the runtime of cannam@95: many possible plans and select the best one. This setup is designed cannam@95: for the situations where so many transforms of the same size must be cannam@95: computed that the start-up time is irrelevant. For short cannam@95: initialization times, but slower transforms, we have provided cannam@95: `FFTW_ESTIMATE'. The `wisdom' mechanism is a way to get the best of cannam@95: both worlds: you compute a good plan once, save it to disk, and later cannam@95: reload it as many times as necessary. The wisdom mechanism can cannam@95: actually save and reload many plans at once, not just one. cannam@95: cannam@95: Whenever you create a plan, the FFTW planner accumulates wisdom, cannam@95: which is information sufficient to reconstruct the plan. After cannam@95: planning, you can save this information to disk by means of the cannam@95: function: cannam@95: int fftw_export_wisdom_to_filename(const char *filename); cannam@95: (This function returns non-zero on success.) cannam@95: cannam@95: The next time you run the program, you can restore the wisdom with cannam@95: `fftw_import_wisdom_from_filename' (which also returns non-zero on cannam@95: success), and then recreate the plan using the same flags as before. cannam@95: int fftw_import_wisdom_from_filename(const char *filename); cannam@95: cannam@95: Wisdom is automatically used for any size to which it is applicable, cannam@95: as long as the planner flags are not more "patient" than those with cannam@95: which the wisdom was created. For example, wisdom created with cannam@95: `FFTW_MEASURE' can be used if you later plan with `FFTW_ESTIMATE' or cannam@95: `FFTW_MEASURE', but not with `FFTW_PATIENT'. cannam@95: cannam@95: The `wisdom' is cumulative, and is stored in a global, private data cannam@95: structure managed internally by FFTW. The storage space required is cannam@95: minimal, proportional to the logarithm of the sizes the wisdom was cannam@95: generated from. If memory usage is a concern, however, the wisdom can cannam@95: be forgotten and its associated memory freed by calling: cannam@95: void fftw_forget_wisdom(void); cannam@95: cannam@95: Wisdom can be exported to a file, a string, or any other medium. cannam@95: For details, see *note Wisdom::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Caveats in Using Wisdom, Prev: Words of Wisdom-Saving Plans, Up: Other Important Topics cannam@95: cannam@95: 3.4 Caveats in Using Wisdom cannam@95: =========================== cannam@95: cannam@95: For in much wisdom is much grief, and he that increaseth knowledge cannam@95: increaseth sorrow. [Ecclesiastes 1:18] cannam@95: cannam@95: There are pitfalls to using wisdom, in that it can negate FFTW's cannam@95: ability to adapt to changing hardware and other conditions. For cannam@95: example, it would be perfectly possible to export wisdom from a program cannam@95: running on one processor and import it into a program running on cannam@95: another processor. Doing so, however, would mean that the second cannam@95: program would use plans optimized for the first processor, instead of cannam@95: the one it is running on. cannam@95: cannam@95: It should be safe to reuse wisdom as long as the hardware and program cannam@95: binaries remain unchanged. (Actually, the optimal plan may change even cannam@95: between runs of the same binary on identical hardware, due to cannam@95: differences in the virtual memory environment, etcetera. Users cannam@95: seriously interested in performance should worry about this problem, cannam@95: too.) It is likely that, if the same wisdom is used for two different cannam@95: program binaries, even running on the same machine, the plans may be cannam@95: sub-optimal because of differing code alignments. It is therefore wise cannam@95: to recreate wisdom every time an application is recompiled. The more cannam@95: the underlying hardware and software changes between the creation of cannam@95: wisdom and its use, the greater grows the risk of sub-optimal plans. cannam@95: cannam@95: Nevertheless, if the choice is between using `FFTW_ESTIMATE' or cannam@95: using possibly-suboptimal wisdom (created on the same machine, but for a cannam@95: different binary), the wisdom is likely to be better. For this reason, cannam@95: we provide a function to import wisdom from a standard system-wide cannam@95: location (`/etc/fftw/wisdom' on Unix): cannam@95: cannam@95: int fftw_import_system_wisdom(void); cannam@95: cannam@95: FFTW also provides a standalone program, `fftw-wisdom' (described by cannam@95: its own `man' page on Unix) with which users can create wisdom, e.g. cannam@95: for a canonical set of sizes to store in the system wisdom file. *Note cannam@95: Wisdom Utilities::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW Reference, Next: Multi-threaded FFTW, Prev: Other Important Topics, Up: Top cannam@95: cannam@95: 4 FFTW Reference cannam@95: **************** cannam@95: cannam@95: This chapter provides a complete reference for all sequential (i.e., cannam@95: one-processor) FFTW functions. Parallel transforms are described in cannam@95: later chapters. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Data Types and Files:: cannam@95: * Using Plans:: cannam@95: * Basic Interface:: cannam@95: * Advanced Interface:: cannam@95: * Guru Interface:: cannam@95: * New-array Execute Functions:: cannam@95: * Wisdom:: cannam@95: * What FFTW Really Computes:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Data Types and Files, Next: Using Plans, Prev: FFTW Reference, Up: FFTW Reference cannam@95: cannam@95: 4.1 Data Types and Files cannam@95: ======================== cannam@95: cannam@95: All programs using FFTW should include its header file: cannam@95: cannam@95: #include cannam@95: cannam@95: You must also link to the FFTW library. On Unix, this means adding cannam@95: `-lfftw3 -lm' at the _end_ of the link command. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Complex numbers:: cannam@95: * Precision:: cannam@95: * Memory Allocation:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Complex numbers, Next: Precision, Prev: Data Types and Files, Up: Data Types and Files cannam@95: cannam@95: 4.1.1 Complex numbers cannam@95: --------------------- cannam@95: cannam@95: The default FFTW interface uses `double' precision for all cannam@95: floating-point numbers, and defines a `fftw_complex' type to hold cannam@95: complex numbers as: cannam@95: cannam@95: typedef double fftw_complex[2]; cannam@95: cannam@95: Here, the `[0]' element holds the real part and the `[1]' element cannam@95: holds the imaginary part. cannam@95: cannam@95: Alternatively, if you have a C compiler (such as `gcc') that cannam@95: supports the C99 revision of the ANSI C standard, you can use C's new cannam@95: native complex type (which is binary-compatible with the typedef above). cannam@95: In particular, if you `#include ' _before_ `', then cannam@95: `fftw_complex' is defined to be the native complex type and you can cannam@95: manipulate it with ordinary arithmetic (e.g. `x = y * (3+4*I)', where cannam@95: `x' and `y' are `fftw_complex' and `I' is the standard symbol for the cannam@95: imaginary unit); cannam@95: cannam@95: C++ has its own `complex' template class, defined in the standard cannam@95: `' header file. Reportedly, the C++ standards committee has cannam@95: recently agreed to mandate that the storage format used for this type cannam@95: be binary-compatible with the C99 type, i.e. an array `T[2]' with cannam@95: consecutive real `[0]' and imaginary `[1]' parts. (See report cannam@95: `http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2002/n1388.pdf cannam@95: WG21/N1388'.) Although not part of the official standard as of this cannam@95: writing, the proposal stated that: "This solution has been tested with cannam@95: all current major implementations of the standard library and shown to cannam@95: be working." To the extent that this is true, if you have a variable cannam@95: `complex *x', you can pass it directly to FFTW via cannam@95: `reinterpret_cast(x)'. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Precision, Next: Memory Allocation, Prev: Complex numbers, Up: Data Types and Files cannam@95: cannam@95: 4.1.2 Precision cannam@95: --------------- cannam@95: cannam@95: You can install single and long-double precision versions of FFTW, cannam@95: which replace `double' with `float' and `long double', respectively cannam@95: (*note Installation and Customization::). To use these interfaces, you: cannam@95: cannam@95: * Link to the single/long-double libraries; on Unix, `-lfftw3f' or cannam@95: `-lfftw3l' instead of (or in addition to) `-lfftw3'. (You can cannam@95: link to the different-precision libraries simultaneously.) cannam@95: cannam@95: * Include the _same_ `' header file. cannam@95: cannam@95: * Replace all lowercase instances of `fftw_' with `fftwf_' or cannam@95: `fftwl_' for single or long-double precision, respectively. cannam@95: (`fftw_complex' becomes `fftwf_complex', `fftw_execute' becomes cannam@95: `fftwf_execute', etcetera.) cannam@95: cannam@95: * Uppercase names, i.e. names beginning with `FFTW_', remain the cannam@95: same. cannam@95: cannam@95: * Replace `double' with `float' or `long double' for subroutine cannam@95: parameters. cannam@95: cannam@95: cannam@95: Depending upon your compiler and/or hardware, `long double' may not cannam@95: be any more precise than `double' (or may not be supported at all, cannam@95: although it is standard in C99). cannam@95: cannam@95: We also support using the nonstandard `__float128' cannam@95: quadruple-precision type provided by recent versions of `gcc' on 32- cannam@95: and 64-bit x86 hardware (*note Installation and Customization::). To cannam@95: use this type, link with `-lfftw3q -lquadmath -lm' (the `libquadmath' cannam@95: library provided by `gcc' is needed for quadruple-precision cannam@95: trigonometric functions) and use `fftwq_' identifiers. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Memory Allocation, Prev: Precision, Up: Data Types and Files cannam@95: cannam@95: 4.1.3 Memory Allocation cannam@95: ----------------------- cannam@95: cannam@95: void *fftw_malloc(size_t n); cannam@95: void fftw_free(void *p); cannam@95: cannam@95: These are functions that behave identically to `malloc' and `free', cannam@95: except that they guarantee that the returned pointer obeys any special cannam@95: alignment restrictions imposed by any algorithm in FFTW (e.g. for SIMD cannam@95: acceleration). *Note SIMD alignment and fftw_malloc::. cannam@95: cannam@95: Data allocated by `fftw_malloc' _must_ be deallocated by `fftw_free' cannam@95: and not by the ordinary `free'. cannam@95: cannam@95: These routines simply call through to your operating system's cannam@95: `malloc' or, if necessary, its aligned equivalent (e.g. `memalign'), so cannam@95: you normally need not worry about any significant time or space cannam@95: overhead. You are _not required_ to use them to allocate your data, cannam@95: but we strongly recommend it. cannam@95: cannam@95: Note: in C++, just as with ordinary `malloc', you must typecast the cannam@95: output of `fftw_malloc' to whatever pointer type you are allocating. cannam@95: cannam@95: We also provide the following two convenience functions to allocate cannam@95: real and complex arrays with `n' elements, which are equivalent to cannam@95: `(double *) fftw_malloc(sizeof(double) * n)' and `(fftw_complex *) cannam@95: fftw_malloc(sizeof(fftw_complex) * n)', respectively: cannam@95: cannam@95: double *fftw_alloc_real(size_t n); cannam@95: fftw_complex *fftw_alloc_complex(size_t n); cannam@95: cannam@95: The equivalent functions in other precisions allocate arrays of `n' cannam@95: elements in that precision. e.g. `fftwf_alloc_real(n)' is equivalent cannam@95: to `(float *) fftwf_malloc(sizeof(float) * n)'. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Using Plans, Next: Basic Interface, Prev: Data Types and Files, Up: FFTW Reference cannam@95: cannam@95: 4.2 Using Plans cannam@95: =============== cannam@95: cannam@95: Plans for all transform types in FFTW are stored as type `fftw_plan' cannam@95: (an opaque pointer type), and are created by one of the various cannam@95: planning routines described in the following sections. An `fftw_plan' cannam@95: contains all information necessary to compute the transform, including cannam@95: the pointers to the input and output arrays. cannam@95: cannam@95: void fftw_execute(const fftw_plan plan); cannam@95: cannam@95: This executes the `plan', to compute the corresponding transform on cannam@95: the arrays for which it was planned (which must still exist). The plan cannam@95: is not modified, and `fftw_execute' can be called as many times as cannam@95: desired. cannam@95: cannam@95: To apply a given plan to a different array, you can use the cannam@95: new-array execute interface. *Note New-array Execute Functions::. cannam@95: cannam@95: `fftw_execute' (and equivalents) is the only function in FFTW cannam@95: guaranteed to be thread-safe; see *note Thread safety::. cannam@95: cannam@95: This function: cannam@95: void fftw_destroy_plan(fftw_plan plan); cannam@95: deallocates the `plan' and all its associated data. cannam@95: cannam@95: FFTW's planner saves some other persistent data, such as the cannam@95: accumulated wisdom and a list of algorithms available in the current cannam@95: configuration. If you want to deallocate all of that and reset FFTW to cannam@95: the pristine state it was in when you started your program, you can cannam@95: call: cannam@95: cannam@95: void fftw_cleanup(void); cannam@95: cannam@95: After calling `fftw_cleanup', all existing plans become undefined, cannam@95: and you should not attempt to execute them nor to destroy them. You can cannam@95: however create and execute/destroy new plans, in which case FFTW starts cannam@95: accumulating wisdom information again. cannam@95: cannam@95: `fftw_cleanup' does not deallocate your plans, however. To prevent cannam@95: memory leaks, you must still call `fftw_destroy_plan' before executing cannam@95: `fftw_cleanup'. cannam@95: cannam@95: Occasionally, it may useful to know FFTW's internal "cost" metric cannam@95: that it uses to compare plans to one another; this cost is proportional cannam@95: to an execution time of the plan, in undocumented units, if the plan cannam@95: was created with the `FFTW_MEASURE' or other timing-based options, or cannam@95: alternatively is a heuristic cost function for `FFTW_ESTIMATE' plans. cannam@95: (The cost values of measured and estimated plans are not comparable, cannam@95: being in different units. Also, costs from different FFTW versions or cannam@95: the same version compiled differently may not be in the same units. cannam@95: Plans created from wisdom have a cost of 0 since no timing measurement cannam@95: is performed for them. Finally, certain problems for which only one cannam@95: top-level algorithm was possible may have required no measurements of cannam@95: the cost of the whole plan, in which case `fftw_cost' will also return cannam@95: 0.) The cost metric for a given plan is returned by: cannam@95: cannam@95: double fftw_cost(const fftw_plan plan); cannam@95: cannam@95: The following two routines are provided purely for academic purposes cannam@95: (that is, for entertainment). cannam@95: cannam@95: void fftw_flops(const fftw_plan plan, cannam@95: double *add, double *mul, double *fma); cannam@95: cannam@95: Given a `plan', set `add', `mul', and `fma' to an exact count of the cannam@95: number of floating-point additions, multiplications, and fused cannam@95: multiply-add operations involved in the plan's execution. The total cannam@95: number of floating-point operations (flops) is `add + mul + 2*fma', or cannam@95: `add + mul + fma' if the hardware supports fused multiply-add cannam@95: instructions (although the number of FMA operations is only approximate cannam@95: because of compiler voodoo). (The number of operations should be an cannam@95: integer, but we use `double' to avoid overflowing `int' for large cannam@95: transforms; the arguments are of type `double' even for single and cannam@95: long-double precision versions of FFTW.) cannam@95: cannam@95: void fftw_fprint_plan(const fftw_plan plan, FILE *output_file); cannam@95: void fftw_print_plan(const fftw_plan plan); cannam@95: cannam@95: This outputs a "nerd-readable" representation of the `plan' to the cannam@95: given file or to `stdout', respectively. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Basic Interface, Next: Advanced Interface, Prev: Using Plans, Up: FFTW Reference cannam@95: cannam@95: 4.3 Basic Interface cannam@95: =================== cannam@95: cannam@95: Recall that the FFTW API is divided into three parts(1): the "basic cannam@95: interface" computes a single transform of contiguous data, the "advanced cannam@95: interface" computes transforms of multiple or strided arrays, and the cannam@95: "guru interface" supports the most general data layouts, cannam@95: multiplicities, and strides. This section describes the the basic cannam@95: interface, which we expect to satisfy the needs of most users. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Complex DFTs:: cannam@95: * Planner Flags:: cannam@95: * Real-data DFTs:: cannam@95: * Real-data DFT Array Format:: cannam@95: * Real-to-Real Transforms:: cannam@95: * Real-to-Real Transform Kinds:: cannam@95: cannam@95: ---------- Footnotes ---------- cannam@95: cannam@95: (1) Gallia est omnis divisa in partes tres (Julius Caesar). cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Complex DFTs, Next: Planner Flags, Prev: Basic Interface, Up: Basic Interface cannam@95: cannam@95: 4.3.1 Complex DFTs cannam@95: ------------------ cannam@95: cannam@95: fftw_plan fftw_plan_dft_1d(int n0, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: fftw_plan fftw_plan_dft_2d(int n0, int n1, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: fftw_plan fftw_plan_dft_3d(int n0, int n1, int n2, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: fftw_plan fftw_plan_dft(int rank, const int *n, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: cannam@95: Plan a complex input/output discrete Fourier transform (DFT) in zero cannam@95: or more dimensions, returning an `fftw_plan' (*note Using Plans::). cannam@95: cannam@95: Once you have created a plan for a certain transform type and cannam@95: parameters, then creating another plan of the same type and parameters, cannam@95: but for different arrays, is fast and shares constant data with the cannam@95: first plan (if it still exists). cannam@95: cannam@95: The planner returns `NULL' if the plan cannot be created. In the cannam@95: standard FFTW distribution, the basic interface is guaranteed to return cannam@95: a non-`NULL' plan. A plan may be `NULL', however, if you are using a cannam@95: customized FFTW configuration supporting a restricted set of transforms. cannam@95: cannam@95: Arguments cannam@95: ......... cannam@95: cannam@95: * `rank' is the rank of the transform (it should be the size of the cannam@95: array `*n'), and can be any non-negative integer. (*Note Complex cannam@95: Multi-Dimensional DFTs::, for the definition of "rank".) The cannam@95: `_1d', `_2d', and `_3d' planners correspond to a `rank' of `1', cannam@95: `2', and `3', respectively. The rank may be zero, which is cannam@95: equivalent to a rank-1 transform of size 1, i.e. a copy of one cannam@95: number from input to output. cannam@95: cannam@95: * `n0', `n1', `n2', or `n[0..rank-1]' (as appropriate for each cannam@95: routine) specify the size of the transform dimensions. They can cannam@95: be any positive integer. cannam@95: cannam@95: - Multi-dimensional arrays are stored in row-major order with cannam@95: dimensions: `n0' x `n1'; or `n0' x `n1' x `n2'; or `n[0]' x cannam@95: `n[1]' x ... x `n[rank-1]'. *Note Multi-dimensional Array cannam@95: Format::. cannam@95: cannam@95: - FFTW is best at handling sizes of the form 2^a 3^b 5^c 7^d cannam@95: 11^e 13^f, where e+f is either 0 or 1, and the other exponents cannam@95: are arbitrary. Other sizes are computed by means of a slow, cannam@95: general-purpose algorithm (which nevertheless retains O(n log cannam@95: n) performance even for prime sizes). It is possible to cannam@95: customize FFTW for different array sizes; see *note cannam@95: Installation and Customization::. Transforms whose sizes are cannam@95: powers of 2 are especially fast. cannam@95: cannam@95: * `in' and `out' point to the input and output arrays of the cannam@95: transform, which may be the same (yielding an in-place transform). These cannam@95: arrays are overwritten during planning, unless `FFTW_ESTIMATE' is cannam@95: used in the flags. (The arrays need not be initialized, but they cannam@95: must be allocated.) cannam@95: cannam@95: If `in == out', the transform is "in-place" and the input array is cannam@95: overwritten. If `in != out', the two arrays must not overlap (but cannam@95: FFTW does not check for this condition). cannam@95: cannam@95: * `sign' is the sign of the exponent in the formula that defines the cannam@95: Fourier transform. It can be -1 (= `FFTW_FORWARD') or +1 (= cannam@95: `FFTW_BACKWARD'). cannam@95: cannam@95: * `flags' is a bitwise OR (`|') of zero or more planner flags, as cannam@95: defined in *note Planner Flags::. cannam@95: cannam@95: cannam@95: FFTW computes an unnormalized transform: computing a forward cannam@95: followed by a backward transform (or vice versa) will result in the cannam@95: original data multiplied by the size of the transform (the product of cannam@95: the dimensions). For more information, see *note What FFTW Really cannam@95: Computes::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Planner Flags, Next: Real-data DFTs, Prev: Complex DFTs, Up: Basic Interface cannam@95: cannam@95: 4.3.2 Planner Flags cannam@95: ------------------- cannam@95: cannam@95: All of the planner routines in FFTW accept an integer `flags' argument, cannam@95: which is a bitwise OR (`|') of zero or more of the flag constants cannam@95: defined below. These flags control the rigor (and time) of the cannam@95: planning process, and can also impose (or lift) restrictions on the cannam@95: type of transform algorithm that is employed. cannam@95: cannam@95: _Important:_ the planner overwrites the input array during planning cannam@95: unless a saved plan (*note Wisdom::) is available for that problem, so cannam@95: you should initialize your input data after creating the plan. The cannam@95: only exceptions to this are the `FFTW_ESTIMATE' and `FFTW_WISDOM_ONLY' cannam@95: flags, as mentioned below. cannam@95: cannam@95: In all cases, if wisdom is available for the given problem that cannam@95: was created with equal-or-greater planning rigor, then the more cannam@95: rigorous wisdom is used. For example, in `FFTW_ESTIMATE' mode any cannam@95: available wisdom is used, whereas in `FFTW_PATIENT' mode only wisdom cannam@95: created in patient or exhaustive mode can be used. *Note Words of cannam@95: Wisdom-Saving Plans::. cannam@95: cannam@95: Planning-rigor flags cannam@95: .................... cannam@95: cannam@95: * `FFTW_ESTIMATE' specifies that, instead of actual measurements of cannam@95: different algorithms, a simple heuristic is used to pick a cannam@95: (probably sub-optimal) plan quickly. With this flag, the cannam@95: input/output arrays are not overwritten during planning. cannam@95: cannam@95: * `FFTW_MEASURE' tells FFTW to find an optimized plan by actually cannam@95: _computing_ several FFTs and measuring their execution time. cannam@95: Depending on your machine, this can take some time (often a few cannam@95: seconds). `FFTW_MEASURE' is the default planning option. cannam@95: cannam@95: * `FFTW_PATIENT' is like `FFTW_MEASURE', but considers a wider range cannam@95: of algorithms and often produces a "more optimal" plan (especially cannam@95: for large transforms), but at the expense of several times longer cannam@95: planning time (especially for large transforms). cannam@95: cannam@95: * `FFTW_EXHAUSTIVE' is like `FFTW_PATIENT', but considers an even cannam@95: wider range of algorithms, including many that we think are cannam@95: unlikely to be fast, to produce the most optimal plan but with a cannam@95: substantially increased planning time. cannam@95: cannam@95: * `FFTW_WISDOM_ONLY' is a special planning mode in which the plan is cannam@95: only created if wisdom is available for the given problem, and cannam@95: otherwise a `NULL' plan is returned. This can be combined with cannam@95: other flags, e.g. `FFTW_WISDOM_ONLY | FFTW_PATIENT' creates a plan cannam@95: only if wisdom is available that was created in `FFTW_PATIENT' or cannam@95: `FFTW_EXHAUSTIVE' mode. The `FFTW_WISDOM_ONLY' flag is intended cannam@95: for users who need to detect whether wisdom is available; for cannam@95: example, if wisdom is not available one may wish to allocate new cannam@95: arrays for planning so that user data is not overwritten. cannam@95: cannam@95: cannam@95: Algorithm-restriction flags cannam@95: ........................... cannam@95: cannam@95: * `FFTW_DESTROY_INPUT' specifies that an out-of-place transform is cannam@95: allowed to _overwrite its input_ array with arbitrary data; this cannam@95: can sometimes allow more efficient algorithms to be employed. cannam@95: cannam@95: * `FFTW_PRESERVE_INPUT' specifies that an out-of-place transform must cannam@95: _not change its input_ array. This is ordinarily the _default_, cannam@95: except for c2r and hc2r (i.e. complex-to-real) transforms for cannam@95: which `FFTW_DESTROY_INPUT' is the default. In the latter cases, cannam@95: passing `FFTW_PRESERVE_INPUT' will attempt to use algorithms that cannam@95: do not destroy the input, at the expense of worse performance; for cannam@95: multi-dimensional c2r transforms, however, no input-preserving cannam@95: algorithms are implemented and the planner will return `NULL' if cannam@95: one is requested. cannam@95: cannam@95: * `FFTW_UNALIGNED' specifies that the algorithm may not impose any cannam@95: unusual alignment requirements on the input/output arrays (i.e. no cannam@95: SIMD may be used). This flag is normally _not necessary_, since cannam@95: the planner automatically detects misaligned arrays. The only use cannam@95: for this flag is if you want to use the new-array execute cannam@95: interface to execute a given plan on a different array that may cannam@95: not be aligned like the original. (Using `fftw_malloc' makes this cannam@95: flag unnecessary even then.) cannam@95: cannam@95: cannam@95: Limiting planning time cannam@95: ...................... cannam@95: cannam@95: extern void fftw_set_timelimit(double seconds); cannam@95: cannam@95: This function instructs FFTW to spend at most `seconds' seconds cannam@95: (approximately) in the planner. If `seconds == FFTW_NO_TIMELIMIT' (the cannam@95: default value, which is negative), then planning time is unbounded. cannam@95: Otherwise, FFTW plans with a progressively wider range of algorithms cannam@95: until the the given time limit is reached or the given range of cannam@95: algorithms is explored, returning the best available plan. cannam@95: cannam@95: For example, specifying `FFTW_PATIENT' first plans in cannam@95: `FFTW_ESTIMATE' mode, then in `FFTW_MEASURE' mode, then finally (time cannam@95: permitting) in `FFTW_PATIENT'. If `FFTW_EXHAUSTIVE' is specified cannam@95: instead, the planner will further progress to `FFTW_EXHAUSTIVE' mode. cannam@95: cannam@95: Note that the `seconds' argument specifies only a rough limit; in cannam@95: practice, the planner may use somewhat more time if the time limit is cannam@95: reached when the planner is in the middle of an operation that cannot cannam@95: be interrupted. At the very least, the planner will complete planning cannam@95: in `FFTW_ESTIMATE' mode (which is thus equivalent to a time limit of 0). cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Real-data DFTs, Next: Real-data DFT Array Format, Prev: Planner Flags, Up: Basic Interface cannam@95: cannam@95: 4.3.3 Real-data DFTs cannam@95: -------------------- cannam@95: cannam@95: fftw_plan fftw_plan_dft_r2c_1d(int n0, cannam@95: double *in, fftw_complex *out, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_dft_r2c_2d(int n0, int n1, cannam@95: double *in, fftw_complex *out, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_dft_r2c_3d(int n0, int n1, int n2, cannam@95: double *in, fftw_complex *out, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_dft_r2c(int rank, const int *n, cannam@95: double *in, fftw_complex *out, cannam@95: unsigned flags); cannam@95: cannam@95: Plan a real-input/complex-output discrete Fourier transform (DFT) in cannam@95: zero or more dimensions, returning an `fftw_plan' (*note Using Plans::). cannam@95: cannam@95: Once you have created a plan for a certain transform type and cannam@95: parameters, then creating another plan of the same type and parameters, cannam@95: but for different arrays, is fast and shares constant data with the cannam@95: first plan (if it still exists). cannam@95: cannam@95: The planner returns `NULL' if the plan cannot be created. A cannam@95: non-`NULL' plan is always returned by the basic interface unless you cannam@95: are using a customized FFTW configuration supporting a restricted set cannam@95: of transforms, or if you use the `FFTW_PRESERVE_INPUT' flag with a cannam@95: multi-dimensional out-of-place c2r transform (see below). cannam@95: cannam@95: Arguments cannam@95: ......... cannam@95: cannam@95: * `rank' is the rank of the transform (it should be the size of the cannam@95: array `*n'), and can be any non-negative integer. (*Note Complex cannam@95: Multi-Dimensional DFTs::, for the definition of "rank".) The cannam@95: `_1d', `_2d', and `_3d' planners correspond to a `rank' of `1', cannam@95: `2', and `3', respectively. The rank may be zero, which is cannam@95: equivalent to a rank-1 transform of size 1, i.e. a copy of one cannam@95: real number (with zero imaginary part) from input to output. cannam@95: cannam@95: * `n0', `n1', `n2', or `n[0..rank-1]', (as appropriate for each cannam@95: routine) specify the size of the transform dimensions. They can cannam@95: be any positive integer. This is different in general from the cannam@95: _physical_ array dimensions, which are described in *note cannam@95: Real-data DFT Array Format::. cannam@95: cannam@95: - FFTW is best at handling sizes of the form 2^a 3^b 5^c 7^d cannam@95: 11^e 13^f, where e+f is either 0 or 1, and the other exponents cannam@95: are arbitrary. Other sizes are computed by means of a slow, cannam@95: general-purpose algorithm (which nevertheless retains O(n log cannam@95: n) performance even for prime sizes). (It is possible to cannam@95: customize FFTW for different array sizes; see *note cannam@95: Installation and Customization::.) Transforms whose sizes cannam@95: are powers of 2 are especially fast, and it is generally cannam@95: beneficial for the _last_ dimension of an r2c/c2r transform cannam@95: to be _even_. cannam@95: cannam@95: * `in' and `out' point to the input and output arrays of the cannam@95: transform, which may be the same (yielding an in-place transform). These cannam@95: arrays are overwritten during planning, unless `FFTW_ESTIMATE' is cannam@95: used in the flags. (The arrays need not be initialized, but they cannam@95: must be allocated.) For an in-place transform, it is important to cannam@95: remember that the real array will require padding, described in cannam@95: *note Real-data DFT Array Format::. cannam@95: cannam@95: * `flags' is a bitwise OR (`|') of zero or more planner flags, as cannam@95: defined in *note Planner Flags::. cannam@95: cannam@95: cannam@95: The inverse transforms, taking complex input (storing the cannam@95: non-redundant half of a logically Hermitian array) to real output, are cannam@95: given by: cannam@95: cannam@95: fftw_plan fftw_plan_dft_c2r_1d(int n0, cannam@95: fftw_complex *in, double *out, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_dft_c2r_2d(int n0, int n1, cannam@95: fftw_complex *in, double *out, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_dft_c2r_3d(int n0, int n1, int n2, cannam@95: fftw_complex *in, double *out, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_dft_c2r(int rank, const int *n, cannam@95: fftw_complex *in, double *out, cannam@95: unsigned flags); cannam@95: cannam@95: The arguments are the same as for the r2c transforms, except that the cannam@95: input and output data formats are reversed. cannam@95: cannam@95: FFTW computes an unnormalized transform: computing an r2c followed cannam@95: by a c2r transform (or vice versa) will result in the original data cannam@95: multiplied by the size of the transform (the product of the logical cannam@95: dimensions). An r2c transform produces the same output as a cannam@95: `FFTW_FORWARD' complex DFT of the same input, and a c2r transform is cannam@95: correspondingly equivalent to `FFTW_BACKWARD'. For more information, cannam@95: see *note What FFTW Really Computes::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Real-data DFT Array Format, Next: Real-to-Real Transforms, Prev: Real-data DFTs, Up: Basic Interface cannam@95: cannam@95: 4.3.4 Real-data DFT Array Format cannam@95: -------------------------------- cannam@95: cannam@95: The output of a DFT of real data (r2c) contains symmetries that, in cannam@95: principle, make half of the outputs redundant (*note What FFTW Really cannam@95: Computes::). (Similarly for the input of an inverse c2r transform.) In cannam@95: practice, it is not possible to entirely realize these savings in an cannam@95: efficient and understandable format that generalizes to cannam@95: multi-dimensional transforms. Instead, the output of the r2c cannam@95: transforms is _slightly_ over half of the output of the corresponding cannam@95: complex transform. We do not "pack" the data in any way, but store it cannam@95: as an ordinary array of `fftw_complex' values. In fact, this data is cannam@95: simply a subsection of what would be the array in the corresponding cannam@95: complex transform. cannam@95: cannam@95: Specifically, for a real transform of d (= `rank') dimensions n[0] x cannam@95: n[1] x n[2] x ... x n[d-1] , the complex data is an n[0] x n[1] x n[2] cannam@95: x ... x (n[d-1]/2 + 1) array of `fftw_complex' values in row-major cannam@95: order (with the division rounded down). That is, we only store the cannam@95: _lower_ half (non-negative frequencies), plus one element, of the last cannam@95: dimension of the data from the ordinary complex transform. (We could cannam@95: have instead taken half of any other dimension, but implementation cannam@95: turns out to be simpler if the last, contiguous, dimension is used.) cannam@95: cannam@95: For an out-of-place transform, the real data is simply an array with cannam@95: physical dimensions n[0] x n[1] x n[2] x ... x n[d-1] in row-major cannam@95: order. cannam@95: cannam@95: For an in-place transform, some complications arise since the cannam@95: complex data is slightly larger than the real data. In this case, the cannam@95: final dimension of the real data must be _padded_ with extra values to cannam@95: accommodate the size of the complex data--two extra if the last cannam@95: dimension is even and one if it is odd. That is, the last dimension of cannam@95: the real data must physically contain 2 * (n[d-1]/2+1) `double' values cannam@95: (exactly enough to hold the complex data). This physical array size cannam@95: does not, however, change the _logical_ array size--only n[d-1] values cannam@95: are actually stored in the last dimension, and n[d-1] is the last cannam@95: dimension passed to the planner. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Real-to-Real Transforms, Next: Real-to-Real Transform Kinds, Prev: Real-data DFT Array Format, Up: Basic Interface cannam@95: cannam@95: 4.3.5 Real-to-Real Transforms cannam@95: ----------------------------- cannam@95: cannam@95: fftw_plan fftw_plan_r2r_1d(int n, double *in, double *out, cannam@95: fftw_r2r_kind kind, unsigned flags); cannam@95: fftw_plan fftw_plan_r2r_2d(int n0, int n1, double *in, double *out, cannam@95: fftw_r2r_kind kind0, fftw_r2r_kind kind1, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_r2r_3d(int n0, int n1, int n2, cannam@95: double *in, double *out, cannam@95: fftw_r2r_kind kind0, cannam@95: fftw_r2r_kind kind1, cannam@95: fftw_r2r_kind kind2, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_r2r(int rank, const int *n, double *in, double *out, cannam@95: const fftw_r2r_kind *kind, unsigned flags); cannam@95: cannam@95: Plan a real input/output (r2r) transform of various kinds in zero or cannam@95: more dimensions, returning an `fftw_plan' (*note Using Plans::). cannam@95: cannam@95: Once you have created a plan for a certain transform type and cannam@95: parameters, then creating another plan of the same type and parameters, cannam@95: but for different arrays, is fast and shares constant data with the cannam@95: first plan (if it still exists). cannam@95: cannam@95: The planner returns `NULL' if the plan cannot be created. A cannam@95: non-`NULL' plan is always returned by the basic interface unless you cannam@95: are using a customized FFTW configuration supporting a restricted set cannam@95: of transforms, or for size-1 `FFTW_REDFT00' kinds (which are not cannam@95: defined). cannam@95: cannam@95: Arguments cannam@95: ......... cannam@95: cannam@95: * `rank' is the dimensionality of the transform (it should be the cannam@95: size of the arrays `*n' and `*kind'), and can be any non-negative cannam@95: integer. The `_1d', `_2d', and `_3d' planners correspond to a cannam@95: `rank' of `1', `2', and `3', respectively. A `rank' of zero is cannam@95: equivalent to a copy of one number from input to output. cannam@95: cannam@95: * `n', or `n0'/`n1'/`n2', or `n[rank]', respectively, gives the cannam@95: (physical) size of the transform dimensions. They can be any cannam@95: positive integer. cannam@95: cannam@95: - Multi-dimensional arrays are stored in row-major order with cannam@95: dimensions: `n0' x `n1'; or `n0' x `n1' x `n2'; or `n[0]' x cannam@95: `n[1]' x ... x `n[rank-1]'. *Note Multi-dimensional Array cannam@95: Format::. cannam@95: cannam@95: - FFTW is generally best at handling sizes of the form 2^a 3^b cannam@95: 5^c 7^d 11^e 13^f, where e+f is either 0 or 1, and the other cannam@95: exponents are arbitrary. Other sizes are computed by means cannam@95: of a slow, general-purpose algorithm (which nevertheless cannam@95: retains O(n log n) performance even for prime sizes). (It cannam@95: is possible to customize FFTW for different array sizes; see cannam@95: *note Installation and Customization::.) Transforms whose cannam@95: sizes are powers of 2 are especially fast. cannam@95: cannam@95: - For a `REDFT00' or `RODFT00' transform kind in a dimension of cannam@95: size n, it is n-1 or n+1, respectively, that should be cannam@95: factorizable in the above form. cannam@95: cannam@95: * `in' and `out' point to the input and output arrays of the cannam@95: transform, which may be the same (yielding an in-place transform). These cannam@95: arrays are overwritten during planning, unless `FFTW_ESTIMATE' is cannam@95: used in the flags. (The arrays need not be initialized, but they cannam@95: must be allocated.) cannam@95: cannam@95: * `kind', or `kind0'/`kind1'/`kind2', or `kind[rank]', is the kind cannam@95: of r2r transform used for the corresponding dimension. The valid cannam@95: kind constants are described in *note Real-to-Real Transform cannam@95: Kinds::. In a multi-dimensional transform, what is computed is cannam@95: the separable product formed by taking each transform kind along cannam@95: the corresponding dimension, one dimension after another. cannam@95: cannam@95: * `flags' is a bitwise OR (`|') of zero or more planner flags, as cannam@95: defined in *note Planner Flags::. cannam@95: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Real-to-Real Transform Kinds, Prev: Real-to-Real Transforms, Up: Basic Interface cannam@95: cannam@95: 4.3.6 Real-to-Real Transform Kinds cannam@95: ---------------------------------- cannam@95: cannam@95: FFTW currently supports 11 different r2r transform kinds, specified by cannam@95: one of the constants below. For the precise definitions of these cannam@95: transforms, see *note What FFTW Really Computes::. For a more cannam@95: colloquial introduction to these transform kinds, see *note More DFTs cannam@95: of Real Data::. cannam@95: cannam@95: For dimension of size `n', there is a corresponding "logical" cannam@95: dimension `N' that determines the normalization (and the optimal cannam@95: factorization); the formula for `N' is given for each kind below. cannam@95: Also, with each transform kind is listed its corrsponding inverse cannam@95: transform. FFTW computes unnormalized transforms: a transform followed cannam@95: by its inverse will result in the original data multiplied by `N' (or cannam@95: the product of the `N''s for each dimension, in multi-dimensions). cannam@95: cannam@95: * `FFTW_R2HC' computes a real-input DFT with output in "halfcomplex" cannam@95: format, i.e. real and imaginary parts for a transform of size `n' cannam@95: stored as: r0, r1, r2, r(n/2), i((n+1)/2-1), ..., i2, i1 (Logical cannam@95: `N=n', inverse is `FFTW_HC2R'.) cannam@95: cannam@95: * `FFTW_HC2R' computes the reverse of `FFTW_R2HC', above. (Logical cannam@95: `N=n', inverse is `FFTW_R2HC'.) cannam@95: cannam@95: * `FFTW_DHT' computes a discrete Hartley transform. (Logical `N=n', cannam@95: inverse is `FFTW_DHT'.) cannam@95: cannam@95: * `FFTW_REDFT00' computes an REDFT00 transform, i.e. a DCT-I. cannam@95: (Logical `N=2*(n-1)', inverse is `FFTW_REDFT00'.) cannam@95: cannam@95: * `FFTW_REDFT10' computes an REDFT10 transform, i.e. a DCT-II cannam@95: (sometimes called "the" DCT). (Logical `N=2*n', inverse is cannam@95: `FFTW_REDFT01'.) cannam@95: cannam@95: * `FFTW_REDFT01' computes an REDFT01 transform, i.e. a DCT-III cannam@95: (sometimes called "the" IDCT, being the inverse of DCT-II). cannam@95: (Logical `N=2*n', inverse is `FFTW_REDFT=10'.) cannam@95: cannam@95: * `FFTW_REDFT11' computes an REDFT11 transform, i.e. a DCT-IV. cannam@95: (Logical `N=2*n', inverse is `FFTW_REDFT11'.) cannam@95: cannam@95: * `FFTW_RODFT00' computes an RODFT00 transform, i.e. a DST-I. cannam@95: (Logical `N=2*(n+1)', inverse is `FFTW_RODFT00'.) cannam@95: cannam@95: * `FFTW_RODFT10' computes an RODFT10 transform, i.e. a DST-II. cannam@95: (Logical `N=2*n', inverse is `FFTW_RODFT01'.) cannam@95: cannam@95: * `FFTW_RODFT01' computes an RODFT01 transform, i.e. a DST-III. cannam@95: (Logical `N=2*n', inverse is `FFTW_RODFT=10'.) cannam@95: cannam@95: * `FFTW_RODFT11' computes an RODFT11 transform, i.e. a DST-IV. cannam@95: (Logical `N=2*n', inverse is `FFTW_RODFT11'.) cannam@95: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Advanced Interface, Next: Guru Interface, Prev: Basic Interface, Up: FFTW Reference cannam@95: cannam@95: 4.4 Advanced Interface cannam@95: ====================== cannam@95: cannam@95: FFTW's "advanced" interface supplements the basic interface with four cannam@95: new planner routines, providing a new level of flexibility: you can plan cannam@95: a transform of multiple arrays simultaneously, operate on non-contiguous cannam@95: (strided) data, and transform a subset of a larger multi-dimensional cannam@95: array. Other than these additional features, the planner operates in cannam@95: the same fashion as in the basic interface, and the resulting cannam@95: `fftw_plan' is used in the same way (*note Using Plans::). cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Advanced Complex DFTs:: cannam@95: * Advanced Real-data DFTs:: cannam@95: * Advanced Real-to-real Transforms:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Advanced Complex DFTs, Next: Advanced Real-data DFTs, Prev: Advanced Interface, Up: Advanced Interface cannam@95: cannam@95: 4.4.1 Advanced Complex DFTs cannam@95: --------------------------- cannam@95: cannam@95: fftw_plan fftw_plan_many_dft(int rank, const int *n, int howmany, cannam@95: fftw_complex *in, const int *inembed, cannam@95: int istride, int idist, cannam@95: fftw_complex *out, const int *onembed, cannam@95: int ostride, int odist, cannam@95: int sign, unsigned flags); cannam@95: cannam@95: This routine plans multiple multidimensional complex DFTs, and it cannam@95: extends the `fftw_plan_dft' routine (*note Complex DFTs::) to compute cannam@95: `howmany' transforms, each having rank `rank' and size `n'. In cannam@95: addition, the transform data need not be contiguous, but it may be laid cannam@95: out in memory with an arbitrary stride. To account for these cannam@95: possibilities, `fftw_plan_many_dft' adds the new parameters `howmany', cannam@95: {`i',`o'}`nembed', {`i',`o'}`stride', and {`i',`o'}`dist'. The FFTW cannam@95: basic interface (*note Complex DFTs::) provides routines specialized cannam@95: for ranks 1, 2, and 3, but the advanced interface handles only the cannam@95: general-rank case. cannam@95: cannam@95: `howmany' is the number of transforms to compute. The resulting cannam@95: plan computes `howmany' transforms, where the input of the `k'-th cannam@95: transform is at location `in+k*idist' (in C pointer arithmetic), and cannam@95: its output is at location `out+k*odist'. Plans obtained in this way cannam@95: can often be faster than calling FFTW multiple times for the individual cannam@95: transforms. The basic `fftw_plan_dft' interface corresponds to cannam@95: `howmany=1' (in which case the `dist' parameters are ignored). cannam@95: cannam@95: Each of the `howmany' transforms has rank `rank' and size `n', as in cannam@95: the basic interface. In addition, the advanced interface allows the cannam@95: input and output arrays of each transform to be row-major subarrays of cannam@95: larger rank-`rank' arrays, described by `inembed' and `onembed' cannam@95: parameters, respectively. {`i',`o'}`nembed' must be arrays of length cannam@95: `rank', and `n' should be elementwise less than or equal to cannam@95: {`i',`o'}`nembed'. Passing `NULL' for an `nembed' parameter is cannam@95: equivalent to passing `n' (i.e. same physical and logical dimensions, cannam@95: as in the basic interface.) cannam@95: cannam@95: The `stride' parameters indicate that the `j'-th element of the cannam@95: input or output arrays is located at `j*istride' or `j*ostride', cannam@95: respectively. (For a multi-dimensional array, `j' is the ordinary cannam@95: row-major index.) When combined with the `k'-th transform in a cannam@95: `howmany' loop, from above, this means that the (`j',`k')-th element is cannam@95: at `j*stride+k*dist'. (The basic `fftw_plan_dft' interface corresponds cannam@95: to a stride of 1.) cannam@95: cannam@95: For in-place transforms, the input and output `stride' and `dist' cannam@95: parameters should be the same; otherwise, the planner may return `NULL'. cannam@95: cannam@95: Arrays `n', `inembed', and `onembed' are not used after this cannam@95: function returns. You can safely free or reuse them. cannam@95: cannam@95: *Examples*: One transform of one 5 by 6 array contiguous in memory: cannam@95: int rank = 2; cannam@95: int n[] = {5, 6}; cannam@95: int howmany = 1; cannam@95: int idist = odist = 0; /* unused because howmany = 1 */ cannam@95: int istride = ostride = 1; /* array is contiguous in memory */ cannam@95: int *inembed = n, *onembed = n; cannam@95: cannam@95: Transform of three 5 by 6 arrays, each contiguous in memory, stored cannam@95: in memory one after another: cannam@95: int rank = 2; cannam@95: int n[] = {5, 6}; cannam@95: int howmany = 3; cannam@95: int idist = odist = n[0]*n[1]; /* = 30, the distance in memory cannam@95: between the first element cannam@95: of the first array and the cannam@95: first element of the second array */ cannam@95: int istride = ostride = 1; /* array is contiguous in memory */ cannam@95: int *inembed = n, *onembed = n; cannam@95: cannam@95: Transform each column of a 2d array with 10 rows and 3 columns: cannam@95: int rank = 1; /* not 2: we are computing 1d transforms */ cannam@95: int n[] = {10}; /* 1d transforms of length 10 */ cannam@95: int howmany = 3; cannam@95: int idist = odist = 1; cannam@95: int istride = ostride = 3; /* distance between two elements in cannam@95: the same column */ cannam@95: int *inembed = n, *onembed = n; cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Advanced Real-data DFTs, Next: Advanced Real-to-real Transforms, Prev: Advanced Complex DFTs, Up: Advanced Interface cannam@95: cannam@95: 4.4.2 Advanced Real-data DFTs cannam@95: ----------------------------- cannam@95: cannam@95: fftw_plan fftw_plan_many_dft_r2c(int rank, const int *n, int howmany, cannam@95: double *in, const int *inembed, cannam@95: int istride, int idist, cannam@95: fftw_complex *out, const int *onembed, cannam@95: int ostride, int odist, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_plan_many_dft_c2r(int rank, const int *n, int howmany, cannam@95: fftw_complex *in, const int *inembed, cannam@95: int istride, int idist, cannam@95: double *out, const int *onembed, cannam@95: int ostride, int odist, cannam@95: unsigned flags); cannam@95: cannam@95: Like `fftw_plan_many_dft', these two functions add `howmany', cannam@95: `nembed', `stride', and `dist' parameters to the `fftw_plan_dft_r2c' cannam@95: and `fftw_plan_dft_c2r' functions, but otherwise behave the same as the cannam@95: basic interface. cannam@95: cannam@95: The interpretation of `howmany', `stride', and `dist' are the same cannam@95: as for `fftw_plan_many_dft', above. Note that the `stride' and `dist' cannam@95: for the real array are in units of `double', and for the complex array cannam@95: are in units of `fftw_complex'. cannam@95: cannam@95: If an `nembed' parameter is `NULL', it is interpreted as what it cannam@95: would be in the basic interface, as described in *note Real-data DFT cannam@95: Array Format::. That is, for the complex array the size is assumed to cannam@95: be the same as `n', but with the last dimension cut roughly in half. cannam@95: For the real array, the size is assumed to be `n' if the transform is cannam@95: out-of-place, or `n' with the last dimension "padded" if the transform cannam@95: is in-place. cannam@95: cannam@95: If an `nembed' parameter is non-`NULL', it is interpreted as the cannam@95: physical size of the corresponding array, in row-major order, just as cannam@95: for `fftw_plan_many_dft'. In this case, each dimension of `nembed' cannam@95: should be `>=' what it would be in the basic interface (e.g. the halved cannam@95: or padded `n'). cannam@95: cannam@95: Arrays `n', `inembed', and `onembed' are not used after this cannam@95: function returns. You can safely free or reuse them. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Advanced Real-to-real Transforms, Prev: Advanced Real-data DFTs, Up: Advanced Interface cannam@95: cannam@95: 4.4.3 Advanced Real-to-real Transforms cannam@95: -------------------------------------- cannam@95: cannam@95: fftw_plan fftw_plan_many_r2r(int rank, const int *n, int howmany, cannam@95: double *in, const int *inembed, cannam@95: int istride, int idist, cannam@95: double *out, const int *onembed, cannam@95: int ostride, int odist, cannam@95: const fftw_r2r_kind *kind, unsigned flags); cannam@95: cannam@95: Like `fftw_plan_many_dft', this functions adds `howmany', `nembed', cannam@95: `stride', and `dist' parameters to the `fftw_plan_r2r' function, but cannam@95: otherwise behave the same as the basic interface. The interpretation cannam@95: of those additional parameters are the same as for cannam@95: `fftw_plan_many_dft'. (Of course, the `stride' and `dist' parameters cannam@95: are now in units of `double', not `fftw_complex'.) cannam@95: cannam@95: Arrays `n', `inembed', `onembed', and `kind' are not used after this cannam@95: function returns. You can safely free or reuse them. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Guru Interface, Next: New-array Execute Functions, Prev: Advanced Interface, Up: FFTW Reference cannam@95: cannam@95: 4.5 Guru Interface cannam@95: ================== cannam@95: cannam@95: The "guru" interface to FFTW is intended to expose as much as possible cannam@95: of the flexibility in the underlying FFTW architecture. It allows one cannam@95: to compute multi-dimensional "vectors" (loops) of multi-dimensional cannam@95: transforms, where each vector/transform dimension has an independent cannam@95: size and stride. One can also use more general complex-number formats, cannam@95: e.g. separate real and imaginary arrays. cannam@95: cannam@95: For those users who require the flexibility of the guru interface, cannam@95: it is important that they pay special attention to the documentation cannam@95: lest they shoot themselves in the foot. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Interleaved and split arrays:: cannam@95: * Guru vector and transform sizes:: cannam@95: * Guru Complex DFTs:: cannam@95: * Guru Real-data DFTs:: cannam@95: * Guru Real-to-real Transforms:: cannam@95: * 64-bit Guru Interface:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Interleaved and split arrays, Next: Guru vector and transform sizes, Prev: Guru Interface, Up: Guru Interface cannam@95: cannam@95: 4.5.1 Interleaved and split arrays cannam@95: ---------------------------------- cannam@95: cannam@95: The guru interface supports two representations of complex numbers, cannam@95: which we call the interleaved and the split format. cannam@95: cannam@95: The "interleaved" format is the same one used by the basic and cannam@95: advanced interfaces, and it is documented in *note Complex numbers::. cannam@95: In the interleaved format, you provide pointers to the real part of a cannam@95: complex number, and the imaginary part understood to be stored in the cannam@95: next memory location. cannam@95: cannam@95: The "split" format allows separate pointers to the real and cannam@95: imaginary parts of a complex array. cannam@95: cannam@95: Technically, the interleaved format is redundant, because you can cannam@95: always express an interleaved array in terms of a split array with cannam@95: appropriate pointers and strides. On the other hand, the interleaved cannam@95: format is simpler to use, and it is common in practice. Hence, FFTW cannam@95: supports it as a special case. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Guru vector and transform sizes, Next: Guru Complex DFTs, Prev: Interleaved and split arrays, Up: Guru Interface cannam@95: cannam@95: 4.5.2 Guru vector and transform sizes cannam@95: ------------------------------------- cannam@95: cannam@95: The guru interface introduces one basic new data structure, cannam@95: `fftw_iodim', that is used to specify sizes and strides for cannam@95: multi-dimensional transforms and vectors: cannam@95: cannam@95: typedef struct { cannam@95: int n; cannam@95: int is; cannam@95: int os; cannam@95: } fftw_iodim; cannam@95: cannam@95: Here, `n' is the size of the dimension, and `is' and `os' are the cannam@95: strides of that dimension for the input and output arrays. (The stride cannam@95: is the separation of consecutive elements along this dimension.) cannam@95: cannam@95: The meaning of the stride parameter depends on the type of the array cannam@95: that the stride refers to. _If the array is interleaved complex, cannam@95: strides are expressed in units of complex numbers (`fftw_complex'). If cannam@95: the array is split complex or real, strides are expressed in units of cannam@95: real numbers (`double')._ This convention is consistent with the usual cannam@95: pointer arithmetic in the C language. An interleaved array is denoted cannam@95: by a pointer `p' to `fftw_complex', so that `p+1' points to the next cannam@95: complex number. Split arrays are denoted by pointers to `double', in cannam@95: which case pointer arithmetic operates in units of `sizeof(double)'. cannam@95: cannam@95: The guru planner interfaces all take a (`rank', `dims[rank]') pair cannam@95: describing the transform size, and a (`howmany_rank', cannam@95: `howmany_dims[howmany_rank]') pair describing the "vector" size (a cannam@95: multi-dimensional loop of transforms to perform), where `dims' and cannam@95: `howmany_dims' are arrays of `fftw_iodim'. cannam@95: cannam@95: For example, the `howmany' parameter in the advanced complex-DFT cannam@95: interface corresponds to `howmany_rank' = 1, `howmany_dims[0].n' = cannam@95: `howmany', `howmany_dims[0].is' = `idist', and `howmany_dims[0].os' = cannam@95: `odist'. (To compute a single transform, you can just use cannam@95: `howmany_rank' = 0.) cannam@95: cannam@95: A row-major multidimensional array with dimensions `n[rank]' (*note cannam@95: Row-major Format::) corresponds to `dims[i].n' = `n[i]' and the cannam@95: recurrence `dims[i].is' = `n[i+1] * dims[i+1].is' (similarly for `os'). cannam@95: The stride of the last (`i=rank-1') dimension is the overall stride of cannam@95: the array. e.g. to be equivalent to the advanced complex-DFT cannam@95: interface, you would have `dims[rank-1].is' = `istride' and cannam@95: `dims[rank-1].os' = `ostride'. cannam@95: cannam@95: In general, we only guarantee FFTW to return a non-`NULL' plan if cannam@95: the vector and transform dimensions correspond to a set of distinct cannam@95: indices, and for in-place transforms the input/output strides should be cannam@95: the same. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Guru Complex DFTs, Next: Guru Real-data DFTs, Prev: Guru vector and transform sizes, Up: Guru Interface cannam@95: cannam@95: 4.5.3 Guru Complex DFTs cannam@95: ----------------------- cannam@95: cannam@95: fftw_plan fftw_plan_guru_dft( cannam@95: int rank, const fftw_iodim *dims, cannam@95: int howmany_rank, const fftw_iodim *howmany_dims, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: cannam@95: fftw_plan fftw_plan_guru_split_dft( cannam@95: int rank, const fftw_iodim *dims, cannam@95: int howmany_rank, const fftw_iodim *howmany_dims, cannam@95: double *ri, double *ii, double *ro, double *io, cannam@95: unsigned flags); cannam@95: cannam@95: These two functions plan a complex-data, multi-dimensional DFT for cannam@95: the interleaved and split format, respectively. Transform dimensions cannam@95: are given by (`rank', `dims') over a multi-dimensional vector (loop) of cannam@95: dimensions (`howmany_rank', `howmany_dims'). `dims' and `howmany_dims' cannam@95: should point to `fftw_iodim' arrays of length `rank' and cannam@95: `howmany_rank', respectively. cannam@95: cannam@95: `flags' is a bitwise OR (`|') of zero or more planner flags, as cannam@95: defined in *note Planner Flags::. cannam@95: cannam@95: In the `fftw_plan_guru_dft' function, the pointers `in' and `out' cannam@95: point to the interleaved input and output arrays, respectively. The cannam@95: sign can be either -1 (= `FFTW_FORWARD') or +1 (= `FFTW_BACKWARD'). If cannam@95: the pointers are equal, the transform is in-place. cannam@95: cannam@95: In the `fftw_plan_guru_split_dft' function, `ri' and `ii' point to cannam@95: the real and imaginary input arrays, and `ro' and `io' point to the cannam@95: real and imaginary output arrays. The input and output pointers may be cannam@95: the same, indicating an in-place transform. For example, for cannam@95: `fftw_complex' pointers `in' and `out', the corresponding parameters cannam@95: are: cannam@95: cannam@95: ri = (double *) in; cannam@95: ii = (double *) in + 1; cannam@95: ro = (double *) out; cannam@95: io = (double *) out + 1; cannam@95: cannam@95: Because `fftw_plan_guru_split_dft' accepts split arrays, strides are cannam@95: expressed in units of `double'. For a contiguous `fftw_complex' array, cannam@95: the overall stride of the transform should be 2, the distance between cannam@95: consecutive real parts or between consecutive imaginary parts; see cannam@95: *note Guru vector and transform sizes::. Note that the dimension cannam@95: strides are applied equally to the real and imaginary parts; real and cannam@95: imaginary arrays with different strides are not supported. cannam@95: cannam@95: There is no `sign' parameter in `fftw_plan_guru_split_dft'. This cannam@95: function always plans for an `FFTW_FORWARD' transform. To plan for an cannam@95: `FFTW_BACKWARD' transform, you can exploit the identity that the cannam@95: backwards DFT is equal to the forwards DFT with the real and imaginary cannam@95: parts swapped. For example, in the case of the `fftw_complex' arrays cannam@95: above, the `FFTW_BACKWARD' transform is computed by the parameters: cannam@95: cannam@95: ri = (double *) in + 1; cannam@95: ii = (double *) in; cannam@95: ro = (double *) out + 1; cannam@95: io = (double *) out; cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Guru Real-data DFTs, Next: Guru Real-to-real Transforms, Prev: Guru Complex DFTs, Up: Guru Interface cannam@95: cannam@95: 4.5.4 Guru Real-data DFTs cannam@95: ------------------------- cannam@95: cannam@95: fftw_plan fftw_plan_guru_dft_r2c( cannam@95: int rank, const fftw_iodim *dims, cannam@95: int howmany_rank, const fftw_iodim *howmany_dims, cannam@95: double *in, fftw_complex *out, cannam@95: unsigned flags); cannam@95: cannam@95: fftw_plan fftw_plan_guru_split_dft_r2c( cannam@95: int rank, const fftw_iodim *dims, cannam@95: int howmany_rank, const fftw_iodim *howmany_dims, cannam@95: double *in, double *ro, double *io, cannam@95: unsigned flags); cannam@95: cannam@95: fftw_plan fftw_plan_guru_dft_c2r( cannam@95: int rank, const fftw_iodim *dims, cannam@95: int howmany_rank, const fftw_iodim *howmany_dims, cannam@95: fftw_complex *in, double *out, cannam@95: unsigned flags); cannam@95: cannam@95: fftw_plan fftw_plan_guru_split_dft_c2r( cannam@95: int rank, const fftw_iodim *dims, cannam@95: int howmany_rank, const fftw_iodim *howmany_dims, cannam@95: double *ri, double *ii, double *out, cannam@95: unsigned flags); cannam@95: cannam@95: Plan a real-input (r2c) or real-output (c2r), multi-dimensional DFT cannam@95: with transform dimensions given by (`rank', `dims') over a cannam@95: multi-dimensional vector (loop) of dimensions (`howmany_rank', cannam@95: `howmany_dims'). `dims' and `howmany_dims' should point to cannam@95: `fftw_iodim' arrays of length `rank' and `howmany_rank', respectively. cannam@95: As for the basic and advanced interfaces, an r2c transform is cannam@95: `FFTW_FORWARD' and a c2r transform is `FFTW_BACKWARD'. cannam@95: cannam@95: The _last_ dimension of `dims' is interpreted specially: that cannam@95: dimension of the real array has size `dims[rank-1].n', but that cannam@95: dimension of the complex array has size `dims[rank-1].n/2+1' (division cannam@95: rounded down). The strides, on the other hand, are taken to be exactly cannam@95: as specified. It is up to the user to specify the strides cannam@95: appropriately for the peculiar dimensions of the data, and we do not cannam@95: guarantee that the planner will succeed (return non-`NULL') for any cannam@95: dimensions other than those described in *note Real-data DFT Array cannam@95: Format:: and generalized in *note Advanced Real-data DFTs::. (That is, cannam@95: for an in-place transform, each individual dimension should be able to cannam@95: operate in place.) cannam@95: cannam@95: `in' and `out' point to the input and output arrays for r2c and c2r cannam@95: transforms, respectively. For split arrays, `ri' and `ii' point to the cannam@95: real and imaginary input arrays for a c2r transform, and `ro' and `io' cannam@95: point to the real and imaginary output arrays for an r2c transform. cannam@95: `in' and `ro' or `ri' and `out' may be the same, indicating an in-place cannam@95: transform. (In-place transforms where `in' and `io' or `ii' and `out' cannam@95: are the same are not currently supported.) cannam@95: cannam@95: `flags' is a bitwise OR (`|') of zero or more planner flags, as cannam@95: defined in *note Planner Flags::. cannam@95: cannam@95: In-place transforms of rank greater than 1 are currently only cannam@95: supported for interleaved arrays. For split arrays, the planner will cannam@95: return `NULL'. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Guru Real-to-real Transforms, Next: 64-bit Guru Interface, Prev: Guru Real-data DFTs, Up: Guru Interface cannam@95: cannam@95: 4.5.5 Guru Real-to-real Transforms cannam@95: ---------------------------------- cannam@95: cannam@95: fftw_plan fftw_plan_guru_r2r(int rank, const fftw_iodim *dims, cannam@95: int howmany_rank, cannam@95: const fftw_iodim *howmany_dims, cannam@95: double *in, double *out, cannam@95: const fftw_r2r_kind *kind, cannam@95: unsigned flags); cannam@95: cannam@95: Plan a real-to-real (r2r) multi-dimensional `FFTW_FORWARD' transform cannam@95: with transform dimensions given by (`rank', `dims') over a cannam@95: multi-dimensional vector (loop) of dimensions (`howmany_rank', cannam@95: `howmany_dims'). `dims' and `howmany_dims' should point to cannam@95: `fftw_iodim' arrays of length `rank' and `howmany_rank', respectively. cannam@95: cannam@95: The transform kind of each dimension is given by the `kind' cannam@95: parameter, which should point to an array of length `rank'. Valid cannam@95: `fftw_r2r_kind' constants are given in *note Real-to-Real Transform cannam@95: Kinds::. cannam@95: cannam@95: `in' and `out' point to the real input and output arrays; they may cannam@95: be the same, indicating an in-place transform. cannam@95: cannam@95: `flags' is a bitwise OR (`|') of zero or more planner flags, as cannam@95: defined in *note Planner Flags::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: 64-bit Guru Interface, Prev: Guru Real-to-real Transforms, Up: Guru Interface cannam@95: cannam@95: 4.5.6 64-bit Guru Interface cannam@95: --------------------------- cannam@95: cannam@95: When compiled in 64-bit mode on a 64-bit architecture (where addresses cannam@95: are 64 bits wide), FFTW uses 64-bit quantities internally for all cannam@95: transform sizes, strides, and so on--you don't have to do anything cannam@95: special to exploit this. However, in the ordinary FFTW interfaces, you cannam@95: specify the transform size by an `int' quantity, which is normally only cannam@95: 32 bits wide. This means that, even though FFTW is using 64-bit sizes cannam@95: internally, you cannot specify a single transform dimension larger than cannam@95: 2^31-1 numbers. cannam@95: cannam@95: We expect that few users will require transforms larger than this, cannam@95: but, for those who do, we provide a 64-bit version of the guru cannam@95: interface in which all sizes are specified as integers of type cannam@95: `ptrdiff_t' instead of `int'. (`ptrdiff_t' is a signed integer type cannam@95: defined by the C standard to be wide enough to represent address cannam@95: differences, and thus must be at least 64 bits wide on a 64-bit cannam@95: machine.) We stress that there is _no performance advantage_ to using cannam@95: this interface--the same internal FFTW code is employed regardless--and cannam@95: it is only necessary if you want to specify very large transform sizes. cannam@95: cannam@95: In particular, the 64-bit guru interface is a set of planner routines cannam@95: that are exactly the same as the guru planner routines, except that cannam@95: they are named with `guru64' instead of `guru' and they take arguments cannam@95: of type `fftw_iodim64' instead of `fftw_iodim'. For example, instead cannam@95: of `fftw_plan_guru_dft', we have `fftw_plan_guru64_dft'. cannam@95: cannam@95: fftw_plan fftw_plan_guru64_dft( cannam@95: int rank, const fftw_iodim64 *dims, cannam@95: int howmany_rank, const fftw_iodim64 *howmany_dims, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: int sign, unsigned flags); cannam@95: cannam@95: The `fftw_iodim64' type is similar to `fftw_iodim', with the same cannam@95: interpretation, except that it uses type `ptrdiff_t' instead of type cannam@95: `int'. cannam@95: cannam@95: typedef struct { cannam@95: ptrdiff_t n; cannam@95: ptrdiff_t is; cannam@95: ptrdiff_t os; cannam@95: } fftw_iodim64; cannam@95: cannam@95: Every other `fftw_plan_guru' function also has a `fftw_plan_guru64' cannam@95: equivalent, but we do not repeat their documentation here since they cannam@95: are identical to the 32-bit versions except as noted above. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: New-array Execute Functions, Next: Wisdom, Prev: Guru Interface, Up: FFTW Reference cannam@95: cannam@95: 4.6 New-array Execute Functions cannam@95: =============================== cannam@95: cannam@95: Normally, one executes a plan for the arrays with which the plan was cannam@95: created, by calling `fftw_execute(plan)' as described in *note Using cannam@95: Plans::. However, it is possible for sophisticated users to apply a cannam@95: given plan to a _different_ array using the "new-array execute" cannam@95: functions detailed below, provided that the following conditions are cannam@95: met: cannam@95: cannam@95: * The array size, strides, etcetera are the same (since those are cannam@95: set by the plan). cannam@95: cannam@95: * The input and output arrays are the same (in-place) or different cannam@95: (out-of-place) if the plan was originally created to be in-place or cannam@95: out-of-place, respectively. cannam@95: cannam@95: * For split arrays, the separations between the real and imaginary cannam@95: parts, `ii-ri' and `io-ro', are the same as they were for the cannam@95: input and output arrays when the plan was created. (This cannam@95: condition is automatically satisfied for interleaved arrays.) cannam@95: cannam@95: * The "alignment" of the new input/output arrays is the same as that cannam@95: of the input/output arrays when the plan was created, unless the cannam@95: plan was created with the `FFTW_UNALIGNED' flag. Here, the cannam@95: alignment is a platform-dependent quantity (for example, it is the cannam@95: address modulo 16 if SSE SIMD instructions are used, but the cannam@95: address modulo 4 for non-SIMD single-precision FFTW on the same cannam@95: machine). In general, only arrays allocated with `fftw_malloc' cannam@95: are guaranteed to be equally aligned (*note SIMD alignment and cannam@95: fftw_malloc::). cannam@95: cannam@95: cannam@95: The alignment issue is especially critical, because if you don't use cannam@95: `fftw_malloc' then you may have little control over the alignment of cannam@95: arrays in memory. For example, neither the C++ `new' function nor the cannam@95: Fortran `allocate' statement provide strong enough guarantees about cannam@95: data alignment. If you don't use `fftw_malloc', therefore, you cannam@95: probably have to use `FFTW_UNALIGNED' (which disables most SIMD cannam@95: support). If possible, it is probably better for you to simply create cannam@95: multiple plans (creating a new plan is quick once one exists for a cannam@95: given size), or better yet re-use the same array for your transforms. cannam@95: cannam@95: If you are tempted to use the new-array execute interface because you cannam@95: want to transform a known bunch of arrays of the same size, you should cannam@95: probably go use the advanced interface instead (*note Advanced cannam@95: Interface::)). cannam@95: cannam@95: The new-array execute functions are: cannam@95: cannam@95: void fftw_execute_dft( cannam@95: const fftw_plan p, cannam@95: fftw_complex *in, fftw_complex *out); cannam@95: cannam@95: void fftw_execute_split_dft( cannam@95: const fftw_plan p, cannam@95: double *ri, double *ii, double *ro, double *io); cannam@95: cannam@95: void fftw_execute_dft_r2c( cannam@95: const fftw_plan p, cannam@95: double *in, fftw_complex *out); cannam@95: cannam@95: void fftw_execute_split_dft_r2c( cannam@95: const fftw_plan p, cannam@95: double *in, double *ro, double *io); cannam@95: cannam@95: void fftw_execute_dft_c2r( cannam@95: const fftw_plan p, cannam@95: fftw_complex *in, double *out); cannam@95: cannam@95: void fftw_execute_split_dft_c2r( cannam@95: const fftw_plan p, cannam@95: double *ri, double *ii, double *out); cannam@95: cannam@95: void fftw_execute_r2r( cannam@95: const fftw_plan p, cannam@95: double *in, double *out); cannam@95: cannam@95: These execute the `plan' to compute the corresponding transform on cannam@95: the input/output arrays specified by the subsequent arguments. The cannam@95: input/output array arguments have the same meanings as the ones passed cannam@95: to the guru planner routines in the preceding sections. The `plan' is cannam@95: not modified, and these routines can be called as many times as cannam@95: desired, or intermixed with calls to the ordinary `fftw_execute'. cannam@95: cannam@95: The `plan' _must_ have been created for the transform type cannam@95: corresponding to the execute function, e.g. it must be a complex-DFT cannam@95: plan for `fftw_execute_dft'. Any of the planner routines for that cannam@95: transform type, from the basic to the guru interface, could have been cannam@95: used to create the plan, however. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Wisdom, Next: What FFTW Really Computes, Prev: New-array Execute Functions, Up: FFTW Reference cannam@95: cannam@95: 4.7 Wisdom cannam@95: ========== cannam@95: cannam@95: This section documents the FFTW mechanism for saving and restoring cannam@95: plans from disk. This mechanism is called "wisdom". cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Wisdom Export:: cannam@95: * Wisdom Import:: cannam@95: * Forgetting Wisdom:: cannam@95: * Wisdom Utilities:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Wisdom Export, Next: Wisdom Import, Prev: Wisdom, Up: Wisdom cannam@95: cannam@95: 4.7.1 Wisdom Export cannam@95: ------------------- cannam@95: cannam@95: int fftw_export_wisdom_to_filename(const char *filename); cannam@95: void fftw_export_wisdom_to_file(FILE *output_file); cannam@95: char *fftw_export_wisdom_to_string(void); cannam@95: void fftw_export_wisdom(void (*write_char)(char c, void *), void *data); cannam@95: cannam@95: These functions allow you to export all currently accumulated wisdom cannam@95: in a form from which it can be later imported and restored, even during cannam@95: a separate run of the program. (*Note Words of Wisdom-Saving Plans::.) cannam@95: The current store of wisdom is not affected by calling any of these cannam@95: routines. cannam@95: cannam@95: `fftw_export_wisdom' exports the wisdom to any output medium, as cannam@95: specified by the callback function `write_char'. `write_char' is a cannam@95: `putc'-like function that writes the character `c' to some output; its cannam@95: second parameter is the `data' pointer passed to `fftw_export_wisdom'. cannam@95: For convenience, the following three "wrapper" routines are provided: cannam@95: cannam@95: `fftw_export_wisdom_to_filename' writes wisdom to a file named cannam@95: `filename' (which is created or overwritten), returning `1' on success cannam@95: and `0' on failure. A lower-level function, which requires you to open cannam@95: and close the file yourself (e.g. if you want to write wisdom to a cannam@95: portion of a larger file) is `fftw_export_wisdom_to_file'. This writes cannam@95: the wisdom to the current position in `output_file', which should be cannam@95: open with write permission; upon exit, the file remains open and is cannam@95: positioned at the end of the wisdom data. cannam@95: cannam@95: `fftw_export_wisdom_to_string' returns a pointer to a cannam@95: `NULL'-terminated string holding the wisdom data. This string is cannam@95: dynamically allocated, and it is the responsibility of the caller to cannam@95: deallocate it with `free' when it is no longer needed. cannam@95: cannam@95: All of these routines export the wisdom in the same format, which we cannam@95: will not document here except to say that it is LISP-like ASCII text cannam@95: that is insensitive to white space. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Wisdom Import, Next: Forgetting Wisdom, Prev: Wisdom Export, Up: Wisdom cannam@95: cannam@95: 4.7.2 Wisdom Import cannam@95: ------------------- cannam@95: cannam@95: int fftw_import_system_wisdom(void); cannam@95: int fftw_import_wisdom_from_filename(const char *filename); cannam@95: int fftw_import_wisdom_from_string(const char *input_string); cannam@95: int fftw_import_wisdom(int (*read_char)(void *), void *data); cannam@95: cannam@95: These functions import wisdom into a program from data stored by the cannam@95: `fftw_export_wisdom' functions above. (*Note Words of Wisdom-Saving cannam@95: Plans::.) The imported wisdom replaces any wisdom already accumulated cannam@95: by the running program. cannam@95: cannam@95: `fftw_import_wisdom' imports wisdom from any input medium, as cannam@95: specified by the callback function `read_char'. `read_char' is a cannam@95: `getc'-like function that returns the next character in the input; its cannam@95: parameter is the `data' pointer passed to `fftw_import_wisdom'. If the cannam@95: end of the input data is reached (which should never happen for valid cannam@95: data), `read_char' should return `EOF' (as defined in `'). cannam@95: For convenience, the following three "wrapper" routines are provided: cannam@95: cannam@95: `fftw_import_wisdom_from_filename' reads wisdom from a file named cannam@95: `filename'. A lower-level function, which requires you to open and cannam@95: close the file yourself (e.g. if you want to read wisdom from a portion cannam@95: of a larger file) is `fftw_import_wisdom_from_file'. This reads wisdom cannam@95: from the current position in `input_file' (which should be open with cannam@95: read permission); upon exit, the file remains open, but the position of cannam@95: the read pointer is unspecified. cannam@95: cannam@95: `fftw_import_wisdom_from_string' reads wisdom from the cannam@95: `NULL'-terminated string `input_string'. cannam@95: cannam@95: `fftw_import_system_wisdom' reads wisdom from an cannam@95: implementation-defined standard file (`/etc/fftw/wisdom' on Unix and cannam@95: GNU systems). cannam@95: cannam@95: The return value of these import routines is `1' if the wisdom was cannam@95: read successfully and `0' otherwise. Note that, in all of these cannam@95: functions, any data in the input stream past the end of the wisdom data cannam@95: is simply ignored. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Forgetting Wisdom, Next: Wisdom Utilities, Prev: Wisdom Import, Up: Wisdom cannam@95: cannam@95: 4.7.3 Forgetting Wisdom cannam@95: ----------------------- cannam@95: cannam@95: void fftw_forget_wisdom(void); cannam@95: cannam@95: Calling `fftw_forget_wisdom' causes all accumulated `wisdom' to be cannam@95: discarded and its associated memory to be freed. (New `wisdom' can cannam@95: still be gathered subsequently, however.) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Wisdom Utilities, Prev: Forgetting Wisdom, Up: Wisdom cannam@95: cannam@95: 4.7.4 Wisdom Utilities cannam@95: ---------------------- cannam@95: cannam@95: FFTW includes two standalone utility programs that deal with wisdom. We cannam@95: merely summarize them here, since they come with their own `man' pages cannam@95: for Unix and GNU systems (with HTML versions on our web site). cannam@95: cannam@95: The first program is `fftw-wisdom' (or `fftwf-wisdom' in single cannam@95: precision, etcetera), which can be used to create a wisdom file cannam@95: containing plans for any of the transform sizes and types supported by cannam@95: FFTW. It is preferable to create wisdom directly from your executable cannam@95: (*note Caveats in Using Wisdom::), but this program is useful for cannam@95: creating global wisdom files for `fftw_import_system_wisdom'. cannam@95: cannam@95: The second program is `fftw-wisdom-to-conf', which takes a wisdom cannam@95: file as input and produces a "configuration routine" as output. The cannam@95: latter is a C subroutine that you can compile and link into your cannam@95: program, replacing a routine of the same name in the FFTW library, that cannam@95: determines which parts of FFTW are callable by your program. cannam@95: `fftw-wisdom-to-conf' produces a configuration routine that links to cannam@95: only those parts of FFTW needed by the saved plans in the wisdom, cannam@95: greatly reducing the size of statically linked executables (which should cannam@95: only attempt to create plans corresponding to those in the wisdom, cannam@95: however). cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: What FFTW Really Computes, Prev: Wisdom, Up: FFTW Reference cannam@95: cannam@95: 4.8 What FFTW Really Computes cannam@95: ============================= cannam@95: cannam@95: In this section, we provide precise mathematical definitions for the cannam@95: transforms that FFTW computes. These transform definitions are fairly cannam@95: standard, but some authors follow slightly different conventions for the cannam@95: normalization of the transform (the constant factor in front) and the cannam@95: sign of the complex exponent. We begin by presenting the cannam@95: one-dimensional (1d) transform definitions, and then give the cannam@95: straightforward extension to multi-dimensional transforms. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * The 1d Discrete Fourier Transform (DFT):: cannam@95: * The 1d Real-data DFT:: cannam@95: * 1d Real-even DFTs (DCTs):: cannam@95: * 1d Real-odd DFTs (DSTs):: cannam@95: * 1d Discrete Hartley Transforms (DHTs):: cannam@95: * Multi-dimensional Transforms:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: The 1d Discrete Fourier Transform (DFT), Next: The 1d Real-data DFT, Prev: What FFTW Really Computes, Up: What FFTW Really Computes cannam@95: cannam@95: 4.8.1 The 1d Discrete Fourier Transform (DFT) cannam@95: --------------------------------------------- cannam@95: cannam@95: The forward (`FFTW_FORWARD') discrete Fourier transform (DFT) of a 1d cannam@95: complex array X of size n computes an array Y, where: Y[k] = sum for j = 0 to (n - 1) of X[j] * exp(-2 pi j k sqrt(-1)/n) . cannam@95: The backward (`FFTW_BACKWARD') DFT computes: Y[k] = sum for j = 0 to (n - 1) of X[j] * exp(2 pi j k sqrt(-1)/n) . cannam@95: FFTW computes an unnormalized transform, in that there is no cannam@95: coefficient in front of the summation in the DFT. In other words, cannam@95: applying the forward and then the backward transform will multiply the cannam@95: input by n. cannam@95: cannam@95: From above, an `FFTW_FORWARD' transform corresponds to a sign of -1 cannam@95: in the exponent of the DFT. Note also that we use the standard cannam@95: "in-order" output ordering--the k-th output corresponds to the cannam@95: frequency k/n (or k/T, where T is your total sampling period). For cannam@95: those who like to think in terms of positive and negative frequencies, cannam@95: this means that the positive frequencies are stored in the first half cannam@95: of the output and the negative frequencies are stored in backwards cannam@95: order in the second half of the output. (The frequency -k/n is the cannam@95: same as the frequency (n-k)/n.) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: The 1d Real-data DFT, Next: 1d Real-even DFTs (DCTs), Prev: The 1d Discrete Fourier Transform (DFT), Up: What FFTW Really Computes cannam@95: cannam@95: 4.8.2 The 1d Real-data DFT cannam@95: -------------------------- cannam@95: cannam@95: The real-input (r2c) DFT in FFTW computes the _forward_ transform Y of cannam@95: the size `n' real array X, exactly as defined above, i.e. Y[k] = sum for j = 0 to (n - 1) of X[j] * exp(-2 pi j k sqrt(-1)/n) . cannam@95: This output array Y can easily be shown to possess the "Hermitian" cannam@95: symmetry Y[k] = Y[n-k]*, where we take Y to be periodic so that Y[n] = cannam@95: Y[0]. cannam@95: cannam@95: As a result of this symmetry, half of the output Y is redundant cannam@95: (being the complex conjugate of the other half), and so the 1d r2c cannam@95: transforms only output elements 0...n/2 of Y (n/2+1 complex numbers), cannam@95: where the division by 2 is rounded down. cannam@95: cannam@95: Moreover, the Hermitian symmetry implies that Y[0] and, if n is cannam@95: even, the Y[n/2] element, are purely real. So, for the `R2HC' r2r cannam@95: transform, these elements are not stored in the halfcomplex output cannam@95: format. cannam@95: cannam@95: The c2r and `H2RC' r2r transforms compute the backward DFT of the cannam@95: _complex_ array X with Hermitian symmetry, stored in the r2c/`R2HC' cannam@95: output formats, respectively, where the backward transform is defined cannam@95: exactly as for the complex case: Y[k] = sum for j = 0 to (n - 1) of X[j] * exp(2 pi j k sqrt(-1)/n) . cannam@95: The outputs `Y' of this transform can easily be seen to be purely cannam@95: real, and are stored as an array of real numbers. cannam@95: cannam@95: Like FFTW's complex DFT, these transforms are unnormalized. In other cannam@95: words, applying the real-to-complex (forward) and then the cannam@95: complex-to-real (backward) transform will multiply the input by n. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: 1d Real-even DFTs (DCTs), Next: 1d Real-odd DFTs (DSTs), Prev: The 1d Real-data DFT, Up: What FFTW Really Computes cannam@95: cannam@95: 4.8.3 1d Real-even DFTs (DCTs) cannam@95: ------------------------------ cannam@95: cannam@95: The Real-even symmetry DFTs in FFTW are exactly equivalent to the cannam@95: unnormalized forward (and backward) DFTs as defined above, where the cannam@95: input array X of length N is purely real and is also "even" symmetry. cannam@95: In this case, the output array is likewise real and even symmetry. cannam@95: cannam@95: For the case of `REDFT00', this even symmetry means that X[j] = cannam@95: X[N-j], where we take X to be periodic so that X[N] = X[0]. Because of cannam@95: this redundancy, only the first n real numbers are actually stored, cannam@95: where N = 2(n-1). cannam@95: cannam@95: The proper definition of even symmetry for `REDFT10', `REDFT01', and cannam@95: `REDFT11' transforms is somewhat more intricate because of the shifts cannam@95: by 1/2 of the input and/or output, although the corresponding boundary cannam@95: conditions are given in *note Real even/odd DFTs (cosine/sine cannam@95: transforms)::. Because of the even symmetry, however, the sine terms cannam@95: in the DFT all cancel and the remaining cosine terms are written cannam@95: explicitly below. This formulation often leads people to call such a cannam@95: transform a "discrete cosine transform" (DCT), although it is really cannam@95: just a special case of the DFT. cannam@95: cannam@95: In each of the definitions below, we transform a real array X of cannam@95: length n to a real array Y of length n: cannam@95: cannam@95: REDFT00 (DCT-I) cannam@95: ............... cannam@95: cannam@95: An `REDFT00' transform (type-I DCT) in FFTW is defined by: Y[k] = X[0] cannam@95: + (-1)^k X[n-1] + 2 (sum for j = 1 to n-2 of X[j] cos(pi jk /(n-1))). cannam@95: Note that this transform is not defined for n=1. For n=2, the cannam@95: summation term above is dropped as you might expect. cannam@95: cannam@95: REDFT10 (DCT-II) cannam@95: ................ cannam@95: cannam@95: An `REDFT10' transform (type-II DCT, sometimes called "the" DCT) in cannam@95: FFTW is defined by: Y[k] = 2 (sum for j = 0 to n-1 of X[j] cos(pi cannam@95: (j+1/2) k / n)). cannam@95: cannam@95: REDFT01 (DCT-III) cannam@95: ................. cannam@95: cannam@95: An `REDFT01' transform (type-III DCT) in FFTW is defined by: Y[k] = cannam@95: X[0] + 2 (sum for j = 1 to n-1 of X[j] cos(pi j (k+1/2) / n)). In the cannam@95: case of n=1, this reduces to Y[0] = X[0]. Up to a scale factor (see cannam@95: below), this is the inverse of `REDFT10' ("the" DCT), and so the cannam@95: `REDFT01' (DCT-III) is sometimes called the "IDCT". cannam@95: cannam@95: REDFT11 (DCT-IV) cannam@95: ................ cannam@95: cannam@95: An `REDFT11' transform (type-IV DCT) in FFTW is defined by: Y[k] = 2 cannam@95: (sum for j = 0 to n-1 of X[j] cos(pi (j+1/2) (k+1/2) / n)). cannam@95: cannam@95: Inverses and Normalization cannam@95: .......................... cannam@95: cannam@95: These definitions correspond directly to the unnormalized DFTs used cannam@95: elsewhere in FFTW (hence the factors of 2 in front of the summations). cannam@95: The unnormalized inverse of `REDFT00' is `REDFT00', of `REDFT10' is cannam@95: `REDFT01' and vice versa, and of `REDFT11' is `REDFT11'. Each cannam@95: unnormalized inverse results in the original array multiplied by N, cannam@95: where N is the _logical_ DFT size. For `REDFT00', N=2(n-1) (note that cannam@95: n=1 is not defined); otherwise, N=2n. cannam@95: cannam@95: In defining the discrete cosine transform, some authors also include cannam@95: additional factors of sqrt(2) (or its inverse) multiplying selected cannam@95: inputs and/or outputs. This is a mostly cosmetic change that makes the cannam@95: transform orthogonal, but sacrifices the direct equivalence to a cannam@95: symmetric DFT. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: 1d Real-odd DFTs (DSTs), Next: 1d Discrete Hartley Transforms (DHTs), Prev: 1d Real-even DFTs (DCTs), Up: What FFTW Really Computes cannam@95: cannam@95: 4.8.4 1d Real-odd DFTs (DSTs) cannam@95: ----------------------------- cannam@95: cannam@95: The Real-odd symmetry DFTs in FFTW are exactly equivalent to the cannam@95: unnormalized forward (and backward) DFTs as defined above, where the cannam@95: input array X of length N is purely real and is also "odd" symmetry. In cannam@95: this case, the output is odd symmetry and purely imaginary. cannam@95: cannam@95: For the case of `RODFT00', this odd symmetry means that X[j] = cannam@95: -X[N-j], where we take X to be periodic so that X[N] = X[0]. Because cannam@95: of this redundancy, only the first n real numbers starting at j=1 are cannam@95: actually stored (the j=0 element is zero), where N = 2(n+1). cannam@95: cannam@95: The proper definition of odd symmetry for `RODFT10', `RODFT01', and cannam@95: `RODFT11' transforms is somewhat more intricate because of the shifts cannam@95: by 1/2 of the input and/or output, although the corresponding boundary cannam@95: conditions are given in *note Real even/odd DFTs (cosine/sine cannam@95: transforms)::. Because of the odd symmetry, however, the cosine terms cannam@95: in the DFT all cancel and the remaining sine terms are written cannam@95: explicitly below. This formulation often leads people to call such a cannam@95: transform a "discrete sine transform" (DST), although it is really just cannam@95: a special case of the DFT. cannam@95: cannam@95: In each of the definitions below, we transform a real array X of cannam@95: length n to a real array Y of length n: cannam@95: cannam@95: RODFT00 (DST-I) cannam@95: ............... cannam@95: cannam@95: An `RODFT00' transform (type-I DST) in FFTW is defined by: Y[k] = 2 cannam@95: (sum for j = 0 to n-1 of X[j] sin(pi (j+1)(k+1) / (n+1))). cannam@95: cannam@95: RODFT10 (DST-II) cannam@95: ................ cannam@95: cannam@95: An `RODFT10' transform (type-II DST) in FFTW is defined by: Y[k] = 2 cannam@95: (sum for j = 0 to n-1 of X[j] sin(pi (j+1/2) (k+1) / n)). cannam@95: cannam@95: RODFT01 (DST-III) cannam@95: ................. cannam@95: cannam@95: An `RODFT01' transform (type-III DST) in FFTW is defined by: Y[k] = cannam@95: (-1)^k X[n-1] + 2 (sum for j = 0 to n-2 of X[j] sin(pi (j+1) (k+1/2) / cannam@95: n)). In the case of n=1, this reduces to Y[0] = X[0]. cannam@95: cannam@95: RODFT11 (DST-IV) cannam@95: ................ cannam@95: cannam@95: An `RODFT11' transform (type-IV DST) in FFTW is defined by: Y[k] = 2 cannam@95: (sum for j = 0 to n-1 of X[j] sin(pi (j+1/2) (k+1/2) / n)). cannam@95: cannam@95: Inverses and Normalization cannam@95: .......................... cannam@95: cannam@95: These definitions correspond directly to the unnormalized DFTs used cannam@95: elsewhere in FFTW (hence the factors of 2 in front of the summations). cannam@95: The unnormalized inverse of `RODFT00' is `RODFT00', of `RODFT10' is cannam@95: `RODFT01' and vice versa, and of `RODFT11' is `RODFT11'. Each cannam@95: unnormalized inverse results in the original array multiplied by N, cannam@95: where N is the _logical_ DFT size. For `RODFT00', N=2(n+1); otherwise, cannam@95: N=2n. cannam@95: cannam@95: In defining the discrete sine transform, some authors also include cannam@95: additional factors of sqrt(2) (or its inverse) multiplying selected cannam@95: inputs and/or outputs. This is a mostly cosmetic change that makes the cannam@95: transform orthogonal, but sacrifices the direct equivalence to an cannam@95: antisymmetric DFT. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: 1d Discrete Hartley Transforms (DHTs), Next: Multi-dimensional Transforms, Prev: 1d Real-odd DFTs (DSTs), Up: What FFTW Really Computes cannam@95: cannam@95: 4.8.5 1d Discrete Hartley Transforms (DHTs) cannam@95: ------------------------------------------- cannam@95: cannam@95: The discrete Hartley transform (DHT) of a 1d real array X of size n cannam@95: computes a real array Y of the same size, where: Y[k] = sum for j = 0 to (n - 1) of X[j] * [cos(2 pi j k / n) + sin(2 pi j k / n)]. cannam@95: FFTW computes an unnormalized transform, in that there is no cannam@95: coefficient in front of the summation in the DHT. In other words, cannam@95: applying the transform twice (the DHT is its own inverse) will multiply cannam@95: the input by n. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Multi-dimensional Transforms, Prev: 1d Discrete Hartley Transforms (DHTs), Up: What FFTW Really Computes cannam@95: cannam@95: 4.8.6 Multi-dimensional Transforms cannam@95: ---------------------------------- cannam@95: cannam@95: The multi-dimensional transforms of FFTW, in general, compute simply the cannam@95: separable product of the given 1d transform along each dimension of the cannam@95: array. Since each of these transforms is unnormalized, computing the cannam@95: forward followed by the backward/inverse multi-dimensional transform cannam@95: will result in the original array scaled by the product of the cannam@95: normalization factors for each dimension (e.g. the product of the cannam@95: dimension sizes, for a multi-dimensional DFT). cannam@95: cannam@95: The definition of FFTW's multi-dimensional DFT of real data (r2c) cannam@95: deserves special attention. In this case, we logically compute the full cannam@95: multi-dimensional DFT of the input data; since the input data are purely cannam@95: real, the output data have the Hermitian symmetry and therefore only one cannam@95: non-redundant half need be stored. More specifically, for an n[0] x cannam@95: n[1] x n[2] x ... x n[d-1] multi-dimensional real-input DFT, the full cannam@95: (logical) complex output array Y[k[0], k[1], ..., k[d-1]] has the cannam@95: symmetry: Y[k[0], k[1], ..., k[d-1]] = Y[n[0] - k[0], n[1] - k[1], ..., cannam@95: n[d-1] - k[d-1]]* (where each dimension is periodic). Because of this cannam@95: symmetry, we only store the k[d-1] = 0...n[d-1]/2 elements of the cannam@95: _last_ dimension (division by 2 is rounded down). (We could instead cannam@95: have cut any other dimension in half, but the last dimension proved cannam@95: computationally convenient.) This results in the peculiar array format cannam@95: described in more detail by *note Real-data DFT Array Format::. cannam@95: cannam@95: The multi-dimensional c2r transform is simply the unnormalized cannam@95: inverse of the r2c transform. i.e. it is the same as FFTW's complex cannam@95: backward multi-dimensional DFT, operating on a Hermitian input array in cannam@95: the peculiar format mentioned above and outputting a real array (since cannam@95: the DFT output is purely real). cannam@95: cannam@95: We should remind the user that the separable product of 1d transforms cannam@95: along each dimension, as computed by FFTW, is not always the same thing cannam@95: as the usual multi-dimensional transform. A multi-dimensional `R2HC' cannam@95: (or `HC2R') transform is not identical to the multi-dimensional DFT, cannam@95: requiring some post-processing to combine the requisite real and cannam@95: imaginary parts, as was described in *note The Halfcomplex-format cannam@95: DFT::. Likewise, FFTW's multidimensional `FFTW_DHT' r2r transform is cannam@95: not the same thing as the logical multi-dimensional discrete Hartley cannam@95: transform defined in the literature, as discussed in *note The Discrete cannam@95: Hartley Transform::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Multi-threaded FFTW, Next: Distributed-memory FFTW with MPI, Prev: FFTW Reference, Up: Top cannam@95: cannam@95: 5 Multi-threaded FFTW cannam@95: ********************* cannam@95: cannam@95: In this chapter we document the parallel FFTW routines for cannam@95: shared-memory parallel hardware. These routines, which support cannam@95: parallel one- and multi-dimensional transforms of both real and complex cannam@95: data, are the easiest way to take advantage of multiple processors with cannam@95: FFTW. They work just like the corresponding uniprocessor transform cannam@95: routines, except that you have an extra initialization routine to call, cannam@95: and there is a routine to set the number of threads to employ. Any cannam@95: program that uses the uniprocessor FFTW can therefore be trivially cannam@95: modified to use the multi-threaded FFTW. cannam@95: cannam@95: A shared-memory machine is one in which all CPUs can directly access cannam@95: the same main memory, and such machines are now common due to the cannam@95: ubiquity of multi-core CPUs. FFTW's multi-threading support allows you cannam@95: to utilize these additional CPUs transparently from a single program. cannam@95: However, this does not necessarily translate into performance cannam@95: gains--when multiple threads/CPUs are employed, there is an overhead cannam@95: required for synchronization that may outweigh the computatational cannam@95: parallelism. Therefore, you can only benefit from threads if your cannam@95: problem is sufficiently large. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Installation and Supported Hardware/Software:: cannam@95: * Usage of Multi-threaded FFTW:: cannam@95: * How Many Threads to Use?:: cannam@95: * Thread safety:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Installation and Supported Hardware/Software, Next: Usage of Multi-threaded FFTW, Prev: Multi-threaded FFTW, Up: Multi-threaded FFTW cannam@95: cannam@95: 5.1 Installation and Supported Hardware/Software cannam@95: ================================================ cannam@95: cannam@95: All of the FFTW threads code is located in the `threads' subdirectory cannam@95: of the FFTW package. On Unix systems, the FFTW threads libraries and cannam@95: header files can be automatically configured, compiled, and installed cannam@95: along with the uniprocessor FFTW libraries simply by including cannam@95: `--enable-threads' in the flags to the `configure' script (*note cannam@95: Installation on Unix::), or `--enable-openmp' to use OpenMP cannam@95: (http://www.openmp.org) threads. cannam@95: cannam@95: The threads routines require your operating system to have some sort cannam@95: of shared-memory threads support. Specifically, the FFTW threads cannam@95: package works with POSIX threads (available on most Unix variants, from cannam@95: GNU/Linux to MacOS X) and Win32 threads. OpenMP threads, which are cannam@95: supported in many common compilers (e.g. gcc) are also supported, and cannam@95: may give better performance on some systems. (OpenMP threads are also cannam@95: useful if you are employing OpenMP in your own code, in order to cannam@95: minimize conflicts between threading models.) If you have a cannam@95: shared-memory machine that uses a different threads API, it should be a cannam@95: simple matter of programming to include support for it; see the file cannam@95: `threads/threads.c' for more detail. cannam@95: cannam@95: You can compile FFTW with _both_ `--enable-threads' and cannam@95: `--enable-openmp' at the same time, since they install libraries with cannam@95: different names (`fftw3_threads' and `fftw3_omp', as described below). cannam@95: However, your programs may only link to _one_ of these two libraries at cannam@95: a time. cannam@95: cannam@95: Ideally, of course, you should also have multiple processors in cannam@95: order to get any benefit from the threaded transforms. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Usage of Multi-threaded FFTW, Next: How Many Threads to Use?, Prev: Installation and Supported Hardware/Software, Up: Multi-threaded FFTW cannam@95: cannam@95: 5.2 Usage of Multi-threaded FFTW cannam@95: ================================ cannam@95: cannam@95: Here, it is assumed that the reader is already familiar with the usage cannam@95: of the uniprocessor FFTW routines, described elsewhere in this manual. cannam@95: We only describe what one has to change in order to use the cannam@95: multi-threaded routines. cannam@95: cannam@95: First, programs using the parallel complex transforms should be cannam@95: linked with `-lfftw3_threads -lfftw3 -lm' on Unix, or `-lfftw3_omp cannam@95: -lfftw3 -lm' if you compiled with OpenMP. You will also need to link cannam@95: with whatever library is responsible for threads on your system (e.g. cannam@95: `-lpthread' on GNU/Linux) or include whatever compiler flag enables cannam@95: OpenMP (e.g. `-fopenmp' with gcc). cannam@95: cannam@95: Second, before calling _any_ FFTW routines, you should call the cannam@95: function: cannam@95: cannam@95: int fftw_init_threads(void); cannam@95: cannam@95: This function, which need only be called once, performs any one-time cannam@95: initialization required to use threads on your system. It returns zero cannam@95: if there was some error (which should not happen under normal cannam@95: circumstances) and a non-zero value otherwise. cannam@95: cannam@95: Third, before creating a plan that you want to parallelize, you cannam@95: should call: cannam@95: cannam@95: void fftw_plan_with_nthreads(int nthreads); cannam@95: cannam@95: The `nthreads' argument indicates the number of threads you want cannam@95: FFTW to use (or actually, the maximum number). All plans subsequently cannam@95: created with any planner routine will use that many threads. You can cannam@95: call `fftw_plan_with_nthreads', create some plans, call cannam@95: `fftw_plan_with_nthreads' again with a different argument, and create cannam@95: some more plans for a new number of threads. Plans already created cannam@95: before a call to `fftw_plan_with_nthreads' are unaffected. If you pass cannam@95: an `nthreads' argument of `1' (the default), threads are disabled for cannam@95: subsequent plans. cannam@95: cannam@95: With OpenMP, to configure FFTW to use all of the currently running cannam@95: OpenMP threads (set by `omp_set_num_threads(nthreads)' or by the cannam@95: `OMP_NUM_THREADS' environment variable), you can do: cannam@95: `fftw_plan_with_nthreads(omp_get_max_threads())'. (The `omp_' OpenMP cannam@95: functions are declared via `#include '.) cannam@95: cannam@95: Given a plan, you then execute it as usual with cannam@95: `fftw_execute(plan)', and the execution will use the number of threads cannam@95: specified when the plan was created. When done, you destroy it as cannam@95: usual with `fftw_destroy_plan'. As described in *note Thread safety::, cannam@95: plan _execution_ is thread-safe, but plan creation and destruction are cannam@95: _not_: you should create/destroy plans only from a single thread, but cannam@95: can safely execute multiple plans in parallel. cannam@95: cannam@95: There is one additional routine: if you want to get rid of all memory cannam@95: and other resources allocated internally by FFTW, you can call: cannam@95: cannam@95: void fftw_cleanup_threads(void); cannam@95: cannam@95: which is much like the `fftw_cleanup()' function except that it also cannam@95: gets rid of threads-related data. You must _not_ execute any cannam@95: previously created plans after calling this function. cannam@95: cannam@95: We should also mention one other restriction: if you save wisdom cannam@95: from a program using the multi-threaded FFTW, that wisdom _cannot be cannam@95: used_ by a program using only the single-threaded FFTW (i.e. not calling cannam@95: `fftw_init_threads'). *Note Words of Wisdom-Saving Plans::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: How Many Threads to Use?, Next: Thread safety, Prev: Usage of Multi-threaded FFTW, Up: Multi-threaded FFTW cannam@95: cannam@95: 5.3 How Many Threads to Use? cannam@95: ============================ cannam@95: cannam@95: There is a fair amount of overhead involved in synchronizing threads, cannam@95: so the optimal number of threads to use depends upon the size of the cannam@95: transform as well as on the number of processors you have. cannam@95: cannam@95: As a general rule, you don't want to use more threads than you have cannam@95: processors. (Using more threads will work, but there will be extra cannam@95: overhead with no benefit.) In fact, if the problem size is too small, cannam@95: you may want to use fewer threads than you have processors. cannam@95: cannam@95: You will have to experiment with your system to see what level of cannam@95: parallelization is best for your problem size. Typically, the problem cannam@95: will have to involve at least a few thousand data points before threads cannam@95: become beneficial. If you plan with `FFTW_PATIENT', it will cannam@95: automatically disable threads for sizes that don't benefit from cannam@95: parallelization. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Thread safety, Prev: How Many Threads to Use?, Up: Multi-threaded FFTW cannam@95: cannam@95: 5.4 Thread safety cannam@95: ================= cannam@95: cannam@95: Users writing multi-threaded programs (including OpenMP) must concern cannam@95: themselves with the "thread safety" of the libraries they use--that is, cannam@95: whether it is safe to call routines in parallel from multiple threads. cannam@95: FFTW can be used in such an environment, but some care must be taken cannam@95: because the planner routines share data (e.g. wisdom and trigonometric cannam@95: tables) between calls and plans. cannam@95: cannam@95: The upshot is that the only thread-safe (re-entrant) routine in FFTW cannam@95: is `fftw_execute' (and the new-array variants thereof). All other cannam@95: routines (e.g. the planner) should only be called from one thread at a cannam@95: time. So, for example, you can wrap a semaphore lock around any calls cannam@95: to the planner; even more simply, you can just create all of your plans cannam@95: from one thread. We do not think this should be an important cannam@95: restriction (FFTW is designed for the situation where the only cannam@95: performance-sensitive code is the actual execution of the transform), cannam@95: and the benefits of shared data between plans are great. cannam@95: cannam@95: Note also that, since the plan is not modified by `fftw_execute', it cannam@95: is safe to execute the _same plan_ in parallel by multiple threads. cannam@95: However, since a given plan operates by default on a fixed array, you cannam@95: need to use one of the new-array execute functions (*note New-array cannam@95: Execute Functions::) so that different threads compute the transform of cannam@95: different data. cannam@95: cannam@95: (Users should note that these comments only apply to programs using cannam@95: shared-memory threads or OpenMP. Parallelism using MPI or forked cannam@95: processes involves a separate address-space and global variables for cannam@95: each process, and is not susceptible to problems of this sort.) cannam@95: cannam@95: If you are configured FFTW with the `--enable-debug' or cannam@95: `--enable-debug-malloc' flags (*note Installation on Unix::), then cannam@95: `fftw_execute' is not thread-safe. These flags are not documented cannam@95: because they are intended only for developing and debugging FFTW, but cannam@95: if you must use `--enable-debug' then you should also specifically pass cannam@95: `--disable-debug-malloc' for `fftw_execute' to be thread-safe. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Distributed-memory FFTW with MPI, Next: Calling FFTW from Modern Fortran, Prev: Multi-threaded FFTW, Up: Top cannam@95: cannam@95: 6 Distributed-memory FFTW with MPI cannam@95: ********************************** cannam@95: cannam@95: In this chapter we document the parallel FFTW routines for parallel cannam@95: systems supporting the MPI message-passing interface. Unlike the cannam@95: shared-memory threads described in the previous chapter, MPI allows you cannam@95: to use _distributed-memory_ parallelism, where each CPU has its own cannam@95: separate memory, and which can scale up to clusters of many thousands cannam@95: of processors. This capability comes at a price, however: each process cannam@95: only stores a _portion_ of the data to be transformed, which means that cannam@95: the data structures and programming-interface are quite different from cannam@95: the serial or threads versions of FFTW. cannam@95: cannam@95: Distributed-memory parallelism is especially useful when you are cannam@95: transforming arrays so large that they do not fit into the memory of a cannam@95: single processor. The storage per-process required by FFTW's MPI cannam@95: routines is proportional to the total array size divided by the number cannam@95: of processes. Conversely, distributed-memory parallelism can easily cannam@95: pose an unacceptably high communications overhead for small problems; cannam@95: the threshold problem size for which parallelism becomes advantageous cannam@95: will depend on the precise problem you are interested in, your cannam@95: hardware, and your MPI implementation. cannam@95: cannam@95: A note on terminology: in MPI, you divide the data among a set of cannam@95: "processes" which each run in their own memory address space. cannam@95: Generally, each process runs on a different physical processor, but cannam@95: this is not required. A set of processes in MPI is described by an cannam@95: opaque data structure called a "communicator," the most common of which cannam@95: is the predefined communicator `MPI_COMM_WORLD' which refers to _all_ cannam@95: processes. For more information on these and other concepts common to cannam@95: all MPI programs, we refer the reader to the documentation at the MPI cannam@95: home page (http://www.mcs.anl.gov/research/projects/mpi/). cannam@95: cannam@95: We assume in this chapter that the reader is familiar with the usage cannam@95: of the serial (uniprocessor) FFTW, and focus only on the concepts new cannam@95: to the MPI interface. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * FFTW MPI Installation:: cannam@95: * Linking and Initializing MPI FFTW:: cannam@95: * 2d MPI example:: cannam@95: * MPI Data Distribution:: cannam@95: * Multi-dimensional MPI DFTs of Real Data:: cannam@95: * Other Multi-dimensional Real-data MPI Transforms:: cannam@95: * FFTW MPI Transposes:: cannam@95: * FFTW MPI Wisdom:: cannam@95: * Avoiding MPI Deadlocks:: cannam@95: * FFTW MPI Performance Tips:: cannam@95: * Combining MPI and Threads:: cannam@95: * FFTW MPI Reference:: cannam@95: * FFTW MPI Fortran Interface:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW MPI Installation, Next: Linking and Initializing MPI FFTW, Prev: Distributed-memory FFTW with MPI, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.1 FFTW MPI Installation cannam@95: ========================= cannam@95: cannam@95: All of the FFTW MPI code is located in the `mpi' subdirectory of the cannam@95: FFTW package. On Unix systems, the FFTW MPI libraries and header files cannam@95: are automatically configured, compiled, and installed along with the cannam@95: uniprocessor FFTW libraries simply by including `--enable-mpi' in the cannam@95: flags to the `configure' script (*note Installation on Unix::). cannam@95: cannam@95: Any implementation of the MPI standard, version 1 or later, should cannam@95: work with FFTW. The `configure' script will attempt to automatically cannam@95: detect how to compile and link code using your MPI implementation. In cannam@95: some cases, especially if you have multiple different MPI cannam@95: implementations installed or have an unusual MPI software package, you cannam@95: may need to provide this information explicitly. cannam@95: cannam@95: Most commonly, one compiles MPI code by invoking a special compiler cannam@95: command, typically `mpicc' for C code. The `configure' script knows cannam@95: the most common names for this command, but you can specify the MPI cannam@95: compilation command explicitly by setting the `MPICC' variable, as in cannam@95: `./configure MPICC=mpicc ...'. cannam@95: cannam@95: If, instead of a special compiler command, you need to link a certain cannam@95: library, you can specify the link command via the `MPILIBS' variable, cannam@95: as in `./configure MPILIBS=-lmpi ...'. Note that if your MPI library cannam@95: is installed in a non-standard location (one the compiler does not know cannam@95: about by default), you may also have to specify the location of the cannam@95: library and header files via `LDFLAGS' and `CPPFLAGS' variables, cannam@95: respectively, as in `./configure LDFLAGS=-L/path/to/mpi/libs cannam@95: CPPFLAGS=-I/path/to/mpi/include ...'. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Linking and Initializing MPI FFTW, Next: 2d MPI example, Prev: FFTW MPI Installation, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.2 Linking and Initializing MPI FFTW cannam@95: ===================================== cannam@95: cannam@95: Programs using the MPI FFTW routines should be linked with `-lfftw3_mpi cannam@95: -lfftw3 -lm' on Unix in double precision, `-lfftw3f_mpi -lfftw3f -lm' cannam@95: in single precision, and so on (*note Precision::). You will also need cannam@95: to link with whatever library is responsible for MPI on your system; in cannam@95: most MPI implementations, there is a special compiler alias named cannam@95: `mpicc' to compile and link MPI code. cannam@95: cannam@95: Before calling any FFTW routines except possibly `fftw_init_threads' cannam@95: (*note Combining MPI and Threads::), but after calling `MPI_Init', you cannam@95: should call the function: cannam@95: cannam@95: void fftw_mpi_init(void); cannam@95: cannam@95: If, at the end of your program, you want to get rid of all memory and cannam@95: other resources allocated internally by FFTW, for both the serial and cannam@95: MPI routines, you can call: cannam@95: cannam@95: void fftw_mpi_cleanup(void); cannam@95: cannam@95: which is much like the `fftw_cleanup()' function except that it also cannam@95: gets rid of FFTW's MPI-related data. You must _not_ execute any cannam@95: previously created plans after calling this function. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: 2d MPI example, Next: MPI Data Distribution, Prev: Linking and Initializing MPI FFTW, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.3 2d MPI example cannam@95: ================== cannam@95: cannam@95: Before we document the FFTW MPI interface in detail, we begin with a cannam@95: simple example outlining how one would perform a two-dimensional `N0' cannam@95: by `N1' complex DFT. cannam@95: cannam@95: #include cannam@95: cannam@95: int main(int argc, char **argv) cannam@95: { cannam@95: const ptrdiff_t N0 = ..., N1 = ...; cannam@95: fftw_plan plan; cannam@95: fftw_complex *data; cannam@95: ptrdiff_t alloc_local, local_n0, local_0_start, i, j; cannam@95: cannam@95: MPI_Init(&argc, &argv); cannam@95: fftw_mpi_init(); cannam@95: cannam@95: /* get local data size and allocate */ cannam@95: alloc_local = fftw_mpi_local_size_2d(N0, N1, MPI_COMM_WORLD, cannam@95: &local_n0, &local_0_start); cannam@95: data = fftw_alloc_complex(alloc_local); cannam@95: cannam@95: /* create plan for in-place forward DFT */ cannam@95: plan = fftw_mpi_plan_dft_2d(N0, N1, data, data, MPI_COMM_WORLD, cannam@95: FFTW_FORWARD, FFTW_ESTIMATE); cannam@95: cannam@95: /* initialize data to some function my_function(x,y) */ cannam@95: for (i = 0; i < local_n0; ++i) for (j = 0; j < N1; ++j) cannam@95: data[i*N1 + j] = my_function(local_0_start + i, j); cannam@95: cannam@95: /* compute transforms, in-place, as many times as desired */ cannam@95: fftw_execute(plan); cannam@95: cannam@95: fftw_destroy_plan(plan); cannam@95: cannam@95: MPI_Finalize(); cannam@95: } cannam@95: cannam@95: As can be seen above, the MPI interface follows the same basic style cannam@95: of allocate/plan/execute/destroy as the serial FFTW routines. All of cannam@95: the MPI-specific routines are prefixed with `fftw_mpi_' instead of cannam@95: `fftw_'. There are a few important differences, however: cannam@95: cannam@95: First, we must call `fftw_mpi_init()' after calling `MPI_Init' cannam@95: (required in all MPI programs) and before calling any other `fftw_mpi_' cannam@95: routine. cannam@95: cannam@95: Second, when we create the plan with `fftw_mpi_plan_dft_2d', cannam@95: analogous to `fftw_plan_dft_2d', we pass an additional argument: the cannam@95: communicator, indicating which processes will participate in the cannam@95: transform (here `MPI_COMM_WORLD', indicating all processes). Whenever cannam@95: you create, execute, or destroy a plan for an MPI transform, you must cannam@95: call the corresponding FFTW routine on _all_ processes in the cannam@95: communicator for that transform. (That is, these are _collective_ cannam@95: calls.) Note that the plan for the MPI transform uses the standard cannam@95: `fftw_execute' and `fftw_destroy' routines (on the other hand, there cannam@95: are MPI-specific new-array execute functions documented below). cannam@95: cannam@95: Third, all of the FFTW MPI routines take `ptrdiff_t' arguments cannam@95: instead of `int' as for the serial FFTW. `ptrdiff_t' is a standard C cannam@95: integer type which is (at least) 32 bits wide on a 32-bit machine and cannam@95: 64 bits wide on a 64-bit machine. This is to make it easy to specify cannam@95: very large parallel transforms on a 64-bit machine. (You can specify cannam@95: 64-bit transform sizes in the serial FFTW, too, but only by using the cannam@95: `guru64' planner interface. *Note 64-bit Guru Interface::.) cannam@95: cannam@95: Fourth, and most importantly, you don't allocate the entire cannam@95: two-dimensional array on each process. Instead, you call cannam@95: `fftw_mpi_local_size_2d' to find out what _portion_ of the array cannam@95: resides on each processor, and how much space to allocate. Here, the cannam@95: portion of the array on each process is a `local_n0' by `N1' slice of cannam@95: the total array, starting at index `local_0_start'. The total number cannam@95: of `fftw_complex' numbers to allocate is given by the `alloc_local' cannam@95: return value, which _may_ be greater than `local_n0 * N1' (in case some cannam@95: intermediate calculations require additional storage). The data cannam@95: distribution in FFTW's MPI interface is described in more detail by the cannam@95: next section. cannam@95: cannam@95: Given the portion of the array that resides on the local process, it cannam@95: is straightforward to initialize the data (here to a function cannam@95: `myfunction') and otherwise manipulate it. Of course, at the end of cannam@95: the program you may want to output the data somehow, but synchronizing cannam@95: this output is up to you and is beyond the scope of this manual. (One cannam@95: good way to output a large multi-dimensional distributed array in MPI cannam@95: to a portable binary file is to use the free HDF5 library; see the HDF cannam@95: home page (http://www.hdfgroup.org/).) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: MPI Data Distribution, Next: Multi-dimensional MPI DFTs of Real Data, Prev: 2d MPI example, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.4 MPI Data Distribution cannam@95: ========================= cannam@95: cannam@95: The most important concept to understand in using FFTW's MPI interface cannam@95: is the data distribution. With a serial or multithreaded FFT, all of cannam@95: the inputs and outputs are stored as a single contiguous chunk of cannam@95: memory. With a distributed-memory FFT, the inputs and outputs are cannam@95: broken into disjoint blocks, one per process. cannam@95: cannam@95: In particular, FFTW uses a _1d block distribution_ of the data, cannam@95: distributed along the _first dimension_. For example, if you want to cannam@95: perform a 100 x 200 complex DFT, distributed over 4 processes, each cannam@95: process will get a 25 x 200 slice of the data. That is, process 0 cannam@95: will get rows 0 through 24, process 1 will get rows 25 through 49, cannam@95: process 2 will get rows 50 through 74, and process 3 will get rows 75 cannam@95: through 99. If you take the same array but distribute it over 3 cannam@95: processes, then it is not evenly divisible so the different processes cannam@95: will have unequal chunks. FFTW's default choice in this case is to cannam@95: assign 34 rows to processes 0 and 1, and 32 rows to process 2. cannam@95: cannam@95: FFTW provides several `fftw_mpi_local_size' routines that you can cannam@95: call to find out what portion of an array is stored on the current cannam@95: process. In most cases, you should use the default block sizes picked cannam@95: by FFTW, but it is also possible to specify your own block size. For cannam@95: example, with a 100 x 200 array on three processes, you can tell FFTW cannam@95: to use a block size of 40, which would assign 40 rows to processes 0 cannam@95: and 1, and 20 rows to process 2. FFTW's default is to divide the data cannam@95: equally among the processes if possible, and as best it can otherwise. cannam@95: The rows are always assigned in "rank order," i.e. process 0 gets the cannam@95: first block of rows, then process 1, and so on. (You can change this cannam@95: by using `MPI_Comm_split' to create a new communicator with re-ordered cannam@95: processes.) However, you should always call the `fftw_mpi_local_size' cannam@95: routines, if possible, rather than trying to predict FFTW's cannam@95: distribution choices. cannam@95: cannam@95: In particular, it is critical that you allocate the storage size that cannam@95: is returned by `fftw_mpi_local_size', which is _not_ necessarily the cannam@95: size of the local slice of the array. The reason is that intermediate cannam@95: steps of FFTW's algorithms involve transposing the array and cannam@95: redistributing the data, so at these intermediate steps FFTW may cannam@95: require more local storage space (albeit always proportional to the cannam@95: total size divided by the number of processes). The cannam@95: `fftw_mpi_local_size' functions know how much storage is required for cannam@95: these intermediate steps and tell you the correct amount to allocate. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Basic and advanced distribution interfaces:: cannam@95: * Load balancing:: cannam@95: * Transposed distributions:: cannam@95: * One-dimensional distributions:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Basic and advanced distribution interfaces, Next: Load balancing, Prev: MPI Data Distribution, Up: MPI Data Distribution cannam@95: cannam@95: 6.4.1 Basic and advanced distribution interfaces cannam@95: ------------------------------------------------ cannam@95: cannam@95: As with the planner interface, the `fftw_mpi_local_size' distribution cannam@95: interface is broken into basic and advanced (`_many') interfaces, where cannam@95: the latter allows you to specify the block size manually and also to cannam@95: request block sizes when computing multiple transforms simultaneously. cannam@95: These functions are documented more exhaustively by the FFTW MPI cannam@95: Reference, but we summarize the basic ideas here using a couple of cannam@95: two-dimensional examples. cannam@95: cannam@95: For the 100 x 200 complex-DFT example, above, we would find the cannam@95: distribution by calling the following function in the basic interface: cannam@95: cannam@95: ptrdiff_t fftw_mpi_local_size_2d(ptrdiff_t n0, ptrdiff_t n1, MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start); cannam@95: cannam@95: Given the total size of the data to be transformed (here, `n0 = 100' cannam@95: and `n1 = 200') and an MPI communicator (`comm'), this function cannam@95: provides three numbers. cannam@95: cannam@95: First, it describes the shape of the local data: the current process cannam@95: should store a `local_n0' by `n1' slice of the overall dataset, in cannam@95: row-major order (`n1' dimension contiguous), starting at index cannam@95: `local_0_start'. That is, if the total dataset is viewed as a `n0' by cannam@95: `n1' matrix, the current process should store the rows `local_0_start' cannam@95: to `local_0_start+local_n0-1'. Obviously, if you are running with only cannam@95: a single MPI process, that process will store the entire array: cannam@95: `local_0_start' will be zero and `local_n0' will be `n0'. *Note cannam@95: Row-major Format::. cannam@95: cannam@95: Second, the return value is the total number of data elements (e.g., cannam@95: complex numbers for a complex DFT) that should be allocated for the cannam@95: input and output arrays on the current process (ideally with cannam@95: `fftw_malloc' or an `fftw_alloc' function, to ensure optimal cannam@95: alignment). It might seem that this should always be equal to cannam@95: `local_n0 * n1', but this is _not_ the case. FFTW's distributed FFT cannam@95: algorithms require data redistributions at intermediate stages of the cannam@95: transform, and in some circumstances this may require slightly larger cannam@95: local storage. This is discussed in more detail below, under *note cannam@95: Load balancing::. cannam@95: cannam@95: The advanced-interface `local_size' function for multidimensional cannam@95: transforms returns the same three things (`local_n0', `local_0_start', cannam@95: and the total number of elements to allocate), but takes more inputs: cannam@95: cannam@95: ptrdiff_t fftw_mpi_local_size_many(int rnk, const ptrdiff_t *n, cannam@95: ptrdiff_t howmany, cannam@95: ptrdiff_t block0, cannam@95: MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, cannam@95: ptrdiff_t *local_0_start); cannam@95: cannam@95: The two-dimensional case above corresponds to `rnk = 2' and an array cannam@95: `n' of length 2 with `n[0] = n0' and `n[1] = n1'. This routine is for cannam@95: any `rnk > 1'; one-dimensional transforms have their own interface cannam@95: because they work slightly differently, as discussed below. cannam@95: cannam@95: First, the advanced interface allows you to perform multiple cannam@95: transforms at once, of interleaved data, as specified by the `howmany' cannam@95: parameter. (`hoamany' is 1 for a single transform.) cannam@95: cannam@95: Second, here you can specify your desired block size in the `n0' cannam@95: dimension, `block0'. To use FFTW's default block size, pass cannam@95: `FFTW_MPI_DEFAULT_BLOCK' (0) for `block0'. Otherwise, on `P' cannam@95: processes, FFTW will return `local_n0' equal to `block0' on the first cannam@95: `P / block0' processes (rounded down), return `local_n0' equal to `n0 - cannam@95: block0 * (P / block0)' on the next process, and `local_n0' equal to cannam@95: zero on any remaining processes. In general, we recommend using the cannam@95: default block size (which corresponds to `n0 / P', rounded up). cannam@95: cannam@95: For example, suppose you have `P = 4' processes and `n0 = 21'. The cannam@95: default will be a block size of `6', which will give `local_n0 = 6' on cannam@95: the first three processes and `local_n0 = 3' on the last process. cannam@95: Instead, however, you could specify `block0 = 5' if you wanted, which cannam@95: would give `local_n0 = 5' on processes 0 to 2, `local_n0 = 6' on cannam@95: process 3. (This choice, while it may look superficially more cannam@95: "balanced," has the same critical path as FFTW's default but requires cannam@95: more communications.) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Load balancing, Next: Transposed distributions, Prev: Basic and advanced distribution interfaces, Up: MPI Data Distribution cannam@95: cannam@95: 6.4.2 Load balancing cannam@95: -------------------- cannam@95: cannam@95: Ideally, when you parallelize a transform over some P processes, each cannam@95: process should end up with work that takes equal time. Otherwise, all cannam@95: of the processes end up waiting on whichever process is slowest. This cannam@95: goal is known as "load balancing." In this section, we describe the cannam@95: circumstances under which FFTW is able to load-balance well, and in cannam@95: particular how you should choose your transform size in order to load cannam@95: balance. cannam@95: cannam@95: Load balancing is especially difficult when you are parallelizing cannam@95: over heterogeneous machines; for example, if one of your processors is a cannam@95: old 486 and another is a Pentium IV, obviously you should give the cannam@95: Pentium more work to do than the 486 since the latter is much slower. cannam@95: FFTW does not deal with this problem, however--it assumes that your cannam@95: processes run on hardware of comparable speed, and that the goal is cannam@95: therefore to divide the problem as equally as possible. cannam@95: cannam@95: For a multi-dimensional complex DFT, FFTW can divide the problem cannam@95: equally among the processes if: (i) the _first_ dimension `n0' is cannam@95: divisible by P; and (ii), the _product_ of the subsequent dimensions is cannam@95: divisible by P. (For the advanced interface, where you can specify cannam@95: multiple simultaneous transforms via some "vector" length `howmany', a cannam@95: factor of `howmany' is included in the product of the subsequent cannam@95: dimensions.) cannam@95: cannam@95: For a one-dimensional complex DFT, the length `N' of the data should cannam@95: be divisible by P _squared_ to be able to divide the problem equally cannam@95: among the processes. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Transposed distributions, Next: One-dimensional distributions, Prev: Load balancing, Up: MPI Data Distribution cannam@95: cannam@95: 6.4.3 Transposed distributions cannam@95: ------------------------------ cannam@95: cannam@95: Internally, FFTW's MPI transform algorithms work by first computing cannam@95: transforms of the data local to each process, then by globally cannam@95: _transposing_ the data in some fashion to redistribute the data among cannam@95: the processes, transforming the new data local to each process, and cannam@95: transposing back. For example, a two-dimensional `n0' by `n1' array, cannam@95: distributed across the `n0' dimension, is transformd by: (i) cannam@95: transforming the `n1' dimension, which are local to each process; (ii) cannam@95: transposing to an `n1' by `n0' array, distributed across the `n1' cannam@95: dimension; (iii) transforming the `n0' dimension, which is now local to cannam@95: each process; (iv) transposing back. cannam@95: cannam@95: However, in many applications it is acceptable to compute a cannam@95: multidimensional DFT whose results are produced in transposed order cannam@95: (e.g., `n1' by `n0' in two dimensions). This provides a significant cannam@95: performance advantage, because it means that the final transposition cannam@95: step can be omitted. FFTW supports this optimization, which you cannam@95: specify by passing the flag `FFTW_MPI_TRANSPOSED_OUT' to the planner cannam@95: routines. To compute the inverse transform of transposed output, you cannam@95: specify `FFTW_MPI_TRANSPOSED_IN' to tell it that the input is cannam@95: transposed. In this section, we explain how to interpret the output cannam@95: format of such a transform. cannam@95: cannam@95: Suppose you have are transforming multi-dimensional data with (at cannam@95: least two) dimensions n[0] x n[1] x n[2] x ... x n[d-1] . As always, cannam@95: it is distributed along the first dimension n[0] . Now, if we compute cannam@95: its DFT with the `FFTW_MPI_TRANSPOSED_OUT' flag, the resulting output cannam@95: data are stored with the first _two_ dimensions transposed: n[1] x n[0] cannam@95: x n[2] x ... x n[d-1] , distributed along the n[1] dimension. cannam@95: Conversely, if we take the n[1] x n[0] x n[2] x ... x n[d-1] data and cannam@95: transform it with the `FFTW_MPI_TRANSPOSED_IN' flag, then the format cannam@95: goes back to the original n[0] x n[1] x n[2] x ... x n[d-1] array. cannam@95: cannam@95: There are two ways to find the portion of the transposed array that cannam@95: resides on the current process. First, you can simply call the cannam@95: appropriate `local_size' function, passing n[1] x n[0] x n[2] x ... x cannam@95: n[d-1] (the transposed dimensions). This would mean calling the cannam@95: `local_size' function twice, once for the transposed and once for the cannam@95: non-transposed dimensions. Alternatively, you can call one of the cannam@95: `local_size_transposed' functions, which returns both the cannam@95: non-transposed and transposed data distribution from a single call. cannam@95: For example, for a 3d transform with transposed output (or input), you cannam@95: might call: cannam@95: cannam@95: ptrdiff_t fftw_mpi_local_size_3d_transposed( cannam@95: ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t n2, MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start, cannam@95: ptrdiff_t *local_n1, ptrdiff_t *local_1_start); cannam@95: cannam@95: Here, `local_n0' and `local_0_start' give the size and starting cannam@95: index of the `n0' dimension for the _non_-transposed data, as in the cannam@95: previous sections. For _transposed_ data (e.g. the output for cannam@95: `FFTW_MPI_TRANSPOSED_OUT'), `local_n1' and `local_1_start' give the cannam@95: size and starting index of the `n1' dimension, which is the first cannam@95: dimension of the transposed data (`n1' by `n0' by `n2'). cannam@95: cannam@95: (Note that `FFTW_MPI_TRANSPOSED_IN' is completely equivalent to cannam@95: performing `FFTW_MPI_TRANSPOSED_OUT' and passing the first two cannam@95: dimensions to the planner in reverse order, or vice versa. If you pass cannam@95: _both_ the `FFTW_MPI_TRANSPOSED_IN' and `FFTW_MPI_TRANSPOSED_OUT' cannam@95: flags, it is equivalent to swapping the first two dimensions passed to cannam@95: the planner and passing _neither_ flag.) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: One-dimensional distributions, Prev: Transposed distributions, Up: MPI Data Distribution cannam@95: cannam@95: 6.4.4 One-dimensional distributions cannam@95: ----------------------------------- cannam@95: cannam@95: For one-dimensional distributed DFTs using FFTW, matters are slightly cannam@95: more complicated because the data distribution is more closely tied to cannam@95: how the algorithm works. In particular, you can no longer pass an cannam@95: arbitrary block size and must accept FFTW's default; also, the block cannam@95: sizes may be different for input and output. Also, the data cannam@95: distribution depends on the flags and transform direction, in order for cannam@95: forward and backward transforms to work correctly. cannam@95: cannam@95: ptrdiff_t fftw_mpi_local_size_1d(ptrdiff_t n0, MPI_Comm comm, cannam@95: int sign, unsigned flags, cannam@95: ptrdiff_t *local_ni, ptrdiff_t *local_i_start, cannam@95: ptrdiff_t *local_no, ptrdiff_t *local_o_start); cannam@95: cannam@95: This function computes the data distribution for a 1d transform of cannam@95: size `n0' with the given transform `sign' and `flags'. Both input and cannam@95: output data use block distributions. The input on the current process cannam@95: will consist of `local_ni' numbers starting at index `local_i_start'; cannam@95: e.g. if only a single process is used, then `local_ni' will be `n0' and cannam@95: `local_i_start' will be `0'. Similarly for the output, with `local_no' cannam@95: numbers starting at index `local_o_start'. The return value of cannam@95: `fftw_mpi_local_size_1d' will be the total number of elements to cannam@95: allocate on the current process (which might be slightly larger than cannam@95: the local size due to intermediate steps in the algorithm). cannam@95: cannam@95: As mentioned above (*note Load balancing::), the data will be divided cannam@95: equally among the processes if `n0' is divisible by the _square_ of the cannam@95: number of processes. In this case, `local_ni' will equal `local_no'. cannam@95: Otherwise, they may be different. cannam@95: cannam@95: For some applications, such as convolutions, the order of the output cannam@95: data is irrelevant. In this case, performance can be improved by cannam@95: specifying that the output data be stored in an FFTW-defined cannam@95: "scrambled" format. (In particular, this is the analogue of transposed cannam@95: output in the multidimensional case: scrambled output saves a cannam@95: communications step.) If you pass `FFTW_MPI_SCRAMBLED_OUT' in the cannam@95: flags, then the output is stored in this (undocumented) scrambled cannam@95: order. Conversely, to perform the inverse transform of data in cannam@95: scrambled order, pass the `FFTW_MPI_SCRAMBLED_IN' flag. cannam@95: cannam@95: In MPI FFTW, only composite sizes `n0' can be parallelized; we have cannam@95: not yet implemented a parallel algorithm for large prime sizes. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Multi-dimensional MPI DFTs of Real Data, Next: Other Multi-dimensional Real-data MPI Transforms, Prev: MPI Data Distribution, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.5 Multi-dimensional MPI DFTs of Real Data cannam@95: =========================================== cannam@95: cannam@95: FFTW's MPI interface also supports multi-dimensional DFTs of real data, cannam@95: similar to the serial r2c and c2r interfaces. (Parallel cannam@95: one-dimensional real-data DFTs are not currently supported; you must cannam@95: use a complex transform and set the imaginary parts of the inputs to cannam@95: zero.) cannam@95: cannam@95: The key points to understand for r2c and c2r MPI transforms (compared cannam@95: to the MPI complex DFTs or the serial r2c/c2r transforms), are: cannam@95: cannam@95: * Just as for serial transforms, r2c/c2r DFTs transform n[0] x n[1] cannam@95: x n[2] x ... x n[d-1] real data to/from n[0] x n[1] x n[2] x ... cannam@95: x (n[d-1]/2 + 1) complex data: the last dimension of the complex cannam@95: data is cut in half (rounded down), plus one. As for the serial cannam@95: transforms, the sizes you pass to the `plan_dft_r2c' and cannam@95: `plan_dft_c2r' are the n[0] x n[1] x n[2] x ... x n[d-1] cannam@95: dimensions of the real data. cannam@95: cannam@95: * Although the real data is _conceptually_ n[0] x n[1] x n[2] x ... cannam@95: x n[d-1] , it is _physically_ stored as an n[0] x n[1] x n[2] x cannam@95: ... x [2 (n[d-1]/2 + 1)] array, where the last dimension has been cannam@95: _padded_ to make it the same size as the complex output. This is cannam@95: much like the in-place serial r2c/c2r interface (*note cannam@95: Multi-Dimensional DFTs of Real Data::), except that in MPI the cannam@95: padding is required even for out-of-place data. The extra padding cannam@95: numbers are ignored by FFTW (they are _not_ like zero-padding the cannam@95: transform to a larger size); they are only used to determine the cannam@95: data layout. cannam@95: cannam@95: * The data distribution in MPI for _both_ the real and complex data cannam@95: is determined by the shape of the _complex_ data. That is, you cannam@95: call the appropriate `local size' function for the n[0] x n[1] x cannam@95: n[2] x ... x (n[d-1]/2 + 1) cannam@95: cannam@95: complex data, and then use the _same_ distribution for the real cannam@95: data except that the last complex dimension is replaced by a cannam@95: (padded) real dimension of twice the length. cannam@95: cannam@95: cannam@95: For example suppose we are performing an out-of-place r2c transform cannam@95: of L x M x N real data [padded to L x M x 2(N/2+1) ], resulting in L x cannam@95: M x N/2+1 complex data. Similar to the example in *note 2d MPI cannam@95: example::, we might do something like: cannam@95: cannam@95: #include cannam@95: cannam@95: int main(int argc, char **argv) cannam@95: { cannam@95: const ptrdiff_t L = ..., M = ..., N = ...; cannam@95: fftw_plan plan; cannam@95: double *rin; cannam@95: fftw_complex *cout; cannam@95: ptrdiff_t alloc_local, local_n0, local_0_start, i, j, k; cannam@95: cannam@95: MPI_Init(&argc, &argv); cannam@95: fftw_mpi_init(); cannam@95: cannam@95: /* get local data size and allocate */ cannam@95: alloc_local = fftw_mpi_local_size_3d(L, M, N/2+1, MPI_COMM_WORLD, cannam@95: &local_n0, &local_0_start); cannam@95: rin = fftw_alloc_real(2 * alloc_local); cannam@95: cout = fftw_alloc_complex(alloc_local); cannam@95: cannam@95: /* create plan for out-of-place r2c DFT */ cannam@95: plan = fftw_mpi_plan_dft_r2c_3d(L, M, N, rin, cout, MPI_COMM_WORLD, cannam@95: FFTW_MEASURE); cannam@95: cannam@95: /* initialize rin to some function my_func(x,y,z) */ cannam@95: for (i = 0; i < local_n0; ++i) cannam@95: for (j = 0; j < M; ++j) cannam@95: for (k = 0; k < N; ++k) cannam@95: rin[(i*M + j) * (2*(N/2+1)) + k] = my_func(local_0_start+i, j, k); cannam@95: cannam@95: /* compute transforms as many times as desired */ cannam@95: fftw_execute(plan); cannam@95: cannam@95: fftw_destroy_plan(plan); cannam@95: cannam@95: MPI_Finalize(); cannam@95: } cannam@95: cannam@95: Note that we allocated `rin' using `fftw_alloc_real' with an cannam@95: argument of `2 * alloc_local': since `alloc_local' is the number of cannam@95: _complex_ values to allocate, the number of _real_ values is twice as cannam@95: many. The `rin' array is then local_n0 x M x 2(N/2+1) in row-major cannam@95: order, so its `(i,j,k)' element is at the index `(i*M + j) * cannam@95: (2*(N/2+1)) + k' (*note Multi-dimensional Array Format::). cannam@95: cannam@95: As for the complex transforms, improved performance can be obtained cannam@95: by specifying that the output is the transpose of the input or vice cannam@95: versa (*note Transposed distributions::). In our L x M x N r2c cannam@95: example, including `FFTW_TRANSPOSED_OUT' in the flags means that the cannam@95: input would be a padded L x M x 2(N/2+1) real array distributed over cannam@95: the `L' dimension, while the output would be a M x L x N/2+1 complex cannam@95: array distributed over the `M' dimension. To perform the inverse c2r cannam@95: transform with the same data distributions, you would use the cannam@95: `FFTW_TRANSPOSED_IN' flag. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Other Multi-dimensional Real-data MPI Transforms, Next: FFTW MPI Transposes, Prev: Multi-dimensional MPI DFTs of Real Data, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.6 Other multi-dimensional Real-Data MPI Transforms cannam@95: ==================================================== cannam@95: cannam@95: FFTW's MPI interface also supports multi-dimensional `r2r' transforms cannam@95: of all kinds supported by the serial interface (e.g. discrete cosine cannam@95: and sine transforms, discrete Hartley transforms, etc.). Only cannam@95: multi-dimensional `r2r' transforms, not one-dimensional transforms, are cannam@95: currently parallelized. cannam@95: cannam@95: These are used much like the multidimensional complex DFTs discussed cannam@95: above, except that the data is real rather than complex, and one needs cannam@95: to pass an r2r transform kind (`fftw_r2r_kind') for each dimension as cannam@95: in the serial FFTW (*note More DFTs of Real Data::). cannam@95: cannam@95: For example, one might perform a two-dimensional L x M that is an cannam@95: REDFT10 (DCT-II) in the first dimension and an RODFT10 (DST-II) in the cannam@95: second dimension with code like: cannam@95: cannam@95: const ptrdiff_t L = ..., M = ...; cannam@95: fftw_plan plan; cannam@95: double *data; cannam@95: ptrdiff_t alloc_local, local_n0, local_0_start, i, j; cannam@95: cannam@95: /* get local data size and allocate */ cannam@95: alloc_local = fftw_mpi_local_size_2d(L, M, MPI_COMM_WORLD, cannam@95: &local_n0, &local_0_start); cannam@95: data = fftw_alloc_real(alloc_local); cannam@95: cannam@95: /* create plan for in-place REDFT10 x RODFT10 */ cannam@95: plan = fftw_mpi_plan_r2r_2d(L, M, data, data, MPI_COMM_WORLD, cannam@95: FFTW_REDFT10, FFTW_RODFT10, FFTW_MEASURE); cannam@95: cannam@95: /* initialize data to some function my_function(x,y) */ cannam@95: for (i = 0; i < local_n0; ++i) for (j = 0; j < M; ++j) cannam@95: data[i*M + j] = my_function(local_0_start + i, j); cannam@95: cannam@95: /* compute transforms, in-place, as many times as desired */ cannam@95: fftw_execute(plan); cannam@95: cannam@95: fftw_destroy_plan(plan); cannam@95: cannam@95: Notice that we use the same `local_size' functions as we did for cannam@95: complex data, only now we interpret the sizes in terms of real rather cannam@95: than complex values, and correspondingly use `fftw_alloc_real'. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW MPI Transposes, Next: FFTW MPI Wisdom, Prev: Other Multi-dimensional Real-data MPI Transforms, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.7 FFTW MPI Transposes cannam@95: ======================= cannam@95: cannam@95: The FFTW's MPI Fourier transforms rely on one or more _global cannam@95: transposition_ step for their communications. For example, the cannam@95: multidimensional transforms work by transforming along some dimensions, cannam@95: then transposing to make the first dimension local and transforming cannam@95: that, then transposing back. Because global transposition of a cannam@95: block-distributed matrix has many other potential uses besides FFTs, cannam@95: FFTW's transpose routines can be called directly, as documented in this cannam@95: section. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Basic distributed-transpose interface:: cannam@95: * Advanced distributed-transpose interface:: cannam@95: * An improved replacement for MPI_Alltoall:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Basic distributed-transpose interface, Next: Advanced distributed-transpose interface, Prev: FFTW MPI Transposes, Up: FFTW MPI Transposes cannam@95: cannam@95: 6.7.1 Basic distributed-transpose interface cannam@95: ------------------------------------------- cannam@95: cannam@95: In particular, suppose that we have an `n0' by `n1' array in row-major cannam@95: order, block-distributed across the `n0' dimension. To transpose this cannam@95: into an `n1' by `n0' array block-distributed across the `n1' dimension, cannam@95: we would create a plan by calling the following function: cannam@95: cannam@95: fftw_plan fftw_mpi_plan_transpose(ptrdiff_t n0, ptrdiff_t n1, cannam@95: double *in, double *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: cannam@95: The input and output arrays (`in' and `out') can be the same. The cannam@95: transpose is actually executed by calling `fftw_execute' on the plan, cannam@95: as usual. cannam@95: cannam@95: The `flags' are the usual FFTW planner flags, but support two cannam@95: additional flags: `FFTW_MPI_TRANSPOSED_OUT' and/or cannam@95: `FFTW_MPI_TRANSPOSED_IN'. What these flags indicate, for transpose cannam@95: plans, is that the output and/or input, respectively, are _locally_ cannam@95: transposed. That is, on each process input data is normally stored as cannam@95: a `local_n0' by `n1' array in row-major order, but for an cannam@95: `FFTW_MPI_TRANSPOSED_IN' plan the input data is stored as `n1' by cannam@95: `local_n0' in row-major order. Similarly, `FFTW_MPI_TRANSPOSED_OUT' cannam@95: means that the output is `n0' by `local_n1' instead of `local_n1' by cannam@95: `n0'. cannam@95: cannam@95: To determine the local size of the array on each process before and cannam@95: after the transpose, as well as the amount of storage that must be cannam@95: allocated, one should call `fftw_mpi_local_size_2d_transposed', just as cannam@95: for a 2d DFT as described in the previous section: cannam@95: cannam@95: ptrdiff_t fftw_mpi_local_size_2d_transposed cannam@95: (ptrdiff_t n0, ptrdiff_t n1, MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start, cannam@95: ptrdiff_t *local_n1, ptrdiff_t *local_1_start); cannam@95: cannam@95: Again, the return value is the local storage to allocate, which in cannam@95: this case is the number of _real_ (`double') values rather than complex cannam@95: numbers as in the previous examples. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Advanced distributed-transpose interface, Next: An improved replacement for MPI_Alltoall, Prev: Basic distributed-transpose interface, Up: FFTW MPI Transposes cannam@95: cannam@95: 6.7.2 Advanced distributed-transpose interface cannam@95: ---------------------------------------------- cannam@95: cannam@95: The above routines are for a transpose of a matrix of numbers (of type cannam@95: `double'), using FFTW's default block sizes. More generally, one can cannam@95: perform transposes of _tuples_ of numbers, with user-specified block cannam@95: sizes for the input and output: cannam@95: cannam@95: fftw_plan fftw_mpi_plan_many_transpose cannam@95: (ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t howmany, cannam@95: ptrdiff_t block0, ptrdiff_t block1, cannam@95: double *in, double *out, MPI_Comm comm, unsigned flags); cannam@95: cannam@95: In this case, one is transposing an `n0' by `n1' matrix of cannam@95: `howmany'-tuples (e.g. `howmany = 2' for complex numbers). The input cannam@95: is distributed along the `n0' dimension with block size `block0', and cannam@95: the `n1' by `n0' output is distributed along the `n1' dimension with cannam@95: block size `block1'. If `FFTW_MPI_DEFAULT_BLOCK' (0) is passed for a cannam@95: block size then FFTW uses its default block size. To get the local cannam@95: size of the data on each process, you should then call cannam@95: `fftw_mpi_local_size_many_transposed'. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: An improved replacement for MPI_Alltoall, Prev: Advanced distributed-transpose interface, Up: FFTW MPI Transposes cannam@95: cannam@95: 6.7.3 An improved replacement for MPI_Alltoall cannam@95: ---------------------------------------------- cannam@95: cannam@95: We close this section by noting that FFTW's MPI transpose routines can cannam@95: be thought of as a generalization for the `MPI_Alltoall' function cannam@95: (albeit only for floating-point types), and in some circumstances can cannam@95: function as an improved replacement. cannam@95: cannam@95: `MPI_Alltoall' is defined by the MPI standard as: cannam@95: cannam@95: int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype, cannam@95: void *recvbuf, int recvcnt, MPI_Datatype recvtype, cannam@95: MPI_Comm comm); cannam@95: cannam@95: In particular, for `double*' arrays `in' and `out', consider the cannam@95: call: cannam@95: cannam@95: MPI_Alltoall(in, howmany, MPI_DOUBLE, out, howmany MPI_DOUBLE, comm); cannam@95: cannam@95: This is completely equivalent to: cannam@95: cannam@95: MPI_Comm_size(comm, &P); cannam@95: plan = fftw_mpi_plan_many_transpose(P, P, howmany, 1, 1, in, out, comm, FFTW_ESTIMATE); cannam@95: fftw_execute(plan); cannam@95: fftw_destroy_plan(plan); cannam@95: cannam@95: That is, computing a P x P transpose on `P' processes, with a block cannam@95: size of 1, is just a standard all-to-all communication. cannam@95: cannam@95: However, using the FFTW routine instead of `MPI_Alltoall' may have cannam@95: certain advantages. First of all, FFTW's routine can operate in-place cannam@95: (`in == out') whereas `MPI_Alltoall' can only operate out-of-place. cannam@95: cannam@95: Second, even for out-of-place plans, FFTW's routine may be faster, cannam@95: especially if you need to perform the all-to-all communication many cannam@95: times and can afford to use `FFTW_MEASURE' or `FFTW_PATIENT'. It cannam@95: should certainly be no slower, not including the time to create the cannam@95: plan, since one of the possible algorithms that FFTW uses for an cannam@95: out-of-place transpose _is_ simply to call `MPI_Alltoall'. However, cannam@95: FFTW also considers several other possible algorithms that, depending cannam@95: on your MPI implementation and your hardware, may be faster. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW MPI Wisdom, Next: Avoiding MPI Deadlocks, Prev: FFTW MPI Transposes, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.8 FFTW MPI Wisdom cannam@95: =================== cannam@95: cannam@95: FFTW's "wisdom" facility (*note Words of Wisdom-Saving Plans::) can be cannam@95: used to save MPI plans as well as to save uniprocessor plans. However, cannam@95: for MPI there are several unavoidable complications. cannam@95: cannam@95: First, the MPI standard does not guarantee that every process can cannam@95: perform file I/O (at least, not using C stdio routines)--in general, we cannam@95: may only assume that process 0 is capable of I/O.(1) So, if we want to cannam@95: export the wisdom from a single process to a file, we must first export cannam@95: the wisdom to a string, then send it to process 0, then write it to a cannam@95: file. cannam@95: cannam@95: Second, in principle we may want to have separate wisdom for every cannam@95: process, since in general the processes may run on different hardware cannam@95: even for a single MPI program. However, in practice FFTW's MPI code is cannam@95: designed for the case of homogeneous hardware (*note Load balancing::), cannam@95: and in this case it is convenient to use the same wisdom for every cannam@95: process. Thus, we need a mechanism to synchronize the wisdom. cannam@95: cannam@95: To address both of these problems, FFTW provides the following two cannam@95: functions: cannam@95: cannam@95: void fftw_mpi_broadcast_wisdom(MPI_Comm comm); cannam@95: void fftw_mpi_gather_wisdom(MPI_Comm comm); cannam@95: cannam@95: Given a communicator `comm', `fftw_mpi_broadcast_wisdom' will cannam@95: broadcast the wisdom from process 0 to all other processes. cannam@95: Conversely, `fftw_mpi_gather_wisdom' will collect wisdom from all cannam@95: processes onto process 0. (If the plans created for the same problem cannam@95: by different processes are not the same, `fftw_mpi_gather_wisdom' will cannam@95: arbitrarily choose one of the plans.) Both of these functions may cannam@95: result in suboptimal plans for different processes if the processes are cannam@95: running on non-identical hardware. Both of these functions are cannam@95: _collective_ calls, which means that they must be executed by all cannam@95: processes in the communicator. cannam@95: cannam@95: So, for example, a typical code snippet to import wisdom from a file cannam@95: and use it on all processes would be: cannam@95: cannam@95: { cannam@95: int rank; cannam@95: cannam@95: fftw_mpi_init(); cannam@95: MPI_Comm_rank(MPI_COMM_WORLD, &rank); cannam@95: if (rank == 0) fftw_import_wisdom_from_filename("mywisdom"); cannam@95: fftw_mpi_broadcast_wisdom(MPI_COMM_WORLD); cannam@95: } cannam@95: cannam@95: (Note that we must call `fftw_mpi_init' before importing any wisdom cannam@95: that might contain MPI plans.) Similarly, a typical code snippet to cannam@95: export wisdom from all processes to a file is: cannam@95: cannam@95: { cannam@95: int rank; cannam@95: cannam@95: fftw_mpi_gather_wisdom(MPI_COMM_WORLD); cannam@95: MPI_Comm_rank(MPI_COMM_WORLD, &rank); cannam@95: if (rank == 0) fftw_export_wisdom_to_filename("mywisdom"); cannam@95: } cannam@95: cannam@95: ---------- Footnotes ---------- cannam@95: cannam@95: (1) In fact, even this assumption is not technically guaranteed by cannam@95: the standard, although it seems to be universal in actual MPI cannam@95: implementations and is widely assumed by MPI-using software. cannam@95: Technically, you need to query the `MPI_IO' attribute of cannam@95: `MPI_COMM_WORLD' with `MPI_Attr_get'. If this attribute is cannam@95: `MPI_PROC_NULL', no I/O is possible. If it is `MPI_ANY_SOURCE', any cannam@95: process can perform I/O. Otherwise, it is the rank of a process that cannam@95: can perform I/O ... but since it is not guaranteed to yield the _same_ cannam@95: rank on all processes, you have to do an `MPI_Allreduce' of some kind cannam@95: if you want all processes to agree about which is going to do I/O. And cannam@95: even then, the standard only guarantees that this process can perform cannam@95: output, but not input. See e.g. `Parallel Programming with MPI' by P. cannam@95: S. Pacheco, section 8.1.3. Needless to say, in our experience cannam@95: virtually no MPI programmers worry about this. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Avoiding MPI Deadlocks, Next: FFTW MPI Performance Tips, Prev: FFTW MPI Wisdom, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.9 Avoiding MPI Deadlocks cannam@95: ========================== cannam@95: cannam@95: An MPI program can _deadlock_ if one process is waiting for a message cannam@95: from another process that never gets sent. To avoid deadlocks when cannam@95: using FFTW's MPI routines, it is important to know which functions are cannam@95: _collective_: that is, which functions must _always_ be called in the cannam@95: _same order_ from _every_ process in a given communicator. (For cannam@95: example, `MPI_Barrier' is the canonical example of a collective cannam@95: function in the MPI standard.) cannam@95: cannam@95: The functions in FFTW that are _always_ collective are: every cannam@95: function beginning with `fftw_mpi_plan', as well as cannam@95: `fftw_mpi_broadcast_wisdom' and `fftw_mpi_gather_wisdom'. Also, the cannam@95: following functions from the ordinary FFTW interface are collective cannam@95: when they are applied to a plan created by an `fftw_mpi_plan' function: cannam@95: `fftw_execute', `fftw_destroy_plan', and `fftw_flops'. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW MPI Performance Tips, Next: Combining MPI and Threads, Prev: Avoiding MPI Deadlocks, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.10 FFTW MPI Performance Tips cannam@95: ============================== cannam@95: cannam@95: In this section, we collect a few tips on getting the best performance cannam@95: out of FFTW's MPI transforms. cannam@95: cannam@95: First, because of the 1d block distribution, FFTW's parallelization cannam@95: is currently limited by the size of the first dimension. cannam@95: (Multidimensional block distributions may be supported by a future cannam@95: version.) More generally, you should ideally arrange the dimensions so cannam@95: that FFTW can divide them equally among the processes. *Note Load cannam@95: balancing::. cannam@95: cannam@95: Second, if it is not too inconvenient, you should consider working cannam@95: with transposed output for multidimensional plans, as this saves a cannam@95: considerable amount of communications. *Note Transposed cannam@95: distributions::. cannam@95: cannam@95: Third, the fastest choices are generally either an in-place transform cannam@95: or an out-of-place transform with the `FFTW_DESTROY_INPUT' flag (which cannam@95: allows the input array to be used as scratch space). In-place is cannam@95: especially beneficial if the amount of data per process is large. cannam@95: cannam@95: Fourth, if you have multiple arrays to transform at once, rather than cannam@95: calling FFTW's MPI transforms several times it usually seems to be cannam@95: faster to interleave the data and use the advanced interface. (This cannam@95: groups the communications together instead of requiring separate cannam@95: messages for each transform.) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Combining MPI and Threads, Next: FFTW MPI Reference, Prev: FFTW MPI Performance Tips, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.11 Combining MPI and Threads cannam@95: ============================== cannam@95: cannam@95: In certain cases, it may be advantageous to combine MPI cannam@95: (distributed-memory) and threads (shared-memory) parallelization. FFTW cannam@95: supports this, with certain caveats. For example, if you have a cannam@95: cluster of 4-processor shared-memory nodes, you may want to use threads cannam@95: within the nodes and MPI between the nodes, instead of MPI for all cannam@95: parallelization. cannam@95: cannam@95: In particular, it is possible to seamlessly combine the MPI FFTW cannam@95: routines with the multi-threaded FFTW routines (*note Multi-threaded cannam@95: FFTW::). However, some care must be taken in the initialization code, cannam@95: which should look something like this: cannam@95: cannam@95: int threads_ok; cannam@95: cannam@95: int main(int argc, char **argv) cannam@95: { cannam@95: int provided; cannam@95: MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); cannam@95: threads_ok = provided >= MPI_THREAD_FUNNELED; cannam@95: cannam@95: if (threads_ok) threads_ok = fftw_init_threads(); cannam@95: fftw_mpi_init(); cannam@95: cannam@95: ... cannam@95: if (threads_ok) fftw_plan_with_nthreads(...); cannam@95: ... cannam@95: cannam@95: MPI_Finalize(); cannam@95: } cannam@95: cannam@95: First, note that instead of calling `MPI_Init', you should call cannam@95: `MPI_Init_threads', which is the initialization routine defined by the cannam@95: MPI-2 standard to indicate to MPI that your program will be cannam@95: multithreaded. We pass `MPI_THREAD_FUNNELED', which indicates that we cannam@95: will only call MPI routines from the main thread. (FFTW will launch cannam@95: additional threads internally, but the extra threads will not call MPI cannam@95: code.) (You may also pass `MPI_THREAD_SERIALIZED' or cannam@95: `MPI_THREAD_MULTIPLE', which requests additional multithreading support cannam@95: from the MPI implementation, but this is not required by FFTW.) The cannam@95: `provided' parameter returns what level of threads support is actually cannam@95: supported by your MPI implementation; this _must_ be at least cannam@95: `MPI_THREAD_FUNNELED' if you want to call the FFTW threads routines, so cannam@95: we define a global variable `threads_ok' to record this. You should cannam@95: only call `fftw_init_threads' or `fftw_plan_with_nthreads' if cannam@95: `threads_ok' is true. For more information on thread safety in MPI, cannam@95: see the MPI and Threads cannam@95: (http://www.mpi-forum.org/docs/mpi-20-html/node162.htm) section of the cannam@95: MPI-2 standard. cannam@95: cannam@95: Second, we must call `fftw_init_threads' _before_ `fftw_mpi_init'. cannam@95: This is critical for technical reasons having to do with how FFTW cannam@95: initializes its list of algorithms. cannam@95: cannam@95: Then, if you call `fftw_plan_with_nthreads(N)', _every_ MPI process cannam@95: will launch (up to) `N' threads to parallelize its transforms. cannam@95: cannam@95: For example, in the hypothetical cluster of 4-processor nodes, you cannam@95: might wish to launch only a single MPI process per node, and then call cannam@95: `fftw_plan_with_nthreads(4)' on each process to use all processors in cannam@95: the nodes. cannam@95: cannam@95: This may or may not be faster than simply using as many MPI processes cannam@95: as you have processors, however. On the one hand, using threads within cannam@95: a node eliminates the need for explicit message passing within the cannam@95: node. On the other hand, FFTW's transpose routines are not cannam@95: multi-threaded, and this means that the communications that do take cannam@95: place will not benefit from parallelization within the node. Moreover, cannam@95: many MPI implementations already have optimizations to exploit shared cannam@95: memory when it is available, so adding the multithreaded FFTW on top of cannam@95: this may be superfluous. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW MPI Reference, Next: FFTW MPI Fortran Interface, Prev: Combining MPI and Threads, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.12 FFTW MPI Reference cannam@95: ======================= cannam@95: cannam@95: This chapter provides a complete reference to all FFTW MPI functions, cannam@95: datatypes, and constants. See also *note FFTW Reference:: for cannam@95: information on functions and types in common with the serial interface. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * MPI Files and Data Types:: cannam@95: * MPI Initialization:: cannam@95: * Using MPI Plans:: cannam@95: * MPI Data Distribution Functions:: cannam@95: * MPI Plan Creation:: cannam@95: * MPI Wisdom Communication:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: MPI Files and Data Types, Next: MPI Initialization, Prev: FFTW MPI Reference, Up: FFTW MPI Reference cannam@95: cannam@95: 6.12.1 MPI Files and Data Types cannam@95: ------------------------------- cannam@95: cannam@95: All programs using FFTW's MPI support should include its header file: cannam@95: cannam@95: #include cannam@95: cannam@95: Note that this header file includes the serial-FFTW `fftw3.h' header cannam@95: file, and also the `mpi.h' header file for MPI, so you need not include cannam@95: those files separately. cannam@95: cannam@95: You must also link to _both_ the FFTW MPI library and to the serial cannam@95: FFTW library. On Unix, this means adding `-lfftw3_mpi -lfftw3 -lm' at cannam@95: the end of the link command. cannam@95: cannam@95: Different precisions are handled as in the serial interface: *Note cannam@95: Precision::. That is, `fftw_' functions become `fftwf_' (in single cannam@95: precision) etcetera, and the libraries become `-lfftw3f_mpi -lfftw3f cannam@95: -lm' etcetera on Unix. Long-double precision is supported in MPI, but cannam@95: quad precision (`fftwq_') is not due to the lack of MPI support for cannam@95: this type. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: MPI Initialization, Next: Using MPI Plans, Prev: MPI Files and Data Types, Up: FFTW MPI Reference cannam@95: cannam@95: 6.12.2 MPI Initialization cannam@95: ------------------------- cannam@95: cannam@95: Before calling any other FFTW MPI (`fftw_mpi_') function, and before cannam@95: importing any wisdom for MPI problems, you must call: cannam@95: cannam@95: void fftw_mpi_init(void); cannam@95: cannam@95: If FFTW threads support is used, however, `fftw_mpi_init' should be cannam@95: called _after_ `fftw_init_threads' (*note Combining MPI and Threads::). cannam@95: Calling `fftw_mpi_init' additional times (before `fftw_mpi_cleanup') cannam@95: has no effect. cannam@95: cannam@95: If you want to deallocate all persistent data and reset FFTW to the cannam@95: pristine state it was in when you started your program, you can call: cannam@95: cannam@95: void fftw_mpi_cleanup(void); cannam@95: cannam@95: (This calls `fftw_cleanup', so you need not call the serial cleanup cannam@95: routine too, although it is safe to do so.) After calling cannam@95: `fftw_mpi_cleanup', all existing plans become undefined, and you should cannam@95: not attempt to execute or destroy them. You must call `fftw_mpi_init' cannam@95: again after `fftw_mpi_cleanup' if you want to resume using the MPI FFTW cannam@95: routines. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Using MPI Plans, Next: MPI Data Distribution Functions, Prev: MPI Initialization, Up: FFTW MPI Reference cannam@95: cannam@95: 6.12.3 Using MPI Plans cannam@95: ---------------------- cannam@95: cannam@95: Once an MPI plan is created, you can execute and destroy it using cannam@95: `fftw_execute', `fftw_destroy_plan', and the other functions in the cannam@95: serial interface that operate on generic plans (*note Using Plans::). cannam@95: cannam@95: The `fftw_execute' and `fftw_destroy_plan' functions, applied to MPI cannam@95: plans, are _collective_ calls: they must be called for all processes in cannam@95: the communicator that was used to create the plan. cannam@95: cannam@95: You must _not_ use the serial new-array plan-execution functions cannam@95: `fftw_execute_dft' and so on (*note New-array Execute Functions::) with cannam@95: MPI plans. Such functions are specialized to the problem type, and cannam@95: there are specific new-array execute functions for MPI plans: cannam@95: cannam@95: void fftw_mpi_execute_dft(fftw_plan p, fftw_complex *in, fftw_complex *out); cannam@95: void fftw_mpi_execute_dft_r2c(fftw_plan p, double *in, fftw_complex *out); cannam@95: void fftw_mpi_execute_dft_c2r(fftw_plan p, fftw_complex *in, double *out); cannam@95: void fftw_mpi_execute_r2r(fftw_plan p, double *in, double *out); cannam@95: cannam@95: These functions have the same restrictions as those of the serial cannam@95: new-array execute functions. They are _always_ safe to apply to the cannam@95: _same_ `in' and `out' arrays that were used to create the plan. They cannam@95: can only be applied to new arrarys if those arrays have the same types, cannam@95: dimensions, in-placeness, and alignment as the original arrays, where cannam@95: the best way to ensure the same alignment is to use FFTW's cannam@95: `fftw_malloc' and related allocation functions for all arrays (*note cannam@95: Memory Allocation::). Note that distributed transposes (*note FFTW MPI cannam@95: Transposes::) use `fftw_mpi_execute_r2r', since they count as rank-zero cannam@95: r2r plans from FFTW's perspective. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: MPI Data Distribution Functions, Next: MPI Plan Creation, Prev: Using MPI Plans, Up: FFTW MPI Reference cannam@95: cannam@95: 6.12.4 MPI Data Distribution Functions cannam@95: -------------------------------------- cannam@95: cannam@95: As described above (*note MPI Data Distribution::), in order to cannam@95: allocate your arrays, _before_ creating a plan, you must first call one cannam@95: of the following routines to determine the required allocation size and cannam@95: the portion of the array locally stored on a given process. The cannam@95: `MPI_Comm' communicator passed here must be equivalent to the cannam@95: communicator used below for plan creation. cannam@95: cannam@95: The basic interface for multidimensional transforms consists of the cannam@95: functions: cannam@95: cannam@95: ptrdiff_t fftw_mpi_local_size_2d(ptrdiff_t n0, ptrdiff_t n1, MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start); cannam@95: ptrdiff_t fftw_mpi_local_size_3d(ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t n2, cannam@95: MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start); cannam@95: ptrdiff_t fftw_mpi_local_size(int rnk, const ptrdiff_t *n, MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start); cannam@95: cannam@95: ptrdiff_t fftw_mpi_local_size_2d_transposed(ptrdiff_t n0, ptrdiff_t n1, MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start, cannam@95: ptrdiff_t *local_n1, ptrdiff_t *local_1_start); cannam@95: ptrdiff_t fftw_mpi_local_size_3d_transposed(ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t n2, cannam@95: MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start, cannam@95: ptrdiff_t *local_n1, ptrdiff_t *local_1_start); cannam@95: ptrdiff_t fftw_mpi_local_size_transposed(int rnk, const ptrdiff_t *n, MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start, cannam@95: ptrdiff_t *local_n1, ptrdiff_t *local_1_start); cannam@95: cannam@95: These functions return the number of elements to allocate (complex cannam@95: numbers for DFT/r2c/c2r plans, real numbers for r2r plans), whereas the cannam@95: `local_n0' and `local_0_start' return the portion (`local_0_start' to cannam@95: `local_0_start + local_n0 - 1') of the first dimension of an n[0] x cannam@95: n[1] x n[2] x ... x n[d-1] array that is stored on the local process. cannam@95: *Note Basic and advanced distribution interfaces::. For cannam@95: `FFTW_MPI_TRANSPOSED_OUT' plans, the `_transposed' variants are useful cannam@95: in order to also return the local portion of the first dimension in the cannam@95: n[1] x n[0] x n[2] x ... x n[d-1] transposed output. *Note Transposed cannam@95: distributions::. The advanced interface for multidimensional cannam@95: transforms is: cannam@95: cannam@95: ptrdiff_t fftw_mpi_local_size_many(int rnk, const ptrdiff_t *n, ptrdiff_t howmany, cannam@95: ptrdiff_t block0, MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start); cannam@95: ptrdiff_t fftw_mpi_local_size_many_transposed(int rnk, const ptrdiff_t *n, ptrdiff_t howmany, cannam@95: ptrdiff_t block0, ptrdiff_t block1, MPI_Comm comm, cannam@95: ptrdiff_t *local_n0, ptrdiff_t *local_0_start, cannam@95: ptrdiff_t *local_n1, ptrdiff_t *local_1_start); cannam@95: cannam@95: These differ from the basic interface in only two ways. First, they cannam@95: allow you to specify block sizes `block0' and `block1' (the latter for cannam@95: the transposed output); you can pass `FFTW_MPI_DEFAULT_BLOCK' to use cannam@95: FFTW's default block size as in the basic interface. Second, you can cannam@95: pass a `howmany' parameter, corresponding to the advanced planning cannam@95: interface below: this is for transforms of contiguous `howmany'-tuples cannam@95: of numbers (`howmany = 1' in the basic interface). cannam@95: cannam@95: The corresponding basic and advanced routines for one-dimensional cannam@95: transforms (currently only complex DFTs) are: cannam@95: cannam@95: ptrdiff_t fftw_mpi_local_size_1d( cannam@95: ptrdiff_t n0, MPI_Comm comm, int sign, unsigned flags, cannam@95: ptrdiff_t *local_ni, ptrdiff_t *local_i_start, cannam@95: ptrdiff_t *local_no, ptrdiff_t *local_o_start); cannam@95: ptrdiff_t fftw_mpi_local_size_many_1d( cannam@95: ptrdiff_t n0, ptrdiff_t howmany, cannam@95: MPI_Comm comm, int sign, unsigned flags, cannam@95: ptrdiff_t *local_ni, ptrdiff_t *local_i_start, cannam@95: ptrdiff_t *local_no, ptrdiff_t *local_o_start); cannam@95: cannam@95: As above, the return value is the number of elements to allocate cannam@95: (complex numbers, for complex DFTs). The `local_ni' and cannam@95: `local_i_start' arguments return the portion (`local_i_start' to cannam@95: `local_i_start + local_ni - 1') of the 1d array that is stored on this cannam@95: process for the transform _input_, and `local_no' and `local_o_start' cannam@95: are the corresponding quantities for the input. The `sign' cannam@95: (`FFTW_FORWARD' or `FFTW_BACKWARD') and `flags' must match the cannam@95: arguments passed when creating a plan. Although the inputs and outputs cannam@95: have different data distributions in general, it is guaranteed that the cannam@95: _output_ data distribution of an `FFTW_FORWARD' plan will match the cannam@95: _input_ data distribution of an `FFTW_BACKWARD' plan and vice versa; cannam@95: similarly for the `FFTW_MPI_SCRAMBLED_OUT' and `FFTW_MPI_SCRAMBLED_IN' cannam@95: flags. *Note One-dimensional distributions::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: MPI Plan Creation, Next: MPI Wisdom Communication, Prev: MPI Data Distribution Functions, Up: FFTW MPI Reference cannam@95: cannam@95: 6.12.5 MPI Plan Creation cannam@95: ------------------------ cannam@95: cannam@95: Complex-data MPI DFTs cannam@95: ..................... cannam@95: cannam@95: Plans for complex-data DFTs (*note 2d MPI example::) are created by: cannam@95: cannam@95: fftw_plan fftw_mpi_plan_dft_1d(ptrdiff_t n0, fftw_complex *in, fftw_complex *out, cannam@95: MPI_Comm comm, int sign, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft_2d(ptrdiff_t n0, ptrdiff_t n1, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: MPI_Comm comm, int sign, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft_3d(ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t n2, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: MPI_Comm comm, int sign, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft(int rnk, const ptrdiff_t *n, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: MPI_Comm comm, int sign, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_many_dft(int rnk, const ptrdiff_t *n, cannam@95: ptrdiff_t howmany, ptrdiff_t block, ptrdiff_t tblock, cannam@95: fftw_complex *in, fftw_complex *out, cannam@95: MPI_Comm comm, int sign, unsigned flags); cannam@95: cannam@95: These are similar to their serial counterparts (*note Complex DFTs::) cannam@95: in specifying the dimensions, sign, and flags of the transform. The cannam@95: `comm' argument gives an MPI communicator that specifies the set of cannam@95: processes to participate in the transform; plan creation is a cannam@95: collective function that must be called for all processes in the cannam@95: communicator. The `in' and `out' pointers refer only to a portion of cannam@95: the overall transform data (*note MPI Data Distribution::) as specified cannam@95: by the `local_size' functions in the previous section. Unless `flags' cannam@95: contains `FFTW_ESTIMATE', these arrays are overwritten during plan cannam@95: creation as for the serial interface. For multi-dimensional cannam@95: transforms, any dimensions `> 1' are supported; for one-dimensional cannam@95: transforms, only composite (non-prime) `n0' are currently supported cannam@95: (unlike the serial FFTW). Requesting an unsupported transform size cannam@95: will yield a `NULL' plan. (As in the serial interface, highly cannam@95: composite sizes generally yield the best performance.) cannam@95: cannam@95: The advanced-interface `fftw_mpi_plan_many_dft' additionally allows cannam@95: you to specify the block sizes for the first dimension (`block') of the cannam@95: n[0] x n[1] x n[2] x ... x n[d-1] input data and the first dimension cannam@95: (`tblock') of the n[1] x n[0] x n[2] x ... x n[d-1] transposed data cannam@95: (at intermediate steps of the transform, and for the output if cannam@95: `FFTW_TRANSPOSED_OUT' is specified in `flags'). These must be the same cannam@95: block sizes as were passed to the corresponding `local_size' function; cannam@95: you can pass `FFTW_MPI_DEFAULT_BLOCK' to use FFTW's default block size cannam@95: as in the basic interface. Also, the `howmany' parameter specifies cannam@95: that the transform is of contiguous `howmany'-tuples rather than cannam@95: individual complex numbers; this corresponds to the same parameter in cannam@95: the serial advanced interface (*note Advanced Complex DFTs::) with cannam@95: `stride = howmany' and `dist = 1'. cannam@95: cannam@95: MPI flags cannam@95: ......... cannam@95: cannam@95: The `flags' can be any of those for the serial FFTW (*note Planner cannam@95: Flags::), and in addition may include one or more of the following cannam@95: MPI-specific flags, which improve performance at the cost of changing cannam@95: the output or input data formats. cannam@95: cannam@95: * `FFTW_MPI_SCRAMBLED_OUT', `FFTW_MPI_SCRAMBLED_IN': valid for 1d cannam@95: transforms only, these flags indicate that the output/input of the cannam@95: transform are in an undocumented "scrambled" order. A forward cannam@95: `FFTW_MPI_SCRAMBLED_OUT' transform can be inverted by a backward cannam@95: `FFTW_MPI_SCRAMBLED_IN' (times the usual 1/N normalization). cannam@95: *Note One-dimensional distributions::. cannam@95: cannam@95: * `FFTW_MPI_TRANSPOSED_OUT', `FFTW_MPI_TRANSPOSED_IN': valid for cannam@95: multidimensional (`rnk > 1') transforms only, these flags specify cannam@95: that the output or input of an n[0] x n[1] x n[2] x ... x n[d-1] cannam@95: transform is transposed to n[1] x n[0] x n[2] x ... x n[d-1] . cannam@95: *Note Transposed distributions::. cannam@95: cannam@95: cannam@95: Real-data MPI DFTs cannam@95: .................. cannam@95: cannam@95: Plans for real-input/output (r2c/c2r) DFTs (*note Multi-dimensional MPI cannam@95: DFTs of Real Data::) are created by: cannam@95: cannam@95: fftw_plan fftw_mpi_plan_dft_r2c_2d(ptrdiff_t n0, ptrdiff_t n1, cannam@95: double *in, fftw_complex *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft_r2c_2d(ptrdiff_t n0, ptrdiff_t n1, cannam@95: double *in, fftw_complex *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft_r2c_3d(ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t n2, cannam@95: double *in, fftw_complex *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft_r2c(int rnk, const ptrdiff_t *n, cannam@95: double *in, fftw_complex *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft_c2r_2d(ptrdiff_t n0, ptrdiff_t n1, cannam@95: fftw_complex *in, double *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft_c2r_2d(ptrdiff_t n0, ptrdiff_t n1, cannam@95: fftw_complex *in, double *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft_c2r_3d(ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t n2, cannam@95: fftw_complex *in, double *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_dft_c2r(int rnk, const ptrdiff_t *n, cannam@95: fftw_complex *in, double *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: cannam@95: Similar to the serial interface (*note Real-data DFTs::), these cannam@95: transform logically n[0] x n[1] x n[2] x ... x n[d-1] real data cannam@95: to/from n[0] x n[1] x n[2] x ... x (n[d-1]/2 + 1) complex data, cannam@95: representing the non-redundant half of the conjugate-symmetry output of cannam@95: a real-input DFT (*note Multi-dimensional Transforms::). However, the cannam@95: real array must be stored within a padded n[0] x n[1] x n[2] x ... x [2 cannam@95: (n[d-1]/2 + 1)] cannam@95: cannam@95: array (much like the in-place serial r2c transforms, but here for cannam@95: out-of-place transforms as well). Currently, only multi-dimensional cannam@95: (`rnk > 1') r2c/c2r transforms are supported (requesting a plan for cannam@95: `rnk = 1' will yield `NULL'). As explained above (*note cannam@95: Multi-dimensional MPI DFTs of Real Data::), the data distribution of cannam@95: both the real and complex arrays is given by the `local_size' function cannam@95: called for the dimensions of the _complex_ array. Similar to the other cannam@95: planning functions, the input and output arrays are overwritten when cannam@95: the plan is created except in `FFTW_ESTIMATE' mode. cannam@95: cannam@95: As for the complex DFTs above, there is an advance interface that cannam@95: allows you to manually specify block sizes and to transform contiguous cannam@95: `howmany'-tuples of real/complex numbers: cannam@95: cannam@95: fftw_plan fftw_mpi_plan_many_dft_r2c cannam@95: (int rnk, const ptrdiff_t *n, ptrdiff_t howmany, cannam@95: ptrdiff_t iblock, ptrdiff_t oblock, cannam@95: double *in, fftw_complex *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_many_dft_c2r cannam@95: (int rnk, const ptrdiff_t *n, ptrdiff_t howmany, cannam@95: ptrdiff_t iblock, ptrdiff_t oblock, cannam@95: fftw_complex *in, double *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: cannam@95: MPI r2r transforms cannam@95: .................. cannam@95: cannam@95: There are corresponding plan-creation routines for r2r transforms cannam@95: (*note More DFTs of Real Data::), currently supporting multidimensional cannam@95: (`rnk > 1') transforms only (`rnk = 1' will yield a `NULL' plan): cannam@95: cannam@95: fftw_plan fftw_mpi_plan_r2r_2d(ptrdiff_t n0, ptrdiff_t n1, cannam@95: double *in, double *out, cannam@95: MPI_Comm comm, cannam@95: fftw_r2r_kind kind0, fftw_r2r_kind kind1, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_r2r_3d(ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t n2, cannam@95: double *in, double *out, cannam@95: MPI_Comm comm, cannam@95: fftw_r2r_kind kind0, fftw_r2r_kind kind1, fftw_r2r_kind kind2, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_r2r(int rnk, const ptrdiff_t *n, cannam@95: double *in, double *out, cannam@95: MPI_Comm comm, const fftw_r2r_kind *kind, cannam@95: unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_many_r2r(int rnk, const ptrdiff_t *n, cannam@95: ptrdiff_t iblock, ptrdiff_t oblock, cannam@95: double *in, double *out, cannam@95: MPI_Comm comm, const fftw_r2r_kind *kind, cannam@95: unsigned flags); cannam@95: cannam@95: The parameters are much the same as for the complex DFTs above, cannam@95: except that the arrays are of real numbers (and hence the outputs of the cannam@95: `local_size' data-distribution functions should be interpreted as cannam@95: counts of real rather than complex numbers). Also, the `kind' cannam@95: parameters specify the r2r kinds along each dimension as for the serial cannam@95: interface (*note Real-to-Real Transform Kinds::). *Note Other cannam@95: Multi-dimensional Real-data MPI Transforms::. cannam@95: cannam@95: MPI transposition cannam@95: ................. cannam@95: cannam@95: FFTW also provides routines to plan a transpose of a distributed `n0' cannam@95: by `n1' array of real numbers, or an array of `howmany'-tuples of real cannam@95: numbers with specified block sizes (*note FFTW MPI Transposes::): cannam@95: cannam@95: fftw_plan fftw_mpi_plan_transpose(ptrdiff_t n0, ptrdiff_t n1, cannam@95: double *in, double *out, cannam@95: MPI_Comm comm, unsigned flags); cannam@95: fftw_plan fftw_mpi_plan_many_transpose cannam@95: (ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t howmany, cannam@95: ptrdiff_t block0, ptrdiff_t block1, cannam@95: double *in, double *out, MPI_Comm comm, unsigned flags); cannam@95: cannam@95: These plans are used with the `fftw_mpi_execute_r2r' new-array cannam@95: execute function (*note Using MPI Plans::), since they count as (rank cannam@95: zero) r2r plans from FFTW's perspective. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: MPI Wisdom Communication, Prev: MPI Plan Creation, Up: FFTW MPI Reference cannam@95: cannam@95: 6.12.6 MPI Wisdom Communication cannam@95: ------------------------------- cannam@95: cannam@95: To facilitate synchronizing wisdom among the different MPI processes, cannam@95: we provide two functions: cannam@95: cannam@95: void fftw_mpi_gather_wisdom(MPI_Comm comm); cannam@95: void fftw_mpi_broadcast_wisdom(MPI_Comm comm); cannam@95: cannam@95: The `fftw_mpi_gather_wisdom' function gathers all wisdom in the cannam@95: given communicator `comm' to the process of rank 0 in the communicator: cannam@95: that process obtains the union of all wisdom on all the processes. As cannam@95: a side effect, some other processes will gain additional wisdom from cannam@95: other processes, but only process 0 will gain the complete union. cannam@95: cannam@95: The `fftw_mpi_broadcast_wisdom' does the reverse: it exports wisdom cannam@95: from process 0 in `comm' to all other processes in the communicator, cannam@95: replacing any wisdom they currently have. cannam@95: cannam@95: *Note FFTW MPI Wisdom::. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW MPI Fortran Interface, Prev: FFTW MPI Reference, Up: Distributed-memory FFTW with MPI cannam@95: cannam@95: 6.13 FFTW MPI Fortran Interface cannam@95: =============================== cannam@95: cannam@95: The FFTW MPI interface is callable from modern Fortran compilers cannam@95: supporting the Fortran 2003 `iso_c_binding' standard for calling C cannam@95: functions. As described in *note Calling FFTW from Modern Fortran::, cannam@95: this means that you can directly call FFTW's C interface from Fortran cannam@95: with only minor changes in syntax. There are, however, a few things cannam@95: specific to the MPI interface to keep in mind: cannam@95: cannam@95: * Instead of including `fftw3.f03' as in *note Overview of Fortran cannam@95: interface::, you should `include 'fftw3-mpi.f03'' (after `use, cannam@95: intrinsic :: iso_c_binding' as before). The `fftw3-mpi.f03' file cannam@95: includes `fftw3.f03', so you should _not_ `include' them both cannam@95: yourself. (You will also want to include the MPI header file, cannam@95: usually via `include 'mpif.h'' or similar, although though this is cannam@95: not needed by `fftw3-mpi.f03' per se.) (To use the `fftwl_' `long cannam@95: double' extended-precision routines in supporting compilers, you cannam@95: should include `fftw3f-mpi.f03' in _addition_ to `fftw3-mpi.f03'. cannam@95: *Note Extended and quadruple precision in Fortran::.) cannam@95: cannam@95: * Because of the different storage conventions between C and Fortran, cannam@95: you reverse the order of your array dimensions when passing them to cannam@95: FFTW (*note Reversing array dimensions::). This is merely a cannam@95: difference in notation and incurs no performance overhead. cannam@95: However, it means that, whereas in C the _first_ dimension is cannam@95: distributed, in Fortran the _last_ dimension of your array is cannam@95: distributed. cannam@95: cannam@95: * In Fortran, communicators are stored as `integer' types; there is cannam@95: no `MPI_Comm' type, nor is there any way to access a C `MPI_Comm'. cannam@95: Fortunately, this is taken care of for you by the FFTW Fortran cannam@95: interface: whenever the C interface expects an `MPI_Comm' type, cannam@95: you should pass the Fortran communicator as an `integer'.(1) cannam@95: cannam@95: * Because you need to call the `local_size' function to find out how cannam@95: much space to allocate, and this may be _larger_ than the local cannam@95: portion of the array (*note MPI Data Distribution::), you should cannam@95: _always_ allocate your arrays dynamically using FFTW's allocation cannam@95: routines as described in *note Allocating aligned memory in cannam@95: Fortran::. (Coincidentally, this also provides the best cannam@95: performance by guaranteeding proper data alignment.) cannam@95: cannam@95: * Because all sizes in the MPI FFTW interface are declared as cannam@95: `ptrdiff_t' in C, you should use `integer(C_INTPTR_T)' in Fortran cannam@95: (*note FFTW Fortran type reference::). cannam@95: cannam@95: * In Fortran, because of the language semantics, we generally cannam@95: recommend using the new-array execute functions for all plans, cannam@95: even in the common case where you are executing the plan on the cannam@95: same arrays for which the plan was created (*note Plan execution cannam@95: in Fortran::). However, note that in the MPI interface these cannam@95: functions are changed: `fftw_execute_dft' becomes cannam@95: `fftw_mpi_execute_dft', etcetera. *Note Using MPI Plans::. cannam@95: cannam@95: cannam@95: For example, here is a Fortran code snippet to perform a distributed cannam@95: L x M complex DFT in-place. (This assumes you have already cannam@95: initialized MPI with `MPI_init' and have also performed `call cannam@95: fftw_mpi_init'.) cannam@95: cannam@95: use, intrinsic :: iso_c_binding cannam@95: include 'fftw3-mpi.f03' cannam@95: integer(C_INTPTR_T), parameter :: L = ... cannam@95: integer(C_INTPTR_T), parameter :: M = ... cannam@95: type(C_PTR) :: plan, cdata cannam@95: complex(C_DOUBLE_COMPLEX), pointer :: data(:,:) cannam@95: integer(C_INTPTR_T) :: i, j, alloc_local, local_M, local_j_offset cannam@95: cannam@95: ! get local data size and allocate (note dimension reversal) cannam@95: alloc_local = fftw_mpi_local_size_2d(M, L, MPI_COMM_WORLD, & cannam@95: local_M, local_j_offset) cannam@95: cdata = fftw_alloc_complex(alloc_local) cannam@95: call c_f_pointer(cdata, data, [L,local_M]) cannam@95: cannam@95: ! create MPI plan for in-place forward DFT (note dimension reversal) cannam@95: plan = fftw_mpi_plan_dft_2d(M, L, data, data, MPI_COMM_WORLD, & cannam@95: FFTW_FORWARD, FFTW_MEASURE) cannam@95: cannam@95: ! initialize data to some function my_function(i,j) cannam@95: do j = 1, local_M cannam@95: do i = 1, L cannam@95: data(i, j) = my_function(i, j + local_j_offset) cannam@95: end do cannam@95: end do cannam@95: cannam@95: ! compute transform (as many times as desired) cannam@95: call fftw_mpi_execute_dft(plan, data, data) cannam@95: cannam@95: call fftw_destroy_plan(plan) cannam@95: call fftw_free(cdata) cannam@95: cannam@95: Note that when we called `fftw_mpi_local_size_2d' and cannam@95: `fftw_mpi_plan_dft_2d' with the dimensions in reversed order, since a L cannam@95: x M Fortran array is viewed by FFTW in C as a M x L array. This cannam@95: means that the array was distributed over the `M' dimension, the local cannam@95: portion of which is a L x local_M array in Fortran. (You must _not_ cannam@95: use an `allocate' statement to allocate an L x local_M array, however; cannam@95: you must allocate `alloc_local' complex numbers, which may be greater cannam@95: than `L * local_M', in order to reserve space for intermediate steps of cannam@95: the transform.) Finally, we mention that because C's array indices are cannam@95: zero-based, the `local_j_offset' argument can conveniently be cannam@95: interpreted as an offset in the 1-based `j' index (rather than as a cannam@95: starting index as in C). cannam@95: cannam@95: If instead you had used the `ior(FFTW_MEASURE, cannam@95: FFTW_MPI_TRANSPOSED_OUT)' flag, the output of the transform would be a cannam@95: transposed M x local_L array, associated with the _same_ `cdata' cannam@95: allocation (since the transform is in-place), and which you could cannam@95: declare with: cannam@95: cannam@95: complex(C_DOUBLE_COMPLEX), pointer :: tdata(:,:) cannam@95: ... cannam@95: call c_f_pointer(cdata, tdata, [M,local_L]) cannam@95: cannam@95: where `local_L' would have been obtained by changing the cannam@95: `fftw_mpi_local_size_2d' call to: cannam@95: cannam@95: alloc_local = fftw_mpi_local_size_2d_transposed(M, L, MPI_COMM_WORLD, & cannam@95: local_M, local_j_offset, local_L, local_i_offset) cannam@95: cannam@95: ---------- Footnotes ---------- cannam@95: cannam@95: (1) Technically, this is because you aren't actually calling the C cannam@95: functions directly. You are calling wrapper functions that translate cannam@95: the communicator with `MPI_Comm_f2c' before calling the ordinary C cannam@95: interface. This is all done transparently, however, since the cannam@95: `fftw3-mpi.f03' interface file renames the wrappers so that they are cannam@95: called in Fortran with the same names as the C interface functions. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Calling FFTW from Modern Fortran, Next: Calling FFTW from Legacy Fortran, Prev: Distributed-memory FFTW with MPI, Up: Top cannam@95: cannam@95: 7 Calling FFTW from Modern Fortran cannam@95: ********************************** cannam@95: cannam@95: Fortran 2003 standardized ways for Fortran code to call C libraries, cannam@95: and this allows us to support a direct translation of the FFTW C API cannam@95: into Fortran. Compared to the legacy Fortran 77 interface (*note cannam@95: Calling FFTW from Legacy Fortran::), this direct interface offers many cannam@95: advantages, especially compile-time type-checking and aligned memory cannam@95: allocation. As of this writing, support for these C interoperability cannam@95: features seems widespread, having been implemented in nearly all major cannam@95: Fortran compilers (e.g. GNU, Intel, IBM, Oracle/Solaris, Portland cannam@95: Group, NAG). cannam@95: cannam@95: This chapter documents that interface. For the most part, since this cannam@95: interface allows Fortran to call the C interface directly, the usage is cannam@95: identical to C translated to Fortran syntax. However, there are a few cannam@95: subtle points such as memory allocation, wisdom, and data types that cannam@95: deserve closer attention. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Overview of Fortran interface:: cannam@95: * Reversing array dimensions:: cannam@95: * FFTW Fortran type reference:: cannam@95: * Plan execution in Fortran:: cannam@95: * Allocating aligned memory in Fortran:: cannam@95: * Accessing the wisdom API from Fortran:: cannam@95: * Defining an FFTW module:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Overview of Fortran interface, Next: Reversing array dimensions, Prev: Calling FFTW from Modern Fortran, Up: Calling FFTW from Modern Fortran cannam@95: cannam@95: 7.1 Overview of Fortran interface cannam@95: ================================= cannam@95: cannam@95: FFTW provides a file `fftw3.f03' that defines Fortran 2003 interfaces cannam@95: for all of its C routines, except for the MPI routines described cannam@95: elsewhere, which can be found in the same directory as `fftw3.h' (the C cannam@95: header file). In any Fortran subroutine where you want to use FFTW cannam@95: functions, you should begin with: cannam@95: cannam@95: use, intrinsic :: iso_c_binding cannam@95: include 'fftw3.f03' cannam@95: cannam@95: This includes the interface definitions and the standard cannam@95: `iso_c_binding' module (which defines the equivalents of C types). You cannam@95: can also put the FFTW functions into a module if you prefer (*note cannam@95: Defining an FFTW module::). cannam@95: cannam@95: At this point, you can now call anything in the FFTW C interface cannam@95: directly, almost exactly as in C other than minor changes in syntax. cannam@95: For example: cannam@95: cannam@95: type(C_PTR) :: plan cannam@95: complex(C_DOUBLE_COMPLEX), dimension(1024,1000) :: in, out cannam@95: plan = fftw_plan_dft_2d(1000,1024, in,out, FFTW_FORWARD,FFTW_ESTIMATE) cannam@95: ... cannam@95: call fftw_execute_dft(plan, in, out) cannam@95: ... cannam@95: call fftw_destroy_plan(plan) cannam@95: cannam@95: A few important things to keep in mind are: cannam@95: cannam@95: * FFTW plans are `type(C_PTR)'. Other C types are mapped in the cannam@95: obvious way via the `iso_c_binding' standard: `int' turns into cannam@95: `integer(C_INT)', `fftw_complex' turns into cannam@95: `complex(C_DOUBLE_COMPLEX)', `double' turns into `real(C_DOUBLE)', cannam@95: and so on. *Note FFTW Fortran type reference::. cannam@95: cannam@95: * Functions in C become functions in Fortran if they have a return cannam@95: value, and subroutines in Fortran otherwise. cannam@95: cannam@95: * The ordering of the Fortran array dimensions must be _reversed_ cannam@95: when they are passed to the FFTW plan creation, thanks to cannam@95: differences in array indexing conventions (*note Multi-dimensional cannam@95: Array Format::). This is _unlike_ the legacy Fortran interface cannam@95: (*note Fortran-interface routines::), which reversed the dimensions cannam@95: for you. *Note Reversing array dimensions::. cannam@95: cannam@95: * Using ordinary Fortran array declarations like this works, but may cannam@95: yield suboptimal performance because the data may not be not cannam@95: aligned to exploit SIMD instructions on modern proessors (*note cannam@95: SIMD alignment and fftw_malloc::). Better performance will often cannam@95: be obtained by allocating with `fftw_alloc'. *Note Allocating cannam@95: aligned memory in Fortran::. cannam@95: cannam@95: * Similar to the legacy Fortran interface (*note FFTW Execution in cannam@95: Fortran::), we currently recommend _not_ using `fftw_execute' but cannam@95: rather using the more specialized functions like cannam@95: `fftw_execute_dft' (*note New-array Execute Functions::). cannam@95: However, you should execute the plan on the `same arrays' as the cannam@95: ones for which you created the plan, unless you are especially cannam@95: careful. *Note Plan execution in Fortran::. To prevent you from cannam@95: using `fftw_execute' by mistake, the `fftw3.f03' file does not cannam@95: provide an `fftw_execute' interface declaration. cannam@95: cannam@95: * Multiple planner flags are combined with `ior' (equivalent to `|' cannam@95: in C). e.g. `FFTW_MEASURE | FFTW_DESTROY_INPUT' becomes cannam@95: `ior(FFTW_MEASURE, FFTW_DESTROY_INPUT)'. (You can also use `+' as cannam@95: long as you don't try to include a given flag more than once.) cannam@95: cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Extended and quadruple precision in Fortran:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Extended and quadruple precision in Fortran, Prev: Overview of Fortran interface, Up: Overview of Fortran interface cannam@95: cannam@95: 7.1.1 Extended and quadruple precision in Fortran cannam@95: ------------------------------------------------- cannam@95: cannam@95: If FFTW is compiled in `long double' (extended) precision (*note cannam@95: Installation and Customization::), you may be able to call the cannam@95: resulting `fftwl_' routines (*note Precision::) from Fortran if your cannam@95: compiler supports the `C_LONG_DOUBLE_COMPLEX' type code. cannam@95: cannam@95: Because some Fortran compilers do not support cannam@95: `C_LONG_DOUBLE_COMPLEX', the `fftwl_' declarations are segregated into cannam@95: a separate interface file `fftw3l.f03', which you should include _in cannam@95: addition_ to `fftw3.f03' (which declares precision-independent `FFTW_' cannam@95: constants): cannam@95: cannam@95: use, intrinsic :: iso_c_binding cannam@95: include 'fftw3.f03' cannam@95: include 'fftw3l.f03' cannam@95: cannam@95: We also support using the nonstandard `__float128' cannam@95: quadruple-precision type provided by recent versions of `gcc' on 32- cannam@95: and 64-bit x86 hardware (*note Installation and Customization::), using cannam@95: the corresponding `real(16)' and `complex(16)' types supported by cannam@95: `gfortran'. The quadruple-precision `fftwq_' functions (*note cannam@95: Precision::) are declared in a `fftw3q.f03' interface file, which cannam@95: should be included in addition to `fftw3l.f03', as above. You should cannam@95: also link with `-lfftw3q -lquadmath -lm' as in C. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Reversing array dimensions, Next: FFTW Fortran type reference, Prev: Overview of Fortran interface, Up: Calling FFTW from Modern Fortran cannam@95: cannam@95: 7.2 Reversing array dimensions cannam@95: ============================== cannam@95: cannam@95: A minor annoyance in calling FFTW from Fortran is that FFTW's array cannam@95: dimensions are defined in the C convention (row-major order), while cannam@95: Fortran's array dimensions are the opposite convention (column-major cannam@95: order). *Note Multi-dimensional Array Format::. This is just a cannam@95: bookkeeping difference, with no effect on performance. The only cannam@95: consequence of this is that, whenever you create an FFTW plan for a cannam@95: multi-dimensional transform, you must always _reverse the ordering of cannam@95: the dimensions_. cannam@95: cannam@95: For example, consider the three-dimensional (L x M x N ) arrays: cannam@95: cannam@95: complex(C_DOUBLE_COMPLEX), dimension(L,M,N) :: in, out cannam@95: cannam@95: To plan a DFT for these arrays using `fftw_plan_dft_3d', you could cannam@95: do: cannam@95: cannam@95: plan = fftw_plan_dft_3d(N,M,L, in,out, FFTW_FORWARD,FFTW_ESTIMATE) cannam@95: cannam@95: That is, from FFTW's perspective this is a N x M x L array. _No cannam@95: data transposition need occur_, as this is _only notation_. Similarly, cannam@95: to use the more generic routine `fftw_plan_dft' with the same arrays, cannam@95: you could do: cannam@95: cannam@95: integer(C_INT), dimension(3) :: n = [N,M,L] cannam@95: plan = fftw_plan_dft_3d(3, n, in,out, FFTW_FORWARD,FFTW_ESTIMATE) cannam@95: cannam@95: Note, by the way, that this is different from the legacy Fortran cannam@95: interface (*note Fortran-interface routines::), which automatically cannam@95: reverses the order of the array dimension for you. Here, you are cannam@95: calling the C interface directly, so there is no "translation" layer. cannam@95: cannam@95: An important thing to keep in mind is the implication of this for cannam@95: multidimensional real-to-complex transforms (*note Multi-Dimensional cannam@95: DFTs of Real Data::). In C, a multidimensional real-to-complex DFT cannam@95: chops the last dimension roughly in half (N x M x L real input goes to cannam@95: N x M x L/2+1 complex output). In Fortran, because the array cannam@95: dimension notation is reversed, the _first_ dimension of the complex cannam@95: data is chopped roughly in half. For example consider the `r2c' cannam@95: transform of L x M x N real input in Fortran: cannam@95: cannam@95: type(C_PTR) :: plan cannam@95: real(C_DOUBLE), dimension(L,M,N) :: in cannam@95: complex(C_DOUBLE_COMPLEX), dimension(L/2+1,M,N) :: out cannam@95: plan = fftw_plan_dft_r2c_3d(N,M,L, in,out, FFTW_ESTIMATE) cannam@95: ... cannam@95: call fftw_execute_dft_r2c(plan, in, out) cannam@95: cannam@95: Alternatively, for an in-place r2c transform, as described in the C cannam@95: documentation we must _pad_ the _first_ dimension of the real input cannam@95: with an extra two entries (which are ignored by FFTW) so as to leave cannam@95: enough space for the complex output. The input is _allocated_ as a cannam@95: 2[L/2+1] x M x N array, even though only L x M x N of it is actually cannam@95: used. In this example, we will allocate the array as a pointer type, cannam@95: using `fftw_alloc' to ensure aligned memory for maximum performance cannam@95: (*note Allocating aligned memory in Fortran::); this also makes it easy cannam@95: to reference the same memory as both a real array and a complex array. cannam@95: cannam@95: real(C_DOUBLE), pointer :: in(:,:,:) cannam@95: complex(C_DOUBLE_COMPLEX), pointer :: out(:,:,:) cannam@95: type(C_PTR) :: plan, data cannam@95: data = fftw_alloc_complex(int((L/2+1) * M * N, C_SIZE_T)) cannam@95: call c_f_pointer(data, in, [2*(L/2+1),M,N]) cannam@95: call c_f_pointer(data, out, [L/2+1,M,N]) cannam@95: plan = fftw_plan_dft_r2c_3d(N,M,L, in,out, FFTW_ESTIMATE) cannam@95: ... cannam@95: call fftw_execute_dft_r2c(plan, in, out) cannam@95: ... cannam@95: call fftw_destroy_plan(plan) cannam@95: call fftw_free(data) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW Fortran type reference, Next: Plan execution in Fortran, Prev: Reversing array dimensions, Up: Calling FFTW from Modern Fortran cannam@95: cannam@95: 7.3 FFTW Fortran type reference cannam@95: =============================== cannam@95: cannam@95: The following are the most important type correspondences between the C cannam@95: interface and Fortran: cannam@95: cannam@95: * Plans (`fftw_plan' and variants) are `type(C_PTR)' (i.e. an opaque cannam@95: pointer). cannam@95: cannam@95: * The C floating-point types `double', `float', and `long double' cannam@95: correspond to `real(C_DOUBLE)', `real(C_FLOAT)', and cannam@95: `real(C_LONG_DOUBLE)', respectively. The C complex types cannam@95: `fftw_complex', `fftwf_complex', and `fftwl_complex' correspond in cannam@95: Fortran to `complex(C_DOUBLE_COMPLEX)', cannam@95: `complex(C_FLOAT_COMPLEX)', and `complex(C_LONG_DOUBLE_COMPLEX)', cannam@95: respectively. Just as in C (*note Precision::), the FFTW cannam@95: subroutines and types are prefixed with `fftw_', `fftwf_', and cannam@95: `fftwl_' for the different precisions, and link to different cannam@95: libraries (`-lfftw3', `-lfftw3f', and `-lfftw3l' on Unix), but use cannam@95: the _same_ include file `fftw3.f03' and the _same_ constants (all cannam@95: of which begin with `FFTW_'). The exception is `long double' cannam@95: precision, for which you should _also_ include `fftw3l.f03' (*note cannam@95: Extended and quadruple precision in Fortran::). cannam@95: cannam@95: * The C integer types `int' and `unsigned' (used for planner flags) cannam@95: become `integer(C_INT)'. The C integer type `ptrdiff_t' (e.g. in cannam@95: the *note 64-bit Guru Interface::) becomes `integer(C_INTPTR_T)', cannam@95: and `size_t' (in `fftw_malloc' etc.) becomes `integer(C_SIZE_T)'. cannam@95: cannam@95: * The `fftw_r2r_kind' type (*note Real-to-Real Transform Kinds::) cannam@95: becomes `integer(C_FFTW_R2R_KIND)'. The various constant values cannam@95: of the C enumerated type (`FFTW_R2HC' etc.) become simply integer cannam@95: constants of the same names in Fortran. cannam@95: cannam@95: * Numeric array pointer arguments (e.g. `double *') become cannam@95: `dimension(*), intent(out)' arrays of the same type, or cannam@95: `dimension(*), intent(in)' if they are pointers to constant data cannam@95: (e.g. `const int *'). There are a few exceptions where numeric cannam@95: pointers refer to scalar outputs (e.g. for `fftw_flops'), in which cannam@95: case they are `intent(out)' scalar arguments in Fortran too. For cannam@95: the new-array execute functions (*note New-array Execute cannam@95: Functions::), the input arrays are declared `dimension(*), cannam@95: intent(inout)', since they can be modified in the case of in-place cannam@95: or `FFTW_DESTROY_INPUT' transforms. cannam@95: cannam@95: * Pointer _return_ values (e.g `double *') become `type(C_PTR)'. cannam@95: (If they are pointers to arrays, as for `fftw_alloc_real', you can cannam@95: convert them back to Fortran array pointers with the standard cannam@95: intrinsic function `c_f_pointer'.) cannam@95: cannam@95: * The `fftw_iodim' type in the guru interface (*note Guru vector and cannam@95: transform sizes::) becomes `type(fftw_iodim)' in Fortran, a cannam@95: derived data type (the Fortran analogue of C's `struct') with cannam@95: three `integer(C_INT)' components: `n', `is', and `os', with the cannam@95: same meanings as in C. The `fftw_iodim64' type in the 64-bit guru cannam@95: interface (*note 64-bit Guru Interface::) is the same, except that cannam@95: its components are of type `integer(C_INTPTR_T)'. cannam@95: cannam@95: * Using the wisdom import/export functions from Fortran is a bit cannam@95: tricky, and is discussed in *note Accessing the wisdom API from cannam@95: Fortran::. In brief, the `FILE *' arguments map to `type(C_PTR)', cannam@95: `const char *' to `character(C_CHAR), dimension(*), intent(in)' cannam@95: (null-terminated!), and the generic read-char/write-char functions cannam@95: map to `type(C_FUNPTR)'. cannam@95: cannam@95: cannam@95: You may be wondering if you need to search-and-replace cannam@95: `real(kind(0.0d0))' (or whatever your favorite Fortran spelling of cannam@95: "double precision" is) with `real(C_DOUBLE)' everywhere in your cannam@95: program, and similarly for `complex' and `integer' types. The answer cannam@95: is no; you can still use your existing types. As long as these types cannam@95: match their C counterparts, things should work without a hitch. The cannam@95: worst that can happen, e.g. in the (unlikely) event of a system where cannam@95: `real(kind(0.0d0))' is different from `real(C_DOUBLE)', is that the cannam@95: compiler will give you a type-mismatch error. That is, if you don't cannam@95: use the `iso_c_binding' kinds you need to accept at least the cannam@95: theoretical possibility of having to change your code in response to cannam@95: compiler errors on some future machine, but you don't need to worry cannam@95: about silently compiling incorrect code that yields runtime errors. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Plan execution in Fortran, Next: Allocating aligned memory in Fortran, Prev: FFTW Fortran type reference, Up: Calling FFTW from Modern Fortran cannam@95: cannam@95: 7.4 Plan execution in Fortran cannam@95: ============================= cannam@95: cannam@95: In C, in order to use a plan, one normally calls `fftw_execute', which cannam@95: executes the plan to perform the transform on the input/output arrays cannam@95: passed when the plan was created (*note Using Plans::). The cannam@95: corresponding subroutine call in modern Fortran is: cannam@95: call fftw_execute(plan) cannam@95: cannam@95: However, we have had reports that this causes problems with some cannam@95: recent optimizing Fortran compilers. The problem is, because the cannam@95: input/output arrays are not passed as explicit arguments to cannam@95: `fftw_execute', the semantics of Fortran (unlike C) allow the compiler cannam@95: to assume that the input/output arrays are not changed by cannam@95: `fftw_execute'. As a consequence, certain compilers end up cannam@95: repositioning the call to `fftw_execute', assuming incorrectly that it cannam@95: does nothing to the arrays. cannam@95: cannam@95: There are various workarounds to this, but the safest and simplest cannam@95: thing is to not use `fftw_execute' in Fortran. Instead, use the cannam@95: functions described in *note New-array Execute Functions::, which take cannam@95: the input/output arrays as explicit arguments. For example, if the cannam@95: plan is for a complex-data DFT and was created for the arrays `in' and cannam@95: `out', you would do: cannam@95: call fftw_execute_dft(plan, in, out) cannam@95: cannam@95: There are a few things to be careful of, however: cannam@95: cannam@95: * You must use the correct type of execute function, matching the way cannam@95: the plan was created. Complex DFT plans should use cannam@95: `fftw_execute_dft', Real-input (r2c) DFT plans should use use cannam@95: `fftw_execute_dft_r2c', and real-output (c2r) DFT plans should use cannam@95: `fftw_execute_dft_c2r'. The various r2r plans should use cannam@95: `fftw_execute_r2r'. Fortunately, if you use the wrong one you cannam@95: will get a compile-time type-mismatch error (unlike legacy cannam@95: Fortran). cannam@95: cannam@95: * You should normally pass the same input/output arrays that were cannam@95: used when creating the plan. This is always safe. cannam@95: cannam@95: * _If_ you pass _different_ input/output arrays compared to those cannam@95: used when creating the plan, you must abide by all the cannam@95: restrictions of the new-array execute functions (*note New-array cannam@95: Execute Functions::). The most tricky of these is the requirement cannam@95: that the new arrays have the same alignment as the original cannam@95: arrays; the best (and possibly only) way to guarantee this is to cannam@95: use the `fftw_alloc' functions to allocate your arrays (*note cannam@95: Allocating aligned memory in Fortran::). Alternatively, you can cannam@95: use the `FFTW_UNALIGNED' flag when creating the plan, in which cannam@95: case the plan does not depend on the alignment, but this may cannam@95: sacrifice substantial performance on architectures (like x86) with cannam@95: SIMD instructions (*note SIMD alignment and fftw_malloc::). cannam@95: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Allocating aligned memory in Fortran, Next: Accessing the wisdom API from Fortran, Prev: Plan execution in Fortran, Up: Calling FFTW from Modern Fortran cannam@95: cannam@95: 7.5 Allocating aligned memory in Fortran cannam@95: ======================================== cannam@95: cannam@95: In order to obtain maximum performance in FFTW, you should store your cannam@95: data in arrays that have been specially aligned in memory (*note SIMD cannam@95: alignment and fftw_malloc::). Enforcing alignment also permits you to cannam@95: safely use the new-array execute functions (*note New-array Execute cannam@95: Functions::) to apply a given plan to more than one pair of in/out cannam@95: arrays. Unfortunately, standard Fortran arrays do _not_ provide any cannam@95: alignment guarantees. The _only_ way to allocate aligned memory in cannam@95: standard Fortran is to allocate it with an external C function, like cannam@95: the `fftw_alloc_real' and `fftw_alloc_complex' functions. Fortunately, cannam@95: Fortran 2003 provides a simple way to associate such allocated memory cannam@95: with a standard Fortran array pointer that you can then use normally. cannam@95: cannam@95: We therefore recommend allocating all your input/output arrays using cannam@95: the following technique: cannam@95: cannam@95: 1. Declare a `pointer', `arr', to your array of the desired type and cannam@95: dimensions. For example, `real(C_DOUBLE), pointer :: a(:,:)' for cannam@95: a 2d real array, or `complex(C_DOUBLE_COMPLEX), pointer :: cannam@95: a(:,:,:)' for a 3d complex array. cannam@95: cannam@95: 2. The number of elements to allocate must be an `integer(C_SIZE_T)'. cannam@95: You can either declare a variable of this type, e.g. cannam@95: `integer(C_SIZE_T) :: sz', to store the number of elements to cannam@95: allocate, or you can use the `int(..., C_SIZE_T)' intrinsic cannam@95: function. e.g. set `sz = L * M * N' or use `int(L * M * N, cannam@95: C_SIZE_T)' for an L x M x N array. cannam@95: cannam@95: 3. Declare a `type(C_PTR) :: p' to hold the return value from FFTW's cannam@95: allocation routine. Set `p = fftw_alloc_real(sz)' for a real cannam@95: array, or `p = fftw_alloc_complex(sz)' for a complex array. cannam@95: cannam@95: 4. Associate your pointer `arr' with the allocated memory `p' using cannam@95: the standard `c_f_pointer' subroutine: `call c_f_pointer(p, arr, cannam@95: [...dimensions...])', where `[...dimensions...])' are an array of cannam@95: the dimensions of the array (in the usual Fortran order). e.g. cannam@95: `call c_f_pointer(p, arr, [L,M,N])' for an L x M x N array. cannam@95: (Alternatively, you can omit the dimensions argument if you cannam@95: specified the shape explicitly when declaring `arr'.) You can now cannam@95: use `arr' as a usual multidimensional array. cannam@95: cannam@95: 5. When you are done using the array, deallocate the memory by `call cannam@95: fftw_free(p)' on `p'. cannam@95: cannam@95: cannam@95: For example, here is how we would allocate an L x M 2d real array: cannam@95: cannam@95: real(C_DOUBLE), pointer :: arr(:,:) cannam@95: type(C_PTR) :: p cannam@95: p = fftw_alloc_real(int(L * M, C_SIZE_T)) cannam@95: call c_f_pointer(p, arr, [L,M]) cannam@95: _...use arr and arr(i,j) as usual..._ cannam@95: call fftw_free(p) cannam@95: cannam@95: and here is an L x M x N 3d complex array: cannam@95: cannam@95: complex(C_DOUBLE_COMPLEX), pointer :: arr(:,:,:) cannam@95: type(C_PTR) :: p cannam@95: p = fftw_alloc_complex(int(L * M * N, C_SIZE_T)) cannam@95: call c_f_pointer(p, arr, [L,M,N]) cannam@95: _...use arr and arr(i,j,k) as usual..._ cannam@95: call fftw_free(p) cannam@95: cannam@95: See *note Reversing array dimensions:: for an example allocating a cannam@95: single array and associating both real and complex array pointers with cannam@95: it, for in-place real-to-complex transforms. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Accessing the wisdom API from Fortran, Next: Defining an FFTW module, Prev: Allocating aligned memory in Fortran, Up: Calling FFTW from Modern Fortran cannam@95: cannam@95: 7.6 Accessing the wisdom API from Fortran cannam@95: ========================================= cannam@95: cannam@95: As explained in *note Words of Wisdom-Saving Plans::, FFTW provides a cannam@95: "wisdom" API for saving plans to disk so that they can be recreated cannam@95: quickly. The C API for exporting (*note Wisdom Export::) and importing cannam@95: (*note Wisdom Import::) wisdom is somewhat tricky to use from Fortran, cannam@95: however, because of differences in file I/O and string types between C cannam@95: and Fortran. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Wisdom File Export/Import from Fortran:: cannam@95: * Wisdom String Export/Import from Fortran:: cannam@95: * Wisdom Generic Export/Import from Fortran:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Wisdom File Export/Import from Fortran, Next: Wisdom String Export/Import from Fortran, Prev: Accessing the wisdom API from Fortran, Up: Accessing the wisdom API from Fortran cannam@95: cannam@95: 7.6.1 Wisdom File Export/Import from Fortran cannam@95: -------------------------------------------- cannam@95: cannam@95: The easiest way to export and import wisdom is to do so using cannam@95: `fftw_export_wisdom_to_filename' and `fftw_wisdom_from_filename'. The cannam@95: only trick is that these require you to pass a C string, which is an cannam@95: array of type `CHARACTER(C_CHAR)' that is terminated by `C_NULL_CHAR'. cannam@95: You can call them like this: cannam@95: cannam@95: integer(C_INT) :: ret cannam@95: ret = fftw_export_wisdom_to_filename(C_CHAR_'my_wisdom.dat' // C_NULL_CHAR) cannam@95: if (ret .eq. 0) stop 'error exporting wisdom to file' cannam@95: ret = fftw_import_wisdom_from_filename(C_CHAR_'my_wisdom.dat' // C_NULL_CHAR) cannam@95: if (ret .eq. 0) stop 'error importing wisdom from file' cannam@95: cannam@95: Note that prepending `C_CHAR_' is needed to specify that the literal cannam@95: string is of kind `C_CHAR', and we null-terminate the string by cannam@95: appending `// C_NULL_CHAR'. These functions return an `integer(C_INT)' cannam@95: (`ret') which is `0' if an error occurred during export/import and cannam@95: nonzero otherwise. cannam@95: cannam@95: It is also possible to use the lower-level routines cannam@95: `fftw_export_wisdom_to_file' and `fftw_import_wisdom_from_file', which cannam@95: accept parameters of the C type `FILE*', expressed in Fortran as cannam@95: `type(C_PTR)'. However, you are then responsible for creating the cannam@95: `FILE*' yourself. You can do this by using `iso_c_binding' to define cannam@95: Fortran intefaces for the C library functions `fopen' and `fclose', cannam@95: which is a bit strange in Fortran but workable. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Wisdom String Export/Import from Fortran, Next: Wisdom Generic Export/Import from Fortran, Prev: Wisdom File Export/Import from Fortran, Up: Accessing the wisdom API from Fortran cannam@95: cannam@95: 7.6.2 Wisdom String Export/Import from Fortran cannam@95: ---------------------------------------------- cannam@95: cannam@95: Dealing with FFTW's C string export/import is a bit more painful. In cannam@95: particular, the `fftw_export_wisdom_to_string' function requires you to cannam@95: deal with a dynamically allocated C string. To get its length, you cannam@95: must define an interface to the C `strlen' function, and to deallocate cannam@95: it you must define an interface to C `free': cannam@95: cannam@95: use, intrinsic :: iso_c_binding cannam@95: interface cannam@95: integer(C_INT) function strlen(s) bind(C, name='strlen') cannam@95: import cannam@95: type(C_PTR), value :: s cannam@95: end function strlen cannam@95: subroutine free(p) bind(C, name='free') cannam@95: import cannam@95: type(C_PTR), value :: p cannam@95: end subroutine free cannam@95: end interface cannam@95: cannam@95: Given these definitions, you can then export wisdom to a Fortran cannam@95: character array: cannam@95: cannam@95: character(C_CHAR), pointer :: s(:) cannam@95: integer(C_SIZE_T) :: slen cannam@95: type(C_PTR) :: p cannam@95: p = fftw_export_wisdom_to_string() cannam@95: if (.not. c_associated(p)) stop 'error exporting wisdom' cannam@95: slen = strlen(p) cannam@95: call c_f_pointer(p, s, [slen+1]) cannam@95: ... cannam@95: call free(p) cannam@95: cannam@95: Note that `slen' is the length of the C string, but the length of cannam@95: the array is `slen+1' because it includes the terminating null cannam@95: character. (You can omit the `+1' if you don't want Fortran to know cannam@95: about the null character.) The standard `c_associated' function checks cannam@95: whether `p' is a null pointer, which is returned by cannam@95: `fftw_export_wisdom_to_string' if there was an error. cannam@95: cannam@95: To import wisdom from a string, use `fftw_import_wisdom_from_string' cannam@95: as usual; note that the argument of this function must be a cannam@95: `character(C_CHAR)' that is terminated by the `C_NULL_CHAR' character, cannam@95: like the `s' array above. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Wisdom Generic Export/Import from Fortran, Prev: Wisdom String Export/Import from Fortran, Up: Accessing the wisdom API from Fortran cannam@95: cannam@95: 7.6.3 Wisdom Generic Export/Import from Fortran cannam@95: ----------------------------------------------- cannam@95: cannam@95: The most generic wisdom export/import functions allow you to provide an cannam@95: arbitrary callback function to read/write one character at a time in cannam@95: any way you want. However, your callback function must be written in a cannam@95: special way, using the `bind(C)' attribute to be passed to a C cannam@95: interface. cannam@95: cannam@95: In particular, to call the generic wisdom export function cannam@95: `fftw_export_wisdom', you would write a callback subroutine of the form: cannam@95: cannam@95: subroutine my_write_char(c, p) bind(C) cannam@95: use, intrinsic :: iso_c_binding cannam@95: character(C_CHAR), value :: c cannam@95: type(C_PTR), value :: p cannam@95: _...write c..._ cannam@95: end subroutine my_write_char cannam@95: cannam@95: Given such a subroutine (along with the corresponding interface cannam@95: definition), you could then export wisdom using: cannam@95: cannam@95: call fftw_export_wisdom(c_funloc(my_write_char), p) cannam@95: cannam@95: The standard `c_funloc' intrinsic converts a Fortran `bind(C)' cannam@95: subroutine into a C function pointer. The parameter `p' is a cannam@95: `type(C_PTR)' to any arbitrary data that you want to pass to cannam@95: `my_write_char' (or `C_NULL_PTR' if none). (Note that you can get a C cannam@95: pointer to Fortran data using the intrinsic `c_loc', and convert it cannam@95: back to a Fortran pointer in `my_write_char' using `c_f_pointer'.) cannam@95: cannam@95: Similarly, to use the generic `fftw_import_wisdom', you would define cannam@95: a callback function of the form: cannam@95: cannam@95: integer(C_INT) function my_read_char(p) bind(C) cannam@95: use, intrinsic :: iso_c_binding cannam@95: type(C_PTR), value :: p cannam@95: character :: c cannam@95: _...read a character c..._ cannam@95: my_read_char = ichar(c, C_INT) cannam@95: end function my_read_char cannam@95: cannam@95: .... cannam@95: cannam@95: integer(C_INT) :: ret cannam@95: ret = fftw_import_wisdom(c_funloc(my_read_char), p) cannam@95: if (ret .eq. 0) stop 'error importing wisdom' cannam@95: cannam@95: Your function can return `-1' if the end of the input is reached. cannam@95: Again, `p' is an arbitrary `type(C_PTR' that is passed through to your cannam@95: function. `fftw_import_wisdom' returns `0' if an error occurred and cannam@95: nonzero otherwise. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Defining an FFTW module, Prev: Accessing the wisdom API from Fortran, Up: Calling FFTW from Modern Fortran cannam@95: cannam@95: 7.7 Defining an FFTW module cannam@95: =========================== cannam@95: cannam@95: Rather than using the `include' statement to include the `fftw3.f03' cannam@95: interface file in any subroutine where you want to use FFTW, you might cannam@95: prefer to define an FFTW Fortran module. FFTW does not install itself cannam@95: as a module, primarily because `fftw3.f03' can be shared between cannam@95: different Fortran compilers while modules (in general) cannot. cannam@95: However, it is trivial to define your own FFTW module if you want. cannam@95: Just create a file containing: cannam@95: cannam@95: module FFTW3 cannam@95: use, intrinsic :: iso_c_binding cannam@95: include 'fftw3.f03' cannam@95: end module cannam@95: cannam@95: Compile this file into a module as usual for your compiler (e.g. with cannam@95: `gfortran -c' you will get a file `fftw3.mod'). Now, instead of cannam@95: `include 'fftw3.f03'', whenever you want to use FFTW routines you can cannam@95: just do: cannam@95: cannam@95: use FFTW3 cannam@95: cannam@95: as usual for Fortran modules. (You still need to link to the FFTW cannam@95: library, of course.) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Calling FFTW from Legacy Fortran, Next: Upgrading from FFTW version 2, Prev: Calling FFTW from Modern Fortran, Up: Top cannam@95: cannam@95: 8 Calling FFTW from Legacy Fortran cannam@95: ********************************** cannam@95: cannam@95: This chapter describes the interface to FFTW callable by Fortran code cannam@95: in older compilers not supporting the Fortran 2003 C interoperability cannam@95: features (*note Calling FFTW from Modern Fortran::). This interface cannam@95: has the major disadvantage that it is not type-checked, so if you cannam@95: mistake the argument types or ordering then your program will not have cannam@95: any compiler errors, and will likely crash at runtime. So, greater cannam@95: care is needed. Also, technically interfacing older Fortran versions cannam@95: to C is nonstandard, but in practice we have found that the techniques cannam@95: used in this chapter have worked with all known Fortran compilers for cannam@95: many years. cannam@95: cannam@95: The legacy Fortran interface differs from the C interface only in the cannam@95: prefix (`dfftw_' instead of `fftw_' in double precision) and a few cannam@95: other minor details. This Fortran interface is included in the FFTW cannam@95: libraries by default, unless a Fortran compiler isn't found on your cannam@95: system or `--disable-fortran' is included in the `configure' flags. We cannam@95: assume here that the reader is already familiar with the usage of FFTW cannam@95: in C, as described elsewhere in this manual. cannam@95: cannam@95: The MPI parallel interface to FFTW is _not_ currently available to cannam@95: legacy Fortran. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Fortran-interface routines:: cannam@95: * FFTW Constants in Fortran:: cannam@95: * FFTW Execution in Fortran:: cannam@95: * Fortran Examples:: cannam@95: * Wisdom of Fortran?:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Fortran-interface routines, Next: FFTW Constants in Fortran, Prev: Calling FFTW from Legacy Fortran, Up: Calling FFTW from Legacy Fortran cannam@95: cannam@95: 8.1 Fortran-interface routines cannam@95: ============================== cannam@95: cannam@95: Nearly all of the FFTW functions have Fortran-callable equivalents. cannam@95: The name of the legacy Fortran routine is the same as that of the cannam@95: corresponding C routine, but with the `fftw_' prefix replaced by cannam@95: `dfftw_'.(1) The single and long-double precision versions use cannam@95: `sfftw_' and `lfftw_', respectively, instead of `fftwf_' and `fftwl_'; cannam@95: quadruple precision (`real*16') is available on some systems as cannam@95: `fftwq_' (*note Precision::). (Note that `long double' on x86 hardware cannam@95: is usually at most 80-bit extended precision, _not_ quadruple cannam@95: precision.) cannam@95: cannam@95: For the most part, all of the arguments to the functions are the cannam@95: same, with the following exceptions: cannam@95: cannam@95: * `plan' variables (what would be of type `fftw_plan' in C), must be cannam@95: declared as a type that is at least as big as a pointer (address) cannam@95: on your machine. We recommend using `integer*8' everywhere, since cannam@95: this should always be big enough. cannam@95: cannam@95: * Any function that returns a value (e.g. `fftw_plan_dft') is cannam@95: converted into a _subroutine_. The return value is converted into cannam@95: an additional _first_ parameter of this subroutine.(2) cannam@95: cannam@95: * The Fortran routines expect multi-dimensional arrays to be in cannam@95: _column-major_ order, which is the ordinary format of Fortran cannam@95: arrays (*note Multi-dimensional Array Format::). They do this cannam@95: transparently and costlessly simply by reversing the order of the cannam@95: dimensions passed to FFTW, but this has one important consequence cannam@95: for multi-dimensional real-complex transforms, discussed below. cannam@95: cannam@95: * Wisdom import and export is somewhat more tricky because one cannot cannam@95: easily pass files or strings between C and Fortran; see *note cannam@95: Wisdom of Fortran?::. cannam@95: cannam@95: * Legacy Fortran cannot use the `fftw_malloc' dynamic-allocation cannam@95: routine. If you want to exploit the SIMD FFTW (*note SIMD cannam@95: alignment and fftw_malloc::), you'll need to figure out some other cannam@95: way to ensure that your arrays are at least 16-byte aligned. cannam@95: cannam@95: * Since Fortran 77 does not have data structures, the `fftw_iodim' cannam@95: structure from the guru interface (*note Guru vector and transform cannam@95: sizes::) must be split into separate arguments. In particular, any cannam@95: `fftw_iodim' array arguments in the C guru interface become three cannam@95: integer array arguments (`n', `is', and `os') in the Fortran guru cannam@95: interface, all of whose lengths should be equal to the cannam@95: corresponding `rank' argument. cannam@95: cannam@95: * The guru planner interface in Fortran does _not_ do any automatic cannam@95: translation between column-major and row-major; you are responsible cannam@95: for setting the strides etcetera to correspond to your Fortran cannam@95: arrays. However, as a slight bug that we are preserving for cannam@95: backwards compatibility, the `plan_guru_r2r' in Fortran _does_ cannam@95: reverse the order of its `kind' array parameter, so the `kind' cannam@95: array of that routine should be in the reverse of the order of the cannam@95: iodim arrays (see above). cannam@95: cannam@95: cannam@95: In general, you should take care to use Fortran data types that cannam@95: correspond to (i.e. are the same size as) the C types used by FFTW. In cannam@95: practice, this correspondence is usually straightforward (i.e. cannam@95: `integer' corresponds to `int', `real' corresponds to `float', cannam@95: etcetera). The native Fortran double/single-precision complex type cannam@95: should be compatible with `fftw_complex'/`fftwf_complex'. Such simple cannam@95: correspondences are assumed in the examples below. cannam@95: cannam@95: ---------- Footnotes ---------- cannam@95: cannam@95: (1) Technically, Fortran 77 identifiers are not allowed to have more cannam@95: than 6 characters, nor may they contain underscores. Any compiler that cannam@95: enforces this limitation doesn't deserve to link to FFTW. cannam@95: cannam@95: (2) The reason for this is that some Fortran implementations seem to cannam@95: have trouble with C function return values, and vice versa. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW Constants in Fortran, Next: FFTW Execution in Fortran, Prev: Fortran-interface routines, Up: Calling FFTW from Legacy Fortran cannam@95: cannam@95: 8.2 FFTW Constants in Fortran cannam@95: ============================= cannam@95: cannam@95: When creating plans in FFTW, a number of constants are used to specify cannam@95: options, such as `FFTW_MEASURE' or `FFTW_ESTIMATE'. The same constants cannam@95: must be used with the wrapper routines, but of course the C header cannam@95: files where the constants are defined can't be incorporated directly cannam@95: into Fortran code. cannam@95: cannam@95: Instead, we have placed Fortran equivalents of the FFTW constant cannam@95: definitions in the file `fftw3.f', which can be found in the same cannam@95: directory as `fftw3.h'. If your Fortran compiler supports a cannam@95: preprocessor of some sort, you should be able to `include' or cannam@95: `#include' this file; otherwise, you can paste it directly into your cannam@95: code. cannam@95: cannam@95: In C, you combine different flags (like `FFTW_PRESERVE_INPUT' and cannam@95: `FFTW_MEASURE') using the ``|'' operator; in Fortran you should just cannam@95: use ``+''. (Take care not to add in the same flag more than once, cannam@95: though. Alternatively, you can use the `ior' intrinsic function cannam@95: standardized in Fortran 95.) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: FFTW Execution in Fortran, Next: Fortran Examples, Prev: FFTW Constants in Fortran, Up: Calling FFTW from Legacy Fortran cannam@95: cannam@95: 8.3 FFTW Execution in Fortran cannam@95: ============================= cannam@95: cannam@95: In C, in order to use a plan, one normally calls `fftw_execute', which cannam@95: executes the plan to perform the transform on the input/output arrays cannam@95: passed when the plan was created (*note Using Plans::). The cannam@95: corresponding subroutine call in legacy Fortran is: cannam@95: call dfftw_execute(plan) cannam@95: cannam@95: However, we have had reports that this causes problems with some cannam@95: recent optimizing Fortran compilers. The problem is, because the cannam@95: input/output arrays are not passed as explicit arguments to cannam@95: `dfftw_execute', the semantics of Fortran (unlike C) allow the compiler cannam@95: to assume that the input/output arrays are not changed by cannam@95: `dfftw_execute'. As a consequence, certain compilers end up optimizing cannam@95: out or repositioning the call to `dfftw_execute', assuming incorrectly cannam@95: that it does nothing. cannam@95: cannam@95: There are various workarounds to this, but the safest and simplest cannam@95: thing is to not use `dfftw_execute' in Fortran. Instead, use the cannam@95: functions described in *note New-array Execute Functions::, which take cannam@95: the input/output arrays as explicit arguments. For example, if the cannam@95: plan is for a complex-data DFT and was created for the arrays `in' and cannam@95: `out', you would do: cannam@95: call dfftw_execute_dft(plan, in, out) cannam@95: cannam@95: There are a few things to be careful of, however: cannam@95: cannam@95: * You must use the correct type of execute function, matching the way cannam@95: the plan was created. Complex DFT plans should use cannam@95: `dfftw_execute_dft', Real-input (r2c) DFT plans should use use cannam@95: `dfftw_execute_dft_r2c', and real-output (c2r) DFT plans should cannam@95: use `dfftw_execute_dft_c2r'. The various r2r plans should use cannam@95: `dfftw_execute_r2r'. cannam@95: cannam@95: * You should normally pass the same input/output arrays that were cannam@95: used when creating the plan. This is always safe. cannam@95: cannam@95: * _If_ you pass _different_ input/output arrays compared to those cannam@95: used when creating the plan, you must abide by all the cannam@95: restrictions of the new-array execute functions (*note New-array cannam@95: Execute Functions::). The most difficult of these, in Fortran, is cannam@95: the requirement that the new arrays have the same alignment as the cannam@95: original arrays, because there seems to be no way in legacy cannam@95: Fortran to obtain guaranteed-aligned arrays (analogous to cannam@95: `fftw_malloc' in C). You can, of course, use the `FFTW_UNALIGNED' cannam@95: flag when creating the plan, in which case the plan does not cannam@95: depend on the alignment, but this may sacrifice substantial cannam@95: performance on architectures (like x86) with SIMD instructions cannam@95: (*note SIMD alignment and fftw_malloc::). cannam@95: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Fortran Examples, Next: Wisdom of Fortran?, Prev: FFTW Execution in Fortran, Up: Calling FFTW from Legacy Fortran cannam@95: cannam@95: 8.4 Fortran Examples cannam@95: ==================== cannam@95: cannam@95: In C, you might have something like the following to transform a cannam@95: one-dimensional complex array: cannam@95: cannam@95: fftw_complex in[N], out[N]; cannam@95: fftw_plan plan; cannam@95: cannam@95: plan = fftw_plan_dft_1d(N,in,out,FFTW_FORWARD,FFTW_ESTIMATE); cannam@95: fftw_execute(plan); cannam@95: fftw_destroy_plan(plan); cannam@95: cannam@95: In Fortran, you would use the following to accomplish the same thing: cannam@95: cannam@95: double complex in, out cannam@95: dimension in(N), out(N) cannam@95: integer*8 plan cannam@95: cannam@95: call dfftw_plan_dft_1d(plan,N,in,out,FFTW_FORWARD,FFTW_ESTIMATE) cannam@95: call dfftw_execute_dft(plan, in, out) cannam@95: call dfftw_destroy_plan(plan) cannam@95: cannam@95: Notice how all routines are called as Fortran subroutines, and the cannam@95: plan is returned via the first argument to `dfftw_plan_dft_1d'. Notice cannam@95: also that we changed `fftw_execute' to `dfftw_execute_dft' (*note FFTW cannam@95: Execution in Fortran::). To do the same thing, but using 8 threads in cannam@95: parallel (*note Multi-threaded FFTW::), you would simply prefix these cannam@95: calls with: cannam@95: cannam@95: integer iret cannam@95: call dfftw_init_threads(iret) cannam@95: call dfftw_plan_with_nthreads(8) cannam@95: cannam@95: (You might want to check the value of `iret': if it is zero, it cannam@95: indicates an unlikely error during thread initialization.) cannam@95: cannam@95: To transform a three-dimensional array in-place with C, you might do: cannam@95: cannam@95: fftw_complex arr[L][M][N]; cannam@95: fftw_plan plan; cannam@95: cannam@95: plan = fftw_plan_dft_3d(L,M,N, arr,arr, cannam@95: FFTW_FORWARD, FFTW_ESTIMATE); cannam@95: fftw_execute(plan); cannam@95: fftw_destroy_plan(plan); cannam@95: cannam@95: In Fortran, you would use this instead: cannam@95: cannam@95: double complex arr cannam@95: dimension arr(L,M,N) cannam@95: integer*8 plan cannam@95: cannam@95: call dfftw_plan_dft_3d(plan, L,M,N, arr,arr, cannam@95: & FFTW_FORWARD, FFTW_ESTIMATE) cannam@95: call dfftw_execute_dft(plan, arr, arr) cannam@95: call dfftw_destroy_plan(plan) cannam@95: cannam@95: Note that we pass the array dimensions in the "natural" order in cannam@95: both C and Fortran. cannam@95: cannam@95: To transform a one-dimensional real array in Fortran, you might do: cannam@95: cannam@95: double precision in cannam@95: dimension in(N) cannam@95: double complex out cannam@95: dimension out(N/2 + 1) cannam@95: integer*8 plan cannam@95: cannam@95: call dfftw_plan_dft_r2c_1d(plan,N,in,out,FFTW_ESTIMATE) cannam@95: call dfftw_execute_dft_r2c(plan, in, out) cannam@95: call dfftw_destroy_plan(plan) cannam@95: cannam@95: To transform a two-dimensional real array, out of place, you might cannam@95: use the following: cannam@95: cannam@95: double precision in cannam@95: dimension in(M,N) cannam@95: double complex out cannam@95: dimension out(M/2 + 1, N) cannam@95: integer*8 plan cannam@95: cannam@95: call dfftw_plan_dft_r2c_2d(plan,M,N,in,out,FFTW_ESTIMATE) cannam@95: call dfftw_execute_dft_r2c(plan, in, out) cannam@95: call dfftw_destroy_plan(plan) cannam@95: cannam@95: *Important:* Notice that it is the _first_ dimension of the complex cannam@95: output array that is cut in half in Fortran, rather than the last cannam@95: dimension as in C. This is a consequence of the interface routines cannam@95: reversing the order of the array dimensions passed to FFTW so that the cannam@95: Fortran program can use its ordinary column-major order. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Wisdom of Fortran?, Prev: Fortran Examples, Up: Calling FFTW from Legacy Fortran cannam@95: cannam@95: 8.5 Wisdom of Fortran? cannam@95: ====================== cannam@95: cannam@95: In this section, we discuss how one can import/export FFTW wisdom cannam@95: (saved plans) to/from a Fortran program; we assume that the reader is cannam@95: already familiar with wisdom, as described in *note Words of cannam@95: Wisdom-Saving Plans::. cannam@95: cannam@95: The basic problem is that is difficult to (portably) pass files and cannam@95: strings between Fortran and C, so we cannot provide a direct Fortran cannam@95: equivalent to the `fftw_export_wisdom_to_file', etcetera, functions. cannam@95: Fortran interfaces _are_ provided for the functions that do not take cannam@95: file/string arguments, however: `dfftw_import_system_wisdom', cannam@95: `dfftw_import_wisdom', `dfftw_export_wisdom', and `dfftw_forget_wisdom'. cannam@95: cannam@95: So, for example, to import the system-wide wisdom, you would do: cannam@95: cannam@95: integer isuccess cannam@95: call dfftw_import_system_wisdom(isuccess) cannam@95: cannam@95: As usual, the C return value is turned into a first parameter; cannam@95: `isuccess' is non-zero on success and zero on failure (e.g. if there is cannam@95: no system wisdom installed). cannam@95: cannam@95: If you want to import/export wisdom from/to an arbitrary file or cannam@95: elsewhere, you can employ the generic `dfftw_import_wisdom' and cannam@95: `dfftw_export_wisdom' functions, for which you must supply a subroutine cannam@95: to read/write one character at a time. The FFTW package contains an cannam@95: example file `doc/f77_wisdom.f' demonstrating how to implement cannam@95: `import_wisdom_from_file' and `export_wisdom_to_file' subroutines in cannam@95: this way. (These routines cannot be compiled into the FFTW library cannam@95: itself, lest all FFTW-using programs be required to link with the cannam@95: Fortran I/O library.) cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Upgrading from FFTW version 2, Next: Installation and Customization, Prev: Calling FFTW from Legacy Fortran, Up: Top cannam@95: cannam@95: 9 Upgrading from FFTW version 2 cannam@95: ******************************* cannam@95: cannam@95: In this chapter, we outline the process for updating codes designed for cannam@95: the older FFTW 2 interface to work with FFTW 3. The interface for FFTW cannam@95: 3 is not backwards-compatible with the interface for FFTW 2 and earlier cannam@95: versions; codes written to use those versions will fail to link with cannam@95: FFTW 3. Nor is it possible to write "compatibility wrappers" to bridge cannam@95: the gap (at least not efficiently), because FFTW 3 has different cannam@95: semantics from previous versions. However, upgrading should be a cannam@95: straightforward process because the data formats are identical and the cannam@95: overall style of planning/execution is essentially the same. cannam@95: cannam@95: Unlike FFTW 2, there are no separate header files for real and cannam@95: complex transforms (or even for different precisions) in FFTW 3; all cannam@95: interfaces are defined in the `' header file. cannam@95: cannam@95: Numeric Types cannam@95: ============= cannam@95: cannam@95: The main difference in data types is that `fftw_complex' in FFTW 2 was cannam@95: defined as a `struct' with macros `c_re' and `c_im' for accessing the cannam@95: real/imaginary parts. (This is binary-compatible with FFTW 3 on any cannam@95: machine except perhaps for some older Crays in single precision.) The cannam@95: equivalent macros for FFTW 3 are: cannam@95: cannam@95: #define c_re(c) ((c)[0]) cannam@95: #define c_im(c) ((c)[1]) cannam@95: cannam@95: This does not work if you are using the C99 complex type, however, cannam@95: unless you insert a `double*' typecast into the above macros (*note cannam@95: Complex numbers::). cannam@95: cannam@95: Also, FFTW 2 had an `fftw_real' typedef that was an alias for cannam@95: `double' (in double precision). In FFTW 3 you should just use `double' cannam@95: (or whatever precision you are employing). cannam@95: cannam@95: Plans cannam@95: ===== cannam@95: cannam@95: The major difference between FFTW 2 and FFTW 3 is in the cannam@95: planning/execution division of labor. In FFTW 2, plans were found for a cannam@95: given transform size and type, and then could be applied to _any_ cannam@95: arrays and for _any_ multiplicity/stride parameters. In FFTW 3, you cannam@95: specify the particular arrays, stride parameters, etcetera when cannam@95: creating the plan, and the plan is then executed for _those_ arrays cannam@95: (unless the guru interface is used) and _those_ parameters _only_. cannam@95: (FFTW 2 had "specific planner" routines that planned for a particular cannam@95: array and stride, but the plan could still be used for other arrays and cannam@95: strides.) That is, much of the information that was formerly specified cannam@95: at execution time is now specified at planning time. cannam@95: cannam@95: Like FFTW 2's specific planner routines, the FFTW 3 planner cannam@95: overwrites the input/output arrays unless you use `FFTW_ESTIMATE'. cannam@95: cannam@95: FFTW 2 had separate data types `fftw_plan', `fftwnd_plan', cannam@95: `rfftw_plan', and `rfftwnd_plan' for complex and real one- and cannam@95: multi-dimensional transforms, and each type had its own `destroy' cannam@95: function. In FFTW 3, all plans are of type `fftw_plan' and all are cannam@95: destroyed by `fftw_destroy_plan(plan)'. cannam@95: cannam@95: Where you formerly used `fftw_create_plan' and `fftw_one' to plan cannam@95: and compute a single 1d transform, you would now use `fftw_plan_dft_1d' cannam@95: to plan the transform. If you used the generic `fftw' function to cannam@95: execute the transform with multiplicity (`howmany') and stride cannam@95: parameters, you would now use the advanced interface cannam@95: `fftw_plan_many_dft' to specify those parameters. The plans are now cannam@95: executed with `fftw_execute(plan)', which takes all of its parameters cannam@95: (including the input/output arrays) from the plan. cannam@95: cannam@95: In-place transforms no longer interpret their output argument as cannam@95: scratch space, nor is there an `FFTW_IN_PLACE' flag. You simply pass cannam@95: the same pointer for both the input and output arguments. (Previously, cannam@95: the output `ostride' and `odist' parameters were ignored for in-place cannam@95: transforms; now, if they are specified via the advanced interface, they cannam@95: are significant even in the in-place case, although they should cannam@95: normally equal the corresponding input parameters.) cannam@95: cannam@95: The `FFTW_ESTIMATE' and `FFTW_MEASURE' flags have the same meaning cannam@95: as before, although the planning time will differ. You may also cannam@95: consider using `FFTW_PATIENT', which is like `FFTW_MEASURE' except that cannam@95: it takes more time in order to consider a wider variety of algorithms. cannam@95: cannam@95: For multi-dimensional complex DFTs, instead of `fftwnd_create_plan' cannam@95: (or `fftw2d_create_plan' or `fftw3d_create_plan'), followed by cannam@95: `fftwnd_one', you would use `fftw_plan_dft' (or `fftw_plan_dft_2d' or cannam@95: `fftw_plan_dft_3d'). followed by `fftw_execute'. If you used `fftwnd' cannam@95: to to specify strides etcetera, you would instead specify these via cannam@95: `fftw_plan_many_dft'. cannam@95: cannam@95: The analogues to `rfftw_create_plan' and `rfftw_one' with cannam@95: `FFTW_REAL_TO_COMPLEX' or `FFTW_COMPLEX_TO_REAL' directions are cannam@95: `fftw_plan_r2r_1d' with kind `FFTW_R2HC' or `FFTW_HC2R', followed by cannam@95: `fftw_execute'. The stride etcetera arguments of `rfftw' are now in cannam@95: `fftw_plan_many_r2r'. cannam@95: cannam@95: Instead of `rfftwnd_create_plan' (or `rfftw2d_create_plan' or cannam@95: `rfftw3d_create_plan') followed by `rfftwnd_one_real_to_complex' or cannam@95: `rfftwnd_one_complex_to_real', you now use `fftw_plan_dft_r2c' (or cannam@95: `fftw_plan_dft_r2c_2d' or `fftw_plan_dft_r2c_3d') or cannam@95: `fftw_plan_dft_c2r' (or `fftw_plan_dft_c2r_2d' or cannam@95: `fftw_plan_dft_c2r_3d'), respectively, followed by `fftw_execute'. As cannam@95: usual, the strides etcetera of `rfftwnd_real_to_complex' or cannam@95: `rfftwnd_complex_to_real' are no specified in the advanced planner cannam@95: routines, `fftw_plan_many_dft_r2c' or `fftw_plan_many_dft_c2r'. cannam@95: cannam@95: Wisdom cannam@95: ====== cannam@95: cannam@95: In FFTW 2, you had to supply the `FFTW_USE_WISDOM' flag in order to use cannam@95: wisdom; in FFTW 3, wisdom is always used. (You could simulate the FFTW cannam@95: 2 wisdom-less behavior by calling `fftw_forget_wisdom' after every cannam@95: planner call.) cannam@95: cannam@95: The FFTW 3 wisdom import/export routines are almost the same as cannam@95: before (although the storage format is entirely different). There is cannam@95: one significant difference, however. In FFTW 2, the import routines cannam@95: would never read past the end of the wisdom, so you could store extra cannam@95: data beyond the wisdom in the same file, for example. In FFTW 3, the cannam@95: file-import routine may read up to a few hundred bytes past the end of cannam@95: the wisdom, so you cannot store other data just beyond it.(1) cannam@95: cannam@95: Wisdom has been enhanced by additional humility in FFTW 3: whereas cannam@95: FFTW 2 would re-use wisdom for a given transform size regardless of the cannam@95: stride etc., in FFTW 3 wisdom is only used with the strides etc. for cannam@95: which it was created. Unfortunately, this means FFTW 3 has to create cannam@95: new plans from scratch more often than FFTW 2 (in FFTW 2, planning e.g. cannam@95: one transform of size 1024 also created wisdom for all smaller powers cannam@95: of 2, but this no longer occurs). cannam@95: cannam@95: FFTW 3 also has the new routine `fftw_import_system_wisdom' to cannam@95: import wisdom from a standard system-wide location. cannam@95: cannam@95: Memory allocation cannam@95: ================= cannam@95: cannam@95: In FFTW 3, we recommend allocating your arrays with `fftw_malloc' and cannam@95: deallocating them with `fftw_free'; this is not required, but allows cannam@95: optimal performance when SIMD acceleration is used. (Those two cannam@95: functions actually existed in FFTW 2, and worked the same way, but were cannam@95: not documented.) cannam@95: cannam@95: In FFTW 2, there were `fftw_malloc_hook' and `fftw_free_hook' cannam@95: functions that allowed the user to replace FFTW's memory-allocation cannam@95: routines (e.g. to implement different error-handling, since by default cannam@95: FFTW prints an error message and calls `exit' to abort the program if cannam@95: `malloc' returns `NULL'). These hooks are not supported in FFTW 3; cannam@95: those few users who require this functionality can just directly modify cannam@95: the memory-allocation routines in FFTW (they are defined in cannam@95: `kernel/alloc.c'). cannam@95: cannam@95: Fortran interface cannam@95: ================= cannam@95: cannam@95: In FFTW 2, the subroutine names were obtained by replacing `fftw_' with cannam@95: `fftw_f77'; in FFTW 3, you replace `fftw_' with `dfftw_' (or `sfftw_' cannam@95: or `lfftw_', depending upon the precision). cannam@95: cannam@95: In FFTW 3, we have begun recommending that you always declare the cannam@95: type used to store plans as `integer*8'. (Too many people didn't notice cannam@95: our instruction to switch from `integer' to `integer*8' for 64-bit cannam@95: machines.) cannam@95: cannam@95: In FFTW 3, we provide a `fftw3.f' "header file" to include in your cannam@95: code (and which is officially installed on Unix systems). (In FFTW 2, cannam@95: we supplied a `fftw_f77.i' file, but it was not installed.) cannam@95: cannam@95: Otherwise, the C-Fortran interface relationship is much the same as cannam@95: it was before (e.g. return values become initial parameters, and cannam@95: multi-dimensional arrays are in column-major order). Unlike FFTW 2, we cannam@95: do provide some support for wisdom import/export in Fortran (*note cannam@95: Wisdom of Fortran?::). cannam@95: cannam@95: Threads cannam@95: ======= cannam@95: cannam@95: Like FFTW 2, only the execution routines are thread-safe. All planner cannam@95: routines, etcetera, should be called by only a single thread at a time cannam@95: (*note Thread safety::). _Unlike_ FFTW 2, there is no special cannam@95: `FFTW_THREADSAFE' flag for the planner to allow a given plan to be cannam@95: usable by multiple threads in parallel; this is now the case by default. cannam@95: cannam@95: The multi-threaded version of FFTW 2 required you to pass the number cannam@95: of threads each time you execute the transform. The number of threads cannam@95: is now stored in the plan, and is specified before the planner is cannam@95: called by `fftw_plan_with_nthreads'. The threads initialization cannam@95: routine used to be called `fftw_threads_init' and would return zero on cannam@95: success; the new routine is called `fftw_init_threads' and returns zero cannam@95: on failure. *Note Multi-threaded FFTW::. cannam@95: cannam@95: There is no separate threads header file in FFTW 3; all the function cannam@95: prototypes are in `'. However, you still have to link to a cannam@95: separate library (`-lfftw3_threads -lfftw3 -lm' on Unix), as well as to cannam@95: the threading library (e.g. POSIX threads on Unix). cannam@95: cannam@95: ---------- Footnotes ---------- cannam@95: cannam@95: (1) We do our own buffering because GNU libc I/O routines are cannam@95: horribly slow for single-character I/O, apparently for thread-safety cannam@95: reasons (whether you are using threads or not). cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Installation and Customization, Next: Acknowledgments, Prev: Upgrading from FFTW version 2, Up: Top cannam@95: cannam@95: 10 Installation and Customization cannam@95: ********************************* cannam@95: cannam@95: This chapter describes the installation and customization of FFTW, the cannam@95: latest version of which may be downloaded from the FFTW home page cannam@95: (http://www.fftw.org). cannam@95: cannam@95: In principle, FFTW should work on any system with an ANSI C compiler cannam@95: (`gcc' is fine). However, planner time is drastically reduced if FFTW cannam@95: can exploit a hardware cycle counter; FFTW comes with cycle-counter cannam@95: support for all modern general-purpose CPUs, but you may need to add a cannam@95: couple of lines of code if your compiler is not yet supported (*note cannam@95: Cycle Counters::). (On Unix, there will be a warning at the end of the cannam@95: `configure' output if no cycle counter is found.) cannam@95: cannam@95: Installation of FFTW is simplest if you have a Unix or a GNU system, cannam@95: such as GNU/Linux, and we describe this case in the first section below, cannam@95: including the use of special configuration options to e.g. install cannam@95: different precisions or exploit optimizations for particular cannam@95: architectures (e.g. SIMD). Compilation on non-Unix systems is a more cannam@95: manual process, but we outline the procedure in the second section. It cannam@95: is also likely that pre-compiled binaries will be available for popular cannam@95: systems. cannam@95: cannam@95: Finally, we describe how you can customize FFTW for particular needs cannam@95: by generating _codelets_ for fast transforms of sizes not supported cannam@95: efficiently by the standard FFTW distribution. cannam@95: cannam@95: * Menu: cannam@95: cannam@95: * Installation on Unix:: cannam@95: * Installation on non-Unix systems:: cannam@95: * Cycle Counters:: cannam@95: * Generating your own code:: cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Installation on Unix, Next: Installation on non-Unix systems, Prev: Installation and Customization, Up: Installation and Customization cannam@95: cannam@95: 10.1 Installation on Unix cannam@95: ========================= cannam@95: cannam@95: FFTW comes with a `configure' program in the GNU style. Installation cannam@95: can be as simple as: cannam@95: cannam@95: ./configure cannam@95: make cannam@95: make install cannam@95: cannam@95: This will build the uniprocessor complex and real transform libraries cannam@95: along with the test programs. (We recommend that you use GNU `make' if cannam@95: it is available; on some systems it is called `gmake'.) The "`make cannam@95: install'" command installs the fftw and rfftw libraries in standard cannam@95: places, and typically requires root privileges (unless you specify a cannam@95: different install directory with the `--prefix' flag to `configure'). cannam@95: You can also type "`make check'" to put the FFTW test programs through cannam@95: their paces. If you have problems during configuration or compilation, cannam@95: you may want to run "`make distclean'" before trying again; this cannam@95: ensures that you don't have any stale files left over from previous cannam@95: compilation attempts. cannam@95: cannam@95: The `configure' script chooses the `gcc' compiler by default, if it cannam@95: is available; you can select some other compiler with: cannam@95: ./configure CC="" cannam@95: cannam@95: The `configure' script knows good `CFLAGS' (C compiler flags) for a cannam@95: few systems. If your system is not known, the `configure' script will cannam@95: print out a warning. In this case, you should re-configure FFTW with cannam@95: the command cannam@95: ./configure CFLAGS="" cannam@95: and then compile as usual. If you do find an optimal set of cannam@95: `CFLAGS' for your system, please let us know what they are (along with cannam@95: the output of `config.guess') so that we can include them in future cannam@95: releases. cannam@95: cannam@95: `configure' supports all the standard flags defined by the GNU cannam@95: Coding Standards; see the `INSTALL' file in FFTW or the GNU web page cannam@95: (http://www.gnu.org/prep/standards/html_node/index.html). Note cannam@95: especially `--help' to list all flags and `--enable-shared' to create cannam@95: shared, rather than static, libraries. `configure' also accepts a few cannam@95: FFTW-specific flags, particularly: cannam@95: cannam@95: * `--enable-float': Produces a single-precision version of FFTW cannam@95: (`float') instead of the default double-precision (`double'). cannam@95: *Note Precision::. cannam@95: cannam@95: * `--enable-long-double': Produces a long-double precision version of cannam@95: FFTW (`long double') instead of the default double-precision cannam@95: (`double'). The `configure' script will halt with an error cannam@95: message if `long double' is the same size as `double' on your cannam@95: machine/compiler. *Note Precision::. cannam@95: cannam@95: * `--enable-quad-precision': Produces a quadruple-precision version cannam@95: of FFTW using the nonstandard `__float128' type provided by `gcc' cannam@95: 4.6 or later on x86, x86-64, and Itanium architectures, instead of cannam@95: the default double-precision (`double'). The `configure' script cannam@95: will halt with an error message if the compiler is not `gcc' cannam@95: version 4.6 or later or if `gcc''s `libquadmath' library is not cannam@95: installed. *Note Precision::. cannam@95: cannam@95: * `--enable-threads': Enables compilation and installation of the cannam@95: FFTW threads library (*note Multi-threaded FFTW::), which provides cannam@95: a simple interface to parallel transforms for SMP systems. By cannam@95: default, the threads routines are not compiled. cannam@95: cannam@95: * `--enable-openmp': Like `--enable-threads', but using OpenMP cannam@95: compiler directives in order to induce parallelism rather than cannam@95: spawning its own threads directly, and installing an `fftw3_omp' cannam@95: library rather than an `fftw3_threads' library (*note cannam@95: Multi-threaded FFTW::). You can use both `--enable-openmp' and cannam@95: `--enable-threads' since they compile/install libraries with cannam@95: different names. By default, the OpenMP routines are not compiled. cannam@95: cannam@95: * `--with-combined-threads': By default, if `--enable-threads' is cannam@95: used, the threads support is compiled into a separate library that cannam@95: must be linked in addition to the main FFTW library. This is so cannam@95: that users of the serial library do not need to link the system cannam@95: threads libraries. If `--with-combined-threads' is specified, cannam@95: however, then no separate threads library is created, and threads cannam@95: are included in the main FFTW library. This is mainly useful cannam@95: under Windows, where no system threads library is required and cannam@95: inter-library dependencies are problematic. cannam@95: cannam@95: * `--enable-mpi': Enables compilation and installation of the FFTW cannam@95: MPI library (*note Distributed-memory FFTW with MPI::), which cannam@95: provides parallel transforms for distributed-memory systems with cannam@95: MPI. (By default, the MPI routines are not compiled.) *Note FFTW cannam@95: MPI Installation::. cannam@95: cannam@95: * `--disable-fortran': Disables inclusion of legacy-Fortran wrapper cannam@95: routines (*note Calling FFTW from Legacy Fortran::) in the standard cannam@95: FFTW libraries. These wrapper routines increase the library size cannam@95: by only a negligible amount, so they are included by default as cannam@95: long as the `configure' script finds a Fortran compiler on your cannam@95: system. (To specify a particular Fortran compiler foo, pass cannam@95: `F77='foo to `configure'.) cannam@95: cannam@95: * `--with-g77-wrappers': By default, when Fortran wrappers are cannam@95: included, the wrappers employ the linking conventions of the cannam@95: Fortran compiler detected by the `configure' script. If this cannam@95: compiler is GNU `g77', however, then _two_ versions of the cannam@95: wrappers are included: one with `g77''s idiosyncratic convention cannam@95: of appending two underscores to identifiers, and one with the more cannam@95: common convention of appending only a single underscore. This cannam@95: way, the same FFTW library will work with both `g77' and other cannam@95: Fortran compilers, such as GNU `gfortran'. However, the converse cannam@95: is not true: if you configure with a different compiler, then the cannam@95: `g77'-compatible wrappers are not included. By specifying cannam@95: `--with-g77-wrappers', the `g77'-compatible wrappers are included cannam@95: in addition to wrappers for whatever Fortran compiler `configure' cannam@95: finds. cannam@95: cannam@95: * `--with-slow-timer': Disables the use of hardware cycle counters, cannam@95: and falls back on `gettimeofday' or `clock'. This greatly worsens cannam@95: performance, and should generally not be used (unless you don't cannam@95: have a cycle counter but still really want an optimized plan cannam@95: regardless of the time). *Note Cycle Counters::. cannam@95: cannam@95: * `--enable-sse', `--enable-sse2', `--enable-avx', cannam@95: `--enable-altivec', `--enable-neon': Enable the compilation of cannam@95: SIMD code for SSE (Pentium III+), SSE2 (Pentium IV+), AVX (Sandy cannam@95: Bridge, Interlagos), AltiVec (PowerPC G4+), NEON (some ARM cannam@95: processors). SSE, AltiVec, and NEON only work with cannam@95: `--enable-float' (above). SSE2 works in both single and double cannam@95: precision (and is simply SSE in single precision). The resulting cannam@95: code will _still work_ on earlier CPUs lacking the SIMD extensions cannam@95: (SIMD is automatically disabled, although the FFTW library is cannam@95: still larger). cannam@95: - These options require a compiler supporting SIMD extensions, cannam@95: and compiler support is always a bit flaky: see the FFTW FAQ cannam@95: for a list of compiler versions that have problems compiling cannam@95: FFTW. cannam@95: cannam@95: - With AltiVec and `gcc', you may have to use the cannam@95: `-mabi=altivec' option when compiling any code that links to cannam@95: FFTW, in order to properly align the stack; otherwise, FFTW cannam@95: could crash when it tries to use an AltiVec feature. (This cannam@95: is not necessary on MacOS X.) cannam@95: cannam@95: - With SSE/SSE2 and `gcc', you should use a version of gcc that cannam@95: properly aligns the stack when compiling any code that links cannam@95: to FFTW. By default, `gcc' 2.95 and later versions align the cannam@95: stack as needed, but you should not compile FFTW with the cannam@95: `-Os' option or the `-mpreferred-stack-boundary' option with cannam@95: an argument less than 4. cannam@95: cannam@95: - Because of the large variety of ARM processors and ABIs, FFTW cannam@95: does not attempt to guess the correct `gcc' flags for cannam@95: generating NEON code. In general, you will have to provide cannam@95: them on the command line. This command line is known to have cannam@95: worked at least once: cannam@95: ./configure --with-slow-timer --host=arm-linux-gnueabi \ cannam@95: --enable-single --enable-neon \ cannam@95: "CC=arm-linux-gnueabi-gcc -march=armv7-a -mfloat-abi=softfp" cannam@95: cannam@95: cannam@95: To force `configure' to use a particular C compiler foo (instead of cannam@95: the default, usually `gcc'), pass `CC='foo to the `configure' script; cannam@95: you may also need to set the flags via the variable `CFLAGS' as cannam@95: described above. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Installation on non-Unix systems, Next: Cycle Counters, Prev: Installation on Unix, Up: Installation and Customization cannam@95: cannam@95: 10.2 Installation on non-Unix systems cannam@95: ===================================== cannam@95: cannam@95: It should be relatively straightforward to compile FFTW even on non-Unix cannam@95: systems lacking the niceties of a `configure' script. Basically, you cannam@95: need to edit the `config.h' header (copy it from `config.h.in') to cannam@95: `#define' the various options and compiler characteristics, and then cannam@95: compile all the `.c' files in the relevant directories. cannam@95: cannam@95: The `config.h' header contains about 100 options to set, each one cannam@95: initially an `#undef', each documented with a comment, and most of them cannam@95: fairly obvious. For most of the options, you should simply `#define' cannam@95: them to `1' if they are applicable, although a few options require a cannam@95: particular value (e.g. `SIZEOF_LONG_LONG' should be defined to the size cannam@95: of the `long long' type, in bytes, or zero if it is not supported). We cannam@95: will likely post some sample `config.h' files for various operating cannam@95: systems and compilers for you to use (at least as a starting point). cannam@95: Please let us know if you have to hand-create a configuration file cannam@95: (and/or a pre-compiled binary) that you want to share. cannam@95: cannam@95: To create the FFTW library, you will then need to compile all of the cannam@95: `.c' files in the `kernel', `dft', `dft/scalar', `dft/scalar/codelets', cannam@95: `rdft', `rdft/scalar', `rdft/scalar/r2cf', `rdft/scalar/r2cb', cannam@95: `rdft/scalar/r2r', `reodft', and `api' directories. If you are cannam@95: compiling with SIMD support (e.g. you defined `HAVE_SSE2' in cannam@95: `config.h'), then you also need to compile the `.c' files in the cannam@95: `simd-support', `{dft,rdft}/simd', `{dft,rdft}/simd/*' directories. cannam@95: cannam@95: Once these files are all compiled, link them into a library, or a cannam@95: shared library, or directly into your program. cannam@95: cannam@95: To compile the FFTW test program, additionally compile the code in cannam@95: the `libbench2/' directory, and link it into a library. Then compile cannam@95: the code in the `tests/' directory and link it to the `libbench2' and cannam@95: FFTW libraries. To compile the `fftw-wisdom' (command-line) tool cannam@95: (*note Wisdom Utilities::), compile `tools/fftw-wisdom.c' and link it cannam@95: to the `libbench2' and FFTW libraries cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Cycle Counters, Next: Generating your own code, Prev: Installation on non-Unix systems, Up: Installation and Customization cannam@95: cannam@95: 10.3 Cycle Counters cannam@95: =================== cannam@95: cannam@95: FFTW's planner actually executes and times different possible FFT cannam@95: algorithms in order to pick the fastest plan for a given n. In order cannam@95: to do this in as short a time as possible, however, the timer must have cannam@95: a very high resolution, and to accomplish this we employ the hardware cannam@95: "cycle counters" that are available on most CPUs. Currently, FFTW cannam@95: supports the cycle counters on x86, PowerPC/POWER, Alpha, UltraSPARC cannam@95: (SPARC v9), IA64, PA-RISC, and MIPS processors. cannam@95: cannam@95: Access to the cycle counters, unfortunately, is a compiler and/or cannam@95: operating-system dependent task, often requiring inline assembly cannam@95: language, and it may be that your compiler is not supported. If you are cannam@95: _not_ supported, FFTW will by default fall back on its estimator cannam@95: (effectively using `FFTW_ESTIMATE' for all plans). cannam@95: cannam@95: You can add support by editing the file `kernel/cycle.h'; normally, cannam@95: this will involve adapting one of the examples already present in order cannam@95: to use the inline-assembler syntax for your C compiler, and will only cannam@95: require a couple of lines of code. Anyone adding support for a new cannam@95: system to `cycle.h' is encouraged to email us at . cannam@95: cannam@95: If a cycle counter is not available on your system (e.g. some cannam@95: embedded processor), and you don't want to use estimated plans, as a cannam@95: last resort you can use the `--with-slow-timer' option to `configure' cannam@95: (on Unix) or `#define WITH_SLOW_TIMER' in `config.h' (elsewhere). This cannam@95: will use the much lower-resolution `gettimeofday' function, or even cannam@95: `clock' if the former is unavailable, and planning will be extremely cannam@95: slow. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Generating your own code, Prev: Cycle Counters, Up: Installation and Customization cannam@95: cannam@95: 10.4 Generating your own code cannam@95: ============================= cannam@95: cannam@95: The directory `genfft' contains the programs that were used to generate cannam@95: FFTW's "codelets," which are hard-coded transforms of small sizes. We cannam@95: do not expect casual users to employ the generator, which is a rather cannam@95: sophisticated program that generates directed acyclic graphs of FFT cannam@95: algorithms and performs algebraic simplifications on them. It was cannam@95: written in Objective Caml, a dialect of ML, which is available at cannam@95: `http://caml.inria.fr/ocaml/index.en.html'. cannam@95: cannam@95: If you have Objective Caml installed (along with recent versions of cannam@95: GNU `autoconf', `automake', and `libtool'), then you can change the set cannam@95: of codelets that are generated or play with the generation options. cannam@95: The set of generated codelets is specified by the cannam@95: `{dft,rdft}/{codelets,simd}/*/Makefile.am' files. For example, you can cannam@95: add efficient REDFT codelets of small sizes by modifying cannam@95: `rdft/codelets/r2r/Makefile.am'. After you modify any `Makefile.am' cannam@95: files, you can type `sh bootstrap.sh' in the top-level directory cannam@95: followed by `make' to re-generate the files. cannam@95: cannam@95: We do not provide more details about the code-generation process, cannam@95: since we do not expect that most users will need to generate their own cannam@95: code. However, feel free to contact us at if you are cannam@95: interested in the subject. cannam@95: cannam@95: You might find it interesting to learn Caml and/or some modern cannam@95: programming techniques that we used in the generator (including monadic cannam@95: programming), especially if you heard the rumor that Java and cannam@95: object-oriented programming are the latest advancement in the field. cannam@95: The internal operation of the codelet generator is described in the cannam@95: paper, "A Fast Fourier Transform Compiler," by M. Frigo, which is cannam@95: available from the FFTW home page (http://www.fftw.org) and also cannam@95: appeared in the `Proceedings of the 1999 ACM SIGPLAN Conference on cannam@95: Programming Language Design and Implementation (PLDI)'. cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: Acknowledgments, Next: License and Copyright, Prev: Installation and Customization, Up: Top cannam@95: cannam@95: 11 Acknowledgments cannam@95: ****************** cannam@95: cannam@95: Matteo Frigo was supported in part by the Special Research Program SFB cannam@95: F011 "AURORA" of the Austrian Science Fund FWF and by MIT Lincoln cannam@95: Laboratory. For previous versions of FFTW, he was supported in part by cannam@95: the Defense Advanced Research Projects Agency (DARPA), under Grants cannam@95: N00014-94-1-0985 and F30602-97-1-0270, and by a Digital Equipment cannam@95: Corporation Fellowship. cannam@95: cannam@95: Steven G. Johnson was supported in part by a Dept. of Defense NDSEG cannam@95: Fellowship, an MIT Karl Taylor Compton Fellowship, and by the Materials cannam@95: Research Science and Engineering Center program of the National Science cannam@95: Foundation under award DMR-9400334. cannam@95: cannam@95: Code for the Cell Broadband Engine was graciously donated to the FFTW cannam@95: project by the IBM Austin Research Lab and included in fftw-3.2. (This cannam@95: code was removed in fftw-3.3.) cannam@95: cannam@95: Code for the MIPS paired-single SIMD support was graciously donated cannam@95: to the FFTW project by CodeSourcery, Inc. cannam@95: cannam@95: We are grateful to Sun Microsystems Inc. for its donation of a cannam@95: cluster of 9 8-processor Ultra HPC 5000 SMPs (24 Gflops peak). These cannam@95: machines served as the primary platform for the development of early cannam@95: versions of FFTW. cannam@95: cannam@95: We thank Intel Corporation for donating a four-processor Pentium Pro cannam@95: machine. We thank the GNU/Linux community for giving us a decent OS to cannam@95: run on that machine. cannam@95: cannam@95: We are thankful to the AMD corporation for donating an AMD Athlon XP cannam@95: 1700+ computer to the FFTW project. cannam@95: cannam@95: We thank the Compaq/HP testdrive program and VA Software Corporation cannam@95: (SourceForge.net) for providing remote access to machines that were used cannam@95: to test FFTW. cannam@95: cannam@95: The `genfft' suite of code generators was written using Objective cannam@95: Caml, a dialect of ML. Objective Caml is a small and elegant language cannam@95: developed by Xavier Leroy. The implementation is available from cannam@95: `http://caml.inria.fr/' (http://caml.inria.fr/). In previous releases cannam@95: of FFTW, `genfft' was written in Caml Light, by the same authors. An cannam@95: even earlier implementation of `genfft' was written in Scheme, but Caml cannam@95: is definitely better for this kind of application. cannam@95: cannam@95: FFTW uses many tools from the GNU project, including `automake', cannam@95: `texinfo', and `libtool'. cannam@95: cannam@95: Prof. Charles E. Leiserson of MIT provided continuous support and cannam@95: encouragement. This program would not exist without him. Charles also cannam@95: proposed the name "codelets" for the basic FFT blocks. cannam@95: cannam@95: Prof. John D. Joannopoulos of MIT demonstrated continuing tolerance cannam@95: of Steven's "extra-curricular" computer-science activities, as well as cannam@95: remarkable creativity in working them into his grant proposals. cannam@95: Steven's physics degree would not exist without him. cannam@95: cannam@95: Franz Franchetti wrote SIMD extensions to FFTW 2, which eventually cannam@95: led to the SIMD support in FFTW 3. cannam@95: cannam@95: Stefan Kral wrote most of the K7 code generator distributed with FFTW cannam@95: 3.0.x and 3.1.x. cannam@95: cannam@95: Andrew Sterian contributed the Windows timing code in FFTW 2. cannam@95: cannam@95: Didier Miras reported a bug in the test procedure used in FFTW 1.2. cannam@95: We now use a completely different test algorithm by Funda Ergun that cannam@95: does not require a separate FFT program to compare against. cannam@95: cannam@95: Wolfgang Reimer contributed the Pentium cycle counter and a few fixes cannam@95: that help portability. cannam@95: cannam@95: Ming-Chang Liu uncovered a well-hidden bug in the complex transforms cannam@95: of FFTW 2.0 and supplied a patch to correct it. cannam@95: cannam@95: The FFTW FAQ was written in `bfnn' (Bizarre Format With No Name) and cannam@95: formatted using the tools developed by Ian Jackson for the Linux FAQ. cannam@95: cannam@95: _We are especially thankful to all of our users for their continuing cannam@95: support, feedback, and interest during our development of FFTW._ cannam@95: cannam@95:  cannam@95: File: fftw3.info, Node: License and Copyright, Next: Concept Index, Prev: Acknowledgments, Up: Top cannam@95: cannam@95: 12 License and Copyright cannam@95: ************************ cannam@95: cannam@95: FFTW is Copyright (C) 2003, 2007-11 Matteo Frigo, Copyright (C) 2003, cannam@95: 2007-11 Massachusetts Institute of Technology. cannam@95: cannam@95: FFTW is free software; you can redistribute it and/or modify it cannam@95: under the terms of the GNU General Public License as published by the cannam@95: Free Software Foundation; either version 2 of the License, or (at your cannam@95: option) any later version. cannam@95: cannam@95: This program is distributed in the hope that it will be useful, but cannam@95: WITHOUT ANY WARRANTY; without even the implied warranty of cannam@95: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU cannam@95: General Public License for more details. cannam@95: cannam@95: You should have received a copy of the GNU General Public License cannam@95: along with this program; if not, write to the Free Software Foundation, cannam@95: Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA You cannam@95: can also find the GPL on the GNU web site cannam@95: (http://www.gnu.org/licenses/gpl-2.0.html). cannam@95: cannam@95: In addition, we kindly ask you to acknowledge FFTW and its authors in cannam@95: any program or publication in which you use FFTW. (You are not cannam@95: _required_ to do so; it is up to your common sense to decide whether cannam@95: you want to comply with this request or not.) For general cannam@95: publications, we suggest referencing: Matteo Frigo and Steven G. cannam@95: Johnson, "The design and implementation of FFTW3," Proc. IEEE 93 (2), cannam@95: 216-231 (2005). cannam@95: cannam@95: Non-free versions of FFTW are available under terms different from cannam@95: those of the General Public License. (e.g. they do not require you to cannam@95: accompany any object code using FFTW with the corresponding source cannam@95: code.) For these alternative terms you must purchase a license from cannam@95: MIT's Technology Licensing Office. Users interested in such a license cannam@95: should contact us () for more information. cannam@95: