9 #if !defined(ASYNC) && !defined(OPENMP) && !defined(CUFFTW)
10 #define FFTW_PLAN_WITH_THREADS() fftw_plan_with_nthreads(4);
12 #define FFTW_PLAN_WITH_THREADS()
17 void Fftw::init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales)
19 Fft::init(width, height, num_of_feats, num_of_scales);
21 #if (!defined(ASYNC) && !defined(CUFFTW)) && defined(OPENMP)
26 std::cout << "FFT: FFTW" << std::endl;
28 std::cout << "FFT: cuFFTW" << std::endl;
31 // FFT forward one scale
33 cv::Mat in_f = cv::Mat::zeros(int(m_height), int(m_width), CV_32FC1);
34 ComplexMat out_f(int(m_height), m_width / 2 + 1, 1);
35 plan_f = fftwf_plan_dft_r2c_2d(int(m_height), int(m_width), reinterpret_cast<float *>(in_f.data),
36 reinterpret_cast<fftwf_complex *>(out_f.get_p_data()), FFTW_PATIENT);
39 // FFT forward all scales
40 if (m_num_of_scales > 1) {
41 cv::Mat in_f_all = cv::Mat::zeros(m_height * m_num_of_scales, m_width, CV_32F);
42 ComplexMat out_f_all(m_height, m_width / 2 + 1, m_num_of_scales);
43 float *in = reinterpret_cast<float *>(in_f_all.data);
44 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(out_f_all.get_p_data());
46 int n[] = {(int)m_height, (int)m_width};
47 int howmany = m_num_of_scales;
48 int idist = m_height * m_width, odist = m_height * (m_width / 2 + 1);
49 int istride = 1, ostride = 1;
50 int *inembed = NULL, *onembed = NULL;
52 FFTW_PLAN_WITH_THREADS();
53 plan_f_all_scales = fftwf_plan_many_dft_r2c(rank, n, howmany, in, inembed, istride, idist, out, onembed,
54 ostride, odist, FFTW_PATIENT);
57 // FFT forward window one scale
59 cv::Mat in_fw = cv::Mat::zeros(int(m_height * m_num_of_feats), int(m_width), CV_32F);
60 ComplexMat out_fw(int(m_height), m_width / 2 + 1, int(m_num_of_feats));
61 float *in = reinterpret_cast<float *>(in_fw.data);
62 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(out_fw.get_p_data());
64 int n[] = {int(m_height), int(m_width)};
65 int howmany = int(m_num_of_feats);
66 int idist = int(m_height * m_width), odist = int(m_height * (m_width / 2 + 1));
67 int istride = 1, ostride = 1;
68 int *inembed = nullptr, *onembed = nullptr;
70 FFTW_PLAN_WITH_THREADS();
71 plan_fw = fftwf_plan_many_dft_r2c(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist,
75 // FFT forward window all scales all feats
76 if (m_num_of_scales > 1) {
77 cv::Mat in_all = cv::Mat::zeros(m_height * (m_num_of_scales * m_num_of_feats), m_width, CV_32F);
78 ComplexMat out_all(m_height, m_width / 2 + 1, m_num_of_scales * m_num_of_feats);
79 float *in = reinterpret_cast<float *>(in_all.data);
80 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(out_all.get_p_data());
82 int n[] = {(int)m_height, (int)m_width};
83 int howmany = m_num_of_scales * m_num_of_feats;
84 int idist = m_height * m_width, odist = m_height * (m_width / 2 + 1);
85 int istride = 1, ostride = 1;
86 int *inembed = NULL, *onembed = NULL;
88 FFTW_PLAN_WITH_THREADS();
89 plan_fw_all_scales = fftwf_plan_many_dft_r2c(rank, n, howmany, in, inembed, istride, idist, out, onembed,
90 ostride, odist, FFTW_PATIENT);
93 // FFT inverse one scale
95 ComplexMat in_i(m_height, m_width, m_num_of_feats);
96 cv::Mat out_i = cv::Mat::zeros(int(m_height), int(m_width), CV_32FC(int(m_num_of_feats)));
97 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(in_i.get_p_data());
98 float *out = reinterpret_cast<float *>(out_i.data);
100 int n[] = {int(m_height), int(m_width)};
101 int howmany = int(m_num_of_feats);
102 int idist = int(m_height * (m_width / 2 + 1)), odist = 1;
103 int istride = 1, ostride = int(m_num_of_feats);
104 int inembed[] = {int(m_height), int(m_width / 2 + 1)}, *onembed = n;
106 FFTW_PLAN_WITH_THREADS();
107 plan_i_features = fftwf_plan_many_dft_c2r(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride,
108 odist, FFTW_PATIENT);
110 // FFT inverse all scales
112 if (m_num_of_scales > 1) {
113 ComplexMat in_i_all(m_height, m_width, m_num_of_feats * m_num_of_scales);
114 cv::Mat out_i_all = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_feats * m_num_of_scales));
115 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(in_i_all.get_p_data());
116 float *out = reinterpret_cast<float *>(out_i_all.data);
118 int n[] = {(int)m_height, (int)m_width};
119 int howmany = m_num_of_feats * m_num_of_scales;
120 int idist = m_height * (m_width / 2 + 1), odist = 1;
121 int istride = 1, ostride = m_num_of_feats * m_num_of_scales;
122 int inembed[] = {(int)m_height, (int)m_width / 2 + 1}, *onembed = n;
124 FFTW_PLAN_WITH_THREADS();
125 plan_i_features_all_scales = fftwf_plan_many_dft_c2r(rank, n, howmany, in, inembed, istride, idist, out,
126 onembed, ostride, odist, FFTW_PATIENT);
129 // FFT inverse one channel
131 ComplexMat in_i1(int(m_height), int(m_width), 1);
132 cv::Mat out_i1 = cv::Mat::zeros(int(m_height), int(m_width), CV_32FC1);
133 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(in_i1.get_p_data());
134 float *out = reinterpret_cast<float *>(out_i1.data);
136 int n[] = {int(m_height), int(m_width)};
137 int howmany = IF_BIG_BATCH(m_num_of_scales, 1);
138 int idist = m_height * (m_width / 2 + 1), odist = 1;
139 int istride = 1, ostride = IF_BIG_BATCH(m_num_of_scales, 1);
140 int inembed[] = {int(m_height), int(m_width / 2 + 1)}, *onembed = n;
142 FFTW_PLAN_WITH_THREADS();
143 plan_i_1ch = fftwf_plan_many_dft_c2r(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride,
144 odist, FFTW_PATIENT);
148 void Fftw::set_window(const MatDynMem &window)
150 Fft::set_window(window);
154 void Fftw::forward(const MatScales &real_input, ComplexMat &complex_result)
156 Fft::forward(real_input, complex_result);
158 if (BIG_BATCH_MODE && real_input.rows == int(m_height * IF_BIG_BATCH(m_num_of_scales, 1))) {
159 fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast<float *>(real_input.data),
160 reinterpret_cast<fftwf_complex *>(complex_result.get_p_data()));
162 fftwf_execute_dft_r2c(plan_f, reinterpret_cast<float *>(real_input.data),
163 reinterpret_cast<fftwf_complex *>(complex_result.get_p_data()));
168 void Fftw::forward_window(MatScaleFeats &feat, ComplexMat & complex_result, MatScaleFeats &temp)
170 Fft::forward_window(feat, complex_result, temp);
172 uint n_channels = feat.size[0];
173 for (uint i = 0; i < n_channels; ++i) {
174 for (uint j = 0; j < uint(feat.size[1]); ++j) {
175 cv::Mat feat_plane = feat.plane(i, j);
176 cv::Mat temp_plane = temp.plane(i, j);
177 temp_plane = feat_plane.mul(m_window);
181 float *in = temp.ptr<float>();
182 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(complex_result.get_p_data());
184 if (n_channels <= m_num_of_feats)
185 fftwf_execute_dft_r2c(plan_fw, in, out);
187 fftwf_execute_dft_r2c(plan_fw_all_scales, in, out);
191 void Fftw::inverse(ComplexMat &complex_input, MatScales &real_result)
193 Fft::inverse(complex_input, real_result);
195 int n_channels = complex_input.n_channels;
196 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(complex_input.get_p_data());
197 float *out = real_result.ptr<float>();
199 if (n_channels == 1|| (BIG_BATCH_MODE && n_channels == int(IF_BIG_BATCH(m_num_of_scales, 1))))
200 fftwf_execute_dft_c2r(plan_i_1ch, in, out);
201 else if (BIG_BATCH_MODE && n_channels == int(m_num_of_feats) * int(IF_BIG_BATCH(m_num_of_scales, 1)))
202 fftwf_execute_dft_c2r(plan_i_features_all_scales, in, out);
204 fftwf_execute_dft_c2r(plan_i_features, in, out);
206 real_result *= 1 / (m_width * m_height);
211 fftwf_destroy_plan(plan_f);
212 fftwf_destroy_plan(plan_fw);
213 fftwf_destroy_plan(plan_i_features);
214 fftwf_destroy_plan(plan_i_1ch);
216 if (BIG_BATCH_MODE) {
217 fftwf_destroy_plan(plan_f_all_scales);
218 fftwf_destroy_plan(plan_i_features_all_scales);
219 fftwf_destroy_plan(plan_fw_all_scales);