Blender V4.3
fftw.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#if defined(WITH_FFTW3_THREADS_F_SUPPORT)
6# include <fftw3.h>
7#endif
8
9#include "BLI_fftw.hh"
10#include "BLI_index_range.hh"
12#include "BLI_task.hh"
13#include "BLI_threads.h"
14
15namespace blender::fftw {
16
17/* Identifies if the given number is a 7-smooth number. */
18static bool is_humble_number(int n)
19{
20 if (n <= 1) {
21 return true;
22 }
23 if (n % 2 == 0) {
24 return is_humble_number(n / 2);
25 }
26 if (n % 3 == 0) {
27 return is_humble_number(n / 3);
28 }
29 if (n % 5 == 0) {
30 return is_humble_number(n / 5);
31 }
32 if (n % 7 == 0) {
33 return is_humble_number(n / 7);
34 }
35 return false;
36}
37
38/* Finds the even humble number larger than or equal the given number. */
40{
41 if (n % 2 == 1) {
42 n++;
43 }
44
45 while (true) {
46 if (is_humble_number(n)) {
47 return n;
48 }
49 n += 2;
50 }
51
52 return n;
53}
54
56{
57 /* FFTW is best at handling sizes of the form 2^a * 3^b * 5^c * 7^d * 11^e * 13^f, where e + f is
58 * either 0 or 1, and the other exponents are arbitrary. And it is beneficial for the size to be
59 * even for real transforms. To simplify computation, we ignore the 11 and 13 factors and find
60 * the even humble number that is more then or equal the given size. See Section 4.3.3 Real-data
61 * DFTs in the FFTW manual for more information. */
63}
64
69
70/* See Section 5.2 Usage of Multi-threaded FFTW in the FFTW manual for more information. */
71[[maybe_unused]] static void tbb_parallel_loop_for_fftw(void *(*work)(char *),
72 char *job_data,
73 size_t element_size,
74 int number_of_jobs,
75 void * /*data*/)
76{
77 threading::parallel_for(IndexRange(number_of_jobs), 1, [&](const IndexRange sub_range) {
78 for (const int64_t i : sub_range) {
79 work(job_data + element_size * i);
80 }
81 });
82}
83
85{
86#if defined(WITH_FFTW3_THREADS_F_SUPPORT)
87 fftwf_init_threads();
88 fftwf_make_planner_thread_safe();
89 fftwf_plan_with_nthreads(BLI_system_thread_count());
90 fftwf_threads_set_callback(tbb_parallel_loop_for_fftw, nullptr);
91#endif
92}
93
94} // namespace blender::fftw
int BLI_system_thread_count(void)
Definition threads.cc:253
void initialize_float()
Definition fftw.cc:84
static void tbb_parallel_loop_for_fftw(void *(*work)(char *), char *job_data, size_t element_size, int number_of_jobs, void *)
Definition fftw.cc:71
static bool is_humble_number(int n)
Definition fftw.cc:18
static int find_next_even_humble_number(int n)
Definition fftw.cc:39
int optimal_size_for_real_transform(int size)
Definition fftw.cc:55
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:95
VecBase< int32_t, 2 > int2
__int64 int64_t
Definition stdint.h:89