Source code for model_io.h

/* Provides zero-dependency binary model container serialization (.lsm / .lsb).
 * Copyright (C) 2026 designed, written and maintained by Giuseppe Marco Randazzo <gmrandazzo@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef MODEL_IO_H
#define MODEL_IO_H
#include <stdio.h> #include <stdint.h> #include <stdbool.h> #include <stddef.h> #include "pca.h" #include "pls.h" #include "cpca.h" #include "mlr.h" #include "lda.h" #include "ica.h" #include "upca.h" #include "upls.h" #ifdef __cplusplus extern "C" { #endif
#define LSCM_MAGIC 0x4D43534CU /* "LSCM" in little-endian */
#define LSCM_VERSION 1U
#define LSCM_MAX_NAME_LEN 64
/** * Enumeration of supported model types in the LSCM container format. */ typedef enum {
MODEL_TYPE_UNKNOWN = 0,
MODEL_TYPE_PCA = 1,
MODEL_TYPE_PLS = 2,
MODEL_TYPE_CPCA = 3,
MODEL_TYPE_MLR = 4,
MODEL_TYPE_LDA = 5,
MODEL_TYPE_ICA = 6,
MODEL_TYPE_UPCA = 7,
MODEL_TYPE_UPLS = 8,
MODEL_TYPE_ANY = 255
} ModelType;
/** * Error codes returned by model I/O routines. */ typedef enum {
LSCM_OK = 0,
LSCM_ERR_FILE_NOT_FOUND = -1,
LSCM_ERR_IO = -2,
LSCM_ERR_INVALID_MAGIC = -3,
LSCM_ERR_UNSUPPORTED_VER= -4,
LSCM_ERR_INVALID_TYPE = -5,
LSCM_ERR_TYPE_MISMATCH = -6,
LSCM_ERR_NOT_FOUND = -7,
LSCM_ERR_MEM = -8,
LSCM_ERR_PARAM = -9,
LSCM_ERR_CORRUPT = -10
} LSCMStatus;
[docs]/** * Metadata descriptor for inspecting files without full payload loading. */ typedef struct {
uint32_t num_models;
bool is_single;
ModelType primary_type;
char primary_name[LSCM_MAX_NAME_LEN];
uint32_t format_version;
uint64_t total_size;
} MODEL_FILE_INFO;
[docs]/** * Single entry within a multi-model bundle. */ typedef struct {
char name[LSCM_MAX_NAME_LEN];
ModelType type;
void *model;
} MODEL_ENTRY;
[docs]/** * Multi-model bundle container representing a project or pipeline. */ typedef struct {
size_t count;
size_t capacity;
MODEL_ENTRY *entries;
} MODEL_BUNDLE;
/* ========================================================================= * Core Single-Model APIs (.lsm) * ========================================================================= */
[docs]/** * Save a single model into a standalone .lsm file. * * @param [in] filepath Destination file path (typically with .lsm extension) * @param [in] model_name Identifier tag for the model (e.g. "qsar_pls" or NULL for "default") * @param [in] type Model type (MODEL_TYPE_PCA, MODEL_TYPE_PLS, etc.) * @param [in] model Pointer to the populated model struct * @return LSCM_OK (0) on success, or a negative LSCMStatus error code */ int SaveModel(const char *filepath, const char *model_name, ModelType type, const void *model);
[docs]/** * Import a single model from a file (.lsm or .lsb with 1 model). * * @param [in] filepath Source file path * @param [in] expected_type Expected ModelType (or MODEL_TYPE_ANY) * @param [out] model Pointer to pre-allocated or initialized target model struct * @return LSCM_OK (0) on success, or a negative LSCMStatus error code */ int ImportModel(const char *filepath, ModelType expected_type, void *model);
/* ========================================================================= * Multi-Model Project Bundle APIs (.lsb) * ========================================================================= */
[docs]/** * Create a new empty model bundle in memory. */ MODEL_BUNDLE* NewModelBundle(void);
[docs]/** * Add a model into a bundle. The bundle takes custody of the model pointer. * * @param [in,out] bundle Target bundle * @param [in] name Unique model identifier name within the project * @param [in] type Model type * @param [in] model Pointer to the concrete model struct * @return LSCM_OK (0) on success, or a negative LSCMStatus error code */ int ModelBundleAddModel(MODEL_BUNDLE *bundle, const char *name, ModelType type, void *model);
[docs]/** * Retrieve a model from a bundle by its unique name. * * @param [in] bundle Source bundle * @param [in] name Unique model name * @param [out] out_type Optional output parameter for model type * @return Pointer to the model struct, or NULL if not found */ void* ModelBundleGetModel(const MODEL_BUNDLE *bundle, const char *name, ModelType *out_type);
[docs]/** * Retrieve a model from a bundle by index. * * @param [in] bundle Source bundle * @param [in] index 0-based index * @param [out] out_name Optional output buffer/pointer for model name * @param [out] out_type Optional output parameter for model type * @return Pointer to the model struct, or NULL if index is out of bounds */ void* ModelBundleGetModelByIndex(const MODEL_BUNDLE *bundle, size_t index, const char **out_name, ModelType *out_type);
[docs]/** * Free a model bundle container. * * @param [in,out] bundle Pointer to bundle pointer * @param [in] free_contained_models If non-zero, frees each contained model struct appropriately */ void DelModelBundle(MODEL_BUNDLE **bundle, int free_contained_models);
[docs]/** * Save multiple models from a bundle into a single .lsb file. * * @param [in] filepath Destination file path (typically with .lsb extension) * @param [in] bundle Model bundle containing 1 or more models * @return LSCM_OK (0) on success, or a negative LSCMStatus error code */ int SaveModelBundle(const char *filepath, const MODEL_BUNDLE *bundle);
[docs]/** * Import a multi-model project bundle from an .lsb file. * * @param [in] filepath Source file path * @return Pointer to loaded MODEL_BUNDLE, or NULL on error */ MODEL_BUNDLE* ImportModelBundle(const char *filepath);
/* ========================================================================= * Inspection & Auto-Detection APIs * ========================================================================= */
[docs]/** * Inspect a model file header without loading full matrix/tensor payloads. * * @param [in] filepath Source file path (.lsm or .lsb) * @param [out] info Output structure with model count, types, and sizes * @return LSCM_OK (0) on success, or a negative LSCMStatus error code */ int InspectModelFile(const char *filepath, MODEL_FILE_INFO *info);
[docs]/** * Automatically import a file, detecting whether it is a single model or a bundle. * * If single model: * - `*out_bundle` will be NULL. * - `*out_single_model` receives the newly allocated model struct. * - `*out_single_type` receives the model type. * - Returns 1. * * If multi-model bundle: * - `*out_single_model` will be NULL. * - `*out_bundle` receives the loaded MODEL_BUNDLE. * - Returns the total count of models in the bundle (> 1). * * @param [in] filepath Source file path (.lsm, .lsb, or generic) * @param [out] out_single_model Output pointer for single model * @param [out] out_single_type Output pointer for single model type * @param [out] out_bundle Output pointer for bundle * @return Number of models imported on success (> 0), or a negative error code */ int ImportModelAuto(const char *filepath, void **out_single_model, ModelType *out_single_type, MODEL_BUNDLE **out_bundle);
/* ========================================================================= * Type-Specific Convenience Helpers * ========================================================================= */
[docs]int SavePCAModel(const char *filepath, const PCAMODEL *pca);
[docs]int ImportPCAModel(const char *filepath, PCAMODEL *pca);
[docs]int SavePLSModel(const char *filepath, const PLSMODEL *pls);
[docs]int ImportPLSModel(const char *filepath, PLSMODEL *pls);
[docs]int SaveCPCAModel(const char *filepath, const CPCAMODEL *cpca);
[docs]int ImportCPCAModel(const char *filepath, CPCAMODEL *cpca);
[docs]int SaveMLRModel(const char *filepath, const MLRMODEL *mlr);
[docs]int ImportMLRModel(const char *filepath, MLRMODEL *mlr);
[docs]int SaveLDAModel(const char *filepath, const LDAMODEL *lda);
[docs]int ImportLDAModel(const char *filepath, LDAMODEL *lda);
[docs]int SaveICAModel(const char *filepath, const ICAMODEL *ica);
[docs]int ImportICAModel(const char *filepath, ICAMODEL *ica);
[docs]int SaveUPCAModel(const char *filepath, const UPCAMODEL *upca);
[docs]int ImportUPCAModel(const char *filepath, UPCAMODEL *upca);
[docs]int SaveUPLSModel(const char *filepath, const UPLSMODEL *upls);
[docs]int ImportUPLSModel(const char *filepath, UPLSMODEL *upls);
[docs]/** * Helper to convert ModelType enum to human-readable string. */ const char* ModelTypeToString(ModelType type);
[docs]/** * Helper to parse human-readable string to ModelType enum. */ ModelType ModelTypeFromString(const char *str);
#ifdef __cplusplus } #endif #endif /* MODEL_IO_H */