Skip to content

Commit

Permalink
BUG: Python factory registration fixups
Browse files Browse the repository at this point in the history
Several fixes addressing previous commit:
- Classes grouping FFT factory registrations are now named `InitFactory`
  to better discriminate between factory overrides vs initializers
- Static initialization with `RegisterInternalFactoryOnce` is replaced
  with nonstatic `RegisterOneFactory` method
- Python factory load-time registration is streamlined
  • Loading branch information
tbirdso committed Mar 4, 2022
1 parent 5abb6b6 commit 907c8b5
Show file tree
Hide file tree
Showing 29 changed files with 285 additions and 279 deletions.
14 changes: 10 additions & 4 deletions CMake/ITKFactoryRegistration.cmake
Expand Up @@ -14,7 +14,7 @@
# Overview: Static registration of ITK factories
# ----------------------------------------------
#
# For each factory type (Image, Transform, Mesh, FFT, ...), a
# For each factory type (Image, Transform, Mesh, FFTImageFilterInit, ...), a
# registration manager header named
# `itk<factory_type>FactoryRegisterManager.h` is configured.
#
Expand All @@ -32,8 +32,14 @@
# a list in a CMake variable named after `LIST_OF_<factory_type>IO_FORMATS`
# generated by this file.
#
# For the FFT factories, each FFT filter which has a factory needs to
# be included.
# "Init factories" (such as "VnlFFTImageFilterInitFactory") are intended to reduce
# overhead. They have the sole purpose of registering multiple factories with the
# object factory singleton at once. Init factories do not inherit from
# ObjectFactoryBase, cannot define initialization overrides, and will never be
# added to the global singleton list of object factories.
#
# For the FFTImageFilterInitFactory classes, each FFT filter which has a factory needs to
# be included in its initialization list.
#
#
#
Expand All @@ -52,7 +58,7 @@
# Setting variable `ITK_NO_<factory_name_uc>_FACTORY_REGISTER_MANAGER` to `ON` prior calling
# `include(${ITK_USE_FILE})` disables the static registration.
# Here <factory_name_uc> is the upper case name of the factory. For example,
# `IMAGEIO`, `MESHIO`, `TRANSFORMIO`, or `FFTIMAGEFILTER`.
# `IMAGEIO`, `MESHIO`, `TRANSFORMIO`, or `FFTIMAGEFILTERINIT`.
#
# All factories can be disabled with the following CMake code:
# foreach(_factory_name ${ITK_FACTORY_LIST})
Expand Down
Expand Up @@ -16,8 +16,8 @@
*
*=========================================================================*/

#ifndef itkFFTImageFilterFactoryRegisterManager_h
#define itkFFTImageFilterFactoryRegisterManager_h
#ifndef itkFFTImageFilterInitFactoryRegisterManager_h
#define itkFFTImageFilterInitFactoryRegisterManager_h

namespace itk {

Expand All @@ -27,10 +27,10 @@ namespace itk {
//
@LIST_OF_FACTORIES_REGISTRATION@

class FFTImageFilterFactoryRegisterManager
class FFTImageFilterInitFactoryRegisterManager
{
public:
explicit FFTImageFilterFactoryRegisterManager(void (* const list[])(void))
explicit FFTImageFilterInitFactoryRegisterManager(void (* const list[])(void))
{
for(;*list != nullptr; ++list)
{
Expand All @@ -44,10 +44,10 @@ class FFTImageFilterFactoryRegisterManager
// application translation units. Note that this code will be expanded in the
// ITK-based applications and not in ITK itself.
//
void (* const FFTImageFilterFactoryRegisterRegisterList[])(void) = {
void (* const FFTImageFilterInitFactoryRegisterList[])(void) = {
@LIST_OF_FACTORY_NAMES@
nullptr};
const FFTImageFilterFactoryRegisterManager FFTImageFilterFactoryRegisterManagerInstance(FFTImageFilterFactoryRegisterRegisterList);
const FFTImageFilterInitFactoryRegisterManager FFTImageFilterInitFactoryRegisterManagerInstance(FFTImageFilterInitFactoryRegisterList);

}

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -582,7 +582,7 @@ install(FILES ${ITK_BINARY_DIR}/CMakeFiles/ITKConfig.cmake
CMake/ITKModuleAPI.cmake
CMake/UseITK.cmake
CMake/ITKFactoryRegistration.cmake
CMake/itkFFTImageFilterFactoryRegisterManager.h.in
CMake/itkFFTImageFilterInitFactoryRegisterManager.h.in
CMake/itkImageIOFactoryRegisterManager.h.in
CMake/itkTransformIOFactoryRegisterManager.h.in
CMake/itkMeshIOFactoryRegisterManager.h.in
Expand Down
Expand Up @@ -119,8 +119,8 @@ class ITK_TEMPLATE_EXPORT ComplexToComplex1DFFTImageFilter : public ImageToImage
# include "itkComplexToComplex1DFFTImageFilter.hxx"
#endif

#ifdef ITK_FFTIMAGEFILTER_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterFactoryRegisterManager.h"
#ifdef ITK_FFTIMAGEFILTERINIT_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterInitFactoryRegisterManager.h"
#endif

#endif // itkComplexToComplex1DFFTImageFilter_h
Expand Up @@ -134,8 +134,8 @@ class ITK_TEMPLATE_EXPORT ComplexToComplexFFTImageFilter : public ImageToImageFi
# include "itkComplexToComplexFFTImageFilter.hxx"
#endif

#ifdef ITK_FFTIMAGEFILTER_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterFactoryRegisterManager.h"
#ifdef ITK_FFTIMAGEFILTERINIT_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterInitFactoryRegisterManager.h"
#endif

#endif
Expand Up @@ -15,55 +15,58 @@
* limitations under the License.
*
*=========================================================================*/
#ifndef itkVnlFFTImageFilterFactory_h
#define itkVnlFFTImageFilterFactory_h
#ifndef itkFFTWFFTImageFilterInitFactory_h
#define itkFFTWFFTImageFilterInitFactory_h
#include "ITKFFTExport.h"

#include "itkObjectFactoryBase.h"
#include "itkLightObject.h"

namespace itk
{
/**
*\class VnlFFTImageFilterFactory
* \brief Create instances of Vnl FFT ImageFilter objects using an object factory.
*\class FFTWFFTImageFilterInitFactory
* \brief Initialize FFTW FFT image filter factory backends.
*
* The purpose of FFTWFFTImageFilterInitFactory is to perform
* one-time registration of factory objects that handle
* creation of FFTW-backend FFT image filter classes
* through the ITK object factory singleton mechanism.
*
* \ingroup ITKFFT
*/
class ITKFFT_EXPORT VnlFFTImageFilterFactory : public ObjectFactoryBase
class ITKFFT_EXPORT FFTWFFTImageFilterInitFactory : public LightObject
{
public:
ITK_DISALLOW_COPY_AND_MOVE(VnlFFTImageFilterFactory);
ITK_DISALLOW_COPY_AND_MOVE(FFTWFFTImageFilterInitFactory);

/** Standard class type aliases. */
using Self = VnlFFTImageFilterFactory;
using Superclass = ObjectFactoryBase;
using Self = FFTWFFTImageFilterInitFactory;
using Superclass = LightObject;
using Pointer = SmartPointer<Self>;
using ConstPointer = SmartPointer<const Self>;

/** Class methods used to interface with the registered factories. */
const char *
GetITKSourceVersion() const override;

const char *
GetDescription() const override;

/** Method for class instantiation. */
itkFactorylessNewMacro(Self);

/** Run-time type information (and related methods). */
itkTypeMacro(VnlFFTImageFilterFactory, ObjectFactoryBase);
itkTypeMacro(FFTWFFTImageFilterInitFactory, LightObject);

/** Register one factory of this type */
/** Register one factory of this type.
* The purpose of an InitFactory is to simply load other factories
* in its constructor, so nothing is returned here.
* Method is required for factory to load correct in Python. */
static void
RegisterOneFactory()
{
auto factory = VnlFFTImageFilterFactory::New();

ObjectFactoryBase::RegisterFactoryInternal(factory);
RegisterFactories();
}

static void
RegisterFactories();

protected:
VnlFFTImageFilterFactory();
~VnlFFTImageFilterFactory() override;
FFTWFFTImageFilterInitFactory();
~FFTWFFTImageFilterInitFactory() override;
};
} // end namespace itk

Expand Down
4 changes: 2 additions & 2 deletions Modules/Filtering/FFT/include/itkForward1DFFTImageFilter.h
Expand Up @@ -104,8 +104,8 @@ class ITK_TEMPLATE_EXPORT Forward1DFFTImageFilter : public ImageToImageFilter<TI
# include "itkForward1DFFTImageFilter.hxx"
#endif

#ifdef ITK_FFTIMAGEFILTER_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterFactoryRegisterManager.h"
#ifdef ITK_FFTIMAGEFILTERINIT_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterInitFactoryRegisterManager.h"
#endif

#endif // itkForward1DFFTImageFilter_h
4 changes: 2 additions & 2 deletions Modules/Filtering/FFT/include/itkForwardFFTImageFilter.h
Expand Up @@ -116,8 +116,8 @@ class ITK_TEMPLATE_EXPORT ForwardFFTImageFilter : public ImageToImageFilter<TInp
# include "itkForwardFFTImageFilter.hxx"
#endif

#ifdef ITK_FFTIMAGEFILTER_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterFactoryRegisterManager.h"
#ifdef ITK_FFTIMAGEFILTERINIT_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterInitFactoryRegisterManager.h"
#endif

#endif
Expand Up @@ -118,8 +118,8 @@ class ITK_TEMPLATE_EXPORT HalfHermitianToRealInverseFFTImageFilter
# include "itkHalfHermitianToRealInverseFFTImageFilter.hxx"
#endif

#ifdef ITK_FFTIMAGEFILTER_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterFactoryRegisterManager.h"
#ifdef ITK_FFTIMAGEFILTERINIT_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterInitFactoryRegisterManager.h"
#endif

#endif
4 changes: 2 additions & 2 deletions Modules/Filtering/FFT/include/itkInverse1DFFTImageFilter.h
Expand Up @@ -99,8 +99,8 @@ class ITK_TEMPLATE_EXPORT Inverse1DFFTImageFilter : public ImageToImageFilter<TI
# include "itkInverse1DFFTImageFilter.hxx"
#endif

#ifdef ITK_FFTIMAGEFILTER_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterFactoryRegisterManager.h"
#ifdef ITK_FFTIMAGEFILTERINIT_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterInitFactoryRegisterManager.h"
#endif

#endif // itkInverse1DFFTImageFilter_h
4 changes: 2 additions & 2 deletions Modules/Filtering/FFT/include/itkInverseFFTImageFilter.h
Expand Up @@ -102,8 +102,8 @@ class ITK_TEMPLATE_EXPORT InverseFFTImageFilter : public ImageToImageFilter<TInp
# include "itkInverseFFTImageFilter.hxx"
#endif

#ifdef ITK_FFTIMAGEFILTER_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterFactoryRegisterManager.h"
#ifdef ITK_FFTIMAGEFILTERINIT_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterInitFactoryRegisterManager.h"
#endif

#endif
Expand Up @@ -120,8 +120,8 @@ class ITK_TEMPLATE_EXPORT RealToHalfHermitianForwardFFTImageFilter
# include "itkRealToHalfHermitianForwardFFTImageFilter.hxx"
#endif

#ifdef ITK_FFTIMAGEFILTER_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterFactoryRegisterManager.h"
#ifdef ITK_FFTIMAGEFILTERINIT_FACTORY_REGISTER_MANAGER
# include "itkFFTImageFilterInitFactoryRegisterManager.h"
#endif

#endif
Expand Up @@ -15,55 +15,56 @@
* limitations under the License.
*
*=========================================================================*/
#ifndef itkFFTWFFTImageFilterFactory_h
#define itkFFTWFFTImageFilterFactory_h
#ifndef itkVnlFFTImageFilterInitFactory_h
#define itkVnlFFTImageFilterInitFactory_h
#include "ITKFFTExport.h"

#include "itkObjectFactoryBase.h"
#include "itkLightObject.h"

namespace itk
{
/**
*\class FFTWFFTImageFilterFactory
* \brief Create instances of FFTW FFT ImageFilter objects using an object factory.
*\class VnlFFTImageFilterInitFactory
* \brief Initialize Vnl FFT image filter factory backends.
*
* The purpose of VnlFFTImageFilterInitFactory is to perform
* one-time registration of factory objects that handle
* creation of Vnl-backend FFT image filter classes
* through the ITK object factory singleton mechanism.
*
* \ingroup ITKFFT
*/
class ITKFFT_EXPORT FFTWFFTImageFilterFactory : public ObjectFactoryBase
class ITKFFT_EXPORT VnlFFTImageFilterInitFactory : public LightObject
{
public:
ITK_DISALLOW_COPY_AND_MOVE(FFTWFFTImageFilterFactory);
ITK_DISALLOW_COPY_AND_MOVE(VnlFFTImageFilterInitFactory);

/** Standard class type aliases. */
using Self = FFTWFFTImageFilterFactory;
using Superclass = ObjectFactoryBase;
using Self = VnlFFTImageFilterInitFactory;
using Superclass = LightObject;
using Pointer = SmartPointer<Self>;
using ConstPointer = SmartPointer<const Self>;

/** Class methods used to interface with the registered factories. */
const char *
GetITKSourceVersion() const override;

const char *
GetDescription() const override;

/** Method for class instantiation. */
itkFactorylessNewMacro(Self);

/** Run-time type information (and related methods). */
itkTypeMacro(FFTWFFTImageFilterFactory, ObjectFactoryBase);
itkTypeMacro(VnlFFTImageFilterInitFactory, LightObject);

/** Register one factory of this type */
/** Mimic factory interface for Python initialization */
static void
RegisterOneFactory()
{
auto factory = FFTWFFTImageFilterFactory::New();

ObjectFactoryBase::RegisterFactoryInternal(factory);
RegisterFactories();
}

/** Register all Vnl FFT factories */
static void
RegisterFactories();

protected:
FFTWFFTImageFilterFactory();
~FFTWFFTImageFilterFactory() override;
VnlFFTImageFilterInitFactory();
~VnlFFTImageFilterInitFactory() override;
};
} // end namespace itk

Expand Down
4 changes: 2 additions & 2 deletions Modules/Filtering/FFT/itk-module.cmake
Expand Up @@ -5,10 +5,10 @@ computations of Fast Fourier Transforms based on
<a href=\"http://www.fftw.org\">FFTW</a>. Note that when using the FFTW
implementation you must comply with the GPL license.")

set(_fft_backends "FFTImageFilter::Vnl")
set(_fft_backends "FFTImageFilterInit::Vnl")
if(ITK_USE_FFTWF OR ITK_USE_FFTWD)
# Prepend so that FFTW constructor is preferred
list(PREPEND _fft_backends "FFTImageFilter::FFTW")
list(PREPEND _fft_backends "FFTImageFilterInit::FFTW")
endif()

itk_module(ITKFFT
Expand Down
4 changes: 2 additions & 2 deletions Modules/Filtering/FFT/src/CMakeLists.txt
@@ -1,10 +1,10 @@
set(ITKFFT_SRCS
itkComplexToComplexFFTImageFilter.cxx
itkVnlFFTImageFilterFactory.cxx)
itkVnlFFTImageFilterInitFactory.cxx)

if( ITK_USE_FFTWF OR ITK_USE_FFTWD AND NOT ITK_USE_CUFFTW)
list(APPEND ITKFFT_SRCS itkFFTWGlobalConfiguration.cxx )
list(APPEND ITKFFT_SRCS itkFFTWFFTImageFilterFactory.cxx )
list(APPEND ITKFFT_SRCS itkFFTWFFTImageFilterInitFactory.cxx )
endif()

itk_module_add_library(ITKFFT ${ITKFFT_SRCS})
Expand Down

0 comments on commit 907c8b5

Please sign in to comment.