Skip to content

Add upsample2d Bilinear (eager+autodiff) and traceable StableHLO lowering (Nearest + Bilinear)#771

Merged
michalharakal merged 2 commits into
developfrom
feat/upsample2d-stablehlo
Jun 28, 2026
Merged

Add upsample2d Bilinear (eager+autodiff) and traceable StableHLO lowering (Nearest + Bilinear)#771
michalharakal merged 2 commits into
developfrom
feat/upsample2d-stablehlo

Conversation

@michalharakal

Copy link
Copy Markdown
Contributor

Closes #770.

What

upsample2d previously existed eager-only for Nearest and had no StableHLO converter, so a traced upsample2d node fell through to the converter's "Operation not supported" path and could not export → compile → run on IREE (blocking YOLO/FPN-style models). This PR makes upsample2d first-class and exportable for both modes.

Because scale, sizes and alignCorners are all static at trace time, both modes lower to fixed shape/linear ops — no runtime index math, no custom_call, so they compile on stock IREE.

Changes

  • DefaultCpuOps.upsample2d — add Bilinear forward (PyTorch coordinate map with/without align_corners, border clamp, 4-neighbor blend). Nearest unchanged.
  • DefaultExecutionTape.upsample2dGrad — dispatch by mode; Bilinear backward is the scatter transpose of the forward (distribute each output gradient to its 4 source neighbors with the same weights). Now threads alignCorners from the recorded attributes.
  • NeuralNetOperationsConverter.convertUpsample2d (new; registered in supportedOperations + when):
    • Nearest → pixel replication: reshape [N,C,H,W] → [N,C,H,1,W,1]broadcast_in_dim → [N,C,H,sH,W,sW]reshape → [N,C,H*sH,W*sW], exactly matching out[oh,ow]=in[oh/sH,ow/sW].
    • Bilinear → separable linear map: precompute constant resize matrices A_h [outH×inH], A_w [outW×inW] (each row = the two bilinear neighbor weights) and apply via two stablehlo.dot_general contractions (no transposes). The weights are the same static floats the eager blend uses, so results match to fp tolerance.

Tests

  • Upsample2dConverterTest (new) — Nearest reshape/broadcast lowering; Bilinear constant-matrix + dot_general lowering; both assert no custom_call / unsupported path.
  • DefaultCpuOpsUpsampleTest — Bilinear forward golden values (corners clamp; interior blends).
  • ConvPoolBackwardTest — Bilinear backward vs finite-difference.

All three module test suites pass locally (skainet-backend-cpu, skainet-compile-dag, skainet-compile-hlo).

Follow-up

A conformance op-suite probe (separate repo) that compiles+runs+validates these on IREE, gated on a release/source build containing this change.

🤖 Generated with Claude Code

michalharakal and others added 2 commits June 28, 2026 17:15
…ering for both modes #770

upsample2d existed eager-only for Nearest with no StableHLO converter, so any
traced upsample node hit the "Operation not supported" path and could not export
(blocking YOLO/FPN). Add Bilinear end-to-end and a converter for both modes.
Because scale/sizes/alignCorners are static at trace time, both lower to fixed
shape/linear ops (no runtime index math, no custom_call):

- DefaultCpuOps.upsample2d: Bilinear forward (PyTorch coord map + clamp + blend).
- DefaultExecutionTape.upsample2dGrad: mode dispatch; Bilinear = scatter transpose.
- NeuralNetOperationsConverter.convertUpsample2d:
    Nearest  -> reshape/broadcast_in_dim/reshape pixel replication.
    Bilinear -> constant resize matrices A_h/A_w applied via two dot_general.

Tests: Upsample2dConverterTest (both modes), Bilinear forward golden values,
Bilinear backward vs finite-difference.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kotlinStoreYarnLock fails on develop-based PRs because the committed JS
kotlin-js-store/yarn.lock (last touched Jun 7) drifted from the resolved
build/js/yarn.lock (lockFileMismatchReport:FAIL). A transitive now pulls
ws 8.20.1. Mirrors the earlier Kotlin/Wasm lock bump (c67f515). Unrelated
to the upsample2d change in this branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@michalharakal michalharakal merged commit a1e40e8 into develop Jun 28, 2026
6 checks passed
@michalharakal michalharakal deleted the feat/upsample2d-stablehlo branch June 28, 2026 16:27
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.

upsample2d: implement Bilinear (eager + autodiff) and add StableHLO lowering for both modes

1 participant