Fix 5G NR FEC memcheck

master
Xavier Arteaga 4 years ago committed by Xavier Arteaga
parent 2835e87ff0
commit 0c2f96d389

@ -86,6 +86,17 @@ srslte_ldpc_encoder_init(srslte_ldpc_encoder_t* q, srslte_ldpc_encoder_type_t ty
*/ */
SRSLTE_API void srslte_ldpc_encoder_free(srslte_ldpc_encoder_t* q); SRSLTE_API void srslte_ldpc_encoder_free(srslte_ldpc_encoder_t* q);
/*!
* Encodes a message into a codeword with the specified encoder.
* \param[in] q A pointer to the desired encoder.
* \param[in] input The message to encode.
* \param[out] output The resulting codeword.
* \param[in] input_length The number of uncoded bits in the input message.
* \return An integer: 0 if the function executes correctly, -1 otherwise.
*/
SRSLTE_API int
srslte_ldpc_encoder_encode(srslte_ldpc_encoder_t* q, const uint8_t* input, uint8_t* output, uint32_t input_length);
/*! /*!
* Encodes a message into a codeword with the specified encoder. * Encodes a message into a codeword with the specified encoder.
* \param[in] q A pointer to the desired encoder. * \param[in] q A pointer to the desired encoder.
@ -95,10 +106,10 @@ SRSLTE_API void srslte_ldpc_encoder_free(srslte_ldpc_encoder_t* q);
* \param[in] cdwd_rm_length The codeword length after rate matching. * \param[in] cdwd_rm_length The codeword length after rate matching.
* \return An integer: 0 if the function executes correctly, -1 otherwise. * \return An integer: 0 if the function executes correctly, -1 otherwise.
*/ */
SRSLTE_API int srslte_ldpc_encoder_encode(srslte_ldpc_encoder_t* q, SRSLTE_API int srslte_ldpc_encoder_encode_rm(srslte_ldpc_encoder_t* q,
const uint8_t* input, const uint8_t* input,
uint8_t* output, uint8_t* output,
uint32_t input_length, uint32_t input_length,
uint32_t cdwd_rm_length); uint32_t cdwd_rm_length);
#endif // SRSLTE_LDPCENCODER_H #endif // SRSLTE_LDPCENCODER_H

@ -18,20 +18,25 @@
# and at http://www.gnu.org/licenses/. # and at http://www.gnu.org/licenses/.
# #
set(FEC_SOURCES ${FEC_SOURCES} if (HAVE_AVX2)
set(AVX2_SOURCES
ldpc/ldpc_dec_c_avx2.c
ldpc/ldpc_dec_c_avx2long.c
ldpc/ldpc_dec_c_avx2_flood.c
ldpc/ldpc_dec_c_avx2long_flood.c
ldpc/ldpc_enc_avx2.c
ldpc/ldpc_enc_avx2long.c
)
endif (HAVE_AVX2)
set(FEC_SOURCES ${FEC_SOURCES} ${AVX2_SOURCES}
ldpc/base_graph.c ldpc/base_graph.c
ldpc/ldpc_dec_f.c ldpc/ldpc_dec_f.c
ldpc/ldpc_dec_s.c ldpc/ldpc_dec_s.c
ldpc/ldpc_dec_c.c ldpc/ldpc_dec_c.c
ldpc/ldpc_dec_c_flood.c ldpc/ldpc_dec_c_flood.c
ldpc/ldpc_dec_c_avx2.c
ldpc/ldpc_dec_c_avx2long.c
ldpc/ldpc_dec_c_avx2_flood.c
ldpc/ldpc_dec_c_avx2long_flood.c
ldpc/ldpc_decoder.c ldpc/ldpc_decoder.c
ldpc/ldpc_enc_c.c ldpc/ldpc_enc_c.c
ldpc/ldpc_enc_avx2.c
ldpc/ldpc_enc_avx2long.c
ldpc/ldpc_encoder.c ldpc/ldpc_encoder.c
ldpc/ldpc_rm.c ldpc/ldpc_rm.c
PARENT_SCOPE) PARENT_SCOPE)

@ -278,11 +278,11 @@ int update_ldpc_check_to_var_c_avx2(void* p,
__m256i this_abs_v2c_epi8; __m256i this_abs_v2c_epi8;
__m256i minp_v2c_epi8 = _mm256_set1_epi8(INT8_MAX); __m256i minp_v2c_epi8 = _mm256_set1_epi8(INT8_MAX);
__m256i mins_v2c_epi8 = _mm256_set1_epi8(INT8_MAX); __m256i mins_v2c_epi8 = _mm256_set1_epi8(INT8_MAX);
__m256i prod_v2c_epi8 = _mm256_set1_epi8(0); __m256i prod_v2c_epi8 = _mm256_setzero_si256();
__m256i mask_sign_epi8; __m256i mask_sign_epi8;
__m256i mask_min_epi8; __m256i mask_min_epi8;
__m256i help_min_epi8; __m256i help_min_epi8;
__m256i min_ix_epi8; __m256i min_ix_epi8 = _mm256_setzero_si256();
__m256i current_ix_epi8; __m256i current_ix_epi8;
int8_t current_var_index = (*these_var_indices)[0]; int8_t current_var_index = (*these_var_indices)[0];

@ -293,11 +293,11 @@ int update_ldpc_check_to_var_c_avx2_flood(void* p,
__m256i this_abs_v2c_epi8; __m256i this_abs_v2c_epi8;
__m256i minp_v2c_epi8 = _mm256_set1_epi8(INT8_MAX); __m256i minp_v2c_epi8 = _mm256_set1_epi8(INT8_MAX);
__m256i mins_v2c_epi8 = _mm256_set1_epi8(INT8_MAX); __m256i mins_v2c_epi8 = _mm256_set1_epi8(INT8_MAX);
__m256i prod_v2c_epi8 = _mm256_set1_epi8(0); __m256i prod_v2c_epi8 = _mm256_setzero_si256();
__m256i mask_sign_epi8; __m256i mask_sign_epi8;
__m256i mask_min_epi8; __m256i mask_min_epi8;
__m256i help_min_epi8; __m256i help_min_epi8;
__m256i min_ix_epi8; __m256i min_ix_epi8 = _mm256_setzero_si256();
__m256i current_ix_epi8; __m256i current_ix_epi8;
int8_t current_var_index = (*these_var_indices)[0]; int8_t current_var_index = (*these_var_indices)[0];

@ -380,11 +380,16 @@ void srslte_ldpc_encoder_free(srslte_ldpc_encoder_t* q)
bzero(q, sizeof(srslte_ldpc_encoder_t)); bzero(q, sizeof(srslte_ldpc_encoder_t));
} }
int srslte_ldpc_encoder_encode(srslte_ldpc_encoder_t* q, int srslte_ldpc_encoder_encode(srslte_ldpc_encoder_t* q, const uint8_t* input, uint8_t* output, uint32_t input_length)
const uint8_t* input, {
uint8_t* output, return q->encode(q, input, output, input_length, q->liftN - 2 * q->ls);
uint32_t input_length, }
uint32_t cdwd_rm_length)
int srslte_ldpc_encoder_encode_rm(srslte_ldpc_encoder_t* q,
const uint8_t* input,
uint8_t* output,
uint32_t input_length,
uint32_t cdwd_rm_length)
{ {
return q->encode(q, input, output, input_length, cdwd_rm_length); return q->encode(q, input, output, input_length, cdwd_rm_length);
} }

@ -190,4 +190,4 @@ set(test_name LDPC-RM-BG1)
set(test_command ldpc_rm_test) set(test_command ldpc_rm_test)
ldpc_rm_unit_tests(${lifting_sizes}) ldpc_rm_unit_tests(${lifting_sizes})
add_test(NAME LDPC-RM-chain COMMAND ldpc_rm_chain_test) add_test(NAME LDPC-RM-chain COMMAND ldpc_rm_chain_test -E 1 -B 1)

@ -44,6 +44,9 @@
* - **-l \<number\>** Lifting Size (according to 5GNR standard. Default 2). * - **-l \<number\>** Lifting Size (according to 5GNR standard. Default 2).
* - **-e \<number\>** Codeword length after rate matching (set to 0 [default] for full rate). * - **-e \<number\>** Codeword length after rate matching (set to 0 [default] for full rate).
* - **-s \<number\>** SNR in dB (Default 3 dB). * - **-s \<number\>** SNR in dB (Default 3 dB).
* - **-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).
*/ */
#include <math.h> #include <math.h>
@ -60,29 +63,31 @@
#include "srslte/phy/utils/random.h" #include "srslte/phy/utils/random.h"
#include "srslte/phy/utils/vector.h" #include "srslte/phy/utils/vector.h"
srslte_basegraph_t base_graph = BG1; /*!< \brief Base Graph (BG1 or BG2). */ static srslte_basegraph_t base_graph = BG1; /*!< \brief Base Graph (BG1 or BG2). */
int lift_size = 2; /*!< \brief Lifting Size. */ static int lift_size = 2; /*!< \brief Lifting Size. */
int rm_length = 0; /*!< \brief Codeword length after rate matching. */ static int rm_length = 0; /*!< \brief Codeword length after rate matching. */
int finalK; /*!< \brief Number of uncoded bits (message length). */ static int finalK; /*!< \brief Number of uncoded bits (message length). */
int finalN; /*!< \brief Number of coded bits (codeword length). */ static int finalN; /*!< \brief Number of coded bits (codeword length). */
float snr = 0; /*!< \brief Signal-to-Noise Ratio [dB]. */ static float snr = 0; /*!< \brief Signal-to-Noise Ratio [dB]. */
#define BATCH_SIZE 100 /*!< \brief Number of codewords in a batch. */ static int batch_size = 100; /*!< \brief Number of codewords in a batch. */
#define MAX_N_BATCH 10000 /*!< \brief Max number of simulated batches. */ static int max_n_batch = 10000; /*!< \brief Max number of simulated batches. */
#define REQ_ERRORS 100 /*!< \brief Minimum number of errors for a significant simulation. */ static int req_errors = 100; /*!< \brief Minimum number of errors for a significant simulation. */
#define MS_SF 0.75f /*!< \brief Scaling factor for the normalized min-sum decoding algorithm. */ #define MS_SF 0.75f /*!< \brief Scaling factor for the normalized min-sum decoding algorithm. */
/*! /*!
* \brief Prints test help when wrong parameter is passed as input. * \brief Prints test help when wrong parameter is passed as input.
*/ */
void usage(char* prog) void usage(char* prog)
{ {
printf("Usage: %s [-bX] [-lX] [-eX] [-sX]\n", prog); printf("Usage: %s [-bX] [-lX] [-eX] [-sX] [-BX]\n", prog);
printf("\t-b Base Graph [(1 or 2) Default %d]\n", base_graph + 1); 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-l Lifting Size [Default %d]\n", lift_size);
printf("\t-e Word length after rate matching [Default %d (no rate matching, only filler-bits are extracted)]\n", printf("\t-e Word length after rate matching [Default %d (no rate matching, only filler-bits are extracted)]\n",
rm_length); rm_length);
printf("\t-s SNR [dB, Default %.1f dB]\n", snr); 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);
} }
/*! /*!
@ -91,7 +96,7 @@ void usage(char* prog)
void parse_args(int argc, char** argv) void parse_args(int argc, char** argv)
{ {
int opt = 0; int opt = 0;
while ((opt = getopt(argc, argv, "b:l:e:s:")) != -1) { while ((opt = getopt(argc, argv, "b:l:e:s:B:N:E:")) != -1) {
switch (opt) { switch (opt) {
case 'b': case 'b':
base_graph = (int)strtol(optarg, NULL, 10) - 1; base_graph = (int)strtol(optarg, NULL, 10) - 1;
@ -103,7 +108,16 @@ void parse_args(int argc, char** argv)
rm_length = (int)strtol(optarg, NULL, 10); rm_length = (int)strtol(optarg, NULL, 10);
break; break;
case 's': case 's':
snr = strtod(optarg, NULL); snr = (float)strtod(optarg, NULL);
break;
case 'B':
batch_size = (int)strtol(optarg, NULL, 10);
break;
case 'N':
max_n_batch = (int)strtol(optarg, NULL, 10);
break;
case 'E':
req_errors = (int)strtol(optarg, NULL, 10);
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
@ -224,18 +238,18 @@ int main(int argc, char** argv)
finalK = encoder.liftK; finalK = encoder.liftK;
finalN = encoder.liftN - 2 * lift_size; finalN = encoder.liftN - 2 * lift_size;
messages_true = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_true = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_f = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_f = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_s = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_s = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_c = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_c = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_c_flood = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_c_flood = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_avx = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_avx = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_avx_flood = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_avx_flood = malloc(finalK * batch_size * sizeof(uint8_t));
codewords = malloc(finalN * BATCH_SIZE * sizeof(uint8_t)); codewords = malloc(finalN * batch_size * sizeof(uint8_t));
symbols_rm = malloc((rm_length + F) * BATCH_SIZE * sizeof(float)); symbols_rm = malloc((rm_length + F) * batch_size * sizeof(float));
symbols = malloc(finalN * BATCH_SIZE * sizeof(float)); symbols = malloc(finalN * batch_size * sizeof(float));
symbols_s = malloc(finalN * BATCH_SIZE * sizeof(int16_t)); symbols_s = malloc(finalN * batch_size * sizeof(int16_t));
symbols_c = malloc(finalN * BATCH_SIZE * sizeof(int8_t)); symbols_c = malloc(finalN * batch_size * sizeof(int8_t));
if (!messages_true || !messages_sim_f || !messages_sim_s || !messages_sim_c || // if (!messages_true || !messages_sim_f || !messages_sim_s || !messages_sim_c || //
!messages_sim_avx || !messages_sim_c_flood || !messages_sim_avx_flood || // !messages_sim_avx || !messages_sim_c_flood || !messages_sim_avx_flood || //
!codewords || !symbols || !symbols_s || !symbols_c) { !codewords || !symbols || !symbols_s || !symbols_c) {
@ -273,8 +287,8 @@ int main(int argc, char** argv)
printf("\nBatch:\n "); printf("\nBatch:\n ");
while (((n_error_words_f < REQ_ERRORS) || (n_error_words_s < REQ_ERRORS) || (n_error_words_c < REQ_ERRORS)) && while (((n_error_words_f < req_errors) || (n_error_words_s < req_errors) || (n_error_words_c < req_errors)) &&
(i_batch < MAX_N_BATCH)) { (i_batch < max_n_batch)) {
i_batch++; i_batch++;
if (!(i_batch % 10)) { if (!(i_batch % 10)) {
@ -286,7 +300,7 @@ int main(int argc, char** argv)
/* generate data_tx */ /* generate data_tx */
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK - F; j++) { for (j = 0; j < finalK - F; j++) {
messages_true[i * finalK + j] = srslte_random_uniform_int_dist(random_gen, 0, 1); messages_true[i * finalK + j] = srslte_random_uniform_int_dist(random_gen, 0, 1);
} }
@ -305,8 +319,8 @@ int main(int argc, char** argv)
// Encode messages // Encode messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_encoder_encode( srslte_ldpc_encoder_encode_rm(
&encoder, messages_true + j * finalK, codewords + j * finalN, finalK, n_useful_symbols); &encoder, messages_true + j * finalK, codewords + j * finalN, finalK, n_useful_symbols);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
@ -314,7 +328,7 @@ int main(int argc, char** argv)
elapsed_time_enc += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_enc += t[0].tv_sec + 1e-6 * t[0].tv_usec;
// Modulate codewords and match rate (puncturing) // Modulate codewords and match rate (puncturing)
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < rm_length + F; j++) { for (j = 0; j < rm_length + F; j++) {
symbols_rm[i * (rm_length + F) + j] = symbols_rm[i * (rm_length + F) + j] =
(codewords[i * finalN + j] == FILLER_BIT) ? INFINITY : 1 - 2 * codewords[i * finalN + j]; (codewords[i * finalN + j] == FILLER_BIT) ? INFINITY : 1 - 2 * codewords[i * finalN + j];
@ -322,11 +336,11 @@ int main(int argc, char** argv)
} }
// Apply AWGN // Apply AWGN
srslte_ch_awgn_f(symbols_rm, symbols_rm, noise_std_dev, BATCH_SIZE * (rm_length + F)); srslte_ch_awgn_f(symbols_rm, symbols_rm, noise_std_dev, batch_size * (rm_length + F));
// Convert symbols into LLRs // Convert symbols into LLRs
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < rm_length + F; j++) { //+F becouse we have alredy considered fillerbits when modulating. for (j = 0; j < rm_length + F; j++) { //+F because we have already considered fillerbits when modulating.
symbols[i * finalN + j] = symbols_rm[i * (rm_length + F) + j] * 2 / (noise_std_dev * noise_std_dev); symbols[i * finalN + j] = symbols_rm[i * (rm_length + F) + j] * 2 / (noise_std_dev * noise_std_dev);
} }
// the rest of symbols are undetermined, set LLR to 0 // the rest of symbols are undetermined, set LLR to 0
@ -338,14 +352,14 @@ int main(int argc, char** argv)
//////// Floating point //////// Floating point
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_f(&decoder_f, symbols + j * finalN, messages_sim_f + j * finalK, n_useful_symbols); srslte_ldpc_decoder_decode_f(&decoder_f, symbols + j * finalN, messages_sim_f + j * finalK, n_useful_symbols);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_f += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_f += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_f[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_f[i_bit] != (1U & messages_true[i_bit])) {
@ -357,18 +371,18 @@ int main(int argc, char** argv)
//////// Fixed point - 16 bit //////// Fixed point - 16 bit
// Quantize LLRs with 16 bits // Quantize LLRs with 16 bits
srslte_vec_quant_fs(symbols, symbols_s, gain_s, 0, inf15, BATCH_SIZE * finalN); srslte_vec_quant_fs(symbols, symbols_s, gain_s, 0, inf15, batch_size * finalN);
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_s(&decoder_s, symbols_s + j * finalN, messages_sim_s + j * finalK, n_useful_symbols); srslte_ldpc_decoder_decode_s(&decoder_s, symbols_s + j * finalN, messages_sim_s + j * finalK, n_useful_symbols);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_s += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_s += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_s[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_s[i_bit] != (1U & messages_true[i_bit])) {
@ -380,18 +394,18 @@ int main(int argc, char** argv)
//////// Fixed point - 8 bit //////// Fixed point - 8 bit
// Quantize LLRs with 8 bits // Quantize LLRs with 8 bits
srslte_vec_quant_fc(symbols, symbols_c, gain_c, 0, inf7, BATCH_SIZE * finalN); srslte_vec_quant_fc(symbols, symbols_c, gain_c, 0, inf7, batch_size * finalN);
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_c(&decoder_c, symbols_c + j * finalN, messages_sim_c + j * finalK, n_useful_symbols); srslte_ldpc_decoder_decode_c(&decoder_c, symbols_c + j * finalN, messages_sim_c + j * finalK, n_useful_symbols);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_c += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_c += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_c[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_c[i_bit] != (1U & messages_true[i_bit])) {
@ -405,7 +419,7 @@ int main(int argc, char** argv)
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_c( srslte_ldpc_decoder_decode_c(
&decoder_c_flood, symbols_c + j * finalN, messages_sim_c_flood + j * finalK, n_useful_symbols); &decoder_c_flood, symbols_c + j * finalN, messages_sim_c_flood + j * finalK, n_useful_symbols);
} }
@ -413,7 +427,7 @@ int main(int argc, char** argv)
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_c_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_c_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_c_flood[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_c_flood[i_bit] != (1U & messages_true[i_bit])) {
@ -428,7 +442,7 @@ int main(int argc, char** argv)
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_c( srslte_ldpc_decoder_decode_c(
&decoder_avx, symbols_c + j * finalN, messages_sim_avx + j * finalK, n_useful_symbols); &decoder_avx, symbols_c + j * finalN, messages_sim_avx + j * finalK, n_useful_symbols);
} }
@ -436,7 +450,7 @@ int main(int argc, char** argv)
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_avx += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_avx += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_avx[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_avx[i_bit] != (1U & messages_true[i_bit])) {
@ -450,7 +464,7 @@ int main(int argc, char** argv)
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_c( srslte_ldpc_decoder_decode_c(
&decoder_avx_flood, symbols_c + j * finalN, messages_sim_avx_flood + j * finalK, n_useful_symbols); &decoder_avx_flood, symbols_c + j * finalN, messages_sim_avx_flood + j * finalK, n_useful_symbols);
} }
@ -458,7 +472,7 @@ int main(int argc, char** argv)
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_avx_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_avx_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_avx_flood[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_avx_flood[i_bit] != (1U & messages_true[i_bit])) {
@ -471,9 +485,9 @@ int main(int argc, char** argv)
} }
printf("\nEstimated throughput encoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", printf("\nEstimated throughput encoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n",
i_batch * BATCH_SIZE / elapsed_time_enc, i_batch * batch_size / elapsed_time_enc,
i_batch * BATCH_SIZE * finalK / elapsed_time_enc, i_batch * batch_size * finalK / elapsed_time_enc,
i_batch * BATCH_SIZE * finalN / elapsed_time_enc); i_batch * batch_size * finalN / elapsed_time_enc);
print_decoder("FLOATING POINT", i_batch, n_error_words_f, elapsed_time_dec_f); print_decoder("FLOATING POINT", i_batch, n_error_words_f, elapsed_time_dec_f);
print_decoder("FIXED POINT (16 bits)", i_batch, n_error_words_s, elapsed_time_dec_s); print_decoder("FIXED POINT (16 bits)", i_batch, n_error_words_s, elapsed_time_dec_s);
@ -500,7 +514,9 @@ int main(int argc, char** argv)
free(symbols_s); free(symbols_s);
free(symbols); free(symbols);
free(codewords); free(codewords);
free(symbols_rm);
free(messages_sim_avx); free(messages_sim_avx);
free(messages_sim_avx_flood);
free(messages_sim_c_flood); free(messages_sim_c_flood);
free(messages_sim_c); free(messages_sim_c);
free(messages_sim_s); free(messages_sim_s);
@ -509,6 +525,7 @@ int main(int argc, char** argv)
srslte_random_free(random_gen); srslte_random_free(random_gen);
#ifdef LV_HAVE_AVX2 #ifdef LV_HAVE_AVX2
srslte_ldpc_decoder_free(&decoder_avx); srslte_ldpc_decoder_free(&decoder_avx);
srslte_ldpc_decoder_free(&decoder_avx_flood);
#endif // LV_HAVE_AVX2 #endif // LV_HAVE_AVX2
srslte_ldpc_decoder_free(&decoder_c_flood); srslte_ldpc_decoder_free(&decoder_c_flood);
srslte_ldpc_decoder_free(&decoder_c); srslte_ldpc_decoder_free(&decoder_c);
@ -520,10 +537,10 @@ int main(int argc, char** argv)
void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time) void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time)
{ {
printf("\n**** %s ****", title); printf("\n**** %s ****", title);
printf("\nEstimated word error rate:\n %e (%d errors)\n", (double)n_errors / n_batches / BATCH_SIZE, n_errors); printf("\nEstimated word error rate:\n %e (%d errors)\n", (double)n_errors / n_batches / batch_size, n_errors);
printf("Estimated throughput decoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", printf("Estimated throughput decoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n",
n_batches * BATCH_SIZE / elapsed_time, n_batches * batch_size / elapsed_time,
n_batches * BATCH_SIZE * finalK / elapsed_time, n_batches * batch_size * finalK / elapsed_time,
n_batches * BATCH_SIZE * finalN / elapsed_time); n_batches * batch_size * finalN / elapsed_time);
} }

@ -32,6 +32,7 @@
* Options: * Options:
* - **-b \<number\>** Base Graph (1 or 2. Default 1). * - **-b \<number\>** Base Graph (1 or 2. Default 1).
* - **-l \<number\>** Lifting Size (according to 5GNR standard. Default 2). * - **-l \<number\>** Lifting Size (according to 5GNR standard. Default 2).
* - **-R \<number\>** Number of times tests are repeated (for computing throughput).
*/ */
#include <stdio.h> #include <stdio.h>
@ -48,8 +49,8 @@ int lift_size = 2; /*!< \brief Lifting Size. */
int finalK; /*!< \brief Number of uncoded bits (message length). */ int finalK; /*!< \brief Number of uncoded bits (message length). */
int finalN; /*!< \brief Number of coded bits (codeword length). */ int finalN; /*!< \brief Number of coded bits (codeword length). */
#define NOF_MESSAGES 10 /*!< \brief Number of codewords in the test. */ #define NOF_MESSAGES 10 /*!< \brief Number of codewords in the test. */
#define NOF_REPS 1000 /*!< \brief Number of times tests are repeated (for computing throughput). */ static int nof_reps = 1; /*!< \brief Number of times tests are repeated (for computing throughput). */
/*! /*!
* \brief Prints test help when a wrong parameter is passed as input. * \brief Prints test help when a wrong parameter is passed as input.
@ -59,6 +60,7 @@ void usage(char* prog)
printf("Usage: %s [-bX] [-lX]\n", prog); printf("Usage: %s [-bX] [-lX]\n", prog);
printf("\t-b Base Graph [(1 or 2) Default %d]\n", base_graph + 1); 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-l Lifting Size [Default %d]\n", lift_size);
printf("\t-R Number of times tests are repeated (for computing throughput). [Default %d]\n", lift_size);
} }
/*! /*!
@ -67,7 +69,7 @@ void usage(char* prog)
void parse_args(int argc, char** argv) void parse_args(int argc, char** argv)
{ {
int opt = 0; int opt = 0;
while ((opt = getopt(argc, argv, "b:l:")) != -1) { while ((opt = getopt(argc, argv, "b:l:R:")) != -1) {
switch (opt) { switch (opt) {
case 'b': case 'b':
base_graph = (int)strtol(optarg, NULL, 10) - 1; base_graph = (int)strtol(optarg, NULL, 10) - 1;
@ -75,6 +77,9 @@ void parse_args(int argc, char** argv)
case 'l': case 'l':
lift_size = (int)strtol(optarg, NULL, 10); lift_size = (int)strtol(optarg, NULL, 10);
break; break;
case 'R':
nof_reps = (int)strtol(optarg, NULL, 10);
break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(-1); exit(-1);
@ -195,14 +200,14 @@ int main(int argc, char** argv)
for (j = 0; j < NOF_MESSAGES; j++) { for (j = 0; j < NOF_MESSAGES; j++) {
printf(" codeword %d\n", j); printf(" codeword %d\n", j);
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (l = 0; l < NOF_REPS; l++) { for (l = 0; l < nof_reps; l++) {
srslte_ldpc_encoder_encode(&encoder, messages + j * finalK, codewords_sim + j * finalN, finalK, finalN); srslte_ldpc_encoder_encode_rm(&encoder, messages + j * finalK, codewords_sim + j * finalN, finalK, finalN);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time += t[0].tv_sec + 1e-6 * t[0].tv_usec;
} }
printf("Elapsed time: %e s\n", elapsed_time / NOF_REPS); printf("Elapsed time: %e s\n", elapsed_time / nof_reps);
printf("\nVerifing results...\n"); printf("\nVerifing results...\n");
for (i = 0; i < NOF_MESSAGES * finalN; i++) { for (i = 0; i < NOF_MESSAGES * finalN; i++) {
@ -213,9 +218,9 @@ int main(int argc, char** argv)
} }
printf("Estimated throughput:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", printf("Estimated throughput:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n",
NOF_MESSAGES / (elapsed_time / NOF_REPS), NOF_MESSAGES / (elapsed_time / nof_reps),
NOF_MESSAGES * finalK / (elapsed_time / NOF_REPS), NOF_MESSAGES * finalK / (elapsed_time / nof_reps),
NOF_MESSAGES * finalN / (elapsed_time / NOF_REPS)); NOF_MESSAGES * finalN / (elapsed_time / nof_reps));
printf("\nTest completed successfully!\n\n"); printf("\nTest completed successfully!\n\n");

@ -32,6 +32,7 @@
* Options: * Options:
* - **-b \<number\>** Base Graph (1 or 2. Default 1). * - **-b \<number\>** Base Graph (1 or 2. Default 1).
* - **-l \<number\>** Lifting Size (according to 5GNR standard. Default 2). * - **-l \<number\>** Lifting Size (according to 5GNR standard. Default 2).
* - **-R \<number\>** Number of times tests are repeated (for computing throughput).
*/ */
#include <stdio.h> #include <stdio.h>
@ -43,13 +44,13 @@
#include "srslte/phy/fec/ldpc/ldpc_encoder.h" #include "srslte/phy/fec/ldpc/ldpc_encoder.h"
#include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/debug.h"
srslte_basegraph_t base_graph = BG1; /*!< \brief Base Graph (BG1 or BG2). */ static srslte_basegraph_t base_graph = BG1; /*!< \brief Base Graph (BG1 or BG2). */
int lift_size = 2; /*!< \brief Lifting Size. */ static int lift_size = 2; /*!< \brief Lifting Size. */
int finalK; /*!< \brief Number of uncoded bits (message length). */ static int finalK; /*!< \brief Number of uncoded bits (message length). */
int finalN; /*!< \brief Number of coded bits (codeword length). */ static int finalN; /*!< \brief Number of coded bits (codeword length). */
#define NOF_MESSAGES 10 /*!< \brief Number of codewords in the test. */ #define NOF_MESSAGES 10 /*!< \brief Number of codewords in the test. */
#define NOF_REPS 1000 /*!< \brief Number of times tests are repeated (for computing throughput). */ static int nof_reps = 1; /*!< \brief Number of times tests are repeated (for computing throughput). */
/*! /*!
* \brief Prints test help when a wrong parameter is passed as input. * \brief Prints test help when a wrong parameter is passed as input.
@ -59,6 +60,7 @@ void usage(char* prog)
printf("Usage: %s [-bX] [-lX]\n", prog); printf("Usage: %s [-bX] [-lX]\n", prog);
printf("\t-b Base Graph [(1 or 2) Default %d]\n", base_graph + 1); 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-l Lifting Size [Default %d]\n", lift_size);
printf("\t-R Number of times tests are repeated (for computing throughput). [Default %d]\n", lift_size);
} }
/*! /*!
@ -67,7 +69,7 @@ void usage(char* prog)
void parse_args(int argc, char** argv) void parse_args(int argc, char** argv)
{ {
int opt = 0; int opt = 0;
while ((opt = getopt(argc, argv, "b:l:")) != -1) { while ((opt = getopt(argc, argv, "b:l:R:")) != -1) {
switch (opt) { switch (opt) {
case 'b': case 'b':
base_graph = (int)strtol(optarg, NULL, 10) - 1; base_graph = (int)strtol(optarg, NULL, 10) - 1;
@ -75,6 +77,9 @@ void parse_args(int argc, char** argv)
case 'l': case 'l':
lift_size = (int)strtol(optarg, NULL, 10); lift_size = (int)strtol(optarg, NULL, 10);
break; break;
case 'R':
nof_reps = (int)strtol(optarg, NULL, 10);
break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(-1); exit(-1);
@ -195,14 +200,14 @@ int main(int argc, char** argv)
for (j = 0; j < NOF_MESSAGES; j++) { for (j = 0; j < NOF_MESSAGES; j++) {
printf(" codeword %d\n", j); printf(" codeword %d\n", j);
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (l = 0; l < NOF_REPS; l++) { for (l = 0; l < nof_reps; l++) {
srslte_ldpc_encoder_encode(&encoder, messages + j * finalK, codewords_sim + j * finalN, finalK, finalN); srslte_ldpc_encoder_encode_rm(&encoder, messages + j * finalK, codewords_sim + j * finalN, finalK, finalN);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time += t[0].tv_sec + 1e-6 * t[0].tv_usec;
} }
printf("Elapsed time: %e s\n", elapsed_time / NOF_REPS); printf("Elapsed time: %e s\n", elapsed_time / nof_reps);
printf("\nVerifing results...\n"); printf("\nVerifing results...\n");
for (i = 0; i < NOF_MESSAGES * finalN; i++) { for (i = 0; i < NOF_MESSAGES * finalN; i++) {
@ -213,9 +218,9 @@ int main(int argc, char** argv)
} }
printf("Estimated throughput:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", printf("Estimated throughput:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n",
NOF_MESSAGES / (elapsed_time / NOF_REPS), NOF_MESSAGES / (elapsed_time / nof_reps),
NOF_MESSAGES * finalK / (elapsed_time / NOF_REPS), NOF_MESSAGES * finalK / (elapsed_time / nof_reps),
NOF_MESSAGES * finalN / (elapsed_time / NOF_REPS)); NOF_MESSAGES * finalN / (elapsed_time / nof_reps));
printf("\nTest completed successfully!\n\n"); printf("\nTest completed successfully!\n\n");

@ -41,9 +41,11 @@
* - **-m \<number\>** Modulation type BPSK = 0, QPSK =1, QAM16 = 2, QAM64 = 3, QAM256 = 4. * - **-m \<number\>** Modulation type BPSK = 0, QPSK =1, QAM16 = 2, QAM64 = 3, QAM256 = 4.
* - **-M \<number\>** Limited buffer size. * - **-M \<number\>** Limited buffer size.
* - **-s \<number\>** SNR in dB(Default 3 dB). * - **-s \<number\>** SNR in dB(Default 3 dB).
* - **-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).
*/ */
#include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -58,23 +60,22 @@
#include "srslte/phy/utils/random.h" #include "srslte/phy/utils/random.h"
#include "srslte/phy/utils/vector.h" #include "srslte/phy/utils/vector.h"
srslte_basegraph_t base_graph = BG1; /*!< \brief Base Graph (BG1 or BG2). */ static srslte_basegraph_t base_graph = BG1; /*!< \brief Base Graph (BG1 or BG2). */
uint32_t lift_size = 2; /*!< \brief Lifting Size. */ static uint32_t lift_size = 2; /*!< \brief Lifting Size. */
uint32_t rm_length = 0; /*!< \brief Codeword length after rate matching. */ static uint32_t rm_length = 0; /*!< \brief Codeword length after rate matching. */
uint32_t F = 22 - 5; /*!< \brief Number of filler bits in each CBS. */ static uint32_t F = 22 - 5; /*!< \brief Number of filler bits in each CBS. */
uint32_t E = 14000; /*!< \brief Rate-matched Codeword size. */ static uint8_t rv = 0; /*!< \brief Redundancy version {0-3}. */
uint8_t rv = 0; /*!< \brief Redundancy version {0-3}. */ static mod_type_t mod_type = BPSK; /*!< \brief Modulation type: BPSK, QPSK, QAM16, QAM64, QAM256 = 4 */
mod_type_t mod_type = BPSK; /*!< \brief Modulation type: BPSK, QPSK, QAM16, QAM64, QAM256 = 4 */ static uint32_t Nref = 0; /*!< \brief Limited buffer size. */
uint32_t Nref = 0; /*!< \brief Limited buffer size. */ static float snr = 0; /*!< \brief Signal-to-Noise Ratio [dB]. */
float snr = 0; /*!< \brief Signal-to-Noise Ratio [dB]. */
int finalK = 0; /*!< \brief Number of uncoded bits (message length, including punctured and filler bits). */ static int finalK = 0; /*!< \brief Number of uncoded bits (message length, including punctured and filler bits). */
int finalN = 0; /*!< \brief Number of coded bits (codeword length). */ static int finalN = 0; /*!< \brief Number of coded bits (codeword length). */
#define BATCH_SIZE 100 /*!< \brief Number of codewords in a batch. */ static int batch_size = 100; /*!< \brief Number of codewords in a batch. */
#define MAX_N_BATCH 10000 /*!< \brief Max number of simulated batches. */ static int max_n_batch = 10000; /*!< \brief Max number of simulated batches. */
#define REQ_ERRORS 100 /*!< \brief Minimum number of errors for a significant simulation. */ static int req_errors = 100; /*!< \brief Minimum number of errors for a significant simulation. */
#define MS_SF 0.75f /*!< \brief Scaling factor for the normalized min-sum decoding algorithm. */ #define MS_SF 0.75f /*!< \brief Scaling factor for the normalized min-sum decoding algorithm. */
/*! /*!
* \brief Prints test help when wrong parameter is passed as input. * \brief Prints test help when wrong parameter is passed as input.
@ -91,6 +92,9 @@ void usage(char* prog)
printf("\t-m Modulation_type BPSK=0, QPSK=1, 16QAM=2, 64QAM=3, 256QAM = 4 [Default %d]\n", mod_type); printf("\t-m Modulation_type BPSK=0, QPSK=1, 16QAM=2, 64QAM=3, 256QAM = 4 [Default %d]\n", mod_type);
printf("\t-M Limited buffer size (Nref) [Default = %d (normal buffer Nref = N)]\n", Nref); printf("\t-M Limited buffer size (Nref) [Default = %d (normal buffer Nref = N)]\n", Nref);
printf("\t-s SNR [dB, Default %.1f dB]\n", snr); printf("\t-s SNR [dB, Default %.1f dB]\n", snr);
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);
} }
/*! /*!
@ -99,7 +103,7 @@ void usage(char* prog)
void parse_args(int argc, char** argv) void parse_args(int argc, char** argv)
{ {
int opt = 0; int opt = 0;
while ((opt = getopt(argc, argv, "b:l:e:f:r:m:M:s:")) != -1) { while ((opt = getopt(argc, argv, "b:l:e:f:r:m:M:s:B:N:E:")) != -1) {
switch (opt) { switch (opt) {
case 'b': case 'b':
base_graph = (int)strtol(optarg, NULL, 10) - 1; base_graph = (int)strtol(optarg, NULL, 10) - 1;
@ -123,7 +127,16 @@ void parse_args(int argc, char** argv)
Nref = (uint32_t)strtol(optarg, NULL, 10); Nref = (uint32_t)strtol(optarg, NULL, 10);
break; break;
case 's': case 's':
snr = strtod(optarg, NULL); snr = (float)strtod(optarg, NULL);
break;
case 'B':
batch_size = (int)strtol(optarg, NULL, 10);
break;
case 'N':
max_n_batch = (int)strtol(optarg, NULL, 10);
break;
case 'E':
req_errors = (int)strtol(optarg, NULL, 10);
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
@ -282,22 +295,22 @@ int main(int argc, char** argv)
1.0 * (encoder.liftK - F) / rm_length); 1.0 * (encoder.liftK - F) / rm_length);
printf("\n Signal-to-Noise Ratio -> %.2f dB\n", snr); printf("\n Signal-to-Noise Ratio -> %.2f dB\n", snr);
messages_true = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_true = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_f = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_f = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_s = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_s = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_c = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_c = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_c_flood = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_c_flood = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_avx = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_avx = malloc(finalK * batch_size * sizeof(uint8_t));
messages_sim_avx_flood = malloc(finalK * BATCH_SIZE * sizeof(uint8_t)); messages_sim_avx_flood = malloc(finalK * batch_size * sizeof(uint8_t));
codewords = malloc(finalN * BATCH_SIZE * sizeof(uint8_t)); codewords = malloc(finalN * batch_size * sizeof(uint8_t));
rm_codewords = malloc(rm_length * BATCH_SIZE * sizeof(uint8_t)); rm_codewords = malloc(rm_length * batch_size * sizeof(uint8_t));
rm_symbols = malloc(rm_length * BATCH_SIZE * sizeof(float)); rm_symbols = malloc(rm_length * batch_size * sizeof(float));
rm_symbols_s = malloc(rm_length * BATCH_SIZE * sizeof(uint16_t)); rm_symbols_s = malloc(rm_length * batch_size * sizeof(uint16_t));
rm_symbols_c = malloc(rm_length * BATCH_SIZE * sizeof(uint8_t)); rm_symbols_c = malloc(rm_length * batch_size * sizeof(uint8_t));
symbols = malloc(finalN * BATCH_SIZE * sizeof(float)); symbols = malloc(finalN * batch_size * sizeof(float));
symbols_s = malloc(finalN * BATCH_SIZE * sizeof(int16_t)); symbols_s = malloc(finalN * batch_size * sizeof(int16_t));
symbols_c = malloc(finalN * BATCH_SIZE * sizeof(int8_t)); symbols_c = malloc(finalN * batch_size * sizeof(int8_t));
if (!messages_true || !messages_sim_f || !messages_sim_s || !messages_sim_c || // if (!messages_true || !messages_sim_f || !messages_sim_s || !messages_sim_c || //
!messages_sim_avx || !messages_sim_c_flood || !messages_sim_avx_flood || // !messages_sim_avx || !messages_sim_c_flood || !messages_sim_avx_flood || //
!codewords || !rm_codewords || !rm_symbols || !rm_symbols_s || !rm_symbols_c || !symbols || !symbols_s || !codewords || !rm_codewords || !rm_symbols || !rm_symbols_s || !rm_symbols_c || !symbols || !symbols_s ||
@ -336,8 +349,8 @@ int main(int argc, char** argv)
printf("\nBatch:\n "); printf("\nBatch:\n ");
while (((n_error_words_f < REQ_ERRORS) || (n_error_words_s < REQ_ERRORS) || (n_error_words_c < REQ_ERRORS)) && while (((n_error_words_f < req_errors) || (n_error_words_s < req_errors) || (n_error_words_c < req_errors)) &&
(i_batch < MAX_N_BATCH)) { (i_batch < max_n_batch)) {
i_batch++; i_batch++;
if (!(i_batch % 10)) { if (!(i_batch % 10)) {
@ -348,7 +361,7 @@ int main(int argc, char** argv)
} }
/* generate data_tx */ /* generate data_tx */
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK - F; j++) { for (j = 0; j < finalK - F; j++) {
messages_true[i * finalK + j] = srslte_random_uniform_int_dist(random_gen, 0, 1); messages_true[i * finalK + j] = srslte_random_uniform_int_dist(random_gen, 0, 1);
} }
@ -357,21 +370,16 @@ int main(int argc, char** argv)
} }
} }
// lDPC Encoding
// compute the number of symbols that we need to encode/decode: at least (E + F) if E+F < N,
unsigned int n_useful_symbols = (E + F);
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_encoder_encode( srslte_ldpc_encoder_encode(&encoder, messages_true + j * finalK, codewords + j * finalN, finalK);
&encoder, messages_true + j * finalK, codewords + j * finalN, finalK, n_useful_symbols);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_enc += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_enc += t[0].tv_sec + 1e-6 * t[0].tv_usec;
// rate matching // rate matching
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_rm_tx(&rm_tx, srslte_ldpc_rm_tx(&rm_tx,
codewords + j * finalN, codewords + j * finalN,
rm_codewords + j * rm_length, rm_codewords + j * rm_length,
@ -383,23 +391,23 @@ int main(int argc, char** argv)
Nref); Nref);
} }
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < rm_length; j++) { for (j = 0; j < rm_length; j++) {
rm_symbols[i * rm_length + j] = 1 - 2 * rm_codewords[i * rm_length + j]; rm_symbols[i * rm_length + j] = 1 - 2 * rm_codewords[i * rm_length + j];
} }
} }
// Apply AWGN // Apply AWGN
srslte_ch_awgn_f(rm_symbols, rm_symbols, noise_std_dev, BATCH_SIZE * rm_length); srslte_ch_awgn_f(rm_symbols, rm_symbols, noise_std_dev, batch_size * rm_length);
// Convert symbols into LLRs // Convert symbols into LLRs
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < rm_length; j++) { for (j = 0; j < rm_length; j++) {
rm_symbols[i * rm_length + j] = rm_symbols[i * rm_length + j] * 2 / (noise_std_dev * noise_std_dev); rm_symbols[i * rm_length + j] = rm_symbols[i * rm_length + j] * 2 / (noise_std_dev * noise_std_dev);
} }
} }
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
if (srslte_ldpc_rm_rx_f(&rm_rx, if (srslte_ldpc_rm_rx_f(&rm_rx,
rm_symbols + i * rm_length, rm_symbols + i * rm_length,
symbols + i * finalN, symbols + i * finalN,
@ -417,14 +425,14 @@ int main(int argc, char** argv)
//////// Floating point //////// Floating point
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_f(&decoder_f, symbols + j * finalN, messages_sim_f + j * finalK, n_useful_symbols); srslte_ldpc_decoder_decode_f(&decoder_f, symbols + j * finalN, messages_sim_f + j * finalK, finalN);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_f += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_f += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_f[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_f[i_bit] != (1U & messages_true[i_bit])) {
@ -437,10 +445,10 @@ int main(int argc, char** argv)
//////// Fixed point - 16 bit //////// Fixed point - 16 bit
// Quantize LLRs with 16 bits // Quantize LLRs with 16 bits
srslte_vec_quant_fs(rm_symbols, rm_symbols_s, gain_s, 0, inf15, BATCH_SIZE * rm_length); srslte_vec_quant_fs(rm_symbols, rm_symbols_s, gain_s, 0, inf15, batch_size * rm_length);
// Rate dematcher // Rate dematcher
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
if (srslte_ldpc_rm_rx_s(&rm_rx_s, if (srslte_ldpc_rm_rx_s(&rm_rx_s,
rm_symbols_s + i * rm_length, rm_symbols_s + i * rm_length,
symbols_s + i * finalN, symbols_s + i * finalN,
@ -457,14 +465,14 @@ int main(int argc, char** argv)
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_s(&decoder_s, symbols_s + j * finalN, messages_sim_s + j * finalK, n_useful_symbols); srslte_ldpc_decoder_decode_s(&decoder_s, symbols_s + j * finalN, messages_sim_s + j * finalK, finalN);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_s += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_s += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_s[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_s[i_bit] != (1U & messages_true[i_bit])) {
@ -476,10 +484,10 @@ int main(int argc, char** argv)
//////// Fixed point - 8 bit //////// Fixed point - 8 bit
// Quantize LLRs with 8 bits // Quantize LLRs with 8 bits
srslte_vec_quant_fc(rm_symbols, rm_symbols_c, gain_c, 0, inf7, BATCH_SIZE * rm_length); srslte_vec_quant_fc(rm_symbols, rm_symbols_c, gain_c, 0, inf7, batch_size * rm_length);
// Rate dematcher // Rate dematcher
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
if (srslte_ldpc_rm_rx_c(&rm_rx_c, if (srslte_ldpc_rm_rx_c(&rm_rx_c,
rm_symbols_c + i * rm_length, rm_symbols_c + i * rm_length,
symbols_c + i * finalN, symbols_c + i * finalN,
@ -496,14 +504,14 @@ int main(int argc, char** argv)
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_c(&decoder_c, symbols_c + j * finalN, messages_sim_c + j * finalK, n_useful_symbols); srslte_ldpc_decoder_decode_c(&decoder_c, symbols_c + j * finalN, messages_sim_c + j * finalK, finalN);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_c += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_c += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_c[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_c[i_bit] != (1U & messages_true[i_bit])) {
@ -517,15 +525,14 @@ int main(int argc, char** argv)
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_c( srslte_ldpc_decoder_decode_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);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_c_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_c_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_c_flood[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_c_flood[i_bit] != (1U & messages_true[i_bit])) {
@ -540,15 +547,14 @@ int main(int argc, char** argv)
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_c( srslte_ldpc_decoder_decode_c(&decoder_avx, symbols_c + j * finalN, messages_sim_avx + j * finalK, finalN);
&decoder_avx, symbols_c + j * finalN, messages_sim_avx + j * finalK, n_useful_symbols);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_avx += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_avx += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_avx[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_avx[i_bit] != (1U & messages_true[i_bit])) {
@ -562,15 +568,15 @@ int main(int argc, char** argv)
// Recover messages // Recover messages
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (j = 0; j < BATCH_SIZE; j++) { for (j = 0; j < batch_size; j++) {
srslte_ldpc_decoder_decode_c( srslte_ldpc_decoder_decode_c(
&decoder_avx_flood, symbols_c + j * finalN, messages_sim_avx_flood + j * finalK, n_useful_symbols); &decoder_avx_flood, symbols_c + j * finalN, messages_sim_avx_flood + j * finalK, finalN);
} }
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
elapsed_time_dec_avx_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec; elapsed_time_dec_avx_flood += t[0].tv_sec + 1e-6 * t[0].tv_usec;
for (i = 0; i < BATCH_SIZE; i++) { for (i = 0; i < batch_size; i++) {
for (j = 0; j < finalK; j++) { for (j = 0; j < finalK; j++) {
i_bit = i * finalK + j; i_bit = i * finalK + j;
if (messages_sim_avx_flood[i_bit] != (1U & messages_true[i_bit])) { if (messages_sim_avx_flood[i_bit] != (1U & messages_true[i_bit])) {
@ -583,9 +589,9 @@ int main(int argc, char** argv)
} }
printf("\nEstimated throughput encoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", printf("\nEstimated throughput encoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n",
i_batch * BATCH_SIZE / elapsed_time_enc, i_batch * batch_size / elapsed_time_enc,
i_batch * BATCH_SIZE * finalK / elapsed_time_enc, i_batch * batch_size * finalK / elapsed_time_enc,
i_batch * BATCH_SIZE * finalN / elapsed_time_enc); i_batch * batch_size * finalN / elapsed_time_enc);
print_decoder("FLOATING POINT", i_batch, n_error_words_f, elapsed_time_dec_f); print_decoder("FLOATING POINT", i_batch, n_error_words_f, elapsed_time_dec_f);
print_decoder("FIXED POINT (16 bits)", i_batch, n_error_words_s, elapsed_time_dec_s); print_decoder("FIXED POINT (16 bits)", i_batch, n_error_words_s, elapsed_time_dec_s);
@ -617,6 +623,7 @@ int main(int argc, char** argv)
free(rm_codewords); free(rm_codewords);
free(codewords); free(codewords);
free(messages_sim_avx); free(messages_sim_avx);
free(messages_sim_avx_flood);
free(messages_sim_c_flood); free(messages_sim_c_flood);
free(messages_sim_c); free(messages_sim_c);
free(messages_sim_s); free(messages_sim_s);
@ -625,6 +632,7 @@ int main(int argc, char** argv)
srslte_random_free(random_gen); srslte_random_free(random_gen);
#ifdef LV_HAVE_AVX2 #ifdef LV_HAVE_AVX2
srslte_ldpc_decoder_free(&decoder_avx); srslte_ldpc_decoder_free(&decoder_avx);
srslte_ldpc_decoder_free(&decoder_avx_flood);
#endif // LV_HAVE_AVX2 #endif // LV_HAVE_AVX2
srslte_ldpc_decoder_free(&decoder_c_flood); srslte_ldpc_decoder_free(&decoder_c_flood);
srslte_ldpc_decoder_free(&decoder_c); srslte_ldpc_decoder_free(&decoder_c);
@ -640,10 +648,10 @@ int main(int argc, char** argv)
void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time) void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time)
{ {
printf("\n**** %s ****", title); printf("\n**** %s ****", title);
printf("\nEstimated word error rate:\n %e (%d errors)\n", (double)n_errors / n_batches / BATCH_SIZE, n_errors); printf("\nEstimated word error rate:\n %e (%d errors)\n", (double)n_errors / n_batches / batch_size, n_errors);
printf("Estimated throughput decoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n", printf("Estimated throughput decoder:\n %e word/s\n %e bit/s (information)\n %e bit/s (encoded)\n",
n_batches * BATCH_SIZE / elapsed_time, n_batches * batch_size / elapsed_time,
n_batches * BATCH_SIZE * finalK / elapsed_time, n_batches * batch_size * finalK / elapsed_time,
n_batches * BATCH_SIZE * finalN / elapsed_time); n_batches * batch_size * finalN / elapsed_time);
} }

@ -51,18 +51,19 @@
#include "srslte/phy/fec/ldpc/ldpc_rm.h" #include "srslte/phy/fec/ldpc/ldpc_rm.h"
#include "srslte/phy/utils/debug.h" #include "srslte/phy/utils/debug.h"
#include "srslte/phy/utils/random.h" #include "srslte/phy/utils/random.h"
#include "srslte/phy/utils/vector.h"
srslte_basegraph_t base_graph = BG2; /*!< \brief Base Graph (BG1 or BG2). */ static srslte_basegraph_t base_graph = BG2; /*!< \brief Base Graph (BG1 or BG2). */
uint32_t lift_size = 208; /*!< \brief Lifting Size. */ static uint32_t lift_size = 208; /*!< \brief Lifting Size. */
uint32_t C = 2; /*!< \brief Number of code block segments (CBS). */ static uint32_t C = 2; /*!< \brief Number of code block segments (CBS). */
uint32_t F = 10; /*!< \brief Number of filler bits in each CBS. */ static uint32_t F = 10; /*!< \brief Number of filler bits in each CBS. */
uint32_t E = 0; /*!< \brief Rate-matched codeword size (E = 0, no rate matching). */ static uint32_t E = 0; /*!< \brief Rate-matched codeword size (E = 0, no rate matching). */
uint8_t rv = 0; /*!< \brief Redundancy version {0-3}. */ static uint8_t rv = 0; /*!< \brief Redundancy version {0-3}. */
mod_type_t mod_type = QPSK; /*!< \brief Modulation type: BPSK, QPSK, QAM16, QAM64, QAM256. */ static mod_type_t mod_type = QPSK; /*!< \brief Modulation type: BPSK, QPSK, QAM16, QAM64, QAM256. */
uint32_t Nref = 0; /*!< \brief Limited buffer size.*/ static uint32_t Nref = 0; /*!< \brief Limited buffer size.*/
uint32_t N = 0; /*!< \brief Codeblock size (including punctured and filler bits). */ static uint32_t N = 0; /*!< \brief Codeblock size (including punctured and filler bits). */
uint32_t K = 0; /*!< \brief Codeword size. */ static uint32_t K = 0; /*!< \brief Codeword size. */
/*! /*!
* \brief Prints test help when a wrong parameter is passed as input. * \brief Prints test help when a wrong parameter is passed as input.
@ -218,7 +219,6 @@ int main(int argc, char** argv)
// Generate random bits // Generate random bits
for (r = 0; r < C; r++) { for (r = 0; r < C; r++) {
for (i = 0; i < K - F; i++) { for (i = 0; i < K - F; i++) {
// codeblock_seg[i] = rand() % 2;
codeblocks[r * K + i] = srslte_random_uniform_int_dist(random_gen, 0, 1); codeblocks[r * K + i] = srslte_random_uniform_int_dist(random_gen, 0, 1);
} }
for (; i < K; i++) { // add filler bits for (; i < K; i++) { // add filler bits
@ -226,14 +226,10 @@ int main(int argc, char** argv)
} }
} }
// lDPC Encoding
// compute the number of symbols that we need to encode/decode: at least (E + F) if E+F < N,
unsigned int n_useful_symbols = (E + F);
// Encode messages // Encode messages
// gettimeofday(&t[1], NULL); // gettimeofday(&t[1], NULL);
for (r = 0; r < C; r++) { for (r = 0; r < C; r++) {
if (srslte_ldpc_encoder_encode(&encoder, codeblocks + r * K, codewords + r * N, K, n_useful_symbols)) { if (srslte_ldpc_encoder_encode(&encoder, codeblocks + r * K, codewords + r * N, K)) {
exit(-1); exit(-1);
} }

@ -1,21 +1,40 @@
# #
# Project: 5GCoding-SRS # Copyright 2013-2020 Software Radio Systems Limited
# Author: Jesus Gomez (CTTC)
# Copyright: Software Radio Systems Limited
# #
# This file is part of srsLTE
#
# srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# srsLTE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# A copy of the GNU Affero General Public License can be found in
# the LICENSE file in the top-level directory of this distribution
# and at http://www.gnu.org/licenses/.
#
if (HAVE_AVX2)
set(AVX2_SOURCES
polar/polar_encoder_avx2.c
polar/polar_decoder_ssc_c_avx2.c
polar/polar_decoder_vector_avx2.c
)
endif (HAVE_AVX2)
set(FEC_SOURCES ${FEC_SOURCES} set(FEC_SOURCES ${FEC_SOURCES} ${AVX2_SOURCES}
polar/polar_encoder.c polar/polar_encoder.c
polar/polar_encoder_pipelined.c polar/polar_encoder_pipelined.c
polar/polar_encoder_avx2.c
polar/polar_decoder.c polar/polar_decoder.c
polar/polar_decoder_ssc_all.c polar/polar_decoder_ssc_all.c
polar/polar_decoder_ssc_f.c polar/polar_decoder_ssc_f.c
polar/polar_decoder_ssc_s.c polar/polar_decoder_ssc_s.c
polar/polar_decoder_ssc_c.c polar/polar_decoder_ssc_c.c
polar/polar_decoder_ssc_c_avx2.c
polar/polar_decoder_vector.c polar/polar_decoder_vector.c
polar/polar_decoder_vector_avx2.c
PARENT_SCOPE) PARENT_SCOPE)
add_subdirectory(test) add_subdirectory(test)

@ -35,6 +35,7 @@
#include "../utils_avx2.h" #include "../utils_avx2.h"
#include "polar_decoder_vector_avx2.h" #include "polar_decoder_vector_avx2.h"
#include "srslte/phy/fec/polar/polar_encoder.h" #include "srslte/phy/fec/polar/polar_encoder.h"
#include "srslte/phy/utils/vector.h"
#ifdef LV_HAVE_AVX2 #ifdef LV_HAVE_AVX2
@ -148,7 +149,8 @@ void* create_polar_decoder_ssc_c_avx2(uint16_t* frozen_set, const uint8_t code_s
return NULL; return NULL;
} }
if ((pp->param->code_stage_size = malloc((code_size_log + 1) * sizeof(uint16_t))) == NULL) { printf("-- code_stage_size=%d;\n", code_size_log + 1);
if ((pp->param->code_stage_size = srslte_vec_u16_malloc(code_size_log + 1)) == NULL) {
free(pp->param); free(pp->param);
free(pp->enc); free(pp->enc);
free(pp); free(pp);
@ -315,7 +317,10 @@ static void simplified_node(struct pSSC_c_avx2* p)
uint8_t* estbits1 = NULL; uint8_t* estbits1 = NULL;
uint16_t stage_size = pp->param->code_stage_size[stage]; uint16_t stage_size = pp->param->code_stage_size[stage];
uint16_t stage_half_size = pp->param->code_stage_size[stage - 1]; uint16_t stage_half_size = 0;
if (stage > 0) {
stage_half_size = pp->param->code_stage_size[stage - 1];
}
switch (pp->param->node_type[stage][bit_pos]) { switch (pp->param->node_type[stage][bit_pos]) {

@ -1,7 +1,21 @@
# #
# Project: 5GCoding-SRS # Copyright 2013-2020 Software Radio Systems Limited
# Author: Jesus Gomez (CTTC) #
# Copyright: Software Radio Systems Limited # This file is part of srsLTE
#
# srsLTE is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# srsLTE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# A copy of the GNU Affero General Public License can be found in
# the LICENSE file in the top-level directory of this distribution
# and at http://www.gnu.org/licenses/.
# #
add_library(polar_test_utils polar_sets.c subchannel_allocation.c) add_library(polar_test_utils polar_sets.c subchannel_allocation.c)

@ -714,6 +714,7 @@ int main(int argc, char** argv)
free(data_rx); free(data_rx);
free(data_rx_s); free(data_rx_s);
free(data_rx_c); free(data_rx_c);
free(data_rx_c_avx2);
free(input_enc); free(input_enc);
free(output_enc); free(output_enc);
@ -722,10 +723,12 @@ int main(int argc, char** argv)
free(llr); free(llr);
free(llr_s); free(llr_s);
free(llr_c); free(llr_c);
free(llr_c_avx2);
free(output_dec); free(output_dec);
free(output_dec_s); free(output_dec_s);
free(output_dec_c); free(output_dec_c);
free(output_dec_c_avx2);
#ifdef DATA_ALL_ONES #ifdef DATA_ALL_ONES
#else #else

Loading…
Cancel
Save