Commit 68c07e29 authored by Guy De Souza's avatar Guy De Souza

Merge branch 'nr_pdsch' of https://gitlab.eurecom.fr/oai/openairinterface5g into nr_pdsch

parents 3feb84ca 6e29ff08
......@@ -686,7 +686,7 @@ function main() {
echo_info "Compiling unitary tests simulators"
# TODO: fix: dlsim_tm4 pucchsim prachsim pdcchsim pbchsim mbmssim
#simlist="dlsim_tm4 dlsim ulsim pucchsim prachsim pdcchsim pbchsim mbmssim"
simlist="dlsim ulsim"
simlist="dlsim ulsim polartest ldpctest"
for f in $simlist ; do
compilations \
lte-simulators $f \
......
......@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
#include "assertions.h"
#include "SIMULATION/TOOLS/sim.h"
#include "PHY/CODING/nrLDPC_encoder/defs.h"
#include "PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.h"
......@@ -38,6 +39,10 @@
# endif
#endif
#define NR_LDPC_PROFILER_DETAIL
#define NR_LDPC_ENABLE_PARITY_CHECK
// 4-bit quantizer
char quantize4bit(double D,double x)
{
......@@ -53,13 +58,33 @@ char quantize4bit(double D,double x)
return((char)qxd);
}
char quantize8bit(double D,double x)
{
double qxd;
//char maxlev;
qxd = floor(x/D);
//maxlev = 1<<(B-1);
//printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev);
if (qxd <= -128)
qxd = -128;
else if (qxd >= 128)
qxd = 127;
return((char)qxd);
}
char quantize(double D,double x,unsigned char B)
{
double qxd;
char maxlev;
short maxlev;
qxd = floor(x/D);
// printf("x=%f,qxd=%f\n",x,qxd);
maxlev = 1<<(B-1);
maxlev = 1<<(B-1);//(char)(pow(2,B-1));
//printf("x=%f,qxd=%f,maxlev=%d\n",x,qxd, maxlev);
if (qxd <= -maxlev)
qxd = -maxlev;
......@@ -69,45 +94,78 @@ char quantize(double D,double x,unsigned char B)
return((char)qxd);
}
typedef struct {
double n_iter_mean;
double n_iter_std;
int n_iter_max;
} n_iter_stats_t;
#define MAX_BLOCK_LENGTH 8448
short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
int test_ldpc(short No_iteration,
//int nom_rate,
//int denom_rate,
int nom_rate,
int denom_rate,
double SNR,
unsigned char qbits,
unsigned short block_length,
short block_length,
unsigned int ntrials,
int n_segments,
unsigned int *errors,
unsigned int *crc_misses)
unsigned int *errors_bit,
double *errors_bit_uncoded,
unsigned int *crc_misses,
time_stats_t *time_optim,
time_stats_t *time_decoder,
n_iter_stats_t * dec_iter)
{
//clock initiate
time_stats_t time,time_optim,tinput,tprep,tparity,toutput;
//time_stats_t time,time_optim,tinput,tprep,tparity,toutput, time_decoder;
time_stats_t time, tinput,tprep,tparity,toutput;
double n_iter_mean = 0;
double n_iter_std = 0;
int n_iter_max = 0;
unsigned int segment_bler = 0;
double sigma;
sigma = 1.0/sqrt(2*SNR);
opp_enabled=1;
cpu_freq_GHz = get_cpu_freq_GHz();
//short test_input[block_length];
unsigned char *test_input[MAX_NUM_DLSCH_SEGMENTS]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};;
//short *c; //padded codeword
unsigned char *estimated_output;
unsigned char *estimated_output[MAX_NUM_DLSCH_SEGMENTS];
unsigned char *estimated_output_bit[MAX_NUM_DLSCH_SEGMENTS];
unsigned char *test_input_bit;
unsigned char *channel_input[MAX_NUM_DLSCH_SEGMENTS];
unsigned char *channel_output_uncoded[MAX_NUM_DLSCH_SEGMENTS];
unsigned char *channel_input_optim[MAX_NUM_DLSCH_SEGMENTS];
double *channel_output;
double *modulated_input;
char *channel_output_fixed;
double *modulated_input[MAX_NUM_DLSCH_SEGMENTS];
char *channel_output_fixed[MAX_NUM_DLSCH_SEGMENTS];
unsigned int i,j,trial=0;
short BG,Zc,Kb;
//short nrows,ncols;
//int no_punctured_columns,removed_bit;
short BG,Zc,Kb,nrows;//,ncols;
int no_punctured_columns,removed_bit;
int i1;
int R_ind = 0;
//Table of possible lifting sizes
short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
int n_segments=8;
int N; //length encoded block
//short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
//int n_segments=1;
int code_rate_vec[8] = {15, 13, 25, 12, 23, 34, 56, 89};
//double code_rate_actual_vec[8] = {0.2, 0.33333, 0.4, 0.5, 0.66667, 0.73333, 0.81481, 0.88};
t_nrLDPC_dec_params decParams;
int n_iter;
t_nrLDPC_time_stats decoder_profiler;
t_nrLDPC_time_stats* p_decoder_profiler =&decoder_profiler ;
int32_t n_iter = 0;;
*errors=0;
*errors_bit=0;
*errors_bit_uncoded=0;
*crc_misses=0;
// generate input block
......@@ -115,40 +173,64 @@ int test_ldpc(short No_iteration,
test_input[j]=(unsigned char *)malloc16(sizeof(unsigned char) * block_length/8);
channel_input[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
channel_input_optim[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
channel_output_uncoded[j] = (unsigned char *)malloc16(sizeof(unsigned char) * 68*384);
estimated_output[j] = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
estimated_output_bit[j] = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
modulated_input[j] = (double *)malloc16(sizeof(double) * 68*384);
channel_output_fixed[j] = (char *)malloc16(sizeof( char) * 68*384);
}
modulated_input = (double *)malloc(sizeof(double) * 68*384);
channel_output = (double *)malloc(sizeof(double) * 68*384);
channel_output_fixed = (char *)malloc16(sizeof(char) * 68*384);
estimated_output = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
memset(channel_output_fixed,0,sizeof(char) * 68*384);
//modulated_input = (double *)malloc(sizeof(double) * 68*384);
//channel_output = (double *)malloc(sizeof(double) * 68*384);
//channel_output_fixed = (char *)malloc16(sizeof(char) * 68*384);
//modulated_input = (double *)calloc(68*384, sizeof(double));
channel_output = (double *)calloc(68*384, sizeof(double));
//channel_output_fixed = (double *)calloc(68*384, sizeof(double));
//channel_output_fixed = (unsigned char*)calloc(68*384, sizeof(unsigned char*));
//estimated_output = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);///8);
//estimated_output_bit = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
test_input_bit = (unsigned char*) malloc16(sizeof(unsigned char) * block_length);
reset_meas(&time);
reset_meas(&time_optim);
reset_meas(time_optim);
reset_meas(time_decoder);
reset_meas(&tinput);
reset_meas(&tprep);
reset_meas(&tparity);
reset_meas(&toutput);
//Reset Decoder profiles
reset_meas(&decoder_profiler.llr2llrProcBuf);
reset_meas(&decoder_profiler.llr2CnProcBuf);
reset_meas(&decoder_profiler.cnProc);
reset_meas(&decoder_profiler.cnProcPc);
reset_meas(&decoder_profiler.bnProc);
reset_meas(&decoder_profiler.bnProcPc);
reset_meas(&decoder_profiler.cn2bnProcBuf);
reset_meas(&decoder_profiler.bn2cnProcBuf);
reset_meas(&decoder_profiler.llrRes2llrOut);
reset_meas(&decoder_profiler.llr2bit);
//reset_meas(&decoder_profiler.total);
for (j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
for (i=0; i<block_length/8; i++) {
test_input[j][i]=(unsigned char) rand();
//test_input[j][i]=j%256;
//test_input[j][i]=252;
}
}
//determine number of bits in codeword
if ((block_length>3840) && (block_length <= MAX_BLOCK_LENGTH))
if (block_length>3840)
{
BG=1;
Kb = 22;
//nrows=46; //parity check bits
nrows=46; //parity check bits
//ncols=22; //info bits
}
else if (block_length<=3840)
{
BG=2;
//nrows=42; //parity check bits
nrows=42; //parity check bits
//ncols=10; // info bits
if (block_length>640)
......@@ -160,13 +242,47 @@ int test_ldpc(short No_iteration,
else
Kb = 6;
}
else {
printf("block_length %d not supported\n",block_length);
exit(-1);
}
if (nom_rate == 1)
if (denom_rate == 5)
if (BG == 2)
R_ind = 0;
else
printf("Not supported");
else if (denom_rate == 3)
R_ind = 1;
else if (denom_rate == 2)
//R_ind = 3;
printf("Not supported");
else
printf("Not supported");
else if (nom_rate == 2)
if (denom_rate == 5)
//R_ind = 2;
printf("Not supported");
else if (denom_rate == 3)
R_ind = 4;
else
printf("Not supported");
else if ((nom_rate == 22) && (denom_rate == 30))
//R_ind = 5;
printf("Not supported");
else if ((nom_rate == 22) && (denom_rate == 27))
//R_ind = 6;
printf("Not supported");
else if ((nom_rate == 22) && (denom_rate == 25))
if (BG == 1)
R_ind = 7;
else
printf("Not supported");
else
printf("Not supported");
//find minimum value in all sets of lifting size
Zc=0;
for (i1=0; i1 < 51; i1++)
{
if (lift_size[i1] >= (double) block_length/Kb)
......@@ -177,21 +293,16 @@ int test_ldpc(short No_iteration,
}
}
if (BG==1)
N=66*Zc;
else if (BG==2)
N=50*Zc;
printf("ldpc_test: block_length %d, BG %d, Zc %d, Kb %d, N %d\n",block_length,BG, Zc, Kb, N);
//no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
printf("ldpc_test: codeword_length %d, n_segments %d, block_length %d, BG %d, Zc %d, Kb %d\n",n_segments *block_length, n_segments, block_length,BG, Zc, Kb);
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
// printf("puncture:%d\n",no_punctured_columns);
//removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
if (ntrials==0)
ldpc_encoder_orig(test_input[0],channel_input[0], block_length, BG, 1);
for (trial=0; trial < ntrials; trial++)
{
segment_bler = 0;
//// encoder
start_meas(&time);
for(j=0;j<n_segments;j++) {
......@@ -199,20 +310,31 @@ int test_ldpc(short No_iteration,
}
stop_meas(&time);
start_meas(&time_optim);
start_meas(time_optim);
ldpc_encoder_optim_8seg(test_input,channel_input_optim,block_length,BG,n_segments,&tinput,&tprep,&tparity,&toutput);
/*for(j=0;j<n_segments;j++) {
ldpc_encoder_optim(test_input[j],channel_input_optim[j],block_length,BG,&tinput,&tprep,&tparity,&toutput);
}*/
stop_meas(&time_optim);
stop_meas(time_optim);
if (ntrials==1)
for (j=0;j<n_segments;j++)
for (i = 0; i < 3*block_length; i++)
for (i = 0; i < block_length+(nrows-no_punctured_columns) * Zc - removed_bit; i++)
if (channel_input[j][i]!=channel_input_optim[j][i]) {
printf("differ in seg %d pos %d (%d,%d)\n",j,i,channel_input[j][i],channel_input_optim[j][i]);
return (-1);
}
//else{
// printf("NOT differ in seg %d pos %d (%d,%d)\n",j,i,channel_input[j][i],channel_input_optim[j][i]);
// }
if (trial== 0) {
printf("nrows: %d\n", nrows);
printf("no_punctured_columns: %d\n", no_punctured_columns);
printf("removed_bit: %d\n", removed_bit);
printf("To: %d\n", (Kb+nrows-no_punctured_columns) * Zc-removed_bit);
printf("number of undecoded bits: %d\n", (Kb+nrows-no_punctured_columns-2) * Zc-removed_bit);
}
//print_meas_now(&time, "", stdout);
......@@ -220,105 +342,211 @@ int test_ldpc(short No_iteration,
//printf("channel_input[%d]=%d\n",i,channel_input[i]);
//printf("%d ",channel_input[i]);
for (i = 2*Zc; i < 3*block_length; i++)
{
//if ((BG==2) && (Zc==128||Zc==256))
if (1) { // Transmitting one segment
for(j=0;j<n_segments;j++) {
for (i = 2*Zc; i < (Kb+nrows-no_punctured_columns) * Zc-removed_bit; i++) {
#ifdef DEBUG_CODER
if ((i&0xf)==0)
printf("\ne %d..%d: ",i,i+15);
#endif
if (channel_input[0][i-2*Zc]==0)
modulated_input[i]=1/sqrt(2); //BPSK
if (channel_input[j][i-2*Zc]==0)
modulated_input[j][i]=1.0;///sqrt(2); //QPSK
else
modulated_input[i]=-1/sqrt(2);
modulated_input[j][i]=-1.0;///sqrt(2);
///channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
//channel_output_fixed[i] = (char) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
//printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
//channel_output_fixed[i] = (char)quantize(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0),qbits);
channel_output_fixed[j][i] = (char)quantize(sigma/4.0/4.0,modulated_input[j][i] + sigma*gaussdouble(0.0,1.0),qbits);
//channel_output_fixed[i] = (char)quantize8bit(sigma/4.0,(2.0*modulated_input[i]) - 1.0 + sigma*gaussdouble(0.0,1.0));
//printf("llr[%d]=%d\n",i,channel_output_fixed[i]);
//printf("channel_output_fixed[%d]: %d\n",i,channel_output_fixed[i]);
channel_output[i] = modulated_input[i] + gaussdouble(0.0,1.0) * 1/sqrt(2*SNR);
if (channel_output[i]>1.0)
channel_output_fixed[i]=127;
else if (channel_output[i]<-1.0)
channel_output_fixed[i]=-128;
//channel_output_fixed[i] = (char)quantize(1,channel_output_fixed[i],qbits);
//Uncoded BER
if (channel_output_fixed[j][i]<0)
channel_output_uncoded[j][i]=1; //QPSK demod
else
channel_output_fixed[i] = (char) ((channel_output[i]*128)<0?(channel_output[i]*128-0.5):(channel_output[i]*128+0.5)); //fixed point 9-7
//printf("llr[%d]=%d (%f)\n",i,channel_output_fixed[i],channel_output[i]);
channel_output_uncoded[j][i]=0;
if (channel_output_uncoded[j][i] != channel_input[j][i-2*Zc])
*errors_bit_uncoded = (*errors_bit_uncoded) + 1;
}
} // End segments
/*
the LDPC decoder supports several rates and the input has to be adapted accordingly (by padding with zeros to the next lower supported rate). Moreover, the first 2*Z LLRs are zero (since they are punctured and not transmitted) then you have the LLRs corresponding to the systematic bits. After that come the filler bits, the encoder uses 0 for the filler bits hence for the decoder you need to put 127 (max LLR for bit 0) at their place. Then come the LLRs corresponding to the punctured bits followed by zeros to pad for the supported decoder rate.
*/
for (i=0;i<2*Zc;i++)
channel_output_fixed[i] = 0;
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
//{
// printf("channel_input[%d]=%d\n",i,channel_input[i]);
//printf("%lf %d\n",channel_output[i], channel_output_fixed[i]);
//printf("v[%d]=%lf\n",i,modulated_input[i]);}
#ifdef DEBUG_CODER
printf("\n");
exit(-1);
#endif
decParams.BG=BG;
decParams.Z=Zc;
decParams.R=13;
decParams.numMaxIter=6;
decParams.R=code_rate_vec[R_ind];//13;
decParams.numMaxIter=No_iteration;
decParams.outMode = nrLDPC_outMode_BIT;
//decParams.outMode =nrLDPC_outMode_LLRINT8;
start_meas(time_decoder);
for(j=0;j<n_segments;j++) {
// decode the sequence
// decoder supports BG2, Z=128 & 256
//estimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, (double)((float)nom_rate/(float)denom_rate));
n_iter = nrLDPC_decoder(&decParams, (int8_t*) channel_output_fixed, (int8_t*) estimated_output, NULL);
//esimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, (double)((float)nom_rate/(float)denom_rate));
///nrLDPC_decoder(&decParams, channel_output_fixed, estimated_output, NULL);
n_iter = nrLDPC_decoder(&decParams, (int8_t*)channel_output_fixed[j], (int8_t*)estimated_output[j], p_decoder_profiler);
}
stop_meas(time_decoder);
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
// printf("esimated_output[%d]=%d\n",i,esimated_output[i]);
//count errors
for(j=0;j<n_segments;j++) {
for (i=0; i<block_length>>3; i++)
{
if (estimated_output[i] != test_input[0][i])
//printf("block_length>>3: %d \n",block_length>>3);
/// printf("i: %d \n",i);
///printf("estimated_output[%d]: %d \n",i,estimated_output[i]);
///printf("test_input[0][%d]: %d \n",i,test_input[0][i]);
if (estimated_output[j][i] != test_input[j][i])
{
printf("error pos %d (%d, %d)\n",i,estimated_output[i],test_input[0][i]);
*errors = (*errors) + 1;
//////printf("error pos %d (%d, %d)\n\n",i,estimated_output[i],test_input[0][i]);
segment_bler = segment_bler + 1;
break;
}
}
for (i=0; i<block_length; i++)
{
estimated_output_bit[j][i] = (estimated_output[j][i/8]&(1<<(i&7)))>>(i&7);
test_input_bit[i] = (test_input[j][i/8]&(1<<(i&7)))>>(i&7); // Further correct for multiple segments
if (estimated_output_bit[j][i] != test_input_bit[i])
{
*errors_bit = (*errors_bit) + 1;
}
}
//if (*errors == 1000)
//break;
n_iter_mean = n_iter_mean + n_iter;
n_iter_std = n_iter_std + pow(n_iter-1,2);
if ( n_iter > n_iter_max )
n_iter_max = n_iter;
} // end segments
if (segment_bler != 0)
*errors = (*errors) + 1;
}
/*else if (trial==0)
printf("decoder is not supported\n");*/
}
dec_iter->n_iter_mean = n_iter_mean/(double)ntrials/(double)n_segments - 1;
dec_iter->n_iter_std = sqrt(n_iter_std/(double)ntrials/(double)n_segments - pow(n_iter_mean/(double)ntrials/(double)n_segments - 1,2));
dec_iter->n_iter_max = n_iter_max -1;
*errors_bit_uncoded = *errors_bit_uncoded / (double)((Kb+nrows-no_punctured_columns-2) * Zc-removed_bit);
for(j=0;j<MAX_NUM_DLSCH_SEGMENTS;j++) {
free(test_input[j]);
free(channel_input[j]);
free(channel_output_uncoded[j]);
free(channel_input_optim[j]);
free(modulated_input[j]);
free(channel_output_fixed[j]);
free(estimated_output[j]);
free(estimated_output_bit[j]);
}
free(modulated_input);
//free(modulated_input);
free(channel_output);
free(channel_output_fixed);
free(estimated_output);
//free(channel_output_fixed);
//free(estimated_output);
print_meas(&time,"ldpc_encoder",NULL,NULL);
print_meas(&time_optim,"ldpc_encoder_optim",NULL,NULL);
print_meas(time_optim,"ldpc_encoder_optim",NULL,NULL);
print_meas(&tinput,"ldpc_encoder_optim(input)",NULL,NULL);
print_meas(&tprep,"ldpc_encoder_optim(prep)",NULL,NULL);
print_meas(&tparity,"ldpc_encoder_optim(parity)",NULL,NULL);
print_meas(&toutput,"ldpc_encoder_optim(output)",NULL,NULL);
printf("\n");
print_meas(time_decoder,"ldpc_decoder",NULL,NULL);
print_meas(&decoder_profiler.llr2llrProcBuf,"llr2llrProcBuf",NULL,NULL);
print_meas(&decoder_profiler.llr2CnProcBuf,"llr2CnProcBuf",NULL,NULL);
print_meas(&decoder_profiler.cnProc,"cnProc (per iteration)",NULL,NULL);
print_meas(&decoder_profiler.cnProcPc,"cnProcPc (per iteration)",NULL,NULL);
print_meas(&decoder_profiler.bnProc,"bnProc (per iteration)",NULL,NULL);
print_meas(&decoder_profiler.bnProcPc,"bnProcPc(per iteration)",NULL,NULL);
print_meas(&decoder_profiler.cn2bnProcBuf,"cn2bnProcBuf (per iteration)",NULL,NULL);
print_meas(&decoder_profiler.bn2cnProcBuf,"bn2cnProcBuf (per iteration)",NULL,NULL);
print_meas(&decoder_profiler.llrRes2llrOut,"llrRes2llrOut",NULL,NULL);
print_meas(&decoder_profiler.llr2bit,"llr2bit",NULL,NULL);
printf("\n");
return *errors;
}
int main(int argc, char *argv[])
{
unsigned int errors,crc_misses;
short block_length=576; // decoder supports length: 1201 -> 1280, 2401 -> 2560
short No_iteration=25;
unsigned int errors, errors_bit, crc_misses;
double errors_bit_uncoded;
short block_length=8448; // decoder supports length: 1201 -> 1280, 2401 -> 2560
short No_iteration=5;
int n_segments=1;
//double rate=0.333;
//int nom_rate=1;
//int denom_rate=3;
int nom_rate=1;
int denom_rate=3;
double SNR0=-2.0,SNR,SNR_lin;
unsigned char qbits=4;
unsigned int decoded_errors[100]; // initiate the size of matrix equivalent to size of SNR
int c,i=0;
unsigned char qbits=8;
unsigned int decoded_errors[10000]; // initiate the size of matrix equivalent to size of SNR
int c,i=0, i1 = 0;
int n_trials = 1;
double SNR_step = 0.1;
randominit(0);
int test_uncoded= 0;
time_stats_t time_optim[10], time_decoder[10];
n_iter_stats_t dec_iter[3];
while ((c = getopt (argc, argv, "q:s:l:n:h")) != -1)
short BG,Zc,Kb;
while ((c = getopt (argc, argv, "q:r:s:S:l:n:d:i:t:u:h")) != -1)
switch (c)
{
case 'q':
qbits = atoi(optarg);
break;
case 'r':
nom_rate = atoi(optarg);
break;
case 'd':
denom_rate = atoi(optarg);
break;
case 'l':
block_length = atoi(optarg);
break;
......@@ -328,41 +556,176 @@ int main(int argc, char *argv[])
break;
case 's':
SNR0 = atoi(optarg);
SNR0 = atof(optarg);
break;
case 'S':
n_segments = atof(optarg);
break;
case 't':
SNR_step = atof(optarg);
break;
case 'i':
No_iteration = atoi(optarg);
break;
case 'u':
test_uncoded = atoi(optarg);
break;
default:
case 'h':
printf("usage ldpctest -h -l blocklength -n n_trials -s SNR\n");
exit(0);
default:
printf("CURRENTLY SUPPORTED CODE RATES: \n");
printf("BG1 (blocklength > 3840): 1/3, 2/3, 22/25 (8/9) \n");
printf("BG2 (blocklength <= 3840): 1/5, 1/3, 2/3 \n\n");
printf("-h This message\n");
printf("-q Quantization bits, Default: 8\n");
printf("-r Nominator rate, (1, 2, 22), Default: 1\n");
printf("-d Denominator rate, (3, 5, 25), Default: 1\n");
printf("-l Block length (l > 3840 -> BG1, rest BG2 ), Default: 8448\n");
printf("-n Number of simulation trials, Default: 1\n");
//printf("-M MCS2 for TB 2\n");
printf("-s SNR per information bit (EbNo) in dB, Default: -2\n");
printf("-S Number of segments (Maximum: 8), Default: 1\n");
printf("-t SNR simulation step, Default: 0.1\n");
printf("-i Max decoder iterations, Default: 5\n");
printf("-u Set SNR per coded bit, Default: 0\n");
exit(1);
break;
}
cpu_freq_GHz = get_cpu_freq_GHz();
//printf("the decoder supports BG2, Kb=10, Z=128 & 256\n");
//printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n");
//printf("rate: %d/%d\n",nom_rate,denom_rate);
printf("block length %d: \n", block_length);
printf("n_trials %d: \n", n_trials);
printf("SNR0 %f: \n", SNR0);
//for (block_length=8;block_length<=MAX_BLOCK_LENGTH;block_length+=8)
for (SNR=SNR0;SNR<SNR0+1.0;SNR+=1.0)
//determine number of bits in codeword
if (block_length>3840)
{
BG=1;
Kb = 22;
//nrows=46; //parity check bits
//ncols=22; //info bits
}
else if (block_length<=3840)
{
BG=2;
//nrows=42; //parity check bits
//ncols=10; // info bits
if (block_length>640)
Kb = 10;
else if (block_length>560)
Kb = 9;
else if (block_length>192)
Kb = 8;
else
Kb = 6;
}
//find minimum value in all sets of lifting size
Zc=0;
for (i1=0; i1 < 51; i1++)
{
if (lift_size[i1] >= (double) block_length/Kb)
{
Zc = lift_size[i1];
//printf("%d\n",Zc);
break;
}
}
char fname[200];
sprintf(fname,"../../../openair1/PHY/CODING/TESTBENCH/ldpctest_BG_%d_Zc_%d_rate_%d-%d_block_length_%d_maxit_%d.txt",BG,Zc,nom_rate,denom_rate,block_length, No_iteration);
FILE *fd=fopen(fname,"w");
AssertFatal(fd!=NULL,"cannot open %s\n",fname);
fprintf(fd,"SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX\n");
for (SNR=SNR0;SNR<SNR0+20.0;SNR+=SNR_step)
{
SNR_lin = pow(10,SNR/10);
//reset_meas(&time_optim);
//reset_meas(&time_decoder);
//n_iter_stats_t dec_iter = {0, 0, 0};
if (test_uncoded == 1)
SNR_lin = pow(10,SNR/10.0);
else
SNR_lin = pow(10,SNR/10.0)*nom_rate/denom_rate;
printf("Linear SNR: %f\n", SNR_lin);
decoded_errors[i]=test_ldpc(No_iteration,
//nom_rate,
//denom_rate,
nom_rate,
denom_rate,
SNR_lin, // noise standard deviation
qbits,
block_length, // block length bytes
n_trials,
n_segments,
&errors,
&crc_misses);
&errors_bit,
&errors_bit_uncoded,
&crc_misses,
time_optim,
time_decoder,
dec_iter);
printf("SNR %f, BLER %f (%d/%d)\n",SNR,(float)decoded_errors[i]/(float)n_trials,decoded_errors[i],n_trials);
printf("SNR %f, BER %f (%d/%d)\n",SNR,(float)errors_bit/(float)n_trials/(float)block_length/(double)n_segments ,decoded_errors[i],n_trials);
printf("SNR %f, Uncoded BER %f (%d/%d)\n",SNR,errors_bit_uncoded/(float)n_trials/(double)n_segments ,decoded_errors[i],n_trials);
printf("SNR %f, Mean iterations: %f\n",SNR, dec_iter->n_iter_mean);
printf("SNR %f, Std iterations: %f\n",SNR, dec_iter->n_iter_std);
printf("SNR %f, Max iterations: %d\n",SNR, dec_iter->n_iter_max);
printf("\n");
printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz);
printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)));
printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/cpu_freq_GHz);
printf("\n");
printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz);
printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)));
printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/cpu_freq_GHz);
fprintf(fd,"%f %f %f %f %f %f %f %f %f %f %f %f %d \n",
SNR,
(double)decoded_errors[i]/(double)n_trials ,
(double)errors_bit/(double)n_trials/(double)block_length/(double)n_segments ,
errors_bit_uncoded/(double)n_trials/(double)n_segments ,
(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,
sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)),
(double)time_optim->max/1000.0/cpu_freq_GHz,
(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,
sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)),
(double)time_decoder->max/1000.0/cpu_freq_GHz,
dec_iter->n_iter_mean,
dec_iter->n_iter_std,
dec_iter->n_iter_max
);
if (decoded_errors[i] == 0)
break;
i=i+1;
}
fclose(fd);
return(0);
}
......@@ -38,6 +38,9 @@
#include "nrLDPC_cnProc.h"
#include "nrLDPC_bnProc.h"
#define NR_LDPC_ENABLE_PARITY_CHECK
#define NR_LDPC_PROFILER_DETAIL
#ifdef NR_LDPC_DEBUG_MODE
#include "nrLDPC_tools/nrLDPC_debug.h"
#endif
......
......@@ -201,7 +201,7 @@ void encode_parity_check_part_optim(uint8_t *c,uint8_t *d, short BG,short Zc,sho
int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
{
short Kb,Zc,nrows,ncols;
short Zc,Kb,nrows,ncols;
int i,i1;
int no_punctured_columns,removed_bit;
......@@ -211,14 +211,19 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh
int simd_size;
//determine number of bits in codeword
//determine number of bits in codeword
//if (block_length>3840)
if (BG==1)
{
//BG=1;
Kb = 22;
nrows=46; //parity check bits
ncols=22; //info bits
}
//else if (block_length<=3840)
else if (BG==2)
{
//BG=2;
nrows=42; //parity check bits
ncols=10; // info bits
......@@ -316,7 +321,7 @@ int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,sh
int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_input,short block_length,short BG,int n_segments,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
{
short Kb,Zc,nrows,ncols;
short Zc,Kb,nrows,ncols;
int i,i1,j;
int no_punctured_columns,removed_bit;
//Table of possible lifting sizes
......@@ -343,14 +348,18 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments);
//determine number of bits in codeword
//if (block_length>3840)
if (BG==1)
{
//BG=1;
Kb = 22;
nrows=46; //parity check bits
ncols=22; //info bits
}
//else if (block_length<=3840)
else if (BG==2)
{
//BG=2;
nrows=42; //parity check bits
ncols=10; // info bits
......@@ -508,3 +517,217 @@ int ldpc_encoder_optim_8seg(unsigned char **test_input,unsigned char **channel_i
stop_meas(toutput);
return 0;
}
int ldpc_encoder_optim_8seg_multi(unsigned char **test_input,unsigned char **channel_input,short block_length,int nom_rate,int denom_rate,int n_segments,unsigned int macro_num, time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput)
{
short BG,Zc,Kb,nrows,ncols;
int i,i1,j;
int no_punctured_columns,removed_bit;
//Table of possible lifting sizes
short lift_size[51]= {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,18,20,22,24,26,28,30,32,36,40,44,48,52,56,60,64,72,80,88,96,104,112,120,128,144,160,176,192,208,224,240,256,288,320,352,384};
char temp;
int simd_size;
int macro_segment, macro_segment_end;
macro_segment = 8*macro_num;
macro_segment_end = (n_segments > 8*(macro_num+1)) ? 8*(macro_num+1) : n_segments;
///printf("macro_segment: %d\n", macro_segment);
///printf("macro_segment_end: %d\n", macro_segment_end );
#ifdef __AVX2__
__m256i shufmask = _mm256_set_epi64x(0x0303030303030303, 0x0202020202020202,0x0101010101010101, 0x0000000000000000);
__m256i andmask = _mm256_set1_epi64x(0x8040201008040201); // every 8 bits -> 8 bytes, pattern repeats.
__m256i zero256 = _mm256_setzero_si256();
__m256i masks[8];
register __m256i c256;
masks[0] = _mm256_set1_epi8(0x1);
masks[1] = _mm256_set1_epi8(0x2);
masks[2] = _mm256_set1_epi8(0x4);
masks[3] = _mm256_set1_epi8(0x8);
masks[4] = _mm256_set1_epi8(0x10);
masks[5] = _mm256_set1_epi8(0x20);
masks[6] = _mm256_set1_epi8(0x40);
masks[7] = _mm256_set1_epi8(0x80);
#endif
///AssertFatal(n_segments>0&&n_segments<=8,"0 < n_segments %d <= 8\n",n_segments);
//determine number of bits in codeword
if (block_length>3840)
{
BG=1;
Kb = 22;
nrows=46; //parity check bits
ncols=22; //info bits
}
else if (block_length<=3840)
{
BG=2;
nrows=42; //parity check bits
ncols=10; // info bits
if (block_length>640)
Kb = 10;
else if (block_length>560)
Kb = 9;
else if (block_length>192)
Kb = 8;
else
Kb = 6;
}
//find minimum value in all sets of lifting size
Zc=0;
for (i1=0; i1 < 51; i1++)
{
if (lift_size[i1] >= (double) block_length/Kb)
{
Zc = lift_size[i1];
//printf("%d\n",Zc);
break;
}
}
#ifdef DEBUG_LDPC
LOG_D(PHY,"ldpc_encoder_optim_8seg: BG %d, Zc %d, Kb %d, block_length %d, segments %d\n",BG,Zc,Kb,block_length,n_segments);
LOG_D(PHY,"ldpc_encoder_optim_8seg: PDU (seg 0) %x %x %x %x\n",test_input[0][0],test_input[0][1],test_input[0][2],test_input[0][3]);
#endif
AssertFatal(Zc>0,"no valid Zc found for block length %d\n",block_length);
if ((Zc&31) > 0) simd_size = 16;
else simd_size = 32;
unsigned char c[22*Zc] __attribute__((aligned(32))); //padded input, unpacked, max size
unsigned char d[46*Zc] __attribute__((aligned(32))); //coded parity part output, unpacked, max size
unsigned char c_extension[2*22*Zc*simd_size] __attribute__((aligned(32))); //double size matrix of c
// calculate number of punctured bits
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc;
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length*3);
// printf("%d\n",no_punctured_columns);
// printf("%d\n",removed_bit);
// unpack input
memset(c,0,sizeof(unsigned char) * ncols * Zc);
memset(d,0,sizeof(unsigned char) * nrows * Zc);
start_meas(tinput);
#if 0
for (i=0; i<block_length; i++) {
//for (j=0; j<n_segments; j++) {
for (j=macro_segment; j < macro_segment_end; j++) {
temp = (test_input[j][i/8]&(1<<(i&7)))>>(i&7);
//printf("c(%d,%d)=%d\n",j,i,temp);
c[i] |= (temp << (j-macro_segment));
}
}
#else
#ifdef __AVX2__
for (i=0; i<block_length>>5; i++) {
c256 = _mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[macro_segment])[i]), shufmask),andmask),zero256),masks[0]);
//for (j=1; j<n_segments; j++) {
for (j=macro_segment+1; j < macro_segment_end; j++) {
c256 = _mm256_or_si256(_mm256_and_si256(_mm256_cmpeq_epi8(_mm256_andnot_si256(_mm256_shuffle_epi8(_mm256_set1_epi32(((uint32_t*)test_input[j])[i]), shufmask),andmask),zero256),masks[j-macro_segment]),c256);
}
((__m256i *)c)[i] = c256;
}
for (i=(block_length>>5)<<5;i<block_length;i++) {
//for (j=0; j<n_segments; j++) {
for (j=macro_segment; j < macro_segment_end; j++) {
temp = (test_input[j][i/8]&(1<<(i&7)))>>(i&7);
//printf("c(%d,%d)=%d\n",j,i,temp);
c[i] |= (temp << (j-macro_segment));
}
}
#else
AssertFatal(1==0,"Need AVX2 for this\n");
#endif
#endif
stop_meas(tinput);
if ((BG==1 && Zc>176) || (BG==2 && Zc>64)) {
// extend matrix
start_meas(tprep);
for (i1=0; i1 < ncols; i1++)
{
memcpy(&c_extension[2*i1*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
memcpy(&c_extension[(2*i1+1)*Zc], &c[i1*Zc], Zc*sizeof(unsigned char));
}
for (i1=1;i1<simd_size;i1++) {
memcpy(&c_extension[(2*ncols*Zc*i1)], &c_extension[i1], (2*ncols*Zc*sizeof(unsigned char))-i1);
// memset(&c_extension[(2*ncols*Zc*i1)],0,i1);
/*
printf("shift %d: ",i1);
for (int j=0;j<64;j++) printf("%d ",c_extension[(2*ncols*Zc*i1)+j]);
printf("\n");
*/
}
stop_meas(tprep);
//parity check part
start_meas(tparity);
encode_parity_check_part_optim(c_extension, d, BG, Zc, Kb);
stop_meas(tparity);
}
else {
if (encode_parity_check_part_orig(c, d, BG, Zc, Kb, block_length)!=0) {
printf("Problem with encoder\n");
return(-1);
}
}
start_meas(toutput);
// information part and puncture columns
/*
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
*/
#ifdef __AVX2__
if ((((2*Zc)&31) == 0) && (((block_length-(2*Zc))&31) == 0)) {
//AssertFatal(((2*Zc)&31) == 0,"2*Zc needs to be a multiple of 32 for now\n");
//AssertFatal(((block_length-(2*Zc))&31) == 0,"block_length-(2*Zc) needs to be a multiple of 32 for now\n");
uint32_t l1 = (block_length-(2*Zc))>>5;
uint32_t l2 = ((nrows-no_punctured_columns) * Zc-removed_bit)>>5;
__m256i *c256p = (__m256i *)&c[2*Zc];
__m256i *d256p = (__m256i *)&d[0];
// if (((block_length-(2*Zc))&31)>0) l1++;
for (i=0;i<l1;i++)
//for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j),masks[0]);
for (j=macro_segment; j < macro_segment_end; j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(c256p[i],j-macro_segment),masks[0]);
// if ((((nrows-no_punctured_columns) * Zc-removed_bit)&31)>0) l2++;
for (i1=0;i1<l2;i1++,i++)
//for (j=0;j<n_segments;j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j),masks[0]);
for (j=macro_segment; j < macro_segment_end; j++) ((__m256i *)channel_input[j])[i] = _mm256_and_si256(_mm256_srai_epi16(d256p[i1],j-macro_segment),masks[0]);
}
else {
#ifdef DEBUG_LDPC
LOG_W(PHY,"using non-optimized version\n");
#endif
// do non-SIMD version
for (i=0;i<(block_length-2*Zc);i++)
//for (j=0; j<n_segments; j++)
for (j=macro_segment; j < macro_segment_end; j++)
channel_input[j][i] = (c[2*Zc+i]>>(j-macro_segment))&1;
for (i=0;i<((nrows-no_punctured_columns) * Zc-removed_bit);i++)
//for (j=0; j<n_segments; j++)
for (j=macro_segment; j < macro_segment_end; j++)
channel_input[j][block_length-2*Zc+i] = (d[i]>>(j-macro_segment))&1;
}
#else
AssertFatal(1==0,"Need AVX2 for now\n");
#endif
stop_meas(toutput);
return 0;
}
......@@ -361,7 +361,7 @@ short *choose_generator_matrix(short BG,short Zc)
return Gen_shift_values;
}
int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,short BG,unsigned char gen_code)
int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length, short BG,unsigned char gen_code)
{
unsigned char c[22*384]; //padded input, unpacked, max size
unsigned char d[68*384]; //coded output, unpacked, max size
......@@ -378,14 +378,18 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
int indlist2[1000];
//determine number of bits in codeword
//if (block_length>3840)
if (BG==1)
{
//BG=1;
Kb = 22;
nrows=46; //parity check bits
ncols=22; //info bits
}
//else if (block_length<=3840)
else if (BG==2)
{
//BG=2;
nrows=42; //parity check bits
ncols=10; // info bits
......@@ -415,8 +419,6 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
return(-1);
}
int K = ncols*Zc;
Gen_shift_values=choose_generator_matrix(BG,Zc);
if (Gen_shift_values==NULL) {
printf("ldpc_encoder_orig: could not find generator matrix\n");
......@@ -438,15 +440,9 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
}
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*3)/Zc;
//nrows - no_punctured_columns = 2 +2*block_length/Zc
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(block_length*3);
// ((nrows-no_punctured_columns) * Zc-removed_bit) =
// 2Zc + 2*block_length
//printf("%d\n",no_punctured_columns);
//printf("%d\n",removed_bit);
//printf("%d\n",nrows-no_punctured_columns);
//printf("%d\n",((nrows-no_punctured_columns) * Zc-removed_bit));
// unpack input
memset(c,0,sizeof(unsigned char) * ncols * Zc);
memset(d,0,sizeof(unsigned char) * nrows * Zc);
......@@ -614,8 +610,8 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,sho
}
// information part and puncture columns
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char)); //systematic bits
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char)); //systematic bits 2Zc + 2*block_length
memcpy(&channel_input[0], &c[2*Zc], (block_length-2*Zc)*sizeof(unsigned char));
memcpy(&channel_input[block_length-2*Zc], &d[0], ((nrows-no_punctured_columns) * Zc-removed_bit)*sizeof(unsigned char));
//memcpy(channel_input,c,Kb*Zc*sizeof(unsigned char));
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment