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)
21 m_num_of_feats = num_of_feats;
22 m_num_of_scales = num_of_scales;
24 #if (!defined(ASYNC) && !defined(CUFFTW)) && defined(OPENMP)
29 std::cout << "FFT: FFTW" << std::endl;
31 std::cout << "FFT: cuFFTW" << std::endl;
34 // FFT forward one scale
36 cv::Mat in_f = cv::Mat::zeros(int(m_height), int(m_width), CV_32FC1);
37 ComplexMat out_f(int(m_height), m_width / 2 + 1, 1);
38 plan_f = fftwf_plan_dft_r2c_2d(int(m_height), int(m_width), reinterpret_cast<float *>(in_f.data),
39 reinterpret_cast<fftwf_complex *>(out_f.get_p_data()), FFTW_PATIENT);
42 // FFT forward all scales
43 if (m_num_of_scales > 1 && BIG_BATCH_MODE) {
44 cv::Mat in_f_all = cv::Mat::zeros(m_height * m_num_of_scales, m_width, CV_32F);
45 ComplexMat out_f_all(m_height, m_width / 2 + 1, m_num_of_scales);
46 float *in = reinterpret_cast<float *>(in_f_all.data);
47 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(out_f_all.get_p_data());
49 int n[] = {(int)m_height, (int)m_width};
50 int howmany = m_num_of_scales;
51 int idist = m_height * m_width, odist = m_height * (m_width / 2 + 1);
52 int istride = 1, ostride = 1;
53 int *inembed = NULL, *onembed = NULL;
55 FFTW_PLAN_WITH_THREADS();
56 plan_f_all_scales = fftwf_plan_many_dft_r2c(rank, n, howmany, in, inembed, istride, idist, out, onembed,
57 ostride, odist, FFTW_PATIENT);
60 // FFT forward window one scale
62 cv::Mat in_fw = cv::Mat::zeros(int(m_height * m_num_of_feats), int(m_width), CV_32F);
63 ComplexMat out_fw(int(m_height), m_width / 2 + 1, int(m_num_of_feats));
64 float *in = reinterpret_cast<float *>(in_fw.data);
65 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(out_fw.get_p_data());
67 int n[] = {int(m_height), int(m_width)};
68 int howmany = int(m_num_of_feats);
69 int idist = int(m_height * m_width), odist = int(m_height * (m_width / 2 + 1));
70 int istride = 1, ostride = 1;
71 int *inembed = nullptr, *onembed = nullptr;
73 FFTW_PLAN_WITH_THREADS();
74 plan_fw = fftwf_plan_many_dft_r2c(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride, odist,
78 // FFT forward window all scales all feats
79 if (m_num_of_scales > 1 && BIG_BATCH_MODE) {
80 cv::Mat in_all = cv::Mat::zeros(m_height * (m_num_of_scales * m_num_of_feats), m_width, CV_32F);
81 ComplexMat out_all(m_height, m_width / 2 + 1, m_num_of_scales * m_num_of_feats);
82 float *in = reinterpret_cast<float *>(in_all.data);
83 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(out_all.get_p_data());
85 int n[] = {(int)m_height, (int)m_width};
86 int howmany = m_num_of_scales * m_num_of_feats;
87 int idist = m_height * m_width, odist = m_height * (m_width / 2 + 1);
88 int istride = 1, ostride = 1;
89 int *inembed = NULL, *onembed = NULL;
91 FFTW_PLAN_WITH_THREADS();
92 plan_fw_all_scales = fftwf_plan_many_dft_r2c(rank, n, howmany, in, inembed, istride, idist, out, onembed,
93 ostride, odist, FFTW_PATIENT);
96 // FFT inverse one scale
98 ComplexMat in_i(m_height, m_width, m_num_of_feats);
99 cv::Mat out_i = cv::Mat::zeros(int(m_height), int(m_width), CV_32FC(int(m_num_of_feats)));
100 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(in_i.get_p_data());
101 float *out = reinterpret_cast<float *>(out_i.data);
103 int n[] = {int(m_height), int(m_width)};
104 int howmany = int(m_num_of_feats);
105 int idist = int(m_height * (m_width / 2 + 1)), odist = 1;
106 int istride = 1, ostride = int(m_num_of_feats);
107 int inembed[] = {int(m_height), int(m_width / 2 + 1)}, *onembed = n;
109 FFTW_PLAN_WITH_THREADS();
110 plan_i_features = fftwf_plan_many_dft_c2r(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride,
111 odist, FFTW_PATIENT);
113 // FFT inverse all scales
115 if (m_num_of_scales > 1 && BIG_BATCH_MODE) {
116 ComplexMat in_i_all(m_height, m_width, m_num_of_feats * m_num_of_scales);
117 cv::Mat out_i_all = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_feats * m_num_of_scales));
118 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(in_i_all.get_p_data());
119 float *out = reinterpret_cast<float *>(out_i_all.data);
121 int n[] = {(int)m_height, (int)m_width};
122 int howmany = m_num_of_feats * m_num_of_scales;
123 int idist = m_height * (m_width / 2 + 1), odist = 1;
124 int istride = 1, ostride = m_num_of_feats * m_num_of_scales;
125 int inembed[] = {(int)m_height, (int)m_width / 2 + 1}, *onembed = n;
127 FFTW_PLAN_WITH_THREADS();
128 plan_i_features_all_scales = fftwf_plan_many_dft_c2r(rank, n, howmany, in, inembed, istride, idist, out,
129 onembed, ostride, odist, FFTW_PATIENT);
132 // FFT inver one channel one scale
134 ComplexMat in_i1(int(m_height), int(m_width), 1);
135 cv::Mat out_i1 = cv::Mat::zeros(int(m_height), int(m_width), CV_32FC1);
136 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(in_i1.get_p_data());
137 float *out = reinterpret_cast<float *>(out_i1.data);
139 int n[] = {int(m_height), int(m_width)};
141 int idist = int(m_height * (m_width / 2 + 1)), odist = 1;
142 int istride = 1, ostride = 1;
143 int inembed[] = {int(m_height), int(m_width) / 2 + 1}, *onembed = n;
145 FFTW_PLAN_WITH_THREADS();
146 plan_i_1ch = fftwf_plan_many_dft_c2r(rank, n, howmany, in, inembed, istride, idist, out, onembed, ostride,
147 odist, FFTW_PATIENT);
150 // FFT inver one channel all scales
151 if (m_num_of_scales > 1 && BIG_BATCH_MODE) {
152 ComplexMat in_i1_all(m_height, m_width, m_num_of_scales);
153 cv::Mat out_i1_all = cv::Mat::zeros(m_height, m_width, CV_32FC(m_num_of_scales));
154 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(in_i1_all.get_p_data());
155 float *out = reinterpret_cast<float *>(out_i1_all.data);
157 int n[] = {(int)m_height, (int)m_width};
158 int howmany = m_num_of_scales;
159 int idist = m_height * (m_width / 2 + 1), odist = 1;
160 int istride = 1, ostride = m_num_of_scales;
161 int inembed[] = {(int)m_height, (int)m_width / 2 + 1}, *onembed = n;
163 FFTW_PLAN_WITH_THREADS();
164 plan_i_1ch_all_scales = fftwf_plan_many_dft_c2r(rank, n, howmany, in, inembed, istride, idist, out, onembed,
165 ostride, odist, FFTW_PATIENT);
170 void Fftw::set_window(const MatDynMem &window)
175 void Fftw::forward(const cv::Mat & real_input, ComplexMat & complex_result)
177 if (BIG_BATCH_MODE && real_input.rows == int(m_height * m_num_of_scales)) {
178 fftwf_execute_dft_r2c(plan_f_all_scales, reinterpret_cast<float *>(real_input.data),
179 reinterpret_cast<fftwf_complex *>(complex_result.get_p_data()));
181 fftwf_execute_dft_r2c(plan_f, reinterpret_cast<float *>(real_input.data),
182 reinterpret_cast<fftwf_complex *>(complex_result.get_p_data()));
187 void Fftw::forward_window(MatDynMem &feat, ComplexMat & complex_result, MatDynMem &temp)
189 assert(is_patch_feats_valid(feat));
191 int n_channels = feat.size[0];
192 for (int i = 0; i < n_channels; ++i) {
193 cv::Mat feat_plane(feat.dims - 1, feat.size + 1, feat.cv::Mat::type(), feat.ptr<void>(i));
194 cv::Mat temp_plane(temp.dims - 1, temp.size + 1, temp.cv::Mat::type(), temp.ptr(i));
195 temp_plane = feat_plane.mul(m_window);
198 float *in = temp.ptr<float>();
199 fftwf_complex *out = reinterpret_cast<fftwf_complex *>(complex_result.get_p_data());
201 if (n_channels <= int(m_num_of_feats))
202 fftwf_execute_dft_r2c(plan_fw, in, out);
204 fftwf_execute_dft_r2c(plan_fw_all_scales, in, out);
208 void Fftw::inverse(ComplexMat & complex_input, MatDynMem & real_result)
210 int n_channels = complex_input.n_channels;
211 fftwf_complex *in = reinterpret_cast<fftwf_complex *>(complex_input.get_p_data());
212 float *out = real_result.ptr<float>();
215 fftwf_execute_dft_c2r(plan_i_1ch, in, out);
216 else if (BIG_BATCH_MODE && n_channels == int(m_num_of_scales))
217 fftwf_execute_dft_c2r(plan_i_1ch_all_scales, in, out);
218 else if (BIG_BATCH_MODE && n_channels == int(m_num_of_feats) * int(m_num_of_scales))
219 fftwf_execute_dft_c2r(plan_i_features_all_scales, in, out);
221 fftwf_execute_dft_c2r(plan_i_features, in, out);
223 real_result = real_result / (m_width * m_height);
228 fftwf_destroy_plan(plan_f);
229 fftwf_destroy_plan(plan_fw);
230 fftwf_destroy_plan(plan_i_features);
231 fftwf_destroy_plan(plan_i_1ch);
233 if (BIG_BATCH_MODE) {
234 fftwf_destroy_plan(plan_f_all_scales);
235 fftwf_destroy_plan(plan_i_features_all_scales);
236 fftwf_destroy_plan(plan_fw_all_scales);
237 fftwf_destroy_plan(plan_i_1ch_all_scales);