From 84c3f70570989a49848b48b818c1aa866301cbbd Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 9 Sep 2018 08:59:26 +0200 Subject: [PATCH 01/19] added prints for unrolling preparation fixed issue for llr updates with the approximation --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 3 ++ .../nrPolar_tools/nr_polar_decoding_tools.c | 52 ++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 3d076296d0..b24c78495b 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -106,6 +106,8 @@ int8_t polar_decoder( uint8_t listIndex[2*listSize], copyIndex; for (uint16_t currentBit=0; currentBitN; currentBit++){ + printf("***************** BIT %d\n",currentBit); + updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 @@ -128,6 +130,7 @@ int8_t polar_decoder( for (int k = 0; k < (polarParams->n+1); k++) { bit[j][k][i+currentListSize]=bit[j][k][i]; llr[j][k][i+currentListSize]=llr[j][k][i];}}} + for (int i = 0; i < currentListSize; i++) { bit[currentBit][0][i]=0; crcState[i+currentListSize]=crcState[i]; 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 0b010131cd..58292c236a 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -20,6 +20,7 @@ */ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" +#define SHOWCOMP 1 void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) { @@ -29,6 +30,10 @@ void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, if(bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen); if(llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation); if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); +#ifdef SHOWCOMP + printf("updating LLR (%d,%d,%d) (bit %d,%d,%d, llr0 %d,%d,%d, llr1 %d,%d,%d \n",row,col,i, + row-offset,col,i,row-offset,col+1,i,row,col+1,i); +#endif llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i]; } else { if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); @@ -48,10 +53,18 @@ void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, if (( (row) % (2*offset) ) >= offset ) { if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen); bit[row][col][i] = bit[row][col-1][i]; +#ifdef SHOWCOMP + printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n", + row,col,i,row,col-1,i); +#endif } else { if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen); if (bitU[row+offset][col-1]==0) updateBit(bit, bitU, listSize, (row+offset), (col-1), xlen, ylen); bit[row][col][i] = ( (bit[row][col-1][i]+bit[row+offset][col-1][i]) % 2); +#ifdef SHOWCOMP + printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", + row,col,i,row,col-1,i,row+offset,col-1,i); +#endif } } @@ -61,6 +74,11 @@ void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8_t bitValue, uint16_t row, uint8_t approximation) { +#ifdef SHOWCOMP + printf("updating path_metric from Frozen bit (%d,%d) \n", + row,0); +#endif + if (approximation) { //eq. (12) for (uint8_t i=0; i Date: Sun, 9 Sep 2018 09:18:15 +0200 Subject: [PATCH 02/19] removed some computations which are repeated in a loop (updateLLR) --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 3 +- .../nrPolar_tools/nr_polar_decoding_tools.c | 44 ++++++++++--------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index b24c78495b..6243d281c9 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -105,8 +105,9 @@ int8_t polar_decoder( int16_t checkCrcBits=-1; uint8_t listIndex[2*listSize], copyIndex; + // for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; for (uint16_t currentBit=0; currentBitN; currentBit++){ - printf("***************** BIT %d\n",currentBit); + // printf("***************** BIT %d\n",currentBit); updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. 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 58292c236a..2c586d8f7d 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -20,29 +20,33 @@ */ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" -#define SHOWCOMP 1 +//#define SHOWCOMP 1 void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, - uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) { - uint16_t offset = (xlen/(pow(2,(ylen-col-1)))); - for (uint8_t i=0; i= offset ) { - if(bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen); - if(llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation); - if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); -#ifdef SHOWCOMP - printf("updating LLR (%d,%d,%d) (bit %d,%d,%d, llr0 %d,%d,%d, llr1 %d,%d,%d \n",row,col,i, - row-offset,col,i,row-offset,col+1,i,row,col+1,i); -#endif - llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i]; - } else { - if(llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); - if(llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation); - computeLLR(llr, row, col, i, offset, approximation); - } - } + uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) { + uint16_t offset = (xlen/(1<<(ylen-col-1))); + if (( (row) % (2*offset) ) >= offset ) { + if (bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen); + if (llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation); + if (llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); + for (uint8_t i=0; i Date: Sun, 9 Sep 2018 09:51:37 +0200 Subject: [PATCH 03/19] small simplification in computeLLR --- .../nrPolar_tools/nr_polar_decoding_tools.c | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 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 2c586d8f7d..a1f67edd35 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -41,9 +41,8 @@ void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, } else { if (llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); if (llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation); - for (uint8_t i=0; i Date: Mon, 10 Sep 2018 01:38:43 +0200 Subject: [PATCH 04/19] order of dimensions on llr array --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 14 +++---- .../nrPolar_tools/nr_polar_decoding_tools.c | 39 +++++++++++-------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 6243d281c9..67fbd7a86e 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -40,7 +40,7 @@ int8_t polar_decoder( uint8_t ***bit = nr_alloc_uint8_t_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True - double ***llr = nr_alloc_double_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); + double ***llr = nr_alloc_double_3D_array(2*listSize,(polarParams->n+1), polarParams->N); uint8_t **crcChecksum = nr_alloc_uint8_t_2D_array(polarParams->crcParityBits, 2*listSize); double *pathMetric = malloc(sizeof(double)*(2*listSize)); uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True @@ -92,7 +92,7 @@ int8_t polar_decoder( double *d_tilde = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); - for (int j = 0; j < polarParams->N; j++) llr[j][polarParams->n][0]=d_tilde[j]; + for (int j = 0; j < polarParams->N; j++) llr[0][polarParams->n][j]=d_tilde[j]; /* @@ -130,7 +130,7 @@ int8_t polar_decoder( for (int j = 0; j < polarParams->N; j++) { for (int k = 0; k < (polarParams->n+1); k++) { bit[j][k][i+currentListSize]=bit[j][k][i]; - llr[j][k][i+currentListSize]=llr[j][k][i];}}} + llr[i+currentListSize][k][j]=llr[i][k][j];}}} for (int i = 0; i < currentListSize; i++) { bit[currentBit][0][i]=0; @@ -167,7 +167,7 @@ int8_t polar_decoder( for (int i=0; iN; i++) { for (int j=0; j<(polarParams->n+1); j++) { bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]]; - llr[i][j][listIndex[(2*listSize-1)-k]]=llr[i][j][listIndex[k]]; + llr[listIndex[(2*listSize-1)-k]][j][i]=llr[listIndex[k]][j][i]; } } } @@ -188,7 +188,7 @@ int8_t polar_decoder( for (int i = 0; i < polarParams->N; i++) { for (int j = 0; j < (polarParams->n + 1); j++) { bit[i][j][k] = bit[i][j][copyIndex]; - llr[i][j][k] = llr[i][j][copyIndex]; + llr[k][j][i] = llr[copyIndex][j][i]; } } } @@ -236,7 +236,7 @@ int8_t polar_decoder( free(pathMetric); free(crcState); nr_free_uint8_t_3D_array(bit, polarParams->N, (polarParams->n+1)); - nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); + nr_free_double_3D_array(llr, 2*listSize, (polarParams->n+1)); nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); return(-1); } @@ -271,7 +271,7 @@ int8_t polar_decoder( free(pathMetric); free(crcState); nr_free_uint8_t_3D_array(bit, polarParams->N, (polarParams->n+1)); - nr_free_double_3D_array(llr, polarParams->N, (polarParams->n+1)); + nr_free_double_3D_array(llr, 2*listSize, (polarParams->n+1)); nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); nr_free_uint8_t_2D_array(tempECGM, polarParams->K); 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 a1f67edd35..64bf636c66 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -36,7 +36,7 @@ void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, printf("updating LLR (%d,%d,%d) (bit %d,%d,%d, llr0 %d,%d,%d, llr1 %d,%d,%d \n",row,col,i, row-offset,col,i,row-offset,col+1,i,row,col+1,i); #endif - llr[row][col][i] = (pow((-1),bit[row-offset][col][i])*llr[row-offset][col+1][i]) + llr[row][col+1][i]; + llr[i][col][row] = (pow((-1),bit[row-offset][col][i])*llr[i][col+1][row-offset]) + llr[i][col+1][row]; } } else { if (llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); @@ -84,11 +84,11 @@ void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8 if (approximation) { //eq. (12) for (uint8_t i=0; i Date: Mon, 10 Sep 2018 02:16:35 +0200 Subject: [PATCH 05/19] memcpy instead of loop-based copy --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 62 ++++++++++++------- .../nrPolar_tools/nr_polar_decoding_tools.c | 6 +- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 67fbd7a86e..9d898a0e66 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -37,7 +37,7 @@ int8_t polar_decoder( uint8_t pathMetricAppr) { - uint8_t ***bit = nr_alloc_uint8_t_3D_array(polarParams->N, (polarParams->n+1), 2*listSize); + uint8_t ***bit = nr_alloc_uint8_t_3D_array(2*listSize, (polarParams->n+1), polarParams->N); uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True double ***llr = nr_alloc_double_3D_array(2*listSize,(polarParams->n+1), polarParams->N); @@ -48,12 +48,14 @@ int8_t polar_decoder( for (int i=0; i<(2*listSize); i++) { pathMetric[i] = 0; crcState[i]=1; + for (int j=0; j< polarParams->n+1; j++) memset((void*)&bit[i][j][0],0,sizeof(uint8_t)*polarParams->N); } for (int i=0; iN; i++) { llrUpdated[i][polarParams->n]=1; bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); } + uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2 for (int i = 0; i < polarParams->K; i++){ @@ -120,23 +122,29 @@ int8_t polar_decoder( } else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { //Information bit with known value of "1". updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr); - for (uint8_t i=0; icrcParityBits); } else { updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr); for (int i = 0; i < currentListSize; i++) { - for (int j = 0; j < polarParams->N; j++) { - for (int k = 0; k < (polarParams->n+1); k++) { - bit[j][k][i+currentListSize]=bit[j][k][i]; - llr[i+currentListSize][k][j]=llr[i][k][j];}}} + for (int k = 0; k < (polarParams->n+1); k++) { + /* + for (int j = 0; j < polarParams->N; j++) { + bit[i+currentListSize][k][j]=bit[i][k][j]; + llr[i+currentListSize][k][j]=llr[i][k][j]; + }*/ + memcpy((void*)&bit[i+currentListSize][k][0],(void*)&bit[i][k][0],sizeof(uint8_t)*polarParams->N); + memcpy((void*)&llr[i+currentListSize][k][0],(void*)&llr[i][k][0],sizeof(double)*polarParams->N); + } + } for (int i = 0; i < currentListSize; i++) { - bit[currentBit][0][i]=0; + bit[i][0][currentBit]=0; crcState[i+currentListSize]=crcState[i]; } - for (int i = currentListSize; i < 2*currentListSize; i++) bit[currentBit][0][i]=1; + for (int i = currentListSize; i < 2*currentListSize; i++) bit[i][0][currentBit]=1; bitUpdated[currentBit][0]=1; updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); currentListSize*=2; @@ -164,12 +172,19 @@ int8_t polar_decoder( //First, backup the best "listSize" number of entries. for (int k=(listSize-1); k>0; k--) { - for (int i=0; iN; i++) { - for (int j=0; j<(polarParams->n+1); j++) { - bit[i][j][listIndex[(2*listSize-1)-k]]=bit[i][j][listIndex[k]]; - llr[listIndex[(2*listSize-1)-k]][j][i]=llr[listIndex[k]][j][i]; - } - } + for (int j=0; j<(polarParams->n+1); j++) { + /* + for (int i=0; iN; i++) { + bit[listIndex[(2*listSize-1)-k]][j][i]=bit[listIndex[k]][j][i]; + llr[listIndex[(2*listSize-1)-k]][j][i]=llr[listIndex[k]][j][i]; + }*/ + memcpy((void*)&bit[listIndex[(2*listSize-1)-k]][j][0], + (void*)&bit[listIndex[k]][j][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&llr[listIndex[(2*listSize-1)-k]][j][0], + (void*)&llr[listIndex[k]][j][0], + sizeof(double)*polarParams->N); + } } for (int k=(listSize-1); k>0; k--) { for (int i = 0; i < polarParams->crcParityBits; i++) { @@ -185,11 +200,14 @@ int8_t polar_decoder( } else { //Use the backup. copyIndex = listIndex[k]; } - for (int i = 0; i < polarParams->N; i++) { - for (int j = 0; j < (polarParams->n + 1); j++) { - bit[i][j][k] = bit[i][j][copyIndex]; - llr[k][j][i] = llr[copyIndex][j][i]; - } + + for (int j = 0; j < (polarParams->n + 1); j++) { + /* for (int i = 0; i < polarParams->N; i++) { + bit[k][j][i] = bit[copyIndex][j][i]; + llr[k][j][i] = llr[copyIndex][j][i]; + }*/ + memcpy((void*)&bit[k][j][0],(void*)&bit[copyIndex][j][0],sizeof(uint8_t)*polarParams->N); + memcpy((void*)&llr[k][j][0],(void*)&llr[copyIndex][j][0],sizeof(double)*polarParams->N); } } for (int k = 0; k < listSize; k++) { @@ -235,7 +253,7 @@ int8_t polar_decoder( free(d_tilde); free(pathMetric); free(crcState); - nr_free_uint8_t_3D_array(bit, polarParams->N, (polarParams->n+1)); + nr_free_uint8_t_3D_array(bit, 2*listSize, (polarParams->n+1)); nr_free_double_3D_array(llr, 2*listSize, (polarParams->n+1)); nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); return(-1); @@ -252,7 +270,7 @@ int8_t polar_decoder( for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { if ( crcState[listIndex[i]] == 1 ) { - for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=bit[j][0][listIndex[i]]; + for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=bit[listIndex[i]][0][j]; //Extract the information bits (û to ĉ) nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); @@ -270,7 +288,7 @@ int8_t polar_decoder( free(d_tilde); free(pathMetric); free(crcState); - nr_free_uint8_t_3D_array(bit, polarParams->N, (polarParams->n+1)); + nr_free_uint8_t_3D_array(bit, 2*listSize, (polarParams->n+1)); nr_free_double_3D_array(llr, 2*listSize, (polarParams->n+1)); nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); 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 64bf636c66..888c209090 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -36,7 +36,7 @@ void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, printf("updating LLR (%d,%d,%d) (bit %d,%d,%d, llr0 %d,%d,%d, llr1 %d,%d,%d \n",row,col,i, row-offset,col,i,row-offset,col+1,i,row,col+1,i); #endif - llr[i][col][row] = (pow((-1),bit[row-offset][col][i])*llr[i][col+1][row-offset]) + llr[i][col+1][row]; + llr[i][col][row] = (pow((-1),bit[i][col][row-offset])*llr[i][col+1][row-offset]) + llr[i][col+1][row]; } } else { if (llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); @@ -55,7 +55,7 @@ void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, for (uint8_t i=0; i= offset ) { if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen); - bit[row][col][i] = bit[row][col-1][i]; + bit[i][col][row] = bit[i][col-1][row]; #ifdef SHOWCOMP printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n", row,col,i,row,col-1,i); @@ -63,7 +63,7 @@ void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, } else { if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen); if (bitU[row+offset][col-1]==0) updateBit(bit, bitU, listSize, (row+offset), (col-1), xlen, ylen); - bit[row][col][i] = ( (bit[row][col-1][i]+bit[row+offset][col-1][i]) % 2); + bit[i][col][row] = ( (bit[i][col-1][row]+bit[i][col-1][row+offset]) % 2); #ifdef SHOWCOMP printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", row,col,i,row,col-1,i,row+offset,col-1,i); From d4d2f8665e54aecf5881c0c06405a12a46cd8382 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 10 Sep 2018 14:50:30 +0200 Subject: [PATCH 06/19] timing statistics and memory clearing --- openair1/PHY/CODING/TESTBENCH/polartest.c | 24 +++++- .../CODING/nrPolar_tools/nr_polar_decoder.c | 75 ++++++++++++++----- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 12 ++- 3 files changed, 87 insertions(+), 24 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index 144b63b353..e844ed74db 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -15,10 +15,20 @@ int main(int argc, char *argv[]) { //Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.) time_stats_t timeEncoder,timeDecoder; + time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving; + time_stats_t path_metric,sorting,update_LLR; opp_enabled=1; cpu_freq_GHz = get_cpu_freq_GHz(); reset_meas(&timeEncoder); reset_meas(&timeDecoder); + reset_meas(&polar_decoder_init); + reset_meas(&polar_rate_matching); + reset_meas(&decoding); + reset_meas(&bit_extraction); + reset_meas(&deinterleaving); + reset_meas(&sorting); + reset_meas(&path_metric); + reset_meas(&update_LLR); randominit(0); //Default simulation values (Aim for iterations = 1000000.) @@ -128,7 +138,7 @@ int main(int argc, char *argv[]) { // We assume no a priori knowledge available about the payload. double aPrioriArray[nrPolar_params.payloadBits]; - for (int i=0; in+1), polarParams->N); uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True @@ -48,9 +59,15 @@ int8_t polar_decoder( for (int i=0; i<(2*listSize); i++) { pathMetric[i] = 0; crcState[i]=1; - for (int j=0; j< polarParams->n+1; j++) memset((void*)&bit[i][j][0],0,sizeof(uint8_t)*polarParams->N); + for (int j=0; j< polarParams->n+1; j++) { + memset((void*)&bit[i][j][0],0,sizeof(uint8_t)*polarParams->N); + memset((void*)&llr[i][j][0],0,sizeof(double)*polarParams->N); + } + for (int j=0;jcrcParityBits;j++) crcChecksum[j][i] = 0; } - for (int i=0; iN; i++) { + for (int i=0; iN; i++) { + memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); + memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); llrUpdated[i][polarParams->n]=1; bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); } @@ -92,42 +109,53 @@ int8_t polar_decoder( } } + stop_meas(init); + start_meas(polar_rate_matching); + double *d_tilde = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); - for (int j = 0; j < polarParams->N; j++) llr[0][polarParams->n][j]=d_tilde[j]; - + memcpy((void*)&llr[0][polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N); + stop_meas(polar_rate_matching); /* * SCL polar decoder. */ - + start_meas(decoding); uint32_t nonFrozenBit=0; uint8_t currentListSize=1; uint8_t decoderIterationCheck=0; int16_t checkCrcBits=-1; - uint8_t listIndex[2*listSize], copyIndex; + uint8_t listIndex[2*listSize], copyIndex=0; // for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; for (uint16_t currentBit=0; currentBitN; currentBit++){ // printf("***************** BIT %d\n",currentBit); + start_meas(update_LLR); updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); + stop_meas(update_LLR); if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 } else { //Information or CRC bit. - if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) { + if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) { + printf("app[%d] %f, payloadBits %d\n",polarParams->interleaving_pattern[nonFrozenBit], + polarParams->payloadBits, + aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]]); + //Information bit with known value of "0". updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); bitUpdated[currentBit][0]=1; //0=False, 1=True - } else if ( (polarParams->interleaving_pattern[nonFrozenBit] <= polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { + } else if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { //Information bit with known value of "1". updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr); for (uint8_t i=0; icrcParityBits); } else { - updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr); - + start_meas(path_metric); + updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr); + stop_meas(path_metric); + start_meas(sorting); for (int i = 0; i < currentListSize; i++) { for (int k = 0; k < (polarParams->n+1); k++) { /* @@ -201,13 +229,15 @@ int8_t polar_decoder( copyIndex = listIndex[k]; } - for (int j = 0; j < (polarParams->n + 1); j++) { - /* for (int i = 0; i < polarParams->N; i++) { - bit[k][j][i] = bit[copyIndex][j][i]; - llr[k][j][i] = llr[copyIndex][j][i]; - }*/ - memcpy((void*)&bit[k][j][0],(void*)&bit[copyIndex][j][0],sizeof(uint8_t)*polarParams->N); - memcpy((void*)&llr[k][j][0],(void*)&llr[copyIndex][j][0],sizeof(double)*polarParams->N); + if (copyIndex!=k) { + for (int j = 0; j < (polarParams->n + 1); j++) { + /* for (int i = 0; i < polarParams->N; i++) { + bit[k][j][i] = bit[copyIndex][j][i]; + llr[k][j][i] = llr[copyIndex][j][i]; + }*/ + memcpy((void*)&bit[k][j][0],(void*)&bit[copyIndex][j][0],sizeof(uint8_t)*polarParams->N); + memcpy((void*)&llr[k][j][0],(void*)&llr[copyIndex][j][0],sizeof(double)*polarParams->N); + } } } for (int k = 0; k < listSize; k++) { @@ -230,6 +260,7 @@ int8_t polar_decoder( } currentListSize = listSize; } + stop_meas(sorting); } for (int i=0; icrcParityBits; i++) { @@ -256,6 +287,7 @@ int8_t polar_decoder( nr_free_uint8_t_3D_array(bit, 2*listSize, (polarParams->n+1)); nr_free_double_3D_array(llr, 2*listSize, (polarParams->n+1)); nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); + stop_meas(decoding); return(-1); } @@ -272,12 +304,14 @@ int8_t polar_decoder( if ( crcState[listIndex[i]] == 1 ) { for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=bit[listIndex[i]][0][j]; + start_meas(bit_extraction); //Extract the information bits (û to ĉ) nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); - + stop_meas(bit_extraction); //Deinterleaving (ĉ to b) + start_meas(deinterleaving); nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); - + stop_meas(deinterleaving); //Remove the CRC (â) for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; @@ -293,5 +327,6 @@ int8_t polar_decoder( nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); nr_free_uint8_t_2D_array(tempECGM, polarParams->K); + stop_meas(decoding); return(0); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 7caf547395..b568004da5 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -30,6 +30,8 @@ #include #include +#include "PHY/TOOLS/time_meas.h" + static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31 }; struct nrPolar_params { @@ -75,7 +77,15 @@ void polar_encoder(uint8_t *input, uint8_t *output, t_nrPolar_params* polarParam void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N); int8_t polar_decoder(double *input, uint8_t *output, t_nrPolar_params *polarParams, - uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr); + uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR); void nr_polar_init(t_nrPolar_params* polarParams, int messageType); From d5e94b2ca08b653c841d816b6a2558412d54ab8f Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 11 Sep 2018 06:50:20 +0200 Subject: [PATCH 07/19] decoder_list_t structure for in-place computations --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 237 ++++++++++-------- .../nrPolar_tools/nr_polar_decoding_tools.c | 169 ++++++------- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 48 ++-- .../nrPolar_tools/nr_polar_matrix_and_array.c | 71 +++--- 4 files changed, 270 insertions(+), 255 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index cb9e829851..cb75811a11 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -29,14 +29,16 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "PHY/TOOLS/time_meas.h" + + int8_t polar_decoder( double *input, uint8_t *output, t_nrPolar_params *polarParams, uint8_t listSize, double *aPrioriPayload, - uint8_t pathMetricAppr, - time_stats_t *init, + uint8_t pathMetricAppr, + time_stats_t *init, time_stats_t *polar_rate_matching, time_stats_t *decoding, time_stats_t *bit_extraction, @@ -48,23 +50,24 @@ int8_t polar_decoder( start_meas(init); - uint8_t ***bit = nr_alloc_uint8_t_3D_array(2*listSize, (polarParams->n+1), polarParams->N); + uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True - double ***llr = nr_alloc_double_3D_array(2*listSize,(polarParams->n+1), polarParams->N); - uint8_t **crcChecksum = nr_alloc_uint8_t_2D_array(polarParams->crcParityBits, 2*listSize); - double *pathMetric = malloc(sizeof(double)*(2*listSize)); - uint8_t *crcState = malloc(sizeof(uint8_t)*(2*listSize)); //0=False, 1=True + decoder_list_t dlist[2*listSize]; - for (int i=0; i<(2*listSize); i++) { - pathMetric[i] = 0; - crcState[i]=1; - for (int j=0; j< polarParams->n+1; j++) { - memset((void*)&bit[i][j][0],0,sizeof(uint8_t)*polarParams->N); - memset((void*)&llr[i][j][0],0,sizeof(double)*polarParams->N); - } - for (int j=0;jcrcParityBits;j++) crcChecksum[j][i] = 0; + for ( int i=0;i<2*listSize;i++) { + dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); + dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N); + dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits); + for (int j=0; j< polarParams->n+1; j++) { + memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N); + memset((void*)&dlist[i].llr[j][0],0,sizeof(double)*polarParams->N); + } + for (int j=0;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; + dlist[i].crcState = 1; + dlist[i].pathMetric = 0; } + for (int i=0; iN; i++) { memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); @@ -114,7 +117,7 @@ int8_t polar_decoder( double *d_tilde = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); - memcpy((void*)&llr[0][polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N); + memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N); stop_meas(polar_rate_matching); /* @@ -125,69 +128,81 @@ int8_t polar_decoder( uint8_t currentListSize=1; uint8_t decoderIterationCheck=0; int16_t checkCrcBits=-1; - uint8_t listIndex[2*listSize], copyIndex=0; + uint8_t copyIndex=0; + + decoder_list_t *sorted_dlist[2*listSize]; + int listIndex[2*listSize]; + double pathMetric[2*listSize]; + + for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; - // for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; for (uint16_t currentBit=0; currentBitN; currentBit++){ // printf("***************** BIT %d\n",currentBit); start_meas(update_LLR); - updateLLR(llr, llrUpdated, bit, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); + updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); stop_meas(update_LLR); - if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. - updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 - } else { //Information or CRC bit. - if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) { - printf("app[%d] %f, payloadBits %d\n",polarParams->interleaving_pattern[nonFrozenBit], - polarParams->payloadBits, - aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]]); - //Information bit with known value of "0". - updatePathMetric(pathMetric, llr, currentListSize, 0, currentBit, pathMetricAppr); - bitUpdated[currentBit][0]=1; //0=False, 1=True - } else if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { - //Information bit with known value of "1". - updatePathMetric(pathMetric, llr, currentListSize, 1, currentBit, pathMetricAppr); - for (uint8_t i=0; icrcParityBits); - } else { - start_meas(path_metric); - updatePathMetric2(pathMetric, llr, currentListSize, currentBit, pathMetricAppr); - stop_meas(path_metric); - start_meas(sorting); - for (int i = 0; i < currentListSize; i++) { - for (int k = 0; k < (polarParams->n+1); k++) { - /* - for (int j = 0; j < polarParams->N; j++) { - bit[i+currentListSize][k][j]=bit[i][k][j]; - llr[i+currentListSize][k][j]=llr[i][k][j]; - }*/ - memcpy((void*)&bit[i+currentListSize][k][0],(void*)&bit[i][k][0],sizeof(uint8_t)*polarParams->N); - memcpy((void*)&llr[i+currentListSize][k][0],(void*)&llr[i][k][0],sizeof(double)*polarParams->N); - } - } + if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. + updatePathMetric(sorted_dlist,currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 + } else { //Information or CRC bit. + if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) { + printf("app[%d] %f, payloadBits %d\n",polarParams->interleaving_pattern[nonFrozenBit], + polarParams->payloadBits, + aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]]); + + //Information bit with known value of "0". + updatePathMetric(sorted_dlist, currentListSize, 0, currentBit, pathMetricAppr); + bitUpdated[currentBit][0]=1; //0=False, 1=True + } else if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { + //Information bit with known value of "1". + updatePathMetric(sorted_dlist, currentListSize, 1, currentBit, pathMetricAppr); + for (uint8_t i=0; ibit[0][currentBit]=1; + bitUpdated[currentBit][0]=1; + updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); + } else { + start_meas(path_metric); + updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr); + stop_meas(path_metric); + start_meas(sorting); + for (int i = 0; i < currentListSize; i++) { + for (int k = 0; k < (polarParams->n+1); k++) { + /* + for (int j = 0; j < polarParams->N; j++) { + bit[i+currentListSize][k][j]=bit[i][k][j]; + llr[i+currentListSize][k][j]=llr[i][k][j]; + }*/ + memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],(void*)&sorted_dlist[i]->bit[k][0],sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],(void*)&sorted_dlist[i]->llr[k][0],sizeof(double)*polarParams->N); + } + } + + for (int i = 0; i < currentListSize; i++) { + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+currentListSize]->crcState=sorted_dlist[i]->crcState; + } + for (int i = currentListSize; i < 2*currentListSize; i++) sorted_dlist[i]->bit[currentBit]=1; + bitUpdated[currentBit][0]=1; + updateCrcChecksum2(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); + currentListSize*=2; + + //Keep only the best "listSize" number of entries. + if (currentListSize > listSize) { + for (int i = 0; i < 2*listSize; i++) { + listIndex[i]=i; + pathMetric[i] = dlist[i].pathMetric; + } - for (int i = 0; i < currentListSize; i++) { - bit[i][0][currentBit]=0; - crcState[i+currentListSize]=crcState[i]; - } - for (int i = currentListSize; i < 2*currentListSize; i++) bit[i][0][currentBit]=1; - bitUpdated[currentBit][0]=1; - updateCrcChecksum2(crcChecksum, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); - currentListSize*=2; - - //Keep only the best "listSize" number of entries. - if (currentListSize > listSize) { - for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; - nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); - - //sort listIndex[listSize, ..., 2*listSize-1] in descending order. - uint8_t swaps, tempInd; - for (uint8_t i = 0; i < listSize; i++) { - swaps = 0; - for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) { - if (listIndex[j+1] > listIndex[j]) { + nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); + for (int i = 0; i < 2*listSize; i++) sorted_dlist[i]=&dlist[listIndex[i]]; + } + /* + //sort listIndex[listSize, ..., 2*listSize-1] in descending order. + uint8_t swaps, tempInd; + for (uint8_t i = 0; i < listSize; i++) { + swaps = 0; + for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) { + if (listIndex[j+1] > listIndex[j]) { tempInd = listIndex[j]; listIndex[j] = listIndex[j + 1]; listIndex[j + 1] = tempInd; @@ -201,11 +216,11 @@ int8_t polar_decoder( //First, backup the best "listSize" number of entries. for (int k=(listSize-1); k>0; k--) { for (int j=0; j<(polarParams->n+1); j++) { - /* - for (int i=0; iN; i++) { - bit[listIndex[(2*listSize-1)-k]][j][i]=bit[listIndex[k]][j][i]; - llr[listIndex[(2*listSize-1)-k]][j][i]=llr[listIndex[k]][j][i]; - }*/ + + //for (int i=0; iN; i++) { + // bit[listIndex[(2*listSize-1)-k]][j][i]=bit[listIndex[k]][j][i]; + // llr[listIndex[(2*listSize-1)-k]][j][i]=llr[listIndex[k]][j][i]; + // } memcpy((void*)&bit[listIndex[(2*listSize-1)-k]][j][0], (void*)&bit[listIndex[k]][j][0], sizeof(uint8_t)*polarParams->N); @@ -231,10 +246,10 @@ int8_t polar_decoder( if (copyIndex!=k) { for (int j = 0; j < (polarParams->n + 1); j++) { - /* for (int i = 0; i < polarParams->N; i++) { - bit[k][j][i] = bit[copyIndex][j][i]; - llr[k][j][i] = llr[copyIndex][j][i]; - }*/ + //for (int i = 0; i < polarParams->N; i++) { + // bit[k][j][i] = bit[copyIndex][j][i]; + // llr[k][j][i] = llr[copyIndex][j][i]; + // } memcpy((void*)&bit[k][j][0],(void*)&bit[copyIndex][j][0],sizeof(uint8_t)*polarParams->N); memcpy((void*)&llr[k][j][0],(void*)&llr[copyIndex][j][0],sizeof(double)*polarParams->N); } @@ -259,7 +274,7 @@ int8_t polar_decoder( crcState[k]=crcState[copyIndex]; } currentListSize = listSize; - } + }*/ stop_meas(sorting); } @@ -272,21 +287,21 @@ int8_t polar_decoder( if ( checkCrcBits > (-1) ) { for (uint8_t i = 0; i < currentListSize; i++) { - if (crcChecksum[checkCrcBits][i]==1) { - crcState[i]=0; //0=False, 1=True + if (dlist[i].crcChecksum[checkCrcBits]==1) { + dlist[i].crcState=0; //0=False, 1=True } } } - for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=crcState[i]; + for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=sorted_dlist[i]->crcState; if (decoderIterationCheck==0) { //perror("[SCL polar decoder] All list entries have failed the CRC checks."); free(d_tilde); - free(pathMetric); - free(crcState); - nr_free_uint8_t_3D_array(bit, 2*listSize, (polarParams->n+1)); - nr_free_double_3D_array(llr, 2*listSize, (polarParams->n+1)); - nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); + for (int i=0;i<2*listSize;i++) { + nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); + nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); + free(dlist[i].crcChecksum); + } stop_meas(decoding); return(-1); } @@ -301,30 +316,30 @@ int8_t polar_decoder( nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { - if ( crcState[listIndex[i]] == 1 ) { - for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=bit[listIndex[i]][0][j]; - - start_meas(bit_extraction); - //Extract the information bits (û to ĉ) - nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); - stop_meas(bit_extraction); - //Deinterleaving (ĉ to b) - start_meas(deinterleaving); - nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); - stop_meas(deinterleaving); - //Remove the CRC (â) - for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; - - break; - } + if ( dlist[i].crcState == 1 ) { + for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=dlist[listIndex[i]].bit[0][j]; + + start_meas(bit_extraction); + //Extract the information bits (û to ĉ) + nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); + stop_meas(bit_extraction); + //Deinterleaving (ĉ to b) + start_meas(deinterleaving); + nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); + stop_meas(deinterleaving); + //Remove the CRC (â) + for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; + + break; + } } - + free(d_tilde); - free(pathMetric); - free(crcState); - nr_free_uint8_t_3D_array(bit, 2*listSize, (polarParams->n+1)); - nr_free_double_3D_array(llr, 2*listSize, (polarParams->n+1)); - nr_free_uint8_t_2D_array(crcChecksum, polarParams->crcParityBits); + for (int i=0;i<2*listSize;i++) { + nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); + nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); + free(dlist[i].crcChecksum); + } nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); nr_free_uint8_t_2D_array(tempECGM, polarParams->K); stop_meas(decoding); 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 888c209090..83ebbdb6c3 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -22,59 +22,85 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" //#define SHOWCOMP 1 -void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, +inline void computeLLR(double **llr, uint16_t row, uint16_t col, + uint16_t offset, uint8_t approximation) __attribute__((always_inline)); +inline void computeLLR(double **llr, uint16_t row, uint16_t col, + uint16_t offset, uint8_t approximation) { + + double a; + double b; + double absA,absB; + + +#ifdef SHOWCOMP + printf("computeLLR (%d,%d,%d,%d)\n",row,col,offset,i); +#endif + a = llr[col + 1][row]; + b = llr[col+1][row + offset]; + + if (approximation) { //eq. (9) + absA = fabs(a); + absB = fabs(b); + llr[col][row] = copysign(1.0, a) * copysign(1.0, b) * fmin(absA, absB); + } else { //eq. (8a) + llr[col][row] = log((exp(a + b) + 1) / (exp(a) + exp(b))); + } +} + + +void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) { uint16_t offset = (xlen/(1<<(ylen-col-1))); if (( (row) % (2*offset) ) >= offset ) { - if (bitU[row-offset][col]==0) updateBit(bit, bitU, listSize, (row-offset), col, xlen, ylen); - if (llrU[row-offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation); - if (llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); + if (bitU[row-offset][col]==0) updateBit(dlist, bitU, listSize, (row-offset), col, xlen, ylen); + if (llrU[row-offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation); + if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation); for (uint8_t i=0; illr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row]; } } else { - if (llrU[row][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, row, (col+1), xlen, ylen, approximation); - if (llrU[row+offset][col+1]==0) updateLLR(llr, llrU, bit, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation); - computeLLR(llr, row, col, listSize, offset, approximation); - + if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation); + if (llrU[row+offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation); + for (int i=0;illr, row, col, offset, approximation); + } - + llrU[row][col]=1; } -void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, - uint16_t col, uint16_t xlen, uint8_t ylen) { - uint16_t offset = ( xlen/(pow(2,(ylen-col))) ); - - for (uint8_t i=0; i= offset ) { - if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen); - bit[i][col][row] = bit[i][col-1][row]; +void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, + uint16_t col, uint16_t xlen, uint8_t ylen) { + uint16_t offset = ( xlen/(pow(2,(ylen-col))) ); + + for (uint8_t i=0; i= offset ) { + if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen); + dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]; #ifdef SHOWCOMP - printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n", - row,col,i,row,col-1,i); + printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n", + row,col,i,row,col-1,i); #endif - } else { - if (bitU[row][col-1]==0) updateBit(bit, bitU, listSize, row, (col-1), xlen, ylen); - if (bitU[row+offset][col-1]==0) updateBit(bit, bitU, listSize, (row+offset), (col-1), xlen, ylen); - bit[i][col][row] = ( (bit[i][col-1][row]+bit[i][col-1][row+offset]) % 2); + } else { + if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen); + if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen); + dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2); #ifdef SHOWCOMP - printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", - row,col,i,row,col-1,i,row+offset,col-1,i); + printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", + row,col,i,row,col-1,i,row+offset,col-1,i); #endif - } - } - - bitU[row][col]=1; + } + } + + bitU[row][col]=1; } -void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8_t bitValue, +void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, uint16_t row, uint8_t approximation) { #ifdef SHOWCOMP @@ -84,11 +110,11 @@ void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, uint8 if (approximation) { //eq. (12) for (uint8_t i=0; illr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]); } } else { //eq. (11b) int8_t multiplier = (2*bitValue) - 1; - for (uint8_t i=0; ipathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ; } } @@ -124,13 +150,13 @@ void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint } */ -void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint16_t row, uint8_t appr) { - - double *pm2=&pathMetric[listSize]; - memcpy((void*)pm2,(void*)pathMetric,listSize*sizeof(double*)); +void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) { int i; + for (i=0;ipathMetric = dlist[i]->pathMetric; + decoder_list_t **dlist2 = &dlist[listSize]; + #ifdef SHOWCOMP printf("updating path_metric from information bit (%d,%d) \n", row,0); @@ -138,65 +164,36 @@ void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint if (appr) { //eq. (12) for (i = 0; i < listSize; i++) { // bitValue=0 - if (llr[i][0][row]<0) pathMetric[i] -= llr[i][0][row]; + if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row]; // bitValue=1 - else pm2[i] += llr[i][0][row]; + else dlist2[i]->pathMetric += dlist[i]->llr[0][row]; } } else { //eq. (11b) for (i = 0; i < listSize; i++) { // bitValue=0 - pathMetric[i] += log(1 + exp(-llr[i][0][row])); + dlist[i]->pathMetric += log(1 + exp(-dlist[i]->llr[0][row])); // bitValue=1 - pm2[i] += log(1 + exp(llr[i][0][row])); + dlist2[i]->pathMetric += log(1 + exp(dlist[i]->llr[0][row])); } } } -inline void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t listSize, - uint16_t offset, uint8_t approximation) __attribute__((always_inline)); -inline void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t listSize, - uint16_t offset, uint8_t approximation) { - - double a; - double b; - double absA,absB; -#ifdef SHOWCOMP - printf("computeLLR (%d,%d,%d,%d)\n",row,col,offset,i); -#endif - if (approximation) { //eq. (9) - for (int i=0;icrcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + } + } } -void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len) { - for (uint8_t i = 0; i < listSize; i++) { - for (uint8_t j = 0; j < len; j++) { - crcChecksum[j][i] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 ); - } - } -} - -void updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len) { - for (uint8_t i = 0; i < listSize; i++) { - for (uint8_t j = 0; j < len; j++) { - crcChecksum[j][i+listSize] = ( (crcChecksum[j][i] + crcGen[i2][j]) % 2 ); - } - } +void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len) { + for (uint8_t i = 0; i < listSize; i++) { + for (uint8_t j = 0; j < len; j++) { + dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + } + } } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index b568004da5..1faf13e885 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -124,27 +124,41 @@ void nr_matrix_multiplication_uint8_t_1D_uint8_t_2D(uint8_t *matrix1, uint8_t ** uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen); uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen); -double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen); +double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen); void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen); void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen); -void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen); +void nr_free_double_2D_array(double **input, uint16_t xlen); + + +typedef struct decoder_list_s { + + uint8_t **bit; + double **llr; + uint8_t *crcChecksum; + uint8_t crcState; + double pathMetric; + +} decoder_list_t; + +void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU, + uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation); + +void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, + uint16_t col, uint16_t xlen, uint8_t ylen); + +void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, + uint16_t row, uint8_t approximation); + +void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr); + +void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len); + +void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len); + -void updateLLR(double ***llr, uint8_t **llrU, uint8_t ***bit, uint8_t **bitU, - uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, - uint8_t ylen, uint8_t approximation); -void updateBit(uint8_t ***bit, uint8_t **bitU, uint8_t listSize, uint16_t row, - uint16_t col, uint16_t xlen, uint8_t ylen); -void updatePathMetric(double *pathMetric, double ***llr, uint8_t listSize, - uint8_t bitValue, uint16_t row, uint8_t approximation); -void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, - uint16_t row, uint8_t approximation); -void computeLLR(double ***llr, uint16_t row, uint16_t col, uint8_t i, - uint16_t offset, uint8_t approximation); -void updateCrcChecksum(uint8_t **crcChecksum, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len); -void updateCrcChecksum2(uint8_t **crcChecksum, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len); void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len); uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c index 572b016cfa..ad37cdbf27 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c @@ -66,38 +66,30 @@ uint8_t ***nr_alloc_uint8_t_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen return output; } -double ***nr_alloc_double_3D_array(uint16_t xlen, uint16_t ylen, uint16_t zlen) { - double ***output; - int i, j; +double **nr_alloc_double_2D_array(uint16_t xlen, uint16_t ylen) { + double **output; + int i, j; + + if ((output = malloc(xlen * sizeof(*output))) == NULL) { + perror("[nr_alloc_double_3D_array] Problem at 1D allocation"); + return NULL; + } + for (i = 0; i < xlen; i++) + output[i] = NULL; + + + for (i = 0; i < xlen; i++) + if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) { + perror("[nr_alloc_double_2D_array] Problem at 2D allocation"); + nr_free_double_2D_array(output, xlen); + return NULL; + } + for (i = 0; i < xlen; i++) + for (j = 0; j < ylen; j++) + output[i][j] = 0; + - if ((output = malloc(xlen * sizeof(*output))) == NULL) { - perror("[nr_alloc_double_3D_array] Problem at 1D allocation"); - return NULL; - } - for (i = 0; i < xlen; i++) - output[i] = NULL; - - - for (i = 0; i < xlen; i++) - if ((output[i] = malloc(ylen * sizeof *output[i])) == NULL) { - perror("[nr_alloc_double_3D_array] Problem at 2D allocation"); - nr_free_double_3D_array(output, xlen, ylen); - return NULL; - } - for (i = 0; i < xlen; i++) - for (j = 0; j < ylen; j++) - output[i][j] = NULL; - - - for (i = 0; i < xlen; i++) - for (j = 0; j < ylen; j++) - if ((output[i][j] = malloc(zlen * sizeof *output[i][j])) == NULL) { - perror("[nr_alloc_double_3D_array] Problem at 3D allocation"); - nr_free_double_3D_array(output, xlen, ylen); - return NULL; - } - - return output; + return output; } uint8_t **nr_alloc_uint8_t_2D_array(uint16_t xlen, uint16_t ylen) { @@ -142,16 +134,13 @@ void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen) { free(input); } -void nr_free_double_3D_array(double ***input, uint16_t xlen, uint16_t ylen) { - int i, j; - - for (i = 0; i < xlen; i++) { - for (j = 0; j < ylen; j++) { - free(input[i][j]); - } - free(input[i]); - } - free(input); +void nr_free_double_2D_array(double **input, uint16_t xlen) { + int i; + + for (i = 0; i < xlen; i++) { + free(input[i]); + } + free(input); } // Modified Bubble Sort. From 720d0d31cdfa91a455d3f24acd92bcf343396646 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 13 Sep 2018 10:22:20 +0200 Subject: [PATCH 08/19] some debugging of memory leaks --- .../PHY/CODING/nrPolar_tools/nr_polar_decoder.c | 12 ++++++++---- openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h | 2 +- .../nrPolar_tools/nr_polar_matrix_and_array.c | 14 +++++++------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index cb75811a11..475fc73a77 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -188,14 +188,15 @@ int8_t polar_decoder( //Keep only the best "listSize" number of entries. if (currentListSize > listSize) { - for (int i = 0; i < 2*listSize; i++) { + for (int i = 0; i < currentListSize; i++) { listIndex[i]=i; pathMetric[i] = dlist[i].pathMetric; } - nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); - for (int i = 0; i < 2*listSize; i++) sorted_dlist[i]=&dlist[listIndex[i]]; + currentListSize = listSize; } + stop_meas(sorting); + /* //sort listIndex[listSize, ..., 2*listSize-1] in descending order. uint8_t swaps, tempInd; @@ -275,7 +276,7 @@ int8_t polar_decoder( } currentListSize = listSize; }*/ - stop_meas(sorting); + } for (int i=0; icrcParityBits; i++) { @@ -298,7 +299,9 @@ int8_t polar_decoder( //perror("[SCL polar decoder] All list entries have failed the CRC checks."); free(d_tilde); for (int i=0;i<2*listSize;i++) { + // printf("error: Freeing dlist[%d].bit %p\n",i,dlist[i].bit); nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); + // printf("error: Freeing dlist[%d].llr %p\n",i,dlist[i].bit); nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); free(dlist[i].crcChecksum); } @@ -336,6 +339,7 @@ int8_t polar_decoder( free(d_tilde); for (int i=0;i<2*listSize;i++) { + // printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit); nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); free(dlist[i].crcChecksum); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 1faf13e885..b5aa841468 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -159,7 +159,7 @@ void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, uint8_t listSize, uint32_t i2, uint8_t len); -void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len); +void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len); uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits); uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c index ad37cdbf27..87da27a59f 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c @@ -130,8 +130,8 @@ void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen) { } void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen) { - for (int i = 0; i < xlen; i++) free(input[i]); - free(input); + for (int i = 0; i < xlen; i++) free(input[i]); + free(input); } void nr_free_double_2D_array(double **input, uint16_t xlen) { @@ -144,14 +144,14 @@ void nr_free_double_2D_array(double **input, uint16_t xlen) { } // Modified Bubble Sort. -void nr_sort_asc_double_1D_array_ind(double *matrix, uint8_t *ind, uint8_t len) { - uint8_t swaps; +void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len) { + int swaps; double temp; - uint8_t tempInd; + int tempInd; - for (uint8_t i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { swaps = 0; - for (uint8_t j = 0; j < (len - i) - 1; j++) { + for (int j = 0; j < (len - i) - 1; j++) { if (matrix[j] > matrix[j + 1]) { temp = matrix[j]; matrix[j] = matrix[j + 1]; From 8b8e6e1209ad7d5bb93f156aabf3cff181ed947b Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 26 Sep 2018 15:04:58 +0200 Subject: [PATCH 09/19] new data strucure for list management (decoding ok) --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 167 +++--------------- .../nrPolar_tools/nr_polar_decoding_tools.c | 4 +- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 8 +- 3 files changed, 35 insertions(+), 144 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 475fc73a77..9e9029800e 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: + * For more information about the OpenAirInterface (OAI) Software Alliance * contact@openairinterface.org */ @@ -56,9 +56,9 @@ int8_t polar_decoder( decoder_list_t dlist[2*listSize]; for ( int i=0;i<2*listSize;i++) { - dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); - dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N); - dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits); + // dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); + // dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N); + //dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits); for (int j=0; j< polarParams->n+1; j++) { memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N); memset((void*)&dlist[i].llr[j][0],0,sizeof(double)*polarParams->N); @@ -115,7 +115,7 @@ int8_t polar_decoder( stop_meas(init); start_meas(polar_rate_matching); - double *d_tilde = malloc(sizeof(double) * polarParams->N); + double d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N); stop_meas(polar_rate_matching); @@ -126,8 +126,6 @@ int8_t polar_decoder( start_meas(decoding); uint32_t nonFrozenBit=0; uint8_t currentListSize=1; - uint8_t decoderIterationCheck=0; - int16_t checkCrcBits=-1; uint8_t copyIndex=0; decoder_list_t *sorted_dlist[2*listSize]; @@ -137,7 +135,7 @@ int8_t polar_decoder( for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; for (uint16_t currentBit=0; currentBitN; currentBit++){ - // printf("***************** BIT %d\n",currentBit); + // printf("***************** BIT %d\n",currentBit); start_meas(update_LLR); updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); @@ -161,17 +159,14 @@ int8_t polar_decoder( bitUpdated[currentBit][0]=1; updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); } else { + start_meas(path_metric); updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr); stop_meas(path_metric); + start_meas(sorting); for (int i = 0; i < currentListSize; i++) { for (int k = 0; k < (polarParams->n+1); k++) { - /* - for (int j = 0; j < polarParams->N; j++) { - bit[i+currentListSize][k][j]=bit[i][k][j]; - llr[i+currentListSize][k][j]=llr[i][k][j]; - }*/ memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],(void*)&sorted_dlist[i]->bit[k][0],sizeof(uint8_t)*polarParams->N); memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],(void*)&sorted_dlist[i]->llr[k][0],sizeof(double)*polarParams->N); } @@ -181,7 +176,7 @@ int8_t polar_decoder( sorted_dlist[i]->bit[0][currentBit]=0; sorted_dlist[i+currentListSize]->crcState=sorted_dlist[i]->crcState; } - for (int i = currentListSize; i < 2*currentListSize; i++) sorted_dlist[i]->bit[currentBit]=1; + for (int i = currentListSize; i < 2*currentListSize; i++) sorted_dlist[i]->bit[0][currentBit]=1; bitUpdated[currentBit][0]=1; updateCrcChecksum2(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); currentListSize*=2; @@ -194,133 +189,26 @@ int8_t polar_decoder( } nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); currentListSize = listSize; + for (uint8_t i = 0; i < 2*listSize; i++) { + sorted_dlist[i] = &dlist[listIndex[i]]; + } } stop_meas(sorting); - - /* - //sort listIndex[listSize, ..., 2*listSize-1] in descending order. - uint8_t swaps, tempInd; - for (uint8_t i = 0; i < listSize; i++) { - swaps = 0; - for (uint8_t j = listSize; j < (2*listSize - i) - 1; j++) { - if (listIndex[j+1] > listIndex[j]) { - tempInd = listIndex[j]; - listIndex[j] = listIndex[j + 1]; - listIndex[j + 1] = tempInd; - swaps++; - } - } - if (swaps == 0) - break; - } - - //First, backup the best "listSize" number of entries. - for (int k=(listSize-1); k>0; k--) { - for (int j=0; j<(polarParams->n+1); j++) { - - //for (int i=0; iN; i++) { - // bit[listIndex[(2*listSize-1)-k]][j][i]=bit[listIndex[k]][j][i]; - // llr[listIndex[(2*listSize-1)-k]][j][i]=llr[listIndex[k]][j][i]; - // } - memcpy((void*)&bit[listIndex[(2*listSize-1)-k]][j][0], - (void*)&bit[listIndex[k]][j][0], - sizeof(uint8_t)*polarParams->N); - memcpy((void*)&llr[listIndex[(2*listSize-1)-k]][j][0], - (void*)&llr[listIndex[k]][j][0], - sizeof(double)*polarParams->N); - } - } - for (int k=(listSize-1); k>0; k--) { - for (int i = 0; i < polarParams->crcParityBits; i++) { - crcChecksum[i][listIndex[(2*listSize-1)-k]] = crcChecksum[i][listIndex[k]]; - } - } - for (int k=(listSize-1); k>0; k--) crcState[listIndex[(2*listSize-1)-k]]=crcState[listIndex[k]]; - - //Copy the best "listSize" number of entries to the first indices. - for (int k = 0; k < listSize; k++) { - if (k > listIndex[k]) { - copyIndex = listIndex[(2*listSize-1)-k]; - } else { //Use the backup. - copyIndex = listIndex[k]; - } - - if (copyIndex!=k) { - for (int j = 0; j < (polarParams->n + 1); j++) { - //for (int i = 0; i < polarParams->N; i++) { - // bit[k][j][i] = bit[copyIndex][j][i]; - // llr[k][j][i] = llr[copyIndex][j][i]; - // } - memcpy((void*)&bit[k][j][0],(void*)&bit[copyIndex][j][0],sizeof(uint8_t)*polarParams->N); - memcpy((void*)&llr[k][j][0],(void*)&llr[copyIndex][j][0],sizeof(double)*polarParams->N); - } - } - } - for (int k = 0; k < listSize; k++) { - if (k > listIndex[k]) { - copyIndex = listIndex[(2*listSize-1)-k]; - } else { //Use the backup. - copyIndex = listIndex[k]; - } - for (int i = 0; i < polarParams->crcParityBits; i++) { - crcChecksum[i][k]=crcChecksum[i][copyIndex]; - } - } - for (int k = 0; k < listSize; k++) { - if (k > listIndex[k]) { - copyIndex = listIndex[(2*listSize-1)-k]; - } else { //Use the backup. - copyIndex = listIndex[k]; - } - crcState[k]=crcState[copyIndex]; - } - currentListSize = listSize; - }*/ - - } - - for (int i=0; icrcParityBits; i++) { - if (last1ind[i]==nonFrozenBit) { - checkCrcBits=i; - break; - } - } - - if ( checkCrcBits > (-1) ) { - for (uint8_t i = 0; i < currentListSize; i++) { - if (dlist[i].crcChecksum[checkCrcBits]==1) { - dlist[i].crcState=0; //0=False, 1=True - } - } - } - - for (uint8_t i = 0; i < currentListSize; i++) decoderIterationCheck+=sorted_dlist[i]->crcState; - if (decoderIterationCheck==0) { - //perror("[SCL polar decoder] All list entries have failed the CRC checks."); - free(d_tilde); - for (int i=0;i<2*listSize;i++) { - // printf("error: Freeing dlist[%d].bit %p\n",i,dlist[i].bit); - nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); - // printf("error: Freeing dlist[%d].llr %p\n",i,dlist[i].bit); - nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); - free(dlist[i].crcChecksum); - } - stop_meas(decoding); - return(-1); - } - - nonFrozenBit++; - decoderIterationCheck=0; - checkCrcBits=-1; - } + + } + nonFrozenBit++; + } + } - - for (uint8_t i = 0; i < 2*listSize; i++) listIndex[i]=i; - nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); - + for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { - if ( dlist[i].crcState == 1 ) { - for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=dlist[listIndex[i]].bit[0][j]; + // printf("list index %d :",i); + // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); + // printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric); + int crcState = 1; + for (int j=0;jcrcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0; + if (crcState == 1) { + for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j]; start_meas(bit_extraction); //Extract the information bits (û to ĉ) @@ -337,13 +225,14 @@ int8_t polar_decoder( } } - free(d_tilde); + // free(d_tilde); + /* for (int i=0;i<2*listSize;i++) { // printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit); nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); free(dlist[i].crcChecksum); - } + }*/ nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); nr_free_uint8_t_2D_array(tempECGM, polarParams->K); stop_meas(decoding); 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 83ebbdb6c3..2596962d97 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -22,9 +22,9 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" //#define SHOWCOMP 1 -inline void computeLLR(double **llr, uint16_t row, uint16_t col, +inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, uint16_t offset, uint8_t approximation) __attribute__((always_inline)); -inline void computeLLR(double **llr, uint16_t row, uint16_t col, +inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, uint16_t offset, uint8_t approximation) { double a; diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index b5aa841468..c35856a0ce 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -130,12 +130,14 @@ void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen); void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen); void nr_free_double_2D_array(double **input, uint16_t xlen); +#define Nmax 1024 +#define nmax 10 typedef struct decoder_list_s { - uint8_t **bit; - double **llr; - uint8_t *crcChecksum; + uint8_t bit[1+nmax][Nmax]; + double llr[1+nmax][Nmax]; + uint8_t crcChecksum[24]; uint8_t crcState; double pathMetric; From 8cda0a0f7bd793cbd1c5a40086b7c0e6b9668769 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 30 Sep 2018 23:38:07 +0200 Subject: [PATCH 10/19] 16-bit integer optimization, reduced memcpy after list sorting --- openair1/PHY/CODING/TESTBENCH/polartest.c | 27 +- .../CODING/nrPolar_tools/nr_polar_decoder.c | 656 +++++++++++++----- .../nrPolar_tools/nr_polar_decoding_tools.c | 185 ++++- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 33 +- .../nrPolar_tools/nr_polar_matrix_and_array.c | 25 + .../nrPolar_tools/nr_polar_rate_match.c | 21 + 6 files changed, 731 insertions(+), 216 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index e844ed74db..9a10b42edb 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -18,6 +18,7 @@ int main(int argc, char *argv[]) { time_stats_t polar_decoder_init,polar_rate_matching,decoding,bit_extraction,deinterleaving; time_stats_t path_metric,sorting,update_LLR; opp_enabled=1; + int decoder_int8=0; cpu_freq_GHz = get_cpu_freq_GHz(); reset_meas(&timeEncoder); reset_meas(&timeDecoder); @@ -30,7 +31,7 @@ int main(int argc, char *argv[]) { reset_meas(&path_metric); reset_meas(&update_LLR); - randominit(0); + randominit(1234); //Default simulation values (Aim for iterations = 1000000.) int itr, iterations = 1000, arguments, polarMessageType = 1; //0=DCI, 1=PBCH, 2=UCI double SNRstart = -20.0, SNRstop = 0.0, SNRinc= 0.5; //dB @@ -43,7 +44,7 @@ int main(int argc, char *argv[]) { uint8_t decoderListSize = 8, pathMetricAppr = 0; //0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12) - while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h")) != -1) + while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h:q")) != -1) switch (arguments) { case 's': @@ -75,6 +76,10 @@ int main(int argc, char *argv[]) { pathMetricAppr = (uint8_t) atoi(optarg); break; + case 'q': + decoder_int8=1; + break; + case 'h': printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=DCI|1=PBCH|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n"); exit(-1); @@ -131,6 +136,7 @@ int main(int argc, char *argv[]) { double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input double *channelOutput = malloc (sizeof(double) * coderLength); //add noise + int16_t *channelOutput_int8 = malloc (sizeof(int16_t) * coderLength); //add noise uint8_t *estimatedOutput = malloc(sizeof(uint8_t) * testLength); //decoder output t_nrPolar_params nrPolar_params; @@ -159,12 +165,19 @@ int main(int argc, char *argv[]) { modulatedInput[i]=(-1)/sqrt(2); channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); + if (decoder_int8==1) { + if (channelOutput[i] > 1024) channelOutput_int8[i] = 32768; + else if (channelOutput[i] < -1023) channelOutput_int8[i] = -32767; + else channelOutput_int8[i] = (int16_t) (32*channelOutput[i]); + } } start_meas(&timeDecoder); - decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params, decoderListSize, aPrioriArray, pathMetricAppr,&polar_decoder_init,&polar_rate_matching,&decoding,&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR); - stop_meas(&timeDecoder); + if (decoder_int8==0) decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params, decoderListSize, aPrioriArray, pathMetricAppr,&polar_decoder_init,&polar_rate_matching,&decoding,&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR); + else + decoderState = polar_decoder_int8(channelOutput_int8, estimatedOutput, &nrPolar_params, decoderListSize, &polar_decoder_init,&polar_rate_matching,&decoding,&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR); + stop_meas(&timeDecoder); //calculate errors if (decoderState==-1) { @@ -207,9 +220,9 @@ int main(int argc, char *argv[]) { printf("decoding decoding %9.3fus\n",decoding.diff/(cpu_freq_GHz*1000.0*decoding.trials)); printf("decoding bit_extraction %9.3fus\n",bit_extraction.diff/(cpu_freq_GHz*1000.0*bit_extraction.trials)); printf("decoding deinterleaving %9.3fus\n",deinterleaving.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials)); - printf("decoding path_metric %9.3fus\n",path_metric.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials)); - printf("decoding sorting %9.3fus\n",sorting.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials)); - printf("decoding updateLLR %9.3fus\n",update_LLR.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials)); + printf("decoding path_metric %9.3fus\n",path_metric.diff/(cpu_freq_GHz*1000.0*decoding.trials)); + printf("decoding sorting %9.3fus\n",sorting.diff/(cpu_freq_GHz*1000.0*decoding.trials)); + printf("decoding updateLLR %9.3fus\n",update_LLR.diff/(cpu_freq_GHz*1000.0*decoding.trials)); blockErrorCumulative = 0; bitErrorCumulative = 0; timeEncoderCumulative = 0; timeDecoderCumulative = 0; } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 9e9029800e..e1b248b27e 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -48,193 +48,499 @@ int8_t polar_decoder( time_stats_t *update_LLR) { - start_meas(init); - - - uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True - uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True - decoder_list_t dlist[2*listSize]; - - for ( int i=0;i<2*listSize;i++) { - // dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); - // dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N); - //dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits); - for (int j=0; j< polarParams->n+1; j++) { - memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N); - memset((void*)&dlist[i].llr[j][0],0,sizeof(double)*polarParams->N); - } - for (int j=0;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; - dlist[i].crcState = 1; - dlist[i].pathMetric = 0; - } - - for (int i=0; iN; i++) { - memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); - memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); - llrUpdated[i][polarParams->n]=1; - bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); - } - + start_meas(init); + + + uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + decoder_list_t dlist[2*listSize]; + + for ( int i=0;i<2*listSize;i++) { + // dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); + // dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N); + //dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits); + for (int j=0; j< polarParams->n+1; j++) { + memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N); + memset((void*)&dlist[i].llr[j][0],0,sizeof(double)*polarParams->N); + } + for (int j=0;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; + dlist[i].pathMetric = 0; + } + + for (int i=0; iN; i++) { + memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); + memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); + llrUpdated[i][polarParams->n]=1; + bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); + } + + + uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 + uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2 + for (int i = 0; i < polarParams->K; i++){ + extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); + tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); + } + + for (int i=0; ipayloadBits; i++) { + for (int j=0; jcrcParityBits; j++) { + tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; + } + } + for (int i=polarParams->payloadBits; iK; i++) { + for (int j=0; jcrcParityBits; j++) { + if( (i-polarParams->payloadBits) == j ){ + tempECGM[i][j]=1; + } else { + tempECGM[i][j]=0; + } + } + } + + for (int i=0; iK; i++) { + for (int j=0; jcrcParityBits; j++) { + extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; + } + } + + stop_meas(init); + start_meas(polar_rate_matching); + + double d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); + nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N); + stop_meas(polar_rate_matching); + + /* + * SCL polar decoder. + */ + start_meas(decoding); + uint32_t nonFrozenBit=0; + uint8_t currentListSize=1; + + decoder_list_t *sorted_dlist[2*listSize]; + decoder_list_t *temp_dlist[2*listSize]; + int listIndex[2*listSize]; + double pathMetric[2*listSize]; + + for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; + + for (uint16_t currentBit=0; currentBitN; currentBit++){ + printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", + currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); + + start_meas(update_LLR); + updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); + stop_meas(update_LLR); + + if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. + updatePathMetric(sorted_dlist,currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 + } else { //Information or CRC bit. + if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) { + //Information bit with known value of "0". + updatePathMetric(sorted_dlist, currentListSize, 0, currentBit, pathMetricAppr); + bitUpdated[currentBit][0]=1; //0=False, 1=True + } else if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { + //Information bit with known value of "1". + printf("Information bit with known value of 1\n"); + updatePathMetric(sorted_dlist, currentListSize, 1, currentBit, pathMetricAppr); + for (uint8_t i=0; ibit[0][currentBit]=1; + bitUpdated[currentBit][0]=1; + updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); + } else { - uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 - uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2 - for (int i = 0; i < polarParams->K; i++){ - extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); - tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); - } + start_meas(path_metric); + updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr); + stop_meas(path_metric); + + start_meas(sorting); - for (int i=0; ipayloadBits; i++) { - for (int j=0; jcrcParityBits; j++) { - tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; - } - } - for (int i=polarParams->payloadBits; iK; i++) { - for (int j=0; jcrcParityBits; j++) { - if( (i-polarParams->payloadBits) == j ){ - tempECGM[i][j]=1; - } else { - tempECGM[i][j]=0; - } - } - } - - for (int i=0; iK; i++) { - for (int j=0; jcrcParityBits; j++) { - extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; - } - } - - //The index of the last 1-valued bit that appears in each column. - uint16_t last1ind[polarParams->crcParityBits]; - for (int j=0; jcrcParityBits; j++) { - for (int i=0; iK; i++) { - if (extended_crc_generator_matrix[i][j]==1) last1ind[j]=i; - } - } - - stop_meas(init); - start_meas(polar_rate_matching); - - double d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); - nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); - memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N); - stop_meas(polar_rate_matching); - - /* - * SCL polar decoder. - */ - start_meas(decoding); - uint32_t nonFrozenBit=0; - uint8_t currentListSize=1; - uint8_t copyIndex=0; - - decoder_list_t *sorted_dlist[2*listSize]; - int listIndex[2*listSize]; - double pathMetric[2*listSize]; - - for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; - - for (uint16_t currentBit=0; currentBitN; currentBit++){ - // printf("***************** BIT %d\n",currentBit); - - start_meas(update_LLR); - updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); - stop_meas(update_LLR); - - if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. - updatePathMetric(sorted_dlist,currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 - } else { //Information or CRC bit. - if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 0) ) { - printf("app[%d] %f, payloadBits %d\n",polarParams->interleaving_pattern[nonFrozenBit], - polarParams->payloadBits, - aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]]); + for (int i=0;ipathMetric); + } + if (currentListSize <= listSize/2) { + // until listsize is full we need to copy bit and LLR arrays to new entries + // below we only copy the ones we need to keep for sure + + for (int i = 0; i < currentListSize; i++) { + for (int k = 0; k < (polarParams->n+1); k++) { - //Information bit with known value of "0". - updatePathMetric(sorted_dlist, currentListSize, 0, currentBit, pathMetricAppr); - bitUpdated[currentBit][0]=1; //0=False, 1=True - } else if ( (polarParams->interleaving_pattern[nonFrozenBit] < polarParams->payloadBits) && (aPrioriPayload[polarParams->interleaving_pattern[nonFrozenBit]] == 1) ) { - //Information bit with known value of "1". - updatePathMetric(sorted_dlist, currentListSize, 1, currentBit, pathMetricAppr); - for (uint8_t i=0; ibit[0][currentBit]=1; - bitUpdated[currentBit][0]=1; - updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); - } else { + memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],(void*)&sorted_dlist[i]->bit[k][0],sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],(void*)&sorted_dlist[i]->llr[k][0],sizeof(double)*polarParams->N); + } + } + } + + for (int i = 0; i < currentListSize; i++) { + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+currentListSize]->bit[0][currentBit]=1; + } + bitUpdated[currentBit][0]=1; + updateCrcChecksum2(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); + + currentListSize*=2; + + //Keep only the best "listSize" number of entries. + if (currentListSize > listSize) { + int listIndex2[listSize]; + + for (int i = 0; i < currentListSize; i++) { + listIndex[i]=i; + pathMetric[i] = sorted_dlist[i]->pathMetric; + } + nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); + for (int i=0;in+1); k++) { - memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],(void*)&sorted_dlist[i]->bit[k][0],sizeof(uint8_t)*polarParams->N); - memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],(void*)&sorted_dlist[i]->llr[k][0],sizeof(double)*polarParams->N); - } - } + + // copy the llr/bit arrays that are needed + for (int i = 0; i < listSize; i++) { + printf("listIndex[%d] %d\n",i,listIndex[i]); + if ((listIndex2[i+listSize]bit[0][currentBit]=0; - sorted_dlist[i+currentListSize]->crcState=sorted_dlist[i]->crcState; + for (int k = 0; k < (polarParams->n+1); k++) { + + memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], + (void*)&sorted_dlist[i]->bit[k][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], + (void*)&sorted_dlist[i]->llr[k][0], + sizeof(double)*polarParams->N); } - for (int i = currentListSize; i < 2*currentListSize; i++) sorted_dlist[i]->bit[0][currentBit]=1; - bitUpdated[currentBit][0]=1; - updateCrcChecksum2(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); - currentListSize*=2; + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + } + else if (listIndex2[i+listSize] listSize) { - for (int i = 0; i < currentListSize; i++) { - listIndex[i]=i; - pathMetric[i] = dlist[i].pathMetric; - } - nr_sort_asc_double_1D_array_ind(pathMetric, listIndex, currentListSize); - currentListSize = listSize; - for (uint8_t i = 0; i < 2*listSize; i++) { - sorted_dlist[i] = &dlist[listIndex[i]]; - } + for (int k = 0; k < (polarParams->n+1); k++) { + memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], + (void*)&sorted_dlist[i]->bit[k][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], + (void*)&sorted_dlist[i]->llr[k][0], + sizeof(double)*polarParams->N); } - stop_meas(sorting); + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + + /* + decoder_list_t *tmp = sorted_dlist[i+listSize]; + sorted_dlist[i+listSize] = sorted_dlist[i]; + sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0], + (void*)&tmp->crcChecksum[0], + 24*sizeof(uint8_t));*/ } - nonFrozenBit++; } - - } - - for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { - // printf("list index %d :",i); - // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); - // printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric); - int crcState = 1; - for (int j=0;jcrcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0; - if (crcState == 1) { - for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j]; - - start_meas(bit_extraction); - //Extract the information bits (û to ĉ) - nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); - stop_meas(bit_extraction); - //Deinterleaving (ĉ to b) - start_meas(deinterleaving); - nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); - stop_meas(deinterleaving); - //Remove the CRC (â) - for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; - - break; + + currentListSize = listSize; + + for (int i = 0; i < 2*listSize; i++) { + temp_dlist[i] = sorted_dlist[i]; + } + for (int i = 0; i < 2*listSize; i++) { + // printf("i %d => %d\n",i,listIndex[i]); + sorted_dlist[i] = temp_dlist[listIndex[i]]; } } + stop_meas(sorting); - // free(d_tilde); - /* - for (int i=0;i<2*listSize;i++) { - // printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit); - nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); - nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); - free(dlist[i].crcChecksum); - }*/ - nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); - nr_free_uint8_t_2D_array(tempECGM, polarParams->K); - stop_meas(decoding); - return(0); + } + nonFrozenBit++; + } + + } + + for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { + // printf("list index %d :",i); + // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); + // printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric); + int crcState = 1; + for (int j=0;jcrcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0; + if (crcState == 1) { + for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j]; + + start_meas(bit_extraction); + //Extract the information bits (û to ĉ) + nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); + stop_meas(bit_extraction); + //Deinterleaving (ĉ to b) + start_meas(deinterleaving); + nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); + stop_meas(deinterleaving); + //Remove the CRC (â) + for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; + + break; + } + } + + // free(d_tilde); + /* + for (int i=0;i<2*listSize;i++) { + // printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit); + nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); + nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); + free(dlist[i].crcChecksum); + }*/ + nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); + nr_free_uint8_t_2D_array(tempECGM, polarParams->K); + stop_meas(decoding); + return(0); +} + + +int8_t polar_decoder_int8(int16_t *input, + uint8_t *output, + t_nrPolar_params *polarParams, + uint8_t listSize, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR) +{ + + start_meas(init); + + + uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + decoder_list_int8_t dlist[2*listSize]; + + + for ( int i=0;i<2*listSize;i++) { + // dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); + // dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N); + //dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits); + for (int j=0; j< polarParams->n+1; j++) { + memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N); + memset((void*)&dlist[i].llr[j][0],0,sizeof(int16_t)*polarParams->N); + } + for (int j=0;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; + dlist[i].pathMetric = 0; + } + + for (int i=0; iN; i++) { + memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); + memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); + llrUpdated[i][polarParams->n]=1; + bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); + } + + + uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 + uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2 + for (int i = 0; i < polarParams->K; i++){ + extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); + tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); + } + + for (int i=0; ipayloadBits; i++) { + for (int j=0; jcrcParityBits; j++) { + tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; + } + } + for (int i=polarParams->payloadBits; iK; i++) { + for (int j=0; jcrcParityBits; j++) { + if( (i-polarParams->payloadBits) == j ){ + tempECGM[i][j]=1; + } else { + tempECGM[i][j]=0; + } + } + } + + for (int i=0; iK; i++) { + for (int j=0; jcrcParityBits; j++) { + extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; + } + } + + stop_meas(init); + start_meas(polar_rate_matching); + + int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); + nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N); + stop_meas(polar_rate_matching); + + /* + * SCL polar decoder. + */ + start_meas(decoding); + uint32_t nonFrozenBit=0; + uint8_t currentListSize=1; + + decoder_list_int8_t *sorted_dlist[2*listSize]; + decoder_list_int8_t *temp_dlist[2*listSize]; + int listIndex[2*listSize]; + int32_t pathMetric[2*listSize]; + + for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; + + for (uint16_t currentBit=0; currentBitN; currentBit++){ + // printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", + // currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); + + start_meas(update_LLR); + updateLLR_int8(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1)); + stop_meas(update_LLR); + + if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. + updatePathMetric0_int8(sorted_dlist,currentListSize, currentBit); //approximation=0 --> 11b, approximation=1 --> 12 + } else { //Information or CRC bit. + start_meas(path_metric); + updatePathMetric2_int8(sorted_dlist, currentListSize, currentBit); + stop_meas(path_metric); + + start_meas(sorting); + + // for (int i=0;ipathMetric); + // } + if (currentListSize <= listSize/2) { + // until listsize is full we need to copy bit and LLR arrays to new entries + // below we only copy the ones we need to keep for sure + + for (int i = 0; i < currentListSize; i++) { + for (int k = 0; k < (polarParams->n+1); k++) { + + memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0], + (void*)&sorted_dlist[i]->bit[k][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0], + (void*)&sorted_dlist[i]->llr[k][0], + sizeof(int16_t)*polarParams->N); + } + } + } + + for (int i = 0; i < currentListSize; i++) { + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+currentListSize]->bit[0][currentBit]=1; + } + bitUpdated[currentBit][0]=1; + updateCrcChecksum2_int8(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); + + currentListSize*=2; + + //Keep only the best "listSize" number of entries. + if (currentListSize > listSize) { + int listIndex2[listSize]; + + for (int i = 0; i < currentListSize; i++) { + listIndex[i]=i; + pathMetric[i] = sorted_dlist[i]->pathMetric; + } + nr_sort_asc_int16_1D_array_ind(pathMetric, listIndex, currentListSize); + for (int i=0;in+1); k++) { + + memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], + (void*)&sorted_dlist[i]->bit[k][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], + (void*)&sorted_dlist[i]->llr[k][0], + sizeof(int16_t)*polarParams->N); + } + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + } + else if (listIndex2[i+listSize]n+1); k++) { + memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], + (void*)&sorted_dlist[i]->bit[k][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], + (void*)&sorted_dlist[i]->llr[k][0], + sizeof(int16_t)*polarParams->N); + } + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + + /* + decoder_list_t *tmp = sorted_dlist[i+listSize]; + sorted_dlist[i+listSize] = sorted_dlist[i]; + sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0], + (void*)&tmp->crcChecksum[0], + 24*sizeof(uint8_t));*/ + + } + } + + currentListSize = listSize; + + for (int i = 0; i < 2*listSize; i++) { + temp_dlist[i] = sorted_dlist[i]; + } + for (int i = 0; i < 2*listSize; i++) { + // printf("i %d => %d\n",i,listIndex[i]); + sorted_dlist[i] = temp_dlist[listIndex[i]]; + } + } + stop_meas(sorting); + + nonFrozenBit++; + } + + } + + + + for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { + // printf("list index %d :",i); + // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); + // printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric); + int crcState = 1; + for (int j=0;jcrcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0; + if (crcState == 1) { + for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j]; + + start_meas(bit_extraction); + //Extract the information bits (û to ĉ) + nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); + stop_meas(bit_extraction); + //Deinterleaving (ĉ to b) + start_meas(deinterleaving); + nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); + stop_meas(deinterleaving); + //Remove the CRC (â) + for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; + + break; + } + } + + // free(d_tilde); + /* + for (int i=0;i<2*listSize;i++) { + // printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit); + nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); + nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); + free(dlist[i].crcChecksum); + }*/ + nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); + nr_free_uint8_t_2D_array(tempECGM, polarParams->K); + stop_meas(decoding); + return(0); } 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 2596962d97..6cc67965fb 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -33,7 +33,7 @@ inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, #ifdef SHOWCOMP - printf("computeLLR (%d,%d,%d,%d)\n",row,col,offset,i); + printf("computeLLR (%d,%d,%d)\n",row,col,offset); #endif a = llr[col + 1][row]; b = llr[col+1][row + offset]; @@ -45,6 +45,37 @@ inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, } else { //eq. (8a) llr[col][row] = log((exp(a + b) + 1) / (exp(a) + exp(b))); } + // printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]); +} + +inline void computeLLR_int8(int16_t llr[1+nmax][Nmax], uint16_t row, uint16_t col, + uint16_t offset) __attribute__((always_inline)); +inline void computeLLR_int8(int16_t llr[1+nmax][Nmax], uint16_t row, uint16_t col, + uint16_t offset) { + + int16_t a; + int16_t b; + int16_t absA,absB; + int16_t maska,maskb; + int16_t minabs; + +#ifdef SHOWCOMP + printf("computeLLR_int8 (%d,%d,%d)\n",row,col,offset); +#endif + a = llr[col + 1][row]; + b = llr[col+1][row + offset]; + // printf("LLR: a %d, b %d\n",a,b); + maska = a>>15; + maskb = b>>15; + absA = (a+maska)^maska; + absB = (b+maskb)^maskb; + // printf("LLR: absA %d, absB %d\n",absA,absB); + minabs = absAllr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row]; + // printf("updating dlist[%d]->llr[%d][%d] => %f (%f,%f) offset %d\n",i,col,row,32*dlist[i]->llr[col][row], + // (pow((-1),dlist[i]->bit[col][row-offset])*32*dlist[i]->llr[col+1][row-offset]),32*dlist[i]->llr[col+1][row],offset); } } else { if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation); if (llrU[row+offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen, approximation); for (int i=0;illr, row, col, offset, approximation); - + } + + llrU[row][col]=1; +} + +void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU, + uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen) { + uint16_t offset = (xlen/(1<<(ylen-col-1))); + if (( (row) % (2*offset) ) >= offset ) { + if (bitU[row-offset][col]==0) updateBit_int8(dlist, bitU, listSize, (row-offset), col, xlen, ylen); + if (llrU[row-offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen); + if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen); + for (uint8_t i=0; ibit[col][row-offset]==0) + dlist[i]->llr[col][row] = dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row]; + else + dlist[i]->llr[col][row] = -dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row]; + // printf("updating dlist[%d]->llr[%d][%d] => %d (%d,%d) offset %d\n",i,col,row,dlist[i]->llr[col][row], + // (dlist[i]->bit[col][row-offset]==0 ? 1 : -1)*dlist[i]->llr[col+1][row-offset],dlist[i]->llr[col+1][row], offset); + } + } else { + if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen); + if (llrU[row+offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen); + for (int i=0;illr, row, col, offset); } llrU[row][col]=1; @@ -90,6 +148,34 @@ void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_ if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen); if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen); dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2); + // printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]); +#ifdef SHOWCOMP + printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", + row,col,i,row,col-1,i,row+offset,col-1,i); +#endif + } + } + + bitU[row][col]=1; +} + +void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, + uint16_t col, uint16_t xlen, uint8_t ylen) { + uint16_t offset = ( xlen/(pow(2,(ylen-col))) ); + + for (uint8_t i=0; i= offset ) { + if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen); + dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]; +#ifdef SHOWCOMP + printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n", + row,col,i,row,col-1,i); +#endif + } else { + if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen); + if (bitU[row+offset][col-1]==0) updateBit_int8(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen); + dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset]; + // printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]); #ifdef SHOWCOMP printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", row,col,i,row,col-1,i,row+offset,col-1,i); @@ -111,44 +197,42 @@ void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, if (approximation) { //eq. (12) for (uint8_t i=0; illr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]); + // printf("updatepathmetric : llr %f pathMetric %f (bitValue %d)\n",32*dlist[i]->llr[0][row],32*dlist[i]->pathMetric,bitValue); } } else { //eq. (11b) - int8_t multiplier = (2*bitValue) - 1; - for (uint8_t i=0; ipathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ; + int8_t multiplier = (2*bitValue) - 1; + for (uint8_t i=0; ipathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ; + // printf("updatepathmetric : llr %f pathMetric %f\n",32*dlist[i]->llr[0][row],32*dlist[i]->pathMetric); + } } } -/* -void updatePathMetric2(double *pathMetric, double ***llr, uint8_t listSize, uint16_t row, uint8_t appr) { - double *tempPM = malloc(sizeof(double) * listSize); - for (int i=0; i < listSize; i++) tempPM[i]=pathMetric[i]; +void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row) { - uint8_t bitValue = 0; - if (appr) { //eq. (12) - for (uint8_t i = 0; i < listSize; i++) { - if ((2 * bitValue) != (1 - copysign(1.0, llr[row][0][i]))) pathMetric[i] += fabs(llr[row][0][i]); - } - } else { //eq. (11b) - int8_t multiplier = (2 * bitValue) - 1; - for (uint8_t i = 0; i < listSize; i++) pathMetric[i] += log(1 + exp(multiplier * llr[row][0][i])); - } +#ifdef SHOWCOMP + printf("updating path_metric from Frozen bit (%d,%d) \n", + row,0); +#endif + int16_t mask; + for (uint8_t i=0; illr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]); + // equiv: if ((llr>0 && bitValue==1) || (llr<0 && bitValue==0) ... + // equiv: (llr>>7 + bitValue) != 0, in opposite case (llr>8 + bitValue) = -1 or 1 + - bitValue = 1; - if (appr) { //eq. (12) - for (uint8_t i = listSize; i < 2*listSize; i++) { - if ((2 * bitValue) != (1 - copysign(1.0, llr[row][0][(i-listSize)]))) pathMetric[i] = tempPM[(i-listSize)] + fabs(llr[row][0][(i-listSize)]); - } - } else { //eq. (11b) - int8_t multiplier = (2 * bitValue) - 1; - for (uint8_t i = listSize; i < 2*listSize; i++) pathMetric[i] = tempPM[(i-listSize)] + log(1 + exp(multiplier * llr[row][0][(i-listSize)])); - } - - free(tempPM); + mask = dlist[i]->llr[0][row]>>15; + + if (mask != 0) { + int16_t absllr = (dlist[i]->llr[0][row]+mask)^mask; + dlist[i]->pathMetric += absllr; + } + // printf("updatepathmetric : llr %d, pathMetric %d (bitValue %d)\n",dlist[i]->llr[0][row],dlist[i]->pathMetric); + } } -*/ void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr) { @@ -174,10 +258,29 @@ void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, u dlist[i]->pathMetric += log(1 + exp(-dlist[i]->llr[0][row])); // bitValue=1 dlist2[i]->pathMetric += log(1 + exp(dlist[i]->llr[0][row])); + } } } +void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row) { + + int i; + + for (i=0;ipathMetric = dlist[i]->pathMetric; + decoder_list_int8_t **dlist2 = &dlist[listSize]; + +#ifdef SHOWCOMP + printf("updating path_metric from information bit (%d,%d) \n", + row,0); +#endif + for (i = 0; i < listSize; i++) { + // bitValue=0 + if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row]; + // bitValue=1 + else dlist2[i]->pathMetric += dlist[i]->llr[0][row]; + } +} void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen, @@ -197,3 +300,21 @@ void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, } } } + +void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len) { + for (uint8_t i = 0; i < listSize; i++) { + for (uint8_t j = 0; j < len; j++) { + dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + } + } +} + +void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len) { + for (uint8_t i = 0; i < listSize; i++) { + for (uint8_t j = 0; j < len; j++) { + dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + } + } +} diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index c35856a0ce..43142864cb 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -104,6 +104,9 @@ void nr_polar_rate_matching_pattern(uint16_t *rmp, uint16_t *J, const uint8_t *P void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E); +void nr_polar_rate_matching_int8(int16_t *input, int16_t *output, uint16_t *rmp, + uint16_t K, uint16_t N, uint16_t E); + void nr_polar_interleaving_pattern(uint16_t K, uint8_t I_IL, uint16_t *PI_k_); void nr_polar_info_bit_pattern(uint8_t *ibp, int16_t *Q_I_N, int16_t *Q_F_N, @@ -138,31 +141,57 @@ typedef struct decoder_list_s { uint8_t bit[1+nmax][Nmax]; double llr[1+nmax][Nmax]; uint8_t crcChecksum[24]; - uint8_t crcState; double pathMetric; } decoder_list_t; +typedef struct decoder_list_int8_s { + + uint8_t bit[1+nmax][Nmax]; + int16_t llr[1+nmax][Nmax]; + uint8_t crcChecksum[24]; + int32_t pathMetric; + +} decoder_list_int8_t; + void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation); +void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU, + uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen); + void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen); +void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, + uint16_t col, uint16_t xlen, uint8_t ylen); + void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, - uint16_t row, uint8_t approximation); + uint16_t row, uint8_t approximation); + +void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row); void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr); +void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row); + void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen, uint8_t listSize, uint32_t i2, uint8_t len); +void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len); + void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, uint8_t listSize, uint32_t i2, uint8_t len); +void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, + uint8_t listSize, uint32_t i2, uint8_t len); + void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len); +void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len); + uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits); uint8_t **crc11_generator_matrix(uint16_t payloadSizeBits); uint8_t **crc6_generator_matrix(uint16_t payloadSizeBits); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c index 87da27a59f..23ec51a400 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_matrix_and_array.c @@ -168,3 +168,28 @@ void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len) { break; } } + +void nr_sort_asc_int16_1D_array_ind(int32_t *matrix, int *ind, int len) { + int swaps; + int16_t temp; + int tempInd; + + for (int i = 0; i < len; i++) { + swaps = 0; + for (int j = 0; j < (len - i) - 1; j++) { + if (matrix[j] > matrix[j + 1]) { + temp = matrix[j]; + matrix[j] = matrix[j + 1]; + matrix[j + 1] = temp; + + tempInd = ind[j]; + ind[j] = ind[j + 1]; + ind[j + 1] = tempInd; + + swaps++; + } + } + if (swaps == 0) + break; + } +} diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c index 90f16183c8..d237603059 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_rate_match.c @@ -79,3 +79,24 @@ void nr_polar_rate_matching(double *input, double *output, uint16_t *rmp, uint16 } } + +void nr_polar_rate_matching_int8(int16_t *input, int16_t *output, uint16_t *rmp, uint16_t K, uint16_t N, uint16_t E){ + + if (E>=N) { //repetition + for (int i=0; i<=N-1; i++) output[i]=0; + for (int i=0; i<=E-1; i++){ + output[rmp[i]]+=input[i]; + } + } else { + if ( (K/(double)E) <= (7.0/16) ) { //puncturing + for (int i=0; i<=N-1; i++) output[i]=0; + } else { //shortening + for (int i=0; i<=N-1; i++) output[i]=INFINITY; + } + + for (int i=0; i<=E-1; i++){ + output[rmp[i]]=input[i]; + } + } + +} From 59c4ddef2454b801859349248ec2dfa00eaa0ed4 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 1 Oct 2018 02:30:29 +0200 Subject: [PATCH 11/19] completed most of code generation tool for polar decoder integrated into "polartest" --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 203 ++++++++++-------- .../nrPolar_tools/nr_polar_decoding_tools.c | 159 +++++++------- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 4 +- 3 files changed, 188 insertions(+), 178 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index e1b248b27e..24d3a8d404 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -30,7 +30,6 @@ #include "PHY/TOOLS/time_meas.h" - int8_t polar_decoder( double *input, uint8_t *output, @@ -294,6 +293,92 @@ int8_t polar_decoder( } +#define decoder_int8_A(sorted_dlist,currentListSize,polarParams) {for (int i = 0; i < currentListSize; i++) { \ + for (int k = 0; k < (polarParams->n+1); k++) { \ + memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],\ + (void*)&sorted_dlist[i]->bit[k][0],\ + sizeof(uint8_t)*polarParams->N);\ + memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],\ + (void*)&sorted_dlist[i]->llr[k][0],\ + sizeof(int16_t)*polarParams->N);}}} + +#define decoder_int8_B(sorted_dlist,currentListSize) {for (int i = 0; i < currentListSize; i++) {sorted_dlist[i]->bit[0][currentBit]=0;sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;}} + +void inline decoder_int8_C(decoder_list_int8_t *sorted_dlist[], + t_nrPolar_params *polarParams, + int currentBit, + int currentListSize, + int listSize) { + + int32_t pathMetric[2*listSize]; + decoder_list_int8_t *temp_dlist[2*listSize]; + + int listIndex[2*listSize]; + int listIndex2[2*listSize]; + + for (int i = 0; i < currentListSize; i++) { + listIndex[i]=i; + pathMetric[i] = sorted_dlist[i]->pathMetric; + } + nr_sort_asc_int16_1D_array_ind(pathMetric, listIndex, currentListSize); + for (int i=0;in+1); k++) { + + memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], + (void*)&sorted_dlist[i]->bit[k][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], + (void*)&sorted_dlist[i]->llr[k][0], + sizeof(int16_t)*polarParams->N); + } + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + } + else if (listIndex2[i+listSize]n+1); k++) { + memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], + (void*)&sorted_dlist[i]->bit[k][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], + (void*)&sorted_dlist[i]->llr[k][0], + sizeof(int16_t)*polarParams->N); + } + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + + /* + decoder_list_t *tmp = sorted_dlist[i+listSize]; + sorted_dlist[i+listSize] = sorted_dlist[i]; + sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0], + (void*)&tmp->crcChecksum[0], + 24*sizeof(uint8_t));*/ + + } + } + + + + for (int i = 0; i < 2*listSize; i++) { + temp_dlist[i] = sorted_dlist[i]; + } + for (int i = 0; i < 2*listSize; i++) { + // printf("i %d => %d\n",i,listIndex[i]); + sorted_dlist[i] = temp_dlist[listIndex[i]]; + } +} + int8_t polar_decoder_int8(int16_t *input, uint8_t *output, t_nrPolar_params *polarParams, @@ -380,12 +465,9 @@ int8_t polar_decoder_int8(int16_t *input, uint8_t currentListSize=1; decoder_list_int8_t *sorted_dlist[2*listSize]; - decoder_list_int8_t *temp_dlist[2*listSize]; - int listIndex[2*listSize]; - int32_t pathMetric[2*listSize]; - + for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; - + for (uint16_t currentBit=0; currentBitN; currentBit++){ // printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", // currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); @@ -402,110 +484,45 @@ int8_t polar_decoder_int8(int16_t *input, stop_meas(path_metric); start_meas(sorting); - - // for (int i=0;ipathMetric); - // } + if (currentListSize <= listSize/2) { // until listsize is full we need to copy bit and LLR arrays to new entries // below we only copy the ones we need to keep for sure + decoder_int8_A(sorted_dlist,currentListSize,polarParams); +#ifdef SHOWCOMP + printf("decoder_int8_A(sorted_dlist,%d,polarParams);\n",currentListSize); +#endif + } + decoder_int8_B(sorted_dlist,currentListSize); +#ifdef SHOWCOMP + printf("decoder_int8_B(sorted_dlist,%d);\n",currentListSize); +#endif - for (int i = 0; i < currentListSize; i++) { - for (int k = 0; k < (polarParams->n+1); k++) { - - memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0], - (void*)&sorted_dlist[i]->bit[k][0], - sizeof(uint8_t)*polarParams->N); - memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0], - (void*)&sorted_dlist[i]->llr[k][0], - sizeof(int16_t)*polarParams->N); - } - } - } - - for (int i = 0; i < currentListSize; i++) { - sorted_dlist[i]->bit[0][currentBit]=0; - sorted_dlist[i+currentListSize]->bit[0][currentBit]=1; - } bitUpdated[currentBit][0]=1; + updateCrcChecksum2_int8(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); currentListSize*=2; //Keep only the best "listSize" number of entries. if (currentListSize > listSize) { - int listIndex2[listSize]; - - for (int i = 0; i < currentListSize; i++) { - listIndex[i]=i; - pathMetric[i] = sorted_dlist[i]->pathMetric; - } - nr_sort_asc_int16_1D_array_ind(pathMetric, listIndex, currentListSize); - for (int i=0;in+1); k++) { - - memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], - (void*)&sorted_dlist[i]->bit[k][0], - sizeof(uint8_t)*polarParams->N); - memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], - (void*)&sorted_dlist[i]->llr[k][0], - sizeof(int16_t)*polarParams->N); - } - sorted_dlist[i]->bit[0][currentBit]=0; - sorted_dlist[i+listSize]->bit[0][currentBit]=1; - } - else if (listIndex2[i+listSize]n+1); k++) { - memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], - (void*)&sorted_dlist[i]->bit[k][0], - sizeof(uint8_t)*polarParams->N); - memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], - (void*)&sorted_dlist[i]->llr[k][0], - sizeof(int16_t)*polarParams->N); - } - sorted_dlist[i+listSize]->bit[0][currentBit]=1; - - /* - decoder_list_t *tmp = sorted_dlist[i+listSize]; - sorted_dlist[i+listSize] = sorted_dlist[i]; - sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric; - sorted_dlist[i+listSize]->bit[0][currentBit]=1; - memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0], - (void*)&tmp->crcChecksum[0], - 24*sizeof(uint8_t));*/ - - } - } - + + decoder_int8_C(sorted_dlist, + polarParams, + currentBit, + currentListSize, + listSize); currentListSize = listSize; - - for (int i = 0; i < 2*listSize; i++) { - temp_dlist[i] = sorted_dlist[i]; - } - for (int i = 0; i < 2*listSize; i++) { - // printf("i %d => %d\n",i,listIndex[i]); - sorted_dlist[i] = temp_dlist[listIndex[i]]; - } } + stop_meas(sorting); - + nonFrozenBit++; + } + } - - } - + for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { // printf("list index %d :",i); 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 6cc67965fb..206dfb955f 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -32,9 +32,6 @@ inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, double absA,absB; -#ifdef SHOWCOMP - printf("computeLLR (%d,%d,%d)\n",row,col,offset); -#endif a = llr[col + 1][row]; b = llr[col+1][row + offset]; @@ -60,7 +57,7 @@ inline void computeLLR_int8(int16_t llr[1+nmax][Nmax], uint16_t row, uint16_t co int16_t minabs; #ifdef SHOWCOMP - printf("computeLLR_int8 (%d,%d,%d)\n",row,col,offset); + printf("computeLLR_int8(llr,%d,%d,%d);\n",row,col,offset); #endif a = llr[col + 1][row]; b = llr[col+1][row + offset]; @@ -87,13 +84,7 @@ void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU, if (llrU[row-offset][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen, approximation); if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation); for (uint8_t i=0; illr[col][row] = (pow((-1),dlist[i]->bit[col][row-offset])*dlist[i]->llr[col+1][row-offset]) + dlist[i]->llr[col+1][row]; - // printf("updating dlist[%d]->llr[%d][%d] => %f (%f,%f) offset %d\n",i,col,row,32*dlist[i]->llr[col][row], - // (pow((-1),dlist[i]->bit[col][row-offset])*32*dlist[i]->llr[col+1][row-offset]),32*dlist[i]->llr[col+1][row],offset); } } else { if (llrU[row][col+1]==0) updateLLR(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen, approximation); @@ -104,6 +95,9 @@ void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU, llrU[row][col]=1; } +#define updateLLR_int8_A(dlist,i,col,row,offset) if (dlist[(i)]->bit[(col)][(row)-(offset)]==0) dlist[(i)]->llr[(col)][(row)] = dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; else dlist[(i)]->llr[(col)][(row)] = -dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; + + void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen) { uint16_t offset = (xlen/(1<<(ylen-col-1))); @@ -111,18 +105,19 @@ void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU, if (bitU[row-offset][col]==0) updateBit_int8(dlist, bitU, listSize, (row-offset), col, xlen, ylen); if (llrU[row-offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen); if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen); + + for (uint8_t i=0; ibit[col][row-offset]==0) dlist[i]->llr[col][row] = dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row]; else - dlist[i]->llr[col][row] = -dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row]; - // printf("updating dlist[%d]->llr[%d][%d] => %d (%d,%d) offset %d\n",i,col,row,dlist[i]->llr[col][row], - // (dlist[i]->bit[col][row-offset]==0 ? 1 : -1)*dlist[i]->llr[col+1][row-offset],dlist[i]->llr[col+1][row], offset); - } + dlist[i]->llr[col][row] = -dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row];*/ + } } else { if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen); if (llrU[row+offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen); @@ -140,25 +135,19 @@ void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_ if (( (row) % (2*offset) ) >= offset ) { if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen); dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]; -#ifdef SHOWCOMP - printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n", - row,col,i,row,col-1,i); -#endif } else { if (bitU[row][col-1]==0) updateBit(dlist, bitU, listSize, row, (col-1), xlen, ylen); if (bitU[row+offset][col-1]==0) updateBit(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen); dlist[i]->bit[col][row] = ( (dlist[i]->bit[col-1][row]+dlist[i]->bit[col-1][row+offset]) % 2); - // printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]); -#ifdef SHOWCOMP - printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", - row,col,i,row,col-1,i,row+offset,col-1,i); -#endif } } bitU[row][col]=1; } +#define updateBit_int8_A(dlist,i,col,row) dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)] +#define updateBit_int8_B(dlist,i,col,row,offset) dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]^dlist[(i)]->bit[(col)-1][(row)+(offset)] + void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen) { uint16_t offset = ( xlen/(pow(2,(ylen-col))) ); @@ -166,71 +155,66 @@ void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSiz for (uint8_t i=0; i= offset ) { if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen); - dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]; + // dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]; #ifdef SHOWCOMP - printf("updating bit (%d,%d,%d) from (%d,%d,%d)\n", - row,col,i,row,col-1,i); + printf("updateBit_int8_A(dlist,%d,%d,%d);\n",i,col,row); #endif + updateBit_int8_A(dlist,i,col,row); + } else { if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen); if (bitU[row+offset][col-1]==0) updateBit_int8(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen); - dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset]; + // dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset]; // printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]); #ifdef SHOWCOMP - printf("updating bit (%d,%d,%d) from (%d,%d,%d)+(%d,%d,%d)\n", - row,col,i,row,col-1,i,row+offset,col-1,i); + printf("updateBit_int8_B(dlist,%d,%d,%d,%d);\n",i,col,row,offset); #endif + updateBit_int8_B(dlist,i,col,row,offset); } } bitU[row][col]=1; } - + void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, - uint16_t row, uint8_t approximation) { - -#ifdef SHOWCOMP - printf("updating path_metric from Frozen bit (%d,%d) \n", - row,0); -#endif - - if (approximation) { //eq. (12) - for (uint8_t i=0; illr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]); - // printf("updatepathmetric : llr %f pathMetric %f (bitValue %d)\n",32*dlist[i]->llr[0][row],32*dlist[i]->pathMetric,bitValue); - } - } else { //eq. (11b) - int8_t multiplier = (2*bitValue) - 1; - for (uint8_t i=0; illr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]); + } + } else { //eq. (11b) + int8_t multiplier = (2*bitValue) - 1; + for (uint8_t i=0; ipathMetric += log ( 1 + exp(multiplier*dlist[i]->llr[0][row]) ) ; - // printf("updatepathmetric : llr %f pathMetric %f\n",32*dlist[i]->llr[0][row],32*dlist[i]->pathMetric); } - } - + } + } - + +#define updatePathMetric0_int8_A(dlist,i,row,mask,absllr) { mask=dlist[i]->llr[0][row]>>15;if(mask!=0){absllr=(dlist[i]->llr[0][row]+mask)^mask;dlist[i]->pathMetric+=absllr;}} void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row) { -#ifdef SHOWCOMP - printf("updating path_metric from Frozen bit (%d,%d) \n", - row,0); -#endif - int16_t mask; + int16_t mask,absllr; for (uint8_t i=0; illr[0][row]) )) dlist[i]->pathMetric += fabs(dlist[i]->llr[0][row]); - // equiv: if ((llr>0 && bitValue==1) || (llr<0 && bitValue==0) ... - // equiv: (llr>>7 + bitValue) != 0, in opposite case (llr>8 + bitValue) = -1 or 1 - + updatePathMetric0_int8_A(dlist,i,row,mask,absllr); +#ifdef SHOWCOMP + printf("updatePathMetric0_int8_A(dlist,i,%d,%d);\n",listSize,row); +#endif + + + /* mask = dlist[i]->llr[0][row]>>15; if (mask != 0) { int16_t absllr = (dlist[i]->llr[0][row]+mask)^mask; dlist[i]->pathMetric += absllr; - } - // printf("updatepathmetric : llr %d, pathMetric %d (bitValue %d)\n",dlist[i]->llr[0][row],dlist[i]->pathMetric); - } + }*/ + + + } } @@ -241,10 +225,6 @@ void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, u for (i=0;ipathMetric = dlist[i]->pathMetric; decoder_list_t **dlist2 = &dlist[listSize]; -#ifdef SHOWCOMP - printf("updating path_metric from information bit (%d,%d) \n", - row,0); -#endif if (appr) { //eq. (12) for (i = 0; i < listSize; i++) { // bitValue=0 @@ -263,22 +243,23 @@ void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, u } } +#define updatePathMetric2_int8_A(dlist,i,listSize,row) {dlist[i+listSize]->pathMetric = dlist[i]->pathMetric;if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric-=dlist[i]->llr[0][row];else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];} + + void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row) { int i; - for (i=0;ipathMetric = dlist[i]->pathMetric; - decoder_list_int8_t **dlist2 = &dlist[listSize]; -#ifdef SHOWCOMP - printf("updating path_metric from information bit (%d,%d) \n", - row,0); -#endif for (i = 0; i < listSize; i++) { - // bitValue=0 - if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row]; - // bitValue=1 - else dlist2[i]->pathMetric += dlist[i]->llr[0][row]; +#ifdef SHOWCOMP + printf("updatePathMetric2_int8_A(dlist,%d,%d,%d);\n", + i,listSize,row); +#endif + updatePathMetric2_int8_A(dlist,i,listSize,row); + // dlist[i+listSize]->pathMetric = dlist[i]->pathMetric; + //if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row]; + //else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row]; } } @@ -301,20 +282,32 @@ void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, } } +#define updateCrcChecksum_int8_A(dlist,i,crcGen,i2,len) {for (uint8_t j = 0; j < len; j++) dlist[i]->crcChecksum[j] = (dlist[i]->crcChecksum[j]^crcGen[i2][j]);} + void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, uint8_t listSize, uint32_t i2, uint8_t len) { for (uint8_t i = 0; i < listSize; i++) { - for (uint8_t j = 0; j < len; j++) { - dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); - } +#ifdef SHOWCOMP + printf("updateCrcChecksum_int8_A(dlist,%d,crcGen,%d,%d);\n",i,i2,len); +#endif + updateCrcChecksum_int8_A(dlist,i,crcGen,i2,len); + // for (uint8_t j = 0; j < len; j++) { + // dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + // } } } +#define updateCrcChecksum2_int8_A(dlist,i,listSize,crcGen,i2,len) {for (uint8_t j = 0; j < len; j++) dlist[i+listSize]->crcChecksum[j]=dlist[i]->crcChecksum[j]^crcGen[i2][j];} + void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, uint8_t listSize, uint32_t i2, uint8_t len) { for (uint8_t i = 0; i < listSize; i++) { - for (uint8_t j = 0; j < len; j++) { - dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); - } +#ifdef SHOWCOMP + printf("updateCrcChecksum2_int8_A(dlist,%d,%d,crcGen,%d,%d);\n",i,listSize,i2,len); +#endif + updateCrcChecksum2_int8_A(dlist,i,listSize,crcGen,i2,len); + // for (uint8_t j = 0; j < len; j++) { + // dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + // } } } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 43142864cb..c9339e308d 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -147,8 +147,8 @@ typedef struct decoder_list_s { typedef struct decoder_list_int8_s { - uint8_t bit[1+nmax][Nmax]; - int16_t llr[1+nmax][Nmax]; + uint8_t bit[1+nmax][Nmax] __attribute__((aligned(32))); + int16_t llr[1+nmax][Nmax]__attribute__((aligned(32))); uint8_t crcChecksum[24]; int32_t pathMetric; From 7aad1584e6e518a6858d28985deab33e2bbfa827 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 3 Oct 2018 09:31:16 +0200 Subject: [PATCH 12/19] removed logging --- .../CODING/nrPolar_tools/nr_polar_decoder.c | 12 +++---- .../nrPolar_tools/nr_polar_decoding_tools.c | 33 ++++++++++--------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 24d3a8d404..11d4eb522f 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -29,6 +29,7 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "PHY/TOOLS/time_meas.h" +#define SHOWCOMP 1 int8_t polar_decoder( double *input, @@ -125,8 +126,8 @@ int8_t polar_decoder( for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; for (uint16_t currentBit=0; currentBitN; currentBit++){ - printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", - currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); + // printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", + // currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); start_meas(update_LLR); updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); @@ -154,9 +155,6 @@ int8_t polar_decoder( start_meas(sorting); - for (int i=0;ipathMetric); - } if (currentListSize <= listSize/2) { // until listsize is full we need to copy bit and LLR arrays to new entries // below we only copy the ones we need to keep for sure @@ -195,7 +193,6 @@ int8_t polar_decoder( // copy the llr/bit arrays that are needed for (int i = 0; i < listSize; i++) { - printf("listIndex[%d] %d\n",i,listIndex[i]); if ((listIndex2[i+listSize]llr; #ifdef SHOWCOMP - printf("computeLLR_int8(llr,%d,%d,%d);\n",row,col,offset); + printf("computeLLR_int8(sorted_dlist,%d,%d,%d);\n",i,row,col,offset); #endif - a = llr[col + 1][row]; - b = llr[col+1][row + offset]; + a = dlist[i]->llr[col + 1][row]; + b = dlist[i]->llr[col+1][row + offset]; // printf("LLR: a %d, b %d\n",a,b); maska = a>>15; maskb = b>>15; @@ -69,9 +70,9 @@ inline void computeLLR_int8(int16_t llr[1+nmax][Nmax], uint16_t row, uint16_t co // printf("LLR: absA %d, absB %d\n",absA,absB); minabs = absAllr[col][row] = minabs; else - llr[col][row] = -minabs; + dlist[i]->llr[col][row] = -minabs; // printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]); } @@ -109,7 +110,7 @@ void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU, for (uint8_t i=0; illr, row, col, offset); + for (int i=0;ibit[col][row] = dlist[i]->bit[col-1][row]; #ifdef SHOWCOMP - printf("updateBit_int8_A(dlist,%d,%d,%d);\n",i,col,row); + printf("updateBit_int8_A(sorted_dlist,%d,%d,%d);\n",i,col,row); #endif updateBit_int8_A(dlist,i,col,row); @@ -167,7 +168,7 @@ void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSiz // dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset]; // printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]); #ifdef SHOWCOMP - printf("updateBit_int8_B(dlist,%d,%d,%d,%d);\n",i,col,row,offset); + printf("updateBit_int8_B(sorted_dlist,%d,%d,%d,%d);\n",i,col,row,offset); #endif updateBit_int8_B(dlist,i,col,row,offset); } @@ -201,7 +202,7 @@ void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16 updatePathMetric0_int8_A(dlist,i,row,mask,absllr); #ifdef SHOWCOMP - printf("updatePathMetric0_int8_A(dlist,i,%d,%d);\n",listSize,row); + printf("updatePathMetric0_int8_A(sorted_dlist,i,%d,%d);\n",listSize,row); #endif @@ -253,7 +254,7 @@ void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint1 for (i = 0; i < listSize; i++) { #ifdef SHOWCOMP - printf("updatePathMetric2_int8_A(dlist,%d,%d,%d);\n", + printf("updatePathMetric2_int8_A(sorted_dlist,%d,%d,%d);\n", i,listSize,row); #endif updatePathMetric2_int8_A(dlist,i,listSize,row); @@ -288,7 +289,7 @@ void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, uint8_t listSize, uint32_t i2, uint8_t len) { for (uint8_t i = 0; i < listSize; i++) { #ifdef SHOWCOMP - printf("updateCrcChecksum_int8_A(dlist,%d,crcGen,%d,%d);\n",i,i2,len); + printf("updateCrcChecksum_int8_A(sorted_dlist,%d,crcGen,%d,%d);\n",i,i2,len); #endif updateCrcChecksum_int8_A(dlist,i,crcGen,i2,len); // for (uint8_t j = 0; j < len; j++) { @@ -303,7 +304,7 @@ void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, uint8_t listSize, uint32_t i2, uint8_t len) { for (uint8_t i = 0; i < listSize; i++) { #ifdef SHOWCOMP - printf("updateCrcChecksum2_int8_A(dlist,%d,%d,crcGen,%d,%d);\n",i,listSize,i2,len); + printf("updateCrcChecksum2_int8_A(sorted_dlist,%d,%d,crcGen,%d,%d);\n",i,listSize,i2,len); #endif updateCrcChecksum2_int8_A(dlist,i,listSize,crcGen,i2,len); // for (uint8_t j = 0; j < len; j++) { From 061fb00feafea070d56e3b23776194973c6e4a79 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 9 Oct 2018 08:46:43 +0200 Subject: [PATCH 13/19] added new polar decoder implementation --- cmake_targets/CMakeLists.txt | 1 + openair1/PHY/CODING/TESTBENCH/polartest.c | 37 +- openair1/PHY/CODING/nrPolar_init.c | 39 ++ .../CODING/nrPolar_tools/nr_polar_decoder.c | 394 ++++++++--------- .../nrPolar_tools/nr_polar_decoding_tools.c | 416 +++++++++++++----- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 324 +++++++++++--- 6 files changed, 817 insertions(+), 394 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 5d5fc808d4..d1659c7067 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1123,6 +1123,7 @@ set(PHY_POLARSRC ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_bit_insertion.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_channel_interleaver_pattern.c # ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_crc.c +# ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/decoder_K56_N512_E864.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_info_bit_pattern.c ${OPENAIR1_DIR}/PHY/CODING/nrPolar_tools/nr_polar_interleaving_pattern.c diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index 9a10b42edb..e23c69215a 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -43,8 +43,9 @@ int main(int argc, char *argv[]) { double timeEncoderCumulative = 0, timeDecoderCumulative = 0; uint8_t decoderListSize = 8, pathMetricAppr = 0; //0 --> eq. (8a) and (11b), 1 --> eq. (9) and (12) + int generate_optim_code=0; - while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h:q")) != -1) + while ((arguments = getopt (argc, argv, "s:d:f:m:i:l:a:h:qg")) != -1) switch (arguments) { case 's': @@ -80,6 +81,13 @@ int main(int argc, char *argv[]) { decoder_int8=1; break; + case 'g': + generate_optim_code=1; + iterations=1; + SNRstart=-6.0; + SNRstop =-6.0; + decoder_int8=1; + break; case 'h': printf("./polartest -s SNRstart -d SNRinc -f SNRstop -m [0=DCI|1=PBCH|2=UCI] -i iterations -l decoderListSize -a pathMetricAppr\n"); exit(-1); @@ -141,12 +149,18 @@ int main(int argc, char *argv[]) { t_nrPolar_params nrPolar_params; nr_polar_init(&nrPolar_params, polarMessageType); + nr_polar_llrtableinit(); + + if (generate_optim_code==1) nrPolar_params.decoder_kernel = NULL; // We assume no a priori knowledge available about the payload. double aPrioriArray[nrPolar_params.payloadBits]; for (int i=0; i<=nrPolar_params.payloadBits; i++) aPrioriArray[i] = NAN; + printf("SNRstart %f, SNRstop %f,, SNRinc %f\n",SNRstart,SNRstop,SNRinc); + for (SNR = SNRstart; SNR <= SNRstop; SNR += SNRinc) { + printf("SNR %f\n",SNR); SNR_lin = pow(10, SNR/10); for (itr = 1; itr <= iterations; itr++) { @@ -165,20 +179,29 @@ int main(int argc, char *argv[]) { modulatedInput[i]=(-1)/sqrt(2); channelOutput[i] = modulatedInput[i] + (gaussdouble(0.0,1.0) * (1/sqrt(2*SNR_lin))); + if (decoder_int8==1) { - if (channelOutput[i] > 1024) channelOutput_int8[i] = 32768; - else if (channelOutput[i] < -1023) channelOutput_int8[i] = -32767; - else channelOutput_int8[i] = (int16_t) (32*channelOutput[i]); + if (channelOutput[i] > 15) channelOutput_int8[i] = 127; + else if (channelOutput[i] < -16) channelOutput_int8[i] = -128; + else channelOutput_int8[i] = (int16_t) (8*channelOutput[i]); } } start_meas(&timeDecoder); - if (decoder_int8==0) decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params, decoderListSize, aPrioriArray, pathMetricAppr,&polar_decoder_init,&polar_rate_matching,&decoding,&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR); + if (decoder_int8==0) + decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params, + decoderListSize, aPrioriArray, pathMetricAppr, + &polar_decoder_init,&polar_rate_matching,&decoding, + &bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR); else - decoderState = polar_decoder_int8(channelOutput_int8, estimatedOutput, &nrPolar_params, decoderListSize, &polar_decoder_init,&polar_rate_matching,&decoding,&bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR); + decoderState = polar_decoder_int8_new(channelOutput_int8, estimatedOutput, &nrPolar_params, + decoderListSize, &polar_decoder_init,&polar_rate_matching, + &decoding,&bit_extraction,&deinterleaving, + &sorting,&path_metric,&update_LLR, + generate_optim_code); stop_meas(&timeDecoder); - + //calculate errors if (decoderState==-1) { blockErrorState=-1; diff --git a/openair1/PHY/CODING/nrPolar_init.c b/openair1/PHY/CODING/nrPolar_init.c index 65422ee073..5928e0684f 100644 --- a/openair1/PHY/CODING/nrPolar_init.c +++ b/openair1/PHY/CODING/nrPolar_init.c @@ -62,6 +62,11 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24... polarParams->nr_polar_u = malloc(sizeof(uint8_t) * polarParams->N); //Decoder: nr_polar_uHat polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_cHat polarParams->nr_polar_b = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_bHat + + polarParams->decoder_kernel = NULL;//polar_decoder_K56_N512_E864; + + + } else if (messageType == 2) { //UCI polarParams->payloadBits = NR_POLAR_PUCCH_PAYLOAD_BITS; //A depends on what they carry... polarParams->encoderLength = NR_POLAR_PUCCH_E ; //E depends on other standards 6.3.1.4 @@ -131,6 +136,7 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24... polarParams->nr_polar_u = malloc(sizeof(uint8_t) * polarParams->N); //Decoder: nr_polar_uHat polarParams->nr_polar_cPrime = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_cHat polarParams->nr_polar_b = malloc(sizeof(uint8_t) * polarParams->K); //Decoder: nr_polar_bHat + } polarParams->crcCorrectionBits = NR_POLAR_CRC_ERROR_CORRECTION_BITS; @@ -161,5 +167,38 @@ uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24... nr_polar_channel_interleaver_pattern(polarParams->channel_interleaver_pattern, polarParams->i_bil, polarParams->encoderLength); + polarParams->extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 + uint8_t tempECGM[polarParams->K][polarParams->crcParityBits]; + for (int i = 0; i < polarParams->K; i++){ + polarParams->extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); + } + + for (int i=0; ipayloadBits; i++) { + for (int j=0; jcrcParityBits; j++) { + tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; + } + } + for (int i=polarParams->payloadBits; iK; i++) { + for (int j=0; jcrcParityBits; j++) { + if( (i-polarParams->payloadBits) == j ){ + tempECGM[i][j]=1; + } else { + tempECGM[i][j]=0; + } + } + } + + for (int i=0; iK; i++) { + for (int j=0; jcrcParityBits; j++) { + polarParams->extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; + } + } + + + build_decoder_tree(polarParams); + printf("decoder tree nodes %d\n",polarParams->tree.num_nodes); + + + free(J); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 11d4eb522f..67fe489424 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -29,7 +29,6 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "PHY/TOOLS/time_meas.h" -#define SHOWCOMP 1 int8_t polar_decoder( double *input, @@ -50,31 +49,6 @@ int8_t polar_decoder( start_meas(init); - - uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True - uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True - decoder_list_t dlist[2*listSize]; - - for ( int i=0;i<2*listSize;i++) { - // dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); - // dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N); - //dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits); - for (int j=0; j< polarParams->n+1; j++) { - memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N); - memset((void*)&dlist[i].llr[j][0],0,sizeof(double)*polarParams->N); - } - for (int j=0;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; - dlist[i].pathMetric = 0; - } - - for (int i=0; iN; i++) { - memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); - memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); - llrUpdated[i][polarParams->n]=1; - bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); - } - - uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2 for (int i = 0; i < polarParams->K; i++){ @@ -102,6 +76,31 @@ int8_t polar_decoder( extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; } } + uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + + decoder_list_t dlist[2*listSize]; + + for ( int i=0;i<2*listSize;i++) { + // dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); + // dlist[i].llr = nr_alloc_double_2D_array((polarParams->n+1), polarParams->N); + //dlist[i].crcChecksum = malloc(sizeof(uint8_t)*polarParams->crcParityBits); + for (int j=0; j< polarParams->n+1; j++) { + memset((void*)&dlist[i].bit[j][0],0,sizeof(uint8_t)*polarParams->N); + memset((void*)&dlist[i].llr[j][0],0,sizeof(double)*polarParams->N); + } + for (int j=0;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; + dlist[i].pathMetric = 0; + } + + + for (int i=0; iN; i++) { + memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); + memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); + llrUpdated[i][polarParams->n]=1; + bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); + } + stop_meas(init); start_meas(polar_rate_matching); @@ -155,6 +154,7 @@ int8_t polar_decoder( start_meas(sorting); + if (currentListSize <= listSize/2) { // until listsize is full we need to copy bit and LLR arrays to new entries // below we only copy the ones we need to keep for sure @@ -290,92 +290,8 @@ int8_t polar_decoder( } -#define decoder_int8_A(sorted_dlist,currentListSize,polarParams) {for (int i = 0; i < currentListSize; i++) { \ - for (int k = 0; k < (polarParams->n+1); k++) { \ - memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],\ - (void*)&sorted_dlist[i]->bit[k][0],\ - sizeof(uint8_t)*polarParams->N);\ - memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],\ - (void*)&sorted_dlist[i]->llr[k][0],\ - sizeof(int16_t)*polarParams->N);}}} -#define decoder_int8_B(sorted_dlist,currentListSize) {for (int i = 0; i < currentListSize; i++) {sorted_dlist[i]->bit[0][currentBit]=0;sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;}} - -void inline decoder_int8_C(decoder_list_int8_t *sorted_dlist[], - t_nrPolar_params *polarParams, - int currentBit, - int currentListSize, - int listSize) { - - int32_t pathMetric[2*listSize]; - decoder_list_int8_t *temp_dlist[2*listSize]; - - int listIndex[2*listSize]; - int listIndex2[2*listSize]; - for (int i = 0; i < currentListSize; i++) { - listIndex[i]=i; - pathMetric[i] = sorted_dlist[i]->pathMetric; - } - nr_sort_asc_int16_1D_array_ind(pathMetric, listIndex, currentListSize); - for (int i=0;in+1); k++) { - - memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], - (void*)&sorted_dlist[i]->bit[k][0], - sizeof(uint8_t)*polarParams->N); - memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], - (void*)&sorted_dlist[i]->llr[k][0], - sizeof(int16_t)*polarParams->N); - } - sorted_dlist[i]->bit[0][currentBit]=0; - sorted_dlist[i+listSize]->bit[0][currentBit]=1; - } - else if (listIndex2[i+listSize]n+1); k++) { - memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], - (void*)&sorted_dlist[i]->bit[k][0], - sizeof(uint8_t)*polarParams->N); - memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], - (void*)&sorted_dlist[i]->llr[k][0], - sizeof(int16_t)*polarParams->N); - } - sorted_dlist[i+listSize]->bit[0][currentBit]=1; - - /* - decoder_list_t *tmp = sorted_dlist[i+listSize]; - sorted_dlist[i+listSize] = sorted_dlist[i]; - sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric; - sorted_dlist[i+listSize]->bit[0][currentBit]=1; - memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0], - (void*)&tmp->crcChecksum[0], - 24*sizeof(uint8_t));*/ - - } - } - - - - for (int i = 0; i < 2*listSize; i++) { - temp_dlist[i] = sorted_dlist[i]; - } - for (int i = 0; i < 2*listSize; i++) { - // printf("i %d => %d\n",i,listIndex[i]); - sorted_dlist[i] = temp_dlist[listIndex[i]]; - } -} - int8_t polar_decoder_int8(int16_t *input, uint8_t *output, t_nrPolar_params *polarParams, @@ -387,16 +303,22 @@ int8_t polar_decoder_int8(int16_t *input, time_stats_t *deinterleaving, time_stats_t *sorting, time_stats_t *path_metric, - time_stats_t *update_LLR) + time_stats_t *update_LLR, + int generate_optim_code) { - start_meas(init); - - - uint8_t **bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True - uint8_t **llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + + uint8_t **bitUpdated; + uint8_t **llrUpdated; + + if (generate_optim_code == 1 || polarParams->decoder_kernel==NULL) { + bitUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + llrUpdated = nr_alloc_uint8_t_2D_array(polarParams->N, (polarParams->n+1)); //0=False, 1=True + } decoder_list_int8_t dlist[2*listSize]; + + start_meas(init); for ( int i=0;i<2*listSize;i++) { // dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); @@ -409,48 +331,28 @@ int8_t polar_decoder_int8(int16_t *input, for (int j=0;jcrcParityBits;j++) dlist[i].crcChecksum[j] = 0; dlist[i].pathMetric = 0; } - - for (int i=0; iN; i++) { - memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); - memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); - llrUpdated[i][polarParams->n]=1; - bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); - } - - - uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 - uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2 - for (int i = 0; i < polarParams->K; i++){ - extended_crc_generator_matrix[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); - tempECGM[i] = malloc(polarParams->crcParityBits * sizeof(uint8_t)); - } - - for (int i=0; ipayloadBits; i++) { - for (int j=0; jcrcParityBits; j++) { - tempECGM[i][j]=polarParams->crc_generator_matrix[i][j]; - } - } - for (int i=polarParams->payloadBits; iK; i++) { - for (int j=0; jcrcParityBits; j++) { - if( (i-polarParams->payloadBits) == j ){ - tempECGM[i][j]=1; - } else { - tempECGM[i][j]=0; - } - } - } - - for (int i=0; iK; i++) { - for (int j=0; jcrcParityBits; j++) { - extended_crc_generator_matrix[i][j]=tempECGM[polarParams->interleaving_pattern[i]][j]; - } - } - + stop_meas(init); + + if (generate_optim_code == 1 || polarParams->decoder_kernel==NULL) { + for (int i=0; iN; i++) { + memset((void *)&llrUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); + memset((void *)&bitUpdated[i][0],0,sizeof(uint8_t)*polarParams->n); + llrUpdated[i][polarParams->n]=1; + bitUpdated[i][0]=((polarParams->information_bit_pattern[i]+1) % 2); + } + } + + + start_meas(polar_rate_matching); int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + for (int i=0;iN;i++) { + if (d_tilde[i]<-128) d_tilde[i]=-128; + else if (d_tilde[i]>127) d_tilde[i]=128; + } memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N); stop_meas(polar_rate_matching); @@ -464,70 +366,81 @@ int8_t polar_decoder_int8(int16_t *input, decoder_list_int8_t *sorted_dlist[2*listSize]; for (uint8_t i = 0; i < 2*listSize; i++) sorted_dlist[i] = &dlist[i]; + char fname[100]; + FILE *fd; + if (generate_optim_code==1) { + sprintf(fname,"decoder_K%d_N%d_E%d.c",polarParams->K,polarParams->N,polarParams->encoderLength); + if ((fd=fopen(fname,"w"))==NULL) {printf("Cannot open %s\n",fname); exit(-1);} + fprintf(fd,"#include \"nr_polar_defs.h\"\n"); + fprintf(fd,"void polar_decoder_K%d_N%d_E%d(t_nrPolar_params *polarParams,decoder_list_int8_t **sorted_dlist) {\n", + polarParams->K,polarParams->N,polarParams->encoderLength); + fprintf(fd,"int16_t mask,absllr;\n"); + } - for (uint16_t currentBit=0; currentBitN; currentBit++){ - // printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", - // currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); - - start_meas(update_LLR); - updateLLR_int8(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1)); - stop_meas(update_LLR); - - if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. - updatePathMetric0_int8(sorted_dlist,currentListSize, currentBit); //approximation=0 --> 11b, approximation=1 --> 12 - } else { //Information or CRC bit. - start_meas(path_metric); - updatePathMetric2_int8(sorted_dlist, currentListSize, currentBit); - stop_meas(path_metric); + if (polarParams->decoder_kernel) polarParams->decoder_kernel(polarParams,sorted_dlist); + else { + for (uint16_t currentBit=0; currentBitN; currentBit++){ + printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", + currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); - start_meas(sorting); + start_meas(update_LLR); + updateLLR_int8(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1),generate_optim_code,fd); + stop_meas(update_LLR); - if (currentListSize <= listSize/2) { - // until listsize is full we need to copy bit and LLR arrays to new entries - // below we only copy the ones we need to keep for sure - decoder_int8_A(sorted_dlist,currentListSize,polarParams); -#ifdef SHOWCOMP - printf("decoder_int8_A(sorted_dlist,%d,polarParams);\n",currentListSize); -#endif - } - decoder_int8_B(sorted_dlist,currentListSize); -#ifdef SHOWCOMP - printf("decoder_int8_B(sorted_dlist,%d);\n",currentListSize); -#endif + if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. + updatePathMetric0_int8(sorted_dlist,currentListSize, currentBit,generate_optim_code,fd); //approximation=0 --> 11b, approximation=1 --> 12 + } else { //Information or CRC bit. + start_meas(path_metric); + updatePathMetric2_int8(sorted_dlist, currentListSize, currentBit,generate_optim_code,fd); + stop_meas(path_metric); - bitUpdated[currentBit][0]=1; - - updateCrcChecksum2_int8(sorted_dlist,extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); - - currentListSize*=2; - - //Keep only the best "listSize" number of entries. - if (currentListSize > listSize) { - - decoder_int8_C(sorted_dlist, - polarParams, - currentBit, - currentListSize, - listSize); -#ifdef SHOWCOMP - printf("decoder_int8_C(sorted_dlist,polarParams,%d,%d,%d);\n",currentBit,currentListSize,listSize); -#endif - currentListSize = listSize; + start_meas(sorting); + + if (currentListSize <= listSize/2) { + // until listsize is full we need to copy bit and LLR arrays to new entries + // below we only copy the ones we need to keep for sure + decoder_int8_A(sorted_dlist,currentListSize,polarParams); + if (generate_optim_code == 1) fprintf(fd,"decoder_int8_A(sorted_dlist,%d,polarParams);\n",currentListSize); + } + decoder_int8_B(sorted_dlist,currentBit,currentListSize); + if (generate_optim_code == 1) fprintf(fd,"decoder_int8_B(sorted_dlist,%d,%d);\n",currentBit,currentListSize); + + + bitUpdated[currentBit][0]=1; + + updateCrcChecksum2_int8(sorted_dlist,polarParams->extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits,generate_optim_code,fd); + + currentListSize*=2; + + //Keep only the best "listSize" number of entries. + if (currentListSize > listSize) { + + decoder_int8_C(sorted_dlist, + polarParams, + currentBit, + currentListSize, + listSize); + + if (generate_optim_code == 1) fprintf(fd,"decoder_int8_C(sorted_dlist,polarParams,%d,%d,%d);\n",currentBit,currentListSize,listSize); + + currentListSize = listSize; + } + + stop_meas(sorting); + + nonFrozenBit++; } - - stop_meas(sorting); - nonFrozenBit++; - } - } - - + + } + + if (generate_optim_code==1) fprintf(fd,"}\n"); for (uint8_t i = 0; i < fmin(listSize, (pow(2,polarParams->crcCorrectionBits)) ); i++) { - // printf("list index %d :",i); - // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); - // printf(" => %d (%f)\n",sorted_dlist[i]->crcState,sorted_dlist[i]->pathMetric); + // printf("list index %d / %d :",i,listSize); + // for (int j=0;jcrcParityBits;j++) printf("%d",sorted_dlist[i]->crcChecksum[j]); + // printf(" => (%d)\n",sorted_dlist[i]->pathMetric); int crcState = 1; for (int j=0;jcrcParityBits;j++) if (sorted_dlist[i]->crcChecksum[j]!=0) crcState=0; if (crcState == 1) { @@ -556,8 +469,69 @@ int8_t polar_decoder_int8(int16_t *input, nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); free(dlist[i].crcChecksum); }*/ - nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); - nr_free_uint8_t_2D_array(tempECGM, polarParams->K); + stop_meas(decoding); + return(0); +} + + +int8_t polar_decoder_int8_new(int16_t *input, + uint8_t *output, + t_nrPolar_params *polarParams, + uint8_t listSize, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR, + int generate_optim_code) +{ + + + start_meas(init); + stop_meas(init); + + start_meas(polar_rate_matching); + + int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); + nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); + for (int i=0;iN;i++) { + if (d_tilde[i]<-128) d_tilde[i]=-128; + else if (d_tilde[i]>127) d_tilde[i]=128; + } + memcpy((void*)&polarParams->tree.root->alpha[0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N); + stop_meas(polar_rate_matching); + + /* + * SCL polar decoder. + */ + start_meas(decoding); + + generic_polar_decoder(polarParams,polarParams->tree.root); + + start_meas(bit_extraction); + //Extract the information bits (û to ĉ) + nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); + stop_meas(bit_extraction); + //Deinterleaving (ĉ to b) + start_meas(deinterleaving); + nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); + stop_meas(deinterleaving); + //Remove the CRC (â) + for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; + + + + // free(d_tilde); + /* + for (int i=0;i<2*listSize;i++) { + // printf("correct: Freeing dlist[%d].bit %p\n",i,dlist[i].bit); + nr_free_uint8_t_2D_array(dlist[i].bit, (polarParams->n+1)); + nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); + free(dlist[i].crcChecksum); + }*/ stop_meas(decoding); return(0); } 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 723131584e..e215be2e2b 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -19,8 +19,9 @@ * contact@openairinterface.org */ +#include "PHY/impl_defs_top.h" #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" -#define SHOWCOMP 1 +#include "PHY/sse_intrin.h" inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, uint16_t offset, uint8_t approximation) __attribute__((always_inline)); @@ -45,40 +46,28 @@ inline void computeLLR(double llr[1+nmax][Nmax], uint16_t row, uint16_t col, // printf("LLR (a %f, b %f): llr[%d][%d] %f\n",32*a,32*b,col,row,32*llr[col][row]); } -inline void computeLLR_int8(decoder_list_int8_t **dlist,int i, uint16_t row, uint16_t col, - uint16_t offset) __attribute__((always_inline)); -inline void computeLLR_int8(decoder_list_int8_t **dlist,int i, uint16_t row, uint16_t col, - uint16_t offset) { +int16_t llrtab[256][256]; - int16_t a; - int16_t b; - int16_t absA,absB; - int16_t maska,maskb; - int16_t minabs; - // int16_t **llr=dlist[i]->llr; +void nr_polar_llrtableinit() { + int16_t absA,absB; + int16_t maska,maskb; + int16_t minabs; -#ifdef SHOWCOMP - printf("computeLLR_int8(sorted_dlist,%d,%d,%d);\n",i,row,col,offset); -#endif - a = dlist[i]->llr[col + 1][row]; - b = dlist[i]->llr[col+1][row + offset]; - // printf("LLR: a %d, b %d\n",a,b); - maska = a>>15; - maskb = b>>15; - absA = (a+maska)^maska; - absB = (b+maskb)^maskb; - // printf("LLR: absA %d, absB %d\n",absA,absB); - minabs = absAllr[col][row] = minabs; - else - dlist[i]->llr[col][row] = -minabs; - // printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]); + for (int a=-128;a<128;a++) { + for (int b=-128;b<128;b++) { + absA=abs(a); + absB=abs(b); + minabs = absA=0 && b>=0)) llrtab[a+128][b+128] = minabs; + else llrtab[a+128][b+128] = -minabs; + } + } } void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation) { + uint16_t offset = (xlen/(1<<(ylen-col-1))); if (( (row) % (2*offset) ) >= offset ) { if (bitU[row-offset][col]==0) updateBit(dlist, bitU, listSize, (row-offset), col, xlen, ylen); @@ -96,33 +85,25 @@ void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU, llrU[row][col]=1; } -#define updateLLR_int8_A(dlist,i,col,row,offset) if (dlist[(i)]->bit[(col)][(row)-(offset)]==0) dlist[(i)]->llr[(col)][(row)] = dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; else dlist[(i)]->llr[(col)][(row)] = -dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; - - void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU, - uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen) { + uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, + int generate_optim_code,FILE *fd) { uint16_t offset = (xlen/(1<<(ylen-col-1))); if (( (row) % (2*offset) ) >= offset ) { - if (bitU[row-offset][col]==0) updateBit_int8(dlist, bitU, listSize, (row-offset), col, xlen, ylen); - if (llrU[row-offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen); - if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen); + if (bitU[row-offset][col]==0) updateBit_int8(dlist, bitU, listSize, (row-offset), col, xlen, ylen,generate_optim_code,fd); + if (llrU[row-offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row-offset), (col+1), xlen, ylen,generate_optim_code,fd); + if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen,generate_optim_code,fd); - for (uint8_t i=0; ibit[col][row-offset]==0) - dlist[i]->llr[col][row] = dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row]; - else - dlist[i]->llr[col][row] = -dlist[i]->llr[col+1][row-offset] + dlist[i]->llr[col+1][row];*/ - } + if (generate_optim_code==1) fprintf(fd,"updateLLR_int8_A(sorted_dlist,%d,%d,%d,%d);\n",listSize,col,row,offset); + + updateLLR_int8_A(dlist,listSize,col,row,offset); + } else { - if (llrU[row][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, row, (col+1), xlen, ylen); - if (llrU[row+offset][col+1]==0) updateLLR_int8(dlist, llrU, bitU, listSize, (row+offset), (col+1), xlen, ylen); - for (int i=0;ibit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)] -#define updateBit_int8_B(dlist,i,col,row,offset) dlist[(i)]->bit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]^dlist[(i)]->bit[(col)-1][(row)+(offset)] -void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, - uint16_t col, uint16_t xlen, uint8_t ylen) { + +void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, + uint8_t listSize, uint16_t row, + uint16_t col, uint16_t xlen, uint8_t ylen, + int generate_optim_code,FILE *fd) { + uint16_t offset = ( xlen/(pow(2,(ylen-col))) ); - for (uint8_t i=0; i= offset ) { - if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen); - // dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]; -#ifdef SHOWCOMP - printf("updateBit_int8_A(sorted_dlist,%d,%d,%d);\n",i,col,row); -#endif - updateBit_int8_A(dlist,i,col,row); + if (( (row) % (2*offset) ) >= offset ) { - } else { - if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen); - if (bitU[row+offset][col-1]==0) updateBit_int8(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen); + if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen,generate_optim_code,fd); + // dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]; + + if (generate_optim_code==1) fprintf(fd,"updateBit_int8_A(sorted_dlist,%d,%d,%d);\n",listSize,col,row); + + updateBit_int8_A(dlist,listSize,col,row); + + } else { + if (bitU[row][col-1]==0) updateBit_int8(dlist, bitU, listSize, row, (col-1), xlen, ylen,generate_optim_code,fd); + if (bitU[row+offset][col-1]==0) updateBit_int8(dlist, bitU, listSize, (row+offset), (col-1), xlen, ylen,generate_optim_code,fd); // dlist[i]->bit[col][row] = dlist[i]->bit[col-1][row]^dlist[i]->bit[col-1][row+offset]; // printf("updating dlist[%d]->bit[%d][%d] => %d\n",i,col,row,dlist[i]->bit[col][row]); -#ifdef SHOWCOMP - printf("updateBit_int8_B(sorted_dlist,%d,%d,%d,%d);\n",i,col,row,offset); -#endif - updateBit_int8_B(dlist,i,col,row,offset); - } + + if (generate_optim_code==1) fprintf(fd,"updateBit_int8_B(sorted_dlist,%d,%d,%d,%d);\n",listSize,col,row,offset); + + updateBit_int8_B(dlist,listSize,col,row,offset); } + bitU[row][col]=1; } @@ -193,17 +176,15 @@ void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, } -#define updatePathMetric0_int8_A(dlist,i,row,mask,absllr) { mask=dlist[i]->llr[0][row]>>15;if(mask!=0){absllr=(dlist[i]->llr[0][row]+mask)^mask;dlist[i]->pathMetric+=absllr;}} -void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row) { + +void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd) { int16_t mask,absllr; - for (uint8_t i=0; ipathMetric = dlist[i]->pathMetric;if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric-=dlist[i]->llr[0][row];else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];} -void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row) { + +void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd) { int i; - for (i = 0; i < listSize; i++) { -#ifdef SHOWCOMP - printf("updatePathMetric2_int8_A(sorted_dlist,%d,%d,%d);\n", - i,listSize,row); -#endif - updatePathMetric2_int8_A(dlist,i,listSize,row); - // dlist[i+listSize]->pathMetric = dlist[i]->pathMetric; - //if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row]; - //else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row]; - } + + if (generate_optim_code == 1) fprintf(fd,"updatePathMetric2_int8_A(sorted_dlist,%d,%d);\n", + listSize,row); + + updatePathMetric2_int8_A(dlist,listSize,row); + // dlist[i+listSize]->pathMetric = dlist[i]->pathMetric; + //if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric -= dlist[i]->llr[0][row]; + //else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row]; + } @@ -283,32 +262,253 @@ void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, } } -#define updateCrcChecksum_int8_A(dlist,i,crcGen,i2,len) {for (uint8_t j = 0; j < len; j++) dlist[i]->crcChecksum[j] = (dlist[i]->crcChecksum[j]^crcGen[i2][j]);} + void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len) { - for (uint8_t i = 0; i < listSize; i++) { -#ifdef SHOWCOMP - printf("updateCrcChecksum_int8_A(sorted_dlist,%d,crcGen,%d,%d);\n",i,i2,len); -#endif - updateCrcChecksum_int8_A(dlist,i,crcGen,i2,len); - // for (uint8_t j = 0; j < len; j++) { - // dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); - // } - } + uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd) { + + if (generate_optim_code == 1) fprintf(fd,"updateCrcChecksum_int8_A(sorted_dlist,%d,crcGen,%d,%d);\n",listSize,i2,len); + + updateCrcChecksum_int8_A(dlist,listSize,crcGen,i2,len); + // for (uint8_t j = 0; j < len; j++) { + // dlist[i]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); + // } + } -#define updateCrcChecksum2_int8_A(dlist,i,listSize,crcGen,i2,len) {for (uint8_t j = 0; j < len; j++) dlist[i+listSize]->crcChecksum[j]=dlist[i]->crcChecksum[j]^crcGen[i2][j];} + void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len) { - for (uint8_t i = 0; i < listSize; i++) { -#ifdef SHOWCOMP - printf("updateCrcChecksum2_int8_A(sorted_dlist,%d,%d,crcGen,%d,%d);\n",i,listSize,i2,len); -#endif - updateCrcChecksum2_int8_A(dlist,i,listSize,crcGen,i2,len); - // for (uint8_t j = 0; j < len; j++) { + uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd) { + + if (generate_optim_code == 1) fprintf(fd,"updateCrcChecksum2_int8_A(sorted_dlist,%d,polarParams->extended_crc_generator_matrix,%d,%d);\n",listSize,i2,len); + + updateCrcChecksum2_int8_A(dlist,listSize,crcGen,i2,len); + // for (uint8_t j = 0; j < len; j++) { // dlist[i+listSize]->crcChecksum[j] = ( (dlist[i]->crcChecksum[j] + crcGen[i2][j]) % 2 ); // } + +} + + +decoder_node_t *new_decoder_node(int first_leaf_index,int level) { + + decoder_node_t *node=(decoder_node_t *)malloc(sizeof(decoder_node_t)); + + node->first_leaf_index=first_leaf_index; + node->level=level; + node->Nv = 1<leaf = 0; + node->left=(decoder_node_t *)NULL; + node->right=(decoder_node_t *)NULL; + node->all_frozen=0; + node->alpha = (int16_t*)malloc16(node->Nv*sizeof(int16_t)); + node->beta = (int8_t*)malloc16(node->Nv*sizeof(int16_t)); + memset((void*)node->beta,-1,node->Nv*sizeof(int16_t)); + + + return(node); +} + +decoder_node_t *add_nodes(int level,int first_leaf_index,t_nrPolar_params *pp) { + + int all_frozen_below=1; + int Nv = 1<tree.num_nodes,Nv,level); + pp->tree.num_nodes++; +#endif + if (level==0) { +#ifdef DEBUG_NEW_IMPL + printf("leaf %d (%s)\n",first_leaf_index,pp->information_bit_pattern[first_leaf_index]==1 ? "information or crc" : "frozen"); +#endif + new_node->leaf=1; + new_node->all_frozen = pp->information_bit_pattern[first_leaf_index]==0 ? 1 : 0; + return new_node; // this is a leaf node + } + + for (int i=0;iinformation_bit_pattern[i+first_leaf_index]>0) all_frozen_below=0; + } +if (all_frozen_below==0) new_node->left=add_nodes(level-1,first_leaf_index,pp); + else { +#ifdef DEBUG_NEW_IMPL + printf("aggregating frozen bits %d ... %d at level %d (%s)\n",first_leaf_index,first_leaf_index+Nv-1,level,((first_leaf_index/Nv)&1)==0?"left":"right"); +#endif + new_node->leaf=1; + new_node->all_frozen=1; + } + if (all_frozen_below==0) new_node->right=add_nodes(level-1,first_leaf_index+(Nv/2),pp); + + return(new_node); +} + +void build_decoder_tree(t_nrPolar_params *pp) { + + pp->tree.num_nodes=0; + pp->tree.root = add_nodes(pp->n,0,pp); + +} + +void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { + int16_t *alpha_v=node->alpha; + int16_t *alpha_l=node->left->alpha; + int16_t *betal = node->left->beta; + int16_t a,b,absa,absb,maska,maskb,minabs; + +#ifdef DEBUG_NEW_IMPL + printf("applyFtoleft %d, Nv %d (level %d,node->left (leaf %d, AF %d))\n",node->first_leaf_index,node->Nv,node->level,node->left->leaf,node->left->all_frozen); + + + for (int i=0;iNv;i++) printf("i%d (frozen %d): alpha_v[i] = %d\n",i,1-pp->information_bit_pattern[node->first_leaf_index+i],alpha_v[i]); +#endif + + + + if (node->left->all_frozen == 0) { + +#if defined(__AVX2__) + int avx2mod = (node->Nv/2)&15; + if (avx2mod == 0) { + __m256i a256,b256,absa256,absb256,minabs256; + int avx2len = node->Nv/2/16; + + for (int i=0;iNv/2;i++) { + a=alpha_v[i]; + b=alpha_v[i+(node->Nv/2)]; + maska=a>>15; + maskb=b>>15; + absa=(a+maska)^maska; + absb=(b+maskb)^maskb; + minabs = absaNv == 2) { // apply hard decision on left node + betal[0] = (alpha_l[0]>0) ? -1 : 1; +#ifdef DEBUG_NEW_IMPL + printf("betal[0] %d (%p)\n",betal[0],&betal[0]); +#endif + pp->nr_polar_u[node->first_leaf_index] = (betal[0]+1)>>1; +#ifdef DEBUG_NEW_IMPL + printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index,(betal[0]+1)>>1,alpha_l[0]); +#endif + } } } + +void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { + + int16_t *alpha_v=node->alpha; + int16_t *alpha_r=node->right->alpha; + int16_t *betal = node->left->beta; + int16_t *betar = node->right->beta; + int8_t frozen_mask=-1; + + if (node->Nv == 2) frozen_mask=-pp->information_bit_pattern[node->first_leaf_index+1]; +#ifdef DEBUG_NEW_IMPL + printf("applyGtoright %d, Nv %d (level %d), (leaf %d, AF %d)\n",node->first_leaf_index,node->Nv,node->level,node->right->leaf,node->right->all_frozen); +#endif + + if (node->right->all_frozen == 0) { +#if defined(__AVX2__) + int avx2mod = (node->Nv/2)&15; + if (avx2mod == 0) { + int avx2len = node->Nv/2/16; + + for (int i=0;iNv/2;i++) { + alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]); + } + } + if (node->Nv == 2) { // apply hard decision on right node + betar[0] = (alpha_r[0]>0) ? -1 : 1; + pp->nr_polar_u[node->first_leaf_index+1] = (betar[0]+1)>>1; +#ifdef DEBUG_NEW_IMPL + printf("Setting bit %d to %d (LLR %d frozen_mask %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0],frozen_mask); +#endif + } + } +} + + +void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) { + + int16_t *betav = node->beta; + int16_t *betal = node->left->beta; + int16_t *betar = node->right->beta; +#ifdef DEBUG_NEW_IMPL + printf("Computing beta @ level %d first_leaf_index %d (all_frozen %d)\n",node->level,node->first_leaf_index,node->left->all_frozen); +#endif + if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits + for (int i=0;iNv/2;i++) { + betav[i] = (betal[i] != betar[i]) ? 1 : -1; +#ifdef DEBUG_NEW_IMPL + printf("COMPUTE betav[%d] %d (%p)\n",i, + betav[i], + &betav[i]); +#endif + } + } + else memcpy((void*)&betav[0],betar,(node->Nv/2)*sizeof(int16_t)); + memcpy((void*)&betav[node->Nv/2],betar,(node->Nv/2)*sizeof(int16_t)); + +} + +void generic_polar_decoder(t_nrPolar_params *pp,decoder_node_t *node) { + + + // Apply F to left + applyFtoleft(pp,node); + // if left is not a leaf recurse down to the left + if (node->left->leaf==0) generic_polar_decoder(pp,node->left); + + applyGtoright(pp,node); + if (node->right->leaf==0) generic_polar_decoder(pp,node->right); + + computeBeta(pp,node); + +} diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index c9339e308d..7acd92324f 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -34,58 +34,125 @@ static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31 }; + +#define Nmax 1024 +#define nmax 10 + +typedef struct decoder_list_s { + + uint8_t bit[1+nmax][Nmax]; + double llr[1+nmax][Nmax]; + uint8_t crcChecksum[24]; + double pathMetric; + +} decoder_list_t; + +typedef struct decoder_list_int8_s { + + uint8_t bit[1+nmax][Nmax] __attribute__((aligned(32))); + int16_t llr[1+nmax][Nmax]__attribute__((aligned(32))); + uint8_t crcChecksum[24]; + int32_t pathMetric; + +} decoder_list_int8_t; + + + +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; + int8_t *beta; +} decoder_node_t; + +typedef struct decoder_tree_t_s { + decoder_node_t *root; + int num_nodes; +} decoder_tree_t; + struct nrPolar_params { - uint8_t n_max; - uint8_t i_il; - uint8_t i_seg; - uint8_t n_pc; - uint8_t n_pc_wm; - uint8_t i_bil; - uint16_t payloadBits; - uint16_t encoderLength; - uint8_t crcParityBits; - uint8_t crcCorrectionBits; - uint16_t K; - uint16_t N; - uint8_t n; + uint8_t n_max; + uint8_t i_il; + uint8_t i_seg; + uint8_t n_pc; + uint8_t n_pc_wm; + uint8_t i_bil; + uint16_t payloadBits; + uint16_t encoderLength; + uint8_t crcParityBits; + uint8_t crcCorrectionBits; + uint16_t K; + uint16_t N; + uint8_t n; + + uint16_t *interleaving_pattern; + uint16_t *rate_matching_pattern; + const uint16_t *Q_0_Nminus1; + int16_t *Q_I_N; + int16_t *Q_F_N; + int16_t *Q_PC_N; + uint8_t *information_bit_pattern; + uint16_t *channel_interleaver_pattern; + uint32_t crc_polynomial; + + uint8_t **crc_generator_matrix; //G_P + uint8_t **G_N; + uint32_t* crc256Table; + uint8_t **extended_crc_generator_matrix; - uint16_t *interleaving_pattern; - uint16_t *rate_matching_pattern; - const uint16_t *Q_0_Nminus1; - int16_t *Q_I_N; - int16_t *Q_F_N; - int16_t *Q_PC_N; - uint8_t *information_bit_pattern; - uint16_t *channel_interleaver_pattern; - uint32_t crc_polynomial; - - uint8_t **crc_generator_matrix; //G_P - uint8_t **G_N; - uint32_t* crc256Table; - - //polar_encoder vectors: - uint8_t *nr_polar_crc; - uint8_t *nr_polar_b; - uint8_t *nr_polar_cPrime; - uint8_t *nr_polar_u; - uint8_t *nr_polar_d; + //polar_encoder vectors: + uint8_t *nr_polar_crc; + uint8_t *nr_polar_b; + uint8_t *nr_polar_cPrime; + uint8_t *nr_polar_u; + uint8_t *nr_polar_d; + + void (*decoder_kernel)(struct nrPolar_params *,decoder_list_int8_t **); + decoder_tree_t tree; } __attribute__ ((__packed__)); typedef struct nrPolar_params t_nrPolar_params; + + + + void polar_encoder(uint8_t *input, uint8_t *output, t_nrPolar_params* polarParams); void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N); int8_t polar_decoder(double *input, uint8_t *output, t_nrPolar_params *polarParams, - uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr, - time_stats_t *init, - time_stats_t *polar_rate_matching, - time_stats_t *decoding, - time_stats_t *bit_extraction, - time_stats_t *deinterleaving, - time_stats_t *sorting, - time_stats_t *path_metric, - time_stats_t *update_LLR); + uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR); + +int8_t polar_decoder_int8(int16_t *input, + uint8_t *output, + t_nrPolar_params *polarParams, + uint8_t listSize, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR, + int generate_optim_code); + + + +void nr_polar_llrtableinit(void); void nr_polar_init(t_nrPolar_params* polarParams, int messageType); @@ -133,59 +200,38 @@ void nr_free_uint8_t_3D_array(uint8_t ***input, uint16_t xlen, uint16_t ylen); void nr_free_uint8_t_2D_array(uint8_t **input, uint16_t xlen); void nr_free_double_2D_array(double **input, uint16_t xlen); -#define Nmax 1024 -#define nmax 10 - -typedef struct decoder_list_s { - - uint8_t bit[1+nmax][Nmax]; - double llr[1+nmax][Nmax]; - uint8_t crcChecksum[24]; - double pathMetric; - -} decoder_list_t; - -typedef struct decoder_list_int8_s { - - uint8_t bit[1+nmax][Nmax] __attribute__((aligned(32))); - int16_t llr[1+nmax][Nmax]__attribute__((aligned(32))); - uint8_t crcChecksum[24]; - int32_t pathMetric; - -} decoder_list_int8_t; - void updateLLR(decoder_list_t **dlist,uint8_t **llrU, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen, uint8_t approximation); void updateLLR_int8(decoder_list_int8_t **dlist,uint8_t **llrU, uint8_t **bitU, - uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen); + uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen,int generate_optim_code,FILE *fd); void updateBit(decoder_list_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, uint16_t col, uint16_t xlen, uint8_t ylen); void updateBit_int8(decoder_list_int8_t **dlist, uint8_t **bitU, uint8_t listSize, uint16_t row, - uint16_t col, uint16_t xlen, uint8_t ylen); + uint16_t col, uint16_t xlen, uint8_t ylen,int generate_optim_code,FILE *fd); void updatePathMetric(decoder_list_t **dlist,uint8_t listSize, uint8_t bitValue, uint16_t row, uint8_t approximation); -void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row); +void updatePathMetric0_int8(decoder_list_int8_t **dlist,uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd); void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, uint8_t appr); -void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row); +void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd); void updateCrcChecksum(decoder_list_t **dlist, uint8_t **crcGen, uint8_t listSize, uint32_t i2, uint8_t len); void updateCrcChecksum_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len); + uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd); void updateCrcChecksum2(decoder_list_t **dlist, uint8_t **crcGen, uint8_t listSize, uint32_t i2, uint8_t len); void updateCrcChecksum2_int8(decoder_list_int8_t **dlist, uint8_t **crcGen, - uint8_t listSize, uint32_t i2, uint8_t len); + uint8_t listSize, uint32_t i2, uint8_t len,int generate_optim_code,FILE *fd); void nr_sort_asc_double_1D_array_ind(double *matrix, int *ind, int len); @@ -213,4 +259,144 @@ static inline void nr_polar_deinterleaver(uint8_t *input, uint8_t *output, uint1 for (int i=0; ibit[(col)][(row)-(offset)]==0) dlist[(i)]->llr[(col)][(row)] = dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)]; else dlist[(i)]->llr[(col)][(row)] = -dlist[(i)]->llr[(col)+1][(row)-(offset)] + dlist[(i)]->llr[(col)+1][(row)];if(dlist[(i)]->llr[col][row]>127 || dlist[i]->llr[col][row]<-128) printf("dlist[%d]->llr[%d][%d] = %d> 8bit\n",i,col,row,dlist[i]->llr[col][row]);}} + +#define updateBit_int8_A(dlist,listSize,col,row) {for (int i=0;ibit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)];}} +#define updateBit_int8_B(dlist,listSize,col,row,offset) {for (int i=0;ibit[(col)][(row)] = dlist[(i)]->bit[(col)-1][(row)]^dlist[(i)]->bit[(col)-1][(row)+(offset)];}} + +#define updatePathMetric0_int8_A(dlist,listSize,row,mask,absllr) {for (int i=0;illr[0][row]>>15;if(mask!=0){absllr=(dlist[i]->llr[0][row]+mask)^mask;dlist[i]->pathMetric+=absllr;}}} + +#define updatePathMetric2_int8_A(dlist,listSize,row) {for (int i=0;ipathMetric = dlist[i]->pathMetric;if (dlist[i]->llr[0][row]<0) dlist[i]->pathMetric-=dlist[i]->llr[0][row];else dlist[i+listSize]->pathMetric += dlist[i]->llr[0][row];}}} + +#define updateCrcChecksum_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;icrcChecksum[j] = (dlist[i]->crcChecksum[j]^crcGen[i2][j]);}} + +#define updateCrcChecksum2_int8_A(dlist,listSize,crcGen,i2,len) {for (int i=0;icrcChecksum[j]=dlist[i]->crcChecksum[j]^crcGen[i2][j];}} + +extern int16_t llrtab[256][256]; + +inline void computeLLR_int8(decoder_list_int8_t **dlist,int listSize, uint16_t row, uint16_t col, + uint16_t offset) __attribute__((always_inline)); +inline void computeLLR_int8(decoder_list_int8_t **dlist,int listSize, uint16_t row, uint16_t col, + uint16_t offset) { + + int16_t a; + int16_t b; + + int16_t absA,absB; + int16_t maska,maskb; + int16_t minabs; + // int16_t **llr=dlist[i]->llr; + + + for (int i=0;illr[col + 1][row]; + b = dlist[i]->llr[col+1][row + offset]; + + // printf("LLR: a %d, b %d\n",a,b); + maska = a>>15; + maskb = b>>15; + absA = (a+maska)^maska; + absB = (b+maskb)^maskb; + // printf("LLR: absA %d, absB %d\n",absA,absB); + minabs = absAllr[col][row] = minabs; + else + dlist[i]->llr[col][row] = -minabs; + // printf("LLR (a %d, b %d): llr[%d][%d] %d\n",a,b,col,row,llr[col][row]); + + //dlist[i]->llr[col][row] = llrtab[a+128][b+128]; + // printf("newLLR [%d,%d]: %d\n",col,row,dlist[i]->llr[col][row]); + } +} + +#define decoder_int8_A(sorted_dlist,currentListSize,polarParams) {for (int i = 0; i < currentListSize; i++) { \ + for (int k = 0; k < (polarParams->n+1); k++) { \ + memcpy((void*)&sorted_dlist[i+currentListSize]->bit[k][0],\ + (void*)&sorted_dlist[i]->bit[k][0],\ + sizeof(uint8_t)*polarParams->N);\ + memcpy((void*)&sorted_dlist[i+currentListSize]->llr[k][0],\ + (void*)&sorted_dlist[i]->llr[k][0],\ + sizeof(int16_t)*polarParams->N);}}} + +#define decoder_int8_B(sorted_dlist,currentBit,currentListSize) {for (int i = 0; i < currentListSize; i++) {sorted_dlist[i]->bit[0][currentBit]=0;sorted_dlist[i+currentListSize]->bit[0][currentBit]=1;}} + +void inline decoder_int8_C(decoder_list_int8_t *sorted_dlist[], + t_nrPolar_params *polarParams, + int currentBit, + int currentListSize, + int listSize) { + + int32_t pathMetric[2*listSize]; + decoder_list_int8_t *temp_dlist[2*listSize]; + + int listIndex[2*listSize]; + int listIndex2[2*listSize]; + + for (int i = 0; i < currentListSize; i++) { + listIndex[i]=i; + pathMetric[i] = sorted_dlist[i]->pathMetric; + } + nr_sort_asc_int16_1D_array_ind(pathMetric, listIndex, currentListSize); + for (int i=0;in+1); k++) { + + memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], + (void*)&sorted_dlist[i]->bit[k][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], + (void*)&sorted_dlist[i]->llr[k][0], + sizeof(int16_t)*polarParams->N); + } + sorted_dlist[i]->bit[0][currentBit]=0; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + } + else if (listIndex2[i+listSize]n+1); k++) { + memcpy((void*)&sorted_dlist[i+listSize]->bit[k][0], + (void*)&sorted_dlist[i]->bit[k][0], + sizeof(uint8_t)*polarParams->N); + memcpy((void*)&sorted_dlist[i+listSize]->llr[k][0], + (void*)&sorted_dlist[i]->llr[k][0], + sizeof(int16_t)*polarParams->N); + } + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + + /* + decoder_list_t *tmp = sorted_dlist[i+listSize]; + sorted_dlist[i+listSize] = sorted_dlist[i]; + sorted_dlist[i+listSize]->pathMetric = tmp->pathMetric; + sorted_dlist[i+listSize]->bit[0][currentBit]=1; + memcpy((void*)&sorted_dlist[i+listSize]->crcChecksum[0], + (void*)&tmp->crcChecksum[0], + 24*sizeof(uint8_t));*/ + + } + } + + + + for (int i = 0; i < 2*listSize; i++) { + temp_dlist[i] = sorted_dlist[i]; + } + for (int i = 0; i < 2*listSize; i++) { + // printf("i %d => %d\n",i,listIndex[i]); + sorted_dlist[i] = temp_dlist[listIndex[i]]; + } +} #endif From 22dae457b78b792f246ebe37458eab4c531391d0 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 9 Oct 2018 13:32:43 +0200 Subject: [PATCH 14/19] additional SIMD optimizations --- .../nrPolar_tools/nr_polar_decoding_tools.c | 36 +++++++++++++------ .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 2 +- 2 files changed, 27 insertions(+), 11 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 e215be2e2b..f9105844d1 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -420,7 +420,7 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { #ifdef DEBUG_NEW_IMPL printf("betal[0] %d (%p)\n",betal[0],&betal[0]); #endif - pp->nr_polar_u[node->first_leaf_index] = (betal[0]+1)>>1; + pp->nr_polar_u[node->first_leaf_index] = (1+betal[0])>>1; #ifdef DEBUG_NEW_IMPL printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index,(betal[0]+1)>>1,alpha_l[0]); #endif @@ -466,7 +466,7 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { } if (node->Nv == 2) { // apply hard decision on right node betar[0] = (alpha_r[0]>0) ? -1 : 1; - pp->nr_polar_u[node->first_leaf_index+1] = (betar[0]+1)>>1; + pp->nr_polar_u[node->first_leaf_index+1] = (1+betar[0])>>1; #ifdef DEBUG_NEW_IMPL printf("Setting bit %d to %d (LLR %d frozen_mask %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0],frozen_mask); #endif @@ -474,7 +474,6 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { } } - void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) { int16_t *betav = node->beta; @@ -484,14 +483,31 @@ void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) { printf("Computing beta @ level %d first_leaf_index %d (all_frozen %d)\n",node->level,node->first_leaf_index,node->left->all_frozen); #endif if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits - for (int i=0;iNv/2;i++) { - betav[i] = (betal[i] != betar[i]) ? 1 : -1; -#ifdef DEBUG_NEW_IMPL - printf("COMPUTE betav[%d] %d (%p)\n",i, - betav[i], - &betav[i]); -#endif + /*#if defined(__AVX2__) + int avx2mod = (node->Nv/2)&15; + if (avx2mod == 0) { + int avx2len = node->Nv/2/16; + + for (int i=0;iNv/2;i++) { + betav[i] = (betal[i] != betar[i]) ? 1 : -1; + } + } } else memcpy((void*)&betav[0],betar,(node->Nv/2)*sizeof(int16_t)); memcpy((void*)&betav[node->Nv/2],betar,(node->Nv/2)*sizeof(int16_t)); diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 7acd92324f..34c2e9a50b 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -67,7 +67,7 @@ typedef struct decoder_node_t_s { int first_leaf_index; int all_frozen; int16_t *alpha; - int8_t *beta; + int16_t *beta; } decoder_node_t; typedef struct decoder_tree_t_s { From 9d9aadd420773c7ede511fde0a583b7e0ffe928d Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 9 Oct 2018 15:08:59 +0200 Subject: [PATCH 15/19] more SIMD modifications --- .../nrPolar_tools/nr_polar_decoding_tools.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 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 f9105844d1..f9d8d7fbb3 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -474,6 +474,11 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { } } +int16_t minus1[16] = {-1,-1,-1,-1, + -1,-1,-1,-1, + -1,-1,-1,-1, + -1,-1,-1,-1}; + void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) { int16_t *betav = node->beta; @@ -483,7 +488,7 @@ void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) { printf("Computing beta @ level %d first_leaf_index %d (all_frozen %d)\n",node->level,node->first_leaf_index,node->left->all_frozen); #endif if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits - /*#if defined(__AVX2__) +#if defined(__AVX2__) int avx2mod = (node->Nv/2)&15; if (avx2mod == 0) { int avx2len = node->Nv/2/16; @@ -491,18 +496,24 @@ void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) { for (int i=0;iNv/2;i++) { betav[i] = (betal[i] != betar[i]) ? 1 : -1; From ffc5faf30a0a8d177d276b0fafb08435558fee9e Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 10 Oct 2018 08:33:33 +0200 Subject: [PATCH 16/19] removal of warnings --- openair1/PHY/CODING/nrPolar_init.c | 6 +++--- .../nrPolar_tools/nr_polar_decoding_tools.c | 6 +----- openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h | 15 +++++++++++++++ openair1/PHY/NR_TRANSPORT/nr_pbch.c | 8 ++++---- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/openair1/PHY/CODING/nrPolar_init.c b/openair1/PHY/CODING/nrPolar_init.c index 5928e0684f..f606acbe95 100644 --- a/openair1/PHY/CODING/nrPolar_init.c +++ b/openair1/PHY/CODING/nrPolar_init.c @@ -27,9 +27,9 @@ void nr_polar_init(t_nrPolar_params* polarParams, int messageType) { uint32_t poly6 = 0x84000000; // 1000100000... -> D^6+D^5+1 uint32_t poly11 = 0x63200000; //11000100001000... -> D^11+D^10+D^9+D^5+1 -uint32_t poly16 = 0x81080000; //100000010000100... - > D^16+D^12+D^5+1 -uint32_t poly24a = 0x864cfb00; //100001100100110011111011 -> D^24+D^23+D^18+D^17+D^14+D^11+D^10+D^7+D^6+D^5+D^4+D^3+D+1 -uint32_t poly24b = 0x80006300; //100000000000000001100011 -> D^24+D^23+D^6+D^5+D+1 +//uint32_t poly16 = 0x81080000; //100000010000100... - > D^16+D^12+D^5+1 +//uint32_t poly24a = 0x864cfb00; //100001100100110011111011 -> D^24+D^23+D^18+D^17+D^14+D^11+D^10+D^7+D^6+D^5+D^4+D^3+D+1 +//uint32_t poly24b = 0x80006300; //100000000000000001100011 -> D^24+D^23+D^6+D^5+D+1 uint32_t poly24c = 0xB2B11700; //101100101011000100010111 -> D^24... if (messageType == 0) { //DCI 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 f9d8d7fbb3..d2a3903dd9 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -50,7 +50,6 @@ int16_t llrtab[256][256]; void nr_polar_llrtableinit() { int16_t absA,absB; - int16_t maska,maskb; int16_t minabs; for (int a=-128;a<128;a++) { @@ -229,7 +228,6 @@ void updatePathMetric2(decoder_list_t **dlist, uint8_t listSize, uint16_t row, u void updatePathMetric2_int8(decoder_list_int8_t **dlist, uint8_t listSize, uint16_t row,int generate_optim_code,FILE *fd) { - int i; @@ -303,7 +301,7 @@ decoder_node_t *new_decoder_node(int first_leaf_index,int level) { node->right=(decoder_node_t *)NULL; node->all_frozen=0; node->alpha = (int16_t*)malloc16(node->Nv*sizeof(int16_t)); - node->beta = (int8_t*)malloc16(node->Nv*sizeof(int16_t)); + node->beta = (int16_t*)malloc16(node->Nv*sizeof(int16_t)); memset((void*)node->beta,-1,node->Nv*sizeof(int16_t)); @@ -434,9 +432,7 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { int16_t *alpha_r=node->right->alpha; int16_t *betal = node->left->beta; int16_t *betar = node->right->beta; - int8_t frozen_mask=-1; - if (node->Nv == 2) frozen_mask=-pp->information_bit_pattern[node->first_leaf_index+1]; #ifdef DEBUG_NEW_IMPL printf("applyGtoright %d, Nv %d (level %d), (leaf %d, AF %d)\n",node->first_leaf_index,node->Nv,node->level,node->right->leaf,node->right->all_frozen); #endif diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 34c2e9a50b..4a4055d404 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -125,6 +125,8 @@ void polar_encoder(uint8_t *input, uint8_t *output, t_nrPolar_params* polarParam void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N); +void generic_polar_decoder(t_nrPolar_params *,decoder_node_t *); + int8_t polar_decoder(double *input, uint8_t *output, t_nrPolar_params *polarParams, uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr, time_stats_t *init, @@ -150,6 +152,19 @@ int8_t polar_decoder_int8(int16_t *input, time_stats_t *update_LLR, int generate_optim_code); +int8_t polar_decoder_int8_new(int16_t *input, + uint8_t *output, + t_nrPolar_params *polarParams, + uint8_t listSize, + time_stats_t *init, + time_stats_t *polar_rate_matching, + time_stats_t *decoding, + time_stats_t *bit_extraction, + time_stats_t *deinterleaving, + time_stats_t *sorting, + time_stats_t *path_metric, + time_stats_t *update_LLR, + int generate_optim_code); void nr_polar_llrtableinit(void); diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index 1e761ea0bb..871e32a6b1 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -219,7 +219,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, uint8_t nushift; uint8_t *xbyte = pbch->pbch_a; memset((void*) xbyte, 0, 1); - uint8_t pbch_a_b[32]; + //uint8_t pbch_a_b[32]; LOG_I(PHY, "PBCH generation started\n"); @@ -282,10 +282,10 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch, printf("pbch_a_prime[%d]: 0x%02x\n", i, pbch->pbch_a_prime[i]); #endif -for (int m=0;m<32;m++){ -pbch_a_b[m] = ((pbch->pbch_a_prime[m/8]>>(m&7))&01); +//for (int m=0;m<32;m++){ +//pbch_a_b[m] = ((pbch->pbch_a_prime[m/8]>>(m&7))&01); //printf("pbch_a_b[%d] %d\n", m, pbch_a_b[m] ); -} +//} /// CRC, coding and rate matching polar_encoder (pbch->pbch_a_prime, pbch->pbch_e, &frame_parms->pbch_polar_params); From 6a2dc297c7ba402101f98823c8a7bab15f797741 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Fri, 12 Oct 2018 07:21:05 +0200 Subject: [PATCH 17/19] compilation of nr-uesoftmodem fixed (polar_decoder parameter list) --- openair1/PHY/CODING/TESTBENCH/polartest.c | 18 +--- .../CODING/nrPolar_tools/nr_polar_decoder.c | 93 ++++--------------- .../PHY/CODING/nrPolar_tools/nr_polar_defs.h | 23 +---- 3 files changed, 24 insertions(+), 110 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index e23c69215a..f5390aeb70 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -191,15 +191,9 @@ int main(int argc, char *argv[]) { start_meas(&timeDecoder); if (decoder_int8==0) decoderState = polar_decoder(channelOutput, estimatedOutput, &nrPolar_params, - decoderListSize, aPrioriArray, pathMetricAppr, - &polar_decoder_init,&polar_rate_matching,&decoding, - &bit_extraction,&deinterleaving,&sorting,&path_metric,&update_LLR); + decoderListSize, aPrioriArray, pathMetricAppr); else - decoderState = polar_decoder_int8_new(channelOutput_int8, estimatedOutput, &nrPolar_params, - decoderListSize, &polar_decoder_init,&polar_rate_matching, - &decoding,&bit_extraction,&deinterleaving, - &sorting,&path_metric,&update_LLR, - generate_optim_code); + decoderState = polar_decoder_int8_new(channelOutput_int8, estimatedOutput, &nrPolar_params); stop_meas(&timeDecoder); //calculate errors @@ -237,15 +231,7 @@ int main(int argc, char *argv[]) { decoderListSize, pathMetricAppr, SNR, ((double)blockErrorCumulative/iterations), ((double)bitErrorCumulative / (iterations*testLength)), (timeEncoderCumulative/iterations),timeDecoderCumulative/iterations); - printf("decoding init %9.3fus\n",polar_decoder_init.diff/(cpu_freq_GHz*1000.0*polar_decoder_init.trials)); - printf("decoding polar_rate_matching %9.3fus\n",polar_rate_matching.diff/(cpu_freq_GHz*1000.0*polar_rate_matching.trials)); - printf("decoding decoding %9.3fus\n",decoding.diff/(cpu_freq_GHz*1000.0*decoding.trials)); - printf("decoding bit_extraction %9.3fus\n",bit_extraction.diff/(cpu_freq_GHz*1000.0*bit_extraction.trials)); - printf("decoding deinterleaving %9.3fus\n",deinterleaving.diff/(cpu_freq_GHz*1000.0*deinterleaving.trials)); - printf("decoding path_metric %9.3fus\n",path_metric.diff/(cpu_freq_GHz*1000.0*decoding.trials)); - printf("decoding sorting %9.3fus\n",sorting.diff/(cpu_freq_GHz*1000.0*decoding.trials)); - printf("decoding updateLLR %9.3fus\n",update_LLR.diff/(cpu_freq_GHz*1000.0*decoding.trials)); blockErrorCumulative = 0; bitErrorCumulative = 0; timeEncoderCumulative = 0; timeDecoderCumulative = 0; } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 67fe489424..349d367ce5 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -27,7 +27,6 @@ #include "PHY/CODING/nrPolar_tools/nr_polar_defs.h" #include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h" -#include "PHY/TOOLS/time_meas.h" int8_t polar_decoder( @@ -36,19 +35,7 @@ int8_t polar_decoder( t_nrPolar_params *polarParams, uint8_t listSize, double *aPrioriPayload, - uint8_t pathMetricAppr, - time_stats_t *init, - time_stats_t *polar_rate_matching, - time_stats_t *decoding, - time_stats_t *bit_extraction, - time_stats_t *deinterleaving, - time_stats_t *sorting, - time_stats_t *path_metric, - time_stats_t *update_LLR) -{ - - start_meas(init); - + uint8_t pathMetricAppr) { uint8_t **extended_crc_generator_matrix = malloc(polarParams->K * sizeof(uint8_t *)); //G_P3 uint8_t **tempECGM = malloc(polarParams->K * sizeof(uint8_t *)); //G_P2 for (int i = 0; i < polarParams->K; i++){ @@ -102,18 +89,14 @@ int8_t polar_decoder( } - stop_meas(init); - start_meas(polar_rate_matching); double d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(double)*polarParams->N); - stop_meas(polar_rate_matching); /* * SCL polar decoder. */ - start_meas(decoding); uint32_t nonFrozenBit=0; uint8_t currentListSize=1; @@ -128,9 +111,7 @@ int8_t polar_decoder( // printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", // currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); - start_meas(update_LLR); updateLLR(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1), pathMetricAppr); - stop_meas(update_LLR); if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. updatePathMetric(sorted_dlist,currentListSize, 0, currentBit, pathMetricAppr); //approximation=0 --> 11b, approximation=1 --> 12 @@ -148,11 +129,9 @@ int8_t polar_decoder( updateCrcChecksum(sorted_dlist, extended_crc_generator_matrix, currentListSize, nonFrozenBit, polarParams->crcParityBits); } else { - start_meas(path_metric); + updatePathMetric2(sorted_dlist, currentListSize, currentBit, pathMetricAppr); - stop_meas(path_metric); - - start_meas(sorting); + if (currentListSize <= listSize/2) { @@ -243,7 +222,6 @@ int8_t polar_decoder( sorted_dlist[i] = temp_dlist[listIndex[i]]; } } - stop_meas(sorting); } nonFrozenBit++; @@ -260,14 +238,10 @@ int8_t polar_decoder( if (crcState == 1) { for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j]; - start_meas(bit_extraction); //Extract the information bits (û to ĉ) nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); - stop_meas(bit_extraction); //Deinterleaving (ĉ to b) - start_meas(deinterleaving); nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); - stop_meas(deinterleaving); //Remove the CRC (â) for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; @@ -285,7 +259,7 @@ int8_t polar_decoder( }*/ nr_free_uint8_t_2D_array(extended_crc_generator_matrix, polarParams->K); nr_free_uint8_t_2D_array(tempECGM, polarParams->K); - stop_meas(decoding); + return(0); } @@ -296,15 +270,8 @@ int8_t polar_decoder_int8(int16_t *input, uint8_t *output, t_nrPolar_params *polarParams, uint8_t listSize, - time_stats_t *init, - time_stats_t *polar_rate_matching, - time_stats_t *decoding, - time_stats_t *bit_extraction, - time_stats_t *deinterleaving, - time_stats_t *sorting, - time_stats_t *path_metric, - time_stats_t *update_LLR, int generate_optim_code) + { @@ -318,7 +285,6 @@ int8_t polar_decoder_int8(int16_t *input, decoder_list_int8_t dlist[2*listSize]; - start_meas(init); for ( int i=0;i<2*listSize;i++) { // dlist[i].bit = nr_alloc_uint8_t_2D_array((polarParams->n+1), polarParams->N); @@ -332,7 +298,6 @@ int8_t polar_decoder_int8(int16_t *input, dlist[i].pathMetric = 0; } - stop_meas(init); if (generate_optim_code == 1 || polarParams->decoder_kernel==NULL) { for (int i=0; iN; i++) { @@ -345,7 +310,6 @@ int8_t polar_decoder_int8(int16_t *input, - start_meas(polar_rate_matching); int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); @@ -354,12 +318,11 @@ int8_t polar_decoder_int8(int16_t *input, else if (d_tilde[i]>127) d_tilde[i]=128; } memcpy((void*)&dlist[0].llr[polarParams->n][0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N); - stop_meas(polar_rate_matching); /* * SCL polar decoder. */ - start_meas(decoding); + uint32_t nonFrozenBit=0; uint8_t currentListSize=1; @@ -383,18 +346,16 @@ int8_t polar_decoder_int8(int16_t *input, printf("***************** BIT %d (currentListSize %d, information_bit_pattern %d)\n", currentBit,currentListSize,polarParams->information_bit_pattern[currentBit]); - start_meas(update_LLR); + updateLLR_int8(sorted_dlist, llrUpdated, bitUpdated, currentListSize, currentBit, 0, polarParams->N, (polarParams->n+1),generate_optim_code,fd); - stop_meas(update_LLR); if (polarParams->information_bit_pattern[currentBit]==0) { //Frozen bit. updatePathMetric0_int8(sorted_dlist,currentListSize, currentBit,generate_optim_code,fd); //approximation=0 --> 11b, approximation=1 --> 12 } else { //Information or CRC bit. - start_meas(path_metric); + updatePathMetric2_int8(sorted_dlist, currentListSize, currentBit,generate_optim_code,fd); - stop_meas(path_metric); + - start_meas(sorting); if (currentListSize <= listSize/2) { // until listsize is full we need to copy bit and LLR arrays to new entries @@ -426,7 +387,6 @@ int8_t polar_decoder_int8(int16_t *input, currentListSize = listSize; } - stop_meas(sorting); nonFrozenBit++; } @@ -446,14 +406,11 @@ int8_t polar_decoder_int8(int16_t *input, if (crcState == 1) { for (int j = 0; j < polarParams->N; j++) polarParams->nr_polar_u[j]=sorted_dlist[i]->bit[0][j]; - start_meas(bit_extraction); + //Extract the information bits (û to ĉ) nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); - stop_meas(bit_extraction); //Deinterleaving (ĉ to b) - start_meas(deinterleaving); nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); - stop_meas(deinterleaving); //Remove the CRC (â) for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; @@ -469,31 +426,16 @@ int8_t polar_decoder_int8(int16_t *input, nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); free(dlist[i].crcChecksum); }*/ - stop_meas(decoding); return(0); } int8_t polar_decoder_int8_new(int16_t *input, uint8_t *output, - t_nrPolar_params *polarParams, - uint8_t listSize, - time_stats_t *init, - time_stats_t *polar_rate_matching, - time_stats_t *decoding, - time_stats_t *bit_extraction, - time_stats_t *deinterleaving, - time_stats_t *sorting, - time_stats_t *path_metric, - time_stats_t *update_LLR, - int generate_optim_code) + t_nrPolar_params *polarParams) { - start_meas(init); - stop_meas(init); - - start_meas(polar_rate_matching); int16_t d_tilde[polarParams->N];// = malloc(sizeof(double) * polarParams->N); nr_polar_rate_matching_int8(input, d_tilde, polarParams->rate_matching_pattern, polarParams->K, polarParams->N, polarParams->encoderLength); @@ -502,23 +444,22 @@ int8_t polar_decoder_int8_new(int16_t *input, else if (d_tilde[i]>127) d_tilde[i]=128; } memcpy((void*)&polarParams->tree.root->alpha[0],(void*)&d_tilde[0],sizeof(int16_t)*polarParams->N); - stop_meas(polar_rate_matching); /* * SCL polar decoder. */ - start_meas(decoding); + generic_polar_decoder(polarParams,polarParams->tree.root); - start_meas(bit_extraction); + //Extract the information bits (û to ĉ) nr_polar_info_bit_extraction(polarParams->nr_polar_u, polarParams->nr_polar_cPrime, polarParams->information_bit_pattern, polarParams->N); - stop_meas(bit_extraction); + //Deinterleaving (ĉ to b) - start_meas(deinterleaving); + nr_polar_deinterleaver(polarParams->nr_polar_cPrime, polarParams->nr_polar_b, polarParams->interleaving_pattern, polarParams->K); - stop_meas(deinterleaving); + //Remove the CRC (â) for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_b[j]; @@ -532,6 +473,6 @@ int8_t polar_decoder_int8_new(int16_t *input, nr_free_double_2D_array(dlist[i].llr, (polarParams->n+1)); free(dlist[i].crcChecksum); }*/ - stop_meas(decoding); + return(0); } diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h index 34c2e9a50b..23314593a5 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_defs.h @@ -30,7 +30,6 @@ #include #include -#include "PHY/TOOLS/time_meas.h" static const uint8_t nr_polar_subblock_interleaver_pattern[32] = { 0, 1, 2, 4, 3, 5, 6, 7, 8, 16, 9, 17, 10, 18, 11, 19, 12, 20, 13, 21, 14, 22, 15, 23, 24, 25, 26, 28, 27, 29, 30, 31 }; @@ -126,30 +125,18 @@ void polar_encoder(uint8_t *input, uint8_t *output, t_nrPolar_params* polarParam void nr_polar_kernal_operation(uint8_t *u, uint8_t *d, uint16_t N); int8_t polar_decoder(double *input, uint8_t *output, t_nrPolar_params *polarParams, - uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr, - time_stats_t *init, - time_stats_t *polar_rate_matching, - time_stats_t *decoding, - time_stats_t *bit_extraction, - time_stats_t *deinterleaving, - time_stats_t *sorting, - time_stats_t *path_metric, - time_stats_t *update_LLR); + uint8_t listSize, double *aPrioriPayload, uint8_t pathMetricAppr); int8_t polar_decoder_int8(int16_t *input, uint8_t *output, t_nrPolar_params *polarParams, uint8_t listSize, - time_stats_t *init, - time_stats_t *polar_rate_matching, - time_stats_t *decoding, - time_stats_t *bit_extraction, - time_stats_t *deinterleaving, - time_stats_t *sorting, - time_stats_t *path_metric, - time_stats_t *update_LLR, int generate_optim_code); +int8_t polar_decoder_int8_new(int16_t *input, + uint8_t *output, + t_nrPolar_params *polarParams); + void nr_polar_llrtableinit(void); From 88d5bf42f8aa309010109b48e6d043aaf8885ca8 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sat, 13 Oct 2018 16:05:43 +0200 Subject: [PATCH 18/19] 16-bit llr decoder integrated --- openair1/PHY/CODING/TESTBENCH/polartest.c | 39 ++++++++++++------- .../CODING/nrPolar_tools/nr_polar_decoder.c | 6 +-- .../nrPolar_tools/nr_polar_decoding_tools.c | 16 ++++++-- openair1/PHY/CODING/nr_polar_init.c | 3 ++ 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c index 9f3ddf97a8..f412be1271 100644 --- a/openair1/PHY/CODING/TESTBENCH/polartest.c +++ b/openair1/PHY/CODING/TESTBENCH/polartest.c @@ -151,7 +151,9 @@ int main(int argc, char *argv[]) { uint8_t *encoderOutputByte = malloc(sizeof(uint8_t) * coderLength); double *modulatedInput = malloc (sizeof(double) * coderLength); //channel input double *channelOutput = malloc (sizeof(double) * coderLength); //add noise - + int16_t *channelOutput_int16; + if (decoder_int16 == 1) channelOutput_int16 = (int16_t*)malloc (sizeof(int16_t) * coderLength); + t_nrPolar_paramsPtr nrPolar_params = NULL, currentPtr = NULL; nr_polar_init(&nrPolar_params, polarMessageType, testLength, aggregation_level); currentPtr = nr_polar_params(nrPolar_params, polarMessageType, testLength, aggregation_level); @@ -323,13 +325,6 @@ int main(int argc, char *argv[]) { /*printf("encoderOutput: [0]->0x%08x\n", encoderOutput[0]); printf("encoderOutput: [1]->0x%08x\n", encoderOutput[1]);*/ -/* - if (decoder_int16==1) { - if (channelOutput[i] > 15) channelOutput_int8[i] = 127; - else if (channelOutput[i] < -16) channelOutput_int8[i] = -128; - else channelOutput_int8[i] = (int16_t) (8*channelOutput[i]); - } -*/ //Bit-to-byte: nr_bit2byte_uint32_8_t(encoderOutput, coderLength, encoderOutputByte); @@ -341,6 +336,15 @@ int main(int argc, char *argv[]) { modulatedInput[i]=(-1)/sqrt(2); 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]); + } + + } start_meas(&timeDecoder); @@ -350,12 +354,19 @@ int main(int argc, char *argv[]) { NR_POLAR_DECODER_LISTSIZE, aPrioriArray, NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION);*/ - decoderState = polar_decoder_aPriori(channelOutput, - estimatedOutput, - currentPtr, - NR_POLAR_DECODER_LISTSIZE, - NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION, - aPrioriArray); + if (decoder_int16==0) + decoderState = polar_decoder_aPriori(channelOutput, + estimatedOutput, + currentPtr, + NR_POLAR_DECODER_LISTSIZE, + NR_POLAR_DECODER_PATH_METRIC_APPROXIMATION, + aPrioriArray); + else + decoderState = polar_decoder_int16(channelOutput_int16, + estimatedOutput, + currentPtr); + + stop_meas(&timeDecoder); /*printf("testInput: [0]->0x%08x\n", testInput[0]); printf("estimatedOutput: [0]->0x%08x\n", estimatedOutput[0]);*/ diff --git a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c index 8353d0f21e..f1b72ae897 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoder.c @@ -1039,7 +1039,7 @@ int8_t polar_decoder_dci(double *input, int8_t polar_decoder_int16(int16_t *input, - uint8_t *output, + uint8_t *out, t_nrPolar_params *polarParams) { @@ -1069,9 +1069,9 @@ int8_t polar_decoder_int16(int16_t *input, nr_polar_deinterleaver(polarParams->nr_polar_CPrime, polarParams->nr_polar_B, polarParams->interleaving_pattern, polarParams->K); //Remove the CRC (â) - for (int j = 0; j < polarParams->payloadBits; j++) output[j]=polarParams->nr_polar_B[j]; - + for (int j = 0; j < polarParams->payloadBits; j++) polarParams->nr_polar_A[j]=polarParams->nr_polar_B[j]; + nr_byte2bit_uint8_32_t(polarParams->nr_polar_A, polarParams->payloadBits, out); return(0); } 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 5f019146f3..2891a3399b 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -34,6 +34,7 @@ #include "PHY/sse_intrin.h" #include "PHY/impl_defs_top.h" +//#define DEBUG_NEW_IMPL void updateLLR(double ***llr, uint8_t **llrU, @@ -266,7 +267,7 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { for (int i=0;iNv;i++) printf("i%d (frozen %d): alpha_v[i] = %d\n",i,1-pp->information_bit_pattern[node->first_leaf_index+i],alpha_v[i]); #endif - + if (node->left->all_frozen == 0) { @@ -275,7 +276,8 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { if (avx2mod == 0) { __m256i a256,b256,absa256,absb256,minabs256; int avx2len = node->Nv/2/16; - + + // printf("avx2len %d\n",avx2len); for (int i=0;iNv/2)]); + */ } } else if (avx2mod == 8) { @@ -315,6 +324,7 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { absb=(b+maskb)^maskb; minabs = absaNv == 2) { // apply hard decision on left node @@ -368,7 +378,7 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { betar[0] = (alpha_r[0]>0) ? -1 : 1; pp->nr_polar_U[node->first_leaf_index+1] = (1+betar[0])>>1; #ifdef DEBUG_NEW_IMPL - printf("Setting bit %d to %d (LLR %d frozen_mask %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0],frozen_mask); + printf("Setting bit %d to %d (LLR %d)\n",node->first_leaf_index+1,(betar[0]+1)>>1,alpha_r[0]); #endif } } diff --git a/openair1/PHY/CODING/nr_polar_init.c b/openair1/PHY/CODING/nr_polar_init.c index 87da29c48e..e238c7b84f 100644 --- a/openair1/PHY/CODING/nr_polar_init.c +++ b/openair1/PHY/CODING/nr_polar_init.c @@ -147,6 +147,9 @@ void nr_polar_init(t_nrPolar_paramsPtr *polarParams, free(J); + build_decoder_tree(newPolarInitNode); + printf("decoder tree nodes %d\n",newPolarInitNode->tree.num_nodes); + } else { AssertFatal(1 == 0, "[nr_polar_init] New t_nrPolar_paramsPtr could not be created"); } From 76ebc5adeb61364b3a2e8de75fb7707d9e9c5500 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 14 Oct 2018 10:10:56 +0200 Subject: [PATCH 19/19] addition of ARM NEON intrinsics --- .../nrPolar_tools/nr_polar_decoding_tools.c | 144 ++++++++++++++---- 1 file changed, 114 insertions(+), 30 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 2891a3399b..b79739e98d 100644 --- a/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c +++ b/openair1/PHY/CODING/nrPolar_tools/nr_polar_decoding_tools.c @@ -254,6 +254,18 @@ void build_decoder_tree(t_nrPolar_params *pp) { } +#if defined(__arm__) || defined(__aarch64__) +// translate 1-1 SIMD functions from SSE to NEON +#define __m128i int16x8_t +#define __m64 int8x8_t +#define _mm_abs_epi16(a) vabsq_s16(a) +#define _mm_min_epi16(a,b) vminq_s16(a,b) +#define _mm_subs_epi16(a,b) vsubq_s16(a,b) +#define _mm_abs_pi16(a) vabs_s16(a) +#define _mm_min_pi16(a,b) vmin_s16(a,b) +#define _mm_subs_pi16(a,b) vsub_s16(a,b) +#endif + void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { int16_t *alpha_v=node->alpha; int16_t *alpha_l=node->left->alpha; @@ -270,7 +282,6 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { if (node->left->all_frozen == 0) { - #if defined(__AVX2__) int avx2mod = (node->Nv/2)&15; if (avx2mod == 0) { @@ -284,14 +295,7 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { absa256 =_mm256_abs_epi16(a256); absb256 =_mm256_abs_epi16(b256); minabs256 =_mm256_min_epi16(absa256,absb256); - ((__m256i*)alpha_l)[i] =_mm256_sign_epi16(minabs256,_mm256_xor_si256(a256,b256)); - /* for (int j=0;j<16;j++) printf("alphal[%d] %d (%d,%d,%d)\n", - (16*i) + j, - alpha_l[(16*i)+j], - ((int16_t*)&minabs256)[j], - alpha_v[(16*i)+j], - alpha_v[(16*i)+j+(node->Nv/2)]); - */ + ((__m256i*)alpha_l)[i] =_mm256_sign_epi16(minabs256,_mm256_sign_epi16(a256,b256)); } } else if (avx2mod == 8) { @@ -301,7 +305,7 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { absa128 =_mm_abs_epi16(a128); absb128 =_mm_abs_epi16(b128); minabs128 =_mm_min_epi16(absa128,absb128); - *((__m128i*)alpha_l) =_mm_sign_epi16(minabs128,_mm_xor_si128(a128,b128)); + *((__m128i*)alpha_l) =_mm_sign_epi16(minabs128,_mm_sign_epi16(a128,b128)); } else if (avx2mod == 4) { __m64 a64,b64,absa64,absb64,minabs64; @@ -310,11 +314,56 @@ void applyFtoleft(t_nrPolar_params *pp,decoder_node_t *node) { absa64 =_mm_abs_pi16(a64); absb64 =_mm_abs_pi16(b64); minabs64 =_mm_min_pi16(absa64,absb64); - *((__m64*)alpha_l) =_mm_sign_pi16(minabs64,_mm_xor_si64(a64,b64)); + *((__m64*)alpha_l) =_mm_sign_pi16(minabs64,_mm_sign_pi16(a64,b64)); } else +#else + int sse4mod = (node->Nv/2)&7; + int sse4len = node->Nv/2/8; +#if defined(__arm__) || defined(__aarch64__) + int16x8_t signatimesb,comp1,comp2,negminabs128; + int16x8_t zero=vdupq_n_s16(0); #endif - { + + if (sse4mod == 0) { + for (int i=0;iNv/2/8; + + a128 =*((__m128i*)alpha_v); + b128 =((__m128i*)alpha_v)[1]; + absa128 =_mm_abs_epi16(a128); + absb128 =_mm_abs_epi16(b128); + minabs128 =_mm_min_epi16(absa128,absb128); +#if defined(__arm__) || defined(__aarch64__) + // unfortunately no direct equivalent to _mm_sign_epi16 + signatimesb=vxorrq_s16(a128,b128); + comp1=vcltq_s16(signatimesb,zero); + comp2=vcgeq_s16(signatimesb,zero); + negminabs128=vnegq_s16(minabs128); + *((__m128i*)alpha_l) =vorrq_s16(vandq_s16(minabs128,comp0),vandq_s16(negminabs128,comp1)); +#else + *((__m128i*)alpha_l) =_mm_sign_epi16(minabs128,_mm_sign_epi16(a128,b128)); +#endif + } + } + else if (sse4mod == 4) { + __m64 a64,b64,absa64,absb64,minabs64; + a64 =*((__m64*)alpha_v); + b64 =((__m64*)alpha_v)[1]; + absa64 =_mm_abs_pi16(a64); + absb64 =_mm_abs_pi16(b64); + minabs64 =_mm_min_pi16(absa64,absb64); +#if defined(__arm__) || defined(__aarch64__) + AssertFatal(1==0,"Need to do this still for ARM\n"); +#else + *((__m64*)alpha_l) =_mm_sign_pi16(minabs64,_mm_sign_epi16(a64,b64)); +#endif + } + + else +#endif + { // equvalent scalar code to above, activated only on non x86/ARM architectures for (int i=0;iNv/2;i++) { a=alpha_v[i]; b=alpha_v[i+(node->Nv/2)]; @@ -367,9 +416,34 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { else if (avx2mod == 8) { ((__m128i *)alpha_r)[0] = _mm_subs_epi16(((__m128i *)alpha_v)[1],_mm_sign_epi16(((__m128i *)alpha_v)[0],((__m128i *)betal)[0])); } + else if (avx2mod == 4) { + ((__m64 *)alpha_r)[0] = _mm_subs_pi16(((__m64 *)alpha_v)[1],_mm_sign_pi16(((__m64 *)alpha_v)[0],((__m64 *)betal)[0])); + } + else +#else + int sse4mod = (node->Nv/2)&7; + + if (sse4mod == 0) { + int sse4len = node->Nv/2/8; + + for (int i=0;iNv/2;i++) { alpha_r[i] = alpha_v[i+(node->Nv/2)] - (betal[i]*alpha_v[i]); } @@ -385,10 +459,10 @@ void applyGtoright(t_nrPolar_params *pp,decoder_node_t *node) { } -int16_t minus1[16] = {-1,-1,-1,-1, - -1,-1,-1,-1, - -1,-1,-1,-1, - -1,-1,-1,-1}; +int16_t all1[16] = {1,1,1,1, + 1,1,1,1, + 1,1,1,1, + 1,1,1,1}; void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) { @@ -401,27 +475,37 @@ void computeBeta(t_nrPolar_params *pp,decoder_node_t *node) { if (node->left->all_frozen==0) { // if left node is not aggregation of frozen bits #if defined(__AVX2__) int avx2mod = (node->Nv/2)&15; + register __m256i allones=*((__m256i*)all1); if (avx2mod == 0) { int avx2len = node->Nv/2/16; - for (int i=0;iNv/2)&15; + + if (ssr4mod == 0) { + int ssr4len = node->Nv/2/8; + register __m128i allones=*((__m128i*)all1); + for (int i=0;i