Mila 0.13.48
Deep Neural Network Library
Loading...
Searching...
No Matches
/__w/Mila/Mila/Mila/Src/Dnn/Serialization/ModelArchive.ixx

Write type-safe metadata to the archive.

Write type-safe metadata to the archive.User-facing API that abstracts JSON serialization format. Components use SerializationMetadata to build metadata without knowledge of underlying format.

Parameters
pathArchive path for metadata file
metadataType-safe metadata container
Exceptions
std::runtime_errorif archive is not in Write mode
std::runtime_erroron serialization failure

SerializationMetadata meta; meta.set("type", "Linear") .set("version", 1) .set("input_features", 128); archive.writeMetadata("meta.json", meta);

module;
#include <memory>
#include <string>
#include <vector>
#include <stdexcept>
#include <utility>
#include <cstdint>
#include <exception>
#include <format>
{
using json = nlohmann::json;
export class ModelArchive
{
public:
explicit ModelArchive( const std::string& filepath, std::unique_ptr<ArchiveSerializer> serializer, OpenMode mode )
: filepath_( filepath ), serializer_( std::move( serializer ) ), mode_( mode ), closed_( false )
{
if ( !serializer_ )
{
throw std::invalid_argument( "ModelArchive requires a non-null serializer" );
}
if ( !serializer_->open( filepath, mode ) )
{
throw std::runtime_error(
std::format( "ModelArchive: failed to open '{}' for {}", filepath, archiveModeToString( mode ) ) );
}
}
{
if ( !closed_ && serializer_ )
{
try
{
close();
}
catch ( ... )
{
}
}
}
ModelArchive( const ModelArchive& ) = delete;
ModelArchive& operator=( const ModelArchive& ) = delete;
ModelArchive( ModelArchive&& other ) noexcept
: serializer_( std::move( other.serializer_ ) )
, filepath_( std::move( other.filepath_ ) )
, mode_( other.mode_ )
, closed_( other.closed_ )
{
other.closed_ = true;
}
ModelArchive& operator=( ModelArchive&& other ) noexcept
{
if ( this != &other )
{
if ( !closed_ )
{
try
{
close();
}
catch ( ... )
{
}
}
serializer_ = std::move( other.serializer_ );
filepath_ = std::move( other.filepath_ );
mode_ = other.mode_;
closed_ = other.closed_;
other.closed_ = true;
}
return *this;
}
OpenMode getMode() const noexcept
{
return mode_;
}
const std::string& getFilepath() const noexcept
{
return filepath_;
}
bool isClosed() const noexcept
{
return closed_;
}
void close()
{
if ( closed_ ) return;
if ( !serializer_ )
{
closed_ = true;
return;
}
try
{
serializer_->close();
closed_ = true;
}
catch ( const std::exception& e )
{
throw std::runtime_error(
std::format( "ModelArchive::close failed for '{}': {}", filepath_, e.what() ) );
}
}
// ====================================================================
// Scoping helpers
// ====================================================================
void pushScope( const std::string& scope )
{
std::string s = scope;
while ( !s.empty() && s.front() == '/' ) s.erase( s.begin() );
while ( !s.empty() && s.back() == '/' ) s.pop_back();
if ( !s.empty() )
{
scope_stack_.push_back( s );
}
}
void popScope()
{
if ( scope_stack_.empty() )
{
throw std::runtime_error( "ModelArchive::popScope: no scope to pop" );
}
scope_stack_.pop_back();
}
class ScopedScope
{
public:
ScopedScope( ModelArchive& archive, const std::string& scope )
: archive_( archive ), active_( true )
{
archive_.pushScope( scope );
}
{
if ( active_ )
{
try
{
}
catch ( ... )
{
}
}
}
ScopedScope( const ScopedScope& ) = delete;
ScopedScope& operator=( const ScopedScope& ) = delete;
ScopedScope( ScopedScope&& other ) noexcept
: archive_( other.archive_ ), active_( other.active_ )
{
other.active_ = false;
}
private:
bool active_;
};
// ====================================================================
// File Query Operations
// ====================================================================
bool hasFile( const std::string& path ) const
{
requireOpen( "hasFile" );
return serializer_->hasFile( scopedPath( path ) );
}
size_t getFileSize( const std::string& path ) const
{
requireOpen( "getFileSize" );
return serializer_->getFileSize( scopedPath( path ) );
}
std::vector<std::string> listFiles() const
{
requireOpen( "listFiles" );
return serializer_->listFiles();
}
// ====================================================================
// Type-Safe Metadata Write/Read (USER-FACING API)
// ====================================================================
void writeMetadata( const std::string& path, const SerializationMetadata& metadata )
{
requireOpen( "writeMetadata" );
requireMode( OpenMode::Write, "writeMetadata" );
json j = metadata.toJson();
const std::string full = scopedPath( path );
std::string s = j.dump( 2 );
if ( !serializer_->addData( full, s.data(), s.size() ) )
{
throw std::runtime_error(
std::format( "ModelArchive::writeMetadata failed for path: {}", full ) );
}
}
SerializationMetadata readMetadata( const std::string& path ) const
{
requireMode( OpenMode::Read, "readMetadata" );
const std::string full = scopedPath( path );
size_t sz = serializer_->getFileSize( full );
if ( sz == 0 )
{
throw std::runtime_error( "ModelArchive::readMetadata missing file: " + full );
}
std::string s( sz, '\0' );
size_t read = serializer_->extractData( full, s.data(), sz );
if ( read != sz )
{
throw std::runtime_error( "ModelArchive::readMetadata failed to read entire file: " + full );
}
try
{
json j = json::parse( s );
}
catch ( const std::exception& e )
{
throw std::runtime_error( std::string( "ModelArchive::readMetadata parse error: " ) + e.what() );
}
}
// ====================================================================
// Binary Blob Operations
// ====================================================================
void writeBlob( const std::string& path, const void* data, size_t size )
{
requireOpen( "writeBlob" );
requireMode( OpenMode::Write, "writeBlob" );
if ( !data && size > 0 )
{
throw std::invalid_argument( "ModelArchive::writeBlob: null data with non-zero size" );
}
const std::string full = scopedPath( path );
if ( !serializer_->addData( full, data, size ) )
{
throw std::runtime_error(
std::format( "ModelArchive::writeBlob failed for path: {}", full ) );
}
}
std::vector<uint8_t> readBlob( const std::string& path ) const
{
requireOpen( "readBlob" );
requireMode( OpenMode::Read, "readBlob" );
const std::string full = scopedPath( path );
if ( !serializer_->hasFile( full ) )
{
throw std::runtime_error(
std::format( "ModelArchive::readBlob: file not found: {}", full ) );
}
size_t sz = serializer_->getFileSize( full );
if ( sz == 0 )
{
return {};
}
std::vector<uint8_t> buf( sz );
size_t read = serializer_->extractData( full, buf.data(), sz );
if ( read != sz )
{
throw std::runtime_error(
std::format( "ModelArchive::readBlob: incomplete read from {}", full ) );
}
return buf;
}
size_t readBlobInto( const std::string& path, void* buffer, size_t buffer_size ) const
{
requireOpen( "readBlobInto" );
requireMode( OpenMode::Read, "readBlobInto" );
const std::string full = scopedPath( path );
if ( !serializer_->hasFile( full ) )
{
throw std::runtime_error(
std::format( "ModelArchive::readBlobInto: file not found: {}", full ) );
}
size_t file_size = serializer_->getFileSize( full );
if ( file_size > buffer_size )
{
throw std::runtime_error(
std::format( "ModelArchive::readBlobInto: buffer too small ({} < {})",
buffer_size, file_size ) );
}
size_t read = serializer_->extractData( full, buffer, file_size );
if ( read != file_size )
{
throw std::runtime_error(
std::format( "ModelArchive::readBlobInto: incomplete read from {}", full ) );
}
return read;
}
void addMetadata( const std::string& key, const std::string& value )
{
serializer_->addMetadata( key, value );
}
std::string getMetadata( const std::string& key ) const
{
return serializer_->getMetadata( key );
}
private:
std::unique_ptr<ArchiveSerializer> serializer_;
std::string filepath_;
bool closed_{ false };
std::vector<std::string> scope_stack_;
static inline const std::vector<std::string> kAbsoluteRoots = { "network/", "components/", "modules/" };
std::string currentPrefix() const
{
if ( scope_stack_.empty() ) return std::string();
std::string p;
for ( size_t i = 0; i < scope_stack_.size(); ++i )
{
if ( i ) p.push_back( '/' );
p += scope_stack_[ i ];
}
if ( !p.empty() && p.back() != '/' ) p.push_back( '/' );
return p;
}
bool isAbsolutePath( const std::string& path ) const noexcept
{
if ( path.empty() ) return false;
if ( path.front() == '/' ) return true;
for ( const auto& root : kAbsoluteRoots )
{
if ( path.rfind( root, 0 ) == 0 ) return true;
}
return false;
}
std::string scopedPath( const std::string& path ) const
{
if ( isAbsolutePath( path ) || scope_stack_.empty() )
{
return path;
}
return currentPrefix() + path;
}
void requireMode( OpenMode expected, const char* op ) const
{
if ( mode_ != expected )
{
throw std::runtime_error(
std::format( "ModelArchive::{}: operation requires {} mode, but archive is in {} mode",
}
}
void requireOpen( const char* op ) const
{
if ( closed_ )
{
throw std::runtime_error(
std::format( "ModelArchive::{}: archive is closed", op ) );
}
}
};
}
bool active_
Definition ModelArchive.ixx:225
ModelArchive & archive_
Definition ModelArchive.ixx:224
~ScopedScope()
Definition ModelArchive.ixx:200
ScopedScope & operator=(const ScopedScope &)=delete
ScopedScope(ModelArchive &archive, const std::string &scope)
Definition ModelArchive.ixx:194
void requireMode(OpenMode expected, const char *op) const
Definition ModelArchive.ixx:523
void addMetadata(const std::string &key, const std::string &value)
Add simple metadata key-value pair.
Definition ModelArchive.ixx:459
std::string filepath_
Definition ModelArchive.ixx:477
std::vector< std::string > scope_stack_
Definition ModelArchive.ixx:480
bool hasFile(const std::string &path) const
Definition ModelArchive.ixx:232
SerializationMetadata readMetadata(const std::string &path) const
Definition ModelArchive.ixx:310
void popScope()
Definition ModelArchive.ixx:182
ModelArchive & operator=(const ModelArchive &)=delete
OpenMode mode_
Definition ModelArchive.ixx:478
ModelArchive(const std::string &filepath, std::unique_ptr< ArchiveSerializer > serializer, OpenMode mode)
Construct archive with serializer and automatically open for specified mode.
Definition ModelArchive.ixx:62
bool isAbsolutePath(const std::string &path) const noexcept
Definition ModelArchive.ixx:500
size_t readBlobInto(const std::string &path, void *buffer, size_t buffer_size) const
Read binary blob directly into provided buffer.
Definition ModelArchive.ixx:422
bool isClosed() const noexcept
Definition ModelArchive.ixx:139
std::vector< uint8_t > readBlob(const std::string &path) const
Read raw binary blob from archive into returned vector.
Definition ModelArchive.ixx:382
static const std::vector< std::string > kAbsoluteRoots
Definition ModelArchive.ixx:482
~ModelArchive()
Destructor automatically closes the serializer.
Definition ModelArchive.ixx:80
std::unique_ptr< ArchiveSerializer > serializer_
Definition ModelArchive.ixx:476
void writeMetadata(const std::string &path, const SerializationMetadata &metadata)
Definition ModelArchive.ixx:274
std::string getMetadata(const std::string &key) const
Retrieve simple metadata value.
Definition ModelArchive.ixx:470
std::string currentPrefix() const
Definition ModelArchive.ixx:484
std::vector< std::string > listFiles() const
Definition ModelArchive.ixx:244
std::string scopedPath(const std::string &path) const
Definition ModelArchive.ixx:513
void close()
Definition ModelArchive.ixx:144
const std::string & getFilepath() const noexcept
Definition ModelArchive.ixx:134
OpenMode getMode() const noexcept
Definition ModelArchive.ixx:129
void writeBlob(const std::string &path, const void *data, size_t size)
Write raw binary blob to archive.
Definition ModelArchive.ixx:354
size_t getFileSize(const std::string &path) const
Definition ModelArchive.ixx:238
bool closed_
Definition ModelArchive.ixx:479
void requireOpen(const char *op) const
Definition ModelArchive.ixx:533
void pushScope(const std::string &scope)
Definition ModelArchive.ixx:170
static SerializationMetadata fromJson(const json &j)
Construct from JSON representation (internal use only).
Definition SerializationMetadata.ixx:606
Definition ArchiveSerializer.ixx:19
OpenMode
Mode indicating whether the archive is used for reading or writing.
Definition OpenMode.ixx:37
@ Write
Definition OpenMode.ixx:39
@ Read
Definition OpenMode.ixx:38
nlohmann::json json
Definition ModelArchive.ixx:27
constexpr std::string_view archiveModeToString(OpenMode mode)
Convert ArchiveMode to string.
Definition OpenMode.ixx:45