gcubed.linearisation.solution_memory

Conservative memory feasibility planning for complete model solutions.

The estimator uses model vector dimensions rather than model-name lookup tables. It combines those estimates with current process, system, cgroup, and optional process/address-space limits before expensive linearisation work begins.

ALLOW_UNVERIFIED_MEMORY_ENV_VAR: str = 'GCUBED_ALLOW_UNVERIFIED_SOLUTION_MEMORY'

Deprecated compatibility setting retained in profiler metadata.

MINIMUM_SAFETY_MARGIN_PERCENT: int = 5

Minimum uncertainty allowance applied to predicted process peak RSS.

SAFETY_MARGIN_ROUNDING_PERCENT: int = 5

Increment used when rounding a calibrated safety margin upward.

SPARSE_HYBRID_ENV_VAR: str = 'GCUBED_SSF_SPARSE_HYBRID'

Environment setting controlling sparse partial-matrix staging.

SPARSE_STAGING_MIN_DENSE_BYTES: int = 67108864

Smallest dense partial matrix considered for sparse staging.

SPARSE_STAGING_MAX_DENSITY: float = 0.01

Largest structural density accepted for sparse staging.

type ProfileValue = bool | float | int | str | None
class InsufficientModelSolutionMemoryError(builtins.MemoryError):

Legacy feasibility exception retained for API compatibility.

Model-solution estimates are now advisory and the standard solution path no longer raises this exception. Actual numerical allocations may still raise MemoryError independently.

InsufficientModelSolutionMemoryError(decision: ModelMemoryDecision)

Initialize an informative memory-feasibility exception.

Args: decision: Failed feasibility decision containing model, estimate, capacity, and shortfall details.

Returns: None.

Raises: ValueError: Raised when decision is feasible.

@dataclass(frozen=True)
class ModelMemoryDimensions:

Vector lengths needed to estimate model-solution matrix payloads.

Attributes: state_variables: Length of x1l/x1r/yxr. jump_variables: Length of j1l/j1r/yjr. expected_endogenous_variables: Length of zel/zer/exz. endogenous_variables: Length of z1l/z1r. exogenous_variables: Length of exo.

ModelMemoryDimensions( state_variables: int, jump_variables: int, expected_endogenous_variables: int, endogenous_variables: int, exogenous_variables: int)
state_variables: int
jump_variables: int
expected_endogenous_variables: int
endogenous_variables: int
exogenous_variables: int
@classmethod
def from_sym_data( cls, sym_data: gcubed.sym_data.SymData) -> ModelMemoryDimensions:

Build dimensions from loaded SYM metadata.

Args: sym_data: Model variable metadata available before linearisation.

Returns: Integer vector lengths used by the memory estimator.

Raises: Exception: Propagated when a required vector length is unavailable. TypeError: Propagated when a vector length cannot be converted to int.

total_lhs_variables: int

Return the sum of all four SSF LHS vector lengths.

Args: None.

Returns: Combined state, jump, expected-endogenous, and endogenous length.

Raises: No deliberate exceptions are raised.

def vector_length(self, vector_name: str) -> int:

Return the dimension represented by an SSF vector name.

Args: vector_name: One of the supported LHS or RHS vector names.

Returns: Corresponding vector length.

Raises: ValueError: Raised for an unsupported vector name.

def profile_fields(self) -> dict[str, int]:

Return JSON-compatible vector lengths.

Args: None.

Returns: Mapping from descriptive dimension names to integer lengths.

Raises: No deliberate exceptions are raised.

@dataclass(frozen=True)
class SolutionMemoryEstimate:

Dimension-based component and peak estimates for a complete solve.

Attributes: dimensions: Vector lengths used by every byte formula. baseline_rss_bytes: RSS after loading the model and before linearisation. dense_partial_bytes: Conservative dense partial-matrix payload. staged_partial_bytes: Estimated retained partial payload after the selected sparse-staging policy is applied. sparse_staged_dense_bytes: Dense payload replaced by sparse staging. sparse_staged_matrix_count: Number of partial blocks expected to stage. sparse_staging_enabled: Whether sparse staging is selected. final_ssf_bytes: Payload of the 16 retained state-space matrices. dominant_lu_factor_bytes: Largest dense eliminated-vector LU factor. dominant_solved_output_bytes: Largest retained solved SSF block. stable_manifold_bytes: Conservative simultaneous stable-manifold arrays. maximum_block_workspace_bytes: Largest reachable block workspace under actual dimensions and the current configured upper bound. linear_model_additional_bytes: Estimated linear-model phase payload. state_space_form_additional_bytes: Estimated SSF phase payload. stable_manifold_additional_bytes: Estimated stable-manifold payload. limiting_phase: Phase with the largest predicted additional payload. predicted_additional_bytes: Largest phase payload before uncertainty. predicted_peak_bytes: Baseline RSS plus predicted additional payload. safety_margin_percent: Uncertainty allowance applied to predicted peak. conservative_peak_bytes: Predicted peak after the safety margin.

SolutionMemoryEstimate( dimensions: ModelMemoryDimensions, baseline_rss_bytes: int, dense_partial_bytes: int, staged_partial_bytes: int, sparse_staged_dense_bytes: int, sparse_staged_matrix_count: int, sparse_staging_enabled: bool, final_ssf_bytes: int, dominant_lu_factor_bytes: int, dominant_solved_output_bytes: int, stable_manifold_bytes: int, maximum_block_workspace_bytes: int, linear_model_additional_bytes: int, state_space_form_additional_bytes: int, stable_manifold_additional_bytes: int, limiting_phase: str, predicted_additional_bytes: int, predicted_peak_bytes: int, safety_margin_percent: int, conservative_peak_bytes: int)
dimensions: ModelMemoryDimensions
baseline_rss_bytes: int
dense_partial_bytes: int
staged_partial_bytes: int
sparse_staged_dense_bytes: int
sparse_staged_matrix_count: int
sparse_staging_enabled: bool
final_ssf_bytes: int
dominant_lu_factor_bytes: int
dominant_solved_output_bytes: int
stable_manifold_bytes: int
maximum_block_workspace_bytes: int
linear_model_additional_bytes: int
state_space_form_additional_bytes: int
stable_manifold_additional_bytes: int
limiting_phase: str
predicted_additional_bytes: int
predicted_peak_bytes: int
safety_margin_percent: int
conservative_peak_bytes: int
def nonworkspace_bytes_for_phase(self, phase: str) -> int:

Return conservative matrix demand excluding block workspace.

Args: phase: linear_model, state_space_form, or stable_manifold.

Returns: Estimated phase payload excluding state-space block workspace.

Raises: ValueError: Raised for an unsupported phase.

def conservative_nonworkspace_bytes_for_phase(self, phase: str) -> int:

Return phase non-workspace demand with the calibrated allowance.

Args: phase: linear_model, state_space_form, or stable_manifold.

Returns: Phase-specific non-workspace bytes padded by the estimate's safety margin, rounded upward to a whole byte.

Raises: ValueError: Raised for an unsupported phase.

def remaining_conservative_nonworkspace_bytes(self, phase: str, *, current_rss_bytes: int | None) -> int:

Return phase demand not already represented by current RSS.

Args: phase: linear_model, state_space_form, or stable_manifold. current_rss_bytes: Current process RSS, or None when it cannot be measured.

Returns: Padded phase payload minus process growth already visible above the estimator baseline. The result is never negative.

Raises: ValueError: Raised for an unsupported phase or negative RSS.

def profile_fields(self) -> dict[str, ProfileValue]:

Return reproducible estimator inputs and outputs.

Args: None.

Returns: JSON-compatible dimensions, component bytes, phase estimates, and conservative peak values.

Raises: No deliberate exceptions are raised.

@dataclass(frozen=True)
class MemoryCapacity:

Additional memory capacities visible to the current process.

Attributes: memory: Current RSS and system/cgroup memory snapshot. process_limit_bytes: Optional configured process RSS target. process_limit_available_bytes: Target minus current RSS. address_space_limit_bytes: Optional finite RLIMIT_AS soft limit. process_virtual_memory_bytes: Current process virtual size. address_space_available_bytes: Address-space limit minus virtual size. effective_available_bytes: Smallest reliable additional capacity. effective_available_source: Source defining effective capacity.

MemoryCapacity( memory: gcubed.linearisation.workspace_planning.MemorySnapshot, process_limit_bytes: int | None, process_limit_available_bytes: int | None, address_space_limit_bytes: int | None, process_virtual_memory_bytes: int | None, address_space_available_bytes: int | None, effective_available_bytes: int | None, effective_available_source: str | None)
process_limit_bytes: int | None
process_limit_available_bytes: int | None
address_space_limit_bytes: int | None
process_virtual_memory_bytes: int | None
address_space_available_bytes: int | None
effective_available_bytes: int | None
effective_available_source: str | None
def profile_fields(self) -> dict[str, ProfileValue]:

Return JSON-compatible capacity evidence.

Args: None.

Returns: Current process and every applicable capacity source.

Raises: No deliberate exceptions are raised.

@dataclass(frozen=True)
class ModelMemoryDecision:

One complete model-solution feasibility decision.

Attributes: model_version: Model version identifier. model_build: Model build identifier. stage: Solution point at which capacity was evaluated. estimate: Dimension-based conservative peak estimate. capacity: Current capacity values used by the decision. expected_additional_bytes: Peak still required above current RSS. available_additional_bytes: Smallest reliable additional capacity. shortfall_bytes: Requirement exceeding available capacity. diagnostic_override: Deprecated compatibility flag retained in profiler output; memory estimates are advisory regardless. feasible: Whether the conservative estimate fits the measured capacity. The standard solve path proceeds either way. reason: Stable decision reason for logs and profiler output.

ModelMemoryDecision( model_version: str, model_build: str, stage: str, estimate: SolutionMemoryEstimate, capacity: MemoryCapacity, expected_additional_bytes: int, available_additional_bytes: int | None, shortfall_bytes: int | None, diagnostic_override: bool, feasible: bool, reason: str)
model_version: str
model_build: str
stage: str
capacity: MemoryCapacity
expected_additional_bytes: int
available_additional_bytes: int | None
shortfall_bytes: int | None
diagnostic_override: bool
feasible: bool
reason: str
def profile_fields(self) -> dict[str, ProfileValue]:

Return complete JSON-compatible decision evidence.

Args: None.

Returns: Model identity, estimator fields, capacity fields, and result.

Raises: No deliberate exceptions are raised.

class ModelSolutionMemoryGuard:

Maintain and re-evaluate one model's conservative memory estimate.

ModelSolutionMemoryGuard( *, model_version: str, model_build: str, dimensions: ModelMemoryDimensions, workspace_configuration: gcubed.linearisation.workspace_planning.WorkspaceConfiguration, baseline_memory: gcubed.linearisation.workspace_planning.MemorySnapshot | None = None, blas_thread_count: int | None = None, safety_margin_percent: int = 5, diagnostic_override: bool | None = None, structural_partial_counts: Mapping[tuple[str, str], int] | None = None)

Create a guard from model dimensions and current memory policy.

Args: model_version: Model version identifier. model_build: Model build identifier. dimensions: Pre-linearisation vector lengths. workspace_configuration: Current SSF workspace/process limits. baseline_memory: Optional injected baseline snapshot. blas_thread_count: Optional injected active BLAS thread count. safety_margin_percent: Conservative peak uncertainty allowance. diagnostic_override: Optional deprecated compatibility flag. structural_partial_counts: Optional equation-map counts available before linearisation begins.

Returns: None.

Raises: ValueError: Raised for empty model identity, an invalid thread count, or an invalid safety margin.

model_version: str
model_build: str
dimensions: ModelMemoryDimensions
blas_signature: str
blas_thread_count: int
safety_margin_percent: int
diagnostic_override: bool
sparse_staging_enabled: bool

Return the current initial or structurally refined estimate.

Args: None.

Returns: Current immutable estimate.

Raises: No deliberate exceptions are raised.

def refine_partial_structure( self, structural_partial_counts: Mapping[tuple[str, str], int]) -> SolutionMemoryEstimate:

Refine partial storage from discovered structural nonzero counts.

Args: structural_partial_counts: LHS/RHS matrix keys and conservative counts of structurally nonzero coefficients.

Returns: Updated complete solution estimate.

Raises: ValueError: Raised for malformed or unsupported matrix keys.

def remaining_conservative_nonworkspace_bytes( self, phase: str, *, memory: gcubed.linearisation.workspace_planning.MemorySnapshot) -> int:

Return phase demand still needing capacity above current RSS.

Args: phase: linear_model, state_space_form, or stable_manifold. memory: Current memory snapshot used by the matching block plan.

Returns: Conservative phase payload not already represented by current RSS.

Raises: ValueError: Raised for an unsupported phase or invalid RSS.

def evaluate( self, stage: str, *, memory: gcubed.linearisation.workspace_planning.MemorySnapshot | None = None, address_space_limit_bytes: int | None = None, process_virtual_memory_bytes: int | None = None, inspect_address_space: bool = True) -> ModelMemoryDecision:

Evaluate current capacity against the conservative estimated peak.

Args: stage: Stable solution-stage label included in diagnostics. memory: Optional injected current memory snapshot. address_space_limit_bytes: Optional injected finite address limit. process_virtual_memory_bytes: Optional injected process virtual size. inspect_address_space: Whether absent address values should be read.

Returns: Feasibility decision with complete reproducibility fields.

Raises: ValueError: Raised when stage is empty or injected values are invalid.

def require( self, stage: str, *, memory: gcubed.linearisation.workspace_planning.MemorySnapshot | None = None) -> ModelMemoryDecision:

Return the checked decision and warn about an estimated shortfall.

Args: stage: Stable solution-stage label included in diagnostics. memory: Optional injected current memory snapshot.

Returns: Current feasibility decision. An infeasible estimate is advisory and does not prevent the caller from attempting the solve.

Raises: No deliberate exceptions are raised after the decision is built.

def calibrated_safety_margin_percent(predicted_and_observed_peaks: Sequence[tuple[int, int]]) -> int:

Calculate the reviewed safety-margin rule from calibration profiles.

Args: predicted_and_observed_peaks: (predicted, observed) byte pairs from build-197 profiles before applying a safety allowance.

Returns: At least 5%, with the worst observed underprediction rounded upward in five-percentage-point increments.

Raises: ValueError: Raised for nonpositive predictions or negative observations.

def estimate_model_solution_memory( *, dimensions: ModelMemoryDimensions, baseline_rss_bytes: int, workspace_cap_bytes: int, blas_thread_count: int, blas_workspace_bytes_per_thread: int = 2097152, structural_partial_counts: Mapping[tuple[str, str], int] | None = None, sparse_staging_enabled: bool | None = None, safety_margin_percent: int = 5) -> SolutionMemoryEstimate:

Estimate unpadded and conservative complete-solution peak RSS.

Args: dimensions: Actual model vector lengths. baseline_rss_bytes: RSS after model loading and before linearisation. workspace_cap_bytes: Current upper bound on one SSF block workspace. blas_thread_count: Active BLAS thread count used for fixed workspace. blas_workspace_bytes_per_thread: Fixed per-thread BLAS allowance from a matching host profile or the conservative fallback. structural_partial_counts: Optional refined nonzero counts by partial matrix key. The initial estimate assumes every pair may be dense. sparse_staging_enabled: Optional selected sparse-staging policy. The environment setting is used when omitted. safety_margin_percent: Uncertainty allowance applied to predicted peak.

Returns: Component, phase, unpadded peak, and conservative peak estimates.

Raises: ValueError: Raised for negative byte values, a nonpositive thread count, a margin below the reviewed minimum, or unsupported structural keys.

def memory_capacity( memory: gcubed.linearisation.workspace_planning.MemorySnapshot, *, process_limit_bytes: int | None = None, address_space_limit_bytes: int | None = None, process_virtual_memory_bytes: int | None = None) -> MemoryCapacity:

Combine all reliable additional-capacity sources.

Args: memory: Current process RSS and system/cgroup availability. process_limit_bytes: Optional configured process RSS target. address_space_limit_bytes: Optional finite process address-space limit. process_virtual_memory_bytes: Current process virtual size.

Returns: Capacity values and the smallest reliable additional-memory source.

Raises: ValueError: Raised for negative injected limits or virtual size.

def decide_model_solution_memory( *, model_version: str, model_build: str, stage: str, estimate: SolutionMemoryEstimate, capacity: MemoryCapacity, diagnostic_override: bool = False) -> ModelMemoryDecision:

Compare a conservative absolute peak with current additional capacity.

Args: model_version: Model version identifier. model_build: Model build identifier. stage: Solution point at which the check occurs. estimate: Conservative absolute peak estimate. capacity: Current process and machine capacity values. diagnostic_override: Deprecated compatibility flag retained in the decision and profiler output. It does not suppress a warning.

Returns: Feasible, insufficient, or explicitly unverified decision.

Raises: ValueError: Raised when identity/stage fields are empty.

def diagnostic_override_enabled() -> bool:

Return the deprecated unverified-capacity compatibility flag.

Args: None.

Returns: Parsed GCUBED_ALLOW_UNVERIFIED_SOLUTION_MEMORY boolean. The flag is retained for configuration compatibility and profiler evidence; it no longer changes whether an estimate is advisory.

Raises: ValueError: Raised for a value other than a recognized true/false form.

def solution_sparse_hybrid_enabled() -> bool:

Return whether the solution uses sparse partial-matrix staging.

Args: None.

Returns: False for 0, false, no, or off; otherwise True.

Raises: No deliberate exceptions are raised.

def active_blas_thread_count(thread_pools: Sequence[Mapping[str, Any]] | None = None) -> int:

Return the largest active BLAS thread-pool size.

Args: thread_pools: Optional previously sampled thread-pool metadata. Current metadata is read when omitted.

Returns: Positive BLAS thread count, defaulting to one when no pool is reported.

Raises: No deliberate exceptions are raised.

def model_solution_memory_warning( decision: ModelMemoryDecision) -> str:

Return the concise warning for an estimated memory shortfall.

Args: decision: Infeasible or unverified decision.

Returns: Required memory, available memory, and termination-risk text.

Raises: No deliberate exceptions are raised.