LDPC#

Low-Density Parity-Check (LDPC) coding modules for 5G NR channel decoding.

Overview#

The LDPC library provides GPU-accelerated modules for 5G NR LDPC channel decoding, implementing the 3GPP TS 38.212 specification. Built on highly optimized cuPHY LDPC CUDA kernels, these modules deliver efficient runtime performance on NVIDIA GPUs. The library consists of three pipeline modules that work together to decode received data:

  • LDPC Derate Matching: Reverses rate matching to produce LLRs suitable for LDPC decoding

  • LDPC Decoder: Performs LDPC decoding on Log-Likelihood Ratios (LLRs)

  • CRC Decoder: Validates CRC checksums and concatenates code blocks into transport blocks

Each module implements the pipeline::IModule interface from the pipeline library, enabling integration into larger processing pipelines with standardized configuration, memory management, and execution patterns.

Core Concepts#

Module Configuration#

All LDPC modules are configured with static parameters at construction time. These parameters define maximum capacities and processing modes.

Creating an LDPC Decoder#

// Configure LDPC decoder with static parameters
const ran::ldpc::LdpcDecoderModule::StaticParams decoder_params{
        .clamp_value = 20.0F,
        .max_num_iterations = 20,
        .max_num_cbs_per_tb = 152,
        .max_num_tbs = 1,
        .normalization_factor = 0.125F,
        .max_iterations_method = ran::ldpc::LdpcMaxIterationsMethod::Fixed,
        .max_num_ldpc_het_configs = ran::ldpc::LDPC_MAX_HET_CONFIGS};

// Create decoder module instance
const auto decoder =
        std::make_unique<ran::ldpc::LdpcDecoderModule>("ldpc_decoder", decoder_params);

Creating a Derate Match Module#

// Configure LDPC derate matching module
const ran::ldpc::LdpcDerateMatchModule::StaticParams derate_params{
        .enable_scrambling = true,
        .max_num_tbs = 1,
        .max_num_cbs_per_tb = 152,
        .max_num_rm_llrs_per_cb = 27000,
        .max_num_ue_grps = 1};

// Create derate matching module
const auto derate_match =
        std::make_unique<ran::ldpc::LdpcDerateMatchModule>("ldpc_derate_match", derate_params);

Creating a CRC Decoder#

// Configure CRC decoder module
const ran::ldpc::CrcDecoderModule::StaticParams crc_params{
        .reverse_bytes = true, .max_num_cbs_per_tb = 152, .max_num_tbs = 1};

// Create CRC decoder module
const auto crc_decoder =
        std::make_unique<ran::ldpc::CrcDecoderModule>("crc_decoder", crc_params);

LDPC Decoder Parameters#

// Configure decoder with custom parameters
const ran::ldpc::LdpcDecoderModule::StaticParams custom_params{
        .clamp_value = 15.0F,          // Custom LLR clamping value
        .max_num_iterations = 10,      // Reduce max iterations for performance
        .max_num_cbs_per_tb = 100,     // Maximum code blocks per transport block
        .max_num_tbs = 4,              // Support multiple transport blocks
        .normalization_factor = 0.15F, // Custom normalization
        .max_iterations_method = ran::ldpc::LdpcMaxIterationsMethod::Fixed,
        .max_num_ldpc_het_configs = ran::ldpc::LDPC_MAX_HET_CONFIGS};

const auto decoder =
        std::make_unique<ran::ldpc::LdpcDecoderModule>("custom_decoder", custom_params);

Key parameters include:

  • clamp_value: Maximum absolute value for input LLRs

  • early_termination: Stop decoding when convergence is detected

  • max_num_iterations: Maximum decoder iterations per code block

  • normalization_factor: LLR normalization applied during decoding

Module Ports#

Each module exposes input and output ports for data flow:

const ran::ldpc::LdpcDecoderModule::StaticParams params{
        .clamp_value = 20.0F,
        .max_num_iterations = 20,
        .max_num_cbs_per_tb = 152,
        .max_num_tbs = 1,
        .normalization_factor = 0.125F,
        .max_iterations_method = ran::ldpc::LdpcMaxIterationsMethod::Fixed,
        .max_num_ldpc_het_configs = ran::ldpc::LDPC_MAX_HET_CONFIGS};

const auto decoder = std::make_unique<ran::ldpc::LdpcDecoderModule>("decoder", params);

// Query module input and output ports
const auto input_ports = decoder->get_input_port_names();
const auto output_ports = decoder->get_output_port_names();

CRC Decoder Ports#

The CRC decoder processes decoded bits and outputs CRC results for both code blocks and transport blocks:

const ran::ldpc::CrcDecoderModule::StaticParams params{
        .reverse_bytes = true, .max_num_cbs_per_tb = 152, .max_num_tbs = 1};

const auto crc = std::make_unique<ran::ldpc::CrcDecoderModule>("crc", params);

// CRC decoder has one input port for decoded bits
const auto inputs = crc->get_input_port_names();

// CRC decoder has three output ports
const auto outputs = crc->get_output_port_names();

The CRC decoder takes decoded bits as input and produces three outputs: code block CRCs, transport block CRCs, and transport block payloads after CRC validation and concatenation.

Memory Management#

Modules report memory requirements that must be allocated before use:

const ran::ldpc::LdpcDerateMatchModule::StaticParams params{
        .enable_scrambling = true,
        .max_num_tbs = 1,
        .max_num_cbs_per_tb = 152,
        .max_num_rm_llrs_per_cb = 27000,
        .max_num_ue_grps = 1};

const auto module = std::make_unique<ran::ldpc::LdpcDerateMatchModule>("derate_match", params);

// Query memory requirements before allocation
const auto requirements = module->get_requirements();

Processing Flow#

A typical LDPC decoding flow involves three stages:

  1. Derate Matching: Converts received symbols to LLRs for LDPC decoding

  2. LDPC Decoding: Decodes LLRs to produce hard-decision bits

  3. CRC Validation: Checks CRC and assembles transport blocks

Each stage is configured with dynamic parameters (transport block configuration) via the configure_io() method and executed via execute() or integrated into a CUDA graph.

Execution Modes#

Modules support two execution modes:

  • Stream Execution: Direct kernel launch via IStreamExecutor::execute()

  • CUDA Graph Execution: Graph node creation via IGraphNodeProvider::add_node_to_graph()

CUDA graph mode enables lower-latency operation via execution graphs.

Stream Execution#

Stream execution provides direct kernel launching on a CUDA stream. After setting inputs, configure the module and execute:

// Configure I/O with dynamic parameters
ldpc_module.configure_io(params, stream.get());

// Execute based on mode
if (execution_mode == pipeline::ExecutionMode::Stream) {
    // Stream mode: Execute directly
    RT_LOG_DEBUG("Executing LDPC decoder module in stream mode");
    ldpc_module.execute(stream.get());
} else {
    // Graph mode: Create graph, add node, instantiate, and launch
    auto graph_manager = std::make_unique<pipeline::GraphManager>();

    graph_node_provider = ldpc_module.as_graph_node_provider();

    // Add module node to graph with no dependencies
    const std::vector<CUgraphNode> no_deps{};
    nodes = graph_manager->add_kernel_node(
            gsl_lite::not_null<pipeline::IGraphNodeProvider *>(graph_node_provider), no_deps);

    // Instantiate and upload graph
    graph_manager->instantiate_graph();
    graph_manager->upload_graph(stream.get());

    // Update graph node parameters
    auto *const exec = graph_manager->get_exec();
    graph_node_provider->update_graph_node_params(exec, params);

    // Launch graph
    RT_LOG_DEBUG("Executing LDPC decoder module in graph mode");
    graph_manager->launch_graph(stream.get());
}

The configure_io() method sets up internal state based on transport block parameters, then execute() launches the kernel on the provided stream.

CUDA Graph Execution#

Modules implementing IGraphNodeProvider can be integrated into CUDA graphs for lower-latency execution. First, create a graph manager and get the module’s graph interface:

// Graph mode: Create graph manager and get module's graph interface
auto graph_manager = std::make_unique<pipeline::GraphManager>();

auto *graph_node_provider = ldpc_module.as_graph_node_provider();

Next, add the module’s kernel node to the graph:

// Add module node(s) to graph with no dependencies
const std::vector<CUgraphNode> no_deps{};
const auto nodes = graph_manager->add_kernel_node(
        gsl_lite::not_null<pipeline::IGraphNodeProvider *>(graph_node_provider), no_deps);

Finally, instantiate the graph, upload it to the GPU, update parameters, and launch:

// Instantiate and upload graph
graph_manager->instantiate_graph();
graph_manager->upload_graph(stream.get());

// Update graph node parameters
auto *const exec = graph_manager->get_exec();
graph_node_provider->update_graph_node_params(exec, params);

// Launch graph
RT_LOG_DEBUG("Executing LDPC derate match module in graph mode");
graph_manager->launch_graph(stream.get());

The graph is instantiated once and can be launched repeatedly with updated parameters. This approach minimizes kernel launch overhead for repeated operations.

Additional Examples#

For complete working examples with full setup and validation, see the test files:

  • LDPC Decoder Tests: ran/runtime/ldpc/tests/ldpc_decoder_module_test.cpp - Full decoder module tests with H5 test vectors

  • Derate Match Tests: ran/runtime/ldpc/tests/ldpc_derate_match_module_test.cpp - Stream and graph execution modes

  • CRC Decoder Tests: ran/runtime/ldpc/tests/crc_decoder_module_test.cpp - CRC validation and transport block assembly

These test files demonstrate complete workflows including memory allocation, input/output setup, and result validation.

API Reference#

enum class ran::ldpc::ModulationOrder : std::uint32_t#

Modulation order enumeration for type-safe modulation scheme specification

Values:

enumerator Qpsk#

QPSK modulation (2 bits per symbol)

enumerator Qam16#

16-QAM modulation (4 bits per symbol)

enumerator Qam64#

64-QAM modulation (6 bits per symbol)

enumerator Qam256#

256-QAM modulation (8 bits per symbol)

enum class ran::ldpc::NewDataIndicator : std::uint32_t#

New Data Indicator enumeration for type-safe transmission type specification

Values:

enumerator Retransmission#

Retransmission of previous data.

enumerator NewTransmission#

New data transmission.

enum class ran::ldpc::LdpcMaxIterationsMethod : std::uint8_t#

Method for determining maximum LDPC decoding iterations

Values:

enumerator Fixed#

Use fixed max_num_iterations value.

enumerator Lut#

Use lookup table based on spectral efficiency.

constexpr float ran::ldpc::LDPC_CLAMP_VALUE = 32.0F#

Clamp value for LLRs.

constexpr std::size_t ran::ldpc::LDPC_MAX_ITERATIONS = 10#

Maximum number of LDPC decoding iterations.

constexpr float ran::ldpc::LDPC_NORMALIZATION_FACTOR = 0.8125F#

Normalization factor.

constexpr std::size_t ran::ldpc::LDPC_MAX_HET_CONFIGS = 32#

Maximum number of heterogeneous LDPC configurations.

constexpr std::size_t ran::ldpc::MAX_NUM_RM_LLRS_PER_CB = 26112#

Maximum number of rate matching LLRs per CB.

static constexpr int ran::ldpc::BITS_PER_BYTE = 8#
ran::ldpc::DECLARE_LOG_COMPONENT(
LdpcComponent,
LdpcParams,
OuterRxParams,
DerateMatch,
LdpcDecoder,
CrcDecoder,
LdpcDecoderModuleFactory,
LdpcDerateMatchModuleFactory,
CrcDecoderModuleFactory,
)#

Declare logging components for LDPC subsystem

inline std::uint32_t ran::ldpc::get_scrambling_init(
std::uint32_t rnti,
std::uint32_t data_scram_id,
)#

Get the scrambling initialization value for a given RNTI and data scrambling ID.

The scrambling initialization value is calculated per 3GPP TS 38.211 Section 6.3.1.1: c_init = n_RNTI * 2^15 + n_ID

Where:

  • n_RNTI is the Radio Network Temporary Identifier

  • n_ID is the data scrambling identity (data_scram_id)

  • 2^15 = 32768 is the shift value defined in the specification

The scrambling sequence generator uses a length-31 Gold sequence with initialization value c_init.

See also

3GPP TS 38.211 Section 6.3.1.1 (Scrambling)

See also

3GPP TS 38.211 Section 5.2.1 (Pseudo-random sequence generation)

Parameters:
  • rnti[in] Radio Network Temporary Identifier (n_RNTI)

  • data_scram_id[in] Data scrambling ID (n_ID)

Returns:

Scrambling initialization value (c_init)

inline std::uint32_t ran::ldpc::get_rate_matching_length(
std::uint16_t num_prbs,
std::uint8_t num_layers,
ModulationOrder mod_order,
std::uint8_t num_symbols,
std::uint8_t num_dmrs_cdm_grps_no_data,
std::uint16_t dmrs_sym_loc_bmsk,
)#

Get the rate matching length for a given number of PRBs, layers, modulation order, number of symbols, number of DMRS CDM groups without data, and DMRS symbol location bitmask.

See also

3GPP TS 38.214 Section 6.1.4.2.

Parameters:
  • num_prbs[in] Number of allocated PRBs.

  • num_layers[in] Number of layers allocated for the UE.

  • mod_order[in] Modulation order.

  • num_symbols[in] Number of symbols allocated for the transmission.

  • num_dmrs_cdm_grps_no_data[in] Number of DMRS CDM groups without data.

  • dmrs_sym_loc_bmsk[in] DMRS symbol location bitmask in SCF FAPI format, 0 = no DMRS, 1 = DMRS.

Throws:

std::invalid_argument – if num_prbs is 0.

Returns:

Rate matching length

class CrcDecoderModule : public framework::pipeline::IModule, public framework::pipeline::IAllocationInfoProvider, public framework::pipeline::IStreamExecutor, public framework::pipeline::IGraphNodeProvider#
#include <crc_decoder_module.hpp>

CRC decoder module implementing IModule interface.

This module provides CRC (Cyclic Redundancy Check) decoding functionality by wrapping existing cuPHY CRC capabilities. It decodes the CRC of the code blocks and transport blocks and concatenates code blocks into transport blocks.

Public Functions

explicit CrcDecoderModule(
std::string instance_id,
const std::any &init_params,
)#

Constructor.

Parameters:
  • instance_id – The instance identifier for this module

  • init_params – Initialization parameters for module configuration

Throws:
  • std::invalid_argument – if initialization parameters are invalid

  • std::runtime_error – if CRC decode object cannot be created

~CrcDecoderModule() override#

Destructor.

CrcDecoderModule(const CrcDecoderModule&) = delete#

Copy constructor (deleted)

CrcDecoderModule manages CUDA resources and pipeline state that cannot be safely copied. Each module instance must have unique identity and resource ownership.

CrcDecoderModule(CrcDecoderModule&&) = delete#

Move constructor (deleted)

CrcDecoderModule &operator=(const CrcDecoderModule&) = delete#

Copy assignment operator (deleted)

CrcDecoderModule &operator=(CrcDecoderModule&&) = delete#

Move assignment operator (deleted)

inline virtual std::string_view get_type_id() const override#

Get the type identifier

Returns:

The type ID as a string_view

virtual std::string_view get_instance_id() const override#

Get the instance identifier

Returns:

The instance ID as a string_view

virtual void setup_memory(
const framework::pipeline::ModuleMemorySlice &memory_slice,
) override#

Perform one-time setup after memory allocation.

Parameters:

memory_slice – Memory slice allocated by PipelineMemoryManager

virtual std::vector<framework::tensor::TensorInfo> get_input_tensor_info(
std::string_view port_name,
) const override#

Get the input tensor information for a given port name.

Parameters:

port_name – The name of the port to get the tensor information for

Throws:

std::invalid_argument – if the port name is invalid

Returns:

Vector of tensor information for all tensors on this port

virtual std::vector<framework::tensor::TensorInfo> get_output_tensor_info(
std::string_view port_name,
) const override#

Get the output tensor information for a given port name.

Parameters:

port_name – The name of the port to get the tensor information for

Throws:

std::invalid_argument – if the port name is invalid

Returns:

Vector of tensor information for all tensors on this port

virtual std::vector<std::string> get_input_port_names(
) const override#

Get the names of all input ports

Returns:

A vector containing input port names

virtual std::vector<std::string> get_output_port_names(
) const override#

Get the names of all output ports

Returns:

A vector containing output port names

virtual void set_inputs(
std::span<const framework::pipeline::PortInfo> inputs,
) override#

Set the inputs for the module.

Parameters:

inputs – Span of port information with device pointers to input data

Throws:

std::invalid_argument – if required inputs are missing or port information doesn’t match with expected inputs

virtual std::vector<framework::pipeline::PortInfo> get_outputs(
) const override#

Get the output port information.

Note

Device pointers are only valid after configure_io() has been called

Throws:

std::runtime_error – if the module inputs/outputs are not configured

Returns:

Vector of port information for all outputs

virtual void configure_io(
const framework::pipeline::DynamicParams &params,
cudaStream_t stream,
) override#

Configure I/O for the current iteration.

Sets up module output tensor information and device pointers, and sets up the cuPHY CRC decode object.

Parameters:
  • params[in] Dynamic parameters for the current iteration

  • stream[in] CUDA stream for async operations during configuration

Throws:
  • std::invalid_argument – if the dynamic parameters are invalid

  • std::runtime_error – if the module is not setup

inline virtual framework::pipeline::IGraphNodeProvider *as_graph_node_provider(
) override#

Return the graph node provider for this module.

Returns:

The graph node provider

inline virtual framework::pipeline::IStreamExecutor *as_stream_executor(
) override#

Return the stream executor for this module.

Returns:

The stream executor

virtual void execute(cudaStream_t stream) override#

Execute the module on the given stream.

Note

All dynamic descriptors must have been copied to device before execution.

Parameters:

stream – The stream to execute the module on

virtual framework::pipeline::ModuleMemoryRequirements get_requirements(
) const override#

Get the memory requirements for the module.

Throws:

std::runtime_error – if failed to get workspace size for CRC check

Returns:

The memory requirements

virtual std::span<const CUgraphNode> add_node_to_graph(
gsl_lite::not_null<framework::pipeline::IGraph*> graph,
const std::span<const CUgraphNode> deps,
) override#

Add node(s) to the graph.

Parameters:
  • graph[in] The graph to add the node(s) to

  • deps[in] The dependencies of the node(s)

Throws:

std::runtime_error – if CUDA graph node creation fails

Returns:

Span of created graph node handles (returns both CRC decode nodes)

virtual void update_graph_node_params(
CUgraphExec exec,
const framework::pipeline::DynamicParams &params,
) override#

Update graph node parameters for dynamic tick changes.

This method enables dynamic updates to kernel launch parameters using cuGraphExecKernelNodeSetParams. Modules can extract their specific parameters from params.module_specific_params and update their graph nodes accordingly (e.g., changing grid dimensions, shared memory size).

Parameters:
  • exec – The executable graph to update

  • params – Dynamic parameters containing module-specific parameters

Throws:

std::runtime_error – if cuGraphExecKernelNodeSetParams fails

struct StaticParams#
#include <crc_decoder_module.hpp>

Configuration parameters for CRC decoder module.

Public Members

bool reverse_bytes = {true}#

Reverse bytes in each word before computing the CRC.

std::size_t max_num_cbs_per_tb = {ran::common::MAX_NUM_CBS_PER_TB}#

Maximum number of code blocks per transport block

std::size_t max_num_tbs = {ran::common::MAX_NUM_TBS}#

Maximum number of transport blocks.

class CrcDecoderModuleFactory : public framework::pipeline::IModuleFactory#
#include <ldpc_module_factories.hpp>

Factory for creating CrcDecoderModule instances

Supports module type: “crc_decoder_module” Accepts CrcDecoderModule::StaticParams via std::any in create_module()

Public Functions

CrcDecoderModuleFactory() = default#

Default constructor

~CrcDecoderModuleFactory() override = default#

Destructor

CrcDecoderModuleFactory(const CrcDecoderModuleFactory&) = delete#
CrcDecoderModuleFactory &operator=(
const CrcDecoderModuleFactory&,
) = delete#
CrcDecoderModuleFactory(CrcDecoderModuleFactory &&other) = default#

Move constructor

Parameters:

other[inout] Source factory to move from

CrcDecoderModuleFactory &operator=(
CrcDecoderModuleFactory &&other,
) = default#

Move assignment operator

Parameters:

other[inout] Source factory to move from

Returns:

Reference to this object

virtual std::unique_ptr<framework::pipeline::IModule> create_module(
std::string_view module_type,
const std::string &instance_id,
const std::any &static_params,
) override#

Create a CrcDecoderModule instance

Parameters:
  • module_type[in] The type of module to create (must be “crc_decoder_module”)

  • instance_id[in] Unique identifier for this module instance

  • static_params[in] Type-erased CrcDecoderModule::StaticParams

Throws:
  • std::invalid_argument – if module_type is not “crc_decoder_module”

  • std::bad_any_cast – if static_params type doesn’t match

Returns:

Unique pointer to the created module

virtual bool supports_module_type(
std::string_view module_type,
) const override#

Check if a module type is supported

Parameters:

module_type[in] The type of module to check

Returns:

true if module_type is “crc_decoder_module”, false otherwise

struct DerateMatchParams#
#include <derate_match_params.hpp>

Configuration parameters for rate matching

Contains all additional parameters for rate matching.

Note

LDPC parameters are needed too by the derate matcher.

Public Members

ModulationOrder mod_order = {ModulationOrder::Qpsk}#

Modulation order.

std::uint8_t n_dmrs_cdm_grps_no_data = {}#

Number of DMRS CDM groups without data.

NewDataIndicator ndi = {NewDataIndicator::NewTransmission}#

New data indicator.

std::uint32_t num_layers = {1}#

Number of transmission layers.

std::uint32_t user_group_idx = {}#

User group index for multi-user scenarios.

std::uint32_t num_ue_grp_layers = {1}#

Number of layers for UE group.

std::vector<std::uint32_t> layer_map = {0}#

Layer mapping vector.

std::uint32_t scrambling_init = {}#

Scrambling initialization value.

class LdpcDecoderModule : public framework::pipeline::IModule, public framework::pipeline::IAllocationInfoProvider, public framework::pipeline::IStreamExecutor, public framework::pipeline::IGraphNodeProvider#
#include <ldpc_decoder_module.hpp>

LDPC decoder module implementing IModule interface.

This module performs LDPC decoding on received LLRs (Log-Likelihood Ratios) and outputs decoded bits.

Public Functions

explicit LdpcDecoderModule(
std::string instance_id,
const std::any &init_params,
)#

Constructor.

Parameters:
  • instance_id – The instance identifier for this module

  • init_params – Initialization parameters for module configuration

Throws:

std::invalid_argument – if initialization parameters are invalid

inline virtual std::string_view get_type_id() const override#

Get the type identifier

Returns:

The type ID as a string_view

virtual std::string_view get_instance_id() const override#

Get the instance identifier

Returns:

The instance ID as a string_view

virtual void setup_memory(
const framework::pipeline::ModuleMemorySlice &memory_slice,
) override#

Perform one-time setup after memory allocation.

Parameters:

memory_slice – Memory slice allocated by PipelineMemoryManager

virtual std::vector<framework::tensor::TensorInfo> get_input_tensor_info(
std::string_view port_name,
) const override#

Get the input tensor information for a given port name.

Parameters:

port_name – The name of the port to get the tensor information for

Throws:

std::invalid_argument – if the port name is invalid or port info not found

Returns:

Vector of tensor information for all tensors on this port

virtual std::vector<framework::tensor::TensorInfo> get_output_tensor_info(
std::string_view port_name,
) const override#

Get the output tensor information for a given port name.

Parameters:

port_name – The name of the port to get the tensor information for

Throws:
  • std::invalid_argument – if the port name is invalid or port info not found

  • std::runtime_error – if called before setup completion

Returns:

Vector of tensor information for all tensors on this port

virtual std::vector<std::string> get_input_port_names(
) const override#

Get the names of all input ports

Returns:

A vector containing “llrs”

virtual std::vector<std::string> get_output_port_names(
) const override#

Get the names of all output ports

Returns:

A vector containing “decoded_bits”

virtual void set_inputs(
std::span<const framework::pipeline::PortInfo> inputs,
) override#

Set the inputs for the module.

Parameters:

inputs – Span of port information with device pointers to input data

Throws:

std::invalid_argument – if required inputs are missing or port names don’t match expected inputs

virtual std::vector<framework::pipeline::PortInfo> get_outputs(
) const override#

Get the output port information.

Note

Device pointers are only valid after configure_io() has been called

Throws:

std::runtime_error – if called before configure_io() has been called

Returns:

Vector of port information for all outputs

virtual void configure_io(
const framework::pipeline::DynamicParams &params,
cudaStream_t stream,
) override#

Configure I/O for the current iteration.

Parameters:
  • params[in] Dynamic parameters for the current iteration

  • stream[in] CUDA stream for async operations during configuration

Throws:

std::invalid_argument – if the dynamic parameters are invalid

inline virtual framework::pipeline::IGraphNodeProvider *as_graph_node_provider(
) override#

Return the graph node provider for this module.

Returns:

The graph node provider

inline virtual framework::pipeline::IStreamExecutor *as_stream_executor(
) override#

Return the stream executor for this module.

Returns:

The stream executor

virtual void execute(cudaStream_t stream) override#

Execute the module on the given stream.

Parameters:

stream – The stream to execute the module on

Throws:
  • std::runtime_error – if called before configure_io() has been called

  • std::runtime_error – if outer_rx parameters are not set

virtual std::span<const CUgraphNode> add_node_to_graph(
gsl_lite::not_null<framework::pipeline::IGraph*> graph,
std::span<const CUgraphNode> deps,
) override#

Add LDPC decoder nodes to CUDA graph

Creates kernel nodes for all LDPC descriptor batches and adds them to the graph. Each descriptor batch becomes a separate kernel node in the graph.

Parameters:
  • graph[in] Graph interface for node creation

  • deps[in] Dependency nodes that must complete before LDPC decoder nodes execute

Throws:

std::runtime_error – if configure_io() was not called before add_node_to_graph()

Returns:

Span of created graph node handles (all LDPC decoder nodes)

virtual void update_graph_node_params(
CUgraphExec exec,
const framework::pipeline::DynamicParams &params,
) override#

Update graph node parameters for dynamic iteration changes

Updates kernel launch parameters in the executable graph. This is called when the dynamic parameters change between iterations.

Parameters:
  • exec[in] Graph executable to update

  • params[in] Dynamic parameters containing updated LDPC configurations

Throws:

std::runtime_error – if cuGraphExecKernelNodeSetParams fails

virtual framework::pipeline::ModuleMemoryRequirements get_requirements(
) const override#

Get the memory requirements for the module.

Returns:

The memory requirements

struct StaticParams#
#include <ldpc_decoder_module.hpp>

Configuration (static)parameters for LDPC decoder module.

Public Members

float clamp_value = {LDPC_CLAMP_VALUE}#

Clamp value for LLRs.

std::size_t max_num_iterations = {LDPC_MAX_ITERATIONS}#

Maximum number of decoding iterations (used when max_iterations_method is Fixed)

std::size_t max_num_cbs_per_tb = {ran::common::MAX_NUM_CBS_PER_TB}#

Maximum number of code blocks per transport block

std::size_t max_num_tbs = {ran::common::MAX_NUM_TBS}#

Maximum number of transport blocks.

float normalization_factor = {LDPC_NORMALIZATION_FACTOR}#

Normalization factor for LLRs.

LdpcMaxIterationsMethod max_iterations_method = {LdpcMaxIterationsMethod::Fixed}#

Method for determining max iterations.

std::size_t max_num_ldpc_het_configs = {LDPC_MAX_HET_CONFIGS}#

Maximum number of heterogeneous LDPC configurations (descriptor set capacity)

class LdpcDecoderModuleFactory : public framework::pipeline::IModuleFactory#
#include <ldpc_module_factories.hpp>

Factory for creating LdpcDecoderModule instances

Supports module type: “ldpc_decoder_module” Accepts LdpcDecoderModule::StaticParams via std::any in create_module()

Public Functions

LdpcDecoderModuleFactory() = default#

Default constructor

~LdpcDecoderModuleFactory() override = default#

Destructor

LdpcDecoderModuleFactory(const LdpcDecoderModuleFactory&) = delete#
LdpcDecoderModuleFactory &operator=(
const LdpcDecoderModuleFactory&,
) = delete#
LdpcDecoderModuleFactory(LdpcDecoderModuleFactory &&other) = default#

Move constructor

Parameters:

other[inout] Source factory to move from

LdpcDecoderModuleFactory &operator=(
LdpcDecoderModuleFactory &&other,
) = default#

Move assignment operator

Parameters:

other[inout] Source factory to move from

Returns:

Reference to this object

virtual std::unique_ptr<framework::pipeline::IModule> create_module(
std::string_view module_type,
const std::string &instance_id,
const std::any &static_params,
) override#

Create an LdpcDecoderModule instance

Parameters:
  • module_type[in] The type of module to create (must be “ldpc_decoder_module”)

  • instance_id[in] Unique identifier for this module instance

  • static_params[in] Type-erased LdpcDecoderModule::StaticParams

Throws:
  • std::invalid_argument – if module_type is not “ldpc_decoder_module”

  • std::bad_any_cast – if static_params type doesn’t match

Returns:

Unique pointer to the created module

virtual bool supports_module_type(
std::string_view module_type,
) const override#

Check if a module type is supported

Parameters:

module_type[in] The type of module to check

Returns:

true if module_type is “ldpc_decoder_module”, false otherwise

class LdpcDerateMatchModule : public framework::pipeline::IModule, public framework::pipeline::IAllocationInfoProvider, public framework::pipeline::IStreamExecutor, public framework::pipeline::IGraphNodeProvider#
#include <ldpc_derate_match_module.hpp>

LDPC derate match module implementing IModule interface.

This module performs LDPC derate matching on received LLRs (Log-Likelihood Ratios) and outputs derate matched LLRs that can be fed into the LDPC decoder. It supports both CUDA graph execution and direct stream execution modes.

Public Functions

explicit LdpcDerateMatchModule(
std::string instance_id,
const std::any &init_params,
)#

Constructor.

Parameters:
  • instance_id – The instance identifier for this module

  • init_params – Initialization parameters for module configuration

Throws:
  • std::invalid_argument – if the initialization parameters are invalid

  • std::runtime_error – if the LDPC derate match object cannot be created

  • std::runtime_error – if pinned host memory cannot be allocated

~LdpcDerateMatchModule() override#

Destructor.

LdpcDerateMatchModule(const LdpcDerateMatchModule &other) = delete#

Copy constructor - deleted to prevent copying

LdpcDerateMatchModule &operator=(
const LdpcDerateMatchModule &other,
) = delete#

Copy assignment operator - deleted to prevent copying

LdpcDerateMatchModule(LdpcDerateMatchModule &&other) = delete#

Move constructor - deleted to prevent moving

LdpcDerateMatchModule &operator=(
LdpcDerateMatchModule &&other,
) = delete#

Move assignment operator - deleted to prevent moving

inline virtual std::string_view get_type_id() const override#

Get the type identifier

Returns:

The type ID as a string view

virtual std::string_view get_instance_id() const override#

Get the instance identifier

Returns:

The instance ID as a string view

virtual void setup_memory(
const framework::pipeline::ModuleMemorySlice &memory_slice,
) override#

Perform one-time setup after memory allocation.

Parameters:

memory_slice – Memory slice allocated by PipelineMemoryManager

virtual std::vector<framework::tensor::TensorInfo> get_input_tensor_info(
std::string_view port_name,
) const override#

Get the input tensor information for a specified port.

Parameters:

port_name – The name of the input port

Throws:

std::invalid_argument – if the input port was not found

Returns:

Vector of tensor information for all tensors on this port

virtual std::vector<framework::tensor::TensorInfo> get_output_tensor_info(
std::string_view port_name,
) const override#

Get the output tensor information for a specified port.

Parameters:

port_name – The name of the output port

Throws:
  • std::runtime_error – if the output tensor information has not been set

  • std::invalid_argument – if the output port was not found

Returns:

Vector of tensor information for all tensors on this port

virtual std::vector<std::string> get_input_port_names(
) const override#

Get the names of all input ports.

Returns:

A vector of port names

virtual std::vector<std::string> get_output_port_names(
) const override#

Get the names of all output ports.

Returns:

A vector of port names

virtual void set_inputs(
std::span<const framework::pipeline::PortInfo> inputs,
) override#

Set input connections for the module.

Parameters:

inputs – Span of port information with device pointers to input data

Throws:

std::invalid_argument – if required inputs are missing or the inputs don’t match with the expected inputs

virtual std::vector<framework::pipeline::PortInfo> get_outputs(
) const override#

Get output port information.

Returns information about all output ports including their device pointers and tensor metadata. This is used by the pipeline to route data between modules.

Throws:

std::runtime_error – if the module is not setup

Returns:

Vector of port information for all outputs

virtual void configure_io(
const framework::pipeline::DynamicParams &params,
cudaStream_t stream,
) override#

Configure I/O for the current iteration.

Parameters:
  • params[in] Dynamic parameters for the current iteration

  • stream[in] CUDA stream for async operations during configuration

Throws:
  • std::invalid_argument – if the dynamic parameters are invalid

  • std::runtime_error – if the underlying cuPHY module setup fails

inline virtual framework::pipeline::IGraphNodeProvider *as_graph_node_provider(
) override#

Return the graph node provider for this module.

Returns:

The graph node provider

inline virtual framework::pipeline::IStreamExecutor *as_stream_executor(
) override#

Cast the module to a IStreamExecutor.

Returns:

The casted module

virtual void execute(cudaStream_t stream) override#

Execute the module on a given stream.

Note

All dynamic descriptors must have been copied to device before execution.

Parameters:

stream – CUDA stream to execute on

Throws:
  • std::runtime_error – if the module is not setup

  • std::runtime_error – if the kernel launch fails

virtual framework::pipeline::ModuleMemoryRequirements get_requirements(
) const override#

Get the memory requirements for the module.

Throws:

std::runtime_error – if the workspace size cannot be determined

Returns:

The memory requirements

virtual std::span<const CUgraphNode> add_node_to_graph(
gsl_lite::not_null<framework::pipeline::IGraph*> graph,
const std::span<const CUgraphNode> deps,
) override#

Add node(s) to the graph.

Parameters:
  • graph[in] The graph to add the node(s) to

  • deps[in] The dependencies of the node(s)

Throws:

std::runtime_error – if the CUDA graph node addition fails

Returns:

Span of created graph node handle (single node)

virtual void update_graph_node_params(
CUgraphExec exec,
const framework::pipeline::DynamicParams &params,
) override#

Update graph node parameters for dynamic parameter changes.

Parameters:
  • exec – The executable graph to update

  • params – Dynamic parameters containing module-specific parameters

Throws:

std::runtime_error – if cuGraphExecKernelNodeSetParams fails

struct StaticParams#
#include <ldpc_derate_match_module.hpp>

Static parameters for LDPC derate match module.

Public Members

bool enable_scrambling = {true}#

Enable/disable scrambling.

std::size_t max_num_tbs = {ran::common::MAX_NUM_TBS}#

Maximum number of transport blocks

std::size_t max_num_cbs_per_tb = {ran::common::MAX_NUM_CBS_PER_TB}#

Maximum number of code blocks per transport block

std::size_t max_num_rm_llrs_per_cb = {MAX_NUM_RM_LLRS_PER_CB}#

Maximum rate matching LLRs per code block

std::size_t max_num_ue_grps = {ran::common::MAX_NUM_UE_GRPS}#

Maximum number of user groups

class LdpcDerateMatchModuleFactory : public framework::pipeline::IModuleFactory#
#include <ldpc_module_factories.hpp>

Factory for creating LdpcDerateMatchModule instances

Supports module type: “ldpc_derate_match_module” Accepts LdpcDerateMatchModule::StaticParams via std::any in create_module()

Public Functions

LdpcDerateMatchModuleFactory() = default#

Default constructor

~LdpcDerateMatchModuleFactory() override = default#

Destructor

LdpcDerateMatchModuleFactory(
const LdpcDerateMatchModuleFactory&,
) = delete#
LdpcDerateMatchModuleFactory &operator=(
const LdpcDerateMatchModuleFactory&,
) = delete#
LdpcDerateMatchModuleFactory(
LdpcDerateMatchModuleFactory &&other,
) = default#

Move constructor

Parameters:

other[inout] Source factory to move from

LdpcDerateMatchModuleFactory &operator=(
LdpcDerateMatchModuleFactory &&other,
) = default#

Move assignment operator

Parameters:

other[inout] Source factory to move from

Returns:

Reference to this object

virtual std::unique_ptr<framework::pipeline::IModule> create_module(
std::string_view module_type,
const std::string &instance_id,
const std::any &static_params,
) override#

Create an LdpcDerateMatchModule instance

Parameters:
  • module_type[in] The type of module to create (must be “ldpc_derate_match_module”)

  • instance_id[in] Unique identifier for this module instance

  • static_params[in] Type-erased LdpcDerateMatchModule::StaticParams

Throws:
  • std::invalid_argument – if module_type is not “ldpc_derate_match_module”

  • std::bad_any_cast – if static_params type doesn’t match

Returns:

Unique pointer to the created module

virtual bool supports_module_type(
std::string_view module_type,
) const override#

Check if a module type is supported

Parameters:

module_type[in] The type of module to check

Returns:

true if module_type is “ldpc_derate_match_module”, false otherwise

class LdpcParams#
#include <ldpc_params.hpp>

LDPC encoding/decoding parameters container that computes derived LDPC parameters.

This class holds the fundamental LDPC encoding/decoding parameters and provides direct access to all computed derived parameters such as code block segmentation, LDPC base graph selection, and other encoding/decoding parameters.

Public Functions

explicit LdpcParams(
std::uint32_t transport_block_size,
float code_rate,
std::optional<std::uint32_t> rate_matching_length,
std::optional<std::uint8_t> redundancy_version,
)#

Construct LDPC encoding/decoding parameters

All derived parameters are computed automatically upon construction, except: If rate_matching_length or redundancy_version are not provided, num_parity_nodes is not computed.

Parameters:
  • transport_block_size[in] Size of the transport block in bits without CRC.

  • code_rate[in] Code rate (0.0 to 1.0)

  • rate_matching_length[in] Rate matching length. This is the number of LLRs in the rate matching block.

  • redundancy_version[in] Redundancy version (0-3)

inline std::uint32_t transport_block_size() const#

Get transport block size

Returns:

Transport block size in bits without CRC

inline float code_rate() const#

Get code rate

Returns:

Code rate (0.0 to 1.0)

inline std::uint32_t rate_matching_length() const#

Get rate matching length

Returns:

Rate matching length. This is the number of LLRs in the rate matching block.

inline std::uint8_t redundancy_version() const#

Get redundancy version

Returns:

Redundancy version (0-3)

inline std::uint8_t lbrm_enabled() const#

Get LBRM enabled flag

Returns:

LBRM enabled (0 or 1) - Not supported yet

inline std::uint8_t base_graph() const#

Get LDPC base graph

Returns:

LDPC base graph (1 or 2)

inline std::uint32_t num_code_blocks() const#

Get number of code blocks

Returns:

Number of code blocks, C in 38.212

inline std::uint32_t num_info_nodes() const#

Get number of information nodes

Returns:

Number of information nodes

inline std::uint32_t k_prime() const#

Get K’ value

Returns:

K’ in 38.212

inline std::uint32_t lifting_size() const#

Get LDPC lifting size

Returns:

LDPC lifting size, Z in 38.212

inline std::uint32_t num_code_block_info_bits() const#

Get number of code block info bits

Returns:

Number of code block info bits, K in 38.212

inline std::uint32_t num_filler_bits() const#

Get number of filler bits

Returns:

Number of filler bits, F in 38.212

inline std::uint32_t circular_buffer_size() const#

Get circular buffer size

Returns:

Circular buffer size for rate matching

inline std::uint32_t circular_buffer_size_padded() const#

Get circular buffer size padded

Returns:

Circular buffer size for rate matching padded

std::uint32_t num_parity_nodes() const#

Get number of parity nodes

Throws:

std::logic_error – If num_parity_nodes was not computed (when rate_matching_length or redundancy_version were not provided to constructor)

Returns:

Number of parity nodes

Public Static Functions

static std::uint8_t get_base_graph(
std::uint32_t tb_size,
float code_rate,
)#

Get the LDPC base graph (1 or 2)

Parameters:
  • tb_size[in] Transport block size in bits without CRC.

  • code_rate[in] Code rate (0.0 to 1.0)

Returns:

LDPC base graph (1 or 2)

static std::uint8_t get_tb_crc_size(std::uint32_t tb_size)#

Get the transport block CRC size

Parameters:

tb_size[in] Transport block size in bits without CRC.

Returns:

Transport block CRC size

static std::uint32_t get_tb_size_with_crc(std::uint32_t tb_size)#

Get the transport block size with CRC

Parameters:

tb_size[in] Transport block size in bits without CRC.

Returns:

Transport block size with CRC

static std::uint32_t get_num_code_blocks(
std::uint32_t tb_size,
std::uint8_t base_graph,
)#

Get the number of code blocks

Parameters:
  • tb_size[in] Transport block size in bits without CRC.

  • base_graph[in] LDPC base graph (1 or 2)

Throws:

std::invalid_argument – if base_graph is not 1 or 2

Returns:

Number of code blocks

static std::uint32_t get_num_info_nodes(
std::uint32_t tb_size,
std::uint8_t base_graph,
)#

Get the number of information nodes

Parameters:
  • tb_size[in] Transport block size in bits without CRC.

  • base_graph[in] LDPC base graph (1 or 2)

Throws:

std::invalid_argument – if base_graph is not 1 or 2

Returns:

Number of information nodes

static std::uint32_t get_k_prime(
std::uint32_t tb_size,
std::uint32_t num_code_blocks,
)#

Get the K’ value

Parameters:
  • tb_size[in] Transport block size in bits without CRC.

  • num_code_blocks[in] Number of code blocks

Returns:

K’ value

static std::uint32_t get_lifting_size(
std::uint32_t tb_size,
std::uint8_t base_graph,
std::optional<std::uint32_t> num_code_blocks,
std::optional<std::uint32_t> num_info_nodes,
std::optional<std::uint32_t> k_prime,
)#

Get the LDPC lifting size

Note

Parameters num_code_blocks, num_info_nodes, and k_prime are optional and will be computed if not provided.

Note

If num_code_blocks is not provided, it will be computed using get_num_code_blocks().

Note

If num_info_nodes is not provided, it will be computed using get_num_info_nodes().

Note

If k_prime is not provided, it will be computed using get_k_prime().

Parameters:
  • tb_size[in] Transport block size in bits without CRC.

  • base_graph[in] LDPC base graph (1 or 2)

  • num_code_blocks[in] Number of code blocks

  • num_info_nodes[in] Number of information nodes

  • k_prime[in] K’ value

Throws:

std::invalid_argument – If base_graph is not 1 or 2.

Returns:

LDPC lifting size

static std::uint32_t get_num_code_block_info_bits(
std::uint8_t base_graph,
std::uint32_t lifting_size,
)#

Get the number of code block info bits

Parameters:
  • base_graph[in] LDPC base graph (1 or 2)

  • lifting_size[in] LDPC lifting size

Throws:

std::invalid_argument – If base_graph is not 1 or 2.

Returns:

Number of code block info bits

Public Static Attributes

static constexpr std::uint32_t MAX_CODE_BLOCK_SIZE_BG1 = 8448#

Maximum code block size for base graph 1.

static constexpr std::uint32_t MAX_CODE_BLOCK_SIZE_BG2 = 3840#

Maximum code block size for base graph 2.

static constexpr std::uint32_t CB_CRC_SIZE = 24#

Code block CRC size.

static constexpr std::uint32_t TB_SIZE_THRESHOLD = 3824#

Transport block size threshold for CRC size selection.

static constexpr std::uint32_t TB_CRC_SIZE_LARGE = 24#

CRC size for large transport blocks.

static constexpr std::uint32_t TB_CRC_SIZE_SMALL = 16#

CRC size for small transport blocks.

static constexpr float CODE_RATE_BG_THRESHOLD_1 = 0.25F#

Code rate threshold 1 for base graph selection.

static constexpr float CODE_RATE_BG_THRESHOLD_2 = 0.67F#

Code rate threshold 2 for base graph selection.

static constexpr std::uint32_t TB_SIZE_BG_THRESHOLD1 = 292#

Transport block size threshold 1 for base graph selection.

static constexpr std::uint32_t TB_SIZE_BG_THRESHOLD2 = 3824#

Transport block size threshold 2 for base graph selection.

static constexpr std::uint32_t MIN_PARITY_NODES = 4#

Minimum permitted parity node count irrespective of BG (base graph)

static constexpr std::uint32_t MAX_PARITY_NODES_BG1 = 46#

Maximum number of parity nodes for base graph 1.

static constexpr std::uint32_t MAX_PARITY_NODES_BG2 = 42#

Maximum number of parity nodes for base graph 2.

static constexpr std::uint32_t UNPUNCTURED_VAR_NODES_BG1 = 66#

Circular buffer nodes for base graph 1.

static constexpr std::uint32_t UNPUNCTURED_VAR_NODES_BG2 = 50#

Circular buffer nodes for base graph 2.

static constexpr std::uint32_t PADDING_ALIGNMENT = 8#

Padding alignment for circular buffer.

static constexpr std::uint32_t INFO_NODES_BG1 = 22#

Information nodes for base graph 1.

static constexpr std::uint32_t INFO_NODES_BG2_MAX = 10#

Information nodes for base graph 2 (maximum)

static constexpr std::uint32_t INFO_NODES_BG2_MEDIUM = 9#

Information nodes for base graph 2 (medium)

static constexpr std::uint32_t INFO_NODES_BG2_SMALL = 8#

Information nodes for base graph 2 (small)

static constexpr std::uint32_t INFO_NODES_BG2_SMALLEST = 6#

Information nodes for base graph 2 (smallest)

static constexpr std::uint32_t TB_SIZE_THRESHOLD_KB10 = 640#

Transport block size threshold for Kb 10.

static constexpr std::uint32_t TB_SIZE_THRESHOLD_KB9 = 560#

Transport block size threshold for Kb 9.

static constexpr std::uint32_t TB_SIZE_THRESHOLD_KB8 = 192#

Transport block size threshold for Kb 8.

static constexpr std::uint32_t MAX_LIFTING_SIZE = 384#

Maximum possible lifting size.

static constexpr std::uint32_t RV1_START_POS_FACTOR_BG1 = 17#

RV1 factor for base graph 1.

static constexpr std::uint32_t RV2_START_POS_FACTOR_BG1 = 33#

RV2 factor for base graph 1.

static constexpr std::uint32_t RV3_START_POS_FACTOR_BG1 = 56#

RV3 factor for base graph 1.

static constexpr std::uint32_t RV1_START_POS_FACTOR_BG2 = 13#

RV1 factor for base graph 2.

static constexpr std::uint32_t RV2_START_POS_FACTOR_BG2 = 25#

RV2 factor for base graph 2.

static constexpr std::uint32_t RV3_START_POS_FACTOR_BG2 = 43#

RV3 factor for base graph 2.

class PuschOuterRxParams#
#include <outer_rx_params.hpp>

Parameters for PUSCH receiver pipeline outer_rx in a single slot.

This class manages the parameters for PUSCH receiver pipeline outer_rx within a single slot, including transport block parameters, LDPC parameters, and derate matching parameters. It provides efficient GPU memory management and conversion to cuPHY-compatible formats.

The class automatically converts SingleTbPuschOuterRxParams to PerTbParams format required by cuPHY and manages the related CPU and GPU memory buffers for all transport blocks in the slot.

Public Functions

explicit PuschOuterRxParams(
const std::vector<SingleTbPuschOuterRxParams> &pusch_outer_rx_params,
const std::vector<std::uint16_t> &sch_user_idxs,
)#

Construct parameters for PUSCH receiver pipeline outer_rx.

Creates a PuschOuterRxParams object. Automatically converts the SingleTbPuschOuterRxParams to cuPHY-compatible PerTbParams format and allocates both CPU and GPU memory buffers.

Parameters:
  • pusch_outer_rx_params[in] Vector of PUSCH receiver outer_rx parameters for all TBs in the slot

  • sch_user_idxs[in] Vector of scheduled user indices corresponding to each single transport block PUSCH receiver outer_rx parameters object.

inline PerTbParams *get_per_tb_params_cpu_ptr() noexcept#

Get pointer to CPU PerTbParams buffer

Returns:

Pointer to CPU memory containing PerTbParams for all transport blocks

inline const PerTbParams *get_per_tb_params_cpu_ptr() const noexcept#

Get const pointer to CPU PerTbParams buffer

Returns:

Const pointer to CPU memory containing PerTbParams for all transport blocks

inline PerTbParams *get_per_tb_params_gpu_ptr() noexcept#

Get pointer to GPU PerTbParams buffer

Returns:

Pointer to GPU memory containing PerTbParams for all transport blocks

inline const PerTbParams *get_per_tb_params_gpu_ptr() const noexcept#

Get const pointer to GPU PerTbParams buffer

Returns:

Const pointer to GPU memory containing PerTbParams for all transport blocks

void copy_tb_params_to_gpu(cudaStream_t stream)#

Copy cuPHY transport block parameters from CPU to GPU memory

Asynchronously copies the PerTbParams data from CPU buffer to GPU buffer using the specified CUDA stream for optimal performance.

Parameters:

stream[in] CUDA stream to use for the memory copy operation

inline std::size_t get_num_sch_ues() const noexcept#

Get the number of scheduled UEs in this slot

Returns:

Number of scheduled user equipments (UEs) for this slot

inline std::span<const std::uint16_t> get_sch_user_idxs(
) const noexcept#

Get the scheduled user indices for this slot

Returns:

Span of scheduled user indices

inline std::size_t num_tbs() const noexcept#

Get the number of transport blocks in this slot

Returns:

Number of transport blocks

inline const SingleTbPuschOuterRxParams &get_pusch_outer_rx_params_single_tb(
std::size_t idx,
) const#

Get SingleTbPuschOuterRxParams for a specific index

Parameters:

idx[in] Index of the transport block (must be less than number of transport blocks)

Returns:

Const reference to SingleTbPuschOuterRxParams at the specified index

inline SingleTbPuschOuterRxParams &operator[](std::size_t idx)#

Get SingleTbPuschOuterRxParams for a specific index

Parameters:

idx[in] Index of the transport block (must be less than number of transport blocks)

Returns:

Reference to SingleTbPuschOuterRxParams at the specified index

inline const SingleTbPuschOuterRxParams &operator[](
std::size_t idx,
) const#

Get SingleTbPuschOuterRxParams for a specific index

Parameters:

idx[in] Index of the transport block (must be less than number of transport blocks)

Returns:

Const reference to SingleTbPuschOuterRxParams at the specified index

class SingleTbPuschOuterRxParams#
#include <outer_rx_params.hpp>

Parameters needed by the PUSCH receiver pipeline outer_rx for processing a single transport block.

This class encapsulates all parameters required for processing a single transport block by the PUSCH receiver pipeline outer_rx, which comprises LDPC rate matching, decoding and CRC decoding. The parameters include:

  • LDPC decoding parameters

  • Rate matching parameters

  • Layer mapping

  • Scrambling configuration

Public Functions

explicit SingleTbPuschOuterRxParams(
const LdpcParams &ldpc_params,
const std::optional<DerateMatchParams> &de_rm_params = std::nullopt,
)#

Construct PUSCH receiver pipeline outer_rx parameters for a single transport block.

Creates SingleTbPuschOuterRxParams using pre-computed LDPC parameters and optional derate matching configuration.

Parameters:
  • ldpc_params[in] Pre-computed LDPC encoding/decoding parameters

  • de_rm_params[in] Optional derate matching parameters. Needed if used for derate matching.

const DerateMatchParams &de_rm_params() const#

Get derate matching configuration parameters

Throws:

std::runtime_error – if derate matching parameters have not been set

Returns:

Const reference to derate matching parameters

inline const LdpcParams &ldpc_params() const noexcept#

Get LDPC parameters

Returns:

Const reference to LDPC parameters

inline bool enable_tf_prcd() const noexcept#

Whether DFT-S-OFDM transform precoding is enabled

Returns:

True if DFT-S-OFDM transform precoding is enabled

void to_per_tb_params(PerTbParams &tb_params) const#

Convert parameters to PerTbParams structure

Parameters:

tb_params[out] PerTbParams structure to populate with converted parameters