runner: add --hybrid-rendering to render Cycles on CPU and GPU together #34

Merged
linus merged 1 commit from ash/hybrid-rendering-33 into develop 2026-10-30 03:54:46 +00:00
Collaborator

Closes #33.

Adds a runner option --hybrid-rendering (env JIGGABLEND_HYBRID_RENDERING, default off). With a GPU backend selected, the render script now enables the CPU device next to the GPU instead of disabling it. The option is ignored when the job renders on CPU only (--force-cpu-rendering, GPU lockout, failed GPU detection, job force_cpu) and when no GPU is found; both cases log why. With the option off, device selection is unchanged.

The task log now lists every enabled device after selection, e.g.

Render devices (hybrid GPU+CPU, 2 enabled):
  - Radeon 8060S [HIP]
  - AMD Ryzen AI Max+ 395 [CPU]

This replaces the hand-placed blender-hybrid wrapper on ai1.

Changes

  • cmd/jiggablend/cmd/runner.go, internal/runner/runner.go: flag, viper binding, startup log, passed into the task context.
  • internal/runner/tasks/processor.go: Context.HybridRendering and ShouldUseHybrid() (off whenever ShouldForceCPU()).
  • internal/runner/tasks/render.go: sends hybrid_cpu in the render settings, logs enabled/ignored.
  • pkg/scripts/scripts/render_blender.py.template: CPU device.use = hybrid_cpu, enabled-device list, no-GPU notice.
  • README "Running a Runner" documents the flag.

Tests (my run on the jumpbox, go test -count=1 ./...): 210 pass, 4 skip, 1 fail. The fail is TestIntegration_Encode_EXR_H264, which needs ffmpeg; the jumpbox has none, CI does.
New: TestContext_ShouldUseHybrid (6 cases) and four TestRenderScript_Hybrid* tests that render the real generated script through a fake bpy (testdata/fake_bpy_harness.py) and assert which devices end up enabled: off keeps GPU only, on enables GPU+CPU, force-cpu and no-GPU leave CPU only. I checked that three of them fail against the old template.

Not proven here: a real Blender render. The jumpbox has no Blender or GPU. Before merge, a real render on ai1 with --hybrid-rendering should show both devices in the task log (and one with it off showing GPU only). Manager-side reporting of hybrid runners is a follow-up per Mira.

Release note: Runners can render Cycles on the CPU alongside the GPU with --hybrid-rendering or JIGGABLEND_HYBRID_RENDERING=true (off by default).

Closes #33. Adds a runner option `--hybrid-rendering` (env `JIGGABLEND_HYBRID_RENDERING`, default off). With a GPU backend selected, the render script now enables the CPU device next to the GPU instead of disabling it. The option is ignored when the job renders on CPU only (`--force-cpu-rendering`, GPU lockout, failed GPU detection, job `force_cpu`) and when no GPU is found; both cases log why. With the option off, device selection is unchanged. The task log now lists every enabled device after selection, e.g. ``` Render devices (hybrid GPU+CPU, 2 enabled): - Radeon 8060S [HIP] - AMD Ryzen AI Max+ 395 [CPU] ``` This replaces the hand-placed blender-hybrid wrapper on ai1. **Changes** - `cmd/jiggablend/cmd/runner.go`, `internal/runner/runner.go`: flag, viper binding, startup log, passed into the task context. - `internal/runner/tasks/processor.go`: `Context.HybridRendering` and `ShouldUseHybrid()` (off whenever `ShouldForceCPU()`). - `internal/runner/tasks/render.go`: sends `hybrid_cpu` in the render settings, logs enabled/ignored. - `pkg/scripts/scripts/render_blender.py.template`: CPU `device.use = hybrid_cpu`, enabled-device list, no-GPU notice. - README "Running a Runner" documents the flag. **Tests** (my run on the jumpbox, `go test -count=1 ./...`): 210 pass, 4 skip, 1 fail. The fail is `TestIntegration_Encode_EXR_H264`, which needs ffmpeg; the jumpbox has none, CI does. New: `TestContext_ShouldUseHybrid` (6 cases) and four `TestRenderScript_Hybrid*` tests that render the real generated script through a fake `bpy` (`testdata/fake_bpy_harness.py`) and assert which devices end up enabled: off keeps GPU only, on enables GPU+CPU, force-cpu and no-GPU leave CPU only. I checked that three of them fail against the old template. **Not proven here:** a real Blender render. The jumpbox has no Blender or GPU. Before merge, a real render on ai1 with `--hybrid-rendering` should show both devices in the task log (and one with it off showing GPU only). Manager-side reporting of hybrid runners is a follow-up per Mira. **Release note:** Runners can render Cycles on the CPU alongside the GPU with `--hybrid-rendering` or `JIGGABLEND_HYBRID_RENDERING=true` (off by default).
runner: add --hybrid-rendering to render Cycles on CPU and GPU together (closes #33)
All checks were successful
CI / check-and-test (pull_request) Successful in 1m46s
b562f88682
The render script enabled only the GPU devices and switched the CPU off,
so Cycles hybrid rendering needed a hand-placed Blender wrapper on ai1.

New runner option --hybrid-rendering (env JIGGABLEND_HYBRID_RENDERING,
default off). When a GPU backend is selected, the CPU device is enabled
next to the GPU instead of being disabled. It is ignored when the job
renders on CPU only (--force-cpu-rendering, GPU lockout, failed GPU
detection, job force_cpu) and when no GPU is found.

The task log now lists every enabled render device, e.g.
"Render devices (hybrid GPU+CPU, 2 enabled):". With the option off the
device selection is unchanged.

Release note: runners can render Cycles on the CPU alongside the GPU with
--hybrid-rendering or JIGGABLEND_HYBRID_RENDERING=true (off by default).
ash requested review from eva 2026-10-29 14:57:38 +00:00
eva approved these changes 2026-10-29 14:59:56 +00:00
eva left a comment

GO on b562f88 for the code.

The flag is wired cleanly from the CLI through viper, RunnerOptions and the task context into the render settings. ShouldUseHybrid() sits on top of ShouldForceCPU(), so every CPU-only path (flag, lockout, failed detection, job force_cpu) ignores it, and the template only flips device.use on CPU devices inside the GPU branch. With the flag off, the only change in behavior is the new "Render devices" list in the log. The fake bpy harness is a good way to test the real generated script without Blender, and thanks for checking that the tests fail against the old template.

One gate before merge, as you said in the body: a real render on ai1 with --hybrid-rendering that shows both the GPU and the CPU in the task log, plus one with the flag off that shows the GPU only. Linus, please hold the merge until that proof is posted here and CI is green. Not security-sensitive, so Blake isn't needed.

GO on b562f88 for the code. The flag is wired cleanly from the CLI through viper, RunnerOptions and the task context into the render settings. `ShouldUseHybrid()` sits on top of `ShouldForceCPU()`, so every CPU-only path (flag, lockout, failed detection, job `force_cpu`) ignores it, and the template only flips `device.use` on CPU devices inside the GPU branch. With the flag off, the only change in behavior is the new "Render devices" list in the log. The fake bpy harness is a good way to test the real generated script without Blender, and thanks for checking that the tests fail against the old template. One gate before merge, as you said in the body: a real render on ai1 with `--hybrid-rendering` that shows both the GPU and the CPU in the task log, plus one with the flag off that shows the GPU only. Linus, please hold the merge until that proof is posted here and CI is green. Not security-sensitive, so Blake isn't needed.
Author
Collaborator

Hybrid half of the ai1 gate, from Jerry's live trial (record: /workspace/state/jiggablend-trial.md, section "10/29 1:30-1:42 PM CT").

ai1 runner is this PR's build: b562f88, built on the jumpbox as 0.0.14-pr34-b562f88, unit ExecStart has --hybrid-rendering, /usr/local/bin/blender pointed straight at Blender 5.2.3 (old blender-hybrid wrapper out of the path, and its log got no new entries). The runner registered with the manager (0.0.12) and took tasks with no protocol mismatch.

Job 4 (KIRA v3, frames 500-620, EXR), task 3925, frame 500, task log:

Hybrid rendering enabled ... (--hybrid-rendering)
Enabling CPU devices (hybrid rendering)...
Enabled CPU: AMD RYZEN AI MAX+ 395
Enabled: AMD Radeon Graphics
Enabled HIPRT
Render devices (hybrid GPU+CPU, 2 enabled)

The render was sampling at 240/4096 by 1:41 PM CT. These lines are quoted from Jerry's record; I haven't read the task log myself.

Still open: the flag-off half (same build, no --hybrid-rendering, task log shows the GPU only). Jerry's focused job 4 is mid-trial, so I'm asking for one flag-off frame when job 4 ends or at the next runner restart, not an interruption. Linus: keep holding the merge until that's posted.

Hybrid half of the ai1 gate, from Jerry's live trial (record: `/workspace/state/jiggablend-trial.md`, section "10/29 1:30-1:42 PM CT"). ai1 runner is this PR's build: b562f88, built on the jumpbox as `0.0.14-pr34-b562f88`, unit ExecStart has `--hybrid-rendering`, `/usr/local/bin/blender` pointed straight at Blender 5.2.3 (old blender-hybrid wrapper out of the path, and its log got no new entries). The runner registered with the manager (0.0.12) and took tasks with no protocol mismatch. Job 4 (KIRA v3, frames 500-620, EXR), task 3925, frame 500, task log: ``` Hybrid rendering enabled ... (--hybrid-rendering) Enabling CPU devices (hybrid rendering)... Enabled CPU: AMD RYZEN AI MAX+ 395 Enabled: AMD Radeon Graphics Enabled HIPRT Render devices (hybrid GPU+CPU, 2 enabled) ``` The render was sampling at 240/4096 by 1:41 PM CT. These lines are quoted from Jerry's record; I haven't read the task log myself. Still open: the flag-off half (same build, no `--hybrid-rendering`, task log shows the GPU only). Jerry's focused job 4 is mid-trial, so I'm asking for one flag-off frame when job 4 ends or at the next runner restart, not an interruption. Linus: keep holding the merge until that's posted.
Contributor

GPU-only proof render (flag off) on ai1, same build 0.0.14-pr34-b562f88, runner started without --hybrid-rendering. Job 4, frame 584, task 4009 (2026-10-30 03:42 UTC).

Starting task: job 4, frame 584, format: EXR
Found devices by type: ['CPU', 'HIP']
Selected HIP as best GPU type with 1 device(s)
Enabling GPU devices for HIP...
  Disabling CPU devices...
    Disabled CPU: AMD RYZEN AI MAX+ 395
  Enabled: AMD Radeon Graphics
  Enabled HIPRT (HIP Ray Tracing) for faster rendering
SUCCESS: Enabled 1 GPU device(s) for HIP
Render devices (GPU only, 1 enabled):
  - AMD Radeon Graphics [HIP]
Final Cycles device: GPU

The hybrid half (flag on, GPU+CPU) was proven in comment 8154. The frame-583 crash during the hybrid run was a segfault in Embree on the CPU side, not in this PR's device selection; it's tracked as a separate issue.

GPU-only proof render (flag off) on ai1, same build `0.0.14-pr34-b562f88`, runner started without `--hybrid-rendering`. Job 4, frame 584, task 4009 (2026-10-30 03:42 UTC). ``` Starting task: job 4, frame 584, format: EXR Found devices by type: ['CPU', 'HIP'] Selected HIP as best GPU type with 1 device(s) Enabling GPU devices for HIP... Disabling CPU devices... Disabled CPU: AMD RYZEN AI MAX+ 395 Enabled: AMD Radeon Graphics Enabled HIPRT (HIP Ray Tracing) for faster rendering SUCCESS: Enabled 1 GPU device(s) for HIP Render devices (GPU only, 1 enabled): - AMD Radeon Graphics [HIP] Final Cycles device: GPU ``` The hybrid half (flag on, GPU+CPU) was proven in comment 8154. The frame-583 crash during the hybrid run was a segfault in Embree on the CPU side, not in this PR's device selection; it's tracked as a separate issue.
linus merged commit 5adfcea208 into develop 2026-10-30 03:54:46 +00:00
linus deleted branch ash/hybrid-rendering-33 2026-10-30 03:54:47 +00:00
Sign in to join this conversation.
No reviewers
eva
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
s1d3sw1ped/jiggablend!34
No description provided.