Compare commits

...

1 Commits

Author SHA1 Message Date
Romain Beurdouche
d458e221c5 feat(ldpc_tee): Add LDPC library tee
ldpc_tee is an LDPC library acting as a tee that distributes TBs between
two libraries according to some criterion implmented in the tee library.
2026-02-10 14:57:52 +01:00
4 changed files with 202 additions and 1 deletions

View File

@@ -41,7 +41,7 @@ BUILD_DIR=ran_build
DISABLE_HARDWARE_DEPENDENCY="False"
CMAKE_BUILD_TYPE="RelWithDebInfo"
CMAKE_CMD="$CMAKE"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_aal ldpc_xdma websrv oai_iqplayer imscope imscope_record"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_aal ldpc_xdma ldpc_tee websrv oai_iqplayer imscope imscope_record"
TARGET_LIST=""
BUILD_TOOL_OPT="-j$(nproc)"

View File

@@ -1,3 +1,4 @@
add_subdirectory(nrLDPC_coding_segment)
add_subdirectory(nrLDPC_coding_xdma)
add_subdirectory(nrLDPC_coding_aal)
add_subdirectory(nrLDPC_coding_tee)

View File

@@ -0,0 +1,19 @@
##########################################################
# LDPC tee library - tee to two libraries
##########################################################
add_boolean_option(ENABLE_LDPC_TEE OFF "Build support for LDPC tee to two LDPC libraries" OFF)
if (ENABLE_LDPC_TEE)
add_library(ldpc_tee MODULE nrLDPC_coding_tee.c)
set_target_properties(ldpc_tee PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
add_dependencies(nr-softmodem ldpc_tee)
add_dependencies(nr-uesoftmodem ldpc_tee)
add_dependencies(nr_ulsim ldpc_tee)
add_dependencies(nr_ulschsim ldpc_tee)
add_dependencies(nr_dlsim ldpc_tee)
add_dependencies(nr_dlschsim ldpc_tee)
endif()

View File

@@ -0,0 +1,181 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/CODING/nrLDPC_coding/nrLDPC_coding_tee/nrLDPC_coding_tee.c
* \brief LDPC coding library acting as a tee between two LDPC libraries.
* It distributes the TBs between the two libraries according to some criterion.
*/
#include "PHY/CODING/nrLDPC_coding/nrLDPC_coding_interface.h"
nrLDPC_coding_interface_t nrLDPC_coding_interface_default, nrLDPC_coding_interface_offload;
bool choose_offload_decode(nrLDPC_TB_decoding_parameters_t *TB)
{
return TB->Z >= 128 && TB->BG == 1 && TB->segments[0].R < 89;
}
int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters)
{
uint8_t nb_tb = nrLDPC_slot_decoding_parameters->nb_TBs;
nrLDPC_TB_decoding_parameters_t *TBs = nrLDPC_slot_decoding_parameters->TBs;
// split and count TBs
nrLDPC_TB_decoding_parameters_t TBs_default[nb_tb];
uint8_t tb_id_default = 0;
nrLDPC_TB_decoding_parameters_t TBs_offload[nb_tb];
uint8_t tb_id_offload = 0;
for (uint8_t tb_id = 0; tb_id < nb_tb; tb_id++) {
if (choose_offload_decode(&TBs[tb_id])) {
TBs_offload[tb_id_offload] = TBs[tb_id];
tb_id_offload++;
} else {
TBs_default[tb_id_default] = TBs[tb_id];
tb_id_default++;
}
}
// TODO parallelize
int ret_decoder = 0;
if (tb_id_default > 0) {
nrLDPC_slot_decoding_parameters_t slot_parameters_default = {.frame = nrLDPC_slot_decoding_parameters->frame,
.slot = nrLDPC_slot_decoding_parameters->slot,
.nb_TBs = tb_id_default,
.threadPool = nrLDPC_slot_decoding_parameters->threadPool,
.TBs = TBs_default};
int ret_default = nrLDPC_coding_interface_default.nrLDPC_coding_decoder(&slot_parameters_default);
ret_decoder = ret_default == 0 ? ret_decoder : ret_default;
}
if (tb_id_offload > 0) {
nrLDPC_slot_decoding_parameters_t slot_parameters_offload = {.frame = nrLDPC_slot_decoding_parameters->frame,
.slot = nrLDPC_slot_decoding_parameters->slot,
.nb_TBs = tb_id_offload,
.threadPool = nrLDPC_slot_decoding_parameters->threadPool,
.TBs = TBs_offload};
int ret_offload = nrLDPC_coding_interface_offload.nrLDPC_coding_decoder(&slot_parameters_offload);
ret_decoder = ret_offload == 0 ? ret_decoder : ret_offload;
}
return ret_decoder;
}
bool choose_offload_encode(nrLDPC_TB_encoding_parameters_t *TB)
{
return TB->BG == 1 && TB->C > 8 && TB->Z == 384;
}
int32_t nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters)
{
uint8_t nb_tb = nrLDPC_slot_encoding_parameters->nb_TBs;
nrLDPC_TB_encoding_parameters_t *TBs = nrLDPC_slot_encoding_parameters->TBs;
// split and count TBs
nrLDPC_TB_encoding_parameters_t TBs_default[nb_tb];
uint8_t tb_id_default = 0;
nrLDPC_TB_encoding_parameters_t TBs_offload[nb_tb];
uint8_t tb_id_offload = 0;
for (uint8_t tb_id = 0; tb_id < nb_tb; tb_id++) {
if (choose_offload_encode(&TBs[tb_id])) {
TBs_offload[tb_id_offload] = TBs[tb_id];
tb_id_offload++;
} else {
TBs_default[tb_id_default] = TBs[tb_id];
tb_id_default++;
}
}
// TODO parallelize
int ret_encoder = 0;
if (tb_id_default > 0) {
nrLDPC_slot_encoding_parameters_t slot_parameters_default = {.frame = nrLDPC_slot_encoding_parameters->frame,
.slot = nrLDPC_slot_encoding_parameters->slot,
.nb_TBs = tb_id_default,
.threadPool = nrLDPC_slot_encoding_parameters->threadPool,
.TBs = TBs_default};
int ret_default = nrLDPC_coding_interface_default.nrLDPC_coding_encoder(&slot_parameters_default);
ret_encoder = ret_default == 0 ? ret_encoder : ret_default;
}
if (tb_id_offload > 0) {
nrLDPC_slot_encoding_parameters_t slot_parameters_offload = {.frame = nrLDPC_slot_encoding_parameters->frame,
.slot = nrLDPC_slot_encoding_parameters->slot,
.nb_TBs = tb_id_offload,
.threadPool = nrLDPC_slot_encoding_parameters->threadPool,
.TBs = TBs_offload};
int ret_offload = nrLDPC_coding_interface_offload.nrLDPC_coding_encoder(&slot_parameters_offload);
ret_encoder = ret_offload == 0 ? ret_encoder : ret_offload;
}
return ret_encoder;
}
int32_t nrLDPC_coding_init(void)
{
int ret_init = 0;
// load LDPC default library
// First query configmodule to know which default library was provided
char *shlibversion_default = NULL;
// clang-format off
paramdef_t LoaderParams_default[] = {
{"shlibversion", NULL, 0, .strptr = &shlibversion_default, .defstrval = "", TYPE_STRING, 0, NULL}
};
// clang-format on
char *cfgprefix_default = "nrLDPC_coding_tee.default";
int ret_cfgmodule = config_get(config_get_if(), LoaderParams_default, sizeofArray(LoaderParams_default), cfgprefix_default);
if (ret_cfgmodule < 0) {
fprintf(stderr, "[LOADER] %s %d couldn't retrieve config from section %s\n", __FILE__, __LINE__, cfgprefix_default);
}
// load
int ret_loader = load_nrLDPC_coding_interface(shlibversion_default, &nrLDPC_coding_interface_default);
ret_init = ret_loader == 0 ? ret_init : ret_loader;
// load LDPC offload library
// First query configmodule to know which offload library was provided
char *shlibversion_offload = NULL;
// clang-format off
paramdef_t LoaderParams_offload[] = {
{"shlibversion", NULL, 0, .strptr = &shlibversion_offload, .defstrval = "", TYPE_STRING, 0, NULL}
};
// clang-format on
char *cfgprefix_offload = "nrLDPC_coding_tee.offload";
ret_cfgmodule = config_get(config_get_if(), LoaderParams_offload, sizeofArray(LoaderParams_offload), cfgprefix_offload);
if (ret_cfgmodule < 0) {
fprintf(stderr, "[LOADER] %s %d couldn't retrieve config from section %s\n", __FILE__, __LINE__, cfgprefix_offload);
}
// load
ret_loader = load_nrLDPC_coding_interface(shlibversion_offload, &nrLDPC_coding_interface_offload);
ret_init = ret_loader == 0 ? ret_init : ret_loader;
return ret_init;
}
int32_t nrLDPC_coding_shutdown(void)
{
int ret_shutdown = 0;
int ret_default = nrLDPC_coding_interface_default.nrLDPC_coding_shutdown();
ret_shutdown = ret_default == 0 ? ret_shutdown : ret_default;
int ret_offload = nrLDPC_coding_interface_offload.nrLDPC_coding_shutdown();
ret_shutdown = ret_offload == 0 ? ret_shutdown : ret_offload;
return ret_shutdown;
}