Skip to content

Implementation of Remaining Metal Backend - #36

Merged
rg2 merged 12 commits into
masterfrom
metal_sim_metrics
Oct 8, 2026
Merged

rg2 merged 12 commits into
masterfrom
metal_sim_metrics

Conversation

@rg2

@rg2 rg2 commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

Summary

Adds Metal implementations of the 2D similarity metrics and of the surface rendering and occluding contour ray casters. With these, a registration can run on a Mac GPU with Metal for both ray casting and similarity scoring. Metal becomes the default backend when a Metal device is available.

New Metal implementations

2D similarity metrics (lib/regi/sim_metrics_2d/)

  • SSD, NCC, Grad-NCC, Patch NCC and Patch Grad-NCC (ImgSimMetric2D*Metal), with a shared base class ImgSimMetric2DMetal.
  • They follow the OpenCL implementations' semantics: mask handling, Gaussian smoothing, edge handling and patch weighting. They don't support the CPU-only Patch NCC options.
  • --backend metal works for all five *SimMetricFromProgOpts() factories.

Ray casters (lib/ray_cast/)

  • RayCasterSurRenderMetal: Phong-shaded surface rendering.
  • RayCasterOccludingContoursMetal: occluding contours.

Shared Metal infrastructure

  • MetalComputeEncoder (xregMetalCompute.h): a plain C++ wrapper for encoding several dependent kernel dispatches and waiting once, so metric and caster classes don't need Objective-C++.
  • ThreadgroupReducer (xregMetalReduce.metal): sums across a threadgroup using SIMD-group reductions.
  • BacktrackToSurface and CentralDiffGradient in xregRayCastBaseMetal.metal. The existing depth kernel now uses BacktrackToSurface; its results are unchanged.

Bug fixes in existing code

  • ImgSimMetric2DSSDOCL: kernel arguments were set before the fixed-image and mask buffers existed. With a host fixed image this crashed; otherwise the image length argument was 0, so the result was each moving image's mean intensity instead of the SSD.
  • RayCasterSurRenderOCL:
    • one extra backtracking step was taken, even with 0 steps requested;
    • backtracking moved in the wrong direction;
    • the surface normal had length 2, which doubled the diffuse term and distorted the specular term.
  • RayCasterSurRenderCPU:
    • the volume's upper index bound was never initialized (std::tie(min, min));
    • an out-of-bounds write to a Pt2 divided every shaded value by the camera focal length.
  • RayCasterOccludingContoursCPU: when continuing past a collision with backtracking, the ray resumed from the backtracked position and stopped advancing inside objects. It now resumes from the sample.

Behaviour changes

  • Default backend: Metal is now the default when a Metal device is available. The backend order is Metal, then OpenCL, then CPU, so systems without Metal are unaffected. --backend ocl and --backend cpu still work.
  • --ocl-id: now accepts any case-insensitive substring that matches exactly one OpenCL device ID, the same as --metal-id. No match, or more than one, is an error that lists the IDs. An exact full ID still takes precedence. The matching logic is shared via FindMapEntriesByKeySubstrIgnoreCase (xregStringUtils.h).
  • tests/wiki_cmds.py: new --backend and --device options.

@rg2
rg2 marked this pull request as ready for review October 8, 2026 21:14
@rg2
rg2 merged commit dd27405 into master Oct 8, 2026
3 checks passed
@rg2
rg2 deleted the metal_sim_metrics branch October 9, 2026 16:58
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