PolarSCLDecoder#

class sionna.phy.fec.polar.PolarSCLDecoder(frozen_pos: numpy.ndarray, n: int, list_size: int = 8, crc_degree: str | None = None, use_hybrid_sc: bool = False, use_fast_scl: bool = True, cpu_only: bool = False, use_scatter: bool = False, ind_iil_inv: numpy.ndarray | None = None, return_crc_status: bool = False, *, precision: str | None = None, device: str | None = None, **kwargs)[source]#

Bases: sionna.phy.block.Block

Successive cancellation list (SCL) decoder [Tal_SCL] for Polar codes and Polar-like codes.

Parameters:
  • frozen_pos (numpy.ndarray) – Array of int defining the n-k indices of the frozen positions.

  • n (int) – Defining the codeword length.

  • list_size (int) – Defines the list size of the decoder.

  • crc_degree (str | None) – Defining the CRC polynomial to be used. Can be any value from {CRC24A, CRC24B, CRC24C, CRC16, CRC11, CRC6}.

  • use_hybrid_sc (bool) – If True, SC decoding is applied and only the codewords with invalid CRC are decoded with SCL. This option requires an outer CRC specified via crc_degree.

  • use_fast_scl (bool) – If True, tree pruning is used to reduce the decoding complexity. The output is equivalent to the non-pruned version (besides numerical differences).

  • cpu_only (bool) – If True, a NumPy-based decoder runs on the CPU. This option is usually slower, but also more memory efficient and in particular recommended for larger blocklengths.

  • use_scatter (bool) – If True, scatter update is used for tensor updates. This option is usually slower, but more memory efficient.

  • ind_iil_inv (numpy.ndarray | None) – If not None, the sequence is used as inverse input bit interleaver before evaluating the CRC. This only affects the CRC evaluation but the output sequence is not permuted.

  • return_crc_status (bool) – If True, the decoder additionally returns the CRC status indicating if a codeword was (most likely) correctly recovered. This is only available if crc_degree is not None.

  • precision (str | None) – Precision used for internal calculations and outputs. If None, precision is used.

  • device (str | None) – Device for computation (e.g., ‘cpu’, ‘cuda:0’). If None, device is used.

Inputs:

llr_ch – […, n], torch.float. Tensor containing the channel LLR values (as logits).

Outputs:
  • b_hat – […, k], torch.float. Binary tensor containing hard-decided estimations of all k information bits.

  • crc_status – […], torch.bool. CRC status indicating if a codeword was (most likely) correctly recovered. This is only returned if return_crc_status is True. Note that false positives are possible.

Notes

This block implements the successive cancellation list (SCL) decoder as described in [Tal_SCL] but uses LLR-based message updates [Stimming_LLR]. The implementation follows the notation from [Gross_Fast_SCL], [Hashemi_SSCL]. If option use_fast_scl is active, tree pruning is used and tree nodes are combined if possible (see [Hashemi_SSCL] for details).

For longer code lengths, the complexity of the decoding graph becomes large and we recommend to use the cpu_only option that uses an embedded NumPy decoder. Further, this function recursively unrolls the SCL decoding tree, thus, for larger values of n building the decoding graph can become time consuming. Please consider the cpu_only option if building the graph takes too long.

A hybrid SC/SCL decoder as proposed in [Cammerer_Hybrid_SCL] (using SC instead of BP) can be activated with option use_hybrid_sc iff an outer CRC is available. Please note that the results are not exactly SCL performance caused by the false positive rate of the CRC.

As commonly done, we assume frozen bits are set to 0. Please note that - although its practical relevance is only little - setting frozen bits to 1 may result in affine codes instead of linear code as the all-zero codeword is not necessarily part of the code any more.

Examples

import torch
from sionna.phy.fec.polar import PolarSCLDecoder, PolarEncoder
from sionna.phy.fec.polar.utils import generate_5g_ranking

k, n = 100, 256
frozen_pos, _ = generate_5g_ranking(k, n)
encoder = PolarEncoder(frozen_pos, n)
decoder = PolarSCLDecoder(frozen_pos, n, list_size=8)

bits = torch.randint(0, 2, (10, k), dtype=torch.float32)
codewords = encoder(bits)
llr_ch = 20.0 * (2.0 * codewords - 1)  # BPSK without noise
decoded = decoder(llr_ch)
print(torch.equal(bits, decoded))
# True

Attributes

property n: int#

Codeword length.

property k: int#

Number of information bits.

property k_crc: int#

Number of CRC bits.

property frozen_pos: numpy.ndarray#

Frozen positions for Polar decoding.

property info_pos: numpy.ndarray#

Information bit positions for Polar encoding.

property llr_max: float#

Maximum LLR value for internal calculations.

property list_size: int#

List size for SCL decoding.

Methods

build(input_shape: Tuple[int, ...]) None[source]#

Build and check if shape of input is invalid.

Parameters:

input_shape (Tuple[int, ...])