Commit 468004ec authored by Raymond Knopp's avatar Raymond Knopp Committed by Florian Kaltenberger

LDPC SIMD optmizations and code generator (BG1)

Conflicts:
	cmake_targets/CMakeLists.txt
	openair1/PHY/CODING/TESTBENCH/ldpctest.c
	openair1/PHY/CODING/defs.h
	openair1/PHY/CODING/ldpc_generate_coefficient.c
parent cea0369a
...@@ -282,7 +282,7 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR}) ...@@ -282,7 +282,7 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR})
# RRC # RRC
###### ######
add_list2_option(RRC_ASN1_VERSION "Rel10" "ASN.1 version of RRC interface" "Rel8" "Rel10" "CBA") add_list2_option(RRC_ASN1_VERSION "Rel14" "ASN.1 version of RRC interface" "Rel8" "Rel10" "CBA")
if (${RRC_ASN1_VERSION} STREQUAL "Rel8") if (${RRC_ASN1_VERSION} STREQUAL "Rel8")
set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn)
...@@ -1089,13 +1089,12 @@ set(PHY_SRC ...@@ -1089,13 +1089,12 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/CODING/nr_segmentation.c ${OPENAIR1_DIR}/PHY/CODING/nr_segmentation.c
${OPENAIR1_DIR}/PHY/CODING/ldpc_decoder.c ${OPENAIR1_DIR}/PHY/CODING/ldpc_decoder.c
${OPENAIR1_DIR}/PHY/CODING/ldpc_encoder.c ${OPENAIR1_DIR}/PHY/CODING/ldpc_encoder.c
${OPENAIR1_DIR}/PHY/CODING/ldpc_encoder2.c
${OPENAIR1_DIR}/PHY/CODING/ldpc_generate_coefficient.c ${OPENAIR1_DIR}/PHY/CODING/ldpc_generate_coefficient.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c ${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c
${OPENAIR1_DIR}/PHY/CODING/crc_byte.c ${OPENAIR1_DIR}/PHY/CODING/crc_byte.c
${OPENAIR1_DIR}/PHY/CODING/ldpc_decoder.c
${OPENAIR1_DIR}/PHY/CODING/ldpc_encoder.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c
......
...@@ -11,5 +11,6 @@ set(PBS_SIM False) ...@@ -11,5 +11,6 @@ set(PBS_SIM False)
set(PERFECT_CE True) set(PERFECT_CE True)
set(NAS_UE False) set(NAS_UE False)
set(MESSAGE_CHART_GENERATOR False) set(MESSAGE_CHART_GENERATOR False)
set(RRC_ASN1_VERSION "Rel14")
include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt) include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
...@@ -62,7 +62,8 @@ char quantize(double D,double x,unsigned char B) ...@@ -62,7 +62,8 @@ char quantize(double D,double x,unsigned char B)
#define MAX_BLOCK_LENGTH 8448 #define MAX_BLOCK_LENGTH 8448
int test_ldpc(short No_iteration, int test_ldpc(short No_iteration,
double rate, int nom_rate,
int denom_rate,
double SNR, double SNR,
unsigned char qbits, unsigned char qbits,
short block_length, short block_length,
...@@ -71,7 +72,7 @@ int test_ldpc(short No_iteration, ...@@ -71,7 +72,7 @@ int test_ldpc(short No_iteration,
unsigned int *crc_misses) unsigned int *crc_misses)
{ {
//clock initiate //clock initiate
time_stats_t time; time_stats_t time,time_optim,tinput,tprep,tparity,toutput;
opp_enabled=1; opp_enabled=1;
cpu_freq_GHz = get_cpu_freq_GHz(); cpu_freq_GHz = get_cpu_freq_GHz();
//short test_input[block_length]; //short test_input[block_length];
...@@ -79,6 +80,7 @@ int test_ldpc(short No_iteration, ...@@ -79,6 +80,7 @@ int test_ldpc(short No_iteration,
//short *c; //padded codeword //short *c; //padded codeword
short *esimated_output; short *esimated_output;
unsigned char *channel_input; unsigned char *channel_input;
unsigned char *channel_input_optim;
double *channel_output; double *channel_output;
double *modulated_input; double *modulated_input;
short *channel_output_fixed; short *channel_output_fixed;
...@@ -91,85 +93,102 @@ int test_ldpc(short No_iteration, ...@@ -91,85 +93,102 @@ int test_ldpc(short No_iteration,
*errors=0; *errors=0;
*crc_misses=0; *crc_misses=0;
// generate input block // generate input block
test_input=(unsigned char *)malloc(sizeof(unsigned char) * block_length/8); test_input=(unsigned char *)malloc(sizeof(unsigned char) * block_length/8);
channel_input = (unsigned char *)malloc(sizeof(unsigned char) * 68*384); channel_input = (unsigned char *)malloc(sizeof(unsigned char) * 68*384);
channel_input_optim = (unsigned char *)malloc(sizeof(unsigned char) * 68*384);
modulated_input = (double *)malloc(sizeof(double) * 68*384); modulated_input = (double *)malloc(sizeof(double) * 68*384);
channel_output = (double *)malloc(sizeof(double) * 68*384); channel_output = (double *)malloc(sizeof(double) * 68*384);
reset_meas(&time); reset_meas(&time);
reset_meas(&time_optim);
reset_meas(&tinput);
reset_meas(&tprep);
reset_meas(&tparity);
reset_meas(&toutput);
for (i=0; i<block_length/8; i++)
{
//test_input[i]=(unsigned char) rand();
test_input[i]=217;
}
for (i=0; i<block_length/8; i++) //determine number of bits in codeword
{ if (block_length>3840)
//test_input[i]=(unsigned char) rand(); {
test_input[i]=217; 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;
}
//determine number of bits in codeword //find minimum value in all sets of lifting size
if (block_length>3840) Zc=0;
{
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 for (i1=0; i1 < 51; i1++)
Zc=0; {
for (i1=0; i1 < 51; i1++) if (lift_size[i1] >= (double) block_length/Kb)
{ {
if (lift_size[i1] >= (double) block_length/Kb) Zc = lift_size[i1];
{ // printf("%d\n",Zc);
Zc = lift_size[i1]; break;
// printf("%d\n",Zc);
break;
}
} }
}
printf("BG %d, Zc %d, Kb %d\n",BG, Zc, Kb); printf("BG %d, Zc %d, Kb %d\n",BG, Zc, Kb);
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length*(1/((float)nom_rate/(float)denom_rate)))/Zc;
no_punctured_columns=(int)((nrows-2)*Zc+block_length-block_length/rate)/Zc; // printf("puncture:%d\n",no_punctured_columns);
//printf("%d\n",no_punctured_columns); 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,channel_input, block_length, nom_rate, denom_rate, 1);
for (trial=0; trial < ntrials; trial++) for (trial=0; trial < ntrials; trial++)
{ {
//// encoder //// encoder
if (ntrials==1) start_meas(&time);
ldpc_encoder_orig(test_input, channel_input,block_length,rate,1);
else { if (BG==1)
start_meas(&time); ldpc_encoder(test_input, channel_input,block_length,nom_rate,denom_rate);
if (BG==1) else
ldpc_encoder(test_input, channel_input,block_length,rate); ldpc_encoder_orig(test_input, channel_input,block_length,nom_rate,denom_rate,0);
else
ldpc_encoder_orig(test_input, channel_input,block_length,rate,0); stop_meas(&time);
stop_meas(&time); start_meas(&time_optim);
if (BG==1) {
ldpc_encoder_optim(test_input, channel_input_optim,block_length,nom_rate,denom_rate,&tinput,&tprep,&tparity,&toutput);
} }
stop_meas(&time_optim);
for (i = 0; i < block_length+(nrows-no_punctured_columns) * Zc - removed_bit; i++)
if (channel_input[i]!=channel_input_optim[i]) printf("differ in pos %d (%d,%d)\n",i,
channel_input[i],
channel_input_optim[i]);
//print_meas_now(&time, "", stdout); //print_meas_now(&time, "", stdout);
//for (i=0;i<25344;i++)
//printf("channel_input[%d]=%d\n",i,channel_input[i]);
// for (i=0;i<8448;i++) //printf("%d ",channel_input[i]);
//printf("channel_input[%d]=%d\n",i,channel_input[i]);
//printf("%d ",channel_input[i]);
if ((BG==2) && (Zc==128||Zc==256)) if ((BG==2) && (Zc==128||Zc==256))
{ {
channel_output_fixed = (short *)malloc( (Kb+nrows) * Zc*sizeof(short)); channel_output_fixed = (short *)malloc( (Kb+nrows) * Zc*sizeof(short));
memset(channel_output_fixed,0,(Kb+nrows) * Zc*sizeof(short)); memset(channel_output_fixed,0,(Kb+nrows) * Zc*sizeof(short));
removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/rate); removed_bit=(nrows-no_punctured_columns-2) * Zc+block_length-(int)(block_length/((float)nom_rate/(float)denom_rate));
//printf("removed_bit:%d\n",removed_bit); //printf("removed_bit:%d\n",removed_bit);
for (i = 2*Zc; i < (Kb+nrows-no_punctured_columns) * Zc-removed_bit; i++) for (i = 2*Zc; i < (Kb+nrows-no_punctured_columns) * Zc-removed_bit; i++)
...@@ -201,7 +220,7 @@ int test_ldpc(short No_iteration, ...@@ -201,7 +220,7 @@ int test_ldpc(short No_iteration,
#endif #endif
// decode the sequence // decode the sequence
// decoder supports BG2, Z=128 & 256 // decoder supports BG2, Z=128 & 256
esimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, rate); esimated_output=ldpc_decoder(channel_output_fixed, block_length, No_iteration, (double)((float)nom_rate/(float)denom_rate));
//for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++) //for (i=(Kb+nrows) * Zc-5;i<(Kb+nrows) * Zc;i++)
// printf("esimated_output[%d]=%d\n",i,esimated_output[i]); // printf("esimated_output[%d]=%d\n",i,esimated_output[i]);
...@@ -218,31 +237,35 @@ int test_ldpc(short No_iteration, ...@@ -218,31 +237,35 @@ int test_ldpc(short No_iteration,
free(channel_output_fixed); free(channel_output_fixed);
} }
else else if (trial==0)
if (trial==0) printf("decoder is not supported\n");
printf("decoder is not supported\n");
} }
print_meas(&time,"ldpc_encoder",NULL,NULL); print_meas(&time,"ldpc_encoder",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);
return *errors; return *errors;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
unsigned int errors,crc_misses; unsigned int errors,crc_misses;
short block_length=22*384; // decoder supports length: 1201 -> 1280, 2401 -> 2560 short block_length=22*384; // decoder supports length: 1201 -> 1280, 2401 -> 2560
short No_iteration=25; short No_iteration=25;
double rate=0.333; //double rate=0.333;
int nom_rate=1;
int denom_rate=3;
double SNR,SNR_lin; double SNR,SNR_lin;
unsigned char qbits=4; unsigned char qbits=4;
unsigned int decoded_errors[100]; // initiate the size of matrix equivalent to size of SNR unsigned int decoded_errors[100]; // initiate the size of matrix equivalent to size of SNR
int c,i=0; int c,i=0;
int n_trials = 100; int n_trials = 1;
randominit(0); randominit(0);
while ((c = getopt (argc, argv, "q:r:l:n:")) != -1) while ((c = getopt (argc, argv, "q:r:s:l:n:")) != -1)
switch (c) switch (c)
{ {
case 'q': case 'q':
...@@ -250,16 +273,20 @@ int main(int argc, char *argv[]) ...@@ -250,16 +273,20 @@ int main(int argc, char *argv[])
break; break;
case 'r': case 'r':
rate = atof(optarg); nom_rate = atoi(optarg);
break;
case 's':
denom_rate = atoi(optarg);
break; break;
case 'l': case 'l':
block_length = atoi(optarg); block_length = atoi(optarg);
break; break;
case 'n': case 'n':
n_trials = atoi(optarg); n_trials = atoi(optarg);
break; break;
default: default:
abort (); abort ();
...@@ -268,13 +295,14 @@ int main(int argc, char *argv[]) ...@@ -268,13 +295,14 @@ int main(int argc, char *argv[])
printf("the decoder supports BG2, Kb=10, Z=128 & 256\n"); printf("the decoder supports BG2, Kb=10, Z=128 & 256\n");
printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n"); printf(" range of blocklength: 1201 -> 1280, 2401 -> 2560\n");
printf("block length %d: \n", block_length); printf("block length %d: \n", block_length);
printf("rate: %f\n",rate); printf("rate: %d/%d\n",nom_rate,denom_rate);
for (SNR=-2.1; SNR<-2; SNR+=.1) for (SNR=-2.1; SNR<-2; SNR+=.1)
{ {
SNR_lin = pow(10,SNR/10); SNR_lin = pow(10,SNR/10);
decoded_errors[i]=test_ldpc(No_iteration, decoded_errors[i]=test_ldpc(No_iteration,
rate, nom_rate,
denom_rate,
SNR_lin, // noise standard deviation SNR_lin, // noise standard deviation
qbits, qbits,
block_length, // block length bytes block_length, // block length bytes
......
...@@ -572,7 +572,10 @@ int16_t reverseBits(int32_t ,int32_t); ...@@ -572,7 +572,10 @@ int16_t reverseBits(int32_t ,int32_t);
void phy_viterbi_dot11(int8_t *,uint8_t *,uint16_t); void phy_viterbi_dot11(int8_t *,uint8_t *,uint16_t);
short *ldpc_decoder(short *msgChannel,short block_length,short No_iteration,double rate); short *ldpc_decoder(short *msgChannel,short block_length,short No_iteration,double rate);
int ldpc_encoder(unsigned char *test_input,unsigned char* channel_input,short block_length,double rate); int encode_parity_check_part(uint16_t *c,uint16_t *d, short BG,short Zc,short Kb);
int ldpc_encoder_orig(unsigned char *test_input,unsigned char* channel_input,short block_length,double rate,unsigned char gen_code); int ldpc_encoder(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate);
int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,unsigned char gen_code);
int ldpc_encoder_multi_segment(unsigned char **test_input,unsigned char **channel_input,short block_length,double rate,uint8_t n_segments);
int ldpc_encoder_optim(unsigned char *test_input,unsigned char *channel_input,short block_length,int nom_rate,int denom_rate,time_stats_t *tinput,time_stats_t *tprep,time_stats_t *tparity,time_stats_t *toutput);
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -766,7 +766,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, ...@@ -766,7 +766,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
unsigned int Kr=0,Kr_bytes,r,r_offset=0,Kr_int=0; unsigned int Kr=0,Kr_bytes,r,r_offset=0,Kr_int=0;
// unsigned short m=dlsch->harq_processes[harq_pid]->mcs; // unsigned short m=dlsch->harq_processes[harq_pid]->mcs;
uint8_t beamforming_mode=0; uint8_t beamforming_mode=0;
double rate = 0.33; //double rate = 0.33;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING, VCD_FUNCTION_IN);
...@@ -899,13 +899,13 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, ...@@ -899,13 +899,13 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
Kr_int = Kr; Kr_int = Kr;
#ifdef DEBUG_DLSCH_CODING #ifdef DEBUG_DLSCH_CODING
printf("start ldpc encoder B %d, rate %f\n",dlsch->harq_processes[harq_pid]->B,rate); printf("start ldpc encoder B %d\n",dlsch->harq_processes[harq_pid]->B);
printf("input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]); printf("input %d %d %d %d %d \n", dlsch->harq_processes[harq_pid]->c[r][0], dlsch->harq_processes[harq_pid]->c[r][1], dlsch->harq_processes[harq_pid]->c[r][2],dlsch->harq_processes[harq_pid]->c[r][3], dlsch->harq_processes[harq_pid]->c[r][4]);
#endif #endif
start_meas(te_stats); start_meas(te_stats);
memset(dlsch->harq_processes[harq_pid]->d[r],0,(96+12+3+3*8448)*sizeof(uint8_t)); memset(dlsch->harq_processes[harq_pid]->d[r],0,(96+12+3+3*8448)*sizeof(uint8_t));
ldpc_encoder((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][96],Kr,rate); ldpc_encoder((unsigned char*)dlsch->harq_processes[harq_pid]->c[r],(unsigned char*)&dlsch->harq_processes[harq_pid]->d[r][96],Kr,1,3);
stop_meas(te_stats); stop_meas(te_stats);
#endif #endif
......
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