Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PERF: Use FixedArray for BSplineInterpolationWeightFunction OutputType #2712

Conversation

N-Dekker
Copy link
Contributor

@N-Dekker N-Dekker commented Sep 3, 2021

Replaced itk::Array by itk::FixedArray as output type (array of
weights) of itk::BSplineInterpolationWeightFunction.

Observed a significant improvement of the runtime performance of a call to itk::BSplineBaseTransform::TransformPoint: the runtime duration appeared ~30% lower than before, from 1.5 sec. down to 1.0 sec. when calling TransformPoint 10'000'000 times. (Tested using Visual C++ 2019 Release).

@github-actions github-actions bot added area:Core Issues affecting the Core module area:Registration Issues affecting the Registration module type:Performance Improvement in terms of compilation or execution time type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct labels Sep 3, 2021
@N-Dekker
Copy link
Contributor Author

N-Dekker commented Sep 3, 2021

Does anyone have a suggestion? https://open.cdash.org/viewBuildError.php?type=1&buildid=7436933 (Linux-Build5098-PR2712-BSplineInterpolationWeightFunction-FixedArray-Python) says:

itkBSplineInterpolationWeightFunction: warning(4): ITK type not wrapped, or currently not known: itk::FunctionBase< itk::ContinuousIndex< double, 2 >, itk::FixedArray< double, 9 > >

Wrapping/Typedefs/itkBSplineInterpolationWeightFunction.i:163: Warning 401: Maybe you forgot to instantiate 'itk::FunctionBase< itk::ContinuousIndex< double,3 >,itk::FixedArray< double,64 > >' using %template.

Copy link
Member

@dzenanz dzenanz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

itk::FixedArray< double, 9 >

I think fixed arrays etc are wrapped by default only up to dimension 4.

@N-Dekker
Copy link
Contributor Author

N-Dekker commented Sep 3, 2021

@dzenanz

I think fixed arrays etc are wrapped by default only up to dimension 4.

Would it be OK to wrap FixedArray<double, 9> and FixedArray<double, 64> as well, by default? If so, can you please tell me how to do that?

I think that both FunctionBase<ContinuousIndex<double, 2>, FixedArray<double, 9>> and FunctionBase<ContinuousIndex<double, 3>, FixedArray<double, 64>> would then also need to be wrapped, but I guess that should be sufficient.

@dzenanz
Copy link
Member

dzenanz commented Sep 3, 2021

I am not sure whether anything needs to be done for FunctionBase, but if it does it should probably be done here.

FixedArray.wrap is incredibly simple, and I don't know where WRAPPER_TEMPLATES is used. https://itk.org/ITKSoftwareGuide/html/Book1/ITKSoftwareGuide-Book1ch9.html does not shine light on it.

@thewtex
Copy link
Member

thewtex commented Sep 4, 2021

FixedArray wrapping types are specified here:

WRAP_TYPE("itk::FixedArray" "FA" "itkFixedArray.h")
set(dims ${ITK_WRAP_IMAGE_DIMS_INCREMENTED})
foreach(d ${ITK_WRAP_IMAGE_DIMS})
math(EXPR d2 "${d} * 2")
# for itk::SymmetricSecondRankTensor
math(EXPR d3 "${d} * (${d} + 1) / 2")
list(APPEND dims ${d2} ${d3})
endforeach()
# FixedArray can be used with dimensions describing
# image dimensions or vector components. Therefore it
# needs to have defined sizes for:
# - ITK_WRAP_IMAGE_DIMS_INCREMENTED
# - ITK_WRAP_VECTOR_COMPONENTS_INCREMENTED
# Dimensions 1;2;3;4;6 should always be wrapped.
UNIQUE(array_sizes "${dims};1;2;3;4;6;${ITK_WRAP_VECTOR_COMPONENTS_INCREMENTED}")
# 3-D FixedArrays are required as superclass of rgb pixels
# TODO: Do we need fixed arrays for all of these types? For just the selected
# pixel types plus some few basic cases? Or just for a basic set of types?
foreach(d ${array_sizes})
ADD_TEMPLATE("${ITKM_D}${d}" "${ITKT_D},${d}")
ADD_TEMPLATE("${ITKM_F}${d}" "${ITKT_F},${d}")
ADD_TEMPLATE("${ITKM_UL}${d}" "${ITKT_UL},${d}")
ADD_TEMPLATE("${ITKM_ULL}${d}" "${ITKT_ULL},${d}")
ADD_TEMPLATE("${ITKM_US}${d}" "${ITKT_US},${d}")
ADD_TEMPLATE("${ITKM_UC}${d}" "${ITKT_UC},${d}")
ADD_TEMPLATE("${ITKM_UI}${d}" "${ITKT_UI},${d}")
ADD_TEMPLATE("${ITKM_SL}${d}" "${ITKT_SL},${d}")
ADD_TEMPLATE("${ITKM_SLL}${d}" "${ITKT_SLL},${d}")
ADD_TEMPLATE("${ITKM_SS}${d}" "${ITKT_SS},${d}")
ADD_TEMPLATE("${ITKM_SC}${d}" "${ITKT_SC},${d}")
ADD_TEMPLATE("${ITKM_B}${d}" "${ITKT_B},${d}")
endforeach()
END_WRAP_TYPE()
set(itk_Wrap_FixedArray ${WRAPPER_TEMPLATES})

@N-Dekker N-Dekker force-pushed the BSplineInterpolationWeightFunction-FixedArray branch from 41fecd6 to 7c79455 Compare September 4, 2021 08:57
@N-Dekker
Copy link
Contributor Author

N-Dekker commented Sep 4, 2021

FixedArray wrapping types are specified here:

@thewtex Thanks Matt! Please check my attempt to wrap FixedArray<double, 9> and FixedArray<double, 64>, with this PR:

# Wrap FixedArray for BSplineInterpolationWeightFunction<CoordRep, 2, 2> and
# BSplineInterpolationWeightFunction<CoordRep, 3, 3>:
ADD_TEMPLATE("${ITKM_D}9" "${ITKT_D},9")
ADD_TEMPLATE("${ITKM_D}64" "${ITKT_D},64")

Unfortunately Darwin-Build5152-PR2712-BSplineInterpolationWeightFunction-FixedArray-Python still says:

itkBSplineInterpolationWeightFunction: warning(4): ITK type not wrapped, or currently not known: itk::FunctionBase< itk::ContinuousIndex< double, 2 >, itk::FixedArray< double, 9 > >
itkBSplineInterpolationWeightFunction: warning(4): ITK type not wrapped, or currently not known: itk::FunctionBase< itk::ContinuousIndex< double, 3 >, itk::FixedArray< double, 64 > >

Do you have more suggestions?

@dzenanz
Copy link
Member

dzenanz commented Sep 4, 2021

I guess we need to add something to https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/wrapping/itkFunctionBase.wrap. I am not quite certain what.

@N-Dekker N-Dekker force-pushed the BSplineInterpolationWeightFunction-FixedArray branch from e83f1ef to a20047a Compare September 4, 2021 22:02
@github-actions github-actions bot added the area:Python wrapping Python bindings for a class label Sep 4, 2021
@N-Dekker
Copy link
Contributor Author

N-Dekker commented Sep 4, 2021

I guess we need to add something to https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/Common/wrapping/itkFunctionBase.wrap. I am not quite certain what.

@dzenanz Thanks! I'm not certain at all, but I gave it a try:

itk_wrap_template("${ITKM_CID2}${ITKM_FAD9}" "${ITKT_CID2}, ${ITKT_FAD9}") 
itk_wrap_template("${ITKM_CID3}${ITKM_FAD64}" "${ITKT_CID3}, ${ITKT_FAD64}") 

# Required by BSplineInterpolationWeightFunction
itk_wrap_template("${ITKM_CID2}${ITKM_FAD9}" "${ITKT_CID2}, ${ITKT_FAD9}")
itk_wrap_template("${ITKM_CID3}${ITKM_FAD64}" "${ITKT_CID3}, ${ITKT_FAD64}")

I'd be surprised if it would work directly, but we'll see.

Replaced `itk::Array` by `itk::FixedArray` as output type (`OutputType`,
`WeightsType`) of `itk::BSplineInterpolationWeightFunction`.

Observed ~30% reduction of the runtime duration of a call to
`BSplineBaseTransform::TransformPoint`: Going from 1.5 sec. down to 1.0
sec. for 10'000'000 `TransformPoint` function calls. Tested on Windows
10, Visual C++ 2019 64-bit, Release configuration.

Allowed `BSplineInterpolationWeightFunction` to be wrapped, by
adding extra `FixedArray` and `FunctionBase` wrappings.
Replaced `itk::Array` by `itk::FixedArray` as `ParameterIndexArrayType`
of `itk::BSplineBaseTransform`. This is the type of indices, used during
BSpline transformations. Suggested by Dženan Zukić.

Observed more than 60% reduction of the runtime duration of a call to
`BSplineBaseTransform::TransformPoint`: Going from 1.0 sec. down to less
than 0.4 sec. for 10'000'000 `TransformPoint` function calls. Tested on
Windows 10, Visual C++ 2019 64-bit, Release configuration.
@N-Dekker N-Dekker force-pushed the BSplineInterpolationWeightFunction-FixedArray branch from a5cf690 to bc7c5df Compare September 6, 2021 19:29
@N-Dekker N-Dekker marked this pull request as ready for review September 7, 2021 09:47
@N-Dekker
Copy link
Contributor Author

N-Dekker commented Sep 7, 2021

@dzenanz @thewtex This PR builds now for the very first time 🎉 No more wrapping warnings! 😄

Copy link
Member

@thewtex thewtex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@N-Dekker awesome work! 🥇 🐍 🪐

Merging for 5.3 RC1

CC @vicory @tbirdso

@thewtex thewtex merged commit 63c8594 into InsightSoftwareConsortium:master Sep 7, 2021
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Sep 8, 2021
Replaced `itk::Array2D` by `itk::FixedArray`, used as private `TableType`
of `BSplineInterpolationWeightFunction`. This is the type of a table,
used internally by its `Evaluate` member function.

Declared this table `const`, and initialized the table by an in-class
default-member-initializer. Defaulted the default-constructor.

Follow-up to pull request InsightSoftwareConsortium#2712
commit bc7c5df
"PERF: Use FixedArray for BSplineBaseTransform ParameterIndexArrayType"
commit 9bf745b
"PERF: Use FixedArray for BSplineInterpolationWeightFunction OutputType"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Sep 8, 2021
Replaced `itk::Array2D` by `itk::FixedArray`, used as private `TableType`
of `BSplineInterpolationWeightFunction`. This is the type of a table,
used internally by its `Evaluate` member function.

Declared this table `const`, and initialized the table by an in-class
default-member-initializer. Defaulted the default-constructor.

Follow-up to pull request InsightSoftwareConsortium#2712
commit bc7c5df
"PERF: Use FixedArray for BSplineBaseTransform ParameterIndexArrayType"
commit 9bf745b
"PERF: Use FixedArray for BSplineInterpolationWeightFunction OutputType"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Sep 9, 2021
Replaced `itk::Array2D` by `itk::FixedArray`, used as private `TableType`
of `BSplineInterpolationWeightFunction`. This is the type of a table,
used internally by its `Evaluate` member function.

Declared this table `const`, and initialized the table by an in-class
default-member-initializer. Defaulted the default-constructor.

Follow-up to pull request InsightSoftwareConsortium#2712
commit bc7c5df
"PERF: Use FixedArray for BSplineBaseTransform ParameterIndexArrayType"
commit 9bf745b
"PERF: Use FixedArray for BSplineInterpolationWeightFunction OutputType"
N-Dekker added a commit to N-Dekker/ITK that referenced this pull request Sep 9, 2021
Replaced `itk::Array2D` by `itk::FixedArray`, used as private `TableType`
of `BSplineInterpolationWeightFunction`. This is the type of a table,
used internally by its `Evaluate` member function.

Declared this table `const`, and initialized the table by an in-class
default-member-initializer. Defaulted the default-constructor.

Follow-up to pull request InsightSoftwareConsortium#2712
commit bc7c5df
"PERF: Use FixedArray for BSplineBaseTransform ParameterIndexArrayType"
commit 9bf745b
"PERF: Use FixedArray for BSplineInterpolationWeightFunction OutputType"
hjmjohnson pushed a commit that referenced this pull request Sep 9, 2021
Replaced `itk::Array2D` by `itk::FixedArray`, used as private `TableType`
of `BSplineInterpolationWeightFunction`. This is the type of a table,
used internally by its `Evaluate` member function.

Declared this table `const`, and initialized the table by an in-class
default-member-initializer. Defaulted the default-constructor.

Follow-up to pull request #2712
commit bc7c5df
"PERF: Use FixedArray for BSplineBaseTransform ParameterIndexArrayType"
commit 9bf745b
"PERF: Use FixedArray for BSplineInterpolationWeightFunction OutputType"
N-Dekker added a commit to SuperElastix/elastix that referenced this pull request Feb 22, 2022
Code like `WeightsType weights(n)` does not necessarily construct an object of `n` weights, as it did before ITK 5.3. It now fills a fixed array of weights by value `n`.

This behavior change is caused by a change of the definition of `itk::BSplineInterpolationWeightFunction::WeightsType`, by ITK pull request InsightSoftwareConsortium/ITK#2712 commit InsightSoftwareConsortium/ITK@9bf745b "PERF: Use FixedArray for BSplineInterpolationWeightFunction OutputType" (merged on 7 September 2021, included with ITK v5.3rc01).

Follow-up to pull request #620 commit a0cf523 "COMP: Upgrade ITK from v5.2.0 to v5.3rc03" (merged on 18 February 2022).
N-Dekker added a commit to SuperElastix/elastix that referenced this pull request Feb 22, 2022
Code like `WeightsType weights(n)` does not necessarily construct an object of `n` weights, as it did before ITK 5.3. It now fills a fixed array of weights by value `n`.

This behavior change is caused by a change of the definition of `itk::BSplineInterpolationWeightFunction::WeightsType`, by ITK pull request InsightSoftwareConsortium/ITK#2712 commit InsightSoftwareConsortium/ITK@9bf745b "PERF: Use FixedArray for BSplineInterpolationWeightFunction OutputType" (merged on 7 September 2021, included with ITK v5.3rc01).

Follow-up to pull request #620 commit a0cf523 "COMP: Upgrade ITK from v5.2.0 to v5.3rc03" (merged on 18 February 2022).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:Core Issues affecting the Core module area:Python wrapping Python bindings for a class area:Registration Issues affecting the Registration module type:Performance Improvement in terms of compilation or execution time type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants