Skip to content

ci: rebuild the MATLAB toolbox workflow on the proven CUDA toolchain - #11

Open
ericwait wants to merge 6 commits into
developfrom
feature/matlab-ci
Open

ci: rebuild the MATLAB toolbox workflow on the proven CUDA toolchain#11
ericwait wants to merge 6 commits into
developfrom
feature/matlab-ci

Conversation

@ericwait

@ericwait ericwait commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Why

The MATLAB toolbox workflow's only run (triggered by the v4.0.0 merge to main) failed on both platforms at the Jimver/cuda-toolkit install step — the exact breakage ci.yml already moved away from during the v4.0.0 CI rework. Nothing had compiled the MEX frontend since the 4.0 rework, so this repairs the workflow, re-proves the MATLAB build, and adds MATLAB testing.

What changed

Toolchain (ported from ci.yml): CUDA from conda-forge (compiler only; runners have no GPU), build in the conda base env, Ninja generator, CUDA 13.x (nvcc 12.x rejects the VS 2026 MSVC on windows-latest).

MATLAB integration:

  • Matlab_ROOT_DIR is passed explicitly — FindMatlab cannot discover the hosted-toolcache install location on its own.
  • MATLAB pinned to R2024b; the packaged toolbox records the same minimum release.
  • MATLAB launched directly by CMake's post-build is not licensed on hosted runners, so the post-build wrapper-generation hook is now behind HYDRA_MEX_AUTOINSTALL (default ON — local builds unchanged) and CI runs autoInstallMex via matlab-actions/run-command.
  • Linux MEX is built with GCC 12: MATLAB loads MEX files against its own bundled libstdc++, and R2024b rejects GCC 14 binaries (CXXABI_1.3.15 not found). This matters for end users, not just CI.

Bug fixes found by the new CI:

  • -DHYDRA_MODULE_NAME=HIP had been a silent no-op since the v4.0 build rework (a plain set() shadowed the cache variable), so the MEX always linked as Hydra.mex*. Now CACHE STRING.
  • AccuracyTest.m called Hydra.DeviceCount(), which does not exist (DeviceCount has no package-level wrapper) — GPU detection always failed and the whole accuracy suite silently skipped as Incomplete, even on a GPU box. Fixed to HIP.Cuda.DeviceCount().

Testing:

  • New Test.SmokeTest (matlab.unittest, no GPU): MEX loads, Info() returns the command table, DeviceCount() returns 0 gracefully, and the regenerated wrappers agree with the command table. CI runs it on both platforms.
  • TESTING.md now has MATLAB steps (build with -DHYDRA_MODULE_NAME=HIP since the wrappers hard-code HIP.Cuda; watch for Incomplete results) and a matlab-multibuild.yml checklist item.

Repo cleanup:

  • The stale pre-4.0 LFS-tracked MEX binaries (HIP.mexw64, HIP.mexa64, Hydra.mexw64) are removed; locally built MEX binaries and the packaged .mltbx are now gitignored. Users get binaries from the CI-built toolbox.

Packaging: the inline Python regex patch of the .prj is replaced by src/MATLAB/build-scripts/packageToolboxCI.m (programmatic ToolboxOptions, same GUID as the .prj so installs upgrade in place, version single-sourced from pyproject.toml — the .prj still said 3.1.2). The toolbox is packaged from the freshly generated wrappers, logo.png is pulled from LFS explicitly, and a guard fails the job if an LFS pointer ever lands where a MEX binary should be.

Triggers: PR (path-filtered, single CUDA arch for speed), push to main + workflow_dispatch (all-major), and release: published attaches the .mltbx to the GitHub Release.

🤖 Generated with Claude Code

The workflow's only run (v4.0.0 merge) failed on both platforms at the
Jimver CUDA install step - the same breakage ci.yml already moved away
from. Port the four ci.yml lessons: CUDA from conda-forge, conda base
env, Ninja generator, CUDA 13.x (nvcc 12.x rejects VS 2026 MSVC).

Other fixes while rebuilding it:
- Pass Matlab_ROOT_DIR explicitly; FindMatlab cannot discover the
  hosted-toolcache install on its own.
- Pin MATLAB R2024b (the release the .prj was authored with) so the
  MEX binaries match the toolbox's recorded minimum release.
- Replace the inline .prj regex patch with packageToolboxCI.m, which
  packages programmatically via ToolboxOptions - no machine-specific
  absolute paths, version single-sourced from pyproject.toml (the old
  .prj still said 3.1.2).
- Package with the freshly generated .m wrappers from the Windows
  build instead of the checked-in copies, and guard against Git LFS
  pointer files sneaking into the toolbox.
- Run path-filtered on PRs (single CUDA arch for speed), all-major on
  main, and attach the .mltbx to published GitHub Releases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Reviewer's Guide

Rebuilds the MATLAB toolbox GitHub Actions workflow to use the same conda-forge CUDA toolchain as ci.yml, adds explicit MATLAB discovery and version pinning, refactors toolbox packaging into a scripted MATLAB entry point with single-sourced versioning, and tightens triggers, artifacts, and release attachment behavior.

File-Level Changes

Change Details Files
Replaced the two separate Windows/Linux MEX build jobs with a matrix-based build job that uses the conda-forge CUDA toolchain, Ninja, and explicit MATLAB root discovery, while adjusting triggers, concurrency, and CUDA architectures for PR vs main/release builds.
  • Renamed the workflow to "MATLAB Toolbox" and updated triggers to include pull_request with path filters, push to main, workflow_dispatch, and release: published, plus added a concurrency group per ref.
  • Consolidated build-mex-windows and build-mex-linux into a single matrix job over windows-latest and ubuntu-latest, using bash shells, Ninja generator, and CMAKE_CUDA_ARCHITECTURES controlled by an env var based on event type.
  • Switched CUDA installation from Jimver/cuda-toolkit to conda-incubator/setup-miniconda plus conda-forge packages (cmake, ninja, cuda-nvcc, cuda-cudart-, and host C/C++ compilers on Linux).
  • Added MSVC environment setup on Windows and a MATLAB release env var (R2024b) passed to matlab-actions/setup-matlab, then used matlab-actions/run-command to write matlabroot to a file and feed it to CMake via Matlab_ROOT_DIR.
  • Enhanced build logging and error reporting by teeing CMake output, printing toolchain paths on failure, and surfacing a few error lines as GitHub annotations.
  • Verified post-build that HIP.mex exists in the expected MATLAB package location, and added a warning-only check for drift between generated .m wrappers and committed ones.
  • Changed artifact strategy so Windows uploads the full +HIP directory (excluding HIP.mexa64) as hip-package-windows, and Linux uploads only HIP.mexa64 as mex-linux.
.github/workflows/matlab-multibuild.yml
Refactored toolbox packaging in the workflow to use a dedicated MATLAB script that builds the .mltbx from the repository layout and single-sources the version from pyproject.toml, with guards against Git LFS pointer binaries and optional release attachment.
  • Removed the inline Python step that patched HydraImageProcessor.prj and replaced it with a bash step that extracts the version from pyproject.toml and exports it as TOOLBOX_VERSION.
  • Added a guard step that checks HIP.mexw64 and HIP.mexa64 sizes to ensure they are real binaries and not Git LFS pointers, failing the job if they look too small.
  • Updated the packaging step to call packageToolboxCI(version) via matlab-actions/run-command, and ensured MATLAB is set up with the same R2024b release used in the build job.
  • Configured artifact upload to require the presence of Hydra Image Processor.mltbx and added a conditional step that, on release events, uses gh release upload to attach the toolbox to the corresponding GitHub Release tag.
.github/workflows/matlab-multibuild.yml
pyproject.toml
src/MATLAB/build-scripts/packageToolboxCI.m
Introduced a MATLAB build-script entry point for CI packaging that constructs ToolboxOptions programmatically, defines metadata, enforces minimum MATLAB release and supported platforms, and validates required MEX binaries before packaging.
  • Created packageToolboxCI.m under src/MATLAB/build-scripts, which derives paths relative to the script location to locate src/MATLAB, +HIP, and the repository root.
  • Configured ToolboxOptions with GUID matching HydraImageProcessor.prj, toolbox name, version, author data, summary, description, icon path, toolbox files (+HIP and CudaMexTester.m), Matlab path, minimum MATLAB release R2024b, and platform support flags.
  • Set the output .mltbx path to src/MATLAB/Hydra Image Processor.mltbx and added a pre-check that errors out if either HIP.mexw64 or HIP.mexa64 is missing from +HIP/@cuda before calling matlab.addons.toolbox.packageToolbox.
  • Documented that HydraImageProcessor.prj remains for interactive packaging while CI uses packageToolboxCI to avoid machine-specific paths and ensure consistent metadata.
src/MATLAB/build-scripts/packageToolboxCI.m
CLAUDE.md
Updated project documentation to describe the new MATLAB toolbox workflow behavior and packaging entry point, aligning CI docs with the rebuilt workflow.
  • Modified the CI section in CLAUDE.md to describe matlab-multibuild.yml as using the same conda-forge CUDA toolchain as ci.yml plus matlab-actions/setup-matlab.
  • Documented that CI packaging now goes through src/MATLAB/build-scripts/packageToolboxCI.m with version single-sourced from pyproject.toml, and that HydraImageProcessor.prj is only for interactive IDE packaging.
  • Noted that the workflow attaches the .mltbx artifact to published GitHub Releases.
CLAUDE.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 832dfce0-ab5a-47dc-ae72-257f010fb54a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/matlab-ci

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The toolbox version extraction in package-toolbox relies on a simple grep/sed pattern; consider making this more robust to pyproject formatting changes (e.g., multiline or commented version fields) to avoid silent misparsing.
  • Both the workflow and packageToolboxCI.m encode the MATLAB release (via MATLAB_RELEASE env and MinimumMatlabRelease); centralizing this value or asserting they match at runtime would reduce the risk of them drifting apart.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The toolbox version extraction in `package-toolbox` relies on a simple `grep`/`sed` pattern; consider making this more robust to pyproject formatting changes (e.g., multiline or commented version fields) to avoid silent misparsing.
- Both the workflow and `packageToolboxCI.m` encode the MATLAB release (via `MATLAB_RELEASE` env and `MinimumMatlabRelease`); centralizing this value or asserting they match at runtime would reduce the risk of them drifting apart.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

ericwait and others added 5 commits July 8, 2026 21:56
…ld hook

Both platforms compiled and linked HydraMex, then failed with License
Manager Error -1: the matlab-actions self-licensing on hosted runners
only covers MATLAB launched through their actions, not a matlab -batch
spawned by the CMake POST_BUILD step. Gate that step behind a new
HYDRA_MEX_AUTOINSTALL option (default ON, so local builds keep the
old behavior) and have the workflow run autoInstallMex via
matlab-actions/run-command after the build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The plain set(HYDRA_MODULE_NAME Hydra) silently shadowed the cache
variable, so -DHYDRA_MODULE_NAME=HIP (documented, and used by the
MATLAB CI to build HIP.mex*) has been a no-op since the v4.0 build
rework - the MEX always linked as Hydra.mex*. Declare it as a CACHE
STRING so the command line wins and the default stays Hydra.

Caught by the rebuilt MATLAB workflow: autoInstallMex could not find
build/src/c/Mex/HIP.mexa64 because the file was Hydra.mexa64.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MATLAB resolves a MEX file's libstdc++ from its own bundled copy, and
R2024b's rejects binaries built with GCC 14 (CXXABI_1.3.15 not found)
- conda-forge's current default cxx-compiler. Build with GCC 12 so the
MEX loads on R2024b and newer for end users as well, not just in CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The toolbox image is LFS-tracked, so the lfs:false checkout leaves a
pointer file and ToolboxOptions rejects it as an unrecognized image
format. Fetch just that file - the remaining LFS assets are large test
images the packaging job does not need.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Remove the LFS-tracked pre-4.0 MEX binaries (HIP.mexw64, HIP.mexa64,
  Hydra.mexw64) and gitignore locally built ones plus the packaged
  .mltbx - users get binaries from the CI-built toolbox, not git.
- Add Test.SmokeTest (matlab.unittest, no GPU): the MEX must load,
  Info() must return the command table, DeviceCount must return 0
  gracefully, and the generated wrappers must agree with the command
  table. matlab-multibuild.yml now runs it on both platforms after
  regenerating the wrappers.
- Fix AccuracyTest GPU detection: it called Hydra.DeviceCount(), which
  does not exist (DeviceCount has no package-level wrapper), so
  devCount was always 0 and the whole suite silently skipped as
  Incomplete even on a GPU box. Use HIP.Cuda.DeviceCount().
- Document the MATLAB steps in TESTING.md (build with
  -DHYDRA_MODULE_NAME=HIP since the wrappers hard-code HIP.Cuda; watch
  for Incomplete results) and CLAUDE.md.
- Simplify the Windows artifact upload: with no checked-in mexa64
  pointer to dodge, upload the whole +HIP directory.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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