From c3dd02c2c674bd8db0788b82a9ca933981bd43e8 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Thu, 25 Aug 2022 21:23:37 +0200 Subject: [PATCH] ENH: Add `NumberOfThreads` property to itk::TransformixFilter Addressed issue https://github.com/InsightSoftwareConsortium/ITKElastix/issues/163 "No option to set number of threads for Transformix", submitted by Sebastian van der Voort. --- .../GTesting/itkTransformixFilterGTest.cxx | 42 +++++++++++++++++++ Core/Main/itkTransformixFilter.h | 5 +++ Core/Main/itkTransformixFilter.hxx | 5 +++ 3 files changed, 52 insertions(+) diff --git a/Core/Main/GTesting/itkTransformixFilterGTest.cxx b/Core/Main/GTesting/itkTransformixFilterGTest.cxx index c17476058..bfbff6132 100644 --- a/Core/Main/GTesting/itkTransformixFilterGTest.cxx +++ b/Core/Main/GTesting/itkTransformixFilterGTest.cxx @@ -63,6 +63,7 @@ using ParameterValuesType = itk::ParameterFileParser::ParameterValuesType; // Using-declarations: using elx::CoreMainGTestUtilities::CheckNew; +using elx::CoreMainGTestUtilities::CreateImage; using elx::CoreMainGTestUtilities::CreateImageFilledWithSequenceOfNaturalNumbers; using elx::CoreMainGTestUtilities::Deref; using elx::CoreMainGTestUtilities::DerefSmartPointer; @@ -445,6 +446,47 @@ GTEST_TEST(itkTransformixFilter, IsDefaultInitialized) EXPECT_FALSE(transformixFilter.GetLogToConsole()); EXPECT_FALSE(transformixFilter.GetLogToFile()); EXPECT_EQ(transformixFilter.GetOutputMesh(), nullptr); + EXPECT_EQ(transformixFilter.GetNumberOfThreads(), 0); +} + + +GTEST_TEST(itkTransformixFilter, NumberOfThreadsEqualsGlobalMaximumNumberOfThreads) +{ + constexpr auto ImageDimension = 2U; + using PixelType = float; + using ImageType = itk::Image; + using TransformixFilterType = itk::TransformixFilter; + + elx::DefaultConstruct transformixFilter; + + constexpr auto imageSize = ImageType::SizeType::Filled(1); + const auto image = CreateImage(imageSize); + + transformixFilter.SetMovingImage(image); + transformixFilter.SetTransformParameterObject( + CreateParameterObject({ // Parameters in alphabetic order: + { "Direction", CreateDefaultDirectionParameterValues() }, + { "Index", ParameterValuesType(ImageDimension, "0") }, + { "NumberOfParameters", { std::to_string(ImageDimension) } }, + { "Origin", ParameterValuesType(ImageDimension, "0") }, + { "ResampleInterpolator", { "FinalLinearInterpolator" } }, + { "Size", ConvertToParameterValues(imageSize) }, + { "Transform", ParameterValuesType{ "TranslationTransform" } }, + { "TransformParameters", ParameterValuesType(ImageDimension, "0") }, + { "Spacing", ParameterValuesType(ImageDimension, "1") } })); + + const auto initialGlobalMaximumNumberOfThreads = itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(); + ASSERT_GE(initialGlobalMaximumNumberOfThreads, 1); + ASSERT_LE(initialGlobalMaximumNumberOfThreads, itk::ITK_MAX_THREADS); + + for (const int numberOfThreads : + { 1, 2, int{ itk::ITK_MAX_THREADS }, static_cast(initialGlobalMaximumNumberOfThreads) }) + { + transformixFilter.SetNumberOfThreads(numberOfThreads); + ASSERT_EQ(transformixFilter.GetNumberOfThreads(), numberOfThreads); + transformixFilter.Update(); + EXPECT_EQ(itk::MultiThreaderBase::GetGlobalMaximumNumberOfThreads(), numberOfThreads); + } } diff --git a/Core/Main/itkTransformixFilter.h b/Core/Main/itkTransformixFilter.h index 42972df0f..5c190fe08 100644 --- a/Core/Main/itkTransformixFilter.h +++ b/Core/Main/itkTransformixFilter.h @@ -200,6 +200,9 @@ class ITK_TEMPLATE_EXPORT TransformixFilter : public ImageSource m_EnableOutput = false; } + itkSetMacro(NumberOfThreads, int); + itkGetConstMacro(NumberOfThreads, int); + /** Sets an (optional) input mesh. An Update() will transform its points, and store them in the output mesh. */ void SetInputMesh(typename MeshType::ConstPointer mesh) @@ -264,6 +267,8 @@ class ITK_TEMPLATE_EXPORT TransformixFilter : public ImageSource bool m_LogToConsole{ false }; bool m_LogToFile{ false }; + int m_NumberOfThreads{ 0 }; + typename MeshType::ConstPointer m_InputMesh{ nullptr }; typename MeshType::Pointer m_OutputMesh{ nullptr }; }; diff --git a/Core/Main/itkTransformixFilter.hxx b/Core/Main/itkTransformixFilter.hxx index 9d07ceecf..6294c391c 100644 --- a/Core/Main/itkTransformixFilter.hxx +++ b/Core/Main/itkTransformixFilter.hxx @@ -146,6 +146,11 @@ TransformixFilter::GenerateData() } } + if (m_NumberOfThreads > 0) + { + argumentMap.insert(ArgumentMapEntryType("-threads", std::to_string(m_NumberOfThreads))); + } + // Setup xout const auto manager = m_EnableOutput ? std::make_unique(logFileName, m_LogToFile, m_LogToConsole)