Commit 00e50f08 authored by Bartosz Podrygajlo's avatar Bartosz Podrygajlo Committed by Robert Schmidt

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.
parent a2352066
...@@ -390,17 +390,55 @@ static inline void computeBeta(decoder_node_t *node) ...@@ -390,17 +390,55 @@ static inline void computeBeta(decoder_node_t *node)
node->betaInit = true; 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 // Apply F to left
applyFtoleft(pp, node, nr_polar_U); 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 left is not a leaf recurse down to the left
if (node->left->leaf==0) 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); 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) 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); 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);
}
}
}
} }
...@@ -60,6 +60,10 @@ static const uint8_t nr_polar_subblock_interleaver_pattern[32] = {0,1,2,4,3,5,6, ...@@ -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 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 { typedef struct decoder_node_t_s {
struct decoder_node_t_s *left; struct decoder_node_t_s *left;
struct decoder_node_t_s *right; struct decoder_node_t_s *right;
...@@ -114,6 +118,14 @@ typedef struct nrPolar_params { ...@@ -114,6 +118,14 @@ typedef struct nrPolar_params {
uint64_t cprime_tab0[16][256]; uint64_t cprime_tab0[16][256];
uint64_t cprime_tab1[16][256]; uint64_t cprime_tab1[16][256];
decoder_tree_t decoder; 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; } t_nrPolar_params;
void polar_encoder(uint32_t *input, void polar_encoder(uint32_t *input,
...@@ -159,7 +171,7 @@ int8_t polar_decoder_dci(double *input, ...@@ -159,7 +171,7 @@ int8_t polar_decoder_dci(double *input,
uint16_t messageLength, uint16_t messageLength,
uint8_t aggregation_level); 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) static inline int16_t *treeAlpha(decoder_node_t *node)
{ {
......
...@@ -98,7 +98,7 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui ...@@ -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)); t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params));
AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created"); 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; PolarList = newPolarInitNode;
pthread_mutex_unlock(&PolarListMutex); 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); // LOG_D(PHY,"Setting new polarParams index %d, messageType %d, messageLength %d, aggregation_prime %d\n",(messageType * messageLength * aggregation_prime),messageType,messageLength,aggregation_prime);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment