From 00e50f082d9a0ca7f04c92896e6589c5c8509a7e Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 10 Sep 2024 10:38:48 +0200 Subject: [PATCH] Limit recursion in polar decoder Use non-recursive polar decoder after traversing the tree once. Maximum number of nodes is set to 600 (unsure of the maximum). This is more performant than the recursive version. --- .../nrPolar_tools/nr_polar_decoding_tools.c | 46 +++++++++++++++++-- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 14 +++++- openair1/PHY/CODING/nr_polar_init.c | 2 +- 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c index 412f1a9a48..21827c4bc5 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -390,17 +390,55 @@ static inline void computeBeta(decoder_node_t *node) node->betaInit = true; } -void generic_polar_decoder(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) -{ +void generic_polar_decoder_recursive(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) { // Apply F to left applyFtoleft(pp, node, nr_polar_U); + int iter = pp->tree_linearization.iter++; + pp->tree_linearization.op_list[iter].op_code = POLAR_OP_CODE_LEFT; + pp->tree_linearization.op_list[iter].node = node; + // if left is not a leaf recurse down to the left if (node->left->leaf==0) - generic_polar_decoder(pp, node->left, nr_polar_U); + generic_polar_decoder_recursive(pp, node->left, nr_polar_U); applyGtoright(pp, node, nr_polar_U); + iter = pp->tree_linearization.iter++; + pp->tree_linearization.op_list[iter].op_code = POLAR_OP_CODE_RIGHT; + pp->tree_linearization.op_list[iter].node = node; + if (node->right->leaf == 0) - generic_polar_decoder(pp, node->right, nr_polar_U); + generic_polar_decoder_recursive(pp, node->right, nr_polar_U); computeBeta(node); + + iter = pp->tree_linearization.iter++; + pp->tree_linearization.op_list[iter].op_code = POLAR_OP_CODE_BETA; + pp->tree_linearization.op_list[iter].node = node; +} + +void generic_polar_decoder(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U) +{ + if (pp->tree_linearization.is_initialized == false) { + pp->tree_linearization.iter = 0; + generic_polar_decoder_recursive(pp, node, nr_polar_U); + pp->tree_linearization.is_initialized = true; + AssertFatal(pp->tree_linearization.iter < sizeofArray(pp->tree_linearization.op_list), + "Arbitrary size %lu is too small, number of operations is %d", + sizeofArray(pp->tree_linearization.op_list), + pp->tree_linearization.iter); + } else { + for (int i = 0; i < pp->tree_linearization.iter; i++) { + decoder_node_t *n = pp->tree_linearization.op_list[i].node; + switch (pp->tree_linearization.op_list[i].op_code) { + case POLAR_OP_CODE_LEFT: + applyFtoleft(pp, n, nr_polar_U); + break; + case POLAR_OP_CODE_RIGHT: + applyGtoright(pp, n, nr_polar_U); + break; + case POLAR_OP_CODE_BETA: + computeBeta(n); + } + } + } } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 83819018a9..546260a5f2 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -60,6 +60,10 @@ static const uint8_t nr_polar_subblock_interleaver_pattern[32] = {0,1,2,4,3,5,6, #define uint128_t __uint128_t +#define POLAR_OP_CODE_LEFT 0 +#define POLAR_OP_CODE_RIGHT 1 +#define POLAR_OP_CODE_BETA 2 + typedef struct decoder_node_t_s { struct decoder_node_t_s *left; struct decoder_node_t_s *right; @@ -114,6 +118,14 @@ typedef struct nrPolar_params { uint64_t cprime_tab0[16][256]; uint64_t cprime_tab1[16][256]; decoder_tree_t decoder; + struct { + int iter; + bool is_initialized; + struct { + int op_code; + decoder_node_t* node; + } op_list[600]; + } tree_linearization; } t_nrPolar_params; void polar_encoder(uint32_t *input, @@ -159,7 +171,7 @@ int8_t polar_decoder_dci(double *input, uint16_t messageLength, uint8_t aggregation_level); -void generic_polar_decoder(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U); +void generic_polar_decoder(t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U); static inline int16_t *treeAlpha(decoder_node_t *node) { diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index 1b04f76da3..899aa5447f 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -98,7 +98,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params)); AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created"); - *newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList}; + *newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList, .tree_linearization.is_initialized = false}; PolarList = newPolarInitNode; pthread_mutex_unlock(&PolarListMutex); // LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime);