Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d1d9b7e
Update CUDA architectures to include additional support
ericwait Oct 3, 2025
67e6410
Use LLVM OpenMP on MSVC and apply compiler-specific OpenMP flags
ericwait Oct 17, 2025
5ea04df
Rename HIP Python module to Hydra; use Python3 CMake targets; bundle …
ericwait Oct 17, 2025
090235d
Add src/Python/hydra_image_processor.egg-info to .gitignore
ericwait Oct 17, 2025
984b746
Update src/Python/environment.yml: pin package versions, add tooling …
ericwait Oct 17, 2025
6e4022a
Fix CUDA error handling: actually throw exceptions on ROI send failur…
ericwait Oct 17, 2025
728f867
Restore default OpenMP detection on MSVC and remove obsolete build sc…
ericwait Oct 17, 2025
9e6f246
Restore MSVC default OpenMP flag and simplify OpenMP linking; move Py…
ericwait Oct 17, 2025
949f0cf
docs: update nomenclature from HIP to Hydra in core documentation
ericwait Feb 9, 2026
8f1c124
feat: add conda packaging recipe and build infrastructure
ericwait Feb 9, 2026
99b7dc8
build: configure python package structure and metadata for distribution
ericwait Feb 9, 2026
06c687f
ci: add github actions workflow for automated conda builds
ericwait Feb 9, 2026
9d4bffb
docs: add GEMINI context and CI-specific documentation
ericwait Feb 9, 2026
107dfb0
test: update python examples and test suite to use hydra namespace
ericwait Feb 9, 2026
8d3d0b8
build: add cmake presets and dll dependency helper script
ericwait Feb 9, 2026
7119c0b
feat(matlab): add new +Hydra package wrapper
ericwait Feb 9, 2026
c215d31
build: ignore agent config and conda build artifacts
ericwait Feb 9, 2026
5a241b4
docs: add code of conduct, security policy, and PR template
ericwait Feb 9, 2026
313057a
build: add tif file support to LFS in .gitattributes
ericwait Feb 10, 2026
b20596c
feat: add new brightMIP images for various filters and operations
ericwait Feb 10, 2026
4ea4681
feat: add new TIFF test images for various filters and operations
ericwait Feb 10, 2026
c7f1f07
feat: implement multi-platform build workflow and add C++ accuracy tests
ericwait Feb 28, 2026
67f3308
feat: add CLAUDE.md for project guidance and build instructions
ericwait Jul 4, 2026
657b54c
feat: add comprehensive roadmap for project vision and development ph…
ericwait Jul 4, 2026
a4f6daf
docs: restructure roadmap into five-step plan of record and add opera…
ericwait Jul 8, 2026
830c9d0
build: adopt scikit-build-core and make the CUDA source self-sufficient
ericwait May 30, 2026
4ab5413
ci: add Windows+Linux build-gate and tag-driven release
ericwait May 30, 2026
aa29ba4
docs: document conda-forge install and the build/release workflow
ericwait May 30, 2026
f0f260b
docs: add release testing checklist
ericwait May 30, 2026
246d75b
fix(python): center make_ellipsoid_mask on the kernel midpoint
ericwait Jul 8, 2026
74711fc
test: repair the C++ accuracy test build and CTest registration
ericwait Jul 8, 2026
81bd52c
test(python): add the TIFF accuracy suite TESTING.md gates on
ericwait Jul 8, 2026
6fee6c8
ci: install CUDA from conda-forge instead of the Jimver action
ericwait Jul 8, 2026
f3e9813
ci: build in the conda base env instead of a named env
ericwait Jul 9, 2026
e587c0f
ci: force the Ninja generator so nvcc comes from conda-forge
ericwait Jul 9, 2026
3b9d13a
ci: annotate build failures with the first error lines
ericwait Jul 9, 2026
354a338
ci: build against CUDA 13.x - nvcc 12.x rejects VS 2026
ericwait Jul 9, 2026
b490a70
fix: include <cstdint> where fixed-width integer types are used
ericwait Jul 9, 2026
0ceae51
chore: remove stray file created by a shell redirect
ericwait Jul 9, 2026
9e29b49
docs: set the 4.0.0 release date and record the pre-release fixes
ericwait Jul 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .condaignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
build/
out/
.vscode/
.claude/
*.mltbx
nul
*.reg
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
*.mexa64 filter=lfs diff=lfs merge=lfs -text
*.pyd filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
37 changes: 37 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

Fixes # (issue)

## Type of change

Please delete options that are not relevant.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration.

- [ ] Test A
- [ ] Test B

**Test Configuration**:
* Firmware version:
* Hardware:
* SDK:

## Checklist:

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream modules
98 changes: 98 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: CI

# Build-gate: compile the CUDA extension and import the package on the same
# platforms conda-forge ships (Windows + Linux). This catches source/recipe
# drift *before* a release reaches the feedstock. Runners have no GPU, so we
# only verify the package builds and imports; the full TIFF accuracy suite is
# run locally on a GPU box before tagging a release.

on:
push:
branches: [main, develop, conda-forge]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
python-matrix:
description: "Comma-separated Python versions to build"
default: "3.12"

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
build-gate:
name: Build & import (${{ matrix.os }}, py${{ matrix.python }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python: ["3.12"]

defaults:
run:
shell: bash -el {0}

steps:
- uses: actions/checkout@v4
with:
lfs: false # source build does not need the LFS test images

- name: Set up MSVC (Windows)
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1

- uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
channels: conda-forge
conda-remove-defaults: "true"
# Use base rather than a named env: activating the auto-created
# 'test' env intermittently fails on the Windows runners
# (EnvironmentNameNotFound), and base always exists.
activate-environment: ""

# CUDA comes from conda-forge (compiler only; runners have no GPU) —
# the same channel the feedstock builds against, and one less
# third-party action that breaks when runner images move.
# CUDA 13.x: nvcc 12.x rejects the MSVC that windows-latest ships
# (VS 2026); the 12.x pairing is covered by the feedstock's own CI,
# which pins VS 2022.
- name: Install build dependencies
run: conda install -y -c conda-forge python=${{ matrix.python }} cmake ninja "scikit-build-core>=0.10" numpy pip cuda-nvcc cuda-cudart-dev cuda-cudart-static "cuda-version=13.*"

- name: Install host compiler for nvcc (Linux)
if: runner.os == 'Linux'
run: conda install -y -c conda-forge c-compiler cxx-compiler

- name: Build & install (mirrors the feedstock pip path)
env:
# A single architecture keeps the gate fast; we only need it to
# compile + import, not to run on a specific GPU.
CMAKE_ARGS: "-DCMAKE_CUDA_ARCHITECTURES=75"
# Force Ninja: on Windows CMake would otherwise pick the Visual
# Studio generator, which needs the CUDA VS-integration files that
# the conda-forge nvcc package does not ship.
CMAKE_GENERATOR: Ninja
# On failure, surface the toolchain and first error lines as
# annotations so the failure is diagnosable from the run summary.
run: |
set -o pipefail
if ! python -m pip install . --no-build-isolation -v 2>&1 | tee build.log; then
echo "::error::cl=$(command -v cl 2>/dev/null || echo MISSING) nvcc=$(command -v nvcc 2>/dev/null || echo MISSING) cmake=$(cmake --version | head -1)"
grep -iE "error|fatal" build.log | head -n 8 | while IFS= read -r line; do echo "::error::${line}"; done
exit 1
fi

- name: Import smoke test (no GPU required to import)
run: |
python - <<'PY'
import hydra_image_processor as hip
import HIP, Hydra # legacy back-compat shims
print("hydra_image_processor", hip.__version__)
assert hip.__version__ == "4.0.0", hip.__version__
assert HIP is Hydra, "shims should both alias the compiled extension"
print("device_count:", hip.device_count()) # 0 on a GPU-less runner
PY
155 changes: 155 additions & 0 deletions .github/workflows/matlab-multibuild.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
name: Multi-Platform Toolbox Build

on:
push:
branches: [ "main", "master" ]
workflow_dispatch:

jobs:
build-mex-windows:
name: Build MEX (Windows)
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

- name: Install CUDA Toolkit
uses: Jimver/cuda-toolkit@v0.2.14
with:
cuda: '12.4.1'

- name: Setup MATLAB
uses: matlab-actions/setup-matlab@v2

- name: Configure CMake
run: |
cmake -S . -B build -G "Visual Studio 17 2022" -DHYDRA_MODULE_NAME=HIP
# Matlab_ROOT is set by setup-matlab and detected by FindMatlab module usually
# If not, we might need -DMatlab_ROOT_DIR=$env:MATLAB_ROOT

- name: Build MEX
run: |
cmake --build build --config Release --target HydraMex

- name: Verify Output
shell: powershell
run: |
# Verify the mex file exists in the source tree (copied by autoInstallMex)
if (Test-Path "src/MATLAB/+HIP/@Cuda/HIP.mexw64") {
Write-Host "MEX file found."
} else {
Write-Error "MEX file not found in src/MATLAB/+HIP/@Cuda/HIP.mexw64"
# Check build dir if autoInstall failed
Get-ChildItem -Recurse -Filter HIP.mexw64
exit 1
}

- uses: actions/upload-artifact@v4
with:
name: mex-windows
path: src/MATLAB/+HIP/@Cuda/HIP.mexw64

build-mex-linux:
name: Build MEX (Linux)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install CUDA Toolkit
uses: Jimver/cuda-toolkit@v0.2.14
with:
cuda: '12.4.1'

- name: Setup MATLAB
uses: matlab-actions/setup-matlab@v2

- name: Configure CMake
run: |
cmake -S . -B build -DHYDRA_MODULE_NAME=HIP

- name: Build MEX
run: |
cmake --build build --config Release --target HydraMex

- name: Verify Output
run: |
if [ -f "src/MATLAB/+HIP/@Cuda/HIP.mexa64" ]; then
echo "MEX file found."
else
echo "MEX file not found in src/MATLAB/+HIP/@Cuda/HIP.mexa64"
find . -name "HIP.mexa64"
exit 1
fi

- uses: actions/upload-artifact@v4
with:
name: mex-linux
path: src/MATLAB/+HIP/@Cuda/HIP.mexa64

package-toolbox:
name: Package Toolbox
needs: [build-mex-windows, build-mex-linux]
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

- name: Setup MATLAB
uses: matlab-actions/setup-matlab@v2

- name: Download Windows MEX
uses: actions/download-artifact@v4
with:
name: mex-windows
path: src/MATLAB/+HIP/@Cuda

- name: Download Linux MEX
uses: actions/download-artifact@v4
with:
name: mex-linux
path: src/MATLAB/+HIP/@Cuda

- name: Patch PRJ File
shell: python
run: |
import os

prj_path = r'src/MATLAB/HydraImageProcessor.prj'
with open(prj_path, 'r') as f:
content = f.read()

# Replace absolute paths with ${PROJECT_ROOT} if they look like the user's local path
# The user's path was D:\Users\ewait\git\programming\hydra-image-processor
# We'll just genericize any absolute path pattern if possible, or just the specific one.
# Easier: Update the <build-deliverables> section to use ${PROJECT_ROOT}

# Since we don't know the exact string that might be in the repo vs what was pasted,
# we will try to be smart.
# But actually, verify if the repo version has absolute paths.
# If it uses ${PROJECT_ROOT} mostly, we are good.
# The snippet showed absolute path in <build-deliverables>.

import re
# Regex to find <file ...>ANYTHING\Hydra Image Processor.mltbx</file> inside <build-deliverables>
# and replace it with <file ...>${PROJECT_ROOT}\Hydra Image Processor.mltbx</file>

new_content = re.sub(
r'(<build-deliverables>\s*<file[^>]*>).*?(\Hydra Image Processor\.mltbx</file>)',
r'\1${PROJECT_ROOT}\2',
content,
flags=re.DOTALL
)

with open(prj_path, 'w') as f:
f.write(new_content)

print("Patched .prj file.")

- name: Package Toolbox
uses: matlab-actions/run-command@v2
with:
command: |
matlab.addons.toolbox.packageToolbox('src/MATLAB/HydraImageProcessor.prj');

- uses: actions/upload-artifact@v4
with:
name: HydraImageProcessor.mltbx
path: src/MATLAB/Hydra Image Processor.mltbx
47 changes: 47 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Release

# Tag-driven release. Pushing a `vX.Y.Z` tag (after the CI gate is green on
# main) creates a GitHub Release. conda-forge's autotick bot detects the new
# release, opens a version-bump PR on the feedstock (updating version + sha256),
# and once merged the feedstock builds and publishes every variant.
#
# Release checklist:
# 1. Bump `[project].version` in pyproject.toml and update CHANGELOG.md.
# 2. Merge to main with a green CI gate.
# 3. git tag vX.Y.Z && git push origin vX.Y.Z (must match pyproject version)
# 4. Merge the feedstock autotick PR (or open one manually).

on:
push:
tags: ["v*"]

permissions:
contents: write # required to create a GitHub Release

jobs:
release:
name: Create GitHub Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
lfs: false

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Verify tag matches pyproject version
run: |
tag="${GITHUB_REF_NAME#v}"
pyproj="$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")"
echo "tag=$tag pyproject=$pyproj"
if [ "$tag" != "$pyproj" ]; then
echo "::error::Tag '$GITHUB_REF_NAME' does not match pyproject version '$pyproj'"
exit 1
fi

- name: Create GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --generate-notes --verify-tag
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,19 @@ CmakeCache.txt
out
.vs
CMakeSettings.json
src/Python/hydra_image_processor.egg-info

# Agent and Build artifacts
.claude/
conda-build-dir/

# Compiled extension dropped into the package dir by local CMake/pip builds
# (the wheel gets its copy from the CMake install rule, not from git)
/src/Python/hydra_image_processor/*.pyd
/src/Python/hydra_image_processor/*.so
/src/Python/hydra_image_processor/*.dylib

# Python build artifacts (scikit-build-core / pip / wheels)
/dist/
*.egg-info/
*.whl
Loading
Loading