Releases: aff3ct/aff3ct
Release list
AFF3CT v4.6.0 - CI/CD moved to GitHub Actions
The main change in this release is infrastructure: AFF3CT's continuous-integration and delivery pipeline has moved from GitLab CI to GitHub Actions, alongside the code and pull requests. For a simulator whose results need to be correct and reproducible, this changes how every contribution is verified.
Changes are verified before they merge
- Pull requests must pass CI to be merged. Static analysis (cppcheck, clang static analyzer, clang-format) and a cross-platform build matrix — Linux (GCC / Clang / ICPX, plus GSL and MPI variants), Windows (MSVC), and macOS (Apple Silicon + Intel) — run on every PR and are required status checks on
develop. - Regression and coverage testing on real hardware. A self-hosted runner replays the reference simulations across each code family (BCH, Convolutional, LDPC, Polar, Turbo, …) and compares the BER/FER curves against stored references, so a change that degrades decoding performance is caught. A fast profile runs on each push; a thorough profile runs weekly.
- Approval gate for external contributions. Because the regression suite runs on our own hardware, an external pull request does not execute on the self-hosted runner until a maintainer approves it. Collaborators with write access run immediately; others wait for review.
Tag-driven releases
- Documentation, the Launchpad PPA package, and binaries (Linux / Windows / macOS arm64 & x86-64) are built and validated on every branch and PR as a dry run, so packaging problems surface early.
- A real publish happens only when a
v*tag is pushed: the PPA upload, the GitHub Release, and the website download page update. This release was produced by that pipeline.
Notes for research use
Building on every supported compiler and OS, re-checking reference curves on real hardware, and accepting external contributions without manual infrastructure steps all support the reproducibility of results produced with AFF3CT and make the toolbox easier to extend.
Also in this release
- 5G NR LDPC (QC) matrices now ship with the toolbox, enabling 5G LDPC simulations out of the box.
- Windows / MSVC 2022 support, with the associated portability fixes.
- Prebuilt binaries for Linux, Windows, and macOS on both arm64 and x86-64 (SSE4.2), available from the download page.
Full changelog: v4.5.0...v4.6.0
AFF3CT - Release 4.5.0: 5G NR UL-SCH LDPC Support & Performance Benchmarks
What’s New
Changes listed bellow:
- Add support for 5G NR UL-SCH FEC (LDPC QC)
- Add optimized 5G LDPC QC encoder implementation
- Add native 5G puncturing and rate-matching compatibility
- Fix Sum-Product Algorithm (SPA) initialization for zero-valued LLRs to avoid division by zero
Performance Benchmarks: AFF3CT vs. Sionna
Nvidia’s Sionna library has recently gained significant traction within the digital communications research community. Starting with v2.0.0, it transitioned from a TensorFlow to a PyTorch backend, significantly improving framework interoperability and developer adoption. Sionna claims that "NVIDIA GPU acceleration provides orders-of-magnitude faster simulations". To verify this, we conducted a rigorous, apples-to-apples comparison focused exclusively on 5G NR UL-SCH LDPC decoding chain. This benchmark evaluates AFF3CT (CPU-optimized) against Sionna (GPU-optimized) across various frame sizes, decoding algorithms, and quantization formats.
Hardware Configuration
- CPU: AMD Ryzen 9 7945HX (AMD Zen 4 architecture, 16 cores, 75 W TDP)
- GPU: Gainward GeForce RTX 4090 Phantom GS 24 GB (Nvidia Ada Lovelace architecture, 128 SMs, 450 W TDP)
- Platform: Dalek cluster (
az4-n4090partition)
This benchmark contrasts a high-performance mobile workstation CPU (approximately 800€ for the motherboard, processor, and 16 GB dual-channel RAM) against a flagship desktop GPU (1,779–3,000€). While the cost and target markets differ significantly, this asymmetric comparison provides valuable insight into the practical trade-offs between CPU-optimized and GPU-accelerated FEC decoding across different deployment scenarios.
Software Environment
The benchmarks were executed on Ubuntu 24.04.4 LTS HWE (Linux kernel 6.17) with Nvidia driver 595.71.05 and CUDA 13.2.1. All C++ components were compiled using GCC 13.3.0. The evaluation utilizes AFF3CT v4.5.0 and Sionna v2.0.1 (PyTorch v2.12.1). AFF3CT was built with the following configuration to maximize CPU throughput and vectorization through well-spread AVX2 SIMD extension:
cmake -S . -B build -DCMAKE_BUILD_TYPE="RelWithDebInfo" -DCMAKE_CXX_FLAGS="-Wall -funroll-loops -faligned-new -mavx2 -mfma"Decoding Configuration & Measured Metrics
To ensure reproducible and stable measurements, all LDPC decoders were executed without early stopping (or syndrome checking). The following parameters and metrics were recorded in the following tables for each experiment:
- ID: Unique experiment identifier
- K: Number of information bits per frame
- Decoder: Scheduling and update rule (BP-F: Flooding schedule; BP-HL: Horizontal Layered schedule; SPA: Sum-Product Algorithm / boxplus; OMS: Offset Min-Sum approximation)
- Format: Data precision and format (f32: 32-bit floating-point; i16: 16-bit fixed-point Q10.4)
- Ite: Number of decoding iterations in the BP
- Threads: CPU thread count (AFF3CT only)
- Batch Size: Number of decoded frames in parallel. For AFF3CT, formatted as (A×B)=C, where A is the inter-frame SIMD width and B the number of CPU threads. For Sionna, this denotes frames processed per GPU kernel launch.
- Throughput: Average information throughput (accounting for K bits)
- Latency: Average decoding time per frame
- Power: Average instantaneous power draw
- Energy: Average energy consumption per frame
Power Measurement Methodology
Power was logged as a stable average during simulation execution. GPU power was captured via nvidia-smi, while CPU power was measured using RAPL (pkg-0 domain) with powerstat. RAM power was excluded as RAPL does not support the memory domain on this platform; however, estimated DDR5 SO-DIMM draw (2–6 W in dual channel) is negligible and does not affect the observed trends.
Metric Measurement & Derivation
To ensure methodological rigor, we distinguish between directly measured and derived quantities:
- Directly Measured: Average information throughput and average instantaneous power consumption are captured directly during simulation execution
- Derived Quantities: Latency and energy are computed to accurately reflect per-frame performance across different parallelization schemes:
- Latency for AFF3CT = (K × Threads) / (Throughput / inter-frame SIMD width)
- Latency for Sionna = K / (Throughput / Batch Size)
- Energy = (Power / (Throughput_Mbps / K)) / 1000 (<=> (Power / (1 / T_μs)) / 1000 <=> (Power × T_μs) / 1000 = Energy_mJ)
Running Sionna
To run Sionna in a way that closely matches the AFF3CT simulator behavior, we developed a minimalist Python script called "MiniFEC". See the minifec.py file included in the release assets. The script supports results reproducibility and enables potential corrections.
Benchmarks Philosophy
The following benchmarks evaluate decoding performance (FER) for a rate-1/2 LDPC code compliant with the 5G NR UL-SCH FEC specification. Three frame sizes are considered, spanning the full range defined in the standard—from short payloads to large transport blocks—allowing us to assess how CPU and GPU architectures scale in terms of throughput, latency, and energy efficiency across realistic deployment scenarios.
Each subsection presents FER results, followed by a summary of key performance metrics and a pie chart showing the distribution of execution time across processing tasks. While this breakdown is easily obtained in AFF3CT using the --sim-stats option, it is more challenging in Sionna, where operations are fused into PyTorch mega-kernels, making per-block analysis less straightforward.
Short Code Length - N = 40, K = 20 (BG2, N_LDPC = 40, K_LDPC = 208)
Open the detailed BER/FER plots on the AFF3CT online comparator.
| ID | K | Toolbox | Decoder | Format | Ite | Threads | Batch Size | Throughput | Latency | Power | Energy |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 20 | AFF3CT | BP-F+SPA | f32 | 20 | 1 | (1x 1)= 1 | 0.47 Mbps | 42 μs | 38 W | 1.62 mJ |
| 1 | 20 | AFF3CT | BP-F+SPA | f32 | 20 | 16 | (1x16)= 16 | 6.18 Mbps | 52 μs | 104 W | 0.33 mJ |
| 2 | 20 | AFF3CT | BP-F+OMS | f32 | 20 | 16 | (8x16)=128 | 38.96 Mbps | 66 μs | 105 W | 0.05 mJ |
| 3 | 20 | AFF3CT | BP-F+OMS | i16 | 20 | 16 | (16x16)=256 | 58.51 Mbps | 88 μs | 104 W | 0.04 mJ |
| 4 | 20 | Sionna | BP-F+SPA | f32 | 20 | - | 1 | 0.05 Mbps | 400 μs | 101 W | 40.40 mJ |
| 5 | 20 | Sionna | BP-F+SPA | f32 | 20 | - | 32768 | 194.45 Mbps | 3,370 μs | 449 W | 0.05 mJ |
| 6 | 20 | Sionna | BP-F+OMS | f32 | 20 | - | 32768 | 208.58 Mbps | 3,142 μs | 449 W | 0.04 mJ |
| 7 | 20 | AFF3CT | BP-HL+SPA | f32 | 10 | 1 | (1x 1)= 1 | 0.27 Mbps | 74 μs | 38 W | 2.81 mJ |
| 8 | 20 | AFF3CT | BP-HL+SPA | f32 | 10 | 16 | (8x16)=128 | 14.79 Mbps | 173 μs | 105 W | 0.14 mJ |
| 9 | 20 | AFF3CT | BP-HL+OMS | f32 | 10 | 16 | (8x16)=128 | 56.20 Mbps | 46 μs | 93 W | 0.03 mJ |
| 10 | 20 | AFF3CT | BP-HL+OMS | i16 | 10 | 16 | (16x16)=256 | 94.00 Mbps | 54 μs | 103 W | 0.02 mJ |
AFF3CT - Release 4.4.0
Changes listed bellow:
- Add polarization-adjusted convolutional (PAC) codes support with state-of-the-art SCL decoder (thx @Murad1997)
- Add a generic convolutional encoder (thx @zsoerenm)
- Add support of generic convolutional simulation with Viterbi and Viterbi list decoders (thx @zsoerenm and @alvalade)
- Improve the speed of the RS encoder (up to 17%) (thx @sudo-LuSer)
- Fix transform_H_to_G_identity for rank-deficient parity-check matrices (thx @zsoerenm)
- Add a new template to customize LDPC syndrome checking (useful to implement coset decoding for instance)
- Update MIPP, StreamPU and references
- New fancy theme for the documentation (Furo)
AFF3CT - Release 4.0.0
New major version.
Changes listed bellow:
- Add Viterbi+TBCC and Viterbi list decoders (for RSC codes)
- Add hard input majority vote repetition decoder
- Update from AFF3CT-core to StreamPU
- Improve CI
- Tons of small code improvements and fixes
AFF3CT - Release 3.0.2
Changes listed below:
- add
operator=method to themodule::Socketclass to simplify the binding - add an automated
create_reset_taskmethod in themodule::Moduleclass - add
get_n_input_socketsandget_n_output_socketsmethods inmodule::Task - add
tools::Interface_is_donetotools::Sequence: enable auto-stop intools::Pipeline - add
exec_stepmethod totools::Sequence: enable task by task execution - improve
tools::Sequence: new task is added to graph if all input sockets are fed - implement
get_info_bits_posmethod inmodule::Extractor_RSCclass - improve
module::Switcher: enable different type and number of elements incommuteandselecttasks - plug CWD socket to the RS decoder (to know if the decoder found a codeword)
- replace reference members by copy in modules (to simplify the binding with
py_aff3ct) - add documentation of some tasks
- fix doc requirements
- fix the LDPC BP flooding/layered decoder (inter-frame SIMD)
- fix the
puncturemethod prototype of themodule::Puncturerclass - fix AZCW simulations
- unbind adaptors when a
tools::Pipelineis destroyed (avoid bugs) - disable backtrace on Android NDK
AFF3CT - Release 3.0.1
Changes listed below:
-
add
tools::Sequenceandtools::Pipeline -
add 0-copy
module::Adaptorfor efficient tools::Pipeline implementation -
add
module::Binaryop,module::Unaryop,module::Reducer -
add
module::Switcher,module::Controllerandmodule::Iteratorto support
loops and conditional structures (if, switch, ...) -
add the
hwlocdependency for thread pinning intools::Sequenceand
tools::Pipeline -
implement clonable modules (required for automated duplication in
tools::Sequence) -
add a
statusmodule::Socketfor each task automatically -
add a priority during the binding of a
module::Socket -
add an
unbindmethod tomodule::Socket -
add BCH and LDPC decoding status
-
add FRA, BE, FE, BER and FER as output sockets for monitor BFER
-
add Multi-kernel Polar encoders and decoders
-
add
module::Extractorto extract information bits in a codeword -
add
module::Initializer,module::Incrementer,module::Sleeperand
module::Finalizer -
add
module::Probefor very precise feedback -
add
module::Sink(write end of a communication system into a file) -
add
module::Subsequenceto regroup multiple tasks in a single one -
add
tools::Interface(clone, reset, set_n_frames, is_done, set_seed, ...) -
add the C++ API doc in Sphinx (Doxygen + Breathe + Sphinx)
-
add an inter-SIMD implementation of the BCH encoder
-
add new code rates to DVB-RCS2
-
add a
set_n_framesmethod in themodule::Module,tools::Sequenceand
tools::Pipeline -
add native support of inter-frames (in the
module::Task) -
add a new socket CWD (codeword) to get the decoding status per frame
-
add the
operator[]method forstringinmodule::Module -
add scripts (based on Clang AST) to simplify the automation of AFF3CT wrappers
(Python, MATLAB) -
add auto-stop feature in
tools::Sequenceandtools::Pipeline(based on the
is_doneinterface) -
add
tools::Digraph(directed graph) -
add a new
operator=tomodule::Socket: sockets can be bound in both
directions (SIN = SOUT or SOUT = SIN) -
replace
tools::Noiseby a channel parameter (CP) socket inmodule::Channel
andmodule::Modem -
command Line Interface (CLI) has been externalized
-
split source code (
src/) in publicinclude/and privatesrc/folders -
simplify
tools::Interleaver: no need to call theinitmethod anymore -
dockerize the CI/CD
-
fix a bug in the LDPC Gallager A decoder for irregular matrices
-
fix the bug on the majority vote of the LDPC Gallager B decoder
-
fix bug en the DVB-S2 constants (thx Ben Mathews)
-
fix Galois field segmentation fault
-
speedup the LDPC Gallager E (~x2)
-
remove SystemC/TLM interfaces
-
remove EXIT chart simulations
-
remove legacy simulation (without
tools::Sequence) -
remove SIN_SOUT socket type
AFF3CT - Release 3.0.0
Changes listed below:
-
add
tools::Sequenceandtools::Pipeline -
add 0-copy
module::Adaptorfor efficient tools::Pipeline implementation -
add
module::Binaryop,module::Unaryop,module::Reducer -
add
module::Switcher,module::Controllerandmodule::Iteratorto support
loops and conditional structures (if, switch, ...) -
add the
hwlocdependency for thread pinning intools::Sequenceand
tools::Pipeline -
implement clonable modules (required for automated duplication in
tools::Sequence) -
add a
statusmodule::Socketfor each task automatically -
add a priority during the binding of a
module::Socket -
add an
unbindmethod tomodule::Socket -
add BCH and LDPC decoding status
-
add FRA, BE, FE, BER and FER as output sockets for monitor BFER
-
add Multi-kernel Polar encoders and decoders
-
add
module::Extractorto extract information bits in a codeword -
add
module::Initializer,module::Incrementer,module::Sleeperand
module::Finalizer -
add
module::Probefor very precise feedback -
add
module::Sink(write end of a communication system into a file) -
add
module::Subsequenceto regroup multiple tasks in a single one -
add
tools::Interface(clone, reset, set_n_frames, is_done, set_seed, ...) -
add the C++ API doc in Sphinx (Doxygen + Breathe + Sphinx)
-
add an inter-SIMD implementation of the BCH encoder
-
add new code rates to DVB-RCS2
-
add a
set_n_framesmethod in themodule::Module,tools::Sequenceand
tools::Pipeline -
add native support of inter-frames (in the
module::Task) -
add a new socket CWD (codeword) to get the decoding status per frame
-
add the
operator[]method forstringinmodule::Module -
add scripts (based on Clang AST) to simplify the automation of AFF3CT wrappers
(Python, MATLAB) -
add auto-stop feature in
tools::Sequenceandtools::Pipeline(based on the
is_doneinterface) -
add
tools::Digraph(directed graph) -
add a new
operator=tomodule::Socket: sockets can be bound in both
directions (SIN = SOUT or SOUT = SIN) -
replace
tools::Noiseby a channel parameter (CP) socket inmodule::Channel
andmodule::Modem -
command Line Interface (CLI) has been externalized
-
split source code (
src/) in publicinclude/and privatesrc/folders -
simplify
tools::Interleaver: no need to call theinitmethod anymore -
dockerize the CI/CD
-
fix a bug in the LDPC Gallager A decoder for irregular matrices
-
fix the bug on the majority vote of the LDPC Gallager B decoder
-
fix bug en the DVB-S2 constants (thx Ben Mathews)
-
fix Galois field segmentation fault
-
speedup the LDPC Gallager E (~x2)
-
remove SystemC/TLM interfaces
-
remove EXIT chart simulations
-
remove legacy simulation (without
tools::Sequence) -
remove SIN_SOUT socket type
AFF3CT - Release 2.3.5
Changes listed below:
- Fix link issues due to missing 'inline' keywords.
- Add a custom name to the abstract 'Module' class.
- Fix SystemC compilation error.
- Remove the outdated completion script.
AFF3CT - Release 2.3.4
Changes listed below:
- Rename PPA packages:
- 'aff3ct' becomes 'aff3ct-bin'.
- 'aff3ct-dev' has been split in 'libaff3ct' and 'libaff3ct-dev'.
- 'aff3ct-doc' stays 'aff3ct-doc'.
- Remove the automatic swap of M, N and K in the alist G and H matrices.
- Add an exception when the path to the polar best channels is wrong.
- Move versioning functions from 'aff3ct' to 'aff3ct::tools' namespace.
- Remove all the code from the '.h' and '.hpp' header files.
- Replace includes relative paths by absolute paths.
- Clean includes, remove useless ones and add others:
- speedup re-compilation time in many cases.
- allow to easily include specific headers from external project.
AFF3CT - Release 2.3.3
Changes listed below:
- Add AFF3CT PPA repositories for Debian/Ubuntu OSes:
- ppa:aff3ct/aff3ct-stable
- ppa:aff3ct/aff3ct-dev
- Doc: explain how to use AFF3CT as a library.