C++ Module: stateRegistry
StateRegistry implements the state storage owned by C++ Module: dynParamManager.
It owns named handles, update policies, layouts, value buffers, and noise connections.
Registration creates temporary matrices. First finalization computes offsets, allocates contiguous buffers, and redirects handles into those buffers. The layout then remains fixed. Later registration retrieves existing states by name and checks that their declarations match; values are updated in place without staging or rollback.
Construction and registration are controlled by the manager. C++ callers inspect
and resolve storage through DynParamManager::getStateRegistry().
StateLayout offsets address the registry’s own arrays of doubles. They differ
from the integrator-global offsets in FlatStateBinding. StateBufferSegment
identifies its registry, buffer kind, and scalar range. The registry must remain alive
while a segment or a pointer resolved from it is in use.
getSegment(kind, firstSlot, elementCount) addresses state, derivative, and
diffusion storage through the same interface. segmentView(segment) returns a
borrowed column matrix whose writes update the live buffer. Calling it on a const
registry returns a read-only view. Typed segment constructors and pointer accessors
remain available when the buffer kind is known.
A segment starts at a registration slot and ends at a complete record boundary.
For diffusion, one record contains all local noise tangents for that state.
States without noise contribute no diffusion scalars. For example, if state A has
two scalar tangents and state B has one, their diffusion segment contains
[A/source0, A/source1, B/source0]. Shared sources still occupy separate local
contributions. Stochastic workspaces gather them into global source order during
capture.
Acquire segment views after finalization. Their addresses remain stable across
later resets, and the registry must outlive them. Module callbacks can continue
to use StateData::stateView(), derivativeView(), and diffusionView(index)
for shaped access to individual records.
See Dynamics state and integrator architecture for the complete storage and integration call path.
Native state-registration lifecycle, immutable layouts, and buffer access.
Enums
-
enum class StateBufferKind
Select the buffer addressed by a StateBufferSegment.
Values:
-
enumerator State
State values.
-
enumerator Derivative
Time derivatives.
-
enumerator Diffusion
All local noise tangents, grouped by state and then by source.
-
enumerator State
-
struct StateLayout
- #include <stateRegistry.h>
Dimensions and scalar offsets of one state in the committed buffers.
Offsets count doubles, not bytes. Matrices use Eigen’s column-major ordering. State, derivative, and diffusion shapes may differ for a special update policy. Layouts are immutable after the first successful registration.
Public Members
-
uint32_t stateRows = 0
Rows in the state matrix.
-
uint32_t stateCols = 0
Columns in the state matrix.
-
size_t stateOffset = 0
First state scalar in StateBuffers::states.
-
size_t stateCount = 0
Number of state scalars, equal to rows times columns.
-
uint32_t derivRows = 0
Rows in the time-derivative matrix.
-
uint32_t derivCols = 0
Columns in the time-derivative matrix.
-
size_t derivOffset = 0
First derivative scalar in StateBuffers::derivatives.
-
size_t derivCount = 0
Number of derivative scalars.
-
uint32_t diffusionRows = 0
Rows in each local noise tangent.
-
uint32_t diffusionCols = 0
Columns in each local noise tangent.
-
size_t diffusionOffset = 0
First tangent scalar in StateBuffers::diffusions.
-
size_t diffusionCountPerSource = 0
Scalars per tangent; local sources occupy consecutive blocks.
-
size_t noiseCount = 0
Number of local noise sources declared for this state.
-
ErrorControlMode errorControl = ErrorControlMode::WholeState
Adaptive error scaling for this record.
-
StateUpdateKind updateKind = StateUpdateKind::Euclidean
Ordinary addition or a special update rule.
-
const StateUpdatePolicy *specialUpdate = nullptr
Borrowed immutable policy, or nullptr for Euclidean states.
-
uint32_t stateRows = 0
-
struct StateBuffers
- #include <stateRegistry.h>
Contiguous state, derivative, and diffusion buffers allocated at finalization. Their addresses remain stable for the registry’s lifetime.
-
struct StateBufferSegment
- #include <stateRegistry.h>
Consecutive complete records in one registry’s buffer. The registry must outlive the segment and every pointer resolved from it.
Public Members
-
const StateRegistry *registry = nullptr
Owner of the referenced storage.
-
StateBufferKind bufferKind = StateBufferKind::State
Buffer containing the scalar range.
-
size_t offset = 0
First scalar in the buffer.
-
size_t count = 0
Number of consecutive scalars.
-
const StateRegistry *registry = nullptr
-
class StateRegistry
- #include <stateRegistry.h>
State declarations and contiguous storage owned by DynParamManager.
Registration creates named handles with temporary matrices. finalizeStates() computes offsets, allocates the buffers, and redirects those handles to the contiguous storage. This transition happens once. Later declarations look up the existing state by name and must match its dimensions and update policy. Values can be reset directly without moving storage or rebuilding integrators.
Setup is not transactional. An exception may leave partially initialized values; callers must complete setup successfully before running the simulation.
Public Types
-
using NoiseEndpoint = std::pair<size_t, size_t>
Registration slot and local noise-source index.
-
using NoiseGroup = std::vector<NoiseEndpoint>
Endpoints driven by one shared process.
-
using NoiseTopology = std::vector<NoiseGroup>
Canonically sorted shared-noise groups.
Public Functions
-
~StateRegistry() = default
Release states, their update policies, and the buffers.
-
StateRegistry(const StateRegistry&) = delete
-
StateRegistry &operator=(const StateRegistry&) = delete
-
StateRegistry(StateRegistry&&) = delete
-
StateRegistry &operator=(StateRegistry&&) = delete
-
inline bool statesAreFinalized() const noexcept
Report whether the fixed layout and contiguous buffers are available.
-
inline size_t getStateCount() const noexcept
Return the number of named states.
-
const std::vector<StateData*> &getStateRegistrationOrder() const
Borrow handles in registration order; requires finalized registration.
-
const std::vector<StateLayout> &getStateLayouts() const
Borrow immutable layouts in registration order; requires finalized registration.
Borrow canonical shared-noise groups; requires finalized registration.
-
StateBufferSegment getSegment(StateBufferKind kind, size_t firstSlot, size_t elementCount) const
Issue a segment of any buffer spanning complete state records.
Note
Diffusion segments retain state/local-source order. They do not group shared sources.
- Parameters:
kind – State, derivative, or diffusion storage.
firstSlot – Zero-based registration slot at the start of the span.
elementCount – Number of scalars, ending at a complete record boundary. A diffusion record includes every local noise tangent of one state; states without noise contribute no scalars.
- Throws:
std::exception – If storage is not finalized, kind is invalid, or the span is invalid.
- Returns:
Segment referring to this registry’s fixed storage.
-
MutableMatrixView segmentView(const StateBufferSegment &segment)
Borrow a segment of any buffer as a writable column matrix.
- Parameters:
segment – Segment previously issued by this registry.
- Throws:
std::logic_error – If storage is not finalized or the segment is invalid.
- Returns:
View with segment.count rows and one column; no values are copied. The view remains valid until the registry is destroyed.
-
ConstMatrixView segmentView(const StateBufferSegment &segment) const
Borrow a segment of any buffer as a read-only column matrix.
- Parameters:
segment – Segment previously issued by this registry.
- Throws:
std::logic_error – If storage is not finalized or the segment is invalid.
- Returns:
View with segment.count rows and one column, valid while the registry exists.
-
StateBufferSegment getStateSegment(size_t firstSlot, size_t elementCount) const
Issue a segment spanning complete state records.
- Parameters:
firstSlot – Zero-based registration slot at the start of the span.
elementCount – Total number of scalars, ending at a record boundary.
- Throws:
std::exception – If registration is not finalized or the span is invalid.
- Returns:
Segment referring to this registry’s fixed storage.
-
StateBufferSegment getDerivativeSegment(size_t firstSlot, size_t elementCount) const
Issue a segment spanning complete derivative records.
- Parameters:
firstSlot – Zero-based registration slot at the start of the span.
elementCount – Total derivative scalars, ending at a record boundary.
- Throws:
std::exception – If registration is not finalized or the span is invalid.
- Returns:
Derivative segment owned by this registry.
-
StateBufferSegment getDiffusionSegment(size_t firstSlot, size_t elementCount) const
Issue a segment spanning complete diffusion records.
See also
- Parameters:
firstSlot – Zero-based registration slot at the start of the span.
elementCount – Total scalars across all local tangents of the selected states.
- Returns:
Diffusion segment in state/local-source order.
-
double *stateSegmentData(const StateBufferSegment &segment)
Resolve a live state segment without allocating or copying.
- Parameters:
segment – Segment previously issued by this registry.
- Throws:
std::logic_error – If storage is not finalized or the segment has the wrong owner, kind, or bounds.
- Returns:
Borrowed pointer into the committed state buffer.
-
const double *stateSegmentData(const StateBufferSegment &segment) const
Resolve a state segment for read-only access.
See also
-
double *derivativeSegmentData(const StateBufferSegment &segment)
Resolve a live derivative segment without allocating or copying.
- Parameters:
segment – Derivative segment previously issued by this registry.
- Throws:
std::logic_error – If storage is not finalized or the segment is invalid.
- Returns:
Borrowed pointer into the committed derivative buffer.
-
const double *derivativeSegmentData(const StateBufferSegment &segment) const
Resolve a derivative segment for read-only access.
See also
-
double *diffusionSegmentData(const StateBufferSegment &segment)
Resolve a live diffusion segment without allocating or copying.
- Parameters:
segment – Diffusion segment previously issued by this registry.
- Throws:
std::logic_error – If storage is not finalized or the segment is invalid.
- Returns:
Borrowed pointer into diffusion storage; may be null for an empty buffer.
-
const double *diffusionSegmentData(const StateBufferSegment &segment) const
Resolve a diffusion segment for read-only access.
- Parameters:
segment – Diffusion segment previously issued by this registry.
- Throws:
std::logic_error – If storage is not finalized or the segment is invalid.
- Returns:
Borrowed pointer into diffusion storage; may be null for an empty buffer.
Private Functions
-
StateRegistry() = default
Construct a registry that accepts new state declarations.
-
void finalizeStates()
Allocate fixed storage once; subsequent calls have no effect.
-
StateData *registerState(std::string stateName, const StateSpec &spec)
Declare a state with Euclidean updates and the supplied dimensions and noise count.
-
StateData *registerState(std::string stateName, const StateSpec &spec, std::unique_ptr<StateUpdatePolicy> policy)
Declare a special-policy state, taking ownership of the policy.
-
StateData *registerState(uint32_t nRow, uint32_t nCol, std::string stateName)
Preserve the legacy equal-shape declaration and its repeated-registration defaults.
-
StateData *getStateObject(const std::string &stateName) const
Find a handle without logging; the manager reports a missing name.
Stage shared-noise endpoints after checking ownership and local source bounds.
-
StateData *registerManagedState(std::string stateName, const StateSpec &spec, std::unique_ptr<StateUpdatePolicy> policy)
Create a named state or return its existing handle after validating the declaration.
-
void validateSpec(const std::string &stateName, const StateSpec &spec, const StateUpdatePolicy *policy) const
Check nonzero shapes, safe storage sizes, and compatibility with the update policy.
-
NoiseTopology canonicalNoiseTopology() const
Sort shared-noise groups and reject ambiguous memberships.
-
void allocateBuffers()
Compute offsets and allocate buffers from the initial declarations.
-
void requireFinalized(const char *operation) const
Throw with the operation name unless live buffers are available for integration.
-
const std::string &handleName(size_t slot) const
Look up the immutable name of a valid handle’s registration slot.
-
inline const StateSpec &handleSpec(size_t slot) const
Borrow the declaration associated with a valid handle’s slot.
-
void setHandleNoiseCount(size_t slot, size_t numSources)
Support registration-time noise-count changes; established topology accepts only its existing count.
-
double *activeDiffusionData(size_t slot, size_t localNoiseIndex)
Resolve one diffusion tangent in temporary matrices or the finalized buffer.
-
const double *activeDiffusionData(size_t slot, size_t localNoiseIndex) const
Resolve one diffusion tangent for read-only access.
-
double *liveStateData(size_t slot)
Resolve one record in finalized live state storage.
-
double *liveDerivativeData(size_t slot)
Resolve one record in finalized live derivative storage.
-
double *liveDiffusionData(size_t slot, size_t localNoiseIndex)
Resolve one local source in finalized live diffusion storage.
-
void requireRawAccess(const char *field) const
Reject buffer access before storage has been allocated.
Private Members
-
bool finalized = false
True after the one-time layout and buffer allocation.
-
std::unordered_map<std::string, size_t> stateSlotByName
Name to stable registration slot.
-
std::vector<StateRecord> stateRecords
Owned handles, declarations, initial matrices, and policies.
-
std::vector<StateLayout> stateLayoutView
Fixed shapes and scalar offsets.
-
StateBuffers liveBuffers
Values used by modules and integrators; never resized after finalization.
-
NoiseTopology finalizedNoiseTopology
Canonical shared-noise groups fixed at finalization.
-
NoiseTopology pendingNoiseGroups
Shared-noise declarations collected before finalization.
Friends
- friend class DynParamManager
- friend class StateData
-
struct StateSeed
Temporary matrices used only before buffer dimensions are established.
-
struct StateRecord
Own one state’s identity, immutable declaration, and optional update rule.
Public Members
-
std::string name
Unique lookup key and repeated-registration identity.
-
std::unique_ptr<StateUpdatePolicy> updatePolicy
Owned immutable special policy, or nullptr.
-
std::string name
-
using NoiseEndpoint = std::pair<size_t, size_t>