WIP: Fix Coverity issues in PHY lib (#3507)

Fix several Coverity issues

This commit adrresses the following code issues found by Coverity:

CID 339785 Division by zero, in fading_channel_test.c
CID 355272 Division by zero, in awgn_channel_test.c
CID 355277 NULL ptr dereference, in awgn_channel_test.c
CID 359663 NULL ptr dereference, in delay_channel_test.c
CID 369544 NULL ptr dereference, in chest_dl_nbiot.c
CID 373326 Resource Leak, in dft_fftw.c
CID 373329 Resource Leak, in dft_fftw.c
CID 372878 Division by zero, in sliv_test.c
CID 372871 Division by zero, in dmrs_pdcch.c
CID 370622 Negative loop bound, in csr_rs.c
CID 370624 Negative loop bound, in csr_rs.c
CID 370626 Negative loop bound, in csr_rs.c
CID's 369568, 369594 NULL ptr dereference, in ch_awgn.c
CID 369540 Logically dead code, in refsignal_dl.c
CID 369608 Logically dead code, in refsignal_ul.c
CIDs 366291, 366296, 366297 Out-of-bounds access, in zc_sequence.c
CID 372209 Division by zero, in cqi.c
CID 370992 Uninitialized pointer read, in pdcch_test.c
CID 373334 Integer overflow, in ue_sync.h
CID 370993, 370995 Undefined division, in pdcch_test.c
CID 370994 Undefined division, in ssb_decode_test.c
CIDs 353368 353364 353365 359673 353366 353367
Explicit null dereferenced, in psss_file_test.c
CID 371865 Unchecked return value, in rf_uhd_imp.cc
CID 363810 Undefined division, in ldpc_rm_chain_test.c
CID 372209, 372211, 372213, 372216 Undefined modulo, in cqi.c
CID 339834 Array compared against 0, in chest_dl.c
CID 369589 Out of bounds access, in dmrs_pucch.c
CID 371681 Out of bounds access, in ue_sync_nr_test.c
CIDs 370761, 370825 Copy-paste error, in ssb.c
CID 369599 out of bounds read, in dmrs_pdcch_test.c
CID 363795 out of bounds read, in ldpc_dec_c_avx2_flood.c
CID 363805 out of bounds read, in ldpc_dec_c_avx2long_flood.c
CID 363821 out of bounds read, in ldpc_dec_c_flood.c
master
Joaquim 3 years ago committed by GitHub
parent bdbaf7357a
commit 93649429dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -967,12 +967,8 @@ static void fill_res(srsran_chest_dl_t* q, srsran_chest_dl_res_t* res)
for (uint32_t port_id = 0; port_id < q->cell.nof_ports; port_id++) { for (uint32_t port_id = 0; port_id < q->cell.nof_ports; port_id++) {
res->rsrp_port_dbm[port_id] = srsran_convert_power_to_dBm(get_rsrp_port(q, port_id)); res->rsrp_port_dbm[port_id] = srsran_convert_power_to_dBm(get_rsrp_port(q, port_id));
for (uint32_t a = 0; a < q->nof_rx_antennas; a++) { for (uint32_t a = 0; a < q->nof_rx_antennas; a++) {
if (q->noise_estimate[a]) {
res->snr_ant_port_db[a][port_id] = res->snr_ant_port_db[a][port_id] =
srsran_convert_power_to_dB(q->rsrp[a][port_id] / q->noise_estimate[a][port_id]); srsran_convert_power_to_dB(q->rsrp[a][port_id] / q->noise_estimate[a][port_id]);
} else {
res->snr_ant_port_db[a][port_id] = 0.0f;
}
res->rsrp_ant_port_dbm[a][port_id] = srsran_convert_power_to_dBm(q->rsrp[a][port_id]); res->rsrp_ant_port_dbm[a][port_id] = srsran_convert_power_to_dBm(q->rsrp[a][port_id]);
res->rsrq_ant_port_db[a][port_id] = res->rsrq_ant_port_db[a][port_id] =
srsran_convert_power_to_dB(q->cell.nof_prb * q->rsrp[a][port_id] / q->rssi[a][port_id]); srsran_convert_power_to_dB(q->cell.nof_prb * q->rsrp[a][port_id] / q->rssi[a][port_id]);

@ -80,7 +80,7 @@ int srsran_chest_dl_nbiot_init(srsran_chest_dl_nbiot_t* q, uint32_t max_prb)
} }
clean_exit: clean_exit:
if (ret != SRSRAN_SUCCESS) { if (ret != SRSRAN_SUCCESS && q != NULL) {
srsran_chest_dl_nbiot_free(q); srsran_chest_dl_nbiot_free(q);
} }
return ret; return ret;

@ -760,6 +760,8 @@ int srsran_csi_rs_nzp_measure_trs(const srsran_carrier_nr_t* carrier,
// Perform Measurements // Perform Measurements
csi_rs_nzp_resource_measure_t measurements[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_PER_SET]; csi_rs_nzp_resource_measure_t measurements[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_PER_SET];
int ret = csi_rs_nzp_measure_set(carrier, slot_cfg, set, grid, measurements); int ret = csi_rs_nzp_measure_set(carrier, slot_cfg, set, grid, measurements);
// Return to prevent assigning negative values to count
if (ret < SRSRAN_SUCCESS) { if (ret < SRSRAN_SUCCESS) {
ERROR("Error performing measurements"); ERROR("Error performing measurements");
return SRSRAN_ERROR; return SRSRAN_ERROR;
@ -856,6 +858,8 @@ int srsran_csi_rs_nzp_measure_channel(const srsran_carrier_nr_t* carrier
// Perform Measurements // Perform Measurements
csi_rs_nzp_resource_measure_t measurements[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_PER_SET]; csi_rs_nzp_resource_measure_t measurements[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_PER_SET];
int ret = csi_rs_nzp_measure_set(carrier, slot_cfg, set, grid, measurements); int ret = csi_rs_nzp_measure_set(carrier, slot_cfg, set, grid, measurements);
// Return to prevent assigning negative values to count
if (ret < SRSRAN_SUCCESS) { if (ret < SRSRAN_SUCCESS) {
ERROR("Error performing measurements"); ERROR("Error performing measurements");
return SRSRAN_ERROR; return SRSRAN_ERROR;
@ -1032,8 +1036,11 @@ int srsran_csi_rs_zp_measure_channel(const srsran_carrier_nr_t* carrier,
// Perform Measurements // Perform Measurements
csi_rs_zp_resource_measure_t measurements[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_PER_SET]; csi_rs_zp_resource_measure_t measurements[SRSRAN_PHCH_CFG_MAX_NOF_CSI_RS_PER_SET];
int ret = csi_rs_zp_measure_set(carrier, slot_cfg, set, grid, measurements); int ret = csi_rs_zp_measure_set(carrier, slot_cfg, set, grid, measurements);
// Return to prevent assigning negative values to count
if (ret < SRSRAN_SUCCESS) { if (ret < SRSRAN_SUCCESS) {
ERROR("Error performing measurements"); ERROR("Error performing measurements");
return SRSRAN_ERROR;
} }
uint32_t count = (uint32_t)ret; uint32_t count = (uint32_t)ret;

@ -454,6 +454,11 @@ int srsran_dmrs_pdcch_get_measure(const srsran_dmrs_pdcch_estimator_t* q,
srsran_vec_apply_cfo(tmp, tmp_sync_err, tmp, nof_pilots); srsran_vec_apply_cfo(tmp, tmp_sync_err, tmp, nof_pilots);
#endif // DMRS_PDCCH_SYNC_PRECOMPENSATE_MEAS #endif // DMRS_PDCCH_SYNC_PRECOMPENSATE_MEAS
// Prevent undefined division
if (!nof_pilots) {
ERROR("Error in DMRS correlation. nof_pilots cannot be zero");
return SRSRAN_ERROR;
}
// Correlate DMRS // Correlate DMRS
corr[l] = srsran_vec_acc_cc(tmp, nof_pilots) / (float)nof_pilots; corr[l] = srsran_vec_acc_cc(tmp, nof_pilots) / (float)nof_pilots;

@ -14,6 +14,7 @@
#include "srsran/phy/common/sequence.h" #include "srsran/phy/common/sequence.h"
#include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/debug.h"
#include "srsran/phy/utils/vector.h" #include "srsran/phy/utils/vector.h"
#include <assert.h>
#include <complex.h> #include <complex.h>
// Implements TS 38.211 table 6.4.1.3.1.1-1: Number of DM-RS symbols and the corresponding N_PUCCH... // Implements TS 38.211 table 6.4.1.3.1.1-1: Number of DM-RS symbols and the corresponding N_PUCCH...
@ -183,6 +184,10 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q,
} }
cf_t ce[SRSRAN_PUCCH_NR_FORMAT1_N_MAX][SRSRAN_NRE]; cf_t ce[SRSRAN_PUCCH_NR_FORMAT1_N_MAX][SRSRAN_NRE];
// Prevent ce[m] overflow
assert(n_pucch <= SRSRAN_PUCCH_NR_FORMAT1_N_MAX);
uint32_t l_prime = resource->start_symbol_idx; uint32_t l_prime = resource->start_symbol_idx;
for (uint32_t m = 0; m < n_pucch; m++) { for (uint32_t m = 0; m < n_pucch; m++) {
// Clause 6.4.1.3.1.2 specifies l=0,2,4... // Clause 6.4.1.3.1.2 specifies l=0,2,4...
@ -213,6 +218,7 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q,
cf_t z[SRSRAN_NRE]; cf_t z[SRSRAN_NRE];
srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE); srsran_vec_sc_prod_ccc(r_uv, w_i_m, z, SRSRAN_NRE);
// TODO: can ce[m] overflow?
// Calculate least square estimates for this symbol // Calculate least square estimates for this symbol
srsran_vec_prod_conj_ccc(slot_symbols_ptr, z, ce[m], SRSRAN_NRE); srsran_vec_prod_conj_ccc(slot_symbols_ptr, z, ce[m], SRSRAN_NRE);
} }

@ -27,7 +27,6 @@
*/ */
int srsran_refsignal_cs_init(srsran_refsignal_t* q, uint32_t max_prb) int srsran_refsignal_cs_init(srsran_refsignal_t* q, uint32_t max_prb)
{ {
int ret = SRSRAN_ERROR_INVALID_INPUTS; int ret = SRSRAN_ERROR_INVALID_INPUTS;
if (q != NULL) { if (q != NULL) {
@ -56,7 +55,6 @@ free_and_exit:
*/ */
int srsran_refsignal_cs_set_cell(srsran_refsignal_t* q, srsran_cell_t cell) int srsran_refsignal_cs_set_cell(srsran_refsignal_t* q, srsran_cell_t cell)
{ {
uint32_t c_init; uint32_t c_init;
uint32_t N_cp, mp; uint32_t N_cp, mp;
srsran_sequence_t seq; srsran_sequence_t seq;
@ -347,7 +345,6 @@ uint32_t srsran_refsignal_mbsfn_nof_symbols()
inline uint32_t srsran_refsignal_mbsfn_fidx(uint32_t l) inline uint32_t srsran_refsignal_mbsfn_fidx(uint32_t l)
{ {
uint32_t ret = 0; uint32_t ret = 0;
if (l == 0) { if (l == 0) {
ret = 0; ret = 0;
@ -447,21 +444,21 @@ free_and_exit:
int srsran_refsignal_mbsfn_set_cell(srsran_refsignal_t* q, srsran_cell_t cell, uint16_t mbsfn_area_id) int srsran_refsignal_mbsfn_set_cell(srsran_refsignal_t* q, srsran_cell_t cell, uint16_t mbsfn_area_id)
{ {
int ret = SRSRAN_SUCCESS;
int ret = SRSRAN_ERROR_INVALID_INPUTS; if (q == NULL) {
q->cell = cell; ret = SRSRAN_ERROR_INVALID_INPUTS;
goto exit;
}
q->cell = cell;
q->mbsfn_area_id = mbsfn_area_id; q->mbsfn_area_id = mbsfn_area_id;
if (srsran_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id)) { if (srsran_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id) < SRSRAN_SUCCESS) {
goto free_and_exit; ret = SRSRAN_ERROR;
goto exit;
} }
ret = SRSRAN_SUCCESS; exit:
free_and_exit:
if (ret == SRSRAN_ERROR) {
srsran_refsignal_free(q);
}
return ret; return ret;
} }

@ -724,14 +724,14 @@ int srsran_refsignal_srs_send_cs(uint32_t subframe_config, uint32_t sf_idx)
} else { } else {
return 1; return 1;
} }
} else if (subframe_config == 14) { }
// subframe_config == 14
else {
if (((sf_idx % tsfc) == 7) || ((sf_idx % tsfc) == 9)) { if (((sf_idx % tsfc) == 7) || ((sf_idx % tsfc) == 9)) {
return 0; return 0;
} else { } else {
return 1; return 1;
} }
} else {
return 0;
} }
} else { } else {
return SRSRAN_ERROR_INVALID_INPUTS; return SRSRAN_ERROR_INVALID_INPUTS;

@ -78,6 +78,9 @@ static int run_test(srsran_dmrs_pdcch_estimator_t* estimator,
TESTASSERT(nof_locations == search_space->nof_candidates[aggregation_level]); TESTASSERT(nof_locations == search_space->nof_candidates[aggregation_level]);
// Prevent possible out of bounds read in locations
TESTASSERT(nof_locations <= SRSRAN_SEARCH_SPACE_MAX_NOF_CANDIDATES_NR);
for (uint32_t candidate = 0; candidate < nof_locations; candidate++) { for (uint32_t candidate = 0; candidate < nof_locations; candidate++) {
dci_location.ncce = locations[candidate]; dci_location.ncce = locations[candidate];

@ -70,6 +70,7 @@ int srsran_channel_awgn_init(srsran_channel_awgn_t* q, uint32_t seed)
q->table_log = srsran_vec_f_malloc(AWGN_TABLE_ALLOC_SIZE); q->table_log = srsran_vec_f_malloc(AWGN_TABLE_ALLOC_SIZE);
if (!q->table_cos || !q->table_log) { if (!q->table_cos || !q->table_log) {
ERROR("Malloc"); ERROR("Malloc");
return SRSRAN_ERROR;
} }
// Fill tables // Fill tables

@ -40,7 +40,7 @@ static void usage(char* prog)
printf("\t-t tolerance: [Default %.3f]\n", tolerance); printf("\t-t tolerance: [Default %.3f]\n", tolerance);
} }
static void parse_args(int argc, char** argv) static int parse_args(int argc, char** argv)
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "nmMst")) != -1) { while ((opt = getopt(argc, argv, "nmMst")) != -1) {
@ -62,9 +62,10 @@ static void parse_args(int argc, char** argv)
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(-1); return SRSRAN_ERROR;
} }
} }
return SRSRAN_SUCCESS;
} }
int main(int argc, char** argv) int main(int argc, char** argv)
@ -75,8 +76,15 @@ int main(int argc, char** argv)
uint64_t count_samples = 0; uint64_t count_samples = 0;
uint64_t count_us = 0; uint64_t count_us = 0;
#ifdef ENABLE_GUI
cf_t* fft_out = NULL;
#endif
// Parse arguments // Parse arguments
parse_args(argc, argv); if (parse_args(argc, argv) < SRSRAN_SUCCESS) {
ret = SRSRAN_ERROR;
goto clean_exit;
}
// Initialise buffers // Initialise buffers
input_buffer = srsran_vec_cf_malloc(nof_samples); input_buffer = srsran_vec_cf_malloc(nof_samples);
@ -85,6 +93,7 @@ int main(int argc, char** argv)
if (!input_buffer || !output_buffer) { if (!input_buffer || !output_buffer) {
ERROR("Error: Allocating memory"); ERROR("Error: Allocating memory");
ret = SRSRAN_ERROR; ret = SRSRAN_ERROR;
goto clean_exit;
} }
// Initialise input // Initialise input
@ -104,24 +113,31 @@ int main(int argc, char** argv)
plot_scatter_setTitle(&plot_fft, "IQ"); plot_scatter_setTitle(&plot_fft, "IQ");
plot_scatter_addToWindowGrid(&plot_fft, (char*)"IQ", 1, 0); plot_scatter_addToWindowGrid(&plot_fft, (char*)"IQ", 1, 0);
cf_t* fft_out = srsran_vec_cf_malloc(nof_samples); fft_out = srsran_vec_cf_malloc(nof_samples);
srsran_dft_plan_t fft = {}; srsran_dft_plan_t fft = {};
if (srsran_dft_plan_c(&fft, nof_samples, SRSRAN_DFT_FORWARD)) { if (srsran_dft_plan_c(&fft, nof_samples, SRSRAN_DFT_FORWARD)) {
ERROR("Error: init DFT"); ERROR("Error: init DFT");
ret = SRSRAN_ERROR; ret = SRSRAN_ERROR;
goto clean_exit;
} }
#endif /* ENABLE_GUI */ #endif /* ENABLE_GUI */
// Initialise AWGN channel // Initialise AWGN channel
if (ret == SRSRAN_SUCCESS) { if (srsran_channel_awgn_init(&awgn, 0) < SRSRAN_SUCCESS) {
ret = srsran_channel_awgn_init(&awgn, 0); ERROR("Error initialising AWGN channel");
ret = SRSRAN_ERROR;
goto clean_exit;
} }
float n0 = n0_min; float n0 = n0_min;
while (!isnan(n0) && !isinf(n0) && n0 < n0_max) { while (!isnan(n0) && !isinf(n0) && n0 < n0_max) {
struct timeval t[3] = {}; struct timeval t[3] = {};
srsran_channel_awgn_set_n0(&awgn, n0); if (srsran_channel_awgn_set_n0(&awgn, n0) < SRSRAN_SUCCESS) {
ERROR("Error setting AWGN n0");
ret = SRSRAN_ERROR;
goto clean_exit;
}
// Run actual test // Run actual test
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
@ -166,13 +182,28 @@ int main(int argc, char** argv)
n0 += n0_step; n0 += n0_step;
} }
// Free // Print result and exit
double msps = 0;
if (count_us) {
msps = (double)nof_samples / (double)count_us;
} else {
ERROR("Error in Msps calculation: undefined division");
ret = SRSRAN_ERROR;
}
printf("Test n0_min=%.3f; n0_max=%.3f; n0_step=%.3f; nof_samples=%d; %s ... %.1f MSps\n",
n0_min,
n0_max,
n0_step,
nof_samples,
(ret == SRSRAN_SUCCESS) ? "Passed" : "Failed",
msps);
clean_exit:
srsran_channel_awgn_free(&awgn); srsran_channel_awgn_free(&awgn);
if (input_buffer) { if (input_buffer) {
free(input_buffer); free(input_buffer);
} }
if (output_buffer) { if (output_buffer) {
free(output_buffer); free(output_buffer);
} }
@ -184,13 +215,5 @@ int main(int argc, char** argv)
srsran_dft_plan_free(&fft); srsran_dft_plan_free(&fft);
#endif /* ENABLE_GUI */ #endif /* ENABLE_GUI */
// Print result and exit
printf("Test n0_min=%.3f; n0_max=%.3f; n0_step=%.3f; nof_samples=%d; %s ... %.1f MSps\n",
n0_min,
n0_max,
n0_step,
nof_samples,
(ret == SRSRAN_SUCCESS) ? "Passed" : "Failed",
(double)nof_samples / (double)count_us);
return ret; return ret;
} }

@ -37,7 +37,7 @@ static void usage(char* prog)
printf("\t-T Simulation Time in periods: [Default %d]\n", sim_time_periods); printf("\t-T Simulation Time in periods: [Default %d]\n", sim_time_periods);
} }
static void parse_args(int argc, char** argv) static int parse_args(int argc, char** argv)
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "mMtsT")) != -1) { while ((opt = getopt(argc, argv, "mMtsT")) != -1) {
@ -59,14 +59,15 @@ static void parse_args(int argc, char** argv)
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(-1); return SRSRAN_ERROR;
} }
} }
return SRSRAN_SUCCESS;
} }
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int ret = SRSRAN_SUCCESS; int ret = SRSRAN_ERROR;
cf_t* input_buffer = NULL; cf_t* input_buffer = NULL;
cf_t* output_buffer = NULL; cf_t* output_buffer = NULL;
srsran_timestamp_t ts = {}; // Initialised to zero srsran_timestamp_t ts = {}; // Initialised to zero
@ -74,28 +75,32 @@ int main(int argc, char** argv)
struct timeval t[3] = {}; struct timeval t[3] = {};
// Parse arguments // Parse arguments
parse_args(argc, argv); if (parse_args(argc, argv) < SRSRAN_SUCCESS) {
goto clean_exit;
}
// Initialise buffers // Initialise buffers
uint32_t size = srate_hz / 1000; uint32_t size = srate_hz / 1000;
input_buffer = srsran_vec_cf_malloc(size); input_buffer = srsran_vec_cf_malloc(size);
output_buffer = srsran_vec_cf_malloc(size); output_buffer = srsran_vec_cf_malloc(size);
if (!input_buffer || !output_buffer) { if (!input_buffer || !output_buffer) {
fprintf(stderr, "Error: Allocating memory\n"); ERROR("Error: Allocating memory");
ret = SRSRAN_ERROR; goto clean_exit;
} }
// Generate random samples // Generate random samples
srsran_random_uniform_complex_dist_vector(random_gen, input_buffer, size, -1.0f, +1.0f); srsran_random_uniform_complex_dist_vector(random_gen, input_buffer, size, -1.0f, +1.0f);
// Initialise delay channel // Initialise delay channel
if (ret == SRSRAN_SUCCESS) { if (srsran_channel_delay_init(&delay, delay_min_us, delay_max_us, delay_period_s, delay_init_time_s, srate_hz) <
ret = srsran_channel_delay_init(&delay, delay_min_us, delay_max_us, delay_period_s, delay_init_time_s, srate_hz); SRSRAN_SUCCESS) {
ERROR("Error initialising delay channel");
goto clean_exit;
} }
// Run actual test // Run actual test
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
for (int i = 0; i < sim_time_periods && ret == SRSRAN_SUCCESS; i++) { for (int i = 0; i < sim_time_periods; i++) {
for (int j = 0; j < 1000 * delay_period_s; j++) { for (int j = 0; j < 1000 * delay_period_s; j++) {
// Run delay channel // Run delay channel
srsran_channel_delay_execute(&delay, input_buffer, output_buffer, size, &ts); srsran_channel_delay_execute(&delay, input_buffer, output_buffer, size, &ts);
@ -107,21 +112,17 @@ int main(int argc, char** argv)
gettimeofday(&t[2], NULL); gettimeofday(&t[2], NULL);
get_time_interval(t); get_time_interval(t);
// Free
srsran_random_free(random_gen);
srsran_channel_delay_free(&delay);
if (input_buffer) {
free(input_buffer);
}
if (output_buffer) {
free(output_buffer);
}
uint64_t nof_samples = sim_time_periods * 1000 * delay_period_s * size; uint64_t nof_samples = sim_time_periods * 1000 * delay_period_s * size;
double elapsed_us = t[0].tv_sec * 1e6 + t[0].tv_usec; double elapsed_us = t[0].tv_sec * 1e6 + t[0].tv_usec;
double msps = 0;
if (isnormal(elapsed_us)) {
msps = (double)nof_samples / elapsed_us;
ret = SRSRAN_SUCCESS;
} else {
ERROR("Error in Msps calculation: undefined division");
}
// Print result and exit // Print result and exit
printf("Test delay_min_us=%d; delay_max_us=%d; delay_period_s=%.1f; srate_hz=%d; periods=%d; %s ... %.1f MSps\n", printf("Test delay_min_us=%d; delay_max_us=%d; delay_period_s=%.1f; srate_hz=%d; periods=%d; %s ... %.1f MSps\n",
delay_min_us, delay_min_us,
@ -130,6 +131,19 @@ int main(int argc, char** argv)
srate_hz, srate_hz,
sim_time_periods, sim_time_periods,
(ret == SRSRAN_SUCCESS) ? "Passed" : "Failed", (ret == SRSRAN_SUCCESS) ? "Passed" : "Failed",
(double)nof_samples / elapsed_us); msps);
exit(ret);
clean_exit:
srsran_random_free(random_gen);
srsran_channel_delay_free(&delay);
if (input_buffer) {
free(input_buffer);
}
if (output_buffer) {
free(output_buffer);
}
return (ret);
} }

@ -49,7 +49,7 @@ static void usage(char* prog)
#endif /* ENABLE_GUI */ #endif /* ENABLE_GUI */
} }
static void parse_args(int argc, char** argv) static int parse_args(int argc, char** argv)
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "mtsrg")) != -1) { while ((opt = getopt(argc, argv, "mtsrg")) != -1) {
@ -73,9 +73,10 @@ static void parse_args(int argc, char** argv)
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(-1); return SRSRAN_ERROR;
} }
} }
return SRSRAN_SUCCESS;
} }
int main(int argc, char** argv) int main(int argc, char** argv)
@ -86,7 +87,16 @@ int main(int argc, char** argv)
struct timeval t[3] = {}; struct timeval t[3] = {};
uint64_t time_usec = 0; uint64_t time_usec = 0;
parse_args(argc, argv); #ifdef ENABLE_GUI
cf_t* fft_buffer = NULL;
float* fft_mag = NULL;
float* imp = NULL;
#endif
// Parse arguments
if (parse_args(argc, argv) < SRSRAN_SUCCESS) {
goto clean_exit;
}
srsran_dft_plan_t ifft; srsran_dft_plan_t ifft;
srsran_dft_plan_c(&ifft, srate / 1000, SRSRAN_DFT_BACKWARD); srsran_dft_plan_c(&ifft, srate / 1000, SRSRAN_DFT_BACKWARD);
@ -97,9 +107,6 @@ int main(int argc, char** argv)
plot_real_t plot_imp = NULL; plot_real_t plot_imp = NULL;
srsran_dft_plan_t fft = {}; srsran_dft_plan_t fft = {};
cf_t* fft_buffer = NULL;
float* fft_mag = NULL;
float* imp = NULL;
if (enable_gui) { if (enable_gui) {
sdrgui_init(); sdrgui_init();
@ -207,15 +214,17 @@ int main(int argc, char** argv)
#endif /* ENABLE_GUI */ #endif /* ENABLE_GUI */
} }
// Print results and exit
double msps = 0;
if (time_usec) {
msps = duration_ms * (srate / 1000.0) / (double)time_usec;
printf("Ok ... %.1f MSps\n", msps);
ret = SRSRAN_SUCCESS; ret = SRSRAN_SUCCESS;
clean_exit:
if (ret) {
printf("Error\n");
} else { } else {
printf("Ok ... %.1f MSps\n", duration_ms * (srate / 1000.0) / (double)time_usec); printf("Error in Msps calculation: undefined division\n");
} }
clean_exit:
srsran_dft_plan_free(&ifft); srsran_dft_plan_free(&ifft);
#ifdef ENABLE_GUI #ifdef ENABLE_GUI

@ -11,6 +11,7 @@
*/ */
#include "srsran/common/test_common.h" #include "srsran/common/test_common.h"
#include "srsran/phy/common/sliv.h" #include "srsran/phy/common/sliv.h"
#include <srsran/phy/utils/debug.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -38,34 +39,52 @@ static int test()
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int ret = SRSRAN_ERROR;
// Parse N // Parse N
if (argc >= 2) { if (argc >= 2) {
N = (uint32_t)strtol(argv[1], NULL, 10); N = (uint32_t)strtol(argv[1], NULL, 10);
} }
// No input arguments are provided
if (argc <= 1) {
ERROR("Error: too few arguments");
}
// If two arguments, run brute force test // If two arguments, run brute force test
if (argc == 2) { else if (argc == 2) {
return test(); ret = test();
} }
// if three arguments, calculate start and length from sliv // if three arguments, calculate start and length from sliv
if (argc == 3) { else if (argc == 3) {
uint32_t sliv = (uint32_t)strtol(argv[2], NULL, 10); uint32_t sliv = (uint32_t)strtol(argv[2], NULL, 10);
uint32_t S = 0; uint32_t S = 0;
uint32_t L = 0; uint32_t L = 0;
srsran_sliv_to_s_and_l(N, sliv, &S, &L);
// check that N is not zero to prevent undefined division
if (N) {
srsran_sliv_to_s_and_l(N, sliv, &S, &L);
printf("SLIV=%d; Start: %d; Length: %d;\n", sliv, S, L); printf("SLIV=%d; Start: %d; Length: %d;\n", sliv, S, L);
return SRSRAN_SUCCESS; ret = SRSRAN_SUCCESS;
}
else {
ERROR("Error: N cannot be 0 to prevent an undefined division");
}
} }
// if four arguments, calculate sliv from start and length // if four arguments, calculate sliv from start and length
if (argc == 4) { else if (argc == 4) {
uint32_t s = (uint32_t)strtol(argv[2], NULL, 10); uint32_t s = (uint32_t)strtol(argv[2], NULL, 10);
uint32_t l = (uint32_t)strtol(argv[3], NULL, 10); uint32_t l = (uint32_t)strtol(argv[3], NULL, 10);
uint32_t sliv = srsran_sliv_from_s_and_l(N, s, l); uint32_t sliv = srsran_sliv_from_s_and_l(N, s, l);
printf("SLIV=%d; Start: %d; Length: %d;\n", sliv, s, l); printf("SLIV=%d; Start: %d; Length: %d;\n", sliv, s, l);
return SRSRAN_SUCCESS; ret = SRSRAN_SUCCESS;
}
else {
ERROR("Error: too many arguments");
} }
return ret;
} }

@ -15,10 +15,13 @@
#include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/debug.h"
#include "srsran/phy/utils/primes.h" #include "srsran/phy/utils/primes.h"
#include "srsran/phy/utils/vector.h" #include "srsran/phy/utils/vector.h"
#include <assert.h>
#include <complex.h> #include <complex.h>
#define NOF_ZC_SEQ 30
// Phi values for M_sc=12 Table 5.5.1.2-1 in TS 36.211 // Phi values for M_sc=12 Table 5.5.1.2-1 in TS 36.211
static const float zc_sequence_lte_phi_M_sc_12[30][12] = { static const float zc_sequence_lte_phi_M_sc_12[NOF_ZC_SEQ][12] = {
{-1, 1, 3, -3, 3, 3, 1, 1, 3, 1, -3, 3}, {1, 1, 3, 3, 3, -1, 1, -3, -3, 1, -3, 3}, {-1, 1, 3, -3, 3, 3, 1, 1, 3, 1, -3, 3}, {1, 1, 3, 3, 3, -1, 1, -3, -3, 1, -3, 3},
{1, 1, -3, -3, -3, -1, -3, -3, 1, -3, 1, -1}, {-1, 1, 1, 1, 1, -1, -3, -3, 1, -3, 3, -1}, {1, 1, -3, -3, -3, -1, -3, -3, 1, -3, 1, -1}, {-1, 1, 1, 1, 1, -1, -3, -3, 1, -3, 3, -1},
{-1, 3, 1, -1, 1, -1, -3, -1, 1, -1, 1, 3}, {1, -3, 3, -1, -1, 1, 1, -1, -1, 3, -3, 1}, {-1, 3, 1, -1, 1, -1, -3, -1, 1, -1, 1, 3}, {1, -3, 3, -1, -1, 1, 1, -1, -1, 3, -3, 1},
@ -36,7 +39,7 @@ static const float zc_sequence_lte_phi_M_sc_12[30][12] = {
{-1, 3, -3, 3, -1, 3, 3, -3, 3, 3, -1, -1}, {3, -3, -3, -1, -1, -3, -1, 3, -3, 3, 1, -1}}; {-1, 3, -3, 3, -1, 3, 3, -3, 3, 3, -1, -1}, {3, -3, -3, -1, -1, -3, -1, 3, -3, 3, 1, -1}};
// Phi values for M_sc=24 Table 5.5.1.2-2 in TS 36.211 // Phi values for M_sc=24 Table 5.5.1.2-2 in TS 36.211
static const float zc_sequence_lte_phi_M_sc_24[30][24] = { static const float zc_sequence_lte_phi_M_sc_24[NOF_ZC_SEQ][24] = {
{-1, 3, 1, -3, 3, -1, 1, 3, -3, 3, 1, 3, -3, 3, 1, 1, -1, 1, 3, -3, 3, -3, -1, -3}, {-1, 3, 1, -3, 3, -1, 1, 3, -3, 3, 1, 3, -3, 3, 1, 1, -1, 1, 3, -3, 3, -3, -1, -3},
{-3, 3, -3, -3, -3, 1, -3, -3, 3, -1, 1, 1, 1, 3, 1, -1, 3, -3, -3, 1, 3, 1, 1, -3}, {-3, 3, -3, -3, -3, 1, -3, -3, 3, -1, 1, 1, 1, 3, 1, -1, 3, -3, -3, 1, 3, 1, 1, -3},
{3, -1, 3, 3, 1, 1, -3, 3, 3, 3, 3, 1, -1, 3, -1, 1, 1, -1, -3, -1, -1, 1, 3, 3}, {3, -1, 3, 3, 1, 1, -3, 3, 3, 3, 3, 1, -1, 3, -1, 1, 1, -1, -3, -1, -1, 1, 3, 3},
@ -69,7 +72,7 @@ static const float zc_sequence_lte_phi_M_sc_24[30][24] = {
{1, 1, -1, -1, -3, -1, 3, -1, 3, -1, 1, 3, 1, -1, 3, 1, 3, -3, -3, 1, -1, -1, 1, 3}}; {1, 1, -1, -1, -3, -1, 3, -1, 3, -1, 1, 3, 1, -1, 3, 1, 3, -3, -3, 1, -1, -1, 1, 3}};
// Phi values for M_sc=12 Table 5.2.2.2-1 in TS 38.211 // Phi values for M_sc=12 Table 5.2.2.2-1 in TS 38.211
static const float zc_sequence_nr_phi_M_sc_6[30][6] = { static const float zc_sequence_nr_phi_M_sc_6[NOF_ZC_SEQ][6] = {
{-3, -1, 3, 3, -1, -3}, {-3, 3, -1, -1, 3, -3}, {-3, -3, -3, 3, 1, -3}, {1, 1, 1, 3, -1, -3}, {-3, -1, 3, 3, -1, -3}, {-3, 3, -1, -1, 3, -3}, {-3, -3, -3, 3, 1, -3}, {1, 1, 1, 3, -1, -3},
{1, 1, 1, -3, -1, 3}, {-3, 1, -1, -3, -3, -3}, {-3, 1, 3, -3, -3, -3}, {-3, -1, 1, -3, 1, -1}, {1, 1, 1, -3, -1, 3}, {-3, 1, -1, -3, -3, -3}, {-3, 1, 3, -3, -3, -3}, {-3, -1, 1, -3, 1, -1},
{-3, -1, -3, 1, -3, -3}, {-3, -3, 1, -3, 3, -3}, {-3, 1, 3, 1, -3, -3}, {-3, -1, -3, 1, 1, -3}, {-3, -1, -3, 1, -3, -3}, {-3, -3, 1, -3, 3, -3}, {-3, 1, 3, 1, -3, -3}, {-3, -1, -3, 1, 1, -3},
@ -80,7 +83,7 @@ static const float zc_sequence_nr_phi_M_sc_6[30][6] = {
{1, 1, -1, 3, -3, -1}, {1, 1, -3, 1, -1, -1}}; {1, 1, -1, 3, -3, -1}, {1, 1, -3, 1, -1, -1}};
// Phi values for M_sc=12 Table 5.2.2.2-2 in TS 38.211 // Phi values for M_sc=12 Table 5.2.2.2-2 in TS 38.211
static const float zc_sequence_nr_phi_M_sc_12[30][12] = { static const float zc_sequence_nr_phi_M_sc_12[NOF_ZC_SEQ][12] = {
{-3, 1, -3, -3, -3, 3, -3, -1, 1, 1, 1, -3}, {-3, 3, 1, -3, 1, 3, -1, -1, 1, 3, 3, 3}, {-3, 1, -3, -3, -3, 3, -3, -1, 1, 1, 1, -3}, {-3, 3, 1, -3, 1, 3, -1, -1, 1, 3, 3, 3},
{-3, 3, 3, 1, -3, 3, -1, 1, 3, -3, 3, -3}, {-3, -3, -1, 3, 3, 3, -3, 3, -3, 1, -1, -3}, {-3, 3, 3, 1, -3, 3, -1, 1, 3, -3, 3, -3}, {-3, -3, -1, 3, 3, 3, -3, 3, -3, 1, -1, -3},
{-3, -1, -1, 1, 3, 1, 1, -1, 1, -1, -3, 1}, {-3, -3, 3, 1, -3, -3, -3, -1, 3, -1, 1, 3}, {-3, -1, -1, 1, 3, 1, 1, -1, 1, -1, -3, 1}, {-3, -3, 3, 1, -3, -3, -3, -1, 3, -1, 1, 3},
@ -98,7 +101,7 @@ static const float zc_sequence_nr_phi_M_sc_12[30][12] = {
{1, -1, 3, 1, 1, -1, -1, -1, 1, 3, -3, 1}, {-3, 3, -3, 3, -3, -3, 3, -1, -1, 1, 3, -3}}; {1, -1, 3, 1, 1, -1, -1, -1, 1, 3, -3, 1}, {-3, 3, -3, 3, -3, -3, 3, -1, -1, 1, 3, -3}};
// Phi values for M_sc=18 Table 5.2.2.2-3 in TS 38.211 // Phi values for M_sc=18 Table 5.2.2.2-3 in TS 38.211
static const float zc_sequence_nr_phi_M_sc_18[30][18] = { static const float zc_sequence_nr_phi_M_sc_18[NOF_ZC_SEQ][18] = {
{-1, 3, -1, -3, 3, 1, -3, -1, 3, -3, -1, -1, 1, 1, 1, -1, -1, -1}, {-1, 3, -1, -3, 3, 1, -3, -1, 3, -3, -1, -1, 1, 1, 1, -1, -1, -1},
{3, -3, 3, -1, 1, 3, -3, -1, -3, -3, -1, -3, 3, 1, -1, 3, -3, 3}, {3, -3, 3, -1, 1, 3, -3, -1, -3, -3, -1, -3, 3, 1, -1, 3, -3, 3},
{-3, 3, 1, -1, -1, 3, -3, -1, 1, 1, 1, 1, 1, -1, 3, -1, -3, -1}, {-3, 3, 1, -1, -1, 3, -3, -1, 1, 1, 1, 1, 1, -1, 3, -1, -3, -1},
@ -131,7 +134,7 @@ static const float zc_sequence_nr_phi_M_sc_18[30][18] = {
{-3, 3, 1, -1, -1, -1, -1, 1, -1, 3, 3, -3, -1, 1, 3, -1, 3, -1}}; {-3, 3, 1, -1, -1, -1, -1, 1, -1, 3, 3, -3, -1, 1, 3, -1, 3, -1}};
// Phi values for M_sc=18 Table 5.2.2.2-3 in TS 38.211 // Phi values for M_sc=18 Table 5.2.2.2-3 in TS 38.211
static const float zc_sequence_nr_phi_M_sc_24[30][24] = { static const float zc_sequence_nr_phi_M_sc_24[NOF_ZC_SEQ][24] = {
{-1, -3, 3, -1, 3, 1, 3, -1, 1, -3, -1, -3, -1, 1, 3, -3, -1, -3, 3, 3, 3, -3, -3, -3}, {-1, -3, 3, -1, 3, 1, 3, -1, 1, -3, -1, -3, -1, 1, 3, -3, -1, -3, 3, 3, 3, -3, -3, -3},
{-1, -3, 3, 1, 1, -3, 1, -3, -3, 1, -3, -1, -1, 3, -3, 3, 3, 3, -3, 1, 3, 3, -3, -3}, {-1, -3, 3, 1, 1, -3, 1, -3, -3, 1, -3, -1, -1, 3, -3, 3, 3, 3, -3, 1, 3, 3, -3, -3},
{-1, -3, -3, 1, -1, -1, -3, 1, 3, -1, -3, -1, -1, -3, 1, 1, 3, 1, -3, -1, -1, 3, -3, -3}, {-1, -3, -3, 1, -1, -1, -3, 1, 3, -1, -3, -1, -1, -3, 1, 1, 3, 1, -3, -1, -1, 3, -3, -3},
@ -165,31 +168,37 @@ static const float zc_sequence_nr_phi_M_sc_24[30][24] = {
static void zc_sequence_lte_r_uv_arg_1prb(uint32_t u, cf_t* tmp_arg) static void zc_sequence_lte_r_uv_arg_1prb(uint32_t u, cf_t* tmp_arg)
{ {
assert(u < NOF_ZC_SEQ);
srsran_vec_sc_prod_fcc(zc_sequence_lte_phi_M_sc_12[u], M_PI_4, tmp_arg, SRSRAN_NRE); srsran_vec_sc_prod_fcc(zc_sequence_lte_phi_M_sc_12[u], M_PI_4, tmp_arg, SRSRAN_NRE);
} }
static void zc_sequence_lte_r_uv_arg_2prb(uint32_t u, cf_t* tmp_arg) static void zc_sequence_lte_r_uv_arg_2prb(uint32_t u, cf_t* tmp_arg)
{ {
assert(u < NOF_ZC_SEQ);
srsran_vec_sc_prod_fcc(zc_sequence_lte_phi_M_sc_24[u], M_PI_4, tmp_arg, 2 * SRSRAN_NRE); srsran_vec_sc_prod_fcc(zc_sequence_lte_phi_M_sc_24[u], M_PI_4, tmp_arg, 2 * SRSRAN_NRE);
} }
static void zc_sequence_nr_r_uv_arg_0dot5prb(uint32_t u, cf_t* tmp_arg) static void zc_sequence_nr_r_uv_arg_0dot5prb(uint32_t u, cf_t* tmp_arg)
{ {
assert(u < NOF_ZC_SEQ);
srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_6[u], M_PI_4, tmp_arg, SRSRAN_NRE / 2); srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_6[u], M_PI_4, tmp_arg, SRSRAN_NRE / 2);
} }
static void zc_sequence_nr_r_uv_arg_1prb(uint32_t u, cf_t* tmp_arg) static void zc_sequence_nr_r_uv_arg_1prb(uint32_t u, cf_t* tmp_arg)
{ {
assert(u < NOF_ZC_SEQ);
srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_12[u], M_PI_4, tmp_arg, SRSRAN_NRE); srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_12[u], M_PI_4, tmp_arg, SRSRAN_NRE);
} }
static void zc_sequence_nr_r_uv_arg_1dot5prb(uint32_t u, cf_t* tmp_arg) static void zc_sequence_nr_r_uv_arg_1dot5prb(uint32_t u, cf_t* tmp_arg)
{ {
assert(u < NOF_ZC_SEQ);
srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_18[u], M_PI_4, tmp_arg, (3 * SRSRAN_NRE) / 2); srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_18[u], M_PI_4, tmp_arg, (3 * SRSRAN_NRE) / 2);
} }
static void zc_sequence_nr_r_uv_arg_2prb(uint32_t u, cf_t* tmp_arg) static void zc_sequence_nr_r_uv_arg_2prb(uint32_t u, cf_t* tmp_arg)
{ {
assert(u < NOF_ZC_SEQ);
srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_24[u], M_PI_4, tmp_arg, 2 * SRSRAN_NRE); srsran_vec_sc_prod_fcc(zc_sequence_nr_phi_M_sc_24[u], M_PI_4, tmp_arg, 2 * SRSRAN_NRE);
} }

@ -57,11 +57,13 @@ __attribute__((constructor)) static void srsran_dft_load()
} }
if (lockf(fileno(fd), F_LOCK, 0) == -1) { if (lockf(fileno(fd), F_LOCK, 0) == -1) {
perror("lockf()"); perror("lockf()");
fclose(fd);
return; return;
} }
fftwf_import_wisdom_from_file(fd); fftwf_import_wisdom_from_file(fd);
if (lockf(fileno(fd), F_ULOCK, 0) == -1) { if (lockf(fileno(fd), F_ULOCK, 0) == -1) {
perror("u-lockf()"); perror("u-lockf()");
fclose(fd);
return; return;
} }
fclose(fd); fclose(fd);
@ -82,11 +84,13 @@ __attribute__((destructor)) void srsran_dft_exit()
} }
if (lockf(fileno(fd), F_LOCK, 0) == -1) { if (lockf(fileno(fd), F_LOCK, 0) == -1) {
perror("lockf()"); perror("lockf()");
fclose(fd);
return; return;
} }
fftwf_export_wisdom_to_file(fd); fftwf_export_wisdom_to_file(fd);
if (lockf(fileno(fd), F_ULOCK, 0) == -1) { if (lockf(fileno(fd), F_ULOCK, 0) == -1) {
perror("u-lockf()"); perror("u-lockf()");
fclose(fd);
return; return;
} }
fclose(fd); fclose(fd);

@ -380,9 +380,8 @@ int update_ldpc_soft_bits_c_avx2_flood(void* p, const int8_t (*these_var_indices
for (i_layer = 0; i_layer < vp->bgM; i_layer++) { for (i_layer = 0; i_layer < vp->bgM; i_layer++) {
current_var_index = these_var_indices[i_layer][0]; current_var_index = these_var_indices[i_layer][0];
this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1); this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1);
for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { for (i = 1; (current_var_index != -1) && (i < MAX_CNCT); i++) {
i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr;
tmp_epi8 = _mm256_adds_epi8(this_check_to_var[i_bit_tmp_base], vp->soft_bits.v[current_var_index]); tmp_epi8 = _mm256_adds_epi8(this_check_to_var[i_bit_tmp_base], vp->soft_bits.v[current_var_index]);
@ -395,7 +394,7 @@ int update_ldpc_soft_bits_c_avx2_flood(void* p, const int8_t (*these_var_indices
mask_epi8 = _mm256_cmpgt_epi8(neg_infty7_epi8, tmp_epi8); mask_epi8 = _mm256_cmpgt_epi8(neg_infty7_epi8, tmp_epi8);
vp->soft_bits.v[current_var_index] = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8); vp->soft_bits.v[current_var_index] = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8);
current_var_index = these_var_indices[i_layer][i + 1]; current_var_index = these_var_indices[i_layer][i];
} }
} }

@ -434,7 +434,7 @@ int update_ldpc_soft_bits_c_avx2long_flood(void* p, const int8_t (*these_var_ind
current_var_index = these_var_indices[i_layer][0]; current_var_index = these_var_indices[i_layer][0];
this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes; this_check_to_var = vp->check_to_var + i_layer * (vp->hrr + 1) * vp->n_subnodes;
for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { for (i = 1; (current_var_index != -1) && (i < MAX_CNCT); i++) {
current_var_index_subnode = current_var_index * vp->n_subnodes; current_var_index_subnode = current_var_index * vp->n_subnodes;
for (j = 0; j < vp->n_subnodes; j++) { for (j = 0; j < vp->n_subnodes; j++) {
i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr; i_bit_tmp_base = (current_var_index <= vp->hrr) ? current_var_index : vp->hrr;
@ -450,7 +450,7 @@ int update_ldpc_soft_bits_c_avx2long_flood(void* p, const int8_t (*these_var_ind
vp->soft_bits[current_var_index_subnode + j].v = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8); vp->soft_bits[current_var_index_subnode + j].v = _mm256_blendv_epi8(tmp_epi8, neg_infty8_epi8, mask_epi8);
} }
current_var_index = these_var_indices[i_layer][i + 1]; current_var_index = these_var_indices[i_layer][i];
} }
} }

@ -317,7 +317,7 @@ int update_ldpc_soft_bits_c_flood(void* p, const int8_t (*these_var_indices)[MAX
for (i_layer = 0; i_layer < vp->bgM; i_layer++) { for (i_layer = 0; i_layer < vp->bgM; i_layer++) {
current_var_index = these_var_indices[i_layer][0]; current_var_index = these_var_indices[i_layer][0];
this_check_to_var = vp->check_to_var + i_layer * (vp->hrrN + vp->ls); this_check_to_var = vp->check_to_var + i_layer * (vp->hrrN + vp->ls);
for (i = 0; (current_var_index != -1) && (i < MAX_CNCT); i++) { for (i = 1; (current_var_index != -1) && (i < MAX_CNCT); i++) {
// recall that current_var_index depends on i! // recall that current_var_index depends on i!
current_var_index_ext = current_var_index * vp->ls; current_var_index_ext = current_var_index * vp->ls;
for (j = 0; j < vp->ls; j++) { for (j = 0; j < vp->ls; j++) {
@ -332,7 +332,7 @@ int update_ldpc_soft_bits_c_flood(void* p, const int8_t (*these_var_indices)[MAX
} }
vp->soft_bits[i_bit] = (int8_t)tmp; vp->soft_bits[i_bit] = (int8_t)tmp;
} }
current_var_index = these_var_indices[i_layer][i + 1]; current_var_index = these_var_indices[i_layer][i];
} }
} }

@ -93,7 +93,7 @@ void usage(char* prog)
/*! /*!
* \brief Parses the input line. * \brief Parses the input line.
*/ */
void parse_args(int argc, char** argv) int parse_args(int argc, char** argv)
{ {
int opt = 0; int opt = 0;
while ((opt = getopt(argc, argv, "b:l:e:f:r:m:w:M:s:B:N:E:")) != -1) { while ((opt = getopt(argc, argv, "b:l:e:f:r:m:w:M:s:B:N:E:")) != -1) {
@ -136,21 +136,24 @@ void parse_args(int argc, char** argv)
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit(-1); return SRSRAN_ERROR;
} }
} }
return SRSRAN_SUCCESS;
} }
/*! /*!
* \brief Prints decoder statistics. * \brief Prints decoder statistics.
*/ */
void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time); int print_decoder(char* title, int n_batches, int n_errors, double elapsed_time);
/*! /*!
* \brief Main test function. * \brief Main test function.
*/ */
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int ret = SRSRAN_ERROR;
uint8_t* messages_true = NULL; uint8_t* messages_true = NULL;
uint8_t* messages_sim_f = NULL; uint8_t* messages_sim_f = NULL;
uint8_t* messages_sim_s = NULL; uint8_t* messages_sim_s = NULL;
@ -169,29 +172,68 @@ int main(int argc, char** argv)
int16_t* symbols_s = NULL; // unrm_symbols int16_t* symbols_s = NULL; // unrm_symbols
int8_t* symbols_c = NULL; // unrm_symbols int8_t* symbols_c = NULL; // unrm_symbols
// LDPC encoder
srsran_ldpc_encoder_t encoder = {};
// LDPC decoder (8 bit)
srsran_ldpc_decoder_t decoder_c = {};
// LDPC decoder (8 bit, flooded)
srsran_ldpc_decoder_t decoder_c_flood = {};
// LDPC decoder (16 bit)
srsran_ldpc_decoder_t decoder_s = {};
// LDPC decoder (float)
srsran_ldpc_decoder_t decoder_f = {};
#ifdef LV_HAVE_AVX2
// LDPC decoder (8 bit, AVX2 version)
srsran_ldpc_decoder_t decoder_avx = {};
// LDPC decoder (8 bit, flooded scheduling, AVX2 version)
srsran_ldpc_decoder_t decoder_avx_flood = {};
#endif
#ifdef LV_HAVE_AVX512
// LDPC decoder (8 bit, AVX512 version)
srsran_ldpc_decoder_t decoder_avx512 = {};
// LDPC decoder (8 bit, flooded scheduling, AVX512 version)
srsran_ldpc_decoder_t decoder_avx512_flood = {};
#endif
// LDPC rate Matcher
srsran_ldpc_rm_t rm_tx = {};
// LDPC rate DeMatcher
srsran_ldpc_rm_t rm_rx = {};
// LDPC rate DeMatcher (int16_t)
srsran_ldpc_rm_t rm_rx_s = {};
// LDPC rate DeMatcher (int8_t)
srsran_ldpc_rm_t rm_rx_c = {};
// Create a random generator
srsran_random_t random_gen = NULL;
random_gen = srsran_random_init(0);
int i = 0; int i = 0;
int j = 0; int j = 0;
parse_args(argc, argv); if (parse_args(argc, argv) < SRSRAN_SUCCESS) {
goto clean_exit;
// create an LDPC encoder }
srsran_ldpc_encoder_t encoder;
#ifdef LV_HAVE_AVX512 #ifdef LV_HAVE_AVX512
if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_AVX512, base_graph, lift_size) != 0) { if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_AVX512, base_graph, lift_size) != 0) {
perror("encoder init"); perror("encoder init");
exit(-1); goto clean_exit;
} }
#else // no AVX512 #else // no AVX512
#ifdef LV_HAVE_AVX2 #ifdef LV_HAVE_AVX2
if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_AVX2, base_graph, lift_size) != 0) { if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_AVX2, base_graph, lift_size) != 0) {
perror("encoder init"); perror("encoder init");
exit(-1); goto clean_exit;
} }
#else // no AVX2 #else // no AVX2
if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_C, base_graph, lift_size) != 0) { if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_C, base_graph, lift_size) != 0) {
perror("encoder init"); perror("encoder init");
exit(-1); goto clean_exit;
} }
#endif // LV_HAVE_AVX2 #endif // LV_HAVE_AVX2
#endif // LV_HAVE_AVX512 #endif // LV_HAVE_AVX512
@ -206,32 +248,28 @@ int main(int argc, char** argv)
Nref = finalN; Nref = finalN;
} }
// create a LDPC rate Matcher // Init the LDPC rate Matcher
srsran_ldpc_rm_t rm_tx;
if (srsran_ldpc_rm_tx_init(&rm_tx) != 0) { if (srsran_ldpc_rm_tx_init(&rm_tx) != 0) {
perror("rate matcher init"); perror("rate matcher init");
exit(-1); goto clean_exit;
} }
// create a LDPC rate DeMatcher // Init LDPC rate DeMatcher
srsran_ldpc_rm_t rm_rx;
if (srsran_ldpc_rm_rx_init_f(&rm_rx) != 0) { if (srsran_ldpc_rm_rx_init_f(&rm_rx) != 0) {
perror("rate dematcher init"); perror("rate dematcher init");
exit(-1); goto clean_exit;
} }
// create a LDPC rate DeMatcher (int16_t) // Init LDPC rate DeMatcher (int16_t)
srsran_ldpc_rm_t rm_rx_s;
if (srsran_ldpc_rm_rx_init_s(&rm_rx_s) != 0) { if (srsran_ldpc_rm_rx_init_s(&rm_rx_s) != 0) {
perror("rate dematcher init (int16_t)"); perror("rate dematcher init (int16_t)");
exit(-1); goto clean_exit;
} }
// create a LDPC rate DeMatcher (int8_t) // Init LDPC rate DeMatcher (int8_t)
srsran_ldpc_rm_t rm_rx_c;
if (srsran_ldpc_rm_rx_init_c(&rm_rx_c) != 0) { if (srsran_ldpc_rm_rx_init_c(&rm_rx_c) != 0) {
perror("rate dematcher init (int8_t)"); perror("rate dematcher init (int8_t)");
exit(-1); goto clean_exit;
} }
// Create LDPC configuration arguments // Create LDPC configuration arguments
@ -240,73 +278,62 @@ int main(int argc, char** argv)
decoder_args.ls = lift_size; decoder_args.ls = lift_size;
decoder_args.scaling_fctr = MS_SF; decoder_args.scaling_fctr = MS_SF;
// create an LDPC decoder (float) // Init the LDPC decoder (float)
srsran_ldpc_decoder_t decoder_f;
decoder_args.type = SRSRAN_LDPC_DECODER_F; decoder_args.type = SRSRAN_LDPC_DECODER_F;
if (srsran_ldpc_decoder_init(&decoder_f, &decoder_args) != 0) { if (srsran_ldpc_decoder_init(&decoder_f, &decoder_args) != 0) {
perror("decoder init"); perror("decoder init");
exit(-1); goto clean_exit;
} }
// create an LDPC decoder (16 bit) // Init the LDPC decoder (16 bit)
srsran_ldpc_decoder_t decoder_s;
decoder_args.type = SRSRAN_LDPC_DECODER_S; decoder_args.type = SRSRAN_LDPC_DECODER_S;
if (srsran_ldpc_decoder_init(&decoder_s, &decoder_args) != 0) { if (srsran_ldpc_decoder_init(&decoder_s, &decoder_args) != 0) {
perror("decoder init (int16_t)"); perror("decoder init (int16_t)");
exit(-1); goto clean_exit;
} }
// create an LDPC decoder (8 bit) // Init the LDPC decoder (8 bit)
srsran_ldpc_decoder_t decoder_c;
decoder_args.type = SRSRAN_LDPC_DECODER_C; decoder_args.type = SRSRAN_LDPC_DECODER_C;
if (srsran_ldpc_decoder_init(&decoder_c, &decoder_args) != 0) { if (srsran_ldpc_decoder_init(&decoder_c, &decoder_args) != 0) {
perror("decoder init (int8_t)"); perror("decoder init (int8_t)");
exit(-1); goto clean_exit;
} }
// create an LDPC decoder (8 bit, flooded) // Init the LDPC decoder (8 bit, flooded)
srsran_ldpc_decoder_t decoder_c_flood;
decoder_args.type = SRSRAN_LDPC_DECODER_C_FLOOD; decoder_args.type = SRSRAN_LDPC_DECODER_C_FLOOD;
if (srsran_ldpc_decoder_init(&decoder_c_flood, &decoder_args) != 0) { if (srsran_ldpc_decoder_init(&decoder_c_flood, &decoder_args) != 0) {
perror("decoder init"); perror("decoder init");
exit(-1); goto clean_exit;
} }
#ifdef LV_HAVE_AVX2 #ifdef LV_HAVE_AVX2
// create an LDPC decoder (8 bit, AVX2 version) // Init the LDPC decoder (8 bit, AVX2 version)
srsran_ldpc_decoder_t decoder_avx;
decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX2; decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX2;
if (srsran_ldpc_decoder_init(&decoder_avx, &decoder_args) != 0) { if (srsran_ldpc_decoder_init(&decoder_avx, &decoder_args) != 0) {
perror("decoder init"); perror("decoder init");
exit(-1); goto clean_exit;
} }
// create an LDPC decoder (8 bit, flooded scheduling, AVX2 version) // Init the LDPC decoder (8 bit, flooded scheduling, AVX2 version)
srsran_ldpc_decoder_t decoder_avx_flood;
decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX2_FLOOD; decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX2_FLOOD;
if (srsran_ldpc_decoder_init(&decoder_avx_flood, &decoder_args) != 0) { if (srsran_ldpc_decoder_init(&decoder_avx_flood, &decoder_args) != 0) {
perror("decoder init"); perror("decoder init");
exit(-1); goto clean_exit;
} }
#endif // LV_HAVE_AVX2 #endif // LV_HAVE_AVX2
#ifdef LV_HAVE_AVX512 #ifdef LV_HAVE_AVX512
// create an LDPC decoder (8 bit, AVX2 version) // Init the LDPC decoder (8 bit, AVX512 version)
srsran_ldpc_decoder_t decoder_avx512;
decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX512; decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX512;
if (srsran_ldpc_decoder_init(&decoder_avx512, &decoder_args) != 0) { if (srsran_ldpc_decoder_init(&decoder_avx512, &decoder_args) != 0) {
perror("decoder init"); perror("decoder init");
exit(-1); goto clean_exit;
} }
// create an LDPC decoder (8 bit, flooded scheduling, AVX512 version) // Init LDPC decoder (8 bit, flooded scheduling, AVX512 version)
srsran_ldpc_decoder_t decoder_avx512_flood;
decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX512_FLOOD; decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX512_FLOOD;
if (srsran_ldpc_decoder_init(&decoder_avx512_flood, &decoder_args) != 0) { if (srsran_ldpc_decoder_init(&decoder_avx512_flood, &decoder_args) != 0) {
perror("decoder init"); perror("decoder init");
exit(-1); goto clean_exit;
} }
#endif // LV_HAVE_AVX512 #endif // LV_HAVE_AVX512
// create a random generator
srsran_random_t random_gen = srsran_random_init(0);
printf("Test LDPC chain:\n"); printf("Test LDPC chain:\n");
printf(" Base Graph -> BG%d\n", encoder.bg + 1); printf(" Base Graph -> BG%d\n", encoder.bg + 1);
printf(" Lifting Size -> %d\n", encoder.ls); printf(" Lifting Size -> %d\n", encoder.ls);
@ -352,7 +379,7 @@ int main(int argc, char** argv)
!messages_sim_avx512_flood || !codewords || !rm_codewords || !rm_symbols || !rm_symbols_s || !rm_symbols_c || !messages_sim_avx512_flood || !codewords || !rm_codewords || !rm_symbols || !rm_symbols_s || !rm_symbols_c ||
!symbols || !symbols_s || !symbols_c) { !symbols || !symbols_s || !symbols_c) {
perror("malloc"); perror("malloc");
exit(-1); goto clean_exit;
} }
int i_bit = 0; int i_bit = 0;
@ -479,7 +506,7 @@ int main(int argc, char** argv)
rv, rv,
mod_type, mod_type,
Nref)) { Nref)) {
exit(-1); goto clean_exit;
} }
} }
@ -519,7 +546,7 @@ int main(int argc, char** argv)
rv, rv,
mod_type, mod_type,
Nref)) { Nref)) {
exit(-1); goto clean_exit;
} }
} }
@ -559,7 +586,7 @@ int main(int argc, char** argv)
rv, rv,
mod_type, mod_type,
Nref) < 0) { Nref) < 0) {
exit(-1); goto clean_exit;
} }
} }
@ -702,63 +729,120 @@ int main(int argc, char** argv)
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); if (print_decoder("FLOATING POINT", i_batch, n_error_words_f, elapsed_time_dec_f) < SRSRAN_SUCCESS) {
print_decoder("FIXED POINT (16 bits)", i_batch, n_error_words_s, elapsed_time_dec_s); goto clean_exit;
print_decoder("FIXED POINT (8 bits)", i_batch, n_error_words_c, elapsed_time_dec_c); }
print_decoder("FIXED POINT (8 bits, flooded scheduling)", i_batch, n_error_words_c_flood, elapsed_time_dec_c_flood); if (print_decoder("FIXED POINT (16 bits)", i_batch, n_error_words_s, elapsed_time_dec_s) < SRSRAN_SUCCESS) {
goto clean_exit;
}
if (print_decoder("FIXED POINT (8 bits)", i_batch, n_error_words_c, elapsed_time_dec_c) < SRSRAN_SUCCESS) {
goto clean_exit;
}
if (print_decoder(
"FIXED POINT (8 bits, flooded scheduling)", i_batch, n_error_words_c_flood, elapsed_time_dec_c_flood) <
SRSRAN_SUCCESS) {
goto clean_exit;
}
#ifdef LV_HAVE_AVX2 #ifdef LV_HAVE_AVX2
print_decoder("FIXED POINT (8 bits - AVX2)", i_batch, n_error_words_avx, elapsed_time_dec_avx); if (print_decoder("FIXED POINT (8 bits - AVX2)", i_batch, n_error_words_avx, elapsed_time_dec_avx) < SRSRAN_SUCCESS) {
print_decoder( goto clean_exit;
"FIXED POINT (8 bits, flooded scheduling - AVX2)", i_batch, n_error_words_avx_flood, elapsed_time_dec_avx_flood); }
if (print_decoder("FIXED POINT (8 bits, flooded scheduling - AVX2)",
i_batch,
n_error_words_avx_flood,
elapsed_time_dec_avx_flood) < SRSRAN_SUCCESS) {
goto clean_exit;
}
#endif // LV_HAVE_AVX2 #endif // LV_HAVE_AVX2
#ifdef LV_HAVE_AVX512 #ifdef LV_HAVE_AVX512
print_decoder("FIXED POINT (8 bits - AVX512)", i_batch, n_error_words_avx512, elapsed_time_dec_avx512); if (print_decoder("FIXED POINT (8 bits - AVX512)", i_batch, n_error_words_avx512, elapsed_time_dec_avx512) <
print_decoder("FIXED POINT (8 bits, flooded scheduling - AVX512)", SRSRAN_SUCCESS) {
goto clean_exit;
}
if (print_decoder("FIXED POINT (8 bits, flooded scheduling - AVX512)",
i_batch, i_batch,
n_error_words_avx512_flood, n_error_words_avx512_flood,
elapsed_time_dec_avx512_flood); elapsed_time_dec_avx512_flood) < SRSRAN_SUCCESS) {
goto clean_exit;
}
#endif // LV_HAVE_AVX512 #endif // LV_HAVE_AVX512
if (n_error_words_s > 10 * n_error_words_f) { if (n_error_words_s > 10 * n_error_words_f) {
perror("16-bit performance too low!"); perror("16-bit performance too low!");
exit(-1); goto clean_exit;
} }
if (n_error_words_c > 10 * n_error_words_f) { if (n_error_words_c > 10 * n_error_words_f) {
perror("8-bit performance too low!"); perror("8-bit performance too low!");
exit(-1); goto clean_exit;
} }
#ifdef LV_HAVE_AVX512 #ifdef LV_HAVE_AVX512
if (n_error_words_avx512 != n_error_words_avx) { if (n_error_words_avx512 != n_error_words_avx) {
perror("The number of errors AVX512 and AVX2 differs !"); perror("The number of errors AVX512 and AVX2 differs !");
exit(-1); goto clean_exit;
} }
if (n_error_words_avx512_flood != n_error_words_avx_flood) { if (n_error_words_avx512_flood != n_error_words_avx_flood) {
perror("The number of errors of flooded AVX512 and AVX2 differs !"); perror("The number of errors of flooded AVX512 and AVX2 differs !");
exit(-1); goto clean_exit;
} }
#endif // LV_HAVE_AVX512 #endif // LV_HAVE_AVX512
printf("\nTest completed successfully!\n\n"); printf("\nTest completed successfully!\n\n");
ret = SRSRAN_SUCCESS;
clean_exit:
if (symbols != NULL) {
free(symbols); free(symbols);
}
if (symbols_s != NULL) {
free(symbols_s); free(symbols_s);
}
if (symbols_c != NULL) {
free(symbols_c); free(symbols_c);
}
if (rm_symbols != NULL) {
free(rm_symbols); free(rm_symbols);
}
if (rm_symbols_s != NULL) {
free(rm_symbols_s); free(rm_symbols_s);
}
if (rm_symbols_c != NULL) {
free(rm_symbols_c); free(rm_symbols_c);
}
if (rm_codewords != NULL) {
free(rm_codewords); free(rm_codewords);
}
if (codewords != NULL) {
free(codewords); free(codewords);
}
if (messages_sim_avx != NULL) {
free(messages_sim_avx); free(messages_sim_avx);
}
if (messages_sim_avx_flood != NULL) {
free(messages_sim_avx_flood); free(messages_sim_avx_flood);
}
if (messages_sim_avx512 != NULL) {
free(messages_sim_avx512); free(messages_sim_avx512);
}
if (messages_sim_avx512_flood != NULL) {
free(messages_sim_avx512_flood); free(messages_sim_avx512_flood);
}
if (messages_sim_c_flood != NULL) {
free(messages_sim_c_flood); free(messages_sim_c_flood);
}
if (messages_sim_c != NULL) {
free(messages_sim_c); free(messages_sim_c);
}
if (messages_sim_s != NULL) {
free(messages_sim_s); free(messages_sim_s);
}
if (messages_sim_f != NULL) {
free(messages_sim_f); free(messages_sim_f);
}
if (messages_true != NULL) {
free(messages_true); free(messages_true);
}
srsran_random_free(random_gen); srsran_random_free(random_gen);
#ifdef LV_HAVE_AVX2 #ifdef LV_HAVE_AVX2
srsran_ldpc_decoder_free(&decoder_avx); srsran_ldpc_decoder_free(&decoder_avx);
@ -777,15 +861,23 @@ int main(int argc, char** argv)
srsran_ldpc_rm_rx_free_f(&rm_rx); srsran_ldpc_rm_rx_free_f(&rm_rx);
srsran_ldpc_rm_rx_free_s(&rm_rx_s); srsran_ldpc_rm_rx_free_s(&rm_rx_s);
srsran_ldpc_rm_rx_free_c(&rm_rx_c); srsran_ldpc_rm_rx_free_c(&rm_rx_c);
return ret;
} }
void print_decoder(char* title, int n_batches, int n_errors, double elapsed_time) int print_decoder(char* title, int n_batches, int n_errors, double elapsed_time)
{ {
printf("\n**** %s ****", title); printf("\n**** %s ****", title);
if (!isnormal(elapsed_time)) {
printf("\nError: elapsed time is not a valid number\n");
return SRSRAN_ERROR;
} else {
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);
return SRSRAN_SUCCESS;
}
} }

@ -523,7 +523,8 @@ static bool ri_send(uint32_t I_cqi_pmi, uint32_t I_ri, uint32_t tti, bool is_fdd
static int cqi_hl_get_subband_size(int nof_prb) static int cqi_hl_get_subband_size(int nof_prb)
{ {
if (nof_prb < 7) { if (nof_prb < 7) {
return 0; ERROR("Error: nof_prb is invalid (< 7)");
return SRSRAN_ERROR;
} else if (nof_prb <= 26) { } else if (nof_prb <= 26) {
return 4; return 4;
} else if (nof_prb <= 63) { } else if (nof_prb <= 63) {
@ -531,7 +532,8 @@ static int cqi_hl_get_subband_size(int nof_prb)
} else if (nof_prb <= 110) { } else if (nof_prb <= 110) {
return 8; return 8;
} else { } else {
return -1; ERROR("Error: nof_prb is invalid (> 110)");
return SRSRAN_ERROR;
} }
} }
@ -541,7 +543,8 @@ static int cqi_hl_get_subband_size(int nof_prb)
static int cqi_hl_get_bwp_J(int nof_prb) static int cqi_hl_get_bwp_J(int nof_prb)
{ {
if (nof_prb < 7) { if (nof_prb < 7) {
return 0; ERROR("Error: nof_prb is not valid (< 7)");
return SRSRAN_ERROR;
} else if (nof_prb <= 10) { } else if (nof_prb <= 10) {
return 1; return 1;
} else if (nof_prb <= 26) { } else if (nof_prb <= 26) {
@ -551,7 +554,8 @@ static int cqi_hl_get_bwp_J(int nof_prb)
} else if (nof_prb <= 110) { } else if (nof_prb <= 110) {
return 4; return 4;
} else { } else {
return -1; ERROR("Error: nof_prb is not valid (> 110)");
return SRSRAN_ERROR;
} }
} }
@ -559,12 +563,20 @@ static int cqi_hl_get_bwp_J(int nof_prb)
*/ */
static int cqi_sb_get_Nj(uint32_t j, uint32_t nof_prb) static int cqi_sb_get_Nj(uint32_t j, uint32_t nof_prb)
{ {
uint32_t J = cqi_hl_get_bwp_J(nof_prb); // from Table 7.2.2-2 in TS 36.213
int J = cqi_hl_get_bwp_J(nof_prb);
int K = cqi_hl_get_subband_size(nof_prb);
// Catch the J and k errors, and prevent undefined modulo operations
if (J <= 0 || K <= 0) {
return 0;
}
if (J == 1) { if (J == 1) {
return (uint32_t)ceil((float)nof_prb / cqi_hl_get_subband_size(nof_prb)); return (uint32_t)ceil((float)nof_prb / K);
} else { } else {
// all bw parts have the same number of subbands except the last one // all bw parts have the same number of subbands except the last one
uint32_t Nj = (uint32_t)ceil((float)nof_prb / cqi_hl_get_subband_size(nof_prb) / J); uint32_t Nj = (uint32_t)ceil((float)nof_prb / K / J);
if (j < J - 1) { if (j < J - 1) {
return Nj; return Nj;
} else { } else {
@ -608,6 +620,13 @@ uint32_t cqi_sb_get_H(const srsran_cqi_report_cfg_t* cfg, uint32_t nof_prb)
{ {
uint32_t K = cfg->subband_wideband_ratio; uint32_t K = cfg->subband_wideband_ratio;
uint32_t J = cqi_hl_get_bwp_J(nof_prb); uint32_t J = cqi_hl_get_bwp_J(nof_prb);
// Catch the J errors
if (J <= 0)
{
return 0;
}
uint32_t H = J * K + 1; uint32_t H = J * K + 1;
return H; return H;
} }
@ -641,9 +660,15 @@ uint32_t srsran_cqi_periodic_sb_bw_part_idx(const srsran_cqi_report_cfg_t* cfg,
} }
} }
assert(N_p != 0);
uint32_t x = ((tti - N_offset) / N_p) % H; uint32_t x = ((tti - N_offset) / N_p) % H;
if (x > 0) { if (x > 0) {
return (x - 1) % cqi_hl_get_bwp_J(nof_prb); int J = cqi_hl_get_bwp_J(nof_prb);
// Catch the J errors and prevent undefined modulo operation
if (J <= 0) {
return 0;
}
return (x - 1) % J;
} else { } else {
return 0; return 0;
} }

@ -317,6 +317,11 @@ static int test_case1()
} }
} }
if (!t_encode_count || !t_decode_count) {
ERROR("Error in test case 1: undefined division");
return SRSRAN_ERROR;
}
printf("test_case_1 - format %s - passed - %.1f usec/encode; %.1f usec/llr; %.1f usec/decode; min_corr=%f; " printf("test_case_1 - format %s - passed - %.1f usec/encode; %.1f usec/llr; %.1f usec/decode; min_corr=%f; "
"false_alarm_prob=%f;\n", "false_alarm_prob=%f;\n",
srsran_dci_format_string(format), srsran_dci_format_string(format),
@ -332,7 +337,7 @@ static int test_case1()
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
srsran_regs_t regs; srsran_regs_t regs = {};
int i; int i;
int ret = SRSRAN_ERROR; int ret = SRSRAN_ERROR;

@ -143,6 +143,7 @@ int srsran_resample_arb_compute(srsran_resample_arb_t* q, cf_t* input, cf_t* out
filter_input, srsran_resample_arb_polyfilt[(idx + 1) % SRSRAN_RESAMPLE_ARB_N], SRSRAN_RESAMPLE_ARB_M); filter_input, srsran_resample_arb_polyfilt[(idx + 1) % SRSRAN_RESAMPLE_ARB_N], SRSRAN_RESAMPLE_ARB_M);
} }
// TODO: this condition is never true
if (idx == SRSRAN_RESAMPLE_ARB_N) { if (idx == SRSRAN_RESAMPLE_ARB_N) {
*output = res1; *output = res1;
} else { } else {

@ -1235,7 +1235,9 @@ void rf_uhd_get_time(void* h, time_t* secs, double* frac_secs)
{ {
rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h;
uhd::time_spec_t timespec; uhd::time_spec_t timespec;
handler->uhd->get_time_now(timespec); if (handler->uhd->get_time_now(timespec) != UHD_ERROR_NONE) {
return;
}
if (secs != nullptr) { if (secs != nullptr) {
*secs = timespec.get_full_secs(); *secs = timespec.get_full_secs();
} }

@ -505,7 +505,7 @@ int srsran_ssb_set_cfg(srsran_ssb_t* q, const srsran_ssb_cfg_t* cfg)
} }
if (!isnormal(q->cfg.beta_pbch_dmrs)) { if (!isnormal(q->cfg.beta_pbch_dmrs)) {
q->cfg.beta_pbch = SRSRAN_SSB_DEFAULT_BETA; q->cfg.beta_pbch_dmrs = SRSRAN_SSB_DEFAULT_BETA;
} }
return SRSRAN_SUCCESS; return SRSRAN_SUCCESS;
@ -729,7 +729,7 @@ ssb_measure(srsran_ssb_t* q, const cf_t ssb_grid[SRSRAN_SSB_NOF_RE], uint32_t N_
if (epre_pss > rsrp_pss) { if (epre_pss > rsrp_pss) {
n0_pss = epre - rsrp_pss; n0_pss = epre - rsrp_pss;
} }
if (epre_pss > rsrp_pss) { if (epre_sss > rsrp_sss) {
n0_sss = epre - rsrp_sss; n0_sss = epre - rsrp_sss;
} }
float n0 = (n0_pss + n0_sss) / 2.0f; float n0 = (n0_pss + n0_sss) / 2.0f;

@ -98,27 +98,41 @@ void parse_args(int argc, char** argv)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int ret = SRSRAN_ERROR;
parse_args(argc, argv); parse_args(argc, argv);
srsran_use_standard_symbol_size(use_standard_lte_rates); srsran_use_standard_symbol_size(use_standard_lte_rates);
// Init buffers
cf_t* input_buffer = NULL;
cf_t* input_buffer_temp = NULL;
cf_t* sf_buffer = NULL;
// Init PSSS
srsran_psss_t psss = {};
if (srsran_psss_init(&psss, nof_prb, cp) < SRSRAN_SUCCESS) {
ERROR("Error initialising the PSSS");
goto clean_exit;
}
if (!input_file_name || srsran_filesource_init(&fsrc, input_file_name, SRSRAN_COMPLEX_FLOAT_BIN)) { if (!input_file_name || srsran_filesource_init(&fsrc, input_file_name, SRSRAN_COMPLEX_FLOAT_BIN)) {
printf("Error opening file %s\n", input_file_name); printf("Error opening file %s\n", input_file_name);
return SRSRAN_ERROR; goto clean_exit;
} }
// alloc memory // Allocate memory
uint32_t sf_n_samples = SRSRAN_SF_LEN_PRB(nof_prb); uint32_t sf_n_samples = SRSRAN_SF_LEN_PRB(nof_prb);
printf("I/Q samples per subframe=%d\n", sf_n_samples); printf("I/Q samples per subframe=%d\n", sf_n_samples);
uint32_t sf_n_re = SRSRAN_CP_NSYMB(SRSRAN_CP_NORM) * SRSRAN_NRE * 2 * nof_prb; uint32_t sf_n_re = SRSRAN_CP_NSYMB(SRSRAN_CP_NORM) * SRSRAN_NRE * 2 * nof_prb;
cf_t* sf_buffer = srsran_vec_cf_malloc(sf_n_re); sf_buffer = srsran_vec_cf_malloc(sf_n_re);
cf_t* input_buffer = srsran_vec_cf_malloc(sf_n_samples); input_buffer = srsran_vec_cf_malloc(sf_n_samples);
cf_t* input_buffer_temp = srsran_vec_cf_malloc(sf_n_samples); input_buffer_temp = srsran_vec_cf_malloc(sf_n_samples);
// init PSSS if (input_buffer == NULL || input_buffer_temp == NULL || sf_buffer == NULL) {
srsran_psss_t psss = {}; ERROR("Error allocating buffers");
srsran_psss_init(&psss, nof_prb, cp); goto clean_exit;
}
struct timeval t[3]; struct timeval t[3];
gettimeofday(&t[1], NULL); gettimeofday(&t[1], NULL);
@ -135,7 +149,7 @@ int main(int argc, char** argv)
break; break;
} else if (samples_read != sf_n_samples) { } else if (samples_read != sf_n_samples) {
printf("Could only read %d of %d requested samples\n", samples_read, sf_n_samples); printf("Could only read %d of %d requested samples\n", samples_read, sf_n_samples);
return SRSRAN_ERROR; goto clean_exit;
} }
// Find PSSS signal // Find PSSS signal
@ -149,11 +163,21 @@ int main(int argc, char** argv)
num_subframes++; num_subframes++;
} while (samples_read == sf_n_samples && num_subframes < max_subframes); } while (samples_read == sf_n_samples && num_subframes < max_subframes);
ret = (sync == SRSRAN_SUCCESS);
clean_exit:
srsran_filesource_free(&fsrc); srsran_filesource_free(&fsrc);
srsran_psss_free(&psss); srsran_psss_free(&psss);
if (input_buffer != NULL) {
free(input_buffer); free(input_buffer);
}
if (input_buffer_temp != NULL) {
free(input_buffer_temp); free(input_buffer_temp);
}
if (sf_buffer != NULL) {
free(sf_buffer); free(sf_buffer);
}
return (sync == SRSRAN_SUCCESS); return ret;
} }

@ -199,6 +199,11 @@ static int test_case_1(srsran_ssb_t* ssb)
} }
} }
if (!count) {
ERROR("Error in test case 1: undefined division");
return SRSRAN_ERROR;
}
INFO("test_case_1 - %.1f usec/encode; %.1f usec/decode; %.1f usec/decode;", INFO("test_case_1 - %.1f usec/encode; %.1f usec/decode; %.1f usec/decode;",
(double)t_encode_usec / (double)(count), (double)t_encode_usec / (double)(count),
(double)t_decode_usec / (double)(count), (double)t_decode_usec / (double)(count),

@ -215,6 +215,12 @@ static int test_case_1(srsran_ue_sync_nr_t* ue_sync)
{ {
for (uint32_t sf_idx = 0; sf_idx < nof_sf; sf_idx++) { for (uint32_t sf_idx = 0; sf_idx < nof_sf; sf_idx++) {
srsran_ue_sync_nr_outcome_t outcome = {}; srsran_ue_sync_nr_outcome_t outcome = {};
// Prevent buffer overflow in srsran_ue_sync_nr_zerocopy
if (ue_sync->nof_rx_channels > 1) {
ERROR("Error configuring number of RX channels");
return SRSRAN_ERROR;
}
TESTASSERT(srsran_ue_sync_nr_zerocopy(ue_sync, &buffer, &outcome) == SRSRAN_SUCCESS); TESTASSERT(srsran_ue_sync_nr_zerocopy(ue_sync, &buffer, &outcome) == SRSRAN_SUCCESS);
// Print outcome // Print outcome

@ -958,7 +958,7 @@ int srsran_ue_sync_run_find_gnss_mode(srsran_ue_sync_t* q,
srsran_timestamp_sub(&ts_tmp, 0, 0.001); ///< account for samples that have already been rx'ed srsran_timestamp_sub(&ts_tmp, 0, 0.001); ///< account for samples that have already been rx'ed
align_len = srsran_timestamp_uint64(&ts_tmp, q->sf_len * 1000); align_len = srsran_timestamp_uint64(&ts_tmp, q->sf_len * 1000);
if (align_len > q->sf_len * 1000) { if (align_len > (uint64_t)q->sf_len * 1000) {
ts_next_rx.full_secs++; ts_next_rx.full_secs++;
ts_next_rx.frac_secs = 0.0; ts_next_rx.frac_secs = 0.0;
srsran_timestamp_copy(&ts_tmp, &ts_next_rx); srsran_timestamp_copy(&ts_tmp, &ts_next_rx);

Loading…
Cancel
Save