Skip to content

Proposal: Hard-fork vnl — drop ITK_USE_SYSTEM_VXL and stop tracking upstream vxl #6250

@hjmjohnson

Description

@hjmjohnson

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:

  1. Aggressively prune. Delete every header outside the closure of
    what ITK actually compiles. The source tree shrinks by a large
    majority.
  2. 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.
  3. Stage a migration to Eigen and std.
    • vnl_math<numbers> / <cmath>
    • vnl_*_fixed<T,N,M>Eigen::Matrix<T,N,M>
    • vnl_matrix / vnl_vectorEigen::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.
  4. 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

  1. Decision on this issue (community discussion, vote if needed).
  2. Deprecate ITK_USE_SYSTEM_VXL in the next minor release with a
    warning at configure time.
  3. Remove the option in the release after that. Vendored copy
    becomes the only path.
  4. Prune the vendored tree to the closure of what ITK builds.
  5. 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions