annotate src/fftw-3.3.8/doc/other.texi @ 169:223a55898ab9 tip default

Add null config files
author Chris Cannam <cannam@all-day-breakfast.com>
date Mon, 02 Mar 2020 14:03:47 +0000
parents bd3cc4d1df30
children
rev   line source
cannam@167 1 @node Other Important Topics, FFTW Reference, Tutorial, Top
cannam@167 2 @chapter Other Important Topics
cannam@167 3 @menu
cannam@167 4 * SIMD alignment and fftw_malloc::
cannam@167 5 * Multi-dimensional Array Format::
cannam@167 6 * Words of Wisdom-Saving Plans::
cannam@167 7 * Caveats in Using Wisdom::
cannam@167 8 @end menu
cannam@167 9
cannam@167 10 @c ------------------------------------------------------------
cannam@167 11 @node SIMD alignment and fftw_malloc, Multi-dimensional Array Format, Other Important Topics, Other Important Topics
cannam@167 12 @section SIMD alignment and fftw_malloc
cannam@167 13
cannam@167 14 SIMD, which stands for ``Single Instruction Multiple Data,'' is a set of
cannam@167 15 special operations supported by some processors to perform a single
cannam@167 16 operation on several numbers (usually 2 or 4) simultaneously. SIMD
cannam@167 17 floating-point instructions are available on several popular CPUs:
cannam@167 18 SSE/SSE2/AVX/AVX2/AVX512/KCVI on some x86/x86-64 processors, AltiVec and
cannam@167 19 VSX on some POWER/PowerPCs, NEON on some ARM models. FFTW can be
cannam@167 20 compiled to support the SIMD instructions on any of these systems.
cannam@167 21 @cindex SIMD
cannam@167 22 @cindex SSE
cannam@167 23 @cindex SSE2
cannam@167 24 @cindex AVX
cannam@167 25 @cindex AVX2
cannam@167 26 @cindex AVX512
cannam@167 27 @cindex AltiVec
cannam@167 28 @cindex VSX
cannam@167 29 @cindex precision
cannam@167 30
cannam@167 31
cannam@167 32 A program linking to an FFTW library compiled with SIMD support can
cannam@167 33 obtain a nonnegligible speedup for most complex and r2c/c2r
cannam@167 34 transforms. In order to obtain this speedup, however, the arrays of
cannam@167 35 complex (or real) data passed to FFTW must be specially aligned in
cannam@167 36 memory (typically 16-byte aligned), and often this alignment is more
cannam@167 37 stringent than that provided by the usual @code{malloc} (etc.)
cannam@167 38 allocation routines.
cannam@167 39
cannam@167 40 @cindex portability
cannam@167 41 In order to guarantee proper alignment for SIMD, therefore, in case
cannam@167 42 your program is ever linked against a SIMD-using FFTW, we recommend
cannam@167 43 allocating your transform data with @code{fftw_malloc} and
cannam@167 44 de-allocating it with @code{fftw_free}.
cannam@167 45 @findex fftw_malloc
cannam@167 46 @findex fftw_free
cannam@167 47 These have exactly the same interface and behavior as
cannam@167 48 @code{malloc}/@code{free}, except that for a SIMD FFTW they ensure
cannam@167 49 that the returned pointer has the necessary alignment (by calling
cannam@167 50 @code{memalign} or its equivalent on your OS).
cannam@167 51
cannam@167 52 You are not @emph{required} to use @code{fftw_malloc}. You can
cannam@167 53 allocate your data in any way that you like, from @code{malloc} to
cannam@167 54 @code{new} (in C++) to a fixed-size array declaration. If the array
cannam@167 55 happens not to be properly aligned, FFTW will not use the SIMD
cannam@167 56 extensions.
cannam@167 57 @cindex C++
cannam@167 58
cannam@167 59 @findex fftw_alloc_real
cannam@167 60 @findex fftw_alloc_complex
cannam@167 61 Since @code{fftw_malloc} only ever needs to be used for real and
cannam@167 62 complex arrays, we provide two convenient wrapper routines
cannam@167 63 @code{fftw_alloc_real(N)} and @code{fftw_alloc_complex(N)} that are
cannam@167 64 equivalent to @code{(double*)fftw_malloc(sizeof(double) * N)} and
cannam@167 65 @code{(fftw_complex*)fftw_malloc(sizeof(fftw_complex) * N)},
cannam@167 66 respectively (or their equivalents in other precisions).
cannam@167 67
cannam@167 68 @c ------------------------------------------------------------
cannam@167 69 @node Multi-dimensional Array Format, Words of Wisdom-Saving Plans, SIMD alignment and fftw_malloc, Other Important Topics
cannam@167 70 @section Multi-dimensional Array Format
cannam@167 71
cannam@167 72 This section describes the format in which multi-dimensional arrays
cannam@167 73 are stored in FFTW. We felt that a detailed discussion of this topic
cannam@167 74 was necessary. Since several different formats are common, this topic
cannam@167 75 is often a source of confusion.
cannam@167 76
cannam@167 77 @menu
cannam@167 78 * Row-major Format::
cannam@167 79 * Column-major Format::
cannam@167 80 * Fixed-size Arrays in C::
cannam@167 81 * Dynamic Arrays in C::
cannam@167 82 * Dynamic Arrays in C-The Wrong Way::
cannam@167 83 @end menu
cannam@167 84
cannam@167 85 @c =========>
cannam@167 86 @node Row-major Format, Column-major Format, Multi-dimensional Array Format, Multi-dimensional Array Format
cannam@167 87 @subsection Row-major Format
cannam@167 88 @cindex row-major
cannam@167 89
cannam@167 90 The multi-dimensional arrays passed to @code{fftw_plan_dft} etcetera
cannam@167 91 are expected to be stored as a single contiguous block in
cannam@167 92 @dfn{row-major} order (sometimes called ``C order''). Basically, this
cannam@167 93 means that as you step through adjacent memory locations, the first
cannam@167 94 dimension's index varies most slowly and the last dimension's index
cannam@167 95 varies most quickly.
cannam@167 96
cannam@167 97 To be more explicit, let us consider an array of rank @math{d} whose
cannam@167 98 dimensions are @ndims{}. Now, we specify a location in the array by a
cannam@167 99 sequence of @math{d} (zero-based) indices, one for each dimension:
cannam@167 100 @tex
cannam@167 101 $(i_0, i_1, i_2, \ldots, i_{d-1})$.
cannam@167 102 @end tex
cannam@167 103 @ifinfo
cannam@167 104 (i[0], i[1], ..., i[d-1]).
cannam@167 105 @end ifinfo
cannam@167 106 @html
cannam@167 107 (i<sub>0</sub>, i<sub>1</sub>, i<sub>2</sub>,..., i<sub>d-1</sub>).
cannam@167 108 @end html
cannam@167 109 If the array is stored in row-major
cannam@167 110 order, then this element is located at the position
cannam@167 111 @tex
cannam@167 112 $i_{d-1} + n_{d-1} (i_{d-2} + n_{d-2} (\ldots + n_1 i_0))$.
cannam@167 113 @end tex
cannam@167 114 @ifinfo
cannam@167 115 i[d-1] + n[d-1] * (i[d-2] + n[d-2] * (... + n[1] * i[0])).
cannam@167 116 @end ifinfo
cannam@167 117 @html
cannam@167 118 i<sub>d-1</sub> + n<sub>d-1</sub> * (i<sub>d-2</sub> + n<sub>d-2</sub> * (... + n<sub>1</sub> * i<sub>0</sub>)).
cannam@167 119 @end html
cannam@167 120
cannam@167 121 Note that, for the ordinary complex DFT, each element of the array
cannam@167 122 must be of type @code{fftw_complex}; i.e. a (real, imaginary) pair of
cannam@167 123 (double-precision) numbers.
cannam@167 124
cannam@167 125 In the advanced FFTW interface, the physical dimensions @math{n} from
cannam@167 126 which the indices are computed can be different from (larger than)
cannam@167 127 the logical dimensions of the transform to be computed, in order to
cannam@167 128 transform a subset of a larger array.
cannam@167 129 @cindex advanced interface
cannam@167 130 Note also that, in the advanced interface, the expression above is
cannam@167 131 multiplied by a @dfn{stride} to get the actual array index---this is
cannam@167 132 useful in situations where each element of the multi-dimensional array
cannam@167 133 is actually a data structure (or another array), and you just want to
cannam@167 134 transform a single field. In the basic interface, however, the stride
cannam@167 135 is 1.
cannam@167 136 @cindex stride
cannam@167 137
cannam@167 138 @c =========>
cannam@167 139 @node Column-major Format, Fixed-size Arrays in C, Row-major Format, Multi-dimensional Array Format
cannam@167 140 @subsection Column-major Format
cannam@167 141 @cindex column-major
cannam@167 142
cannam@167 143 Readers from the Fortran world are used to arrays stored in
cannam@167 144 @dfn{column-major} order (sometimes called ``Fortran order''). This is
cannam@167 145 essentially the exact opposite of row-major order in that, here, the
cannam@167 146 @emph{first} dimension's index varies most quickly.
cannam@167 147
cannam@167 148 If you have an array stored in column-major order and wish to
cannam@167 149 transform it using FFTW, it is quite easy to do. When creating the
cannam@167 150 plan, simply pass the dimensions of the array to the planner in
cannam@167 151 @emph{reverse order}. For example, if your array is a rank three
cannam@167 152 @code{N x M x L} matrix in column-major order, you should pass the
cannam@167 153 dimensions of the array as if it were an @code{L x M x N} matrix
cannam@167 154 (which it is, from the perspective of FFTW). This is done for you
cannam@167 155 @emph{automatically} by the FFTW legacy-Fortran interface
cannam@167 156 (@pxref{Calling FFTW from Legacy Fortran}), but you must do it
cannam@167 157 manually with the modern Fortran interface (@pxref{Reversing array
cannam@167 158 dimensions}).
cannam@167 159 @cindex Fortran interface
cannam@167 160
cannam@167 161 @c =========>
cannam@167 162 @node Fixed-size Arrays in C, Dynamic Arrays in C, Column-major Format, Multi-dimensional Array Format
cannam@167 163 @subsection Fixed-size Arrays in C
cannam@167 164 @cindex C multi-dimensional arrays
cannam@167 165
cannam@167 166 A multi-dimensional array whose size is declared at compile time in C
cannam@167 167 is @emph{already} in row-major order. You don't have to do anything
cannam@167 168 special to transform it. For example:
cannam@167 169
cannam@167 170 @example
cannam@167 171 @{
cannam@167 172 fftw_complex data[N0][N1][N2];
cannam@167 173 fftw_plan plan;
cannam@167 174 ...
cannam@167 175 plan = fftw_plan_dft_3d(N0, N1, N2, &data[0][0][0], &data[0][0][0],
cannam@167 176 FFTW_FORWARD, FFTW_ESTIMATE);
cannam@167 177 ...
cannam@167 178 @}
cannam@167 179 @end example
cannam@167 180
cannam@167 181 This will plan a 3d in-place transform of size @code{N0 x N1 x N2}.
cannam@167 182 Notice how we took the address of the zero-th element to pass to the
cannam@167 183 planner (we could also have used a typecast).
cannam@167 184
cannam@167 185 However, we tend to @emph{discourage} users from declaring their
cannam@167 186 arrays in this way, for two reasons. First, this allocates the array
cannam@167 187 on the stack (``automatic'' storage), which has a very limited size on
cannam@167 188 most operating systems (declaring an array with more than a few
cannam@167 189 thousand elements will often cause a crash). (You can get around this
cannam@167 190 limitation on many systems by declaring the array as
cannam@167 191 @code{static} and/or global, but that has its own drawbacks.)
cannam@167 192 Second, it may not optimally align the array for use with a SIMD
cannam@167 193 FFTW (@pxref{SIMD alignment and fftw_malloc}). Instead, we recommend
cannam@167 194 using @code{fftw_malloc}, as described below.
cannam@167 195
cannam@167 196 @c =========>
cannam@167 197 @node Dynamic Arrays in C, Dynamic Arrays in C-The Wrong Way, Fixed-size Arrays in C, Multi-dimensional Array Format
cannam@167 198 @subsection Dynamic Arrays in C
cannam@167 199
cannam@167 200 We recommend allocating most arrays dynamically, with
cannam@167 201 @code{fftw_malloc}. This isn't too hard to do, although it is not as
cannam@167 202 straightforward for multi-dimensional arrays as it is for
cannam@167 203 one-dimensional arrays.
cannam@167 204
cannam@167 205 Creating the array is simple: using a dynamic-allocation routine like
cannam@167 206 @code{fftw_malloc}, allocate an array big enough to store N
cannam@167 207 @code{fftw_complex} values (for a complex DFT), where N is the product
cannam@167 208 of the sizes of the array dimensions (i.e. the total number of complex
cannam@167 209 values in the array). For example, here is code to allocate a
cannam@167 210 @threedims{5,12,27} rank-3 array:
cannam@167 211 @findex fftw_malloc
cannam@167 212
cannam@167 213 @example
cannam@167 214 fftw_complex *an_array;
cannam@167 215 an_array = (fftw_complex*) fftw_malloc(5*12*27 * sizeof(fftw_complex));
cannam@167 216 @end example
cannam@167 217
cannam@167 218 Accessing the array elements, however, is more tricky---you can't
cannam@167 219 simply use multiple applications of the @samp{[]} operator like you
cannam@167 220 could for fixed-size arrays. Instead, you have to explicitly compute
cannam@167 221 the offset into the array using the formula given earlier for
cannam@167 222 row-major arrays. For example, to reference the @math{(i,j,k)}-th
cannam@167 223 element of the array allocated above, you would use the expression
cannam@167 224 @code{an_array[k + 27 * (j + 12 * i)]}.
cannam@167 225
cannam@167 226 This pain can be alleviated somewhat by defining appropriate macros,
cannam@167 227 or, in C++, creating a class and overloading the @samp{()} operator.
cannam@167 228 The recent C99 standard provides a way to reinterpret the dynamic
cannam@167 229 array as a ``variable-length'' multi-dimensional array amenable to
cannam@167 230 @samp{[]}, but this feature is not yet widely supported by compilers.
cannam@167 231 @cindex C99
cannam@167 232 @cindex C++
cannam@167 233
cannam@167 234 @c =========>
cannam@167 235 @node Dynamic Arrays in C-The Wrong Way, , Dynamic Arrays in C, Multi-dimensional Array Format
cannam@167 236 @subsection Dynamic Arrays in C---The Wrong Way
cannam@167 237
cannam@167 238 A different method for allocating multi-dimensional arrays in C is
cannam@167 239 often suggested that is incompatible with FFTW: @emph{using it will
cannam@167 240 cause FFTW to die a painful death}. We discuss the technique here,
cannam@167 241 however, because it is so commonly known and used. This method is to
cannam@167 242 create arrays of pointers of arrays of pointers of @dots{}etcetera.
cannam@167 243 For example, the analogue in this method to the example above is:
cannam@167 244
cannam@167 245 @example
cannam@167 246 int i,j;
cannam@167 247 fftw_complex ***a_bad_array; /* @r{another way to make a 5x12x27 array} */
cannam@167 248
cannam@167 249 a_bad_array = (fftw_complex ***) malloc(5 * sizeof(fftw_complex **));
cannam@167 250 for (i = 0; i < 5; ++i) @{
cannam@167 251 a_bad_array[i] =
cannam@167 252 (fftw_complex **) malloc(12 * sizeof(fftw_complex *));
cannam@167 253 for (j = 0; j < 12; ++j)
cannam@167 254 a_bad_array[i][j] =
cannam@167 255 (fftw_complex *) malloc(27 * sizeof(fftw_complex));
cannam@167 256 @}
cannam@167 257 @end example
cannam@167 258
cannam@167 259 As you can see, this sort of array is inconvenient to allocate (and
cannam@167 260 deallocate). On the other hand, it has the advantage that the
cannam@167 261 @math{(i,j,k)}-th element can be referenced simply by
cannam@167 262 @code{a_bad_array[i][j][k]}.
cannam@167 263
cannam@167 264 If you like this technique and want to maximize convenience in accessing
cannam@167 265 the array, but still want to pass the array to FFTW, you can use a
cannam@167 266 hybrid method. Allocate the array as one contiguous block, but also
cannam@167 267 declare an array of arrays of pointers that point to appropriate places
cannam@167 268 in the block. That sort of trick is beyond the scope of this
cannam@167 269 documentation; for more information on multi-dimensional arrays in C,
cannam@167 270 see the @code{comp.lang.c}
cannam@167 271 @uref{http://c-faq.com/aryptr/dynmuldimary.html, FAQ}.
cannam@167 272
cannam@167 273 @c ------------------------------------------------------------
cannam@167 274 @node Words of Wisdom-Saving Plans, Caveats in Using Wisdom, Multi-dimensional Array Format, Other Important Topics
cannam@167 275 @section Words of Wisdom---Saving Plans
cannam@167 276 @cindex wisdom
cannam@167 277 @cindex saving plans to disk
cannam@167 278
cannam@167 279 FFTW implements a method for saving plans to disk and restoring them.
cannam@167 280 In fact, what FFTW does is more general than just saving and loading
cannam@167 281 plans. The mechanism is called @dfn{wisdom}. Here, we describe
cannam@167 282 this feature at a high level. @xref{FFTW Reference}, for a less casual
cannam@167 283 but more complete discussion of how to use wisdom in FFTW.
cannam@167 284
cannam@167 285 Plans created with the @code{FFTW_MEASURE}, @code{FFTW_PATIENT}, or
cannam@167 286 @code{FFTW_EXHAUSTIVE} options produce near-optimal FFT performance,
cannam@167 287 but may require a long time to compute because FFTW must measure the
cannam@167 288 runtime of many possible plans and select the best one. This setup is
cannam@167 289 designed for the situations where so many transforms of the same size
cannam@167 290 must be computed that the start-up time is irrelevant. For short
cannam@167 291 initialization times, but slower transforms, we have provided
cannam@167 292 @code{FFTW_ESTIMATE}. The @code{wisdom} mechanism is a way to get the
cannam@167 293 best of both worlds: you compute a good plan once, save it to
cannam@167 294 disk, and later reload it as many times as necessary. The wisdom
cannam@167 295 mechanism can actually save and reload many plans at once, not just
cannam@167 296 one.
cannam@167 297 @ctindex FFTW_MEASURE
cannam@167 298 @ctindex FFTW_PATIENT
cannam@167 299 @ctindex FFTW_EXHAUSTIVE
cannam@167 300 @ctindex FFTW_ESTIMATE
cannam@167 301
cannam@167 302
cannam@167 303 Whenever you create a plan, the FFTW planner accumulates wisdom, which
cannam@167 304 is information sufficient to reconstruct the plan. After planning,
cannam@167 305 you can save this information to disk by means of the function:
cannam@167 306 @example
cannam@167 307 int fftw_export_wisdom_to_filename(const char *filename);
cannam@167 308 @end example
cannam@167 309 @findex fftw_export_wisdom_to_filename
cannam@167 310 (This function returns non-zero on success.)
cannam@167 311
cannam@167 312 The next time you run the program, you can restore the wisdom with
cannam@167 313 @code{fftw_import_wisdom_from_filename} (which also returns non-zero on success),
cannam@167 314 and then recreate the plan using the same flags as before.
cannam@167 315 @example
cannam@167 316 int fftw_import_wisdom_from_filename(const char *filename);
cannam@167 317 @end example
cannam@167 318 @findex fftw_import_wisdom_from_filename
cannam@167 319
cannam@167 320 Wisdom is automatically used for any size to which it is applicable, as
cannam@167 321 long as the planner flags are not more ``patient'' than those with which
cannam@167 322 the wisdom was created. For example, wisdom created with
cannam@167 323 @code{FFTW_MEASURE} can be used if you later plan with
cannam@167 324 @code{FFTW_ESTIMATE} or @code{FFTW_MEASURE}, but not with
cannam@167 325 @code{FFTW_PATIENT}.
cannam@167 326
cannam@167 327 The @code{wisdom} is cumulative, and is stored in a global, private
cannam@167 328 data structure managed internally by FFTW. The storage space required
cannam@167 329 is minimal, proportional to the logarithm of the sizes the wisdom was
cannam@167 330 generated from. If memory usage is a concern, however, the wisdom can
cannam@167 331 be forgotten and its associated memory freed by calling:
cannam@167 332 @example
cannam@167 333 void fftw_forget_wisdom(void);
cannam@167 334 @end example
cannam@167 335 @findex fftw_forget_wisdom
cannam@167 336
cannam@167 337 Wisdom can be exported to a file, a string, or any other medium.
cannam@167 338 For details, see @ref{Wisdom}.
cannam@167 339
cannam@167 340 @node Caveats in Using Wisdom, , Words of Wisdom-Saving Plans, Other Important Topics
cannam@167 341 @section Caveats in Using Wisdom
cannam@167 342 @cindex wisdom, problems with
cannam@167 343
cannam@167 344 @quotation
cannam@167 345 @html
cannam@167 346 <i>
cannam@167 347 @end html
cannam@167 348 For in much wisdom is much grief, and he that increaseth knowledge
cannam@167 349 increaseth sorrow.
cannam@167 350 @html
cannam@167 351 </i>
cannam@167 352 @end html
cannam@167 353 [Ecclesiastes 1:18]
cannam@167 354 @cindex Ecclesiastes
cannam@167 355 @end quotation
cannam@167 356 @iftex
cannam@167 357 @medskip
cannam@167 358 @end iftex
cannam@167 359
cannam@167 360 @cindex portability
cannam@167 361 There are pitfalls to using wisdom, in that it can negate FFTW's
cannam@167 362 ability to adapt to changing hardware and other conditions. For
cannam@167 363 example, it would be perfectly possible to export wisdom from a
cannam@167 364 program running on one processor and import it into a program running
cannam@167 365 on another processor. Doing so, however, would mean that the second
cannam@167 366 program would use plans optimized for the first processor, instead of
cannam@167 367 the one it is running on.
cannam@167 368
cannam@167 369 It should be safe to reuse wisdom as long as the hardware and program
cannam@167 370 binaries remain unchanged. (Actually, the optimal plan may change even
cannam@167 371 between runs of the same binary on identical hardware, due to
cannam@167 372 differences in the virtual memory environment, etcetera. Users
cannam@167 373 seriously interested in performance should worry about this problem,
cannam@167 374 too.) It is likely that, if the same wisdom is used for two
cannam@167 375 different program binaries, even running on the same machine, the
cannam@167 376 plans may be sub-optimal because of differing code alignments. It is
cannam@167 377 therefore wise to recreate wisdom every time an application is
cannam@167 378 recompiled. The more the underlying hardware and software changes
cannam@167 379 between the creation of wisdom and its use, the greater grows
cannam@167 380 the risk of sub-optimal plans.
cannam@167 381
cannam@167 382 Nevertheless, if the choice is between using @code{FFTW_ESTIMATE} or
cannam@167 383 using possibly-suboptimal wisdom (created on the same machine, but for a
cannam@167 384 different binary), the wisdom is likely to be better. For this reason,
cannam@167 385 we provide a function to import wisdom from a standard system-wide
cannam@167 386 location (@code{/etc/fftw/wisdom} on Unix):
cannam@167 387 @cindex wisdom, system-wide
cannam@167 388
cannam@167 389 @example
cannam@167 390 int fftw_import_system_wisdom(void);
cannam@167 391 @end example
cannam@167 392 @findex fftw_import_system_wisdom
cannam@167 393
cannam@167 394 FFTW also provides a standalone program, @code{fftw-wisdom} (described
cannam@167 395 by its own @code{man} page on Unix) with which users can create wisdom,
cannam@167 396 e.g. for a canonical set of sizes to store in the system wisdom file.
cannam@167 397 @xref{Wisdom Utilities}.
cannam@167 398 @cindex fftw-wisdom utility
cannam@167 399