Proposal
Stop supporting ITK_USE_SYSTEM_VXL (external vxl) and stop tracking
upstream vxl/vxl for the vendored copy under Modules/ThirdParty/VNL/.
Treat ITK's vnl as a hard fork — vendored, pruned, and evolved on
ITK's schedule and ITK's needs alone.
NOTE: Pruning VXL of items not needed by ITK (2208 → 1115 files, ~50% reduction) greatly reduces the maintenance surface area, and greatly reduces the cmake complexity.
Motivation
A symbol-level audit of ITK's vxl usage shows a narrow, concentrated
footprint:
- ITK uses only
core/vnl, core/vnl/algo, core/vcl (already
zero vcl_* includes in ITK source — fully migrated), and
v3p/netlib.
- Zero references in ITK to
core/vbl, core/vgl, core/vul,
core/vil, core/vsl, core/vpl, or any of contrib/.
- Top consumers (mention counts in ITK source):
vnl_vector (405),
vnl_matrix (202), vnl_vector_fixed (81), vnl_matrix_fixed
(73), vnl_nonlinear_minimizer (50), vnl_math (45),
vnl_lbfgsb (21), vnl_svd (19), vnl_lbfgs (18),
vnl_matrix_inverse (17), vnl_quaternion (15), vnl_amoeba
(14), vnl_cost_function (14), vnl_sparse_matrix (14),
vnl_symmetric_eigensystem (6), vnl_fft_base (7).
- ITK's existing
VXL_BUILD_CORE_NUMERICS_ONLY=ON already restricts
the build to roughly this set, but the source tree under
Modules/ThirdParty/VNL/src/vxl/ still ships everything.
A survey of the 124 visible forks of vxl/vxl shows essentially no
divergent downstream community. Every ITK-contributor fork
(hjmjohnson, thewtex, blowekamp, N-Dekker, bradking,
dzenanz, seanm) is 0 commits ahead of upstream — pure PR-staging
mirrors. The only meaningfully divergent fork is one researcher's
computer-vision fork (rfabbri/vxl-1). Outside ITK, the active
contributor base is one other organization with computer-vision
priorities that diverge from ITK's medical-imaging-numerics priorities.
The two groups end up burdening each other:
- ITK carries only config, core, v3p, vcl in the source tree, but changes to these core have often required upstream VXL changes in vbl/vgl/vul/vil/vsl/vpl/contrib that ITK does not use, build, or test.
- Upstream vxl carries API and ABI commitments around vnl that ITK
doesn't need but cannot break unilaterally.
- Cross-org review burden on PRs that one side cares about and the
other tolerates.
What this unlocks
Treating vnl as ITK-owned vendored code (no external option, no
upstream tracking) gives us freedom to:
- Aggressively prune. Delete every header outside the closure of
what ITK actually compiles. The source tree shrinks by a large
majority.
- Hide / shrink the public surface. Most of the vnl API is not
exposed in ITK's public headers. The unexposed portion can be
rewritten, renamed, made internal::, or replaced behind ITK's
own thin facades without backward-compat concerns.
- Stage a migration to Eigen and
std.
vnl_math → <numbers> / <cmath>
vnl_*_fixed<T,N,M> → Eigen::Matrix<T,N,M>
vnl_matrix / vnl_vector → Eigen::MatrixXd / VectorXd
vnl_svd / vnl_symmetric_eigensystem / vnl_sparse_matrix →
Eigen equivalents
- Optimizers (
vnl_lbfgs, vnl_lbfgsb, vnl_amoeba,
vnl_levenberg_marquardt, vnl_powell,
vnl_conjugate_gradient) phase last — they need a numerical
regression suite before swap because ITK's registration
framework depends on their exact behavior.
- Land performance improvements (alignment, SIMD, view types,
move-only semantics, allocator-aware containers) that would be
ABI/API-breaking upstream.
What this costs
- ITK is no longer a consumer of upstream vxl bug fixes. We accept
that — the bug-fix flux from upstream into ITK's slice has been
small in recent years.
- ITK contributors who maintain the
0-ahead mirror forks lose the
ability to round-trip a vnl fix through both projects. In practice
these PRs have been rare and can still be done by hand if an
upstream-relevant fix surfaces.
ITK_USE_SYSTEM_VXL users (if any exist in production) need a
migration path. A deprecation cycle of one minor release is
reasonable.
Proposed sequence
- Decision on this issue (community discussion, vote if needed).
- Deprecate
ITK_USE_SYSTEM_VXL in the next minor release with a
warning at configure time.
- Remove the option in the release after that. Vendored copy
becomes the only path.
- Prune the vendored tree to the closure of what ITK builds.
- Begin migration in priority order:
vnl_math and
vnl_*_fixed first (mechanical), vnl_matrix/vector second
(bulk but mechanical), solvers third, optimizers last with
numerical regression coverage.
Discussion points
- Are there ITK_USE_SYSTEM_VXL users in production we need to survey?
- Any objection to the rename of the vendored module from "VXL" to
something more honest about its scope (e.g., "VNLForITK") once
the prune lands?
- Should the optimizer phase be coordinated with the registration
framework's own modernization roadmap?
Proposal
Stop supporting
ITK_USE_SYSTEM_VXL(external vxl) and stop trackingupstream
vxl/vxlfor the vendored copy underModules/ThirdParty/VNL/.Treat ITK's vnl as a hard fork — vendored, pruned, and evolved on
ITK's schedule and ITK's needs alone.
NOTE: Pruning VXL of items not needed by ITK (2208 → 1115 files, ~50% reduction) greatly reduces the maintenance surface area, and greatly reduces the cmake complexity.
Motivation
A symbol-level audit of ITK's vxl usage shows a narrow, concentrated
footprint:
core/vnl,core/vnl/algo,core/vcl(alreadyzero
vcl_*includes in ITK source — fully migrated), andv3p/netlib.core/vbl,core/vgl,core/vul,core/vil,core/vsl,core/vpl, or any ofcontrib/.vnl_vector(405),vnl_matrix(202),vnl_vector_fixed(81),vnl_matrix_fixed(73),
vnl_nonlinear_minimizer(50),vnl_math(45),vnl_lbfgsb(21),vnl_svd(19),vnl_lbfgs(18),vnl_matrix_inverse(17),vnl_quaternion(15),vnl_amoeba(14),
vnl_cost_function(14),vnl_sparse_matrix(14),vnl_symmetric_eigensystem(6),vnl_fft_base(7).VXL_BUILD_CORE_NUMERICS_ONLY=ONalready restrictsthe build to roughly this set, but the source tree under
Modules/ThirdParty/VNL/src/vxl/still ships everything.A survey of the 124 visible forks of
vxl/vxlshows essentially nodivergent downstream community. Every ITK-contributor fork
(
hjmjohnson,thewtex,blowekamp,N-Dekker,bradking,dzenanz,seanm) is0 commits aheadof upstream — pure PR-stagingmirrors. The only meaningfully divergent fork is one researcher's
computer-vision fork (
rfabbri/vxl-1). Outside ITK, the activecontributor base is one other organization with computer-vision
priorities that diverge from ITK's medical-imaging-numerics priorities.
The two groups end up burdening each other:
doesn't need but cannot break unilaterally.
other tolerates.
What this unlocks
Treating vnl as ITK-owned vendored code (no external option, no
upstream tracking) gives us freedom to:
what ITK actually compiles. The source tree shrinks by a large
majority.
exposed in ITK's public headers. The unexposed portion can be
rewritten, renamed, made
internal::, or replaced behind ITK'sown thin facades without backward-compat concerns.
std.vnl_math→<numbers>/<cmath>vnl_*_fixed<T,N,M>→Eigen::Matrix<T,N,M>vnl_matrix/vnl_vector→Eigen::MatrixXd/VectorXdvnl_svd/vnl_symmetric_eigensystem/vnl_sparse_matrix→Eigen equivalents
vnl_lbfgs,vnl_lbfgsb,vnl_amoeba,vnl_levenberg_marquardt,vnl_powell,vnl_conjugate_gradient) phase last — they need a numericalregression suite before swap because ITK's registration
framework depends on their exact behavior.
move-only semantics, allocator-aware containers) that would be
ABI/API-breaking upstream.
What this costs
that — the bug-fix flux from upstream into ITK's slice has been
small in recent years.
0-aheadmirror forks lose theability to round-trip a vnl fix through both projects. In practice
these PRs have been rare and can still be done by hand if an
upstream-relevant fix surfaces.
ITK_USE_SYSTEM_VXLusers (if any exist in production) need amigration path. A deprecation cycle of one minor release is
reasonable.
Proposed sequence
ITK_USE_SYSTEM_VXLin the next minor release with awarning at configure time.
becomes the only path.
vnl_mathandvnl_*_fixedfirst (mechanical),vnl_matrix/vectorsecond(bulk but mechanical), solvers third, optimizers last with
numerical regression coverage.
Discussion points
something more honest about its scope (e.g., "VNLForITK") once
the prune lands?
framework's own modernization roadmap?