Commit d57ea715 authored by Laurent THOMAS's avatar Laurent THOMAS Committed by Robert Schmidt

Improve polar decoder/encoder

- Ensure packed struct through bitfield
- decoder tree buffer increase: i don't find evidence in the 3GPP
  standard of the max size of polar coded PDU.  even with this max size,
  the way this tree is built is not trivial.  so, it is hard to predict,
  i just put 8 system pages (32KB) that looks enough [1]
- a lot of reformatting

[1] https://arxiv.org/pdf/1804.04389
according to this paper, the largest polar code in 5G is in UL, so
likely the biggest problem will be in gNB, not the UE.  in DL, the max
output coded block is 512, in UL 1024.  probably the tree we discuss is
related to this size.

"frozen bits" means only bits we don't encode/decode because polar code
size is only by power of 2.
We see this in OAI code:  NR_POLAR_PUCCH_N_MAX is 10, so 2^10 is 1024,
that is the maximum size for 5G polar code length.  in the code, we
assert if N > 512: "N = %d, not done yet\n",
polarParams->N".  so, the today OAI code can't do PUCCH large blocks.

using current oai limitation of 2⁹ max code size, we can create up to
2^9+2⁸... nodes, so 1023 nodes in the tree.  the problem then is that
each node have variable size, depending on the 'level' (the power of 2
we are currently).  the algo provision large alpha and beta to be able
to store all lower levels in the tree (int leaf_sz = 1 << level)
therefore upper tree nodes are large (the top level for n=9 uses about
1.5KB) and the bottom nodes uses 64 bytes.  if all nodes are populated,
the size will be very large: 1.5KB + 2 * 800 + ....  but, we create
nodes in the tree only for the "information bits", so the payload, that
is limited to 128 bits (else we assert, the code is not "finished").
1.5KB * 128 is >> 8KB i allocated.  but, we can't create more than one
mode at top level, so there is maximum 1.5KB + 2 * 800, + 4 * 400 + 8 *
200 + 16 * 100 + remaining of 128-32 nodes of 64 bytes.  about 14KB.

i allocated 1024*sizeof(__m256i) bytes = 32KB that looks good.
parent 6c1d94a3
......@@ -91,11 +91,12 @@ int main(int argc, char *argv[])
case 'L':
aggregation_level=atoi(optarg);
if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8 && aggregation_level != 16) {
printf("Illegal aggregation level %d \n",aggregation_level);
exit(-1);
}
break;
if (aggregation_level != 1 && aggregation_level != 2 && aggregation_level != 4 && aggregation_level != 8
&& aggregation_level != 16) {
printf("Illegal aggregation level %d \n", aggregation_level);
exit(-1);
}
break;
case 'k':
testLength=atoi(optarg);
......@@ -106,9 +107,10 @@ int main(int argc, char *argv[])
break;
case 'h':
printf("./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n"
"-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n"
"-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n");
printf(
"./polartest\nOptions\n-h Print this help\n-s SNRstart (dB)\n-d SNRinc (dB)\n-f SNRstop (dB)\n-m [0=PBCH|1=DCI|2=UCI]\n"
"-i Number of iterations\n-l decoderListSize\n-q Flag for optimized coders usage\n-F Flag for test results logging\n"
"-L aggregation level (for DCI)\n-k packet_length (bits) for DCI/UCI\n");
exit(-1);
break;
......@@ -186,7 +188,7 @@ int main(int argc, char *argv[])
double channelOutput[coderLength]; //add noise
int16_t channelOutput_int16[coderLength];
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level, true);
t_nrPolar_params *currentPtr = nr_polar_params(polarMessageType, testLength, aggregation_level);
#ifdef DEBUG_DCI_POLAR_PARAMS
uint32_t dci_pdu[4];
......@@ -283,30 +285,37 @@ int main(int argc, char *argv[])
channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin)));
if (decoder_int16==1) {
if (channelOutput[i] > 15) channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16) channelOutput_int16[i] = -128;
else channelOutput_int16[i] = (int16_t) (8*channelOutput[i]);
}
if (channelOutput[i] > 15)
channelOutput_int16[i] = 127;
else if (channelOutput[i] < -16)
channelOutput_int16[i] = -128;
else
channelOutput_int16[i] = (int16_t)(8 * channelOutput[i]);
}
}
start_meas(&timeDecoder);
if (decoder_int16==1) {
decoderState = polar_decoder_int16(channelOutput_int16, (uint64_t *)estimatedOutput, 0,
polarMessageType, testLength, aggregation_level);
decoderState = polar_decoder_int16(channelOutput_int16,
(uint64_t *)estimatedOutput,
0,
polarMessageType,
testLength,
aggregation_level);
} else { //0 --> PBCH, 1 --> DCI, -1 --> UCI
if (polarMessageType == 0) {
decoderState = polar_decoder(channelOutput,
estimatedOutput,
decoderListSize,
polarMessageType, testLength, aggregation_level);
} else if (polarMessageType == 1) {
decoderState = polar_decoder_dci(channelOutput,
estimatedOutput,
decoderListSize,
rnti,
polarMessageType, testLength, aggregation_level);
}
decoderState =
polar_decoder(channelOutput, estimatedOutput, decoderListSize, polarMessageType, testLength, aggregation_level);
} else if (polarMessageType == 1) {
decoderState = polar_decoder_dci(channelOutput,
estimatedOutput,
decoderListSize,
rnti,
polarMessageType,
testLength,
aggregation_level);
}
}
stop_meas(&timeDecoder);
......@@ -332,7 +341,12 @@ int main(int argc, char *argv[])
if (nBitError>0) blockErrorState=1;
#ifdef DEBUG_POLARTEST
for (int i = 0; i < testArrayLength; i++)
printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",decoderState, i, testInput[i], i, estimatedOutput[i]);
printf("[polartest/decoderState=%u] testInput[%d]=0x%08x, estimatedOutput[%d]=0x%08x\n",
decoderState,
i,
testInput[i],
i,
estimatedOutput[i]);
#endif
//Iteration times are in microseconds.
......
......@@ -66,7 +66,7 @@ int8_t polar_decoder(double *input,
uint8_t aggregation_level
)
{
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true);
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
//Assumes no a priori knowledge.
uint8_t bit[polarParams->N][polarParams->n + 1][2 * listSize];
memset(bit, 0, sizeof bit);
......@@ -329,7 +329,7 @@ int8_t polar_decoder_dci(double *input,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level ) {
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true);
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
uint8_t bit[polarParams->N][polarParams->n+1][2*listSize];
memset(bit,0,sizeof bit);
......@@ -595,25 +595,17 @@ int8_t polar_decoder_dci(double *input,
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
AssertFatal(polarParams->K > 17, "K = %d < 18, is not allowed\n",polarParams->K);
AssertFatal(polarParams->K < 129, "K = %d > 128, is not supported yet\n",polarParams->K);
int bit_i,ip,ipmod64;
int numbytes = polarParams->K>>3;
int residue = polarParams->K & 7;
if (residue > 0)
numbytes++;
int numbytes = (polarParams->K + 7) / 8;
for (int byte=0; byte<numbytes; byte++) {
int numbits = byte < (polarParams->K >> 3) ? 8 : residue;
int numbits = byte < (polarParams->K >> 3) ? 8 : polarParams->K & 7;
for (int i=0; i<numbits; i++) {
for (int bit = 0; bit < numbits; bit++) {
// flip bit endian for B
ip = polarParams->K - 1 - polarParams->interleaving_pattern[(8 * byte) + i];
ipmod64 = ip&63;
AssertFatal(ip<128,"ip = %d\n",ip);
int ip = polarParams->K - 1 - polarParams->interleaving_pattern[(8 * byte) + bit];
int ipmod64 = ip & 63;
AssertFatal(ip < 128, "ip = %d\n", ip);
for (int val=0; val<256; val++) {
bit_i=(val>>i)&1;
int bit_i = (val >> bit) & 1;
if (ip < 64)
polarParams->B_tab0[byte][val] |= ((uint64_t)bit_i) << ipmod64;
else
......@@ -623,6 +615,64 @@ void init_polar_deinterleaver_table(t_nrPolar_params *polarParams) {
}
}
static inline void nr_polar_rate_matching_int16(int16_t *input,
int16_t *output,
const uint16_t *rmp,
const uint16_t K,
const uint16_t N,
const uint16_t E,
const uint8_t i_bil)
{
if (E >= N) { // repetition
memset(output, 0, N * sizeof(*output));
for (int i = 0; i <= E - 1; i++)
output[rmp[i]] += input[i];
} else {
if ((K / (double)E) <= (7.0 / 16))
memset(output, 0, N * sizeof(*output)); // puncturing
else { // shortening
for (int i = 0; i <= N - 1; i++)
output[i] = 32767; // instead of INFINITY, to prevent [-Woverflow]
}
for (int i = 0; i <= E - 1; i++)
output[rmp[i]] = input[i];
}
}
static inline void nr_polar_info_extraction_from_u(uint64_t *Cprime,
const uint8_t *u,
const uint8_t *information_bit_pattern,
const uint8_t *parity_check_bit_pattern,
uint16_t N,
uint8_t n_pc)
{
int k = 0;
if (n_pc > 0) {
for (int n = 0; n < N; n++) {
if (information_bit_pattern[n] == 1) {
if (parity_check_bit_pattern[n] == 0) {
int k1 = k >> 6;
int k2 = k - (k1 << 6);
Cprime[k1] |= (uint64_t)u[n] << k2;
k++;
}
}
}
} else {
for (int n = 0; n < N; n++) {
if (information_bit_pattern[n] == 1) {
int k1 = k >> 6;
int k2 = k - (k1 << 6);
Cprime[k1] |= (uint64_t)u[n] << k2;
k++;
}
}
}
}
uint32_t polar_decoder_int16(int16_t *input,
uint64_t *out,
uint8_t ones_flag,
......@@ -630,12 +680,12 @@ uint32_t polar_decoder_int16(int16_t *input,
uint16_t messageLength,
uint8_t aggregation_level)
{
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, true);
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
const uint N = polarParams->N;
#ifdef POLAR_CODING_DEBUG
printf("\nRX\n");
printf("rm:");
for (int i = 0; i < polarParams->N; i++) {
for (int i = 0; i < N; i++) {
if (i % 4 == 0) {
printf(" ");
}
......@@ -644,25 +694,28 @@ uint32_t polar_decoder_int16(int16_t *input,
printf("\n");
#endif
int16_t d_tilde[polarParams->N];
nr_polar_rate_matching_int16(input,
int16_t d_tilde[N];
const uint E = polarParams->encoderLength;
int16_t inbis[E];
int16_t *input_deinterleaved;
if (polarParams->i_bil) {
for (int i = 0; i < E; i++)
inbis[i] = input[polarParams->i_bil_pattern[i]];
input_deinterleaved = inbis;
} else {
input_deinterleaved = input;
}
nr_polar_rate_matching_int16(input_deinterleaved,
d_tilde,
polarParams->rate_matching_pattern,
polarParams->K,
polarParams->N,
polarParams->encoderLength,
N,
E,
polarParams->i_bil);
for (int i=0; i<polarParams->N; i++) {
if (d_tilde[i] < -128)
d_tilde[i] = -128;
else if (d_tilde[i] > 127)
d_tilde[i] = 128;
}
#ifdef POLAR_CODING_DEBUG
printf("d: ");
for (int i = 0; i < polarParams->N; i++) {
for (int i = 0; i < N; i++) {
if (i % 4 == 0) {
printf(" ");
}
......@@ -670,15 +723,23 @@ uint32_t polar_decoder_int16(int16_t *input,
}
printf("\n");
#endif
memcpy(polarParams->tree.root->alpha, d_tilde, sizeof(d_tilde));
uint8_t nr_polar_U[polarParams->N];
uint8_t nr_polar_U[N];
memset(nr_polar_U, 0, sizeof(nr_polar_U));
generic_polar_decoder(polarParams, polarParams->tree.root, nr_polar_U);
static uint64_t cnt = 0, timeTree = 0, timeDecoder = 0;
uint64_t a = rdtsc_oai();
decoder_tree_t tree;
build_decoder_tree(&tree, polarParams);
uint64_t b = rdtsc_oai();
memcpy(treeAlpha(tree.root), d_tilde, sizeof(d_tilde));
generic_polar_decoder(polarParams, tree.root, nr_polar_U);
uint64_t c = rdtsc_oai();
timeTree += b - a;
timeDecoder += c - b;
if (cnt++ % 1000 == 0)
printf("tree: %ld, dec %ld\n", timeTree / (cnt), timeDecoder / (cnt));
#ifdef POLAR_CODING_DEBUG
printf("u: ");
for (int i = 0; i < polarParams->N; i++) {
for (int i = 0; i < N; i++) {
if (i % 4 == 0) {
printf(" ");
}
......@@ -693,7 +754,7 @@ uint32_t polar_decoder_int16(int16_t *input,
nr_polar_U,
polarParams->information_bit_pattern,
polarParams->parity_check_bit_pattern,
polarParams->N,
N,
polarParams->n_pc);
#ifdef POLAR_CODING_DEBUG
......@@ -718,17 +779,30 @@ uint32_t polar_decoder_int16(int16_t *input,
| polarParams->B_tab0[3][Cprimebyte[3]] | polarParams->B_tab0[4][Cprimebyte[4]] | polarParams->B_tab0[5][Cprimebyte[5]]
| polarParams->B_tab0[6][Cprimebyte[6]] | polarParams->B_tab0[7][Cprimebyte[7]];
} else if (polarParams->K<129) {
int len = polarParams->K/8;
if ((polarParams->K & 7) > 0)
len++;
for (int k=0; k<len; k++) {
for (int k = 0; k < 8; k++) {
B[0] |= polarParams->B_tab0[k][Cprimebyte[k]];
B[1] |= polarParams->B_tab1[k][Cprimebyte[k]];
}
}
uint128_t Cprime128 = *(uint128_t *)Cprime;
uint128_t res = 0;
uint deinterleaving_pattern[polarParams->K];
for (int i = 0; i < polarParams->K; i++)
deinterleaving_pattern[polarParams->interleaving_pattern[i]] = i;
for (int i = 0; i < polarParams->K; i++) {
uint128_t bit = (Cprime128 >> i) & 1;
res |= bit << (polarParams->K - 1 - deinterleaving_pattern[i]);
}
uint128_t B128 = *(uint128_t *)B;
printf("old:(k=%d)", polarParams->K);
for (int i = 0; i < polarParams->K; i++)
printf("%lld", (B128 >> i) & 1);
printf("\nnew:(k=%d)", polarParams->K);
for (int i = 0; i < polarParams->K; i++)
printf("%lld", (res >> i) & 1);
printf("\n\n");
#ifdef POLAR_CODING_DEBUG
int B_array = (polarParams->K + 63) >> 6;
int n_start = (B_array << 6) - polarParams->K;
......
......@@ -63,18 +63,18 @@ static const uint8_t nr_polar_subblock_interleaver_pattern[32] = {0,1,2,4,3,5,6,
typedef struct decoder_node_t_s {
struct decoder_node_t_s *left;
struct decoder_node_t_s *right;
int level;
int leaf;
int Nv;
int first_leaf_index;
int all_frozen;
int16_t *alpha;
int16_t *beta;
uint64_t level: 16;
uint64_t leaf: 16;
uint64_t first_leaf_index: 16;
uint64_t all_frozen: 1;
uint64_t betaInit: 1;
uint32_t alpha;
uint32_t beta;
} decoder_node_t;
typedef struct decoder_tree_t_s {
decoder_node_t *root;
int num_nodes;
simde__m256i buffer[1024]; // seems enough but to be refined
} decoder_tree_t;
typedef struct nrPolar_params {
......@@ -100,6 +100,7 @@ typedef struct nrPolar_params {
uint16_t *interleaving_pattern;
uint16_t *rate_matching_pattern;
uint16_t *i_bil_pattern;
const uint16_t *Q_0_Nminus1;
int16_t *Q_I_N;
int16_t *Q_F_N;
......@@ -110,13 +111,10 @@ typedef struct nrPolar_params {
const uint8_t **G_N;
int groupsize;
int *rm_tab;
uint64_t cprime_tab0[32][256];
uint64_t cprime_tab1[32][256];
uint64_t B_tab0[32][256];
uint64_t B_tab1[32][256];
// lowercase: bits, Uppercase: Bits stored in bytes
// polar_encoder vectors
decoder_tree_t tree;
uint64_t cprime_tab0[16][256];
uint64_t cprime_tab1[16][256];
uint64_t B_tab0[16][256];
uint64_t B_tab1[16][256];
} t_nrPolar_params;
void polar_encoder(uint32_t *input,
......@@ -164,19 +162,23 @@ int8_t polar_decoder_dci(double *input,
void generic_polar_decoder(const t_nrPolar_params *pp, decoder_node_t *node, uint8_t *nr_polar_U);
void computeBeta(const t_nrPolar_params *pp,
decoder_node_t *node);
static inline int16_t *treeAlpha(decoder_node_t *node)
{
return (int16_t *)((uint8_t *)node + node->alpha);
}
static inline int8_t *treeBeta(decoder_node_t *node)
{
return (int8_t *)node + node->beta;
}
void build_decoder_tree(t_nrPolar_params *pp);
void build_decoder_tree(decoder_tree_t *tree, const t_nrPolar_params *pp);
void build_polar_tables(t_nrPolar_params *polarParams);
void init_polar_deinterleaver_table(t_nrPolar_params *polarParams);
void nr_polar_print_polarParams(void);
t_nrPolar_params *nr_polar_params (int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level,
int decoder_flag);
t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level);
uint16_t nr_polar_aggregation_prime (uint8_t aggregation_level);
......@@ -207,14 +209,6 @@ void nr_polar_rate_matching(double *input,
uint16_t N,
uint16_t E);
void nr_polar_rate_matching_int16(int16_t *input,
int16_t *output,
const uint16_t *rmp,
const uint16_t K,
const uint16_t N,
const uint16_t E,
const uint8_t i_bil);
void nr_polar_interleaving_pattern(uint16_t K,
uint8_t I_IL,
uint16_t *PI_k_);
......@@ -256,13 +250,6 @@ void nr_polar_generate_u(uint64_t *u,
void nr_polar_uxG(uint8_t const* u, size_t N, uint8_t* D);
void nr_polar_info_extraction_from_u(uint64_t *Cprime,
const uint8_t *u,
const uint8_t *information_bit_pattern,
const uint8_t *parity_check_bit_pattern,
uint16_t N,
uint8_t n_pc);
void nr_polar_bit_insertion(uint8_t *input,
uint8_t *output,
uint16_t N,
......@@ -328,7 +315,52 @@ static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint1
output[pattern[i]] = input[i];
}
void delete_decoder_tree(t_nrPolar_params *);
/*
* De-interleaving of coded bits implementation
* TS 138.212: Section 5.4.1.3 - Interleaving of coded bits
*/
static inline void nr_polar_rm_deinterleaving_lut(uint16_t *out, const uint E)
{
int16_t in[E];
for (int i = 0; i < E; i++)
in[i] = i;
int T = ceil((sqrt(8 * E + 1) - 1) / 2);
int v_tab[T][T];
memset(v_tab, 0, sizeof(v_tab));
int k = 0;
for (int i = 0; i < T; i++) {
for (int j = 0; j < T - i; j++) {
if (k < E) {
v_tab[i][j] = k + 1;
}
k++;
}
}
int v[T][T];
k = 0;
for (int j = 0; j < T; j++) {
for (int i = 0; i < T - j; i++) {
if (k < E && v_tab[i][j] != 0) {
v[i][j] = in[k];
k++;
} else {
v[i][j] = INT_MAX;
}
}
}
k = 0;
memset(out, 0, E * sizeof(*out));
for (int i = 0; i < T; i++) {
for (int j = 0; j < T - i; j++) {
if (v[i][j] != INT_MAX) {
out[k] = v[i][j];
k++;
}
}
}
}
extern pthread_mutex_t PolarListMutex;
static inline void polarReturn(t_nrPolar_params *polarParams)
......
......@@ -47,7 +47,7 @@ void polar_encoder(uint32_t *in,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level) {
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false);
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
uint8_t nr_polar_A[polarParams->payloadBits];
nr_bit2byte_uint32_8(in, polarParams->payloadBits, nr_polar_A);
/*
......@@ -146,7 +146,7 @@ void polar_encoder_dci(uint32_t *in,
int8_t messageType,
uint16_t messageLength,
uint8_t aggregation_level) {
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false);
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
#ifdef DEBUG_POLAR_ENCODER_DCI
printf("[polar_encoder_dci] in: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\n", in[0], in[1], in[2], in[3]);
......@@ -463,7 +463,7 @@ void polar_encoder_fast(uint64_t *A,
uint16_t messageLength,
uint8_t aggregation_level)
{
t_nrPolar_params *polarParams=nr_polar_params(messageType, messageLength, aggregation_level, false);
t_nrPolar_params *polarParams = nr_polar_params(messageType, messageLength, aggregation_level);
#ifdef POLAR_CODING_DEBUG
printf("polarParams->payloadBits = %i\n", polarParams->payloadBits);
......
......@@ -33,7 +33,7 @@
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_){
uint K_IL_max = 164, k = 0;
uint K_IL_max = 164;
uint8_t interleaving_pattern_table[164] = {
0, 2, 4, 7, 9, 14, 19, 20, 24, 25, 26, 28, 31, 34, 42, 45, 49, 50, 51, 53, 54, 56, 58, 59,
61, 62, 65, 66, 67, 69, 70, 71, 72, 76, 77, 81, 82, 83, 87, 88, 89, 91, 93, 95, 98, 101, 104, 106,
......@@ -44,10 +44,10 @@ void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_){
40, 146, 41, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163};
if (I_IL == 0) {
for (; k <= K - 1; k++)
for (int k = 0; k < K; k++)
PI_k_[k] = k;
} else {
for (int m = 0; m <= (K_IL_max - 1); m++) {
for (int m = 0, k = 0; m < K_IL_max; m++) {
if (interleaving_pattern_table[m] >= (K_IL_max - K)) {
PI_k_[k] = interleaving_pattern_table[m] - (K_IL_max - K);
k++;
......
......@@ -89,40 +89,6 @@ void nr_polar_generate_u(uint64_t *u,
}
}
void nr_polar_info_extraction_from_u(uint64_t *Cprime,
const uint8_t *u,
const uint8_t *information_bit_pattern,
const uint8_t *parity_check_bit_pattern,
uint16_t N,
uint8_t n_pc)
{
int k = 0;
if (n_pc > 0) {
for (int n = 0; n < N; n++) {
if (information_bit_pattern[n] == 1) {
if (parity_check_bit_pattern[n] == 0) {
int k1 = k >> 6;
int k2 = k - (k1 << 6);
Cprime[k1] |= (uint64_t)u[n] << k2;
k++;
}
}
}
} else {
for (int n = 0; n < N; n++) {
if (information_bit_pattern[n] == 1) {
int k1 = k >> 6;
int k2 = k - (k1 << 6);
Cprime[k1] |= (uint64_t)u[n] << k2;
k++;
}
}
}
}
static
void encode_packed_byte(uint8_t* in_out)
{
......@@ -442,76 +408,3 @@ void nr_polar_rate_matching(double *input,
}
}
}
/*
* De-interleaving of coded bits implementation
* TS 138.212: Section 5.4.1.3 - Interleaving of coded bits
*/
void nr_polar_rm_deinterleaving_cb(const int16_t *in, int16_t *out, const uint16_t E)
{
int T = ceil((sqrt(8 * E + 1) - 1) / 2);
int v_tab[T][T];
memset(v_tab, 0, sizeof(v_tab));
int k = 0;
for (int i = 0; i < T; i++) {
for (int j = 0; j < T - i; j++) {
if (k < E) {
v_tab[i][j] = k + 1;
}
k++;
}
}
int v[T][T];
k = 0;
for (int j = 0; j < T; j++) {
for (int i = 0; i < T - j; i++) {
if (k < E && v_tab[i][j] != 0) {
v[i][j] = in[k];
k++;
} else {
v[i][j] = INT_MAX;
}
}
}
k = 0;
memset(out, 0, E * sizeof(*out));
for (int i = 0; i < T; i++) {
for (int j = 0; j < T - i; j++) {
if (v[i][j] != INT_MAX) {
out[k] = v[i][j];
k++;
}
}
}
}
void nr_polar_rate_matching_int16(int16_t *input,
int16_t *output,
const uint16_t *rmp,
const uint16_t K,
const uint16_t N,
const uint16_t E,
const uint8_t i_bil)
{
if (i_bil == 1) {
nr_polar_rm_deinterleaving_cb(input, input, E);
}
if (E >= N) { // repetition
memset(output, 0, N * sizeof(*output));
for (int i = 0; i <= E - 1; i++)
output[rmp[i]] += input[i];
} else {
if ((K / (double)E) <= (7.0 / 16))
memset(output, 0, N * sizeof(*output)); // puncturing
else { // shortening
for (int i = 0; i <= N - 1; i++)
output[i] = 32767; // instead of INFINITY, to prevent [-Woverflow]
}
for (int i = 0; i <= E - 1; i++)
output[rmp[i]] = input[i];
}
}
......@@ -47,8 +47,7 @@ static void nr_polar_delete_list(t_nrPolar_params * polarParams) {
return;
if (polarParams->nextPtr)
nr_polar_delete_list(polarParams->nextPtr);
delete_decoder_tree(polarParams);
// From build_polar_tables()
free(polarParams->rm_tab);
if (polarParams->crc_generator_matrix)
......@@ -71,7 +70,7 @@ static void nr_polar_delete(void) {
pthread_mutex_unlock(&PolarListMutex);
}
t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level, int decoder_flag)
t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, uint8_t aggregation_level)
{
// The lock is weak, because we never delete in the list, only at exit time
// therefore, returning t_nrPolar_params * from the list is safe for future usage
......@@ -87,8 +86,6 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
if (currentPtr->busy == false && currentPtr->idx == PolarKey ) {
currentPtr->busy=true;
pthread_mutex_unlock(&PolarListMutex);
if (decoder_flag && !currentPtr->tree.root)
build_decoder_tree(currentPtr);
return currentPtr ;
}
else
......@@ -97,11 +94,10 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
// printf("currentPtr %p (polarParams %p)\n",currentPtr,polarParams);
//Else, initialize and add node to the end of the linked list.
t_nrPolar_params *newPolarInitNode = calloc(sizeof(t_nrPolar_params),1);
t_nrPolar_params *newPolarInitNode = malloc(sizeof(t_nrPolar_params));
AssertFatal(newPolarInitNode, "[nr_polar_init] New t_nrPolar_params * could not be created");
newPolarInitNode->busy = true;
newPolarInitNode->nextPtr = NULL;
newPolarInitNode->nextPtr = PolarList;
*newPolarInitNode = (t_nrPolar_params){.busy = true, .nextPtr = PolarList};
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);
......@@ -220,6 +216,10 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
newPolarInitNode->K,
newPolarInitNode->N,
newPolarInitNode->encoderLength);
if (newPolarInitNode->i_bil) {
newPolarInitNode->i_bil_pattern = malloc(sizeof(uint16_t) * newPolarInitNode->encoderLength);
nr_polar_rm_deinterleaving_lut(newPolarInitNode->i_bil_pattern, newPolarInitNode->encoderLength);
}
newPolarInitNode->information_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->parity_check_bit_pattern = malloc(sizeof(uint8_t) * newPolarInitNode->N);
newPolarInitNode->Q_I_N = malloc(sizeof(int16_t) * (newPolarInitNode->K + newPolarInitNode->n_pc));
......@@ -245,8 +245,6 @@ t_nrPolar_params *nr_polar_params(int8_t messageType, uint16_t messageLength, ui
// sort the Q_I_N array in ascending order (first K positions)
qsort((void *)newPolarInitNode->Q_I_N,newPolarInitNode->K,sizeof(int16_t),intcmp);
if (decoder_flag == 1)
build_decoder_tree(newPolarInitNode);
build_polar_tables(newPolarInitNode);
init_polar_deinterleaver_table(newPolarInitNode);
......
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