Files
openairinterface5g/openair1/PHY/TOOLS/tests/test_channel_pipeline_tools.c
T
Bartosz Podrygajlo 47ba5d3ca5 Acceleration of channel convolution and noise generation
Added two versions of channel convolution and noise generation:
 - accelerated via threadpool
 - accelerated using CUDA

The main difference between this and previous versions of channel
convolution implementations is that these functions take a real-world
approach to input/output where both could be split unevenly over a set of
buffers, e.g. ring buffers used in vrtsim.

The CUDA-accelerated version only works on systems with unified memory, e.g. NVidia
DGX Spark or GH
2026-03-30 09:48:50 +02:00

85 lines
2.4 KiB
C

/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include <stdlib.h>
#include "test_channel_pipeline_tools.h"
#include "channel_pipeline.h"
#include "thread-pool.h"
void *init_tpool(int num_threads)
{
tpool_t *tpool = malloc(sizeof(*tpool));
initFloatingCoresTpool(num_threads, tpool, false, NULL);
return tpool;
}
void destroy_tpool(void *tpool)
{
abortTpool((tpool_t *)tpool);
free(tpool);
}
void channel_convolution_cpu(const cf_t **channel,
const c16_t **tx_sig0,
const c16_t **tx_sig1,
int num_samples_tx_sig0,
c16_t **rx_sig0,
c16_t **rx_sig1,
int num_samples_rx_sig0,
int num_samples,
int channel_length,
int nb_tx,
int nb_rx)
{
for (int rx_ant = 0; rx_ant < nb_rx; rx_ant++) {
for (int i = 0; i < num_samples; i++) {
float rx_r = 0.0f;
float rx_i = 0.0f;
for (int tx_ant = 0; tx_ant < nb_tx; tx_ant++) {
for (int l = 0; l < channel_length; l++) {
int idx = i + (channel_length - 1) - l;
c16_t in_sample;
if (idx < num_samples_tx_sig0) {
in_sample = tx_sig0[tx_ant][idx];
} else {
in_sample = tx_sig1[tx_ant][idx - num_samples_tx_sig0];
}
cf_t tx_sample = {(float)in_sample.r, (float)in_sample.i};
int chan_idx = tx_ant + nb_tx * rx_ant;
cf_t ch = channel[chan_idx][l];
rx_r += tx_sample.r * ch.r - tx_sample.i * ch.i;
rx_i += tx_sample.r * ch.i + tx_sample.i * ch.r;
}
}
if (i < num_samples_rx_sig0) {
rx_sig0[rx_ant][i].r = (int16_t)rx_r;
rx_sig0[rx_ant][i].i = (int16_t)rx_i;
} else {
rx_sig1[rx_ant][i - num_samples_rx_sig0].r = (int16_t)rx_r;
rx_sig1[rx_ant][i - num_samples_rx_sig0].i = (int16_t)rx_i;
}
}
}
}
void generate_random_signal(c16_t *sig, int num_samples)
{
for (int i = 0; i < num_samples; i++) {
sig[i].r = (rand() % 2000) - 1000;
sig[i].i = (rand() % 2000) - 1000;
}
}
void generate_random_signal_float(cf_t *sig, int num_samples)
{
for (int i = 0; i < num_samples; i++) {
sig[i].r = (rand() % 2000) - 1000;
sig[i].i = (rand() % 2000) - 1000;
}
}