ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkFFTWCommon.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkFFTWCommon_h
19#define itkFFTWCommon_h
20
21#if defined(ITK_USE_FFTWF) || defined(ITK_USE_FFTWD)
22# if defined(ITK_USE_CUFFTW)
23# include "cufftw.h"
24# else
26# include "fftw3.h"
27# endif
28# if !defined(FFTW_WISDOM_ONLY)
29// FFTW_WISDOM_ONLY is a "beyond guru" option that is only available in fftw 3.2.2
30// to be compatible with all the fftw 3.x API, we need to define this away here:
31# error "FFTW 3.3.2 or later is required so that FFTW_WISDOM_ONLY is defined."
32# endif
33
34#endif
35
36#include <mutex>
37
38namespace itk
39{
40namespace fftw
41{
53template <typename TPixel>
54class Proxy
55{
56 // empty -- only double and float specializations work
57
58protected:
59 Proxy() = default;
60 ~Proxy() = default;
61};
62
63#if defined(ITK_USE_FFTWF)
64
65template <>
66class Proxy<float>
67{
68public:
69 using PixelType = float;
70 using ComplexType = fftwf_complex;
71 using PlanType = fftwf_plan;
72 using Self = Proxy<float>;
73
74 // FFTW works with any data size, but is optimized for size decomposition with prime factors up to 13.
75# ifdef ITK_USE_CUFFTW
76 static constexpr SizeValueType GREATEST_PRIME_FACTOR = 7;
77# else
78 static constexpr SizeValueType GREATEST_PRIME_FACTOR = 13;
79# endif
80
81 static PlanType
82 Plan_dft_c2r_1d(int n,
83 ComplexType * in,
84 PixelType * out,
85 unsigned int flags,
86 int threads = 1,
87 bool canDestroyInput = false)
88 {
89 return Plan_dft_c2r(1, &n, in, out, flags, threads, canDestroyInput);
90 }
91
92 static PlanType
93 Plan_dft_c2r_2d(int nx,
94 int ny,
95 ComplexType * in,
96 PixelType * out,
97 unsigned int flags,
98 int threads = 1,
99 bool canDestroyInput = false)
100 {
101 int sizes[2];
102 sizes[0] = nx;
103 sizes[1] = ny;
104 PlanType plan = Plan_dft_c2r(2, sizes, in, out, flags, threads, canDestroyInput);
105 return plan;
106 }
107
108 static PlanType
109 Plan_dft_c2r_3d(int nx,
110 int ny,
111 int nz,
112 ComplexType * in,
113 PixelType * out,
114 unsigned int flags,
115 int threads = 1,
116 bool canDestroyInput = false)
117 {
118 int sizes[3];
119 sizes[0] = nx;
120 sizes[1] = ny;
121 sizes[2] = nz;
122 PlanType plan = Plan_dft_c2r(3, sizes, in, out, flags, threads, canDestroyInput);
123 return plan;
124 }
125
126 static PlanType
127 Plan_dft_c2r(int rank,
128 const int * n,
129 ComplexType * in,
130 PixelType * out,
131 unsigned int flags,
132 [[maybe_unused]] int threads = 1,
133 bool canDestroyInput = false)
134 {
135# ifndef ITK_USE_CUFFTW
136 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
137 fftwf_plan_with_nthreads(threads);
138# endif
139 // don't add FFTW_WISDOM_ONLY if the plan rigor is FFTW_ESTIMATE
140 // because FFTW_ESTIMATE guarantee to not destroy the input
141 unsigned int roflags = flags;
142 if (!(flags & FFTW_ESTIMATE))
143 {
144 roflags = flags | FFTW_WISDOM_ONLY;
145 }
146 PlanType plan = fftwf_plan_dft_c2r(rank, n, in, out, roflags);
147 if (plan == nullptr)
148 {
149 // no wisdom available for that plan
150 if (canDestroyInput)
151 {
152 // just create the plan
153 plan = fftwf_plan_dft_c2r(rank, n, in, out, flags);
154 }
155 else
156 {
157 // lets create a plan with a fake input to generate the wisdom
158 int total = 1;
159 for (int i = 0; i < rank; ++i)
160 {
161 total *= n[i];
162 }
163 auto * din = new ComplexType[total];
164 fftwf_plan_dft_c2r(rank, n, din, out, flags);
165 delete[] din;
166 // and then create the final plan - this time it shouldn't fail
167 plan = fftwf_plan_dft_c2r(rank, n, in, out, roflags);
168 }
169# ifndef ITK_USE_CUFFTW
171# endif
172 }
173 itkAssertOrThrowMacro(plan != nullptr, "PLAN_CREATION_FAILED ");
174 return plan;
175 }
176
177
178 static PlanType
179 Plan_dft_r2c_1d(int n,
180 PixelType * in,
181 ComplexType * out,
182 unsigned int flags,
183 int threads = 1,
184 bool canDestroyInput = false)
185 {
186 return Plan_dft_r2c(1, &n, in, out, flags, threads, canDestroyInput);
187 }
188
189 static PlanType
190 Plan_dft_r2c_2d(int nx,
191 int ny,
192 PixelType * in,
193 ComplexType * out,
194 unsigned int flags,
195 int threads = 1,
196 bool canDestroyInput = false)
197 {
198 int sizes[2];
199 sizes[0] = nx;
200 sizes[1] = ny;
201 PlanType plan = Plan_dft_r2c(2, sizes, in, out, flags, threads, canDestroyInput);
202 return plan;
203 }
204
205 static PlanType
206 Plan_dft_r2c_3d(int nx,
207 int ny,
208 int nz,
209 PixelType * in,
210 ComplexType * out,
211 unsigned int flags,
212 int threads = 1,
213 bool canDestroyInput = false)
214 {
215 int sizes[3];
216 sizes[0] = nx;
217 sizes[1] = ny;
218 sizes[2] = nz;
219 PlanType plan = Plan_dft_r2c(3, sizes, in, out, flags, threads, canDestroyInput);
220 return plan;
221 }
222
223 static PlanType
224 Plan_dft_r2c(int rank,
225 const int * n,
226 PixelType * in,
227 ComplexType * out,
228 unsigned int flags,
229 [[maybe_unused]] int threads = 1,
230 bool canDestroyInput = false)
231 {
232 //
233# ifndef ITK_USE_CUFFTW
234 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
235 fftwf_plan_with_nthreads(threads);
236# endif
237 // don't add FFTW_WISDOM_ONLY if the plan rigor is FFTW_ESTIMATE
238 // because FFTW_ESTIMATE guarantee to not destroy the input
239 unsigned int roflags = flags;
240 if (!(flags & FFTW_ESTIMATE))
241 {
242 roflags = flags | FFTW_WISDOM_ONLY;
243 }
244 PlanType plan = fftwf_plan_dft_r2c(rank, n, in, out, roflags);
245 if (plan == nullptr)
246 {
247 // no wisdom available for that plan
248 if (canDestroyInput)
249 {
250 // just create the plan
251 plan = fftwf_plan_dft_r2c(rank, n, in, out, flags);
252 }
253 else
254 {
255 // lets create a plan with a fake input to generate the wisdom
256 int total = 1;
257 for (int i = 0; i < rank; ++i)
258 {
259 total *= n[i];
260 }
261 auto * din = new PixelType[total];
262 fftwf_plan_dft_r2c(rank, n, din, out, flags);
263 delete[] din;
264 // and then create the final plan - this time it shouldn't fail
265 plan = fftwf_plan_dft_r2c(rank, n, in, out, roflags);
266 }
267# ifndef ITK_USE_CUFFTW
269# endif
270 }
271 itkAssertOrThrowMacro(plan != nullptr, "PLAN_CREATION_FAILED ");
272 return plan;
273 }
274
275 static PlanType
276 Plan_dft_1d(int n,
277 ComplexType * in,
278 ComplexType * out,
279 int sign,
280 unsigned int flags,
281 int threads = 1,
282 bool canDestroyInput = false)
283 {
284 return Plan_dft(1, &n, in, out, sign, flags, threads, canDestroyInput);
285 }
286
287 static PlanType
288 Plan_dft_2d(int nx,
289 int ny,
290 ComplexType * in,
291 ComplexType * out,
292 int sign,
293 unsigned int flags,
294 int threads = 1,
295 bool canDestroyInput = false)
296 {
297 int sizes[2];
298 sizes[0] = nx;
299 sizes[1] = ny;
300 PlanType plan = Plan_dft(2, sizes, in, out, sign, flags, threads, canDestroyInput);
301 return plan;
302 }
303
304 static PlanType
305 Plan_dft_3d(int nx,
306 int ny,
307 int nz,
308 ComplexType * in,
309 ComplexType * out,
310 int sign,
311 unsigned int flags,
312 int threads = 1,
313 bool canDestroyInput = false)
314 {
315 int sizes[3];
316 sizes[0] = nx;
317 sizes[1] = ny;
318 sizes[2] = nz;
319 PlanType plan = Plan_dft(3, sizes, in, out, sign, flags, threads, canDestroyInput);
320 return plan;
321 }
322
323 static PlanType
324 Plan_dft(int rank,
325 const int * n,
326 ComplexType * in,
327 ComplexType * out,
328 int sign,
329 unsigned int flags,
330 [[maybe_unused]] int threads = 1,
331 bool canDestroyInput = false)
332 {
333# ifndef ITK_USE_CUFFTW
334 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
335 fftwf_plan_with_nthreads(threads);
336# endif
337 // don't add FFTW_WISDOM_ONLY if the plan rigor is FFTW_ESTIMATE
338 // because FFTW_ESTIMATE guarantee to not destroy the input
339 unsigned int roflags = flags;
340 if (!(flags & FFTW_ESTIMATE))
341 {
342 roflags = flags | FFTW_WISDOM_ONLY;
343 }
344 PlanType plan = fftwf_plan_dft(rank, n, in, out, sign, roflags);
345 if (plan == nullptr)
346 {
347 // no wisdom available for that plan
348 if (canDestroyInput)
349 {
350 // just create the plan
351 plan = fftwf_plan_dft(rank, n, in, out, sign, flags);
352 }
353 else
354 {
355 // lets create a plan with a fake input to generate the wisdom
356 int total = 1;
357 for (int i = 0; i < rank; ++i)
358 {
359 total *= n[i];
360 }
361 auto * din = new ComplexType[total];
362 fftwf_plan_dft(rank, n, din, out, sign, flags);
363 delete[] din;
364 // and then create the final plan - this time it shouldn't fail
365 plan = fftwf_plan_dft(rank, n, in, out, sign, roflags);
366 }
367# ifndef ITK_USE_CUFFTW
369# endif
370 }
371 itkAssertOrThrowMacro(plan != nullptr, "PLAN_CREATION_FAILED ");
372 return plan;
373 }
374
375
376 static PlanType
377 Plan_r2r(int rank,
378 const int * n,
379 PixelType * in,
380 PixelType * out,
381 const fftw_r2r_kind * kind,
382 unsigned int flags,
383 [[maybe_unused]] int threads = 1,
384 bool canDestroyInput = false)
385 {
386# ifndef ITK_USE_CUFFTW
387 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
388 fftwf_plan_with_nthreads(threads);
389# endif
390 unsigned int roflags = flags;
391 if (!(flags & FFTW_ESTIMATE))
392 {
393 roflags = flags | FFTW_WISDOM_ONLY;
394 }
395 PlanType plan = fftwf_plan_r2r(rank, n, in, out, kind, roflags);
396 if (plan == nullptr)
397 {
398 if (canDestroyInput)
399 {
400 plan = fftwf_plan_r2r(rank, n, in, out, kind, flags);
401 }
402 else
403 {
404 int total = 1;
405 for (int i = 0; i < rank; ++i)
406 {
407 total *= n[i];
408 }
409 auto * din = new PixelType[total];
410 fftwf_plan_r2r(rank, n, din, out, kind, flags);
411 delete[] din;
412 plan = fftwf_plan_r2r(rank, n, in, out, kind, roflags);
413 }
414# ifndef ITK_USE_CUFFTW
416# endif
417 }
418 itkAssertOrThrowMacro(plan != nullptr, "PLAN_CREATION_FAILED ");
419 return plan;
420 }
421
422 static void
423 Execute(PlanType p)
424 {
425 fftwf_execute(p);
426 }
427 static void
428 DestroyPlan(PlanType p)
429 {
430# ifndef ITK_USE_CUFFTW
431 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
432# endif
433 fftwf_destroy_plan(p);
434 }
435};
436
437#endif // ITK_USE_FFTWF
438
439
440#if defined(ITK_USE_FFTWD)
441template <>
442class Proxy<double>
443{
444public:
445 using PixelType = double;
446 using ComplexType = fftw_complex;
447 using PlanType = fftw_plan;
448 using Self = Proxy<double>;
449
450 // FFTW works with any data size, but is optimized for size decomposition with prime factors up to 13.
451# ifdef ITK_USE_CUFFTW
452 static constexpr SizeValueType GREATEST_PRIME_FACTOR = 7;
453# else
454 static constexpr SizeValueType GREATEST_PRIME_FACTOR = 13;
455# endif
456
457 static PlanType
458 Plan_dft_c2r_1d(int n,
459 ComplexType * in,
460 PixelType * out,
461 unsigned int flags,
462 int threads = 1,
463 bool canDestroyInput = false)
464 {
465 return Plan_dft_c2r(1, &n, in, out, flags, threads, canDestroyInput);
466 }
467
468 static PlanType
469 Plan_dft_c2r_2d(int nx,
470 int ny,
471 ComplexType * in,
472 PixelType * out,
473 unsigned int flags,
474 int threads = 1,
475 bool canDestroyInput = false)
476 {
477 int sizes[2];
478 sizes[0] = nx;
479 sizes[1] = ny;
480 PlanType plan = Plan_dft_c2r(2, sizes, in, out, flags, threads, canDestroyInput);
481 return plan;
482 }
483
484 static PlanType
485 Plan_dft_c2r_3d(int nx,
486 int ny,
487 int nz,
488 ComplexType * in,
489 PixelType * out,
490 unsigned int flags,
491 int threads = 1,
492 bool canDestroyInput = false)
493 {
494 int sizes[3];
495 sizes[0] = nx;
496 sizes[1] = ny;
497 sizes[2] = nz;
498 PlanType plan = Plan_dft_c2r(3, sizes, in, out, flags, threads, canDestroyInput);
499 return plan;
500 }
501
502 static PlanType
503 Plan_dft_c2r(int rank,
504 const int * n,
505 ComplexType * in,
506 PixelType * out,
507 unsigned int flags,
508 [[maybe_unused]] int threads = 1,
509 bool canDestroyInput = false)
510 {
511# ifndef ITK_USE_CUFFTW
512 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
513 fftw_plan_with_nthreads(threads);
514# endif
515 // don't add FFTW_WISDOM_ONLY if the plan rigor is FFTW_ESTIMATE
516 // because FFTW_ESTIMATE guarantee to not destroy the input
517 unsigned int roflags = flags;
518 if (!(flags & FFTW_ESTIMATE))
519 {
520 roflags = flags | FFTW_WISDOM_ONLY;
521 }
522 PlanType plan = fftw_plan_dft_c2r(rank, n, in, out, roflags);
523 if (plan == nullptr)
524 {
525 // no wisdom available for that plan
526 if (canDestroyInput)
527 {
528 // just create the plan
529 plan = fftw_plan_dft_c2r(rank, n, in, out, flags);
530 }
531 else
532 {
533 // lets create a plan with a fake input to generate the wisdom
534 int total = 1;
535 for (int i = 0; i < rank; ++i)
536 {
537 total *= n[i];
538 }
539 auto * din = new ComplexType[total];
540 fftw_plan_dft_c2r(rank, n, din, out, flags);
541 delete[] din;
542 // and then create the final plan - this time it shouldn't fail
543 plan = fftw_plan_dft_c2r(rank, n, in, out, roflags);
544 }
545# ifndef ITK_USE_CUFFTW
547# endif
548 }
549 itkAssertOrThrowMacro(plan != nullptr, "PLAN_CREATION_FAILED ");
550 return plan;
551 }
552
553
554 static PlanType
555 Plan_dft_r2c_1d(int n,
556 PixelType * in,
557 ComplexType * out,
558 unsigned int flags,
559 int threads = 1,
560 bool canDestroyInput = false)
561 {
562 return Plan_dft_r2c(1, &n, in, out, flags, threads, canDestroyInput);
563 }
564
565 static PlanType
566 Plan_dft_r2c_2d(int nx,
567 int ny,
568 PixelType * in,
569 ComplexType * out,
570 unsigned int flags,
571 int threads = 1,
572 bool canDestroyInput = false)
573 {
574 int sizes[2];
575 sizes[0] = nx;
576 sizes[1] = ny;
577 PlanType plan = Plan_dft_r2c(2, sizes, in, out, flags, threads, canDestroyInput);
578 return plan;
579 }
580
581 static PlanType
582 Plan_dft_r2c_3d(int nx,
583 int ny,
584 int nz,
585 PixelType * in,
586 ComplexType * out,
587 unsigned int flags,
588 int threads = 1,
589 bool canDestroyInput = false)
590 {
591 int sizes[3];
592 sizes[0] = nx;
593 sizes[1] = ny;
594 sizes[2] = nz;
595 PlanType plan = Plan_dft_r2c(3, sizes, in, out, flags, threads, canDestroyInput);
596 return plan;
597 }
598
599 static PlanType
600 Plan_dft_r2c(int rank,
601 const int * n,
602 PixelType * in,
603 ComplexType * out,
604 unsigned int flags,
605 [[maybe_unused]] int threads = 1,
606 bool canDestroyInput = false)
607 {
608# ifndef ITK_USE_CUFFTW
609 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
610 fftw_plan_with_nthreads(threads);
611# endif
612 // don't add FFTW_WISDOM_ONLY if the plan rigor is FFTW_ESTIMATE
613 // because FFTW_ESTIMATE guarantee to not destroy the input
614 unsigned int roflags = flags;
615 if (!(flags & FFTW_ESTIMATE))
616 {
617 roflags = flags | FFTW_WISDOM_ONLY;
618 }
619 PlanType plan = fftw_plan_dft_r2c(rank, n, in, out, roflags);
620 if (plan == nullptr)
621 {
622 // no wisdom available for that plan
623 if (canDestroyInput)
624 {
625 // just create the plan
626 plan = fftw_plan_dft_r2c(rank, n, in, out, flags);
627 }
628 else
629 {
630 // lets create a plan with a fake input to generate the wisdom
631 int total = 1;
632 for (int i = 0; i < rank; ++i)
633 {
634 total *= n[i];
635 }
636 auto * din = new PixelType[total];
637 fftw_plan_dft_r2c(rank, n, din, out, flags);
638 delete[] din;
639 // and then create the final plan - this time it shouldn't fail
640 plan = fftw_plan_dft_r2c(rank, n, in, out, roflags);
641 }
642# ifndef ITK_USE_CUFFTW
644# endif
645 }
646 itkAssertOrThrowMacro(plan != nullptr, "PLAN_CREATION_FAILED ");
647 return plan;
648 }
649
650 static PlanType
651 Plan_dft_1d(int n,
652 ComplexType * in,
653 ComplexType * out,
654 int sign,
655 unsigned int flags,
656 int threads = 1,
657 bool canDestroyInput = false)
658 {
659 return Plan_dft(1, &n, in, out, sign, flags, threads, canDestroyInput);
660 }
661
662 static PlanType
663 Plan_dft_2d(int nx,
664 int ny,
665 ComplexType * in,
666 ComplexType * out,
667 int sign,
668 unsigned int flags,
669 int threads = 1,
670 bool canDestroyInput = false)
671 {
672 int sizes[2];
673 sizes[0] = nx;
674 sizes[1] = ny;
675 PlanType plan = Plan_dft(2, sizes, in, out, sign, flags, threads, canDestroyInput);
676 return plan;
677 }
678
679 static PlanType
680 Plan_dft_3d(int nx,
681 int ny,
682 int nz,
683 ComplexType * in,
684 ComplexType * out,
685 int sign,
686 unsigned int flags,
687 int threads = 1,
688 bool canDestroyInput = false)
689 {
690 int sizes[3];
691 sizes[0] = nx;
692 sizes[1] = ny;
693 sizes[2] = nz;
694 PlanType plan = Plan_dft(3, sizes, in, out, sign, flags, threads, canDestroyInput);
695 return plan;
696 }
697
698 static PlanType
699 Plan_dft(int rank,
700 const int * n,
701 ComplexType * in,
702 ComplexType * out,
703 int sign,
704 unsigned int flags,
705 [[maybe_unused]] int threads = 1,
706 bool canDestroyInput = false)
707 {
708# ifndef ITK_USE_CUFFTW
709 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
710 fftw_plan_with_nthreads(threads);
711# endif
712 // don't add FFTW_WISDOM_ONLY if the plan rigor is FFTW_ESTIMATE
713 // because FFTW_ESTIMATE guarantee to not destroy the input
714 unsigned int roflags = flags;
715 if (!(flags & FFTW_ESTIMATE))
716 {
717 roflags = flags | FFTW_WISDOM_ONLY;
718 }
719 PlanType plan = fftw_plan_dft(rank, n, in, out, sign, roflags);
720 if (plan == nullptr)
721 {
722 // no wisdom available for that plan
723 if (canDestroyInput)
724 {
725 // just create the plan
726 plan = fftw_plan_dft(rank, n, in, out, sign, flags);
727 }
728 else
729 {
730 // lets create a plan with a fake input to generate the wisdom
731 int total = 1;
732 for (int i = 0; i < rank; ++i)
733 {
734 total *= n[i];
735 }
736 auto * din = new ComplexType[total];
737 fftw_plan_dft(rank, n, din, out, sign, flags);
738 delete[] din;
739 // and then create the final plan - this time it shouldn't fail
740 plan = fftw_plan_dft(rank, n, in, out, sign, roflags);
741 }
742# ifndef ITK_USE_CUFFTW
744# endif
745 }
746 itkAssertOrThrowMacro(plan != nullptr, "PLAN_CREATION_FAILED ");
747 return plan;
748 }
749
750
751 static PlanType
752 Plan_r2r(int rank,
753 const int * n,
754 PixelType * in,
755 PixelType * out,
756 const fftw_r2r_kind * kind,
757 unsigned int flags,
758 [[maybe_unused]] int threads = 1,
759 bool canDestroyInput = false)
760 {
761# ifndef ITK_USE_CUFFTW
762 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
763 fftw_plan_with_nthreads(threads);
764# endif
765 unsigned int roflags = flags;
766 if (!(flags & FFTW_ESTIMATE))
767 {
768 roflags = flags | FFTW_WISDOM_ONLY;
769 }
770 PlanType plan = fftw_plan_r2r(rank, n, in, out, kind, roflags);
771 if (plan == nullptr)
772 {
773 if (canDestroyInput)
774 {
775 plan = fftw_plan_r2r(rank, n, in, out, kind, flags);
776 }
777 else
778 {
779 int total = 1;
780 for (int i = 0; i < rank; ++i)
781 {
782 total *= n[i];
783 }
784 auto * din = new PixelType[total];
785 fftw_plan_r2r(rank, n, din, out, kind, flags);
786 delete[] din;
787 plan = fftw_plan_r2r(rank, n, in, out, kind, roflags);
788 }
789# ifndef ITK_USE_CUFFTW
791# endif
792 }
793 itkAssertOrThrowMacro(plan != nullptr, "PLAN_CREATION_FAILED ");
794 return plan;
795 }
796
797 static void
798 Execute(PlanType p)
799 {
800 fftw_execute(p);
801 }
802 static void
803 DestroyPlan(PlanType p)
804 {
805# ifndef ITK_USE_CUFFTW
806 const std::lock_guard<FFTWGlobalConfiguration::MutexType> lockGuard(FFTWGlobalConfiguration::GetLockMutex());
807# endif
808 fftw_destroy_plan(p);
809 }
810};
811
812#endif
813} // end namespace fftw
814} // end namespace itk
815#endif
static std::mutex & GetLockMutex()
static void SetNewWisdomAvailable(const bool v)
~Proxy()=default
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
unsigned long SizeValueType
Definition itkIntTypes.h:86