Repository navigation
SuperSLM 1.8.0
SuperSLM 1.8.0
Released 2026-09-25.
SuperSLM 1.8.0 makes the GPU path report memory exhaustion as memory exhaustion. An allocation
failure during a GPU call, on a device that is not removed, returns SSLM_GPU_ALLOCATION_FAILED,
leaves the process's GPU command list closed, and leaves the context, the device and every other
handle usable. No token, save format, SslmGpuStatus ordinal or ABI struct changes. Several
statuses change for the same fault; read "Compatibility and required action" before upgrading a
host that maps GPU statuses.
The status contract a caller relies on
Stated once in include/superslm/gpu_1p0.h, beside SSLM_GPU_ALLOCATION_FAILED:
- When. One of these fails inside a GPU call, on any heap, while the device is not reported
removed at the moment the call classifies the failure:- a host allocation (
std::bad_alloc,std::length_error); - a D3D12 call returning
E_OUTOFMEMORY-- resource creation,Map,Reset, pipeline creation,
and aCloseorSignalthe engine confirmed recovered; - the first-time setup of the process's submission device, at the first call that submits GPU
work.
- a host allocation (
- What stays valid. The context and the device, with the submission command list closed; every
other sequence, model and adapter handle. An entry point with an output handle leaves it null. In
sslm_decode_step_batch_gputhe status is that sequence's ownout_statuses[i], and the other
sequences are recorded and complete as usual. - What the caller may do next. Retry the call; it succeeds once memory is available. Retrying
smaller is also valid: a smallercontext_cap, or a model mapped without
SSLM_GPU_RESIDENCY_HEAD_ON_DEVICE. A sequence the failed call was advancing must be reset
(sslm_gpu_seq_reset) or restored before its next generation call: a prompt or schema prefill
may have committed earlier sub-chunks; its prefill snapshot is empty, so
sslm_gpu_seq_read_prefill_final_hiddenreturnsSSLM_PREFILL_HIDDEN_UNAVAILABLE; a decode
step's finish may have written K/V the host mirror does not hold. - Named residuals, both reported as
SSLM_DEVICE_LOST, the conservative direction:- an allocation failure racing an unrelated device removal;
- a stranded submission: memory exhausted during command recording where the command list
cannot be confirmed Closed afterClose, a retry and a confirm step, or a fenceSignalor
wait that cannot be confirmed. That is the terminal casegpu_1p0.halready documents: every
later call on that list's context fails, and for the process's submission list, which every
decode and prefill uses, every later submitting call in the process.
SSLM_DEVICE_LOSTnow means one of: the device is reported removed; a GPU operation failed
for a reason other than memory (a missing shader, a D3D12 call failing with anotherHRESULT); a
stranded submission; the submission device's first-time setup failed for a reason other than
memory; or, as before, a saturated context cap in a prefill. It never means that memory ran out
on a live device with the submission clean.- A failed first-time setup of the process's submission device returns one status per cause,
the same from every entry point:SSLM_DEVICE_LOST, on every call for the life of the process,
when setup failed for a reason other than memory (no adapter, device creation refused, a
non-memory D3D12 failure);SSLM_GPU_ALLOCATION_FAILEDwhen it ran out of memory, and the next
call sets up again.
What changed
1.7.1 got the status wrong in three ways when memory ran out during a GPU call (TE-419, TE-421,
TE-423):
- At many sites -- every D3D12 upload and readback heap allocation during an encode, and the host
allocations of a submission's finish -- it reported the GPU as lost, although the engine had
recovered. - At every host allocation inside a command-recording window it reported the allocation failure
correctly but left the process's shared command list recording, so the next GPU call in the
process, on whichever handle ran next, failed and reported the GPU as lost. - If memory ran out while the process set up its GPU submission device, the failure was cached for
the life of the process, with a different permanent status depending on which call touched the
device first (SSLM_DEVICE_LOST,SSLM_SEQUENCE_REJECTEDorSSLM_SEQUENCE_KV_BUFFER_MISMATCH).
The fix, in src/gpu/:
- Classified at the throw.
SSLM_GPU_HRthrowsharness::GpuAllocationErrorfor
E_OUTOFMEMORYfrom any D3D12 call, and a plainstd::runtime_errorfor every other failure. - One classifier at every site that turns an exception into a status. Rules, in order: a
stranded submission isSSLM_DEVICE_LOST; a removed device isSSLM_DEVICE_LOST; an
allocation failure isSSLM_GPU_ALLOCATION_FAILED; anything else keeps the site's
non-allocation status. - The status is no longer discarded. The prompt and schema prefill twins, per-token decode,
sslm_gpu_ready, the decode-step bridge and batch decode return the classified status. - Every command-recording window closes its list on every exception type, including a
catch-all that closes the list and rethrows, and each submission tail contains every exception
type, waiting its submitted work out before the buffers that work uses are released. Every
Closeon the 1.0 path goes through
CloseListConfirmed:Close, a retry, then a confirm (ResetthenClose), so aClosethat
fails withE_OUTOFMEMORYbut did close the list is recoverable, and one that did not is
reported as the stranded terminal case. - Every other
tryon the GPU path contains every exception type too. A decode's finish did
not: a non-standard exception type from one of its host allocations left the sequence
Submittedwith its in-flight token freed, so reset, release and model unmap refused it as busy
and the nextsslm_gpu_readyon it read freed memory (also true of 1.7.1). Sequence restore, the
batched prefill's chunk submission and every handle-creating site now end in the same clause.
tools/ci/check_gpu_catch_totality.pyfails CI on an outermosttryundersrc/gpu/whose
handlers do not end incatch (...). - The internal forward status splits.
SslmForwardStatus::GpuAllocationFailednow means only
an allocation failure on a live device with the submission clean. A new, appended
SslmForwardStatus::GpuOperationFailedcarries every non-allocation GPU failure on a live device,
so a missing.csoduring recording, or finishing a call with no in-flight token, is never
reported as out-of-memory. harness::GetDevice()never throws, and a first-time setup that ran out of memory is retried
by the next submission, at most one attempt per submission (a batch submits each sequence in
turn, so a later sequence in the same batch may set the device up again).
No shader, dispatch, barrier, recording order, readback or host arithmetic on data changed: every
changed statement in src/gpu/ is inside a catch clause or a helper only catch clauses call, at a
throw site, in a status mapping or
status-carrying signature, in the GetDevice() holder and Device::Init()'s setup-failure record,
in the close and fence helpers, or the one flag set after the command list's Reset.
Compatibility and required action
Statuses change for the same fault.
SSLM_DEVICE_LOSTbecomesSSLM_GPU_ALLOCATION_FAILEDfor memory exhaustion on a live device,
host or GPU, fromsslm_gpu_context_create,sslm_gpu_model_map(with or without
SSLM_GPU_RESIDENCY_HEAD_ON_DEVICE),sslm_gpu_adapter_map,sslm_gpu_seq_create,
sslm_gpu_seq_restore, both prefill twins,sslm_decode_step_gpu,sslm_gpu_ready's
out_status,sslm_decode_step_batch_gpu'sout_statuses, the decode-step bridge and
SslmGpuSeqFinishTokenForG5Bridge. A host that treatedSSLM_DEVICE_LOSTas the only GPU
memory signal must handleSSLM_GPU_ALLOCATION_FAILEDon these entry points as a recoverable,
per-call failure.- A batch no longer marks the rest of its sequences
SSLM_DEVICE_LOSTwhen one sequence runs out
of memory; only a device loss does that. - A failed first-time device setup returns
SSLM_DEVICE_LOSTfrom every entry point, on every
call; one that ran out of memory returnsSSLM_GPU_ALLOCATION_FAILEDand is retried by the next
call. In 1.7.1 decode-first readSSLM_SEQUENCE_REJECTEDand restore-first
SSLM_SEQUENCE_KV_BUFFER_MISMATCH, permanently. SslmGpuSeqDecodeStepForG5Bridgereturns the status its underlying decode calls reported --
SSLM_GPU_ALLOCATION_FAILED,SSLM_SEQUENCE_REJECTEDfor a guard refusal,
SSLM_DISPATCH_BUDGET_TOO_SMALLfor a budget below one layer,SSLM_DEVICE_LOSTfor a device
failure -- where 1.7.1 reported every such failure asSSLM_DEVICE_LOST.
No new SslmGpuStatus value, and no ordinal moves. A host whose build fails on an unmapped
SslmGpuStatus (the SuperSLM-Unreal plugin's G5 guard) needs no new arm; it needs to map the
changed meanings above deliberately.
SslmForwardStatus gains one appended enumerator, GpuOperationFailed (installed header
include/superslm/checked_chain_funnel.h). No existing ordinal moves. It never crosses the C ABI
(MapForwardStatus maps it to SSLM_ARTIFACT_REJECTED; the CPU path never produces it), but a
consumer that switches exhaustively over SslmForwardStatus must add an arm.
superslm_gpu::RestoreGpuSequenceState (installed header include/superslm/gpu_port.h) gains
a trailing, defaulted out-parameter, out_setup_status. Source-compatible; a caller compiled
against 1.7.1's header must be recompiled.
For consumers that include the internal harness header (src/gpu/d3d12_harness.h;
SuperSLM-Unreal does):
harness::GetDevice()still never throws, and is now declarednoexcept.Device::availableis nowstd::atomic<bool>; reads of it compile unchanged.Devicegains
setup_failure(std::atomic<harness::SetupFailure>) and is no longer copyable.- An unavailable submission device may become available on a later
GetDevice()call, after a
first-time setup that ran out of memory. Device::Init()no longer throws: it records a failed setup inavailable,init_errorand
setup_failure.Device::CloseListWithRetry()is replaced byDevice::CloseListConfirmed()(reports whether the
list ended Closed) andDevice::CloseListOrThrow().SSLM_GPU_HRthrowsharness::GpuAllocationError, derived fromstd::runtime_error, for
E_OUTOFMEMORY; an existingcatch (const std::runtime_error&)still catches it.
GPU sequence saves are unchanged (SLM5), and no model-artifact reconversion is required.
Files changed
src/gpu/d3d12_harness.h--GpuAllocationError,GpuSubmissionStrandedErrorand the fault
classifier;SSLM_GPU_HR's typed failure;Device::Init()'s setup-failure record;
CloseListConfirmed,CloseListOrThrowand the fence helpers; theGetDevice()holder; the
classifier's removed-device query.src/gpu/superslm_gpu.cpp-- the recording windows' cleanup (AbandonRecording) and catch-all;
both submission tails; the finish; the chunk-open state's setup-failure status andlist_opened
flag; the non-final sub-chunk exclusion list; restore's round trip; the O11 seam's thrown type.src/gpu/gpu_1p0.cpp-- the classifier at every handle-creating site; the device logits bundle
and its run; context create; the decode mappings; the chunk submission's recorded fault and the
twins' use of it; the decode-step drive; the API boundary'sGpuAllocationErrorclause.include/superslm/gpu_1p0.h-- the status contract, every paragraph that promised
SSLM_DEVICE_LOSTfor an allocation failure, and the schema twin's list of its causes.include/superslm/checked_chain_funnel.h,src/forward/checked_chain_funnel.cpp,
src/sslm_abi.cpp--GpuOperationFailed, its name, and itsMapForwardStatusarm.include/superslm/gpu_port.h--RestoreGpuSequenceState's out-status and comments.tests/ci/check_gpu_guard_status_parity.py-- its citations of the GPU statuses' return shape.tools/ci/check_gpu_catch_totality.py,.github/workflows/tests.yml-- the gate that every
outermosttryundersrc/gpu/ends incatch (...), and its CI step.CMakeLists.txt,README.md,CHANGELOG.md,tests/install-consumer/CMakeLists.txt-- release
bookkeeping for 1.8.0.