### Multi-threaded FFT with fftw_init_threads Source: https://context7.com/fftw/fftw3/llms.txt This example shows how to enable multi-threaded FFTW execution. It covers initializing the threading system, setting the number of threads, and creating plans that utilize multiple cores for faster computation. ```APIDOC ## Multi-threaded FFT with fftw_init_threads ### Description FFTW supports parallel execution using multiple threads. Initialize threading once, then set the number of threads before creating plans. This example demonstrates setting up and using FFTW with multiple threads. ### Key Functions - **`fftw_init_threads()`**: Initializes the FFTW threading system. Should be called once at the beginning of the program. - **`fftw_plan_with_nthreads(int nthreads)`**: Sets the number of threads to be used for subsequent plan creation and execution. - **`fftw_planner_nthreads()`**: Returns the number of threads currently configured for FFTW. - **`fftw_cleanup_threads()`**: Cleans up FFTW threading resources. Should be called before program exit. ### Method `fftw_init_threads`, `fftw_plan_with_nthreads`, `fftw_execute` (implicitly uses threads if configured) ### Parameters - **`nthreads`** (int) - The number of threads to use for FFTW operations. ### Request Example ```c #include #include #include // For omp_get_max_threads() (optional) int main(void) { int N = 1024 * 1024; fftw_complex *data; fftw_plan p; // Initialize threading (call once) if (fftw_init_threads() == 0) { fprintf(stderr, "Error initializing FFTW threads\n"); return 1; } // Set number of threads int nthreads = 4; // Or use omp_get_max_threads() fftw_plan_with_nthreads(nthreads); printf("Using %d threads for FFT\n", fftw_planner_nthreads()); data = fftw_alloc_complex(N); // Create plan (will use multiple threads) p = fftw_plan_dft_1d(N, data, data, FFTW_FORWARD, FFTW_MEASURE); // ... initialize data, execute plan, cleanup ... fftw_destroy_plan(p); fftw_free(data); fftw_cleanup_threads(); // Clean up threading resources return 0; } ``` ### Compilation - **Standard**: `gcc -o threaded_fft threaded_fft.c -lfftw3_threads -lfftw3 -lpthread -lm` - **With OpenMP**: `gcc -fopenmp -o threaded_fft threaded_fft.c -lfftw3_omp -lfftw3 -lm` ### Response - **Success**: The FFT transform is computed using multiple threads. - **Error**: `fftw_init_threads` returns 0 if initialization fails. ``` -------------------------------- ### fftw_plan_many_dft - Batch Transform Multiple Arrays Source: https://context7.com/fftw/fftw3/llms.txt This example demonstrates how to create a plan for computing multiple 1D DFTs at once using `fftw_plan_many_dft`. It's efficient for transforming many small arrays or data with specific strides and distances. ```APIDOC ## fftw_plan_many_dft - Batch Transform Multiple Arrays ### Description Creates a plan for computing multiple transforms at once. This is efficient for transforming many small arrays or for strided/interleaved data layouts. ### Method `fftw_plan_many_dft` ### Parameters - **rank** (int) - The number of dimensions of the transform (e.g., 1 for 1D, 2 for 2D). - **n** (const int*) - An array of integers specifying the size of the transform in each dimension. - **howmany** (int) - The number of transforms to compute. - **in** (fftw_complex*) - The input array. - **inembed** (const int*) - Embedding array for input (NULL if not used). - **istride** (int) - The stride between consecutive elements in the input array. - **idist** (int) - The distance between the first elements of consecutive transforms in the input array. - **out** (fftw_complex*) - The output array. - **onembed** (const int*) - Embedding array for output (NULL if not used). - **ostride** (int) - The stride between consecutive elements in the output array. - **odist** (int) - The distance between the first elements of consecutive transforms in the output array. - **sign** (int) - `FFTW_FORWARD` or `FFTW_BACKWARD`. - **flags** (unsigned int) - Planning flags (e.g., `FFTW_ESTIMATE`, `FFTW_MEASURE`). ### Request Example ```c #include #include int main(void) { int N = 8; int howmany = 3; int idist = N; int odist = N; int istride = 1; int ostride = 1; fftw_complex *in, *out; fftw_plan p; in = fftw_alloc_complex(N * howmany); out = fftw_alloc_complex(N * howmany); p = fftw_plan_many_dft( 1, // rank: 1D transforms &N, // n: array of transform sizes howmany, // number of transforms in, NULL, // input array and embedding istride, idist, out, NULL, // output array and embedding ostride, odist, FFTW_FORWARD, FFTW_ESTIMATE ); // ... initialization and execution ... fftw_destroy_plan(p); fftw_free(in); fftw_free(out); return 0; } ``` ### Response - **fftw_plan** - A handle to the created FFTW plan. ``` -------------------------------- ### Get FFTW Plan Information and Cost Functions Source: https://context7.com/fftw/fftw3/llms.txt Query information about created FFTW plans, including operation counts and internal cost metrics. Use fftw_flops to get operation counts and fftw_cost for an internal metric. fftw_print_plan and fftw_sprint_plan can be used for debugging. ```c #include #include int main(void) { int N = 64; fftw_complex *in, *out; fftw_plan p_estimate, p_measure; double add, mul, fma; in = fftw_alloc_complex(N); out = fftw_alloc_complex(N); // Create plans with different optimization levels p_estimate = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); p_measure = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_MEASURE); // Get floating-point operation counts fftw_flops(p_estimate, &add, &mul, &fma); printf("ESTIMATE plan for N=%d:\n", N); printf(" Additions: %.0f, Multiplications: %.0f, FMAs: %.0f\n", add, mul, fma); printf(" Total FLOPs: %.0f (or %.0f with FMA hardware)\n", add + mul + 2*fma, add + mul + fma); fftw_flops(p_measure, &add, &mul, &fma); printf("\nMEASURE plan for N=%d:\n", N); printf(" Additions: %.0f, Multiplications: %.0f, FMAs: %.0f\n", add, mul, fma); // Get internal cost metric double cost = fftw_cost(p_measure); printf(" Internal cost metric: %g\n", cost); // Print plan structure (for debugging/understanding) printf("\nPlan structure:\n"); fftw_print_plan(p_measure); printf("\n"); // Get plan as string char *plan_str = fftw_sprint_plan(p_measure); printf("Plan string: %s\n", plan_str); fftw_free(plan_str); // Copy a plan (increments internal reference count) fftw_plan p_copy = fftw_copy_plan(p_measure); // Both must be destroyed separately fftw_destroy_plan(p_estimate); fftw_destroy_plan(p_measure); fftw_destroy_plan(p_copy); fftw_free(in); fftw_free(out); return 0; } ``` -------------------------------- ### Set interface include directories Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Sets interface include directories for the library, making headers available for installed targets. ```cmake target_include_directories (${fftw3_lib} INTERFACE $) ``` -------------------------------- ### Create 2D Complex DFT Plan with FFTW Source: https://context7.com/fftw/fftw3/llms.txt Shows how to create and execute 2D forward and backward complex DFT plans using FFTW. This example performs an in-place transform, meaning the input and output arrays are the same. Note that FFTW computes unnormalized transforms, so manual scaling is required for the backward transform to recover the original data. ```c #include #include int main(void) { int n0 = 4, n1 = 4; // 4x4 2D transform fftw_complex *data; fftw_plan forward_plan, backward_plan; // Allocate memory for in-place transform data = fftw_alloc_complex(n0 * n1); // Create forward and backward plans (in-place: same array for input/output) forward_plan = fftw_plan_dft_2d(n0, n1, data, data, FFTW_FORWARD, FFTW_ESTIMATE); backward_plan = fftw_plan_dft_2d(n0, n1, data, data, FFTW_BACKWARD, FFTW_ESTIMATE); // Initialize data: identity-like pattern for (int i = 0; i < n0; i++) { for (int j = 0; j < n1; j++) { int idx = i * n1 + j; // Row-major indexing data[idx][0] = (i == j) ? 1.0 : 0.0; // Real part data[idx][1] = 0.0; // Imaginary part } } // Forward transform fftw_execute(forward_plan); printf("After forward 2D FFT:\n"); for (int i = 0; i < n0; i++) { for (int j = 0; j < n1; j++) { int idx = i * n1 + j; printf("(%5.2f,%5.2f) ", data[idx][0], data[idx][1]); } printf("\n"); } // Backward transform (result scaled by n0*n1) fftw_execute(backward_plan); // Normalize: FFTW computes unnormalized transforms double scale = 1.0 / (n0 * n1); for (int i = 0; i < n0 * n1; i++) { data[i][0] *= scale; data[i][1] *= scale; } fftw_destroy_plan(forward_plan); fftw_destroy_plan(backward_plan); fftw_free(data); return 0; } ``` -------------------------------- ### FFTW3 Real-to-Real Transforms (DCT/DST/DHT) Source: https://context7.com/fftw/fftw3/llms.txt Use fftw_plan_r2r_1d to create plans for various real-to-real transforms, including DCT types I-IV, DST types I-IV, and DHT. The example demonstrates DCT-II and its inverse (DCT-III), as well as the DHT. ```c #include #include #include int main(void) { int N = 8; double *in, *out; fftw_plan dct_plan, idct_plan; in = fftw_alloc_real(N); out = fftw_alloc_real(N); // DCT-II (the most common "DCT") and its inverse DCT-III ("IDCT") dct_plan = fftw_plan_r2r_1d(N, in, out, FFTW_REDFT10, FFTW_ESTIMATE); // DCT-II idct_plan = fftw_plan_r2r_1d(N, out, in, FFTW_REDFT01, FFTW_ESTIMATE); // DCT-III (IDCT) // Initialize input: simple test signal for (int i = 0; i < N; i++) { in[i] = (i < N/2) ? 1.0 : -1.0; // Step function } printf("Original signal:\n"); for (int i = 0; i < N; i++) printf("%7.3f ", in[i]); printf("\n\n"); // Forward DCT fftw_execute(dct_plan); printf("DCT-II coefficients:\n"); for (int i = 0; i < N; i++) printf("%7.3f ", out[i]); printf("\n\n"); // Inverse DCT (DCT-III) fftw_execute(idct_plan); // Normalize: DCT-II followed by DCT-III scales by 2*N printf("Recovered signal (normalized):\n"); for (int i = 0; i < N; i++) printf("%7.3f ", in[i] / (2.0 * N)); printf("\n"); // DHT example (Discrete Hartley Transform - self-inverse) fftw_plan dht_plan = fftw_plan_r2r_1d(N, in, out, FFTW_DHT, FFTW_ESTIMATE); for (int i = 0; i < N; i++) in[i] = (double)i; fftw_execute(dht_plan); printf("\nDHT of [0,1,2,...,7]:\n"); for (int i = 0; i < N; i++) printf("%7.3f ", out[i]); printf("\n"); fftw_destroy_plan(dct_plan); fftw_destroy_plan(idct_plan); fftw_destroy_plan(dht_plan); fftw_free(in); fftw_free(out); return 0; } ``` -------------------------------- ### Save and Load FFTW Wisdom Source: https://context7.com/fftw/fftw3/llms.txt Demonstrates how to save optimized FFTW plans to a file and load them back. This avoids re-calculating plans, speeding up subsequent runs. Includes importing/exporting wisdom to/from strings and system-wide wisdom. ```c #include #include int main(void) { int N = 256; fftw_complex *in, *out; fftw_plan p; in = fftw_alloc_complex(N); out = fftw_alloc_complex(N); // Try to load existing wisdom if (fftw_import_wisdom_from_filename("fftw_wisdom.dat")) { printf("Loaded wisdom from file\n"); } else { printf("No wisdom file found, will generate new wisdom\n"); } // Create an optimized plan (FFTW_MEASURE takes time but finds fast algorithm) // With wisdom loaded, this may be instant printf("Creating plan with FFTW_MEASURE...\n"); p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_MEASURE); // FFTW_WISDOM_ONLY: only create plan if wisdom exists, else return NULL fftw_plan p2 = fftw_plan_dft_1d(512, in, out, FFTW_FORWARD, FFTW_WISDOM_ONLY | FFTW_ESTIMATE); if (p2 == NULL) { printf("No wisdom for size 512, would need to measure\n"); } // Execute transform for (int i = 0; i < N; i++) { in[i][0] = i; in[i][1] = 0; } fftw_execute(p); // Save wisdom for future runs if (fftw_export_wisdom_to_filename("fftw_wisdom.dat")) { printf("Saved wisdom to file\n"); } // Alternative: export to string char *wisdom_str = fftw_export_wisdom_to_string(); printf("Wisdom string length: %zu bytes\n", strlen(wisdom_str)); // Import from string fftw_import_wisdom_from_string(wisdom_str); // Load system-wide wisdom (typically from /etc/fftw/wisdom) fftw_import_system_wisdom(); // Clean up fftw_free(wisdom_str); // Must use fftw_free for fftw-allocated strings fftw_destroy_plan(p); if (p2) fftw_destroy_plan(p2); fftw_free(in); fftw_free(out); fftw_cleanup(); // Clears accumulated wisdom return 0; } ``` -------------------------------- ### Configure header and include directories Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Configures the 'config.h' file and sets include directories. ```cmake configure_file (cmake.config.h.in config.h @ONLY) include_directories (${CMAKE_CURRENT_BINARY_DIR}) ``` -------------------------------- ### Initialize and Use FFTW Multi-threading Source: https://context7.com/fftw/fftw3/llms.txt Enable multi-threaded FFTW computations by calling `fftw_init_threads` once at program startup. Then, use `fftw_plan_with_nthreads` to specify the number of threads for subsequent plans. Remember to call `fftw_cleanup_threads` before exiting. ```c #include #include #include // For omp_get_max_threads() int main(void) { int N = 1024 * 1024; // Large transform benefits from threading fftw_complex *data; fftw_plan p; // Initialize threading (call once at program start) if (fftw_init_threads() == 0) { fprintf(stderr, "Error initializing FFTW threads\n"); return 1; } // Set number of threads for subsequent plans // Use all available cores int nthreads = 4; // Or: omp_get_max_threads() fftw_plan_with_nthreads(nthreads); printf("Using %d threads for FFT\n", fftw_planner_nthreads()); data = fftw_alloc_complex(N); // Create plan (will use multiple threads) p = fftw_plan_dft_1d(N, data, data, FFTW_FORWARD, FFTW_MEASURE); // Initialize data for (int i = 0; i < N; i++) { data[i][0] = (double)i / N; data[i][1] = 0.0; } // Execute (threaded) fftw_execute(p); printf("Transform completed. First few outputs:\n"); for (int i = 0; i < 5; i++) { printf(" out[%d] = (%g, %g)\n", i, data[i][0], data[i][1]); } // Clean up fftw_destroy_plan(p); fftw_free(data); fftw_cleanup_threads(); // Clean up threading resources return 0; } // Compile: gcc -o threaded_fft threaded_fft.c -lfftw3_threads -lfftw3 -lpthread -lm // Or with OpenMP: gcc -fopenmp -o threaded_fft threaded_fft.c -lfftw3_omp -lfftw3 -lm ``` -------------------------------- ### Include directories Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Sets include directories for the build. ```cmake include_directories (.) if (WITH_COMBINED_THREADS) list (APPEND SOURCEFILES ${fftw_threads_SOURCE}) endif () ``` -------------------------------- ### Execute FFTW Plan on New Arrays Source: https://context7.com/fftw/fftw3/llms.txt Shows how to use `fftw_execute_dft` to apply a previously created FFTW plan to different input and output arrays. This is useful for transforming multiple datasets with the same configuration without re-planning. ```c #include #include int main(void) { int N = 8; fftw_complex *in1, *in2, *out1, *out2; fftw_plan p; // Allocate multiple arrays in1 = fftw_alloc_complex(N); in2 = fftw_alloc_complex(N); out1 = fftw_alloc_complex(N); out2 = fftw_alloc_complex(N); // Create plan with first arrays p = fftw_plan_dft_1d(N, in1, out1, FFTW_FORWARD, FFTW_ESTIMATE); // Initialize first input for (int i = 0; i < N; i++) { in1[i][0] = 1.0; in1[i][1] = 0.0; } // Execute on original arrays fftw_execute(p); printf("Transform of all-ones: out1[0] = (%g, %g)\n", out1[0][0], out1[0][1]); // Initialize second input (different data) for (int i = 0; i < N; i++) { in2[i][0] = (i == 0) ? 1.0 : 0.0; // Delta function in2[i][1] = 0.0; } // Execute same plan on DIFFERENT arrays // Arrays must have same size and alignment as original fftw_execute_dft(p, in2, out2); printf("Transform of delta: out2[0] = (%g, %g)\n", out2[0][0], out2[0][1]); // For r2c transforms: fftw_execute_dft_r2c(plan, in_real, out_complex) // For c2r transforms: fftw_execute_dft_c2r(plan, in_complex, out_real) // For r2r transforms: fftw_execute_r2r(plan, in_real, out_real) fftw_destroy_plan(p); fftw_free(in1); fftw_free(in2); fftw_free(out1); fftw_free(out2); return 0; } ``` -------------------------------- ### Create 1D Complex DFT Plan with FFTW Source: https://context7.com/fftw/fftw3/llms.txt Demonstrates creating and executing a 1D complex DFT plan using FFTW. Ensure memory is allocated with fftw_malloc and plans are destroyed with fftw_destroy_plan. The FFTW_MEASURE flag can be used for plan optimization, but it may overwrite input arrays. ```c #include #include #include int main(void) { int N = 8; fftw_complex *in, *out; fftw_plan p; // Allocate aligned memory for input and output in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); // Create plan BEFORE initializing input (FFTW_MEASURE may overwrite arrays) p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); // Initialize input data: a simple sine wave for (int i = 0; i < N; i++) { in[i][0] = cos(2.0 * M_PI * i / N); // Real part in[i][1] = 0.0; // Imaginary part } // Execute the transform fftw_execute(p); // Print results printf("Input -> Output:\n"); for (int i = 0; i < N; i++) { printf("(%6.3f, %6.3f) -> (%6.3f, %6.3f)\n", in[i][0], in[i][1], out[i][0], out[i][1]); } // Clean up fftw_destroy_plan(p); fftw_free(in); fftw_free(out); return 0; } // Compile: gcc -o fft_example fft_example.c -lfftw3 -lm ``` -------------------------------- ### fftw_plan_r2r_1d - Real-to-Real Transforms (DCT/DST/DHT) Source: https://context7.com/fftw/fftw3/llms.txt This function generates plans for various one-dimensional real-to-real transforms. It supports Discrete Cosine Transforms (DCT types I-IV), Discrete Sine Transforms (DST types I-IV), and Discrete Hartley Transforms (DHT). The specific transform is determined by the `kind` parameter. ```APIDOC ## fftw_plan_r2r_1d - Real-to-Real Transforms (DCT/DST/DHT) ### Description Creates plans for various real-to-real transforms including Discrete Cosine Transforms (DCT types I-IV), Discrete Sine Transforms (DST types I-IV), and Discrete Hartley Transforms (DHT). ### Method `fftw_plan_r2r_1d` is a planning function. ### Endpoint N/A (These are C library functions, not HTTP endpoints) ### Parameters #### Function Signature (Conceptual) - `fftw_plan fftw_plan_r2r_1d(int N, double *in, double *out, fftw_r2r_kind kind, unsigned int flags)` #### Parameters - **N** (int) - Required - The size of the transform. - **in** (double pointer) - Required - Pointer to the input data array. - **out** (double pointer) - Required - Pointer to the output data array. - **kind** (fftw_r2r_kind) - Required - The type of real-to-real transform (e.g., `FFTW_REDFT10` for DCT-II, `FFTW_REDFT01` for DCT-III, `FFTW_DHT` for DHT). - **flags** (unsigned int) - Required - Planning flags (e.g., `FFTW_ESTIMATE`, `FFTW_MEASURE`). ### Request Example ```c #include int N = 8; double *in = fftw_alloc_real(N); double *out = fftw_alloc_real(N); fftw_plan dct_plan = fftw_plan_r2r_1d(N, in, out, FFTW_REDFT10, FFTW_ESTIMATE); // DCT-II // ... execute plan ... fftw_destroy_plan(dct_plan); fftw_free(in); fftw_free(out); ``` ### Response #### Success Response Returns a `fftw_plan` object which is an opaque handle to the execution plan. #### Response Example ```c fftw_plan my_dht_plan; my_dht_plan = fftw_plan_r2r_1d(8, input_real, output_real, FFTW_DHT, FFTW_ESTIMATE); ``` ``` -------------------------------- ### Aggregate source files Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Aggregates various source file lists into a main SOURCEFILES list. ```cmake set(SOURCEFILES ${fftw_api_SOURCE} ${fftw_dft_SOURCE} ${fftw_dft_scalar_SOURCE} ${fftw_dft_scalar_codelets_SOURCE} ${fftw_dft_simd_SOURCE} ${fftw_kernel_SOURCE} ${fftw_rdft_SOURCE} ${fftw_rdft_scalar_SOURCE} ${fftw_rdft_scalar_r2cb_SOURCE} ${fftw_rdft_scalar_r2cf_SOURCE} ${fftw_rdft_scalar_r2r_SOURCE} ${fftw_rdft_simd_SOURCE} ${fftw_reodft_SOURCE} ${fftw_simd_support_SOURCE} ${fftw_threads_SOURCE} ) ``` -------------------------------- ### Define threaded source files Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Defines source files for FFTW's threaded implementation. ```cmake set(fftw_par_SOURCE threads/api.c threads/conf.c threads/ct.c threads/dft-vrank-geq1.c threads/f77api.c threads/hc2hc.c threads/rdft-vrank-geq1.c threads/vrank-geq1-rdft2.c) set (fftw_threads_SOURCE ${fftw_par_SOURCE} threads/threads.c) set (fftw_omp_SOURCE ${fftw_par_SOURCE} threads/openmp.c) ``` -------------------------------- ### Define SIMD support Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Sets HAVE_SIMD to TRUE if SSE2 or AVX is available. ```cmake if (HAVE_SSE2 OR HAVE_AVX) set (HAVE_SIMD TRUE) endif () ``` -------------------------------- ### fftw_plan_dft_r2c / fftw_plan_dft_c2r - Real-to-Complex and Complex-to-Real DFT Source: https://context7.com/fftw/fftw3/llms.txt These functions create plans for performing one-dimensional DFTs on real data. `fftw_plan_dft_r2c` transforms real input to complex output, exploiting Hermitian symmetry to produce N/2+1 complex values. `fftw_plan_dft_c2r` performs the inverse operation, transforming complex data back to real data. ```APIDOC ## fftw_plan_dft_r2c / fftw_plan_dft_c2r - Real-to-Complex and Complex-to-Real DFT ### Description Creates plans for transforms of real data. Real-to-complex (r2c) transforms take N real inputs and produce N/2+1 complex outputs (exploiting Hermitian symmetry). Complex-to-real (c2r) is the inverse operation. ### Method `fftw_plan_dft_r2c_1d` and `fftw_plan_dft_c2r_1d` are planning functions. ### Endpoint N/A (These are C library functions, not HTTP endpoints) ### Parameters #### Function Signature (Conceptual) - `fftw_plan_dft_r2c_1d(int N, fftw_real *in, fftw_complex *out, unsigned int flags)` - `fftw_plan_dft_c2r_1d(int N, fftw_complex *in, fftw_real *out, unsigned int flags)` #### Parameters - **N** (int) - Required - The size of the transform. - **in** (pointer) - Required - Pointer to the input data array. - **out** (pointer) - Required - Pointer to the output data array. - **flags** (unsigned int) - Required - Planning flags (e.g., `FFTW_ESTIMATE`, `FFTW_MEASURE`). ### Request Example ```c #include int N = 8; fftw_real *real_data = fftw_alloc_real(N); fftw_complex *complex_data = fftw_alloc_complex(N/2 + 1); fftw_plan r2c_plan = fftw_plan_dft_r2c_1d(N, real_data, complex_data, FFTW_ESTIMATE); // ... execute plan ... fftw_destroy_plan(r2c_plan); fftw_free(real_data); fftw_free(complex_data); ``` ### Response #### Success Response Returns a `fftw_plan` object which is an opaque handle to the execution plan. #### Response Example ```c fftw_plan my_plan; my_plan = fftw_plan_dft_r2c_1d(8, input_real, output_complex, FFTW_ESTIMATE); ``` ``` -------------------------------- ### Glob FFTW source files Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Uses file(GLOB) to find source and header files for various FFTW modules. ```cmake file(GLOB fftw_api_SOURCE api/*.c api/*.h) file(GLOB fftw_dft_SOURCE dft/*.c dft/*.h) file(GLOB fftw_dft_scalar_SOURCE dft/scalar/*.c dft/scalar/*.h) file(GLOB fftw_dft_scalar_codelets_SOURCE dft/scalar/codelets/*.c dft/scalar/codelets/*.h) file(GLOB fftw_dft_simd_SOURCE dft/simd/*.c dft/simd/*.h) file(GLOB fftw_dft_simd_sse2_SOURCE dft/simd/sse2/*.c dft/simd/sse2/*.h) file(GLOB fftw_dft_simd_avx_SOURCE dft/simd/avx/*.c dft/simd/avx/*.h) file(GLOB fftw_dft_simd_avx2_SOURCE dft/simd/avx2/*.c dft/simd/avx2/*.h dft/simd/avx2-128/*.c dft/simd/avx2-128/*.h) file(GLOB fftw_kernel_SOURCE kernel/*.c kernel/*.h) file(GLOB fftw_rdft_SOURCE rdft/*.c rdft/*.h) file(GLOB fftw_rdft_scalar_SOURCE rdft/scalar/*.c rdft/scalar/*.h) file(GLOB fftw_rdft_scalar_r2cb_SOURCE rdft/scalar/r2cb/*.c rdft/scalar/r2cb/*.h) file(GLOB fftw_rdft_scalar_r2cf_SOURCE rdft/scalar/r2cf/*.c rdft/scalar/r2cf/*.h) file(GLOB fftw_rdft_scalar_r2r_SOURCE rdft/scalar/r2r/*.c rdft/scalar/r2r/*.h) file(GLOB fftw_rdft_simd_SOURCE rdft/simd/*.c rdft/simd/*.h) file(GLOB fftw_rdft_simd_sse2_SOURCE rdft/simd/sse2/*.c rdft/simd/sse2/*.h) file(GLOB fftw_rdft_simd_avx_SOURCE rdft/simd/avx/*.c rdft/simd/avx/*.h) file(GLOB fftw_rdft_simd_avx2_SOURCE rdft/simd/avx2/*.c rdft/simd/avx2/*.h rdft/simd/avx2-128/*.c rdft/simd/avx2-128/*.h) file(GLOB fftw_reodft_SOURCE reodft/*.c reodft/*.h) file(GLOB fftw_simd_support_SOURCE simd-support/*.c simd-support/*.h) file(GLOB fftw_libbench2_SOURCE libbench2/*.c libbench2/*.h) list (REMOVE_ITEM fftw_libbench2_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/libbench2/useropt.c) ``` -------------------------------- ### Create FFT Plan for Multiple DFTs Source: https://context7.com/fftw/fftw3/llms.txt Use `fftw_plan_many_dft` to create a single plan for computing multiple 1D, 2D, or 3D transforms at once. This is efficient for transforming many small arrays or for strided/interleaved data layouts. Ensure memory is allocated for all transforms and specify strides and distances correctly. ```c #include #include int main(void) { int N = 8; // Transform size int howmany = 3; // Number of transforms int idist = N; // Distance between input arrays int odist = N; // Distance between output arrays int istride = 1; // Input stride (contiguous) int ostride = 1; // Output stride (contiguous) fftw_complex *in, *out; fftw_plan p; // Allocate space for multiple transforms in = fftw_alloc_complex(N * howmany); out = fftw_alloc_complex(N * howmany); // Create plan for multiple 1D transforms // NULL for inembed/onembed means same as n p = fftw_plan_many_dft( 1, // rank: 1D transforms &N, // n: array of transform sizes howmany, // number of transforms in, NULL, // input array and embedding istride, idist, out, NULL, // output array and embedding ostride, odist, FFTW_FORWARD, FFTW_ESTIMATE ); // Initialize: different signals for each batch for (int batch = 0; batch < howmany; batch++) { for (int i = 0; i < N; i++) { int idx = batch * N + i; in[idx][0] = (batch + 1) * (i == 0 ? 1.0 : 0.0); // Delta functions in[idx][1] = 0.0; } } // Execute all transforms at once fftw_execute(p); // Print results for (int batch = 0; batch < howmany; batch++) { printf("Batch %d output:\n", batch); for (int i = 0; i < N; i++) { int idx = batch * N + i; printf(" (%5.2f, %5.2f)\n", out[idx][0], out[idx][1]); } } fftw_destroy_plan(p); fftw_free(in); fftw_free(out); return 0; } ``` -------------------------------- ### Add FFTW library target Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Adds the main FFTW library target with all collected source files. ```cmake add_library (${fftw3_lib} ${SOURCEFILES}) ``` -------------------------------- ### Set FFTW version and precision suffix Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Sets the FFTW version and determines the precision suffix (f, l, q) based on enabled precision options. ```cmake set (FFTW_VERSION 3.3.10) set (PREC_SUFFIX) if (ENABLE_FLOAT) set (FFTW_SINGLE TRUE) set (BENCHFFT_SINGLE TRUE) set (PREC_SUFFIX f) endif () if (ENABLE_LONG_DOUBLE) set (FFTW_LDOUBLE TRUE) set (BENCHFFT_LDOUBLE TRUE) set (PREC_SUFFIX l) endif () if (ENABLE_QUAD_PRECISION) set (FFTW_QUAD TRUE) set (BENCHFFT_QUAD TRUE) set (PREC_SUFFIX q) endif () ``` -------------------------------- ### fftw_plan_dft_2d / fftw_plan_dft_3d - Multi-Dimensional Complex DFT Plans Source: https://context7.com/fftw/fftw3/llms.txt These functions create plans for two-dimensional or three-dimensional complex DFT transforms. Data is expected in row-major order. ```APIDOC ## fftw_plan_dft_2d / fftw_plan_dft_3d ### Description Creates plans for two-dimensional or three-dimensional complex DFT transforms. Arrays are stored in row-major order (C standard), with the last dimension having the fastest-varying index. ### Method C Function Call ### Endpoint N/A (Library Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c #include #include int main(void) { int n0 = 4, n1 = 4; // 4x4 2D transform fftw_complex *data; fftw_plan forward_plan, backward_plan; // Allocate memory for in-place transform data = fftw_alloc_complex(n0 * n1); // Create forward and backward plans (in-place: same array for input/output) forward_plan = fftw_plan_dft_2d(n0, n1, data, data, FFTW_FORWARD, FFTW_ESTIMATE); backward_plan = fftw_plan_dft_2d(n0, n1, data, data, FFTW_BACKWARD, FFTW_ESTIMATE); // Initialize data: identity-like pattern for (int i = 0; i < n0; i++) { for (int j = 0; j < n1; j++) { int idx = i * n1 + j; // Row-major indexing data[idx][0] = (i == j) ? 1.0 : 0.0; // Real part data[idx][1] = 0.0; // Imaginary part } } // Forward transform fftw_execute(forward_plan); printf("After forward 2D FFT:\n"); for (int i = 0; i < n0; i++) { for (int j = 0; j < n1; j++) { int idx = i * n1 + j; printf("(%5.2f,%5.2f) ", data[idx][0], data[idx][1]); } printf("\n"); } // Backward transform (result scaled by n0*n1) fftw_execute(backward_plan); // Normalize: FFTW computes unnormalized transforms double scale = 1.0 / (n0 * n1); for (int i = 0; i < n0 * n1; i++) { data[i][0] *= scale; data[i][1] *= scale; } fftw_destroy_plan(forward_plan); fftw_destroy_plan(backward_plan); fftw_free(data); return 0; } ``` ### Response #### Success Response (200) Returns a `fftw_plan` object which is an opaque handle to the execution plan for the specified multi-dimensional DFT. #### Response Example N/A (Function returns a plan handle) ``` -------------------------------- ### Enable ARMv8-A PMCCNTR_EL0 for User Mode Source: https://github.com/fftw/fftw3/blob/master/README-perfcnt.md Enables user-mode access to the PMCCNTR_EL0 (Performance Monitors Cycle Count Register) on ARMv8-A. This involves setting PMUSERENR_EL0, PMCR_EL0, PMCNTENSET_EL0, and PMCCFILTR_EL0, requiring kernel mode execution. ```c #define PERF_DEF_OPTS (1 | 16) /* enable user-mode access to counters */ asm volatile("msr PMUSERENR_EL0, %0" :: "r"(1)); /* Program PMU and enable all counters */ asm volatile("msr PMCR_EL0, %0" :: "r"(PERF_DEF_OPTS)); asm volatile("msr PMCNTENSET_EL0, %0" :: "r"(0x8000000f)); asm volatile("msr PMCCFILTR_EL0, %0" :: "r"(0)); ``` -------------------------------- ### Enable ARMv7-A PMCCNTR for User Mode Source: https://github.com/fftw/fftw3/blob/master/README-perfcnt.md Enables user-mode access to the PMCCNTR (Performance Monitors Cycle Count Register) on ARMv7-A. This involves programming the PMU and enabling all counters, requiring kernel mode execution. ```c #define PERF_DEF_OPTS (1 | 16) /* enable user-mode access to counters */ asm volatile("mcr p15, 0, %0, c9, c14, 0" :: "r"(1)); /* Program PMU and enable all counters */ asm volatile("mcr p15, 0, %0, c9, c12, 0" :: "r"(PERF_DEF_OPTS)); asm volatile("mcr p15, 0, %0, c9, c12, 1" :: "r"(0x8000000f)); ``` -------------------------------- ### Add shared library definition Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Adds the DFFTW_DLL definition if building shared libraries. ```cmake if (BUILD_SHARED_LIBS) add_definitions (-DFFTW_DLL) endif () ``` -------------------------------- ### fftw_plan_dft_1d - Create 1D Complex DFT Plan Source: https://context7.com/fftw/fftw3/llms.txt This function creates a plan for a one-dimensional discrete Fourier transform of complex data. The plan optimizes the transform based on the provided flags. ```APIDOC ## fftw_plan_dft_1d ### Description Creates a plan for a one-dimensional discrete Fourier transform of complex data. The plan encapsulates all information needed to compute the transform, including optimal algorithm selection based on the specified flags. ### Method C Function Call ### Endpoint N/A (Library Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c #include #include #include int main(void) { int N = 8; fftw_complex *in, *out; fftw_plan p; // Allocate aligned memory for input and output in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); // Create plan BEFORE initializing input (FFTW_MEASURE may overwrite arrays) p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); // Initialize input data: a simple sine wave for (int i = 0; i < N; i++) { in[i][0] = cos(2.0 * M_PI * i / N); // Real part in[i][1] = 0.0; // Imaginary part } // Execute the transform fftw_execute(p); // Print results printf("Input -> Output:\n"); for (int i = 0; i < N; i++) { printf("(%6.3f, %6.3f) -> (%6.3f, %6.3f)\n", in[i][0], in[i][1], out[i][0], out[i][1]); } // Clean up fftw_destroy_plan(p); fftw_free(in); fftw_free(out); return 0; } // Compile: gcc -o fft_example fft_example.c -lfftw3 -lm ``` ### Response #### Success Response (200) Returns a `fftw_plan` object which is an opaque handle to the execution plan. #### Response Example N/A (Function returns a plan handle) ``` -------------------------------- ### Define library name Source: https://github.com/fftw/fftw3/blob/master/CMakeLists.txt Defines the final library name based on the precision suffix. ```cmake set (fftw3_lib fftw3${PREC_SUFFIX}) ```