Skip to content

Commit 0ed533c

Browse files
authored
Merge pull request #6073 from SimonRit/fftw_required_factories
BUG: Register FFTW factories in test drivers if ITK_USE_FFTW* is ON
2 parents 713ef22 + 8cbd742 commit 0ed533c

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed

Modules/Core/TestKernel/src/itkTestDriverIncludeRequiredFactories.cxx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@
4141
#include "itkOFFMeshIOFactory.h"
4242
#include "itkVTKPolyDataMeshIOFactory.h"
4343

44+
// FFTW
45+
#include "itkConfigure.h"
46+
#if defined(ITK_USE_FFTWF) || defined(ITK_USE_FFTWD)
47+
# include "itkFFTWComplexToComplex1DFFTImageFilter.h"
48+
# include "itkFFTWComplexToComplexFFTImageFilter.h"
49+
# include "itkFFTWForward1DFFTImageFilter.h"
50+
# include "itkFFTWForwardFFTImageFilter.h"
51+
# include "itkFFTWHalfHermitianToRealInverseFFTImageFilter.h"
52+
# include "itkFFTWInverse1DFFTImageFilter.h"
53+
# include "itkFFTWInverseFFTImageFilter.h"
54+
# include "itkFFTWRealToHalfHermitianForwardFFTImageFilter.h"
55+
#endif
56+
4457
// FFT
4558
#include "itkFFTImageFilterFactory.h"
4659
#include "itkVnlComplexToComplex1DFFTImageFilter.h"
@@ -92,6 +105,19 @@ RegisterRequiredIOFactories()
92105
void
93106
RegisterRequiredFFTFactories()
94107
{
108+
#if defined(ITK_USE_FFTWF) || defined(ITK_USE_FFTWD)
109+
itk::ObjectFactoryBase::RegisterFactory(itk::FFTImageFilterFactory<itk::FFTWComplexToComplex1DFFTImageFilter>::New());
110+
itk::ObjectFactoryBase::RegisterFactory(itk::FFTImageFilterFactory<itk::FFTWComplexToComplexFFTImageFilter>::New());
111+
itk::ObjectFactoryBase::RegisterFactory(itk::FFTImageFilterFactory<itk::FFTWForward1DFFTImageFilter>::New());
112+
itk::ObjectFactoryBase::RegisterFactory(itk::FFTImageFilterFactory<itk::FFTWForwardFFTImageFilter>::New());
113+
itk::ObjectFactoryBase::RegisterFactory(
114+
itk::FFTImageFilterFactory<itk::FFTWHalfHermitianToRealInverseFFTImageFilter>::New());
115+
itk::ObjectFactoryBase::RegisterFactory(itk::FFTImageFilterFactory<itk::FFTWInverse1DFFTImageFilter>::New());
116+
itk::ObjectFactoryBase::RegisterFactory(itk::FFTImageFilterFactory<itk::FFTWInverseFFTImageFilter>::New());
117+
itk::ObjectFactoryBase::RegisterFactory(
118+
itk::FFTImageFilterFactory<itk::FFTWRealToHalfHermitianForwardFFTImageFilter>::New());
119+
#endif
120+
95121
itk::ObjectFactoryBase::RegisterFactory(itk::FFTImageFilterFactory<itk::VnlComplexToComplex1DFFTImageFilter>::New());
96122
itk::ObjectFactoryBase::RegisterFactory(itk::FFTImageFilterFactory<itk::VnlComplexToComplexFFTImageFilter>::New());
97123
itk::ObjectFactoryBase::RegisterFactory(itk::FFTImageFilterFactory<itk::VnlForward1DFFTImageFilter>::New());

Modules/Filtering/FFT/test/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,3 +607,9 @@ if(ITK_USE_FFTWF OR ITK_USE_FFTWD)
607607
2
608608
)
609609
endif()
610+
611+
# GTests for FFTW factory registration verification
612+
if(ITK_USE_FFTWF OR ITK_USE_FFTWD)
613+
set(ITKFFTGTests itkFFTWFactoryRegistrationGTest.cxx)
614+
creategoogletestdriver(ITKFFT "${ITKFFT-Test_LIBRARIES}" "${ITKFFTGTests}")
615+
endif()
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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+
19+
#include "gtest/gtest.h"
20+
#include "itkConfigure.h"
21+
22+
#if defined(ITK_USE_FFTWF) || defined(ITK_USE_FFTWD)
23+
24+
# include "itkImage.h"
25+
# include "itkForwardFFTImageFilter.h"
26+
# include "itkInverseFFTImageFilter.h"
27+
# include "itkForward1DFFTImageFilter.h"
28+
# include "itkInverse1DFFTImageFilter.h"
29+
# include "itkComplexToComplexFFTImageFilter.h"
30+
# include "itkComplexToComplex1DFFTImageFilter.h"
31+
# include "itkRealToHalfHermitianForwardFFTImageFilter.h"
32+
# include "itkHalfHermitianToRealInverseFFTImageFilter.h"
33+
# include "itkTestDriverIncludeRequiredFactories.h"
34+
# include <complex>
35+
# include <string>
36+
37+
namespace
38+
{
39+
40+
// Call RegisterRequiredFactories() once for the entire test suite.
41+
class FFTWFactoryRegistrationTestSuite : public ::testing::Test
42+
{
43+
protected:
44+
static void
45+
SetUpTestSuite()
46+
{
47+
RegisterRequiredFactories();
48+
}
49+
};
50+
51+
// Helper: verify the filter created by New() has "FFTW" in its class name.
52+
void
53+
ExpectFFTWBackend(const itk::LightObject * filter, const std::string & filterDescription)
54+
{
55+
ASSERT_NE(filter, nullptr) << filterDescription << "::New() returned nullptr";
56+
const std::string name = filter->GetNameOfClass();
57+
EXPECT_NE(name.find("FFTW"), std::string::npos)
58+
<< filterDescription << "::New() resolved to '" << name << "' (expected FFTW backend)";
59+
}
60+
61+
} // namespace
62+
63+
64+
# if defined(ITK_USE_FFTWF)
65+
66+
using FloatImage2D = itk::Image<float, 2>;
67+
using FloatComplexImage2D = itk::Image<std::complex<float>, 2>;
68+
69+
TEST_F(FFTWFactoryRegistrationTestSuite, ForwardFFT_float)
70+
{
71+
auto filter = itk::ForwardFFTImageFilter<FloatImage2D>::New();
72+
ExpectFFTWBackend(filter, "ForwardFFTImageFilter<float>");
73+
}
74+
75+
TEST_F(FFTWFactoryRegistrationTestSuite, InverseFFT_float)
76+
{
77+
auto filter = itk::InverseFFTImageFilter<FloatComplexImage2D, FloatImage2D>::New();
78+
ExpectFFTWBackend(filter, "InverseFFTImageFilter<float>");
79+
}
80+
81+
TEST_F(FFTWFactoryRegistrationTestSuite, Forward1DFFT_float)
82+
{
83+
auto filter = itk::Forward1DFFTImageFilter<FloatImage2D>::New();
84+
ExpectFFTWBackend(filter, "Forward1DFFTImageFilter<float>");
85+
}
86+
87+
TEST_F(FFTWFactoryRegistrationTestSuite, Inverse1DFFT_float)
88+
{
89+
auto filter = itk::Inverse1DFFTImageFilter<FloatComplexImage2D, FloatImage2D>::New();
90+
ExpectFFTWBackend(filter, "Inverse1DFFTImageFilter<float>");
91+
}
92+
93+
TEST_F(FFTWFactoryRegistrationTestSuite, ComplexToComplexFFT_float)
94+
{
95+
auto filter = itk::ComplexToComplexFFTImageFilter<FloatComplexImage2D>::New();
96+
ExpectFFTWBackend(filter, "ComplexToComplexFFTImageFilter<float>");
97+
}
98+
99+
TEST_F(FFTWFactoryRegistrationTestSuite, ComplexToComplex1DFFT_float)
100+
{
101+
auto filter = itk::ComplexToComplex1DFFTImageFilter<FloatComplexImage2D>::New();
102+
ExpectFFTWBackend(filter, "ComplexToComplex1DFFTImageFilter<float>");
103+
}
104+
105+
TEST_F(FFTWFactoryRegistrationTestSuite, RealToHalfHermitianForwardFFT_float)
106+
{
107+
auto filter = itk::RealToHalfHermitianForwardFFTImageFilter<FloatImage2D>::New();
108+
ExpectFFTWBackend(filter, "RealToHalfHermitianForwardFFTImageFilter<float>");
109+
}
110+
111+
TEST_F(FFTWFactoryRegistrationTestSuite, HalfHermitianToRealInverseFFT_float)
112+
{
113+
auto filter = itk::HalfHermitianToRealInverseFFTImageFilter<FloatComplexImage2D, FloatImage2D>::New();
114+
ExpectFFTWBackend(filter, "HalfHermitianToRealInverseFFTImageFilter<float>");
115+
}
116+
117+
# endif // ITK_USE_FFTWF
118+
119+
120+
# if defined(ITK_USE_FFTWD)
121+
122+
using DoubleImage2D = itk::Image<double, 2>;
123+
using DoubleComplexImage2D = itk::Image<std::complex<double>, 2>;
124+
125+
TEST_F(FFTWFactoryRegistrationTestSuite, ForwardFFT_double)
126+
{
127+
auto filter = itk::ForwardFFTImageFilter<DoubleImage2D>::New();
128+
ExpectFFTWBackend(filter, "ForwardFFTImageFilter<double>");
129+
}
130+
131+
TEST_F(FFTWFactoryRegistrationTestSuite, InverseFFT_double)
132+
{
133+
auto filter = itk::InverseFFTImageFilter<DoubleComplexImage2D, DoubleImage2D>::New();
134+
ExpectFFTWBackend(filter, "InverseFFTImageFilter<double>");
135+
}
136+
137+
TEST_F(FFTWFactoryRegistrationTestSuite, Forward1DFFT_double)
138+
{
139+
auto filter = itk::Forward1DFFTImageFilter<DoubleImage2D>::New();
140+
ExpectFFTWBackend(filter, "Forward1DFFTImageFilter<double>");
141+
}
142+
143+
TEST_F(FFTWFactoryRegistrationTestSuite, Inverse1DFFT_double)
144+
{
145+
auto filter = itk::Inverse1DFFTImageFilter<DoubleComplexImage2D, DoubleImage2D>::New();
146+
ExpectFFTWBackend(filter, "Inverse1DFFTImageFilter<double>");
147+
}
148+
149+
TEST_F(FFTWFactoryRegistrationTestSuite, ComplexToComplexFFT_double)
150+
{
151+
auto filter = itk::ComplexToComplexFFTImageFilter<DoubleComplexImage2D>::New();
152+
ExpectFFTWBackend(filter, "ComplexToComplexFFTImageFilter<double>");
153+
}
154+
155+
TEST_F(FFTWFactoryRegistrationTestSuite, ComplexToComplex1DFFT_double)
156+
{
157+
auto filter = itk::ComplexToComplex1DFFTImageFilter<DoubleComplexImage2D>::New();
158+
ExpectFFTWBackend(filter, "ComplexToComplex1DFFTImageFilter<double>");
159+
}
160+
161+
TEST_F(FFTWFactoryRegistrationTestSuite, RealToHalfHermitianForwardFFT_double)
162+
{
163+
auto filter = itk::RealToHalfHermitianForwardFFTImageFilter<DoubleImage2D>::New();
164+
ExpectFFTWBackend(filter, "RealToHalfHermitianForwardFFTImageFilter<double>");
165+
}
166+
167+
TEST_F(FFTWFactoryRegistrationTestSuite, HalfHermitianToRealInverseFFT_double)
168+
{
169+
auto filter = itk::HalfHermitianToRealInverseFFTImageFilter<DoubleComplexImage2D, DoubleImage2D>::New();
170+
ExpectFFTWBackend(filter, "HalfHermitianToRealInverseFFTImageFilter<double>");
171+
}
172+
173+
# endif // ITK_USE_FFTWD
174+
175+
#endif // ITK_USE_FFTWF || ITK_USE_FFTWD

0 commit comments

Comments
 (0)