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
This commit is contained in:
Joaquim 2021-10-26 19:59:45 +02:00 committed by GitHub
parent bdbaf7357a
commit 93649429dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 482 additions and 230 deletions

View File

@ -320,9 +320,9 @@ static float estimate_noise_pilots(srsran_chest_dl_t* q, srsran_dl_sf_cfg_t* sf,
float sum_power = 0.0f;
uint32_t count = 0;
uint32_t npilots = (ch_mode == SRSRAN_SF_MBSFN) ? SRSRAN_REFSIGNAL_NUM_SF_MBSFN(q->cell.nof_prb, port_id)
: srsran_refsignal_cs_nof_re(&q->csr_refs, sf, port_id);
uint32_t nsymbols = (ch_mode == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols()
: srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id);
: srsran_refsignal_cs_nof_re(&q->csr_refs, sf, port_id);
uint32_t nsymbols = (ch_mode == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols()
: srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id);
if (nsymbols == 0) {
ERROR("Invalid number of CRS symbols\n");
return SRSRAN_ERROR;
@ -433,8 +433,8 @@ static void interpolate_pilots(srsran_chest_dl_t* q,
uint32_t port_id)
{
/* interpolate the symbols with references in the freq domain */
uint32_t nsymbols = (sf->sf_type == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols() + 1
: srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id);
uint32_t nsymbols = (sf->sf_type == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols() + 1
: srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id);
uint32_t fidx_offset = 0;
/* Interpolate in the frequency domain */
@ -556,7 +556,7 @@ static void average_pilots(srsran_chest_dl_t* q,
{
uint32_t nsymbols = (sf->sf_type == SRSRAN_SF_MBSFN) ? srsran_refsignal_mbsfn_nof_symbols()
: srsran_refsignal_cs_nof_symbols(&q->csr_refs, sf, port_id);
uint32_t nref = (sf->sf_type == SRSRAN_SF_MBSFN) ? 6 * q->cell.nof_prb : 2 * q->cell.nof_prb;
uint32_t nref = (sf->sf_type == SRSRAN_SF_MBSFN) ? 6 * q->cell.nof_prb : 2 * q->cell.nof_prb;
// Average in the time domain if enabled
if (cfg->estimator_alg == SRSRAN_ESTIMATOR_ALG_AVERAGE && nsymbols > 1) {
@ -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++) {
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++) {
if (q->noise_estimate[a]) {
res->snr_ant_port_db[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->snr_ant_port_db[a][port_id] =
srsran_convert_power_to_dB(q->rsrp[a][port_id] / q->noise_estimate[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] =
srsran_convert_power_to_dB(q->cell.nof_prb * q->rsrp[a][port_id] / q->rssi[a][port_id]);

View File

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

View File

@ -760,6 +760,8 @@ int srsran_csi_rs_nzp_measure_trs(const srsran_carrier_nr_t* carrier,
// Perform Measurements
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);
// Return to prevent assigning negative values to count
if (ret < SRSRAN_SUCCESS) {
ERROR("Error performing measurements");
return SRSRAN_ERROR;
@ -856,6 +858,8 @@ int srsran_csi_rs_nzp_measure_channel(const srsran_carrier_nr_t* carrier
// Perform Measurements
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);
// Return to prevent assigning negative values to count
if (ret < SRSRAN_SUCCESS) {
ERROR("Error performing measurements");
return SRSRAN_ERROR;
@ -1032,8 +1036,11 @@ int srsran_csi_rs_zp_measure_channel(const srsran_carrier_nr_t* carrier,
// Perform Measurements
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);
// Return to prevent assigning negative values to count
if (ret < SRSRAN_SUCCESS) {
ERROR("Error performing measurements");
return SRSRAN_ERROR;
}
uint32_t count = (uint32_t)ret;

View File

@ -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);
#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
corr[l] = srsran_vec_acc_cc(tmp, nof_pilots) / (float)nof_pilots;

View File

@ -14,6 +14,7 @@
#include "srsran/phy/common/sequence.h"
#include "srsran/phy/utils/debug.h"
#include "srsran/phy/utils/vector.h"
#include <assert.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...
@ -182,7 +183,11 @@ int srsran_dmrs_pucch_format1_estimate(const srsran_pucch_nr_t* q,
return SRSRAN_ERROR;
}
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;
for (uint32_t m = 0; m < n_pucch; m++) {
// 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];
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
srsran_vec_prod_conj_ccc(slot_symbols_ptr, z, ce[m], SRSRAN_NRE);
}

View File

@ -27,7 +27,6 @@
*/
int srsran_refsignal_cs_init(srsran_refsignal_t* q, uint32_t max_prb)
{
int ret = SRSRAN_ERROR_INVALID_INPUTS;
if (q != NULL) {
@ -56,7 +55,6 @@ free_and_exit:
*/
int srsran_refsignal_cs_set_cell(srsran_refsignal_t* q, srsran_cell_t cell)
{
uint32_t c_init;
uint32_t N_cp, mp;
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)
{
uint32_t ret = 0;
if (l == 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 ret = SRSRAN_SUCCESS;
int ret = SRSRAN_ERROR_INVALID_INPUTS;
q->cell = cell;
if (q == NULL) {
ret = SRSRAN_ERROR_INVALID_INPUTS;
goto exit;
}
q->cell = cell;
q->mbsfn_area_id = mbsfn_area_id;
if (srsran_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id)) {
goto free_and_exit;
if (srsran_refsignal_mbsfn_gen_seq(q, q->cell, q->mbsfn_area_id) < SRSRAN_SUCCESS) {
ret = SRSRAN_ERROR;
goto exit;
}
ret = SRSRAN_SUCCESS;
free_and_exit:
if (ret == SRSRAN_ERROR) {
srsran_refsignal_free(q);
}
exit:
return ret;
}

View File

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

View File

@ -78,6 +78,9 @@ static int run_test(srsran_dmrs_pdcch_estimator_t* estimator,
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++) {
dci_location.ncce = locations[candidate];

View File

@ -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);
if (!q->table_cos || !q->table_log) {
ERROR("Malloc");
return SRSRAN_ERROR;
}
// Fill tables

View File

@ -40,7 +40,7 @@ static void usage(char* prog)
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;
while ((opt = getopt(argc, argv, "nmMst")) != -1) {
@ -62,9 +62,10 @@ static void parse_args(int argc, char** argv)
break;
default:
usage(argv[0]);
exit(-1);
return SRSRAN_ERROR;
}
}
return SRSRAN_SUCCESS;
}
int main(int argc, char** argv)
@ -75,8 +76,15 @@ int main(int argc, char** argv)
uint64_t count_samples = 0;
uint64_t count_us = 0;
#ifdef ENABLE_GUI
cf_t* fft_out = NULL;
#endif
// Parse arguments
parse_args(argc, argv);
if (parse_args(argc, argv) < SRSRAN_SUCCESS) {
ret = SRSRAN_ERROR;
goto clean_exit;
}
// Initialise buffers
input_buffer = srsran_vec_cf_malloc(nof_samples);
@ -85,6 +93,7 @@ int main(int argc, char** argv)
if (!input_buffer || !output_buffer) {
ERROR("Error: Allocating memory");
ret = SRSRAN_ERROR;
goto clean_exit;
}
// Initialise input
@ -104,24 +113,31 @@ int main(int argc, char** argv)
plot_scatter_setTitle(&plot_fft, "IQ");
plot_scatter_addToWindowGrid(&plot_fft, (char*)"IQ", 1, 0);
cf_t* fft_out = srsran_vec_cf_malloc(nof_samples);
srsran_dft_plan_t fft = {};
fft_out = srsran_vec_cf_malloc(nof_samples);
srsran_dft_plan_t fft = {};
if (srsran_dft_plan_c(&fft, nof_samples, SRSRAN_DFT_FORWARD)) {
ERROR("Error: init DFT");
ret = SRSRAN_ERROR;
goto clean_exit;
}
#endif /* ENABLE_GUI */
// Initialise AWGN channel
if (ret == SRSRAN_SUCCESS) {
ret = srsran_channel_awgn_init(&awgn, 0);
if (srsran_channel_awgn_init(&awgn, 0) < SRSRAN_SUCCESS) {
ERROR("Error initialising AWGN channel");
ret = SRSRAN_ERROR;
goto clean_exit;
}
float n0 = n0_min;
while (!isnan(n0) && !isinf(n0) && n0 < n0_max) {
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
gettimeofday(&t[1], NULL);
@ -166,13 +182,28 @@ int main(int argc, char** argv)
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);
if (input_buffer) {
free(input_buffer);
}
if (output_buffer) {
free(output_buffer);
}
@ -184,13 +215,5 @@ int main(int argc, char** argv)
srsran_dft_plan_free(&fft);
#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;
}

View File

@ -37,7 +37,7 @@ static void usage(char* prog)
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;
while ((opt = getopt(argc, argv, "mMtsT")) != -1) {
@ -59,14 +59,15 @@ static void parse_args(int argc, char** argv)
break;
default:
usage(argv[0]);
exit(-1);
return SRSRAN_ERROR;
}
}
return SRSRAN_SUCCESS;
}
int main(int argc, char** argv)
{
int ret = SRSRAN_SUCCESS;
int ret = SRSRAN_ERROR;
cf_t* input_buffer = NULL;
cf_t* output_buffer = NULL;
srsran_timestamp_t ts = {}; // Initialised to zero
@ -74,28 +75,32 @@ int main(int argc, char** argv)
struct timeval t[3] = {};
// Parse arguments
parse_args(argc, argv);
if (parse_args(argc, argv) < SRSRAN_SUCCESS) {
goto clean_exit;
}
// Initialise buffers
uint32_t size = srate_hz / 1000;
input_buffer = srsran_vec_cf_malloc(size);
output_buffer = srsran_vec_cf_malloc(size);
if (!input_buffer || !output_buffer) {
fprintf(stderr, "Error: Allocating memory\n");
ret = SRSRAN_ERROR;
ERROR("Error: Allocating memory");
goto clean_exit;
}
// Generate random samples
srsran_random_uniform_complex_dist_vector(random_gen, input_buffer, size, -1.0f, +1.0f);
// Initialise delay channel
if (ret == SRSRAN_SUCCESS) {
ret = srsran_channel_delay_init(&delay, delay_min_us, delay_max_us, delay_period_s, delay_init_time_s, srate_hz);
if (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
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++) {
// Run delay channel
srsran_channel_delay_execute(&delay, input_buffer, output_buffer, size, &ts);
@ -107,7 +112,28 @@ int main(int argc, char** argv)
gettimeofday(&t[2], NULL);
get_time_interval(t);
// Free
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 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
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_max_us,
delay_period_s,
srate_hz,
sim_time_periods,
(ret == SRSRAN_SUCCESS) ? "Passed" : "Failed",
msps);
clean_exit:
srsran_random_free(random_gen);
srsran_channel_delay_free(&delay);
@ -119,17 +145,5 @@ int main(int argc, char** argv)
free(output_buffer);
}
uint64_t nof_samples = sim_time_periods * 1000 * delay_period_s * size;
double elapsed_us = t[0].tv_sec * 1e6 + t[0].tv_usec;
// 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",
delay_min_us,
delay_max_us,
delay_period_s,
srate_hz,
sim_time_periods,
(ret == SRSRAN_SUCCESS) ? "Passed" : "Failed",
(double)nof_samples / elapsed_us);
exit(ret);
return (ret);
}

View File

@ -49,7 +49,7 @@ static void usage(char* prog)
#endif /* ENABLE_GUI */
}
static void parse_args(int argc, char** argv)
static int parse_args(int argc, char** argv)
{
int opt;
while ((opt = getopt(argc, argv, "mtsrg")) != -1) {
@ -73,9 +73,10 @@ static void parse_args(int argc, char** argv)
break;
default:
usage(argv[0]);
exit(-1);
return SRSRAN_ERROR;
}
}
return SRSRAN_SUCCESS;
}
int main(int argc, char** argv)
@ -86,7 +87,16 @@ int main(int argc, char** argv)
struct timeval t[3] = {};
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_c(&ifft, srate / 1000, SRSRAN_DFT_BACKWARD);
@ -96,10 +106,7 @@ int main(int argc, char** argv)
plot_real_t plot_h = NULL;
plot_real_t plot_imp = NULL;
srsran_dft_plan_t fft = {};
cf_t* fft_buffer = NULL;
float* fft_mag = NULL;
float* imp = NULL;
srsran_dft_plan_t fft = {};
if (enable_gui) {
sdrgui_init();
@ -207,15 +214,17 @@ int main(int argc, char** argv)
#endif /* ENABLE_GUI */
}
ret = SRSRAN_SUCCESS;
clean_exit:
if (ret) {
printf("Error\n");
// 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;
} 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);
#ifdef ENABLE_GUI

View File

@ -11,6 +11,7 @@
*/
#include "srsran/common/test_common.h"
#include "srsran/phy/common/sliv.h"
#include <srsran/phy/utils/debug.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -38,34 +39,52 @@ static int test()
int main(int argc, char** argv)
{
int ret = SRSRAN_ERROR;
// Parse N
if (argc >= 2) {
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 (argc == 2) {
return test();
else if (argc == 2) {
ret = test();
}
// 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 S = 0;
uint32_t L = 0;
srsran_sliv_to_s_and_l(N, sliv, &S, &L);
printf("SLIV=%d; Start: %d; Length: %d;\n", sliv, S, L);
return SRSRAN_SUCCESS;
// 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);
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 (argc == 4) {
else if (argc == 4) {
uint32_t s = (uint32_t)strtol(argv[2], NULL, 10);
uint32_t l = (uint32_t)strtol(argv[3], NULL, 10);
uint32_t sliv = srsran_sliv_from_s_and_l(N, 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;
}

View File

@ -15,10 +15,13 @@
#include "srsran/phy/utils/debug.h"
#include "srsran/phy/utils/primes.h"
#include "srsran/phy/utils/vector.h"
#include <assert.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
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, -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},
@ -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}};
// 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},
{-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},
@ -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}};
// 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},
{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},
@ -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}};
// 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, 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},
@ -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}};
// 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},
{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},
@ -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}};
// 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, 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},
@ -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)
{
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}

View File

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

View File

@ -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++) {
current_var_index = these_var_indices[i_layer][0];
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;
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);
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];
}
}

View File

@ -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];
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;
for (j = 0; j < vp->n_subnodes; j++) {
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);
}
current_var_index = these_var_indices[i_layer][i + 1];
current_var_index = these_var_indices[i_layer][i];
}
}

View File

@ -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++) {
current_var_index = these_var_indices[i_layer][0];
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!
current_var_index_ext = current_var_index * vp->ls;
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;
}
current_var_index = these_var_indices[i_layer][i + 1];
current_var_index = these_var_indices[i_layer][i];
}
}

View File

@ -60,7 +60,7 @@ static uint8_t rv = 0; /*!< \brief Redundancy version {
static srsran_mod_t mod_type = SRSRAN_MOD_BPSK; /*!< \brief Modulation type: BPSK, QPSK, QAM16, QAM64, QAM256 = 4 */
static uint32_t Nref = 0; /*!< \brief Limited buffer size. */
static float snr = 0; /*!< \brief Signal-to-Noise Ratio [dB]. */
static uint8_t rm_aware = 1; /*!< \brief Flag rate matching aware encoding/decoding (1 to enable). */
static uint8_t rm_aware = 1; /*!< \brief Flag rate matching aware encoding/decoding (1 to enable). */
static int finalK = 0; /*!< \brief Number of uncoded bits (message length, including punctured and filler bits). */
static int finalN = 0; /*!< \brief Number of coded bits (codeword length). */
@ -93,7 +93,7 @@ void usage(char* prog)
/*!
* \brief Parses the input line.
*/
void parse_args(int argc, char** argv)
int parse_args(int argc, char** argv)
{
int opt = 0;
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;
default:
usage(argv[0]);
exit(-1);
return SRSRAN_ERROR;
}
}
return SRSRAN_SUCCESS;
}
/*!
* \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.
*/
int main(int argc, char** argv)
{
int ret = SRSRAN_ERROR;
uint8_t* messages_true = NULL;
uint8_t* messages_sim_f = NULL;
uint8_t* messages_sim_s = NULL;
@ -169,29 +172,68 @@ int main(int argc, char** argv)
int16_t* symbols_s = 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 j = 0;
parse_args(argc, argv);
// create an LDPC encoder
srsran_ldpc_encoder_t encoder;
if (parse_args(argc, argv) < SRSRAN_SUCCESS) {
goto clean_exit;
}
#ifdef LV_HAVE_AVX512
if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_AVX512, base_graph, lift_size) != 0) {
perror("encoder init");
exit(-1);
goto clean_exit;
}
#else // no AVX512
#ifdef LV_HAVE_AVX2
if (srsran_ldpc_encoder_init(&encoder, SRSRAN_LDPC_ENCODER_AVX2, base_graph, lift_size) != 0) {
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) {
perror("encoder init");
exit(-1);
goto clean_exit;
}
#endif // LV_HAVE_AVX2
#endif // LV_HAVE_AVX512
@ -206,32 +248,28 @@ int main(int argc, char** argv)
Nref = finalN;
}
// create a LDPC rate Matcher
srsran_ldpc_rm_t rm_tx;
// Init the LDPC rate Matcher
if (srsran_ldpc_rm_tx_init(&rm_tx) != 0) {
perror("rate matcher init");
exit(-1);
goto clean_exit;
}
// create a LDPC rate DeMatcher
srsran_ldpc_rm_t rm_rx;
// Init LDPC rate DeMatcher
if (srsran_ldpc_rm_rx_init_f(&rm_rx) != 0) {
perror("rate dematcher init");
exit(-1);
goto clean_exit;
}
// create a LDPC rate DeMatcher (int16_t)
srsran_ldpc_rm_t rm_rx_s;
// Init LDPC rate DeMatcher (int16_t)
if (srsran_ldpc_rm_rx_init_s(&rm_rx_s) != 0) {
perror("rate dematcher init (int16_t)");
exit(-1);
goto clean_exit;
}
// create a LDPC rate DeMatcher (int8_t)
srsran_ldpc_rm_t rm_rx_c;
// Init LDPC rate DeMatcher (int8_t)
if (srsran_ldpc_rm_rx_init_c(&rm_rx_c) != 0) {
perror("rate dematcher init (int8_t)");
exit(-1);
goto clean_exit;
}
// Create LDPC configuration arguments
@ -240,73 +278,62 @@ int main(int argc, char** argv)
decoder_args.ls = lift_size;
decoder_args.scaling_fctr = MS_SF;
// create an LDPC decoder (float)
srsran_ldpc_decoder_t decoder_f;
// Init the LDPC decoder (float)
decoder_args.type = SRSRAN_LDPC_DECODER_F;
if (srsran_ldpc_decoder_init(&decoder_f, &decoder_args) != 0) {
perror("decoder init");
exit(-1);
goto clean_exit;
}
// create an LDPC decoder (16 bit)
srsran_ldpc_decoder_t decoder_s;
// Init the LDPC decoder (16 bit)
decoder_args.type = SRSRAN_LDPC_DECODER_S;
if (srsran_ldpc_decoder_init(&decoder_s, &decoder_args) != 0) {
perror("decoder init (int16_t)");
exit(-1);
goto clean_exit;
}
// create an LDPC decoder (8 bit)
srsran_ldpc_decoder_t decoder_c;
// Init the LDPC decoder (8 bit)
decoder_args.type = SRSRAN_LDPC_DECODER_C;
if (srsran_ldpc_decoder_init(&decoder_c, &decoder_args) != 0) {
perror("decoder init (int8_t)");
exit(-1);
goto clean_exit;
}
// create an LDPC decoder (8 bit, flooded)
srsran_ldpc_decoder_t decoder_c_flood;
// Init the LDPC decoder (8 bit, flooded)
decoder_args.type = SRSRAN_LDPC_DECODER_C_FLOOD;
if (srsran_ldpc_decoder_init(&decoder_c_flood, &decoder_args) != 0) {
perror("decoder init");
exit(-1);
goto clean_exit;
}
#ifdef LV_HAVE_AVX2
// create an LDPC decoder (8 bit, AVX2 version)
srsran_ldpc_decoder_t decoder_avx;
// Init the LDPC decoder (8 bit, AVX2 version)
decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX2;
if (srsran_ldpc_decoder_init(&decoder_avx, &decoder_args) != 0) {
perror("decoder init");
exit(-1);
goto clean_exit;
}
// create an LDPC decoder (8 bit, flooded scheduling, AVX2 version)
srsran_ldpc_decoder_t decoder_avx_flood;
// Init the LDPC decoder (8 bit, flooded scheduling, AVX2 version)
decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX2_FLOOD;
if (srsran_ldpc_decoder_init(&decoder_avx_flood, &decoder_args) != 0) {
perror("decoder init");
exit(-1);
goto clean_exit;
}
#endif // LV_HAVE_AVX2
#ifdef LV_HAVE_AVX512
// create an LDPC decoder (8 bit, AVX2 version)
srsran_ldpc_decoder_t decoder_avx512;
// Init the LDPC decoder (8 bit, AVX512 version)
decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX512;
if (srsran_ldpc_decoder_init(&decoder_avx512, &decoder_args) != 0) {
perror("decoder init");
exit(-1);
goto clean_exit;
}
// create an LDPC decoder (8 bit, flooded scheduling, AVX512 version)
srsran_ldpc_decoder_t decoder_avx512_flood;
// Init LDPC decoder (8 bit, flooded scheduling, AVX512 version)
decoder_args.type = SRSRAN_LDPC_DECODER_C_AVX512_FLOOD;
if (srsran_ldpc_decoder_init(&decoder_avx512_flood, &decoder_args) != 0) {
perror("decoder init");
exit(-1);
goto clean_exit;
}
#endif // LV_HAVE_AVX512
// create a random generator
srsran_random_t random_gen = srsran_random_init(0);
printf("Test LDPC chain:\n");
printf(" Base Graph -> BG%d\n", encoder.bg + 1);
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 ||
!symbols || !symbols_s || !symbols_c) {
perror("malloc");
exit(-1);
goto clean_exit;
}
int i_bit = 0;
@ -479,7 +506,7 @@ int main(int argc, char** argv)
rv,
mod_type,
Nref)) {
exit(-1);
goto clean_exit;
}
}
@ -519,7 +546,7 @@ int main(int argc, char** argv)
rv,
mod_type,
Nref)) {
exit(-1);
goto clean_exit;
}
}
@ -559,7 +586,7 @@ int main(int argc, char** argv)
rv,
mod_type,
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 * finalN / elapsed_time_enc);
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 (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("FLOATING POINT", i_batch, n_error_words_f, elapsed_time_dec_f) < SRSRAN_SUCCESS) {
goto clean_exit;
}
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
print_decoder("FIXED POINT (8 bits - AVX2)", i_batch, n_error_words_avx, elapsed_time_dec_avx);
print_decoder(
"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 - AVX2)", i_batch, n_error_words_avx, elapsed_time_dec_avx) < SRSRAN_SUCCESS) {
goto clean_exit;
}
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
#ifdef LV_HAVE_AVX512
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)",
i_batch,
n_error_words_avx512_flood,
elapsed_time_dec_avx512_flood);
if (print_decoder("FIXED POINT (8 bits - AVX512)", i_batch, n_error_words_avx512, elapsed_time_dec_avx512) <
SRSRAN_SUCCESS) {
goto clean_exit;
}
if (print_decoder("FIXED POINT (8 bits, flooded scheduling - AVX512)",
i_batch,
n_error_words_avx512_flood,
elapsed_time_dec_avx512_flood) < SRSRAN_SUCCESS) {
goto clean_exit;
}
#endif // LV_HAVE_AVX512
if (n_error_words_s > 10 * n_error_words_f) {
perror("16-bit performance too low!");
exit(-1);
goto clean_exit;
}
if (n_error_words_c > 10 * n_error_words_f) {
perror("8-bit performance too low!");
exit(-1);
goto clean_exit;
}
#ifdef LV_HAVE_AVX512
if (n_error_words_avx512 != n_error_words_avx) {
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) {
perror("The number of errors of flooded AVX512 and AVX2 differs !");
exit(-1);
goto clean_exit;
}
#endif // LV_HAVE_AVX512
printf("\nTest completed successfully!\n\n");
ret = SRSRAN_SUCCESS;
free(symbols);
free(symbols_s);
free(symbols_c);
free(rm_symbols);
free(rm_symbols_s);
free(rm_symbols_c);
free(rm_codewords);
free(codewords);
free(messages_sim_avx);
free(messages_sim_avx_flood);
free(messages_sim_avx512);
free(messages_sim_avx512_flood);
free(messages_sim_c_flood);
free(messages_sim_c);
free(messages_sim_s);
free(messages_sim_f);
free(messages_true);
clean_exit:
if (symbols != NULL) {
free(symbols);
}
if (symbols_s != NULL) {
free(symbols_s);
}
if (symbols_c != NULL) {
free(symbols_c);
}
if (rm_symbols != NULL) {
free(rm_symbols);
}
if (rm_symbols_s != NULL) {
free(rm_symbols_s);
}
if (rm_symbols_c != NULL) {
free(rm_symbols_c);
}
if (rm_codewords != NULL) {
free(rm_codewords);
}
if (codewords != NULL) {
free(codewords);
}
if (messages_sim_avx != NULL) {
free(messages_sim_avx);
}
if (messages_sim_avx_flood != NULL) {
free(messages_sim_avx_flood);
}
if (messages_sim_avx512 != NULL) {
free(messages_sim_avx512);
}
if (messages_sim_avx512_flood != NULL) {
free(messages_sim_avx512_flood);
}
if (messages_sim_c_flood != NULL) {
free(messages_sim_c_flood);
}
if (messages_sim_c != NULL) {
free(messages_sim_c);
}
if (messages_sim_s != NULL) {
free(messages_sim_s);
}
if (messages_sim_f != NULL) {
free(messages_sim_f);
}
if (messages_true != NULL) {
free(messages_true);
}
srsran_random_free(random_gen);
#ifdef LV_HAVE_AVX2
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_s(&rm_rx_s);
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("\nEstimated word error rate:\n %e (%d errors)\n", (double)n_errors / n_batches / batch_size, n_errors);
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("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 * finalK / elapsed_time,
n_batches * batch_size * finalN / elapsed_time);
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 * finalK / elapsed_time,
n_batches * batch_size * finalN / elapsed_time);
return SRSRAN_SUCCESS;
}
}

View File

@ -303,7 +303,7 @@ int srsran_cqi_value_tostring(srsran_cqi_cfg_t* cfg, srsran_cqi_value_t* value,
ret = cqi_hl_subband_tostring(cfg, &value->subband_hl, buff, buff_len);
break;
default:
/* Do nothing */;
/* Do nothing */;
}
return ret;
@ -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)
{
if (nof_prb < 7) {
return 0;
ERROR("Error: nof_prb is invalid (< 7)");
return SRSRAN_ERROR;
} else if (nof_prb <= 26) {
return 4;
} else if (nof_prb <= 63) {
@ -531,7 +532,8 @@ static int cqi_hl_get_subband_size(int nof_prb)
} else if (nof_prb <= 110) {
return 8;
} 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)
{
if (nof_prb < 7) {
return 0;
ERROR("Error: nof_prb is not valid (< 7)");
return SRSRAN_ERROR;
} else if (nof_prb <= 10) {
return 1;
} else if (nof_prb <= 26) {
@ -551,7 +554,8 @@ static int cqi_hl_get_bwp_J(int nof_prb)
} else if (nof_prb <= 110) {
return 4;
} 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)
{
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) {
return (uint32_t)ceil((float)nof_prb / cqi_hl_get_subband_size(nof_prb));
return (uint32_t)ceil((float)nof_prb / K);
} else {
// 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) {
return Nj;
} 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 J = cqi_hl_get_bwp_J(nof_prb);
// Catch the J errors
if (J <= 0)
{
return 0;
}
uint32_t H = J * K + 1;
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;
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 {
return 0;
}

View File

@ -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; "
"false_alarm_prob=%f;\n",
srsran_dci_format_string(format),
@ -332,7 +337,7 @@ static int test_case1()
int main(int argc, char** argv)
{
srsran_regs_t regs;
srsran_regs_t regs = {};
int i;
int ret = SRSRAN_ERROR;

View File

@ -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);
}
// TODO: this condition is never true
if (idx == SRSRAN_RESAMPLE_ARB_N) {
*output = res1;
} else {

View File

@ -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;
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) {
*secs = timespec.get_full_secs();
}

View File

@ -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)) {
q->cfg.beta_pbch = SRSRAN_SSB_DEFAULT_BETA;
q->cfg.beta_pbch_dmrs = SRSRAN_SSB_DEFAULT_BETA;
}
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) {
n0_pss = epre - rsrp_pss;
}
if (epre_pss > rsrp_pss) {
if (epre_sss > rsrp_sss) {
n0_sss = epre - rsrp_sss;
}
float n0 = (n0_pss + n0_sss) / 2.0f;

View File

@ -24,7 +24,7 @@
#include "srsran/phy/sync/ssss.h"
#include "srsran/srsran.h"
char* input_file_name;
char* input_file_name;
float frequency_offset = 0.0;
float snr = 100.0;
srsran_cp_t cp = SRSRAN_CP_NORM;
@ -98,27 +98,41 @@ void parse_args(int argc, char** argv)
int main(int argc, char** argv)
{
int ret = SRSRAN_ERROR;
parse_args(argc, argv);
srsran_use_standard_symbol_size(use_standard_lte_rates);
if (!input_file_name || srsran_filesource_init(&fsrc, input_file_name, SRSRAN_COMPLEX_FLOAT_BIN)) {
printf("Error opening file %s\n", input_file_name);
return SRSRAN_ERROR;
// 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;
}
// alloc memory
if (!input_file_name || srsran_filesource_init(&fsrc, input_file_name, SRSRAN_COMPLEX_FLOAT_BIN)) {
printf("Error opening file %s\n", input_file_name);
goto clean_exit;
}
// Allocate memory
uint32_t sf_n_samples = SRSRAN_SF_LEN_PRB(nof_prb);
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;
cf_t* sf_buffer = srsran_vec_cf_malloc(sf_n_re);
uint32_t sf_n_re = SRSRAN_CP_NSYMB(SRSRAN_CP_NORM) * SRSRAN_NRE * 2 * nof_prb;
sf_buffer = srsran_vec_cf_malloc(sf_n_re);
cf_t* input_buffer = srsran_vec_cf_malloc(sf_n_samples);
cf_t* input_buffer_temp = srsran_vec_cf_malloc(sf_n_samples);
input_buffer = srsran_vec_cf_malloc(sf_n_samples);
input_buffer_temp = srsran_vec_cf_malloc(sf_n_samples);
// init PSSS
srsran_psss_t psss = {};
srsran_psss_init(&psss, nof_prb, cp);
if (input_buffer == NULL || input_buffer_temp == NULL || sf_buffer == NULL) {
ERROR("Error allocating buffers");
goto clean_exit;
}
struct timeval t[3];
gettimeofday(&t[1], NULL);
@ -135,7 +149,7 @@ int main(int argc, char** argv)
break;
} else if (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
@ -149,11 +163,21 @@ int main(int argc, char** argv)
num_subframes++;
} while (samples_read == sf_n_samples && num_subframes < max_subframes);
ret = (sync == SRSRAN_SUCCESS);
clean_exit:
srsran_filesource_free(&fsrc);
srsran_psss_free(&psss);
free(input_buffer);
free(input_buffer_temp);
free(sf_buffer);
return (sync == SRSRAN_SUCCESS);
if (input_buffer != NULL) {
free(input_buffer);
}
if (input_buffer_temp != NULL) {
free(input_buffer_temp);
}
if (sf_buffer != NULL) {
free(sf_buffer);
}
return ret;
}

View File

@ -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;",
(double)t_encode_usec / (double)(count),
(double)t_decode_usec / (double)(count),

View File

@ -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++) {
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);
// Print outcome

View File

@ -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
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.frac_secs = 0.0;
srsran_timestamp_copy(&ts_tmp, &ts_next_rx);