Inspect diagnostics and budget sparse memory

The sparse engine can estimate its memory needs before a solve, enforce a per-model memory budget, and retain additional solve diagnostics when asked. The examples below use the small generated fixture shared with the other vignettes.

Estimate before solving

estimateMemory() reports an estimate for the selected engine and whether post-simulation work is included. Use it as planning information for the model and runtime you are about to execute:

memoryEstimate = model$estimateMemory(engine = "sparse", postsim = FALSE)
print(memoryEstimate)
#> $engine
#> [1] "sparse"
#> 
#> $har_input_bytes
#> [1] 9304
#> 
#> $model_variable_bytes
#> [1] 48
#> 
#> $equation_positions
#> [1] 3
#> 
#> $variable_positions
#> [1] 6
#> 
#> $endogenous_positions
#> [1] 3
#> 
#> $estimated_sparse_triplets
#> [1] 6
#> 
#> $estimated_triplet_bytes
#> [1] 96
#> 
#> $estimated_sparse_matrix_bytes
#> [1] 120
#> 
#> $estimated_factor_workspace_bytes
#> [1] 192
#> 
#> $estimated_rhs_bytes
#> [1] 24
#> 
#> $estimated_metadata_bytes
#> [1] 16360
#> 
#> $estimated_schur_bytes
#> $estimated_schur_bytes$dense_matrix_bytes
#> [1] 0
#> 
#> $estimated_schur_bytes$dense_factor_bytes
#> [1] 0
#> 
#> $estimated_schur_bytes$dense_workspace_bytes
#> [1] 0
#> 
#> $estimated_schur_bytes$coupling_bytes
#> [1] 0
#> 
#> $estimated_schur_bytes$worker_workspace_bytes
#> [1] 0
#> 
#> $estimated_schur_bytes$krylov_bytes
#> [1] 0
#> 
#> $estimated_schur_bytes$sparse_factor_scratch_bytes
#> [1] 0
#> 
#> 
#> $estimated_peak_bytes
#> [1] 26144
#> 
#> $post_simulation_retained
#> [1] FALSE
#> 
#> $dense_fallback
#> [1] FALSE
#> 
#> $budget_bytes
#> numeric(0)

The public estimate describes generic sparse storage. During solveModel(), the selected structured backend additionally accounts for its partition: dense regional/global matrices and factors, simultaneously live copies, coupling transfers, local factor fill, Arnoldi vectors and worker scratch. The budget guard uses this fuller estimate before assembly. Counts from the original partition can overestimate storage later removed by elimination. Factor fill and allocator overhead remain estimates; this is not a hard cap on process RSS. Detailed solve diagnostics retain the component estimates.

Set a memory budget

setMemoryBudget(bytes) stores an instance-level sparse budget. A solve fails during preflight if its estimate exceeds the available budget. The example sets a one-gibibyte budget, ample for this tiny fixture. The memory_budget argument to solveModel() can instead set or override the budget for one solve.

model$setMemoryBudget(1024^3)

Request compact output and detailed diagnostics

Compact output avoids materializing the full compatibility output structure. By default, diagnostics = FALSE stores the compact stable outcome envelope. Set diagnostics = TRUE when you also need residual history, timings, allocation and capability evidence, detailed cleanup, and memory estimates.

model$solveModel(
  iter = 1,
  steps = 1,
  engine = "sparse",
  backend = "Matrix",
  postsim = FALSE,
  output = "compact",
  variables = "q",
  diagnostics = TRUE
)
model$compactOutput
#> $q
#> reg
#> north south  east 
#>     0     6     0 
#> 
#> $solution
#> [1] 0 6 0

The top-level diagnostics fields include the requested runtime and backend, the implementation selected, and the solve status:

model$lastDiagnostics[c(
  "schema_version", "engine", "requested_backend", "implementation", "status"
)]
#> $schema_version
#> [1] 1
#> 
#> $engine
#> [1] "sparse"
#> 
#> $requested_backend
#> [1] "Matrix"
#> 
#> $implementation
#> [1] "r"
#> 
#> $status
#> [1] "succeeded"

For the stable field list and failure statuses, see the GEModelR package help Diagnostics add evidence to the record; they do not change which backend was requested or permit fallback.

Every accepted sparse solution passes the full-system check \(\lVert A x-b\rVert_2 / \max(1,\lVert b\rVert_2)\) at the documented residual tolerance. Scaled arithmetic forms this ratio without overflowing the denominator. Invalid products or non-finite residual entries fail before state is committed. An absolute L2 diagnostic can be infinite when its exact value exceeds the double range; acceptance still requires a finite scaled relative residual. Small RHS vectors retain the existing absolute-tolerance semantics.

The C++ backend carries only structural metadata between solves. Its keys include index/closure layout, sparse pattern, grouping and batching settings. Numeric factors and regional transfers belong to one solve and are rebuilt after coefficient changes. Prepared sparse factors own validated snapshots and reusable scratch; cleanup releases native handles before results are committed or a failure is returned. Matrix references needed for acceptance are released before simulation updates.

With detailed diagnostics, phase_allocations reports nonnegative changes in sampled R heap usage. Samples use full garbage collections and R’s reported MiB, including the platform-specific size of node cells. peak_gc_bytes is the largest of those phase samples across the solve; the same samples are reused for progress and final diagnostics. These rounded heap estimates do not include all native allocations and are distinct from process peak RSS.