PUSCH#
Physical Uplink Shared Channel processing pipeline for 5G NR.
Overview#
The PUSCH runtime module provides a complete processing pipeline for Physical Uplink Shared Channel (PUSCH) in 5G NR systems. It consists of a TensorRT-accelerated inner receiver stage for signal processing and an outer receiver stage with LDPC channel decoding to transform received uplink signals into decoded transport blocks.
The pipeline consists of the following modules organized into two stages:
Inner Receiver: TensorRT-based signal processing that performs channel estimation, noise estimation, equalization, and soft demapping
Outer Receiver: Channel decoding chain that performs derate matching, LDPC decode, and CRC check
The inner receiver module uses TensorRT for GPU-accelerated neural
network inference, while the outer receiver uses the LDPC library modules for channel decoding. All modules
implement the pipeline::IModule interface from the
pipeline library, enabling standardized
configuration, memory management, and execution patterns.
Key Features#
TensorRT Inner Receiver: GPU-accelerated signal processing with TensorRT
Channel Decoding: LDPC decoder with derate matching and CRC validation
Pipeline Architecture: Modular design with factory-based module creation
Execution Modes: Support for both stream and CUDA graph execution
Memory Management: Efficient memory allocation and reuse across iterations
Core Concepts#
Pipeline Architecture#
The PUSCH pipeline processes uplink signals through two stages:
Inner Receiver Stage
The inner receiver module (InnerRxModule) performs signal
processing on received time-frequency samples:
Channel Estimation: Estimates channel response using DMRS (Demodulation Reference Signals)
Noise Estimation: Estimates noise covariance matrix for equalization
Equalization: Compensates for channel effects using estimated channel
Soft Demapping: Generates Log-Likelihood Ratios (LLRs) from equalized symbols
This stage is implemented using TensorRT for optimized GPU execution.
Outer Receiver Stage
The outer receiver consists of three LDPC library modules:
LDPC Derate Match Module: Reverses rate matching to prepare LLRs for LDPC decoding
LDPC Decoder Module: Performs iterative LDPC decoding on LLRs to produce hard-decision bits
CRC Decoder Module: Validates CRC checksums and concatenates code blocks into transport blocks
Each module implements the IModule interface from the pipeline
library and can be created using the factory
pattern.
Module Factory#
The PuschModuleFactory creates all module types used in the
pipeline:
// Create a module factory for PUSCH pipeline
auto factory = std::make_unique<PuschModuleFactory>();
// Check supported module types
const bool supports_inner_rx = factory->supports_module_type("inner_rx_module");
const bool supports_ldpc = factory->supports_module_type("ldpc_decoder_module");
Module Configuration#
Modules are configured using static parameters at creation time:
// Configure physical layer parameters
PhyParams phy_params{};
phy_params.num_rx_ant = 4;
phy_params.num_prb = 273;
phy_params.bandwidth = 100;
// Configure inner_rx module parameters
const InnerRxModule::StaticParams params{
.phy_params = phy_params, .execution_mode = pipeline::ExecutionMode::Stream};
// Create the inner_rx module
auto module = std::make_unique<InnerRxModule>("inner_rx_0", params);
Physical layer parameters include antenna configuration, PRB count, and bandwidth configuration.
Pipeline Specification#
Pipeline behavior is defined using PipelineSpec:
// Create pipeline specification
pipeline::PipelineSpec spec;
spec.pipeline_name = "PuschPipeline";
spec.execution_mode = pipeline::ExecutionMode::Stream;
// Configure physical layer parameters
PhyParams phy_params{};
phy_params.num_rx_ant = 4;
phy_params.num_prb = 273;
// Add inner receiver (inner_rx) module to specification
const InnerRxModule::StaticParams inner_rx_params{
.phy_params = phy_params, .execution_mode = spec.execution_mode};
spec.modules.emplace_back(pipeline::ModuleCreationInfo{
.module_type = "inner_rx_module",
.instance_id = "inner_rx_0",
.init_params = std::any(inner_rx_params)});
// Add outer receiver modules (derate match, LDPC decoder, CRC decoder)
const LdpcDerateMatchModule::StaticParams derate_params{
.max_num_tbs = ran::common::MAX_NUM_TBS,
.max_num_cbs_per_tb = ran::common::MAX_NUM_CBS_PER_TB,
.max_num_rm_llrs_per_cb = ran::ldpc::MAX_NUM_RM_LLRS_PER_CB,
.max_num_ue_grps = ran::common::MAX_NUM_UE_GRPS};
spec.modules.emplace_back(pipeline::ModuleCreationInfo{
.module_type = "ldpc_derate_match_module",
.instance_id = "ldpc_derate_match_0",
.init_params = std::any(derate_params)});
const LdpcDecoderModule::StaticParams decoder_params{
.clamp_value = ran::ldpc::LDPC_CLAMP_VALUE,
.max_num_iterations = ran::ldpc::LDPC_MAX_ITERATIONS,
.max_num_cbs_per_tb = ran::common::MAX_NUM_CBS_PER_TB,
.max_num_tbs = ran::common::MAX_NUM_TBS,
.normalization_factor = ran::ldpc::LDPC_NORMALIZATION_FACTOR,
.max_iterations_method = ran::ldpc::LdpcMaxIterationsMethod::Fixed,
.max_num_ldpc_het_configs = ran::ldpc::LDPC_MAX_HET_CONFIGS};
spec.modules.emplace_back(pipeline::ModuleCreationInfo{
.module_type = "ldpc_decoder_module",
.instance_id = "ldpc_decoder_0",
.init_params = std::any(decoder_params)});
const CrcDecoderModule::StaticParams crc_params{
.max_num_cbs_per_tb = ran::common::MAX_NUM_CBS_PER_TB,
.max_num_tbs = ran::common::MAX_NUM_TBS};
spec.modules.emplace_back(pipeline::ModuleCreationInfo{
.module_type = "crc_decoder_module",
.instance_id = "crc_decoder_0",
.init_params = std::any(crc_params)});
Module Introspection#
Modules provide introspection APIs for discovering ports and tensor information:
// Create inner_rx module
PhyParams phy_params{};
phy_params.num_rx_ant = 4;
phy_params.num_prb = 273;
const InnerRxModule::StaticParams params{
.phy_params = phy_params, .execution_mode = pipeline::ExecutionMode::Stream};
auto module = std::make_unique<InnerRxModule>("inner_rx_0", params);
// Inspect module ports
const auto input_ports = module->get_input_port_names();
const auto output_ports = module->get_output_port_names();
Execution Flow#
A typical PUSCH processing iteration follows these steps:
Pipeline Setup#
Setup allocates memory and initializes all modules:
// Setup pipeline
pipeline_->setup();
This is called once during initialization before any processing begins.
Configure and Execute#
For each slot, configure the pipeline with dynamic parameters:
// Configure I/O with dynamic parameters
pipeline_->configure_io(params, external_inputs_, external_outputs_, stream.get());
// Warmup pipeline
pipeline_->warmup(stream.get());
The configure_io() method sets up input/output ports and prepares
internal state based on transport block parameters. The warmup()
method prepares execution paths (called once after setup).
Then execute the pipeline:
// Execute based on pipeline mode
if (pipeline_->get_execution_mode() == pipeline::ExecutionMode::Stream) {
pipeline_->execute_stream(stream.get());
} else {
pipeline_->execute_graph(stream.get());
}
The execute_stream() or execute_graph() method runs the
complete pipeline processing on the provided CUDA stream.
Dynamic parameters change per slot and include UE-specific configuration like MCS, PRB allocation, and HARQ parameters.
Additional Examples#
For complete working examples with full setup and validation, see:
ran/runtime/pusch/tests/pusch_pipeline_runner.cpp- Pipeline runner implementation for benchmarks and testsran/runtime/pusch/tests/pusch_pipeline_test.cpp- Complete pipeline test with TensorRT integrationran/runtime/pusch/tests/pusch_sample_tests.cpp- Documentation examples
API Reference#
-
constexpr uint32_t ran::pusch::NUM_PUSCH_MODULES = 4#
Number of PUSCH modules.
-
constexpr std::size_t ran::pusch::NUM_EXTERNAL_INPUTS = 1#
Number of external input ports.
-
constexpr std::size_t ran::pusch::NUM_EXTERNAL_OUTPUTS = 4#
Number of external output ports.
- ran::pusch::DECLARE_LOG_COMPONENT(
- PuschComponent,
- PuschPipeline,
- PuschModuleFactory,
- InnerRxModuleFactory,
- InnerRxModule,
PUSCH logging components
- ran::pusch::DECLARE_LOG_EVENT(
- PuschPipelineEvent,
- CreatePipeline,
- CreateModules,
- PipelineSetup,
- PipelineWarmup,
- PipelineConfigureIo,
- PipelineExecuteStream,
- PipelineBuildGraph,
- PipelineExecuteGraph,
- ModuleSetupMemory,
- ModuleSetInputs,
- ModuleWarmup,
- ModuleConfigureIo,
- ModuleGetOutputs,
- ModuleExecute,
- ModuleAddNodeToGraph,
PUSCH pipeline event logging identifiers
- ran::pusch::DECLARE_LOG_EVENT(
- PuschErrorEvent,
- InvalidParam,
- InvalidState,
PUSCH error event logging identifiers
-
bool ran::pusch::init_ran_trt_plugins() noexcept#
Initialize RAN TensorRT plugins
Uses an internal static TensorRT logger that forwards all messages to RT_LOG. Thread-safe and only initializes once.
- Returns:
true if plugins initialized successfully
-
std::string ran::pusch::get_trt_engine_path()#
Get TRT engine file path from environment variable
Reads the full path to the TRT engine file from the RAN_TRT_ENGINE_PATH environment variable and verifies the file exists.
- Throws:
std::runtime_error – if RAN_TRT_ENGINE_PATH not set or file doesn’t exist
- Returns:
Full path to TRT engine file
- std::vector<framework::memory::UniqueDevicePtr<std::byte>> ran::pusch::prepare_pusch_inputs(
- std::vector<pipeline::PortInfo> &inputs,
- const ran::common::PhyParams &phy_params,
- const ran::aerial_tv::CuphyPuschTestVector &test_vector,
- cudaStream_t stream,
-
template<typename T>
std::vector<T> ran::pusch::tensor_to_host_vector( - const tensor::TensorInfo &tensor_info,
- const void *device_ptr,
- cudaStream_t stream,
Copy device tensor data to host vector using stream-aware async copy
Computes number of elements from tensor_info, creates a std::vector<T> with that capacity, and copies data from device_ptr to the vector using cudaMemcpyAsync on the specified stream for proper synchronization.
- Parameters:
tensor_info – [in] Tensor information containing dimensions
device_ptr – [in] Device pointer to tensor data
stream – [in] CUDA stream to use for async memory copy (ensures proper ordering)
- Returns:
Vector containing the copied data
- pipeline::PipelineSpec ran::pusch::create_pusch_pipeline_spec(
- const std::string &instance_id,
- const ran::common::PhyParams &phy_params,
- const pipeline::ExecutionMode execution_mode,
Create PUSCH pipeline specification for testing/benchmarking
- Parameters:
instance_id – [in] Instance identifier for the pipeline
phy_params – [in] Physical layer parameters
execution_mode – [in] Execution mode (Stream or Graph)
- Returns:
Pipeline specification with all module configurations
- BenchmarkStatistics ran::pusch::compute_benchmark_statistics(
- const std::vector<double> ×,
Compute statistics from benchmark timing samples
- Parameters:
times – [in] Vector of timing measurements
- Returns:
Computed statistics
- std::vector<framework::memory::UniqueDevicePtr<std::byte>> ran::pusch::prepare_pusch_inputs(
- std::vector<framework::pipeline::PortInfo> &inputs,
- const ran::common::PhyParams &phy_params,
- const ran::aerial_tv::CuphyPuschTestVector &test_vector,
- cudaStream_t stream,
Prepare PUSCH inputs with managed memory using stream-aware copy
- Parameters:
inputs – [out] Input ports
phy_params – [in] Physical layer parameters
test_vector – [in] Test vector
stream – [in] CUDA stream for async memory copy
- Returns:
Managed device pointers (memory freed automatically via RAII)
-
struct BenchmarkStatistics#
- #include <pusch_test_utils.hpp>
Benchmark timing statistics
-
class InnerRxModule : public framework::pipeline::IModule, public framework::pipeline::IAllocationInfoProvider, public framework::pipeline::IGraphNodeProvider, public framework::pipeline::IStreamExecutor#
- #include <inner_rx_module.hpp>
Inner Rx Module
Generic front-end processing module template. Can be customized for specific front-end processing tasks.
Configuration:
Configurable input/output ports
Support for both stream and graph execution modes
Public Functions
-
InnerRxModule(std::string instance_id, const StaticParams ¶ms)#
Construct module with instance ID and parameters
- Parameters:
instance_id – [in] Unique identifier for this module instance
params – [in] Static configuration parameters
-
~InnerRxModule() override = default#
Destructor
-
InnerRxModule(const InnerRxModule&) = delete#
-
InnerRxModule &operator=(const InnerRxModule&) = delete#
-
InnerRxModule(InnerRxModule&&) = delete#
-
InnerRxModule &operator=(InnerRxModule&&) = delete#
-
inline virtual std::string_view get_type_id() const override#
Get module type identifier
- Returns:
Module type ID
-
inline virtual std::string_view get_instance_id() const override#
Get module instance identifier
- Returns:
Module instance ID
- virtual framework::pipeline::IStreamExecutor *as_stream_executor(
Get stream executor interface
- Returns:
Pointer to stream executor interface
- virtual framework::pipeline::IGraphNodeProvider *as_graph_node_provider(
Get graph node provider interface
- Returns:
Pointer to graph node provider interface
- virtual std::vector<std::string> get_input_port_names(
Get list of input port names
- Returns:
Vector of input port names
- virtual std::vector<std::string> get_output_port_names(
Get list of output port names
- Returns:
Vector of output port names
- virtual std::vector<framework::tensor::TensorInfo> get_input_tensor_info(
- std::string_view port_name,
Get tensor information for input port
- Parameters:
port_name – [in] Input port name
- Throws:
std::invalid_argument – if port name is unknown
- Returns:
Vector of tensor information
- virtual std::vector<framework::tensor::TensorInfo> get_output_tensor_info(
- std::string_view port_name,
Get tensor information for output port
- Parameters:
port_name – [in] Output port name
- Throws:
std::invalid_argument – if port name is unknown
- Returns:
Vector of tensor information
- virtual framework::pipeline::InputPortMemoryCharacteristics get_input_memory_characteristics(
- std::string_view port_name,
Get input port memory characteristics
- Parameters:
port_name – [in] Input port name
- Throws:
std::invalid_argument – if port name is unknown
- Returns:
Memory characteristics for the port
- virtual framework::pipeline::OutputPortMemoryCharacteristics get_output_memory_characteristics(
- std::string_view port_name,
Get output port memory characteristics
- Parameters:
port_name – [in] Output port name
- Throws:
std::invalid_argument – if port name is unknown
- Returns:
Memory characteristics for the port
- virtual void set_connection_copy_mode(
- std::string_view port_name,
- framework::pipeline::ConnectionCopyMode mode,
Configure connection copy mode for an input port
- Parameters:
port_name – [in] Input port name
mode – [in] Connection copy mode (Copy or ZeroCopy)
- Throws:
std::invalid_argument – if port name is unknown
- virtual framework::pipeline::ModuleMemoryRequirements get_requirements(
Get module memory requirements
- Returns:
Memory requirements for this module
- virtual void setup_memory(
- const framework::pipeline::ModuleMemorySlice &memory_slice,
Setup module memory
- Parameters:
memory_slice – [in] Memory slice allocated for this module
- virtual void set_inputs(
- std::span<const framework::pipeline::PortInfo> inputs,
Configure input port connections
- Parameters:
inputs – [in] Input port information containing data pointers
- Throws:
std::invalid_argument – if required inputs are missing or port names don’t match with expected inputs
-
virtual void warmup(cudaStream_t stream) override#
Warmup execution
- Parameters:
stream – [in] CUDA stream for warmup
- Throws:
std::runtime_error – if warmup is called before setup_memory() and set_inputs() have been called, or if the TRT engine setup() or warmup() fails
- virtual void configure_io(
- const framework::pipeline::DynamicParams ¶ms,
- cudaStream_t stream,
Configure I/O for current iteration
- Parameters:
params – [in] Dynamic parameters for this iteration
stream – [in] CUDA stream for async operations during configuration
- Throws:
std::runtime_error – if input ports are not set before configure_io()
- virtual std::vector<framework::pipeline::PortInfo> get_outputs(
Get output port information
- Returns:
Vector of output port information
-
virtual void execute(cudaStream_t stream) override#
Execute module on stream
- Parameters:
stream – [in] CUDA stream for execution
- Throws:
std::runtime_error – if the TRT engine run() fails
- virtual std::span<const CUgraphNode> add_node_to_graph(
- gsl_lite::not_null<framework::pipeline::IGraph*> graph,
- std::span<const CUgraphNode> deps,
Add processing node to CUDA graph
- Parameters:
graph – [in] Graph interface for node creation
deps – [in] Dependency nodes that must complete before this node
- Throws:
std::runtime_error – if warmup() is not called before add_node_to_graph(), or if the graph capturer is not in capture mode, or if the captured TensorRT graph is not available
- Returns:
Span of created graph node handle (single TensorRT node)
- virtual void update_graph_node_params(
- CUgraphExec exec,
- const framework::pipeline::DynamicParams ¶ms,
Update graph node parameters
- Parameters:
exec – [in] Graph executable to update
params – [in] Dynamic parameters for the update
-
struct StaticParams#
- #include <inner_rx_module.hpp>
Static parameters for module construction
Public Members
-
ran::common::PhyParams phy_params = {}#
Physical layer parameters.
-
framework::pipeline::ExecutionMode execution_mode = {framework::pipeline::ExecutionMode::Graph}#
Module execution mode.
-
ran::common::PhyParams phy_params = {}#
-
class InnerRxModuleFactory : public framework::pipeline::IModuleFactory#
- #include <pusch_module_factories.hpp>
Factory for creating InnerRxModule instances
Supports module type: “inner_rx_module” Accepts InnerRxModule::StaticParams via std::any in create_module()
Public Functions
-
InnerRxModuleFactory() = default#
Default constructor
-
~InnerRxModuleFactory() override = default#
Destructor
-
InnerRxModuleFactory(const InnerRxModuleFactory&) = delete#
-
InnerRxModuleFactory &operator=(const InnerRxModuleFactory&) = delete#
-
InnerRxModuleFactory(InnerRxModuleFactory &&other) = default#
Move constructor
- Parameters:
other – [inout] Source factory to move from
- InnerRxModuleFactory &operator=(
- InnerRxModuleFactory &&other,
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,
Create a InnerRxModule instance
- Parameters:
module_type – [in] The type of module to create (must be “inner_rx_module”)
instance_id – [in] Unique identifier for this module instance
static_params – [in] Type-erased InnerRxModule::StaticParams
- Throws:
std::invalid_argument – if module_type is not “inner_rx_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,
Check if a module type is supported
- Parameters:
module_type – [in] The type of module to check
- Returns:
true if module_type is “inner_rx_module”, false otherwise
-
InnerRxModuleFactory() = default#
-
class InnerRxModuleRunner#
- #include <inner_rx_module_runner.hpp>
InnerRx module execution helper for benchmarks and tests
Encapsulates inner_rx module setup, configuration, and execution. Follows RAII - module is fully initialized upon construction.
Public Functions
- InnerRxModuleRunner(
- const std::string &test_vector_path,
- framework::pipeline::ExecutionMode execution_mode,
Construct and initialize inner_rx module with test vector
- Parameters:
test_vector_path – [in] Full path to H5 test vector file
execution_mode – [in] Execution mode (Stream or Graph)
-
~InnerRxModuleRunner() = default#
-
InnerRxModuleRunner(const InnerRxModuleRunner&) = delete#
-
InnerRxModuleRunner &operator=(const InnerRxModuleRunner&) = delete#
-
InnerRxModuleRunner(InnerRxModuleRunner&&) noexcept = default#
Move constructor
- InnerRxModuleRunner &operator=( ) noexcept = default#
Move assignment operator
- Returns:
Reference to this object
-
void configure(const framework::utils::CudaStream &stream)#
Configure I/O and dynamic parameters
Call once before execute_once() or after parameter changes. Note: This method includes an initial warmup call.
- Parameters:
stream – [in] CUDA stream for execution
-
void warmup(const framework::utils::CudaStream &stream)#
Warmup module execution paths
Optional: Additional warmup can be performed by calling this method or by executing the module multiple times before benchmarking.
- Parameters:
stream – [in] CUDA stream for warmup
-
void execute_once(const framework::utils::CudaStream &stream)#
Execute one iteration of the module
Only performs execute() or launch_graph() call.
- Parameters:
stream – [in] CUDA stream for execution
-
inline framework::pipeline::ExecutionMode get_execution_mode() const#
Get module execution mode
- Returns:
Execution mode (Stream or Graph)
-
std::vector<framework::pipeline::PortInfo> get_outputs() const#
Get module outputs after execution
- Returns:
Vector of output port information
-
inline const ran::common::PhyParams &get_phy_params() const#
Get PhyParams
- Returns:
Physical layer parameters
- inline const ran::aerial_tv::CuphyPuschTestVector &get_test_vector(
Get test vector
- Returns:
Test vector used for module configuration
-
struct PuschDynamicParams#
- #include <pusch_defines.hpp>
PUSCH dynamic parameters data structure
This structure contains the dynamic parameters for the PUSCH pipeline. It is used to pass the dynamic parameters to the PUSCH pipeline.
- Param inner_rx_params:
[in] InnerRx parameters
- Param outer_rx_params:
[in] OuterRx parameters
Public Members
-
PuschInnerRxRxParams inner_rx_params#
InnerRx parameters.
-
ran::ldpc::PuschOuterRxParams outer_rx_params#
OuterRx parameters.
-
struct PuschInnerRxRxParams#
- #include <pusch_defines.hpp>
InnerRx parameters structure
-
struct PuschInput#
- #include <pusch_defines.hpp>
PUSCH Input Data
Contains all input parameters and data for PUSCH processing.
Public Functions
-
inline bool check_bounds() const#
Check if indices are within bounds
- Returns:
true if indices are within valid ranges
Public Members
-
std::vector<PuschUeParams> ue_params#
UE parameters.
-
uint32_t ue_params_index = {}#
UE parameters index.
-
std::vector<std::vector<int8_t>> ue_group_idx_map#
map between ue params index and ue group index. ue_group_idx_map is sized by number of ue groups each slot. ue_group_idx_map[ue_group_idx] contains the indexes into ue_params for the UE which belong to this group.
-
uint32_t ue_group_idx_index = {}#
UE group index index.
-
std::vector<float> xtf#
XTF data (real/imag interleaved)
-
inline bool check_bounds() const#
-
class PuschModuleFactory : public framework::pipeline::IModuleFactory#
- #include <pusch_module_factories.hpp>
Combined factory for all PUSCH pipeline modules
Aggregates InnerRxModuleFactory and LDPC module factories. Supports module types: “inner_rx_module”, “ldpc_decoder_module”, “ldpc_derate_match_module”, “crc_decoder_module”
This factory delegates to the appropriate sub-factory based on module type.
Public Functions
-
PuschModuleFactory()#
Constructor - initializes sub-factories
-
~PuschModuleFactory() override = default#
Destructor
-
PuschModuleFactory(const PuschModuleFactory&) = delete#
-
PuschModuleFactory &operator=(const PuschModuleFactory&) = delete#
-
PuschModuleFactory(PuschModuleFactory &&other) = default#
Move constructor
- Parameters:
other – [inout] Source factory to move from
-
PuschModuleFactory &operator=(PuschModuleFactory &&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,
Create a module instance
Delegates to the appropriate sub-factory based on module_type.
- Parameters:
module_type – [in] The type of module to create
instance_id – [in] Unique identifier for this module instance
static_params – [in] Type-erased module static parameters
- Throws:
std::invalid_argument – if module_type is not supported
std::bad_any_cast – if static_params type doesn’t match module requirements
- Returns:
Unique pointer to the created module
- virtual bool supports_module_type(
- std::string_view module_type,
Check if a module type is supported
- Parameters:
module_type – [in] The type of module to check
- Returns:
true if supported by any sub-factory, false otherwise
-
PuschModuleFactory()#
-
struct PuschOutput#
- #include <pusch_defines.hpp>
PUSCH Output Data
Contains all output results from PUSCH processing.
Public Members
-
std::vector<std::uint32_t> tb_crcs#
Transport block CRCs.
-
std::vector<std::uint8_t*> tb_payloads#
Transport block payloads.
-
void *d_tb_payloads = {}#
pointer to device memory containing Transport block payloads
-
std::vector<float> post_eq_noise_var_db#
Post-EQ noise variance db.
-
std::vector<float> post_eq_sinr_db#
Post-EQ SINR db.
-
std::vector<std::uint32_t> tb_crcs#
-
class PuschPipeline : public framework::pipeline::IPipeline#
- #include <pusch_pipeline.hpp>
PUSCH Pipeline
Pipeline for PUSCH processing:
External Inputs ─→ InnerRx module (TensorRT) ─→ LDPC derate match module (CUDA) ─→ LDPC decoder module ─→ CRC decoder module ─→ External Outputs
Features:
The full pipeline for PUSCH processing
InnerRx module: TensorRT-based processing
Channel decoding chain modules: CUDA-based LDPC decoding
Stream and graph execution modes
External input/output handling
Memory management
Public Functions
- explicit PuschPipeline(
- std::string pipeline_id,
- gsl_lite::not_null<framework::pipeline::IModuleFactory*> module_factory,
- const framework::pipeline::PipelineSpec &spec,
Construct PUSCH pipeline using factory pattern
Creates all modules via the provided factory and configures the pipeline according to the PipelineSpec.
- Parameters:
pipeline_id – [in] Unique identifier for pipeline instance
module_factory – [in] Factory for creating modules (non-owning pointer)
spec – [in] Pipeline specification with module configurations
- Throws:
std::invalid_argument – if spec doesn’t have exactly 4 modules
std::runtime_error – if module creation fails
-
~PuschPipeline() override = default#
-
PuschPipeline(const PuschPipeline&) = delete#
-
PuschPipeline &operator=(const PuschPipeline&) = delete#
-
PuschPipeline(PuschPipeline&&) = delete#
-
PuschPipeline &operator=(PuschPipeline&&) = delete#
-
inline virtual std::string_view get_pipeline_id() const override#
Get pipeline identifier
- Returns:
Pipeline ID string
-
inline virtual std::size_t get_num_external_inputs() const override#
Get number of external inputs
- Returns:
Number of external input ports
-
inline virtual std::size_t get_num_external_outputs() const override#
Get number of external outputs
- Returns:
Number of external output ports
-
inline framework::pipeline::ExecutionMode get_execution_mode() const#
Get pipeline execution mode
- Returns:
Execution mode (Stream or Graph)
-
virtual void setup() override#
Setup pipeline and modules
Allocates memory and initializes all modules
-
virtual void warmup(cudaStream_t stream) override#
Warmup pipeline execution
- Parameters:
stream – [in] CUDA stream for warmup
- virtual void configure_io(
- const framework::pipeline::DynamicParams ¶ms,
- std::span<const framework::pipeline::PortInfo> external_inputs,
- std::span<framework::pipeline::PortInfo> external_outputs,
- cudaStream_t stream,
Configure pipeline I/O for the current iteration.
Routes external inputs to modules and calls configure_io() on each module. Copies dynamic kernel descriptors to device and synchronizes stream. Routes module outputs to external outputs.
- Parameters:
params – [in] Dynamic parameters for this iteration
external_inputs – [in] External input port information
external_outputs – [out] External output port information to populate
stream – [in] CUDA stream for any necessary operations
- Throws:
std::invalid_argument – if dynamic parameters are invalid
-
virtual void execute_stream(cudaStream_t stream) override#
Execute pipeline in stream mode
- Parameters:
stream – [in] CUDA stream for execution
-
virtual void execute_graph(cudaStream_t stream) override#
Execute pipeline in graph mode
- Parameters:
stream – [in] CUDA stream for execution
- Throws:
std::runtime_error – if not in graph mode or if graph build fails
std::runtime_error – if graph execution fails
-
class PuschPipelineRunner#
- #include <pusch_pipeline_runner.hpp>
Pipeline execution helper for benchmarks and tests
Encapsulates pipeline setup, configuration, and execution for benchmarking. Follows RAII - pipeline is fully initialized upon construction.
Public Functions
- PuschPipelineRunner(
- const std::string &test_vector_path,
- framework::pipeline::ExecutionMode execution_mode,
Construct and initialize pipeline with test vector
- Parameters:
test_vector_path – [in] Full path to H5 test vector file
execution_mode – [in] Execution mode (Stream or Graph)
-
~PuschPipelineRunner() = default#
-
PuschPipelineRunner(const PuschPipelineRunner&) = delete#
-
PuschPipelineRunner &operator=(const PuschPipelineRunner&) = delete#
-
PuschPipelineRunner(PuschPipelineRunner&&) noexcept = default#
Move constructor
- PuschPipelineRunner &operator=( ) noexcept = default#
Move assignment operator
- Returns:
Reference to this object
-
void configure(const framework::utils::CudaStream &stream)#
Configure I/O and dynamic parameters
Call once before execute_once() or after parameter changes.
- Parameters:
stream – [in] CUDA stream for execution
-
void warmup(cudaStream_t stream)#
Warmup pipeline execution paths
- Parameters:
stream – [in] CUDA stream for warmup
-
void execute_once(const framework::utils::CudaStream &stream)#
Execute one iteration of the pipeline
Only performs execute_stream() or execute_graph() call.
- Parameters:
stream – [in] CUDA stream for execution
-
framework::pipeline::ExecutionMode get_execution_mode() const#
Get pipeline execution mode
- Returns:
Execution mode (Stream or Graph)
-
std::size_t get_num_external_outputs() const#
Get number of external outputs
- Returns:
Count of external output ports
- inline const std::vector<framework::pipeline::PortInfo> &get_external_outputs(
Get external outputs after execution
- Returns:
Vector of external output port information
-
inline const ran::common::PhyParams &get_phy_params() const#
Get PhyParams
- Returns:
Physical layer parameters
- inline const ran::aerial_tv::CuphyPuschTestVector &get_test_vector(
Get test vector
- Returns:
Test vector used for pipeline configuration
-
struct PuschUeParams#
- #include <pusch_defines.hpp>
PUSCH UE parameters structure
Public Members
-
uint16_t cell_id = {}#
Cell ID (0-65535)
-
uint16_t sfn = {}#
System Frame Number (0-1023)
-
uint16_t rnti = {}#
Radio Network Temporary Identifier (0-65535)
-
uint32_t handle = {}#
Handle for UL indication.
-
uint16_t target_code_rate = {}#
Target code rate.
-
uint8_t qam_mod_order = {}#
QAM modulation order (2,4,6,8 for TP disabled; 1,2,4,6,8 for TP enabled)
-
uint8_t mcs_index = {}#
MCS index (0-31)
-
uint8_t mcs_table = {}#
MCS table index (0-4)
-
uint8_t transform_precoding = {}#
Transform precoding (0-1)
-
uint16_t data_scrambling_id = {}#
Data scrambling ID (0-65535)
-
uint8_t num_layers = {}#
Number of layers (1-4)
-
uint16_t dmrs_sym_pos_bmsk = {}#
DMRS symbol position bitmask.
-
uint8_t num_dmrs_cdm_grps_no_data = {}#
Number of DMRS CDM groups without data.
-
uint16_t start_prb = {}#
Start physical resource block for RA type 1.
-
uint16_t num_prb = {}#
Number of physical resource blocks for RA type 1.
-
uint8_t num_symbols = {}#
Number of symbols.
-
uint8_t start_symbol_index = {}#
Start symbol index.
-
uint8_t rv_index = {}#
Redundancy version index (0-3)
-
uint8_t harq_process_id = {}#
HARQ process ID (0-15)
-
uint8_t ndi = {}#
New data indicator (0-1)
-
uint32_t tb_size = {}#
Transport block size in bytes.
-
uint16_t cell_id = {}#