Environment Persistence
DIP can persist an evaluated environment in the DIPH5 HDF5 format. This is useful when a DIPL input has already been parsed and evaluated and the resulting values need to be exchanged with another application, stored for a later calculation, or inspected by scientific software using HDF5.
The persisted object is an evaluated environment, not the original DIPL program or the complete parser runtime. The format stores values, hierarchy, collections, units, node settings, and provenance; current round-trip limitations are listed below. Runtime function definitions, branching state, and complete parser registries are not reconstructed.
The recommended filename extension is .diph5. The extension is only a
naming convention; the file is identified normatively by its root
_DIPL_Format and _DIPL_Schema_Version attributes.
Saving and loading
The C++ API saves and loads through snt::dip::Environment:
snt::dip::DIP parser;
parser.add_file("parameters.dipl");
snt::dip::Environment env = parser.parse();
env.save("parameters.diph5");
snt::dip::Environment restored;
restored.load("parameters.diph5");
save() overwrites an existing destination file. load() replaces the
current environment only after the file has been read successfully; a failed
load leaves the existing environment unchanged.
Current limitations
The current implementation does not yet preserve every detail on a save/load round trip:
Units associated with null values are not restored by the loader.
Groups and collections without value-node descendants are not written: the writer constructs the hierarchy from the saved value paths.
Source identifiers, line numbers, captured source lines, and citation metadata
remain node-level provenance. DIPH5 version 2 stores a source manifest with
each source’s name, recorded path, parent relationship, and SHA-256 hash of
the exact parsed content. Source paths can be saved relative to the DIPH5
directory with SnapshotSaveOptions and
SourcePathPolicy::RelativeToSnapshot. Relative paths in a loaded snapshot
are interpreted from that snapshot’s directory when it is saved again with
the same policy. The default preserves the original path strings.
Version 2.1 additionally preserves the trace IDs of registered units, schemas,
and functions. Version 2.4 adds schema-level
descriptions, citations, and source locations to those trace entries. In C++,
get_schema_manifest() returns these descriptive records and
get_applied_schemas(path) finds schemas applied along a value path.
get_contributing_schema(path) identifies the schema that supplied a value
node, when known. Loading
does not recreate complete source text, parsed source nodes, schema definitions,
executable functions, or source-qualified lookups; a loaded schema cannot be
instantiated from the snapshot.
HDF5 mapping
Fully qualified DIPL paths become HDF5 paths. Hierarchy and collection nodes are groups, while value nodes are datasets:
/simulation group (_DIPL_Kind=group)
/simulation/steps dataset (_DIPL_Kind=value)
/boundary group (_DIPL_Kind=map)
/boundary/inlet group (_DIPL_Kind=map_item)
/boundary/inlet/velocity dataset (_DIPL_Kind=value)
/samples group (_DIPL_Kind=list)
/samples/0 group (_DIPL_Kind=list_item)
/samples/0/time dataset (_DIPL_Kind=value)
The _DIPL_* attributes carry the DIPL meaning that cannot be inferred
from HDF5 names alone. Value datasets use native HDF5 numeric datatypes,
simple dataspaces for arrays, and null dataspaces for null values. Node
settings and provenance are stored as dataset attributes.
Comparing DIPH5 snapshots
Construct a snt::dip::Comparison with two DIPH5 snapshots. It
loads and compares them once, then lets you inspect or render the result as
often as needed. The result contains added, removed, and changed entries
sorted by category and path. Each changed value lists the fields that differ. Arrays report the count
of changed elements and a bounded sample of flat, zero-based indices. The
plain-text renderer limits the number of entries while keeping the totals.
#include <snt/dip/comparison.h>
snt::dip::Comparison comparison{"before.diph5", "after.diph5"};
std::cout << comparison.render(50);
The default Effective scope compares persisted value paths, declared and
stored types, shapes, units, and element values. Full also compares tags,
metadata, options, provenance, settings, and source, trace, and schema
manifests. equal() means equal within the selected scope; it does not
compare HDF5 bytes or layout. Numeric comparison is exact, with two NaNs
treated as equal. Array examples are controlled by
ComparisonOptions::max_array_examples.
snt::dip::ComparisonOptions options;
options.scope = snt::dip::ComparisonScope::Full;
options.max_array_examples = 5;
snt::dip::Comparison comparison{"before.diph5", "after.diph5", options};
if (!comparison.equal()) {
for (const auto& difference : comparison.result().differences) {
// Use the structured differences in your application.
}
}
For applications using the command layer, snt::api::DIPCompare
provides the same comparison and text rendering. See also the
CLI, REST,
Python, and C
interfaces.
Full DIPH5 specification
The complete format contract, including object kinds, value datatypes, attributes, compatibility rules, and DIPL-to-HDF5 examples, is provided in the standalone specification below.