What is syNumpy?
syNumpy is a standalone C++17 library from Symisc Systems ↗ designed for reading and writing NumPy .npy files.
It gives C++ applications a clean and efficient way to exchange numerical arrays with Python-based workflows, while remaining easy to integrate into existing native codebases. The library is released under the 3-Clause BSD License, and the source code is hosted on GitHub ↗.
Production Usage
syNumpy is used internally by FACEIO ↗ for facial features extraction workflows and by PixLab production systems behind the DocScan Mobile App, PixLab internal visual-search and document-processing workflows exposed through the PixLab API Endpoints, and the DOCSCAN API endpoint for scanning passports, driver licenses, visas, residence permits, and other identity documents issued around the world.
Core Features
syNumpy focuses on robust .npy support for scalar numeric and complex dtypes. The core parser entry point is syNumpy::loadNpyBuffer(), the file APIs are thin wrappers on top of that parser, and malformed headers or truncated payloads are rejected explicitly.
Stores shape dimensions, dtype descriptors, Fortran-order flags, and the raw payload bytes efficiently in memory.
Use syNumpy::loadNpy() to read from disk, or syNumpy::loadNpyBuffer() to parse an in-memory NumPy dataset directly.
syNumpy::saveNpyRaw() allows explicit dtype descriptors, while saveNpy() overloads handle common native C++ workflows automatically.
Set mode = "a" to extend axis 0. It rigorously validates headers, endianness, and trailing dims before appending.
Build & Integration
The simplest integration path is to copy synumpy.hpp and synumpy.cpp into your source tree and compile them with your existing C++17 target.
- Public files synumpy.hpp, synumpy.cpp
- Language requirement C++17
- Runtime dependencies None
- Alternative build files CMakeLists.txt, Makefile
Minimal Example
C++17 API Reference Guide
The following reference describes the current public interface exported by synumpy.hpp.
Version Constants
syNumpy::kVersionMajor syNumpy::kVersionMinor syNumpy::kVersionPatch syNumpy::kVersionStringclass syNumpy::Error
explicit Error(const std::string& message)
message - The exception text.std::runtime_error-derived exception object used for parse, validation, and I/O failures.class syNumpy::NpyArray
NpyArray() = default
NpyArray(std::vector<std::size_t> shape, std::string dtype_descr, bool fortran_order)
.npy array in memory together with its shape, dtype metadata, Fortran-order flag, and payload bytes.shape, dtype_descr, and fortran_order for the materializing constructor.shape(),dtypeDescr(),wordSize(),fortranOrder(),numValues(), andnumBytes()expose array metadata.bytes()returns raw payload bytes.is<T>(),data<T>(), andasVector<T>()provide typed access and throwsyNumpy::Erroron dtype mismatch.
function syNumpy::loadNpyBuffer()
NpyArray loadNpyBuffer(const void* buffer, std::size_t size)
.npy image that is already loaded in memory. This is the core parser entry point used by the file-loading path.buffer - A pointer to the first byte of a complete .npy image.size - The total available byte count.
syNumpy::NpyArray.syNumpy::Error on malformed headers, truncated payloads, unsupported dtypes, or unsupported endianness.function syNumpy::loadNpy()
NpyArray loadNpy(const std::filesystem::path& path)
.npy file from disk, reads its contents, and returns the parsed array as a syNumpy::NpyArray.path - The filesystem path to a .npy file.syNumpy::NpyArray.function syNumpy::saveNpyRaw()
void saveNpyRaw(const std::filesystem::path& path, const void* data, std::size_t byte_count, const std::vector<std::size_t>& shape,
std::string_view dtype_descr, std::string_view mode = "w")
.npy file from raw bytes and an explicit NumPy dtype descriptor. It is the low-level save path behind the typed overloads and also supports compatible append mode.path, data, byte_count, shape, and dtype_descr.mode = "w" or "wb" to overwrite or create, and mode = "a" or "ab" to append along axis 0 when the existing file is compatible.function syNumpy::saveNpy() Typed Overloads
template <typename T> void saveNpy(const std::filesystem::path& path, const T* data, const std::vector<std::size_t>& shape, std::string_view mode = "w")
template <typename T> void saveNpy(const std::filesystem::path& path, const std::vector<T>& data, const
std::vector<std::size_t>& shape, std::string_view mode = "w")
template <typename T> void saveNpy(const std::filesystem::path& path, const std::vector<T>& data, std::string_view mode =
"w")
data.size() to match the element count implied by the provided shape. The vector-only overload automatically infers a one-dimensional shape equal to {data.size()}.Supported Native Types
bool, 8/16/32/64-bit signed and unsigned integers, float, double, long double, and std::complex<T> for the supported floating-point scalar families.Full Usage Example
The following example covers direct integration, save/load round-trips, explicit shapes, buffer parsing, and append mode combined in one place.