Blender V5.0
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
8
9#if defined(WITH_FFTW3)
10# include <fftw3.h>
11#endif
12
13#include "BLI_fftw.hh"
14#include "BLI_index_range.hh"
16#include "BLI_task.hh"
17#include "BLI_threads.h"
18
19namespace blender::fftw {
20
21/* Identifies if the given number is a 7-smooth number. */
22static bool is_humble_number(int n)
23{
24 if (n <= 1) {
25 return true;
26 }
27 if (n % 2 == 0) {
28 return is_humble_number(n / 2);
29 }
30 if (n % 3 == 0) {
31 return is_humble_number(n / 3);
32 }
33 if (n % 5 == 0) {
34 return is_humble_number(n / 5);
35 }
36 if (n % 7 == 0) {
37 return is_humble_number(n / 7);
38 }
39 return false;
40}
41
42/* Finds the even humble number larger than or equal the given number. */
44{
45 if (n % 2 == 1) {
46 n++;
47 }
48
49 while (true) {
50 if (is_humble_number(n)) {
51 return n;
52 }
53 n += 2;
54 }
55
56 return n;
57}
58
60{
61 /* 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
62 * either 0 or 1, and the other exponents are arbitrary. And it is beneficial for the size to be
63 * even for real transforms. To simplify computation, we ignore the 11 and 13 factors and find
64 * the even humble number that is more then or equal the given size. See Section 4.3.3 Real-data
65 * DFTs in the FFTW manual for more information. */
67}
68
73
74/* See Section 5.2 Usage of Multi-threaded FFTW in the FFTW manual for more information. */
75[[maybe_unused]] static void tbb_parallel_loop_for_fftw(void *(*work)(char *),
76 char *job_data,
77 size_t element_size,
78 int number_of_jobs,
79 void * /*data*/)
80{
81 threading::parallel_for(IndexRange(number_of_jobs), 1, [&](const IndexRange sub_range) {
82 for (const int64_t i : sub_range) {
83 work(job_data + element_size * i);
84 }
85 });
86}
87
89{
90#if defined(WITH_FFTW3)
91 fftwf_init_threads();
92 fftwf_make_planner_thread_safe();
93 fftwf_plan_with_nthreads(BLI_system_thread_count());
94 fftwf_threads_set_callback(tbb_parallel_loop_for_fftw, nullptr);
95#endif
96}
97
98} // namespace blender::fftw
int BLI_system_thread_count(void)
Definition threads.cc:253
long long int int64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void initialize_float()
Definition fftw.cc:88
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:75
static bool is_humble_number(int n)
Definition fftw.cc:22
static int find_next_even_humble_number(int n)
Definition fftw.cc:43
int optimal_size_for_real_transform(int size)
Definition fftw.cc:59
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:93
VecBase< int32_t, 2 > int2
i
Definition text_draw.cc:230