mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 12:40:28 +00:00
Compare commits
4 Commits
pucch2_deb
...
ldpc_lib_s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3959b04335 | ||
|
|
faa49f46c9 | ||
|
|
478428af3b | ||
|
|
de55c1883b |
@@ -1329,6 +1329,18 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nrLDPC_coding_claim_decode(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters, int8_t *claims)
|
||||
{
|
||||
for (int i = 0; i < nrLDPC_slot_decoding_parameters->nb_TBs; i++) {
|
||||
nrLDPC_TB_decoding_parameters_t *nrLDPC_TB_decoding_parameters = &nrLDPC_slot_decoding_parameters->TBs[i];
|
||||
if (nrLDPC_TB_decoding_parameters->Z >= 128 && nrLDPC_TB_decoding_parameters->BG == 1 && nrLDPC_TB_decoding_parameters->segments[0].R < 89) {
|
||||
claims[i] = 1;
|
||||
} else {
|
||||
claims[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters)
|
||||
{
|
||||
pthread_mutex_lock(&encode_mutex);
|
||||
@@ -1367,3 +1379,15 @@ int32_t nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_enc
|
||||
pthread_mutex_unlock(&encode_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void nrLDPC_coding_claim_encode(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters, int8_t *claims)
|
||||
{
|
||||
for (int i = 0; i < nrLDPC_slot_encoding_parameters->nb_TBs; i++) {
|
||||
nrLDPC_TB_encoding_parameters_t *nrLDPC_TB_encoding_parameters = &nrLDPC_slot_encoding_parameters->TBs[i];
|
||||
if (nrLDPC_TB_encoding_parameters->BG == 1 && nrLDPC_TB_encoding_parameters->C > 8 && nrLDPC_TB_encoding_parameters->Z == 384) {
|
||||
claims[i] = 1;
|
||||
} else {
|
||||
claims[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,12 +235,32 @@ typedef struct nrLDPC_slot_encoding_parameters_s{
|
||||
typedef int32_t(nrLDPC_coding_init_t)(void);
|
||||
typedef int32_t(nrLDPC_coding_shutdown_t)(void);
|
||||
|
||||
/**
|
||||
* \brief slot decoding claim function interface
|
||||
* through the value returned by this function the LDPC coding library indicates for each Transport Block
|
||||
* whether it supports decoding the Transport Block and whether it is worth using this implementation
|
||||
* \param nrLDPC_slot_decoding_parameters pointer to the structure holding the parameters necessary for decoding
|
||||
* \param claims array of claims upon the Transport blocks of the slot:
|
||||
* < 0 means not supported, == 0 means supported but not recommended and > 0 means supported and recommended
|
||||
*/
|
||||
typedef void(nrLDPC_coding_claim_decode_t)(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters, int8_t *claims);
|
||||
|
||||
/**
|
||||
* \brief slot decoding function interface
|
||||
* \param nrLDPC_slot_decoding_parameters pointer to the structure holding the parameters necessary for decoding
|
||||
*/
|
||||
typedef int32_t(nrLDPC_coding_decoder_t)(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters);
|
||||
|
||||
/**
|
||||
* \brief slot encoding claim function interface
|
||||
* through the claims filled returned by this function the LDPC coding library indicates for each Transport Block
|
||||
* whether it supports encoding the Transport Black and whether it is worth using this implementation
|
||||
* \param nrLDPC_slot_encoding_parameters pointer to the structure holding the parameters necessary for encoding
|
||||
* \param claims array of claims upon the Transport blocks of the slot:
|
||||
* < 0 means not supported, == 0 means supported but not recommended and > 0 means supported and recommended
|
||||
*/
|
||||
typedef void(nrLDPC_coding_claim_encode_t)(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters, int8_t *claims);
|
||||
|
||||
/**
|
||||
* \brief slot encoding function interface
|
||||
* \param nrLDPC_slot_encoding_parameters pointer to the structure holding the parameters necessary for encoding
|
||||
@@ -250,11 +270,25 @@ typedef int32_t(nrLDPC_coding_encoder_t)(nrLDPC_slot_encoding_parameters_t *nrLD
|
||||
typedef struct nrLDPC_coding_interface_s {
|
||||
nrLDPC_coding_init_t *nrLDPC_coding_init;
|
||||
nrLDPC_coding_shutdown_t *nrLDPC_coding_shutdown;
|
||||
nrLDPC_coding_claim_decode_t *nrLDPC_coding_claim_decode;
|
||||
nrLDPC_coding_decoder_t *nrLDPC_coding_decoder;
|
||||
nrLDPC_coding_claim_encode_t *nrLDPC_coding_claim_encode;
|
||||
nrLDPC_coding_encoder_t *nrLDPC_coding_encoder;
|
||||
} nrLDPC_coding_interface_t;
|
||||
|
||||
/**
|
||||
* \brief LDPC coding library loading function
|
||||
* \param specifier specifies the configmodule argument to be queried
|
||||
* the loader loads the library provided with argument --loader.ldpc.<specifier>.shlibversion or --loader.ldpc.<specifier>.shlibpath
|
||||
* if specifier is NULL then the loader loads the library provided with argument --loader.ldpc.shlibversion or --loader.ldpc.shlibpath
|
||||
* \param version if not NULL then overrides the library version provided by configmodule
|
||||
* \param interface pointer to the interface structure
|
||||
*/
|
||||
int load_nrLDPC_coding_interface(char *version, nrLDPC_coding_interface_t *interface);
|
||||
/**
|
||||
* \brief LDPC coding library release function
|
||||
* \param interface pointer to the interface structure
|
||||
*/
|
||||
int free_nrLDPC_coding_interface(nrLDPC_coding_interface_t *interface);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -50,18 +50,22 @@ int load_nrLDPC_coding_interface(char *version, nrLDPC_coding_interface_t *itf)
|
||||
/* function description array, to be used when loading the encoding/decoding shared lib */
|
||||
loader_shlibfunc_t shlib_fdesc[] = {{.fname = "nrLDPC_coding_init"},
|
||||
{.fname = "nrLDPC_coding_shutdown"},
|
||||
{.fname = "nrLDPC_coding_claim_decode"},
|
||||
{.fname = "nrLDPC_coding_decoder"},
|
||||
{.fname = "nrLDPC_coding_claim_encode"},
|
||||
{.fname = "nrLDPC_coding_encoder"}};
|
||||
int ret;
|
||||
ret = load_module_version_shlib(libname, version, shlib_fdesc, sizeofArray(shlib_fdesc), NULL);
|
||||
if(ret < 0){
|
||||
LOG_D(PHY, "NR ULSCH decoding module unavailable");
|
||||
LOG_D(PHY, "NR channel coding module unavailable");
|
||||
return ret;
|
||||
}
|
||||
itf->nrLDPC_coding_init = (nrLDPC_coding_init_t *)shlib_fdesc[0].fptr;
|
||||
itf->nrLDPC_coding_shutdown = (nrLDPC_coding_shutdown_t *)shlib_fdesc[1].fptr;
|
||||
itf->nrLDPC_coding_decoder = (nrLDPC_coding_decoder_t *)shlib_fdesc[2].fptr;
|
||||
itf->nrLDPC_coding_encoder = (nrLDPC_coding_encoder_t *)shlib_fdesc[3].fptr;
|
||||
itf->nrLDPC_coding_claim_decode = (nrLDPC_coding_claim_decode_t *)shlib_fdesc[2].fptr;
|
||||
itf->nrLDPC_coding_decoder = (nrLDPC_coding_decoder_t *)shlib_fdesc[3].fptr;
|
||||
itf->nrLDPC_coding_claim_encode = (nrLDPC_coding_claim_encode_t *)shlib_fdesc[4].fptr;
|
||||
itf->nrLDPC_coding_encoder = (nrLDPC_coding_encoder_t *)shlib_fdesc[5].fptr;
|
||||
|
||||
AssertFatal(itf->nrLDPC_coding_init() == 0, "error starting LDPC library %s %s\n", libname, version);
|
||||
|
||||
|
||||
@@ -317,3 +317,10 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nrLDPC_coding_claim_decode(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters, int8_t *claims)
|
||||
{
|
||||
for (int i = 0; i < nrLDPC_slot_decoding_parameters->nb_TBs; i++) {
|
||||
claims[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,3 +501,10 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nrLDPC_coding_claim_encode(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters, int8_t *claims)
|
||||
{
|
||||
for (int i = 0; i < nrLDPC_slot_encoding_parameters->nb_TBs; i++) {
|
||||
claims[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,13 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *slot_params, in
|
||||
return nbDecode;
|
||||
}
|
||||
|
||||
void nrLDPC_coding_claim_decode(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_decoding_parameters, int8_t *claims)
|
||||
{
|
||||
for (int i = 0; i < nrLDPC_slot_decoding_parameters->nb_TBs; i++) {
|
||||
claims[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
int32_t nrLDPC_coding_encoder(void)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "executables/nr-softmodem-common.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "common/utils/load_module_shlib.h"
|
||||
#include "common/ran_context.h"
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/NR_REFSIG/nr_refsig.h"
|
||||
@@ -137,6 +138,31 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
int ret_loader = load_nrLDPC_coding_interface(NULL, &gNB->nrLDPC_coding_interface);
|
||||
AssertFatal(ret_loader == 0, "error loading LDPC library\n");
|
||||
|
||||
// load LDPC offload library
|
||||
// First query configmodule to know if an offload library was provided
|
||||
char *shlibversion = NULL;
|
||||
// clang-format off
|
||||
paramdef_t LoaderParams[] = {
|
||||
{"shlibversion", NULL, 0, .strptr = &shlibversion, .defstrval = NULL, TYPE_STRING, 0, NULL}
|
||||
};
|
||||
// clang-format on
|
||||
char cfgprefix[sizeof(LOADER_CONFIG_PREFIX) + 30];
|
||||
sprintf(cfgprefix, LOADER_CONFIG_PREFIX ".ldpc.offload");
|
||||
int ret_cfgmodule = config_get(config_get_if(), LoaderParams, sizeofArray(LoaderParams), cfgprefix);
|
||||
if (ret_cfgmodule <0) {
|
||||
fprintf(stderr, "[LOADER] %s %d couldn't retrieve config from section %s\n", __FILE__, __LINE__, cfgprefix);
|
||||
}
|
||||
if (shlibversion != NULL) {
|
||||
// an offload library was provided, load it
|
||||
LOG_D(PHY, "LDPC offload library provided\n");
|
||||
ret_loader = load_nrLDPC_coding_interface(shlibversion, &gNB->nrLDPC_coding_interface_offload);
|
||||
gNB->use_offload = (ret_loader == 0);
|
||||
} else {
|
||||
// no offload library
|
||||
LOG_D(PHY, "No LDPC offload library provided\n");
|
||||
gNB->use_offload = false;
|
||||
}
|
||||
|
||||
gNB->max_nb_pdsch = MAX_MOBILES_PER_GNB;
|
||||
init_delay_table(fp->ofdm_symbol_size, MAX_DELAY_COMP, NR_MAX_OFDM_SYMBOL_SIZE, fp->delay_table);
|
||||
init_delay_table(128, MAX_DELAY_COMP, 128, fp->delay_table128);
|
||||
@@ -283,6 +309,9 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
|
||||
free(gNB->pusch_vars);
|
||||
|
||||
free_nrLDPC_coding_interface(&gNB->nrLDPC_coding_interface);
|
||||
if (gNB->use_offload) {
|
||||
free_nrLDPC_coding_interface(&gNB->nrLDPC_coding_interface_offload);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -280,7 +280,62 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
.tparity = tparity,
|
||||
.toutput = toutput,
|
||||
.TBs = TBs};
|
||||
gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters);
|
||||
|
||||
if (gNB->use_offload) {
|
||||
// get claims from default implementation
|
||||
int8_t claims_default[n_dlsch];
|
||||
memset(claims_default, 0xff, n_dlsch * sizeof(int8_t));
|
||||
gNB->nrLDPC_coding_interface.nrLDPC_coding_claim_encode(&slot_parameters, claims_default);
|
||||
|
||||
// get claims from offload implementation
|
||||
int8_t claims_offload[n_dlsch];
|
||||
memset(claims_offload, 0xff, n_dlsch * sizeof(int8_t));
|
||||
gNB->nrLDPC_coding_interface_offload.nrLDPC_coding_claim_encode(&slot_parameters, claims_offload);
|
||||
|
||||
// split and count TBs
|
||||
nrLDPC_TB_encoding_parameters_t TBs_default[n_dlsch];
|
||||
uint8_t pdsch_id_default = 0;
|
||||
nrLDPC_TB_encoding_parameters_t TBs_offload[n_dlsch];
|
||||
uint8_t pdsch_id_offload = 0;
|
||||
for (uint8_t pdsch_id = 0; pdsch_id < n_dlsch; pdsch_id++) {
|
||||
if (claims_offload[pdsch_id] > 0 && claims_offload[pdsch_id] > claims_default[pdsch_id]) {
|
||||
TBs_offload[pdsch_id_offload] = TBs[pdsch_id];
|
||||
pdsch_id_offload++;
|
||||
} else {
|
||||
TBs_default[pdsch_id_default] = TBs[pdsch_id];
|
||||
pdsch_id_default++;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO parallelize
|
||||
if (pdsch_id_default > 0) {
|
||||
nrLDPC_slot_encoding_parameters_t slot_parameters_default = {.frame = frame,
|
||||
.slot = slot,
|
||||
.nb_TBs = pdsch_id_default,
|
||||
.threadPool = &gNB->threadPool,
|
||||
.tinput = tinput,
|
||||
.tprep = tprep,
|
||||
.tparity = tparity,
|
||||
.toutput = toutput,
|
||||
.TBs = TBs_default};
|
||||
gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters_default);
|
||||
}
|
||||
|
||||
if (pdsch_id_offload > 0) {
|
||||
nrLDPC_slot_encoding_parameters_t slot_parameters_offload = {.frame = frame,
|
||||
.slot = slot,
|
||||
.nb_TBs = pdsch_id_offload,
|
||||
.threadPool = &gNB->threadPool,
|
||||
.tinput = tinput,
|
||||
.tprep = tprep,
|
||||
.tparity = tparity,
|
||||
.toutput = toutput,
|
||||
.TBs = TBs_offload};
|
||||
gNB->nrLDPC_coding_interface_offload.nrLDPC_coding_encoder(&slot_parameters_offload);
|
||||
}
|
||||
} else {
|
||||
gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n_dlsch; i++) {
|
||||
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[i];
|
||||
|
||||
@@ -281,7 +281,56 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
}
|
||||
}
|
||||
|
||||
int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
|
||||
int ret_decoder = 0;
|
||||
if (phy_vars_gNB->use_offload) {
|
||||
// get claims from default implementation
|
||||
int8_t claims_default[nb_pusch];
|
||||
memset(claims_default, 0xff, nb_pusch * sizeof(int8_t));
|
||||
phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_claim_decode(&slot_parameters, claims_default);
|
||||
|
||||
// get claims from offload implementation
|
||||
int8_t claims_offload[nb_pusch];
|
||||
memset(claims_offload, 0xff, nb_pusch * sizeof(int8_t));
|
||||
phy_vars_gNB->nrLDPC_coding_interface_offload.nrLDPC_coding_claim_decode(&slot_parameters, claims_offload);
|
||||
|
||||
// split and count TBs
|
||||
nrLDPC_TB_decoding_parameters_t TBs_default[nb_pusch];
|
||||
uint8_t pusch_id_default = 0;
|
||||
nrLDPC_TB_decoding_parameters_t TBs_offload[nb_pusch];
|
||||
uint8_t pusch_id_offload = 0;
|
||||
for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) {
|
||||
if (claims_offload[pusch_id] > 0 && claims_offload[pusch_id] > claims_default[pusch_id]) {
|
||||
TBs_offload[pusch_id_offload] = TBs[pusch_id];
|
||||
pusch_id_offload++;
|
||||
} else {
|
||||
TBs_default[pusch_id_default] = TBs[pusch_id];
|
||||
pusch_id_default++;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO parallelize
|
||||
if (pusch_id_default > 0) {
|
||||
nrLDPC_slot_decoding_parameters_t slot_parameters_default = {.frame = frame,
|
||||
.slot = nr_tti_rx,
|
||||
.nb_TBs = pusch_id_default,
|
||||
.threadPool = &phy_vars_gNB->threadPool,
|
||||
.TBs = TBs_default};
|
||||
int ret_default = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters_default);
|
||||
ret_decoder = ret_default == 0 ? ret_decoder : ret_default;
|
||||
}
|
||||
|
||||
if (pusch_id_offload > 0) {
|
||||
nrLDPC_slot_decoding_parameters_t slot_parameters_offload = {.frame = frame,
|
||||
.slot = nr_tti_rx,
|
||||
.nb_TBs = pusch_id_offload,
|
||||
.threadPool = &phy_vars_gNB->threadPool,
|
||||
.TBs = TBs_offload};
|
||||
int ret_offload = phy_vars_gNB->nrLDPC_coding_interface_offload.nrLDPC_coding_decoder(&slot_parameters_offload);
|
||||
ret_decoder = ret_offload == 0 ? ret_decoder : ret_offload;
|
||||
}
|
||||
} else {
|
||||
ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
|
||||
}
|
||||
|
||||
// post decode
|
||||
for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) {
|
||||
|
||||
@@ -421,6 +421,8 @@ typedef struct PHY_VARS_gNB_s {
|
||||
|
||||
/// NR LDPC coding related
|
||||
nrLDPC_coding_interface_t nrLDPC_coding_interface;
|
||||
nrLDPC_coding_interface_t nrLDPC_coding_interface_offload;
|
||||
bool use_offload;
|
||||
int max_ldpc_iterations;
|
||||
|
||||
/// indicate the channel estimation technique in time domain
|
||||
|
||||
Reference in New Issue
Block a user