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);