A pluggable C++ pipeline that runs BOA neural
compression with backbone inference implemented by
SOFIE. All device memory is in alpaka::Buf, so the pipeline
is portable across every backend alpaka supports (CPU, CUDA, HIP, SYCL)
via a single compile-time tag.
For the full explanation of the compression/decompression cycle see the BOA Constrictor README.
| Component | Header | Role |
|---|---|---|
Compressor<TagAcc> |
boso/compressor/Compressor.hpp |
Drives the compression pipeline |
Decompressor<TagAcc> |
boso/decompressor/Decompressor.hpp |
Drives the decompression pipeline |
ChunkedByteIngestion<TagAcc> |
boso/compressor/ChunkedByteIngestion.hpp |
Offline byte buffer → token batches |
StreamingByteIngestion<TagAcc> |
boso/compressor/StreamingByteIngestion.hpp |
std::istream → token batches |
SofieBackbone<TagAcc, SessionT> |
boso/backbone/SofieBackbone.hpp |
Wraps a SOFIE-generated stateful session as an IBackbone |
PortableRangeCoder<TagAcc> |
boso/rangecoder/PortableRangeCoder.hpp |
Alpaka port of the BOA carryless range coder |
OfflineEncodedSink / OfflineEncodedSource |
boso/encoded/ |
In-memory chunk collection; serialises to .boa file |
StreamingEncodedSink / StreamingEncodedSource |
boso/encoded/ |
Streaming BOSS .boss format (per-chunk CRC32) |
boso/compressor/Compressor.hpp and boso/decompressor/Decompressor.hpp each
pull in their own concrete components (ingestion, range coder, container,
sinks/sources) transitively, so an user only needs to include those two
headers plus a backbone header.
| Interface | Header | Swap to… |
|---|---|---|
IDataIngestion<TagAcc> |
boso/compressor/IDataIngestion.hpp |
Memory-mapped file, socket, GPU-resident buffer |
IBackbone<TagAcc> |
boso/backbone/IBackbone.hpp |
Different trained model, hand-written predictor |
IRangeCoder<TagAcc> |
boso/rangecoder/IRangeCoder.hpp |
|
IEncodedSink / IBytesSink |
boso/encoded/ / boso/bytes/ |
#include "boso/compressor/Compressor.hpp"
#include "boso/decompressor/Decompressor.hpp"
#include "boso/backbone/SofieBackbone.hpp"
using TagAcc = alpaka::TagCpuSerial; // or TagGpuCudaRt / TagGpuHipRt
using Traits = boso::AccTraits<TagAcc>;
using Backbone = boso::SofieBackbone<TagAcc, MySOFIESession>;
auto device = Traits::device();
auto host = Traits::host();
typename Traits::QueueAcc queue{device};
// --- Compress (offline: file → file) ---
auto ingestion = std::make_unique<boso::ChunkedByteIngestion<TagAcc>>(
payload, /*batchSize=*/4, /*chunkLength=*/4096, device, host);
boso::Compressor<TagAcc> compressor(
std::move(ingestion),
std::make_unique<Backbone>(queue, vocabSize, dModel, embeddingWeights, device, host),
std::make_unique<boso::PortableRangeCoder<TagAcc>>(device));
boso::OfflineEncodedSink sink;
compressor.run(queue, sink);
boso::Container c;
c.backboneName = "my_model";
c.batchSize = 4;
c.chunkLength = 4096;
c.uncompressedBytes = payload.size();
c.chunks = sink.takeChunks();
boso::writeContainer("output.boa", c);
// --- Decompress (offline: file → memory) ---
boso::Container container = boso::readContainer("output.boa");
boso::OfflineEncodedSource source(std::move(container));
boso::Decompressor<TagAcc> decompressor(
std::make_unique<Backbone>(queue, vocabSize, dModel, embeddingWeights, device, host),
std::make_unique<boso::PortableRangeCoder<TagAcc>>(device));
boso::OfflineBytesSink bytesSink;
decompressor.run(source, bytesSink, queue);
std::vector<std::uint8_t> recovered = bytesSink.takeBytes();See tutorials/boso_demo.cpp for a self-contained
round-trip example using DemoIdentitySession (no trained weights needed).
- Export the trained BOA Constrictor model to ONNX.
- Generate the header file with SOFIE.
- Add an entry to
tutorials/backbones.json:
{
"name": "my_model",
"include_dir": "/path/to/sofie/generated",
"header": "SOFIE_MyModel/MyModel.hxx",
"session": "SOFIE_MyModel::Session",
"vocab_size": 256,
"d_model": 512
}CMake reads this at configure time and stamps out one boso_my_model
binary from src/boso_tool.cpp.in. Reconfigure to pick up new entries.
# Offline: file → BOA3 .boa container
boso_<name> compress <source.bin> <output.boa> [batchSize] [chunkLength]
# Streaming: stdin/file → BOSS .boss / stdout
boso_<name> compress <source.bin|-> <output.boss|-> [batchSize] [chunkLength]
# Decompress (format auto-detected from magic: BOA3 or BOSS)
boso_<name> decompress <input.boa|input.boss|-> <output|->`
# Via job file
boso_<name> compress --job compress_job.json
boso_<name> decompress --job decompress_job.jsonA boso_<name> binary is compiled against exactly one backbone. It refuses
to decompress a file tagged with a different backbone name rather than
silently desyncing the range coder.
| Format | Magic | Extension | Notes |
|---|---|---|---|
| BOA3 | BOA3 |
.boa |
Offline container; whole-file CRC32; random-access required |
| BOSS | BOSS |
.boss or - |
Streaming; per-chunk CRC32 + ENDS sentinel; pipe-safe |
BOSO reuses the .boa extension from BOA Constrictor, the project this pipeline is modeled on, for the same role, i.e. an
offline, whole-file compressed container. The wire format itself differs:
BOA Constrictor uses magic BOA2 with its own internal layout, while BOSO
uses magic BOA3.
cmake -S . -B build -DBOSO_ALPAKA_BACKEND=cpu # or cuda / hip
cmake --build build -j- Alpaka — checked via
find_package(alpaka); fetched if absent. - sofieBLAS — checked as a sibling checkout (
../sofieBLAS); fetched if absent.
Parts of this project were written with assistance from Claude (Anthropic), under human review and direction throughout. Every behavioral claim in this README was verified by building and running against a real installation.