### Testing FFTW Library Source: https://www.fftw.org/install/fftw-3.0.1BC_installation Guides on how to test the installed FFTW library. This includes using the 'check.pl' script with Perl for random tests and the 'bench' command-line tool for specific problem size and type tests. ```bash perl check.pl --random bench -y irf256x256 ``` -------------------------------- ### Multi-threaded FFTW Setup in Fortran Source: https://www.fftw.org/doc/Fortran-Examples Initializes FFTW for multi-threaded execution and sets the number of threads to use for planning. Requires FFTW library compiled with thread support. Returns an integer status code. ```fortran integer iret call dfftw_init_threads(iret) call dfftw_plan_with_nthreads(8) ``` -------------------------------- ### Configure FFTW with SIMD Instruction Sets (Example: NEON) Source: https://www.fftw.org/doc/Installation-on-Unix Enables various SIMD instruction sets for performance optimization. This example shows how to configure FFTW with single precision and NEON support for ARM architecture, specifying custom GCC flags for compilation. The library attempts to detect CPU support at runtime. ```bash ./configure --with-slow-timer --host=arm-linux-gnueabi \ --enable-single --enable-neon \ "CC=arm-linux-gnueabi-gcc -march=armv7-a -mfloat-abi=softfp" ``` -------------------------------- ### Basic FFTW Installation on Unix Source: https://www.fftw.org/fftw2_doc/fftw_6 Standard commands to configure, build, and install FFTW on Unix-like systems. This process builds the default complex and real transform libraries and associated test programs. ```bash ./configure make make install ``` -------------------------------- ### FFTW VMS Test Makefile Setup Source: https://www.fftw.org/install/vms This Makefile snippet is from the tests directory and configures the paths for FFTW sources and headers on VMS. It defines the `FFTWDIR`, `LIBFFT`, `HEADERS`, and `INCLUDE` variables to point to the correct locations within the VMS file system. ```makefile # VMS FFTWDIR=[-.src] LIBFFT = $(FFTWDIR)libfftw.olb HEADERS = $(FFTWDIR)fftw.h INCLUDE = /include=$(FFTWDIR) ``` -------------------------------- ### Standard FFTW Installation on Unix Source: https://www.fftw.org/doc/Installation-on-Unix The default installation process for FFTW on Unix-like systems. This builds the uniprocessor complex and real transform libraries along with test programs. 'make install' typically requires root privileges unless a custom prefix is specified. ```bash ./configure make make install ``` -------------------------------- ### FFTW Configuration Options Source: https://www.fftw.org/fftw2_doc/fftw_6 Examples of using `configure` script flags to customize FFTW build. These options control features like floating-point precision, shared library creation, threading, MPI support, and compiler choices. ```bash # Enable single-precision (float) instead of double-precision ./configure --enable-float # Create shared libraries instead of static ones ./configure --enable-shared # Enable multi-threaded FFTW library ./configure --enable-threads # Enable FFTW MPI library for distributed memory systems ./configure --enable-mpi # Disable Fortran wrapper routines ./configure --disable-fortran # Enable specific gcc/Pentium optimizations ./configure --enable-i386-hacks --enable-pentium-timer ``` -------------------------------- ### Example Usage of FFTW Wisdom Import/Export (C) Source: https://www.fftw.org/fftw2_doc/fftw_2 A C code example demonstrating the process of reading wisdom from a file, creating an FFTW plan, exporting the accumulated wisdom to a string, printing it, and then re-importing it after clearing the existing wisdom. This showcases the full lifecycle of wisdom management. ```c { fftw_plan plan; char *wisdom_string; FILE *input_file; /* open file to read wisdom from */ input_file = fopen("sample.wisdom", "r"); if (FFTW_FAILURE == fftw_import_wisdom_from_file(input_file)) printf("Error reading wisdom!\n"); fclose(input_file); /* be sure to close the file! */ /* create a plan for N=64, possibly creating and/or using wisdom */ plan = fftw_create_plan(64,FFTW_FORWARD, FFTW_MEASURE | FFTW_USE_WISDOM); /* ... do some computations with the plan ... */ /* always destroy plans when you are done */ fftw_destroy_plan(plan); /* write the wisdom to a string */ wisdom_string = fftw_export_wisdom_to_string(); if (wisdom_string != NULL) { printf("Accumulated wisdom: %s\n",wisdom_string); /* Just for fun, destroy and restore the wisdom */ fftw_forget_wisdom(); /* all gone! */ fftw_import_wisdom_from_string(wisdom_string); /* wisdom is back! */ fftw_free(wisdom_string); /* deallocate it since we're done */ } } ``` -------------------------------- ### Installing Dual Precision FFTW Libraries (Unix) Source: https://www.fftw.org/fftw2_doc/fftw_6 This section provides commands for installing both single and double precision FFTW libraries on Unix-like systems. It uses the `./configure` script with `--enable-type-prefix` for the double-precision build, followed by a second configuration with `--enable-float` and `--enable-type-prefix` for the single-precision build. ```shell # Install double-precision version with type prefix ./configure --enable-type-prefix _[ other options ]_ make make install make clean # Install single-precision version with type prefix ./configure --enable-float --enable-type-prefix _[ other options ]_ make make install ``` -------------------------------- ### Configure and Build FFTW with MinGW Source: https://www.fftw.org/install/windows This snippet demonstrates the command-line steps to configure and build FFTW 3 on Windows using MinGW. It highlights recommended options for creating shared libraries, enabling multi-threading, portable binaries, SSE2 instructions, and managing stack alignment. The process concludes with standard 'make' and 'make install' commands. ```bash ./configure --with-our-malloc16 --with-windows-f77-mangling --enable-shared --disable-static --enable-threads --with-combined-threads --enable-portable-binary --enable-sse2 --with-incoming-stack-boundary=2 make make install ``` -------------------------------- ### FFTW MPI Example: 2D DFT in C Source: https://www.fftw.org/fftw3_doc Provides a basic example of performing a two-dimensional Discrete Fourier Transform (DFT) using FFTW with MPI for distributed memory systems. This involves setting up MPI, distributing data, creating MPI-aware FFTW plans, executing the transform, and gathering results. ```C #include int main(int argc, char **argv) { int rank, size; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); int n0 = 64, n1 = 64; fftw_complex *data; fftw_plan plan; // Initialize MPI communicator for FFTW fftw_mpi_init(); // Allocate distributed array data = fftw_malloc(sizeof(fftw_complex) * fftw_mpi_local_size_2d(n0, n1, MPI_COMM_WORLD)); // Create a 2D distributed plan plan = fftw_mpi_plan_dft_2d(n0, n1, data, data, MPI_COMM_WORLD, FFTW_FORWARD, FFTW_ESTIMATE); // Initialize input data 'data' on each process // ... fftw_execute(plan); // Use the transformed data 'data' // ... fftw_destroy_plan(plan); fftw_free(data); MPI_Finalize(); return 0; } ``` -------------------------------- ### Fortran Example: Creating and Executing an FFTW Plan Source: https://www.fftw.org/doc/Overview-of-Fortran-interface An example demonstrating how to declare FFTW types in Fortran, create a 2D DFT plan, execute it, and destroy the plan. It highlights the use of 'type(C_PTR)' for plans and 'complex(C_DOUBLE_COMPLEX)' for complex data. ```Fortran type(C_PTR) :: plan complex(C_DOUBLE_COMPLEX), dimension(1024,1000) :: in, out plan = fftw_plan_dft_2d(1000,1024, in,out, FFTW_FORWARD,FFTW_ESTIMATE) ... call fftw_execute_dft(plan, in, out) ... call fftw_destroy_plan(plan) ``` -------------------------------- ### FFTW VMS Makefile Configuration (src/Makefile) Source: https://www.fftw.org/install/vms This Makefile snippet configures the build process for FFTW on OpenVMS. It defines VMS-specific commands for compilation, archiving, and file manipulation, along with variables for object file prefixes and source files. It sets up rules for creating the library, installing it, and cleaning the build artifacts. ```makefile # VMS LIBFFT = libfftw.olb HEADERS = fftw.h INCLUDE = /include=[] LIBDIR = sys$library INCLUDEDIR =sys$library RM = delete CP = copy MAKE = mms AR = library CC = cc CFLAGS = /optimize$(INCLUDE) NOTW_PREFIX=fn_ TWID_PREFIX=ftw_ NOTWI_PREFIX=fni_ TWIDI_PREFIX=ftwi_ NOTW_BLOCKS=$(NOTW_PREFIX)1.obj;,$(NOTW_PREFIX)2.obj;,$(NOTW_PREFIX)3.obj;, \ $(NOTW_PREFIX)4.obj;,$(NOTW_PREFIX)5.obj;,$(NOTW_PREFIX)6.obj;, \ $(NOTW_PREFIX)7.obj;,$(NOTW_PREFIX)8.obj;,$(NOTW_PREFIX)9.obj;, \ $(NOTW_PREFIX)10.obj;,$(NOTW_PREFIX)11.obj;,$(NOTW_PREFIX)12.obj;, \ $(NOTW_PREFIX)13.obj;,$(NOTW_PREFIX)14.obj;,$(NOTW_PREFIX)15.obj;, \ $(NOTW_PREFIX)16.obj;,$(NOTW_PREFIX)32.obj;,$(NOTW_PREFIX)64.obj;, TWID_BLOCKS=$(TWID_PREFIX)2.obj;,$(TWID_PREFIX)3.obj;,$(TWID_PREFIX)4.obj;, \ $(TWID_PREFIX)5.obj;,$(TWID_PREFIX)6.obj;,$(TWID_PREFIX)7.obj;, \ $(TWID_PREFIX)8.obj;,$(TWID_PREFIX)9.obj;,$(TWID_PREFIX)10.obj;, \ $(TWID_PREFIX)16.obj;,$(TWID_PREFIX)32.obj;,$(TWID_PREFIX)64.obj;, NOTWI_BLOCKS=$(NOTWI_PREFIX)1.obj;,$(NOTWI_PREFIX)2.obj;,$(NOTWI_PREFIX)3.obj;,\ $(NOTWI_PREFIX)4.obj;,$(NOTWI_PREFIX)5.obj;,$(NOTWI_PREFIX)6.obj;, \ $(NOTWI_PREFIX)7.obj;,$(NOTWI_PREFIX)8.obj;,$(NOTWI_PREFIX)9.obj;, \ $(NOTWI_PREFIX)10.obj;,$(NOTWI_PREFIX)11.obj;,$(NOTWI_PREFIX)12.obj;, \ $(NOTWI_PREFIX)13.obj;,$(NOTWI_PREFIX)14.obj;,$(NOTWI_PREFIX)15.obj;, \ $(NOTWI_PREFIX)16.obj;,$(NOTWI_PREFIX)32.obj;,$(NOTWI_PREFIX)64.obj;, TWIDI_BLOCKS=$(TWIDI_PREFIX)2.obj;,$(TWIDI_PREFIX)3.obj;, \ $(TWIDI_PREFIX)4.obj;,$(TWIDI_PREFIX)5.obj;,$(TWIDI_PREFIX)6.obj;, \ $(TWIDI_PREFIX)7.obj;,$(TWIDI_PREFIX)8.obj;,$(TWIDI_PREFIX)9.obj;, \ $(TWIDI_PREFIX)10.obj;,$(TWIDI_PREFIX)16.obj;,$(TWIDI_PREFIX)32.obj;,\\ $(TWIDI_PREFIX)64.obj;, NOTW_SRC=$(NOTW_PREFIX)1.c $(NOTW_PREFIX)2.c $(NOTW_PREFIX)3.c \ $(NOTW_PREFIX)4.c $(NOTW_PREFIX)5.c $(NOTW_PREFIX)6.c \ $(NOTW_PREFIX)7.c $(NOTW_PREFIX)8.c $(NOTW_PREFIX)9.c \ $(NOTW_PREFIX)10.c $(NOTW_PREFIX)11.c $(NOTW_PREFIX)12.c \ $(NOTW_PREFIX)13.c $(NOTW_PREFIX)14.c $(NOTW_PREFIX)15.c \ $(NOTW_PREFIX)16.c $(NOTW_PREFIX)32.c $(NOTW_PREFIX)64.c TWID_SRC=$(TWID_PREFIX)2.c $(TWID_PREFIX)3.c $(TWID_PREFIX)4.c \ $(TWID_PREFIX)5.c $(TWID_PREFIX)6.c $(TWID_PREFIX)7.c \ $(TWID_PREFIX)8.c $(TWID_PREFIX)9.c $(TWID_PREFIX)10.c \ $(TWID_PREFIX)16.c $(TWID_PREFIX)32.c $(TWID_PREFIX)64.c NOTWI_SRC=$(NOTWI_PREFIX)1.c $(NOTWI_PREFIX)2.c $(NOTWI_PREFIX)3.c \ $(NOTWI_PREFIX)4.c $(NOTWI_PREFIX)5.c $(NOTWI_PREFIX)6.c \ $(NOTWI_PREFIX)7.c $(NOTWI_PREFIX)8.c $(NOTWI_PREFIX)9.c \ $(NOTWI_PREFIX)10.c $(NOTWI_PREFIX)11.c $(NOTWI_PREFIX)12.c \ $(NOTWI_PREFIX)13.c $(NOTWI_PREFIX)14.c $(NOTWI_PREFIX)15.c \ $(NOTWI_PREFIX)16.c $(NOTWI_PREFIX)32.c $(NOTWI_PREFIX)64.c TWIDI_SRC=$(TWIDI_PREFIX)2.c $(TWIDI_PREFIX)3.c $(TWIDI_PREFIX)4.c \ $(TWIDI_PREFIX)5.c $(TWIDI_PREFIX)6.c $(TWIDI_PREFIX)7.c \ $(TWIDI_PREFIX)8.c $(TWIDI_PREFIX)9.c $(TWIDI_PREFIX)10.c \ $(TWIDI_PREFIX)16.c $(TWIDI_PREFIX)32.c $(TWIDI_PREFIX)64.c OTHEROBJ = timer.obj;,config.obj;,planner.obj;,twiddle.obj;,executor.obj;,naive.obj;, generic.obj;,fftwnd.obj;,malloc.obj;,wisdom.obj;,common_io.obj; BLOCKS = $(NOTW_BLOCKS) $(NOTWI_BLOCKS) $(TWID_BLOCKS) $(TWIDI_BLOCKS) ALLOBJ = $(BLOCKS) $(OTHEROBJ) all : $(MAKE) $(LIBFFT) install : $(LIBFFT) $(CP) $(LIBFFT) $(LIBDIR) $(RANLIB) $(LIBDIR)/$(LIBFFT) $(CP) $(HEADERS) $(INCLUDEDIR) $(LIBFFT) : $(ALLOBJ) $(AR)/create $(LIBFFT) $(ALLOBJ) sources : $(MAKE) -f Makefile.sources $(NOTW_SRC) $(NOTWI_SRC) \ $(TWID_SRC) $(TWIDI_SRC) \ NOTW_PREFIX=$(NOTW_PREFIX) \ NOTWI_PREFIX=$(NOTWI_PREFIX) \ TWID_PREFIX=$(TWID_PREFIX) \ TWIDI_PREFIX=$(TWIDI_PREFIX) realclean : clean $(RM) $(LIBFFT) $(NOTW_SRC) $(NOTWI_SRC) $(TWID_SRC) $(TWIDI_SRC) clean : $(RM) -f *.obj;,*~ core a.out test gmon.objut mon.out *.zi *.zo *.s genfft $(ALLOBJ) : $(HEADERS) konst.h ``` -------------------------------- ### Basic FFTW Transform Workflow (C) Source: https://www.fftw.org/fftw2_doc/fftw_2 Demonstrates the typical workflow for performing a one-dimensional FFT using the FFTW library in C. This includes creating a plan, executing the transform, and destroying the plan. It requires the `fftw.h` header and linking with `-lfftw -lm`. ```c #include ... { fftw_complex in[N], out[N]; fftw_plan p; ... p = fftw_create_plan(N, FFTW_FORWARD, FFTW_ESTIMATE); ... fftw_one(p, in, out); ... fftw_destroy_plan(p); } ``` -------------------------------- ### Example: In-place 3D FFT in C Source: https://www.fftw.org/fftw2_doc/fftw_2 Demonstrates how to perform an in-place FFT on a 3D array using FFTW. It includes creating a plan, executing the transform, and destroying the plan. Note the use of '&in[0][0][0]' to pass the array's first element. ```c #include ... { fftw_complex in[L][M][N]; fftwnd_plan p; ... p = fftw3d_create_plan(L, M, N, FFTW_FORWARD, FFTW_MEASURE | FFTW_IN_PLACE); ... fftwnd_one(p, &in[0][0][0], NULL); ... fftwnd_destroy_plan(p); } ``` -------------------------------- ### FFTW3 Borland C++ Def File Alias Example Source: https://www.fftw.org/install/bcb-fftw3 This example shows how to create an alias for a Borland C++ function name to match the exported name from the FFTW3 DLL. This is necessary because Borland C++ expects function names to start with a leading underscore '_', while Visual C++ and Intel compilers omit it. ```text _fftw_version = fftw_version ``` -------------------------------- ### Get Local Size for 2D Distributed FFT (C) Source: https://www.fftw.org/doc/Basic-and-advanced-distribution-interfaces Calculates the local data dimensions and starting index for a 2D distributed FFT. It takes the global dimensions (n0, n1), an MPI communicator, and pointers to store the local size (local_n0) and start index (local_0_start). It returns the total number of elements to allocate on the current process. ```c ptrdiff_t fftw_mpi_local_size_2d(ptrdiff_t n0, ptrdiff_t n1, MPI_Comm comm, ptrdiff_t *local_n0, ptrdiff_t *local_0_start); ``` -------------------------------- ### FFTW Example: Multiple Contiguous 2D DFTs (C) Source: https://www.fftw.org/fftw3_doc/Advanced-Complex-DFTs This example shows planning for three 2D DFTs (5x6) stored sequentially in memory. `howmany` is 3. `idist` and `odist` are set to `n[0]*n[1]` (30) to represent the memory distance between the start of consecutive arrays. `istride`/`ostride` are 1 for contiguity within each array. ```c int rank = 2; int n[] = {5, 6}; int howmany = 3; int idist = odist = n[0]*n[1]; /* = 30, the distance in memory between the first element of the first array and the first element of the second array */ int istride = ostride = 1; /* array is contiguous in memory */ int *inembed = n, *onembed = n; ``` -------------------------------- ### Get MPI FFTW Local Data Sizes (C) Source: https://www.fftw.org/fftw2_doc/fftw_4 This C function retrieves the local data dimensions and starting indices for each process involved in an MPI FFTW transform. It's crucial for correctly allocating memory on each process. The output parameters specify the number of rows (`local_nx`), starting row index (`local_x_start`), transposed dimensions (`local_ny_after_transpose`, `local_y_start_after_transpose`), and total local elements (`total_local_size`). ```c void fftwnd_mpi_local_sizes(fftwnd_mpi_plan p, int *local_nx, int *local_x_start, int *local_ny_after_transpose, int *local_y_start_after_transpose, int *total_local_size); ``` -------------------------------- ### Building FFTW Library Source: https://www.fftw.org/install/fftw-3.0.1BC_installation Instructions for building the FFTW library. Typing 'make' from the root directory compiles the main library, resulting in 'fftw3.lib' and 'fftw3.dll'. To build the threaded version, navigate to the 'threads' directory and run 'make'. ```makefile make cd threads/ make ``` -------------------------------- ### Get Local Transposed Data Distribution (C) Source: https://www.fftw.org/doc/Transposed-distributions This function retrieves the size and starting index for both non-transposed and transposed data dimensions for a 3D transform. It's useful when using FFTW_MPI_TRANSPOSED_OUT or FFTW_MPI_TRANSPOSED_IN flags. ```c ptrdiff_t fftw_mpi_local_size_3d_transposed( ptrdiff_t n0, ptrdiff_t n1, ptrdiff_t n2, MPI_Comm comm, ptrdiff_t *local_n0, ptrdiff_t *local_0_start, ptrdiff_t *local_n1, ptrdiff_t *local_1_start); ``` -------------------------------- ### Exporting Functions for Borland Delphi DLL Source: https://www.fftw.org/install/fftw-3.0.1BC_installation Demonstrates how to export functions from the FFTW library for use with the Borland Delphi compiler. This involves modifying function declarations in the C source code by prefixing them with '__declspec(dllexport)'. The example shows exporting the fftw_malloc function. ```c void *X(malloc)(size_t n) __declspec(dllexport) void *X(malloc)(size_t n) ``` -------------------------------- ### FFTW Example: Column Transforms in 2D Array (C) Source: https://www.fftw.org/fftw3_doc/Advanced-Complex-DFTs This example illustrates planning to transform each column of a 2D array (10 rows, 3 columns). `rank` is 1, defining 1D transforms of length 10. `howmany` is 3, one for each column. `istride`/`ostride` are set to 3, the distance between elements in the same column (row-major index progresses by 3 for each step down a column). `idist`/`odist` are 1, meaning the next transform (next column) starts immediately after the previous one in memory. ```c int rank = 1; /* not 2: we are computing 1d transforms */ int n[] = {10}; /* 1d transforms of length 10 */ int howmany = 3; int idist = odist = 1; int istride = ostride = 3; /* distance between two elements in the same column */ int *inembed = n, *onembed = n; ``` -------------------------------- ### Example: Power Spectrum Calculation with RFFTW Source: https://www.fftw.org/fftw2_doc/fftw_2 Demonstrates how to compute the power spectrum of a real array using RFFTW. It involves creating a plan for real-to-complex transform, executing the transform, and then calculating the squared magnitudes of the resulting complex DFT amplitudes. ```c #include ... { fftw_real in[N], out[N], power_spectrum[N/2+1]; rfftw_plan p; int k; ... p = rfftw_create_plan(N, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); ... rfftw_one(p, in, out); power_spectrum[0] = out[0]*out[0]; /* DC component */ for (k = 1; k < (N+1)/2; ++k) /* (k < N/2 rounded up) */ power_spectrum[k] = out[k]*out[k] + out[N-k]*out[N-k]; if (N % 2 == 0) /* N is even */ power_spectrum[N/2] = out[N/2]*out[N/2]; /* Nyquist freq. */ ... rfftw_destroy_plan(p); } ``` -------------------------------- ### Get Local Sizes for MPI FFTW Transform Source: https://www.fftw.org/fftw2_doc/fftw_4 Determines the local data distribution for a given MPI FFTW plan. It outputs the number of elements (`local_n`) and the starting index (`local_start`) for the current process before the transform. It also provides the same information (`local_n_after_transform`, `local_start_after_transform`) for the data distribution after the transform, and the total number of elements (`total_local_size`) that need to be allocated for `local_data`. ```c void fftw_mpi_local_sizes(fftw_mpi_plan p, int *local_n, int *local_start, int *local_n_after_transform, int *local_start_after_transform, int *total_local_size); ``` -------------------------------- ### Create Real Multi-dimensional Transform Plan (C) Source: https://www.fftw.org/fftw2_doc/fftw_2 Creates a plan for real multi-dimensional FFTW transforms. It takes the rank of the data, its dimensions, the transform direction, and flags. Alternate versions like `rfftw2d_create_plan` and `rfftw3d_create_plan` are available for convenience. `FFTW_IN_PLACE` flag enables in-place transforms. ```c #include rfftwnd_plan plan = rfftwnd_create_plan(rank, n, dir, flags); ``` -------------------------------- ### Perform 2D DFT with FFTW MPI in C Source: https://www.fftw.org/doc/2d-MPI-example This C code snippet demonstrates how to perform a two-dimensional complex DFT using the FFTW MPI library. It includes initialization of MPI and FFTW, calculating local data sizes, allocating memory, creating a DFT plan, initializing data, executing the transform, and cleaning up resources. It assumes MPI and FFTW3-MPI are installed. ```c #include int main(int argc, char **argv) { const ptrdiff_t N0 = ..., N1 = ...; fftw_plan plan; fftw_complex *data; ptrdiff_t alloc_local, local_n0, local_0_start, i, j; MPI_Init(&argc, &argv); fftw_mpi_init(); /* get local data size and allocate */ alloc_local = fftw_mpi_local_size_2d(N0, N1, MPI_COMM_WORLD, &local_n0, &local_0_start); data = fftw_alloc_complex(alloc_local); /* create plan for in-place forward DFT */ plan = fftw_mpi_plan_dft_2d(N0, N1, data, data, MPI_COMM_WORLD, FFTW_FORWARD, FFTW_ESTIMATE); /* initialize data to some function my_function(x,y) */ for (i = 0; i < local_n0; ++i) for (j = 0; j < N1; ++j) data[i*N1 + j] = my_function(local_0_start + i, j); /* compute transforms, in-place, as many times as desired */ fftw_execute(plan); fftw_destroy_plan(plan); MPI_Finalize(); return 0; } ``` -------------------------------- ### Importing FFTW Wisdom Source: https://www.fftw.org/fftw2_doc/fftw_2 Restores FFTW wisdom from a specified source. This enables the quick recreation of previously computed optimal plans without the need for runtime measurements. ```c fftw_import_wisdom(...); plan = fftw_create_plan(..., ... | FFTW_USE_WISDOM); ``` -------------------------------- ### Initialize Multi-threaded FFTW in Fortran Source: https://www.fftw.org/fftw3_doc/Fortran-Examples Shows how to initialize FFTW for multi-threaded execution in Fortran and set the number of threads to use for planning. It includes a check for initialization errors. ```fortran integer iret call dfftw_init_threads(iret) call dfftw_plan_with_nthreads(8) ``` -------------------------------- ### Get Local Size for Multi-Dimensional Distributed FFT (C) Source: https://www.fftw.org/doc/Basic-and-advanced-distribution-interfaces The advanced interface for calculating local data dimensions for multi-dimensional distributed FFTs. It allows specifying the rank (rnk), global dimensions (n), number of transforms (howmany), desired block size (block0), and MPI communicator. It returns the local size (local_n0) and start index (local_0_start), along with the total elements to allocate. ```c ptrdiff_t fftw_mpi_local_size_many(int rnk, const ptrdiff_t *n, ptrdiff_t howmany, ptrdiff_t block0, MPI_Comm comm, ptrdiff_t *local_n0, ptrdiff_t *local_0_start); ```