Address CRAN review: \value tags, runnable examples, DESCRIPTION - #47
Merged
Conversation
The staging mechanism (pin host copies once, onload by non-blocking DMA, offload by pointer swap) is about to be shared by the FLUX-family image loaders, so drop the ltx23 prefix: staging_ltx23.R -> staging.R, and .ltx23_pin_host/.ltx23_pin_component/.ltx23_staged_onload/ .ltx23_staged_offload -> .pin_host/.pin_component/.staged_onload/ .staged_offload. Doc topic staging_ltx23 -> staging (alias kept). Pure rename across the LTX pipeline, the Gemma3 encoder, and the fp8 loader; no behavior change.
flux1/flux2/zimage phase-swap the transformer, VAE decoder, and text encoder(s) CPU<->GPU every generation, through pageable host memory. Pin them once at load (the LTX staging mechanism) so onload runs at full PCIe rate and offload is a pointer swap. Payoff: flux1 T5 encode ~7-12 s -> sub-second, flux2/zimage Qwen3 swap ~2-4 s -> ~0.4 s, plus faster transformer/decoder moves. - Shared pin gate: extract .pin_decision (host RAM >= 2x pinned set) from recommend() and add .resolve_pin (explicit pin= > option > decision). Loaders gain pin=NULL. "full" checkpoints map to the bf16 row. - .flux_build_staging pins the listed components; the resident-fp8 transformer (flux2/zimage) also pins its plain weight_fp8/weight_scale fields via .flux_fp8_collect (set_data keeps the field reference live). Generation skips .flux_fp8_to_device when staging covers the transformer, else the field reassignment would orphan the staged pairs. - flux1 now GPU-encodes T5 (bf16, pinned) on 14 GB+ cards where its ~9.8 GB encode phase fits; nf4 tiers keep the CPU-fp32 encode. text_device default "cpu" -> NULL (profile-resolved); gc footprint sized to the T5 phase. An explicit text_device="cpu" still encodes in place (also fixes a latent flux2/zimage OOM on that path). - VAE decoder cast to compute dtype once at load so staged onload is device-only. onload/offload closures route by component name. - .pinned_set_gb flux1 row 43/31/26 -> 34/22/17 (T5 host copy now bf16). - Tests: test_flux_staging (gate logic, .flux_fp8_collect, pin round trip) and a zimage end-to-end smoke test.
The 0.2.0 submission was returned for four items, none of which
R CMD check implements (there is no missing-\value check anywhere in
tools, no \dontrun policy check, and no DESCRIPTION quoting or
whitespace check), so every local check had been green.
* \value on all 50 exported .Rd files that had a \usage block and no
return documentation, chiefly the nn_module generators for the FLUX,
FLUX.2, Z-Image, LTX-2.3 and Gemma3 ports. Doc-only topic pages have
no \usage and are correctly exempt.
* Examples: 14 of the 23 \dontrun{} blocks now run during check, and
were rewritten to be self-contained rather than referencing objects
that were never defined. The 9 that remain need model weights on
disk; cran-comments.md itemises them.
* DESCRIPTION: 'Python', 'Stable Diffusion' and 'Hugging Face' (with
its URL) single-quoted; trailing whitespace removed. Every
continuation line had ended in a space since the first commit, and
DCF folding turned each one into a double space.
Making the examples run surfaced two dead defaults. ddim_scheduler_create()
never passed beta_schedule through match.arg(), so switch() errored on the
length-3 default, and its device default was a length-2 vector that
torch_tensor() rejects; ddim_scheduler_step() had the same missing
match.arg() on prediction_type. Every internal caller passes these
explicitly, which is why the documented defaults were never exercised.
device now defaults to torch_device("cpu").
Also refreshes the safetensors messaging: mlverse/safetensors#11, #13
and #14 merged upstream on 2026-07-31 without a version bump, so the
advice now points at upstream rather than the fork, and the comments
record why the gates are runtime probes (the version number cannot
distinguish the two 0.2.1 builds). The install.packages()/
install_github() literals in hint text are reworded, since CRAN's
scanner flags the token regardless of context.
R CMD check --as-cran runs the examples a second time with \donttest{}
enabled, feeding diffuseR-Ex.R to R on stdin. The mp4 branch of
save_video() hands off to an ffmpeg process that inherits that stdin and
consumes a byte of the script, so every later example parsed one
character short: the run died on
base::assign(".ptime", proc.time(), pos = "CheckExEv")
Error in as.environment(pos) :
no item called "CheckExEv" on the search list
with the generated file plainly containing "CheckExEnv" (81 occurrences,
none of them mangled) and R evaluating a string one byte shorter. It
reproduced at the same offset with the GPU hidden, so it was never
CUDA-related.
The frames backend already exercises save_video() live and needs no
external encoder, so the encoder call is now a commented example with
the reason recorded next to it.
TroyHernandez
added a commit
that referenced
this pull request
Aug 3, 2026
CI has been red on every run since PR #47, on both ubuntu-latest and macos-latest: FAILED[xcpt]: test_resident.R<117> call| expect_error(diffuseR:::.resident_check_fits(huge), pattern = "needs") diff| No error The function is right and the test was wrong. .resident_check_fits() refuses a bulk activation only when it can prove the set does not fit; with no GPU the measurement is 0, which means "cannot tell", so it declines to block. The test asserted the refusal unconditionally, so it passed on the GPU box and failed everywhere else. free_gb is now an argument, NULL measuring as before. The test states a budget rather than depending on the machine having a card, and also covers the cases it never did: a set that fits is allowed, and an undetectable 0 or NA does not block. Same class as the win-builder lantern failure and the Windows st_caps failure: an assertion that read the environment instead of stating it. Verified against all three environments this package has to survive -- 58 assertions with a GPU, 43 with CUDA_VISIBLE_DEVICES="" (CI), 33 with an empty TORCH_HOME (win-builder). Full suite CI-style: 1070 pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The 0.2.0 submission came back on four items, none of which
R CMD checkimplements: there is no missing-
\valuecheck anywhere intools, no\dontrun-vs-\donttestpolicy check, and nothing that inspectsDESCRIPTION quoting or whitespace. Every local check had been green, and
always would have been.
\valueon all 50 exported.Rdfiles that had a\usageblock andno return documentation, chiefly the
nn_modulegenerators for the FLUX,FLUX.2, Z-Image, LTX-2.3 and Gemma3 ports. Doc-only topic pages have no
\usageand are correctly exempt.\dontrun{}blocks now run during check, andwere rewritten to be self-contained rather than referencing objects that
were never defined. The 9 that remain need model weights on disk and are
itemised in
cran-comments.md.'Python','Stable Diffusion'and'Hugging Face'(with its URL) single-quoted; trailing whitespace removed. Every
continuation line had ended in a space since the first commit, and DCF
folding turned each one into a double space.
Two bugs surfaced from making the examples actually run:
ddim_scheduler_create()was uncallable at its documented defaults —beta_schedulenever went throughmatch.arg(), soswitch()errored onthe length-3 default, and
devicedefaulted to a length-2 vector thattorch_tensor()rejects.ddim_scheduler_step()had the same missingmatch.arg()onprediction_type. Every internal caller passes theseexplicitly, which is why the documented defaults were never exercised.
save_video()'s mp4 example ate the check script.--as-cranruns examplesa second time feeding
diffuseR-Ex.Rto R on stdin; the encoder inheritsthat stdin and consumes a byte, so every later example parsed one character
short and the run died on
pos = "CheckExEv"—CheckExEnvwith one bytegone. It reproduced at the same offset with the GPU hidden, so it was never
CUDA-related.
Also refreshes the safetensors messaging: mlverse/safetensors#11, #13 and #14
merged upstream on 2026-07-31 without a version bump, so CRAN's 0.2.1 and
upstream's share a version string and no version expression can tell them
apart. The advice now points upstream, and the comments record why the gates
are runtime probes.
R CMD check: 0 errors, 0 warnings, 2 NOTEs (New submission + the localtorch/lantern artifact already documented in
cran-comments.md).