Skip to content

Build linux/aarch64 wheels by compiling VTK from source - #61

Closed
jqmcginnis wants to merge 1 commit into
pyushkevich:masterfrom
jqmcginnis:feat/linux-aarch64-wheels
Closed

Build linux/aarch64 wheels by compiling VTK from source#61
jqmcginnis wants to merge 1 commit into
pyushkevich:masterfrom
jqmcginnis:feat/linux-aarch64-wheels

Conversation

@jqmcginnis

@jqmcginnis jqmcginnis commented Aug 10, 2026

Copy link
Copy Markdown

Hi, thank you very much for providing greedy. We are actively using it in LST-AI and really love the speed and performance.

Right now, we are actively trying to port our stack to non x86 architectures, most recently using the DGX Spark architecture (ARM-based CPU).

Why?

picsl-greedy publishes no linux aarch64 wheel. The blocker isn't greedy; it builds fine on arm64, as the macOS arm64 wheels demonstrate. It's Kitware's VTK wheel-SDK that prebuild.sh downloads, which exists for x86_64 only:

version x86_64 aarch64
9.3.1 200 404
9.4.1 200 404
9.5.0 / 9.6.0 no SDK published n/a

Everything else prebuild.sh needs (Eigen, ITK) is already built from source and is architecture-agnostic. Only VTK has to change.

What

On aarch64, build VTK from source instead of downloading the SDK, enabling only the ten modules CMakeLists.txt requires and refusing the Rendering/Qt/Views/Web/Imaging/MPI groups. That's what keeps it cheap, the whole prebuild takes ~6 mins in manylinux2014_aarch64.

compile.yml enables the ubuntu-22.04-arm runner already present in your commented-out matrix, and sets CIBW_ARCHS_LINUX: auto so each linux runner builds natively.

Two things you may want to know regardless of this PR

The ubuntu-* branch matches on OS alone, so enabling an arm runner without this change would have silently downloaded the x86_64 SDK. It now tests uname -m.

VTK's exported targets resolve library paths relative to the config file. CMake walks three levels up from vtk-9.3.1.data/headers/cmake, so VTK is installed into install/vtk for that arithmetic to land correctly, and the config is symlinked to the SDK's path. This means CIBW_ENVIRONMENT's VTK_DIR needs no per-arch variant and every other platform is byte-identical.

Verification

Built on a DGX Spark (GB10, aarch64). The wheel imports and registers. On five subjects of the Mendeley MS dataset, an affine registration recovering a known 6 degree rotation plus 5 voxel translation raised lesion-mask Dice from a range of 0.15 to 0.40 (before registration) to a mean of 0.989 (after).

Note re #57

#57 bumps cibuildwheel two lines from one of our edits, so a small conflict is likely. More substantively: if that bump moves the default manylinux image to manylinux_2_28, ITK 5.2.1 will fail to build, 'uint8_t' was not declared in this scope in itkMathematicalMorphologyEnums.h, because GCC 13 no longer includes <cstdint> transitively. We hit this directly. manylinux2014 (GCC 10.2.1) is unaffected, so this PR doesn't need a workaround, but it will surface whenever the image moves.

AI Disclosure

We used claude code in the development process.

picsl-greedy publishes no linux aarch64 wheel. The blocker is not greedy
itself — it builds fine on arm64, as the macOS arm64 wheels show — but
Kitware's VTK wheel-SDK, which prebuild.sh downloads and which exists for
x86_64 only. There is no aarch64 build at any published version (9.3.1
and 9.4.1 return 404 for the aarch64 tarball; 9.5.0 and 9.6.0 publish no
SDK at all).

Everything else prebuild.sh needs is already built from source and is
architecture-agnostic: Eigen and ITK. So only VTK has to change.

On aarch64, build VTK from source instead of downloading the SDK. Only
the ten modules greedy's CMakeLists requires are enabled, and the
Rendering/Qt/Views/Web/Imaging/MPI groups are refused, which is what
keeps this cheap — the whole prebuild (Eigen + VTK + ITK + greedy with
Python wrapping) takes 583 seconds in manylinux2014_aarch64.

Two details worth noting:

  * The ubuntu branch previously matched on OS alone, so enabling an arm
    runner would have downloaded the x86_64 SDK. It now tests uname -m.

  * VTK's exported targets resolve library paths relative to the config
    file, walking three levels up from vtk-9.3.1.data/headers/cmake. VTK
    is therefore installed into install/vtk so that arithmetic lands
    correctly, and the config is symlinked to the path the wheel-SDK
    would have provided — so CIBW_ENVIRONMENT's VTK_DIR needs no
    per-architecture variant and every other platform is untouched.

The static build leaves install/vtk/shared empty; auditwheel has nothing
to bundle, which is correct for a static VTK.

compile.yml enables the ubuntu-22.04-arm runner already present in the
commented-out matrix, and sets CIBW_ARCHS_LINUX to auto so each linux
runner builds its native architecture.

Verified on a DGX Spark (GB10, aarch64): the resulting wheel imports and
registers correctly. On five subjects of the Mendeley MS dataset, an
affine registration recovering a known 6 degree rotation plus 5 voxel
translation raised expert lesion-mask Dice from 0.15-0.40 to a mean of
0.989.
@jqmcginnis

Copy link
Copy Markdown
Author

Closing this in favour of an equivalent PR against pyushkevich/greedy_python, which is where the published picsl-greedy wheels are built — this repo's pyproject.toml is at 0.0.9 while PyPI ships 1.4.0. Same change, right place. (For anyone else who lands here: PyPI's Homepage metadata for picsl-greedy points at this repo, which is what sent me here.)

One finding that applies to this repo regardless of the wheel question: prebuild.sh matches ubuntu-* on OS alone, so enabling an arm runner in compile.yml would silently download the x86_64 VTK wheel-SDK rather than failing. Worth an uname -m test if that path is still used.

Apologies for the noise.

@jqmcginnis jqmcginnis closed this Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant