ldpc_toolbox/decoder/
factory.rs

1//! LDPC decoder factory.
2//!
3//! This module contains routines to build an LDPC decoder generically over
4//! different internal implementations. Such decoders are represented by
5//! `Box<dyn LdpcDecoder>`, using the trait [`LdpcDecoder`].
6
7use super::{LdpcDecoder, arithmetic::*, flooding, horizontal_layered};
8use crate::sparse::SparseMatrix;
9use clap::ValueEnum;
10use std::fmt::Display;
11
12/// Decoder factory.
13///
14/// This trait is implemented by [`DecoderImplementation`], which builds a
15/// suitable decoder depending on the value of an enum. Other factories can be
16/// implemented by the user in order to run a BER test with an LDPC decoder
17/// implemented externally to ldpc-toolbox (such decoder must be wrapped as a
18/// `Box <dyn LdpcDecoder>`).
19pub trait DecoderFactory: Display + Clone + Sync + Send + 'static {
20    /// Builds and LDPC decoder.
21    ///
22    /// Given a parity check matrix, this function builds an LDPC decoder
23    /// corresponding to this decoder implementation.
24    fn build_decoder(&self, h: SparseMatrix) -> Box<dyn LdpcDecoder>;
25}
26
27/// LDPC decoder implementation.
28///
29/// This enum lists the LDPC decoder implementations corresponding to different
30/// arithmetic rules.
31#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, ValueEnum)]
32#[clap(rename_all = "verbatim")]
33pub enum DecoderImplementation {
34    /// The [`Phif64`] implementation, using `f64` and the involution
35    /// `phi(x)`. This uses a flooding schedule.
36    Phif64,
37    /// The [`Phif32`] implementation, using `f32` and the involution
38    /// `phi(x)`. This uses a flooding schedule.
39    Phif32,
40    /// The [`Tanhf64`] implementation, using `f64` and the tanh rule. This uses
41    /// a flooding schedule.
42    Tanhf64,
43    /// The [`Tanhf32`] implementation, using `f32` and the tanh rule. This uses
44    /// a flooding schedule.
45    Tanhf32,
46    /// The [`Minstarapproxf64`] implementation, using `f64` and an
47    /// approximation to the min* function. This uses a flooding schedule.
48    Minstarapproxf64,
49    /// The [`Minstarapproxf32`] implementation, using `f32` and an
50    /// approximation to the min* function. This uses a flooding schedule.
51    Minstarapproxf32,
52    /// The [`Minstarapproxi8`] implementation, using 8-bit quantization and a
53    /// quantized approximation to the min* function (implemented using small
54    /// table lookup). This uses a flooding schedule.
55    Minstarapproxi8,
56    /// The [`Minstarapproxi8Jones`] implementation, using 8-bit quantization, a
57    /// quantized approximation to the min* function (implemented using small
58    /// table lookup), and Jones clipping for variable nodes. This uses a
59    /// flooding schedule.
60    Minstarapproxi8Jones,
61    /// The [`Minstarapproxi8PartialHardLimit`] implementation, using 8-bit
62    /// quantization, a quantized approximation to the min* function
63    /// (implemented using small table lookup), and partial hard-limiting for
64    /// check nodes. This uses a flooding schedule.
65    Minstarapproxi8PartialHardLimit,
66    /// The [`Minstarapproxi8JonesPartialHardLimit`] implementation, using 8-bit
67    /// quantization, a quantized approximation to the min* function
68    /// (implemented using small table lookup), Jones clipping for variable
69    /// nodes, and partial hard-limiting for check nodes. This uses a flooding
70    /// schedule.
71    Minstarapproxi8JonesPartialHardLimit,
72    /// The [`Minstarapproxi8Deg1Clip`] implementation, using 8-bit
73    /// quantization, a quantized approximation to the min* function
74    /// (implemented using small table lookup), and degree-1 variable node
75    /// clipping. This uses a flooding schedule.
76    Minstarapproxi8Deg1Clip,
77    /// The [`Minstarapproxi8JonesDeg1Clip`] implementation, using 8-bit
78    /// quantization, a quantized approximation to the min* function
79    /// (implemented using small table lookup), Jones clipping for variable
80    /// nodes, and degree-1 variable node clipping. This uses a flooding
81    /// schedule.
82    Minstarapproxi8JonesDeg1Clip,
83    /// The [`Minstarapproxi8PartialHardLimitDeg1Clip`] implementation, using
84    /// 8-bit quantization, a quantized approximation to the min* function
85    /// (implemented using small table lookup), partial hard-limiting for check
86    /// nodes, and degree-1 variable node clipping. This uses a flooding
87    /// schedule.
88    Minstarapproxi8PartialHardLimitDeg1Clip,
89    /// The [`Minstarapproxi8JonesPartialHardLimitDeg1Clip`] implementation,
90    /// using 8-bit quantization, a quantized approximation to the min* function
91    /// (implemented using small table lookup), Jones clipping for variable
92    /// nodes, partial hard-limiting for check nodes, and degree-1 variable node
93    /// clipping. This uses a flooding schedule.
94    Minstarapproxi8JonesPartialHardLimitDeg1Clip,
95    /// The [`Aminstarf64`] implementation, using `f64` and an approximation to
96    /// the min* function. This uses a flooding schedule.
97    Aminstarf64,
98    /// The [`Aminstarf32`] implementation, using `f32` and an approximation to
99    /// the min* function. This uses a flooding schedule.
100    Aminstarf32,
101    /// The [`Aminstari8`] implementation, using 8-bit quantization and a
102    /// quantized approximation to the min* function (implemented using small
103    /// table lookup). This uses a flooding schedule.
104    Aminstari8,
105    /// The [`Aminstari8Jones`] implementation, using 8-bit quantization, a
106    /// quantized approximation to the min* function (implemented using small
107    /// table lookup), and Jones clipping for variable nodes. This uses a
108    /// flooding schedule.
109    Aminstari8Jones,
110    /// The [`Aminstari8PartialHardLimit`] implementation, using 8-bit
111    /// quantization, a quantized approximation to the min* function
112    /// (implemented using small table lookup), and partial hard-limiting for
113    /// check nodes. This uses a flooding schedule.
114    Aminstari8PartialHardLimit,
115    /// The [`Aminstari8JonesPartialHardLimit`] implementation, using 8-bit
116    /// quantization, a quantized approximation to the min* function
117    /// (implemented using small table lookup), Jones clipping for variable
118    /// nodes, and partial hard-limiting for check nodes. This uses a flooding
119    /// schedule.
120    Aminstari8JonesPartialHardLimit,
121    /// The [`Aminstari8Deg1Clip`] implementation, using 8-bit quantization, a
122    /// quantized approximation to the min* function (implemented using small
123    /// table lookup), and degree-1 variable node clipping. This uses a flooding
124    /// schedule.
125    Aminstari8Deg1Clip,
126    /// The [`Aminstari8JonesDeg1Clip`] implementation, using 8-bit
127    /// quantization, a quantized approximation to the min* function
128    /// (implemented using small table lookup), Jones clipping for variable
129    /// nodes, and degree-1 variable node clipping. This uses a flooding
130    /// schedule.
131    Aminstari8JonesDeg1Clip,
132    /// The [`Aminstari8PartialHardLimitDeg1Clip`] implementation, using 8-bit
133    /// quantization, a quantized approximation to the min* function
134    /// (implemented using small table lookup), partial hard-limiting for check
135    /// nodes, and degree-1 variable node clipping. This uses a flooding
136    /// schedule.
137    Aminstari8PartialHardLimitDeg1Clip,
138    /// The [`Aminstari8JonesPartialHardLimitDeg1Clip`] implementation, using
139    /// 8-bit quantization, a quantized approximation to the min* function
140    /// (implemented using small table lookup), Jones clipping for variable
141    /// nodes, partial hard-limiting for check nodes, and degree-1 variable node
142    /// clipping. This uses a flooding schedule.
143    Aminstari8JonesPartialHardLimitDeg1Clip,
144    /// The [`Phif64`] implementation, using `f64` and the involution
145    /// `phi(x)`. This uses a horizontal layered schedule.
146    HLPhif64,
147    /// The [`Phif32`] implementation, using `f32` and the involution
148    /// `phi(x)`. This uses a horizontal layered schedule.
149    HLPhif32,
150    /// The [`Tanhf64`] implementation, using `f64` and the tanh rule. This uses
151    /// a horizontal layered schedule.
152    HLTanhf64,
153    /// The [`Tanhf32`] implementation, using `f32` and the tanh rule. This uses
154    /// a horizontal layered schedule.
155    HLTanhf32,
156    /// The [`Minstarapproxf64`] implementation, using `f64` and an
157    /// approximation to the min* function. This uses a horizontal layered
158    /// schedule.
159    HLMinstarapproxf64,
160    /// The [`Minstarapproxf32`] implementation, using `f32` and an
161    /// approximation to the min* function. This uses a horizontal layered
162    /// schedule.
163    HLMinstarapproxf32,
164    /// The [`Minstarapproxi8`] implementation, using 8-bit quantization and a
165    /// quantized approximation to the min* function (implemented using small
166    /// table lookup). This uses a horizontal layered schedule.
167    HLMinstarapproxi8,
168    /// The [`Minstarapproxi8PartialHardLimit`] implementation, using 8-bit
169    /// quantization, a quantized approximation to the min* function
170    /// (implemented using small table lookup), and partial hard-limiting for
171    /// check nodes. This uses a horizontal layered schedule.
172    HLMinstarapproxi8PartialHardLimit,
173    /// The [`Aminstarf64`] implementation, using `f64` and an approximation to
174    /// the min* function. This uses a horizontal layered schedule.
175    HLAminstarf64,
176    /// The [`Aminstarf32`] implementation, using `f32` and an approximation to
177    /// the min* function. This uses a horizontal layered schedule.
178    HLAminstarf32,
179    /// The [`Aminstari8`] implementation, using 8-bit quantization and a
180    /// quantized approximation to the min* function (implemented using small
181    /// table lookup). This uses a horizontal layered schedule.
182    HLAminstari8,
183    /// The [`Aminstari8PartialHardLimit`] implementation, using 8-bit
184    /// quantization, a quantized approximation to the min* function
185    /// (implemented using small table lookup), and partial hard-limiting for
186    /// check nodes. This uses a horizontal layered schedule.
187    HLAminstari8PartialHardLimit,
188}
189
190macro_rules! new_decoder {
191    (flooding, $arith:ty, $h:expr) => {
192        flooding::Decoder::new($h, <$arith>::new())
193    };
194    (horizontal_layered, $arith:ty, $h:expr) => {
195        horizontal_layered::Decoder::new($h, <$arith>::new())
196    };
197}
198
199macro_rules! impl_decoderimplementation {
200    ($($var:path, $arith:ty, $decoder:tt, $text:expr);+;) => {
201        impl DecoderFactory for DecoderImplementation {
202            fn build_decoder(&self, h: SparseMatrix) -> Box<dyn LdpcDecoder> {
203                match self {
204                    $(
205                        $var => Box::new(new_decoder!($decoder, $arith, h)),
206                    )+
207                }
208            }
209        }
210
211        impl std::str::FromStr for DecoderImplementation {
212            type Err = &'static str;
213
214            fn from_str(s: &str) -> Result<Self, Self::Err> {
215                Ok(match s {
216                    $(
217                        $text => $var,
218                    )+
219                    _ => return Err("invalid decoder implementation"),
220                })
221            }
222        }
223
224        impl Display for DecoderImplementation {
225            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
226                write!(
227                    f,
228                    "{}",
229                    match self {
230                        $(
231                            $var => $text,
232                        )+
233                    }
234                )
235            }
236        }
237    }
238}
239
240impl_decoderimplementation!(
241    DecoderImplementation::Phif64, Phif64, flooding, "Phif64";
242    DecoderImplementation::Phif32, Phif32, flooding, "Phif32";
243    DecoderImplementation::Tanhf64, Tanhf64, flooding, "Tanhf64";
244    DecoderImplementation::Tanhf32, Tanhf32, flooding, "Tanhf32";
245    DecoderImplementation::Minstarapproxf64, Minstarapproxf64, flooding, "Minstarapproxf64";
246    DecoderImplementation::Minstarapproxf32, Minstarapproxf32, flooding, "Minstarapproxf32";
247    DecoderImplementation::Minstarapproxi8, Minstarapproxi8, flooding, "Minstarapproxi8";
248    DecoderImplementation::Minstarapproxi8Jones, Minstarapproxi8Jones, flooding, "Minstarapproxi8Jones";
249    DecoderImplementation::Minstarapproxi8PartialHardLimit, Minstarapproxi8PartialHardLimit, flooding, "Minstarapproxi8PartialHardLimit";
250    DecoderImplementation::Minstarapproxi8JonesPartialHardLimit, Minstarapproxi8JonesPartialHardLimit, flooding, "Minstarapproxi8JonesPartialHardLimit";
251    DecoderImplementation::Minstarapproxi8Deg1Clip, Minstarapproxi8Deg1Clip, flooding, "Minstarapproxi8Deg1Clip";
252    DecoderImplementation::Minstarapproxi8JonesDeg1Clip, Minstarapproxi8JonesDeg1Clip, flooding, "Minstarapproxi8JonesDeg1Clip";
253    DecoderImplementation::Minstarapproxi8PartialHardLimitDeg1Clip, Minstarapproxi8PartialHardLimitDeg1Clip, flooding, "Minstarapproxi8PartialHardLimitDeg1Clip";
254    DecoderImplementation::Minstarapproxi8JonesPartialHardLimitDeg1Clip, Minstarapproxi8JonesPartialHardLimitDeg1Clip, flooding, "Minstarapproxi8JonesPartialHardLimitDeg1Clip";
255    DecoderImplementation::Aminstarf64, Aminstarf64, flooding, "Aminstarf64";
256    DecoderImplementation::Aminstarf32, Aminstarf32, flooding, "Aminstarf32";
257    DecoderImplementation::Aminstari8, Aminstari8, flooding, "Aminstari8";
258    DecoderImplementation::Aminstari8Jones, Aminstari8Jones, flooding, "Aminstari8Jones";
259    DecoderImplementation::Aminstari8PartialHardLimit, Aminstari8PartialHardLimit, flooding, "Aminstari8PartialHardLimit";
260    DecoderImplementation::Aminstari8JonesPartialHardLimit, Aminstari8JonesPartialHardLimit, flooding, "Aminstari8JonesPartialHardLimit";
261    DecoderImplementation::Aminstari8Deg1Clip, Aminstari8Deg1Clip, flooding, "Aminstari8Deg1Clip";
262    DecoderImplementation::Aminstari8JonesDeg1Clip, Aminstari8JonesDeg1Clip, flooding, "Aminstari8JonesDeg1Clip";
263    DecoderImplementation::Aminstari8PartialHardLimitDeg1Clip, Aminstari8PartialHardLimitDeg1Clip, flooding, "Aminstari8PartialHardLimitDeg1Clip";
264    DecoderImplementation::Aminstari8JonesPartialHardLimitDeg1Clip, Aminstari8JonesPartialHardLimitDeg1Clip, flooding, "Aminstari8JonesPartialHardLimitDeg1Clip";
265    DecoderImplementation::HLPhif64, Phif64, horizontal_layered, "HLPhif64";
266    DecoderImplementation::HLPhif32, Phif32, horizontal_layered, "HLPhif32";
267    DecoderImplementation::HLTanhf64, Tanhf64, horizontal_layered, "HLTanhf64";
268    DecoderImplementation::HLTanhf32, Tanhf32, horizontal_layered, "HLTanhf32";
269    DecoderImplementation::HLMinstarapproxf64, Minstarapproxf64, horizontal_layered, "HLMinstarapproxf64";
270    DecoderImplementation::HLMinstarapproxf32, Minstarapproxf32, horizontal_layered, "HLMinstarapproxf32";
271    DecoderImplementation::HLMinstarapproxi8, Minstarapproxi8, horizontal_layered, "HLMinstarapproxi8";
272    DecoderImplementation::HLMinstarapproxi8PartialHardLimit, Minstarapproxi8PartialHardLimit, horizontal_layered, "HLMinstarapproxi8PartialHardLimit";
273    DecoderImplementation::HLAminstarf64, Aminstarf64, horizontal_layered, "HLAminstarf64";
274    DecoderImplementation::HLAminstarf32, Aminstarf32, horizontal_layered, "HLAminstarf32";
275    DecoderImplementation::HLAminstari8, Aminstari8, horizontal_layered, "HLAminstari8";
276    DecoderImplementation::HLAminstari8PartialHardLimit, Aminstari8PartialHardLimit, horizontal_layered, "HLAminstari8PartialHardLimit";
277);