Materializable auxiliary storage and admission
Cause and proof
The existing side-pool protocol proves occupancy safety with q <= C and
n * b <= C - q: a batch of n main invocations may emit at most b items
each. That contract requires prepare_for_producer to materialize all
abstract free capacity on demand. It cannot express an append allocator which
deliberately postpones relocation of dead holes. Treating such holes as already
available either forces a different client policy or overflows its append tail.
The new storage-only pre-admission hook preserves every item, stage count, and
capacity. Afterwards the client reports materializable slots A, constrained
by 0 <= A <= C - q. Admission additionally requires n * b <= A, using the
existing exact 64-bit product of 32-bit factors. If blocked, the client’s usual
non-empty admission stage runs. An empty pool must materialize its full capacity
to retain the existing bounded-producer progress guarantee. An assertion checks
host occupancy, capacity, and the availability bound after preparation.
Both preparation hooks enqueue storage operations on the same stream as the
producer, never semantic stages. They may not change observed populations.
Default preparation is a no-op and default availability is C - q, so existing
clients retain their previous behavior. The final prepare_for_producer hook
still guarantees admitted storage before the actual continuation resumes.
No allocator threshold, rendering state, device-kernel ID, or application policy is encoded in the scheduler. Physical queues with pre-resume annotations continue to use their logical target’s producer bound.
Smallest counterexample
Two main frames publish three times into four auxiliary append slots. Each
consumer releases two items; the client reclaims its append extent only when
empty. After two publications and one drain, q=2, extent=4, C=4: abstract
free capacity is two, but append availability is zero.
The old scheduler forces an unrequested reclaim and drains populations
[4, 4, 2]. The new contract first drains [4, 2], reclaims the empty pool,
admits the last publication, and then drains [2]. All six publications and
both final main results remain correct in the old witness. It records any
premature preparation and reclaims defensively before an invalid memory access;
it does not depend on corruption or undefined behavior to fail.
test_coro_wavefront_auxiliary_admission covers plain/annotated producers,
SoA/AoS, legacy/incremental/fused accounting, and scheduler reuse. The original
header, with the test’s future hooks non-overriding, fails 72 of 144 assertions
on HIP; the new protocol passes all 144 on HIP and fallback. This is a scheduler
protocol extension, not a compiler transformation or initialization change.
Evidence directory: /var/tmp/psycles-wavefront-admission-6YMdzL.
analysis.md, red.cpp, red-build.log, red-hip.log, green-build.log,
green-hip.log, and green-fallback.log retain the reasoning and witness.
The application’s original shadow-pool module also fails its newly added
policy regression before integration (psycles-red-hip.log), then passes HIP
and fallback after integration. Its independent oracle invokes verbatim
external Cycles host functions; the actual pool regression checks live NEE
payload and shade-owned batch relocation, delayed reclamation, film values,
and all per-stage counts. The generic SDK test has no renderer implementation.
Whole-module validation
All builds use 32 threads. full-sdk-build.log builds all 14 affected coroutine
executables from the clean candidate headers and test sources. All pass HIP
and fallback: 157 cases per backend, 13607/13606 assertions respectively.
full-build.log rebuilds the original Psycles application and tests (207
steps). The HIP selection passes 157/157, fallback 159/159, and compiler/adapter
selection 101/101. The latter excludes the already-known
blender_export_render_settings failure; it is not a full-repository green claim.
native-sdk.log and native-psycles.log run the independent witness and actual
shadow pool with LUISA_VULKAN_USE_XIR=1,
LUISA_VULKAN_REQUIRE_NATIVE_XIR_SPIRV=1, LUISA_VULKAN_DISABLE_DXC=1, and
LD_DEBUG=libs. Both pass, with 46 and 36 native SPIR-V compilations and no
DXC/DXIL library loads. These tests link the active compiler/backend libraries;
they do not claim a clean rebuild of unrelated pending Local/scope/XIR changes.
The application A/B/B at 1440x1080, 256 samples is neutral: old admission 14.3138 seconds, new admission 14.2950 and 14.3686 seconds. No device-kernel instruction reduction or end-to-end speedup is claimed for this host protocol.