Applied LDPC fixes and minor aestheic modifications

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent 13443c3f8c
commit 2e59f6a568

@ -34,7 +34,9 @@
#define SRSLTE_LDPC_BG1_MAX_LEN_CB 8448 /*!< \brief Maximum code block size for LDPC BG1 */
#define SRSLTE_LDPC_BG2_MAX_LEN_CB 3840 /*!< \brief Maximum code block size for LDPC BG2 */
#define SRSLTE_LDPC_MAX_LEN_CB SRSLTE_MAX(SRSLTE_LDPC_BG1_MAX_LEN_CB, SRSLTE_LDPC_BG2_MAX_LEN_CB)
#define SRSLTE_LDPC_MAX_LEN_CB \
SRSLTE_MAX(SRSLTE_LDPC_BG1_MAX_LEN_CB, \
SRSLTE_LDPC_BG2_MAX_LEN_CB) /*!< \brief Maximum code block size for LDPC BG1 or BG2 */
#define BG1Nfull 68 /*!< \brief Number of variable nodes in BG1. */
#define BG1N 66 /*!< \brief Number of variable nodes in BG1 after puncturing. */

@ -133,8 +133,7 @@ SRSLTE_API int srslte_ldpc_rm_rx_init_s(srslte_ldpc_rm_t* q);
* \param[in] rv Redundancy version 0,1,2,3.
* \param[in] mod_type Modulation type.
* \param[in] Nref Size of limited buffer.
* \param[out] output The rate-dematched codeword resulting from the rate-dematching
* operation.
* \return An integer: 0 if the function executes correctly, -1 otherwise.
*/
SRSLTE_API int srslte_ldpc_rm_rx_s(srslte_ldpc_rm_t* q,
const int16_t* input,

@ -366,7 +366,8 @@ int update_ldpc_soft_bits_c_avx2(void* p, int i_layer, const int8_t (*these_var_
/*!
* Returns the decoded message (hard bits) from the current soft bits (optimized 8-bit version, LS <= \ref
* SRSLTE_AVX2_B_SIZE). \param[in] p A pointer to the decoder registers (an ldpc_regs_c_avx2 structure).
* SRSLTE_AVX2_B_SIZE).
* \param[in] p A pointer to the decoder registers (an ldpc_regs_c_avx2 structure).
* \param[out] message A pointer to the decoded message.
* \param[in] liftK The length of the decoded message.
* \return An integer: 0 if the function executes correctly, -1 otherwise.
@ -375,7 +376,8 @@ int extract_ldpc_message_c_avx2(void* p, uint8_t* message, uint16_t liftK);
/*!
* Creates the registers used by the optimized 8-bit-based implementation of the LDPC decoder (LS > \ref
* SRSLTE_AVX2_B_SIZE). \param[in] bgN Codeword length. \param[in] bgM Number of check nodes.
* SRSLTE_AVX2_B_SIZE).
* \param[in] bgN Codeword length. \param[in] bgM Number of check nodes.
* \param[in] ls Lifting size. \param[in] scaling_fctr Scaling factor of the normalized min-sum algorithm.
* \return A pointer to the created registers (an ldpc_regs_c_avx2long structure).
*/

@ -180,7 +180,8 @@ void* create_ldpc_dec_c_avx2(uint8_t bgN, uint8_t bgM, uint16_t ls, float scalin
vp->hrr = hrr;
vp->ls = ls;
vp->scaling_fctr = _mm256_set1_epi16((uint16_t)(scaling_fctr * F2I));
// correction > 1/16 to compensate the scaling error (2^16-1)/2^16 incurred in _mm256_scalei_epi8
vp->scaling_fctr = _mm256_set1_epi16((uint16_t)((scaling_fctr + 0.00001525879) * F2I));
return vp;
}

@ -190,7 +190,8 @@ void* create_ldpc_dec_c_avx2_flood(uint8_t bgN, uint8_t bgM, uint16_t ls, float
vp->hrr = hrr;
vp->ls = ls;
vp->scaling_fctr = _mm256_set1_epi16((uint16_t)(scaling_fctr * F2I));
// correction > 1/16 to compensate the scaling error (2^16-1)/2^16 incurred in _mm256_scalei_epi8
vp->scaling_fctr = _mm256_set1_epi16((uint16_t)((scaling_fctr + 0.00001525879) * F2I));
return vp;
}

@ -227,7 +227,8 @@ void* create_ldpc_dec_c_avx2long(uint8_t bgN, uint8_t bgM, uint16_t ls, float sc
vp->n_subnodes = n_subnodes;
vp->scaling_fctr = _mm256_set1_epi16((uint16_t)(scaling_fctr * F2I));
// correction > 1/16 to compensate the scaling error (2^16-1)/2^16 incurred in _mm256_scalei_epi8
vp->scaling_fctr = _mm256_set1_epi16((uint16_t)((scaling_fctr + 0.00001525879) * F2I));
return vp;
}

@ -240,7 +240,8 @@ void* create_ldpc_dec_c_avx2long_flood(uint8_t bgN, uint8_t bgM, uint16_t ls, fl
vp->n_subnodes = n_subnodes;
vp->scaling_fctr = _mm256_set1_epi16((uint16_t)(scaling_fctr * F2I));
// correction > 1/16 to compensate the scaling error (2^16-1)/2^16 incurred in _mm256_scalei_epi8
vp->scaling_fctr = _mm256_set1_epi16((uint16_t)((scaling_fctr + 0.00001525879) * F2I));
return vp;
}

@ -108,17 +108,17 @@ void preprocess_systematic_bits_avx2(srslte_ldpc_encoder_t* q);
void encode_high_rate_case1_avx2(void* o);
/*! Computes the high-rate parity bits for BG1 and ls_index in {6} (SIMD-optimized version, LS <= \ref
* SRSLTE_AVX2_B_SIZE). \param[in,out] q A pointer to an encoder.
* SRSLTE_AVX2_B_SIZE). \param[in,out] o A pointer to an encoder.
*/
void encode_high_rate_case2_avx2(void* o);
/*! Computes the high-rate parity bits for BG2 and ls_index in {0, 1, 2, 4, 5, 6} (SIMD-optimized version, LS <= \ref
* SRSLTE_AVX2_B_SIZE). \param[in,out] q A pointer to an encoder.
* SRSLTE_AVX2_B_SIZE). \param[in,out] o A pointer to an encoder.
*/
void encode_high_rate_case3_avx2(void* o);
/*! Computes the high-rate parity bits for BG2 and ls_index in {3, 7} (SIMD-optimized version, LS <= \ref
* SRSLTE_AVX2_B_SIZE). \param[in,out] q A pointer to an encoder.
* SRSLTE_AVX2_B_SIZE). \param[in,out] o A pointer to an encoder.
*/
void encode_high_rate_case4_avx2(void* o);

@ -126,8 +126,9 @@ void encode_high_rate_case1(void* q_, uint8_t* output)
}
}
void encode_high_rate_case2(srslte_ldpc_encoder_t* q, uint8_t* output)
void encode_high_rate_case2(void* q_, uint8_t* output)
{
srslte_ldpc_encoder_t* q = (srslte_ldpc_encoder_t*)q_;
uint8_t(*aux)[q->ls] = q->ptr;
int ls = q->ls;
@ -155,8 +156,9 @@ void encode_high_rate_case2(srslte_ldpc_encoder_t* q, uint8_t* output)
}
}
void encode_high_rate_case3(srslte_ldpc_encoder_t* q, uint8_t* output)
void encode_high_rate_case3(void* q_, uint8_t* output)
{
srslte_ldpc_encoder_t* q = (srslte_ldpc_encoder_t*)q_;
uint8_t(*aux)[q->ls] = q->ptr;
int ls = q->ls;
@ -184,8 +186,9 @@ void encode_high_rate_case3(srslte_ldpc_encoder_t* q, uint8_t* output)
}
}
void encode_high_rate_case4(srslte_ldpc_encoder_t* q, uint8_t* output)
void encode_high_rate_case4(void* q_, uint8_t* output)
{
srslte_ldpc_encoder_t* q = (srslte_ldpc_encoder_t*)q_;
uint8_t(*aux)[q->ls] = q->ptr;
int ls = q->ls;

@ -35,6 +35,7 @@
* - **-B \<number\>** Number of codewords in a batch.(Default 100).
* - **-N \<number\>** Max number of simulated batches.(Default 10000).
* - **-E \<number\>** Minimum number of errors for a significant simulation.(Default 100).
* - **-w \<number\>** Rate-matching aware encoding/decoding [(0 or 1)]
*/
#include <stdio.h>
@ -54,11 +55,12 @@
static srslte_basegraph_t base_graph = BG1; /*!< \brief Base Graph (BG1 or BG2). */
static uint32_t lift_size = 2; /*!< \brief Lifting Size. */
static uint32_t rm_length = 0; /*!< \brief Codeword length after rate matching. */
static uint32_t F = 22 - 5; /*!< \brief Number of filler bits in each CBS. */
static uint32_t F = 0; /*!< \brief Number of filler bits in each CBS. */
static uint8_t rv = 0; /*!< \brief Redundancy version {0-3}. */
static srslte_mod_t mod_type = SRSLTE_MOD_BPSK; /*!< \brief Modulation type: BPSK, QPSK, QAM16, QAM64, QAM256 = 4 */
static uint32_t Nref = 0; /*!< \brief Limited buffer size. */
static float snr = 0; /*!< \brief Signal-to-Noise Ratio [dB]. */
static uint8_t rm_aware = 1; /*!< \brief Flag rate matching aware encoding/decoding (1 to enable). */
static int finalK = 0; /*!< \brief Number of uncoded bits (message length, including punctured and filler bits). */
static int finalN = 0; /*!< \brief Number of coded bits (codeword length). */
@ -74,7 +76,7 @@ static int req_errors = 100; /*!< \brief Minimum number of errors for a signi
void usage(char* prog)
{
printf("Usage: %s [-bX] [-lX] [-eX] [-fX] [-rX] [-mX] [-MX] [sX]\n", prog);
printf("Usage: %s [-bX] [-lX] [-eX] [-fX] [-rX] [-mX] [-MX] [-wX] [-sX]\n", prog);
printf("\t-b Base Graph [(1 or 2) Default %d]\n", base_graph + 1);
printf("\t-l Lifting Size [Default %d]\n", lift_size);
printf("\t-e Word length after rate matching [Default %d (no rate matching i.e. E = N - F)]\n", rm_length);
@ -86,6 +88,7 @@ void usage(char* prog)
printf("\t-B Number of codewords in a batch. [Default %d]\n", batch_size);
printf("\t-N Max number of simulated batches. [Default %d]\n", max_n_batch);
printf("\t-E Minimum number of errors for a significant simulation. [Default %d]\n", req_errors);
printf("\t-w Rate-matching aware encoding/decoding [(0 or 1) Default = %d (normal buffer Nref = N)]\n", rm_aware);
}
/*!
@ -94,7 +97,7 @@ void usage(char* prog)
void parse_args(int argc, char** argv)
{
int opt = 0;
while ((opt = getopt(argc, argv, "b:l:e:f:r:m:M:s:B:N:E:")) != -1) {
while ((opt = getopt(argc, argv, "b:l:e:f:r:m:w:M:s:B:N:E:")) != -1) {
switch (opt) {
case 'b':
base_graph = (int)strtol(optarg, NULL, 10) - 1;
@ -117,6 +120,9 @@ void parse_args(int argc, char** argv)
case 'M':
Nref = (uint32_t)strtol(optarg, NULL, 10);
break;
case 'w':
rm_aware = (uint8_t)strtol(optarg, NULL, 10);
break;
case 's':
snr = (float)strtod(optarg, NULL);
break;
@ -338,6 +344,15 @@ int main(int argc, char** argv)
int8_t inf7 = (1U << 6U) - 1;
float gain_c = inf7 * noise_std_dev / 8 / (1 / noise_std_dev + 2);
// RM aware LDPC Encoding
// compute the number of symbols that we need to encode/decode: at least (rm_length + F) if rm_length +F < N,
unsigned int n_useful_symbols_enc = finalN;
unsigned int n_useful_symbols_dec = finalN;
if (rm_aware > 0) {
n_useful_symbols_enc = (rm_length + F); // if n_useful_symbols > N, the encoder set n_useful_symbols = finalN;
n_useful_symbols_dec = (rm_length + F); // if n_useful_symbols > N, the encoder set n_useful_symbols = finalN;
}
printf("\nBatch:\n ");
while (((n_error_words_f < req_errors) || (n_error_words_s < req_errors) || (n_error_words_c < req_errors)) &&
@ -363,7 +378,8 @@ int main(int argc, char** argv)
gettimeofday(&t[1], NULL);
for (j = 0; j < batch_size; j++) {
srslte_ldpc_encoder_encode(&encoder, messages_true + j * finalK, codewords + j * finalN, finalK);
srslte_ldpc_encoder_encode_rm(
&encoder, messages_true + j * finalK, codewords + j * finalN, finalK, n_useful_symbols_enc);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);
@ -425,12 +441,11 @@ int main(int argc, char** argv)
// Recover messages
gettimeofday(&t[1], NULL);
for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_f(&decoder_f, symbols + j * finalN, messages_sim_f + j * finalK, finalN);
srslte_ldpc_decoder_decode_f(&decoder_f, symbols + j * finalN, messages_sim_f + j * finalK, n_useful_symbols_dec);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);
elapsed_time_dec_f += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j;
@ -465,7 +480,8 @@ int main(int argc, char** argv)
// Recover messages
gettimeofday(&t[1], NULL);
for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_s(&decoder_s, symbols_s + j * finalN, messages_sim_s + j * finalK, finalN);
srslte_ldpc_decoder_decode_s(
&decoder_s, symbols_s + j * finalN, messages_sim_s + j * finalK, n_useful_symbols_dec);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);
@ -504,7 +520,8 @@ int main(int argc, char** argv)
// Recover messages
gettimeofday(&t[1], NULL);
for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_rm_c(&decoder_c, symbols_c + j * finalN, messages_sim_c + j * finalK, finalN);
srslte_ldpc_decoder_decode_rm_c(
&decoder_c, symbols_c + j * finalN, messages_sim_c + j * finalK, n_useful_symbols_dec);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);
@ -526,7 +543,7 @@ int main(int argc, char** argv)
gettimeofday(&t[1], NULL);
for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_rm_c(
&decoder_c_flood, symbols_c + j * finalN, messages_sim_c_flood + j * finalK, finalN);
&decoder_c_flood, symbols_c + j * finalN, messages_sim_c_flood + j * finalK, n_useful_symbols_dec);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);
@ -548,7 +565,8 @@ int main(int argc, char** argv)
// Recover messages
gettimeofday(&t[1], NULL);
for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_rm_c(&decoder_avx, symbols_c + j * finalN, messages_sim_avx + j * finalK, finalN);
srslte_ldpc_decoder_decode_rm_c(
&decoder_avx, symbols_c + j * finalN, messages_sim_avx + j * finalK, n_useful_symbols_dec);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);
@ -570,7 +588,7 @@ int main(int argc, char** argv)
gettimeofday(&t[1], NULL);
for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_rm_c(
&decoder_avx_flood, symbols_c + j * finalN, messages_sim_avx_flood + j * finalK, finalN);
&decoder_avx_flood, symbols_c + j * finalN, messages_sim_avx_flood + j * finalK, n_useful_symbols_dec);
}
gettimeofday(&t[2], NULL);
get_time_interval(t);

Loading…
Cancel
Save