Repository navigation
COMP: Build and test against ITK 5.4 and ITK 6 - #61
Conversation
UseITK registers every IO factory of the ITK build as a directory-wide compile definition, so each test object references the *ImageIOFactoryRegister__Private symbols of modules this module never links, and the test driver fails to link against an ITK that has ITKIOGE or ITKIOFDF enabled. ITKModuleExternal already applies ITK's flags, and the module template does not include the use file.
src/CMakeLists.txt linked ITK::LesionSizingToolkitModule, an interface library that exists only in ITK 6, so configuring against ITK 5.4 failed and every CI job has been red since 2026-01-27. Pick the module library at configure time and fall back to LesionSizingToolkit_LIBRARIES. Run the C++ and Python workflows twice, pinned to the v5.4.6 and v6.0b02 releases of ITKRemoteModuleBuildTestPackageAction, so both supported ITK majors are covered. Only the ITK 6 Python job publishes.
ITK_EXERCISE_BASIC_OBJECT_METHODS compares Superclass::GetNameOfClass() with the stringified third argument and fails the test on a mismatch. Nine calls named a class that is not the object's direct superclass: - MaximumFeatureAggregator derives from FeatureAggregator, not UnaryFunctorImageFilter (itkDescoteauxSheetnessFeatureGeneratorMultiScaleTest1). - LesionSegmentationMethod derives from ProcessObject, not LightObject (itkLesionSegmentationMethodTest10). - SatoVesselnessSigmoidFeatureGenerator derives from SatoVesselnessFeatureGenerator, not FeatureGenerator (itkSatoVesselnessSigmoidFeatureGeneratorMultiScaleTest1, four calls; itkFeatureAggregatorTest1, one call). - LungWallFeatureGenerator and SigmoidFeatureGenerator derive from FeatureGenerator, not FeatureAggregator (itkFeatureAggregatorTest1). The first three tests fail identically against ITK main and ITK release-5.4 in the downstream build matrix. itkFeatureAggregatorTest1 is only built when TEST_CORNELL_DATA_ROOT is set, so its three mismatches were latent.
CannyEdgeDetectionRecursiveGaussianImageFilter requires floating-point input and output, which ITK 5.4's concept checks enforce, so its integer instantiations fail castxml. LesionSegmentationImageFilter8 grafts the float image of its segmentation module onto its output, so a double output cannot be const_cast from it; wrap the output as float.
|
The first run ( |
ITKRemoteModuleBuildTestPackageAction validates that each job produced an itk_* wheel, and every published ITK remote module uses the itk- prefix. Neither name is on PyPI.
The v6.0b02 release of ITKRemoteModuleBuildTestPackageAction builds ITK at c6e1c1be (2026-03-10), which is older than the v6.0b02 tag and 6,400 commits behind main. Three tests segfault on Windows against that snapshot and pass against main, so pin the C++ job to the main commit the module was verified with.
|
Run for |
Both flooding filters copied the offset table with memcpy sized by sizeof(unsigned long), which is 4 bytes on Windows while OffsetValueType is 8 bytes there (ITK_USE_64BITS_IDS defaults to ON on 64-bit Windows). Only the first two strides were copied and the slice and volume strides kept whatever the heap held, so neighbor offsets were garbage: silently wrong on platforms that happened to hand back zeros, and access violations under ITK 6 on Windows. Copy the table element-wise and accumulate the neighbor offset in OffsetValueType.
|
Root cause of the Windows ITK 6 segfaults, caught under Debugger excerpt |
|
Green on |
|
@dzenanz no hurry on this. Based on comments for ITK regarding issues with InsightSoftwareConsortium/ITK#6891. I wanted to ensure that LesionSizingToolkit did not have other issues causing the failures. It turns out that the LSTK had several CI exposed problems, and this rather large PR is the set of fixes needed to make CI green. Breaking it apart will result in non-green CI's. |
Every CI job has been red since 2026-01-27 because
src/CMakeLists.txtlinksITK::LesionSizingToolkitModule, an interface library that exists only in ITK 6, while the workflow builds against ITK 5.4. This picks the module library at configure time so the module builds against both majors, runs the C++ and Python workflows twice, pinned toITKRemoteModuleBuildTestPackageActionv5.4.6andv6.0b02, and fixes the four defects that CI exposed once it could build again, including a Windows-only crash in two flooding filters. Carries the commits of #59 and #60, which it needs to go green; those can merge first or be closed in favor of this. CI is green: 26 of 26 jobs ond108038.Changes
src/CMakeLists.txt: useITK::LesionSizingToolkitModulewhen that target exists (ITK 6), else the bareLesionSizingToolkitModule, else${LesionSizingToolkit_LIBRARIES}(ITK 5.4)..github/workflows/build-test-package.yml:cxx-build-workflow-itk5/-itk6andpython-build-workflow-itk5/-itk6, each using the action release's default ITK, wheel, and package tags (v5.4.6;c6e1c1be/v6.0b02). Only the ITK 6 Python job receives the PyPI secret, so av*tag publishes one set of wheels.wrapping/itkCannyEdgeDetectionRecursiveGaussianImageFilter.wrap: floating-point types only; the filter'sIsFloatingPointconcept checks, enforced by ITK 5.4, rejected the integer instantiations at castxml time.wrapping/itkLesionSegmentationImageFilter8.wrap: outputfloatonly; the filter grafts its segmentation module'sfloatimage onto the output, so thedoubleoutput instantiation failed to compile.pyproject.toml: package renameditk-lesionsizingtoolkit, the name the wheel validation expects; neither name is on PyPI.VotingBinaryHoleFillFloodingImageFilterandRegionCompetitionImageFiltercopied the image offset table withmemcpysized bysizeof(unsigned long)(4 bytes on Windows, 8-byteOffsetValueType), leaving the slice and volume strides uninitialized; wrong neighbor offsets everywhere, access violations on the ITK 6 Windows heap. Nowstd::copy_noverOffsetValueType.mainat5d31af3c(2026-10-01) rather than the action's defaultc6e1c1be(2026-03-10); replace withv6.0.0when it exists.include(${ITK_USE_FILE}), which made every test object reference IO factories the driver does not link.ITK_EXERCISE_BASIC_OBJECT_METHODScalls; MSVC's variant of the macro compares the name, and the Windows jobs failed exactly those three tests.Test plan
Configured, built, and ran
ctestin two external-module builds on macOS arm64 (clang, Release):v5.4.7-61-gb3abd15c12, wrapping off: configure and build succeed, 52 of 52 tests pass.main(6.0), wrapping on: configure, build, and wrapping succeed, 52 of 52 tests pass;ITK::LesionSizingToolkitModuleexists there, so the first branch is taken.CI history on this PR:
7b023acbuilt everywhere for the first time since January and exposed the wrap-file and superclass-name failures;033c429exposed the Windows ITK 6 access violations, which acdbrun on a fork branch placed inVotingBinaryHoleFillFloodingImageFilter's neighbor loop;d108038passes all 26 jobs (ITK 5.4.6 and ITK 6 C++ on Linux, macOS Intel, macOS arm64, Windows; 16 wheel jobs). Linux ASan+UBSan at the pinned ITK commit was clean throughout, which is consistent with an uninitialized read rather than an invalid access.