Commit 9d3670ee authored by Bartosz Podrygajlo's avatar Bartosz Podrygajlo

vrtsim: Enable batch processing in perform_channel_modelling

In perfrom_channel_modelling, do convolution in batches which allows
vrtsim to write the channel samples as they are being produced instead
of waiting for the last sample in the slot to be ready.
parent 8f116f68
...@@ -372,6 +372,8 @@ typedef struct { ...@@ -372,6 +372,8 @@ typedef struct {
int nbAnt; int nbAnt;
int flags; int flags;
int aarx; int aarx;
int batch_size;
int num_batches;
c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN]; c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN];
} channel_modelling_args_t; } channel_modelling_args_t;
...@@ -415,48 +417,55 @@ static void perform_channel_modelling(void *arg) ...@@ -415,48 +417,55 @@ static void perform_channel_modelling(void *arg)
} }
} }
for (int aatx = 0; aatx < nb_tx_ant; aatx++) { for (int batch_index = 0; batch_index < channel_modelling_args->num_batches; batch_index++) {
for (int i = 0; i < nsamps; i++) { int start_sample = batch_index * channel_modelling_args->batch_size;
cf_t *impulse_response = channel_impulse_response_p[aatx]; int num_samples = min(channel_modelling_args->batch_size, nsamps - start_sample);
for (int l = 0; l < channel_desc->channel_length; l++) { if (start_sample >= nsamps) {
int idx = i - l; break;
// TODO: Use AVX2 for this }
c16_t tx_input = idx >= 0 ? input_samples[aatx][idx] for (int aatx = 0; aatx < nb_tx_ant; aatx++) {
: channel_modelling_args->saved_samples[aatx][SAVED_SAMPLES_LEN + idx]; for (int i = start_sample; i < start_sample + num_samples; i++) {
samples[i].r += tx_input.r * impulse_response[l].r - tx_input.i * impulse_response[l].i; cf_t *impulse_response = channel_impulse_response_p[aatx];
samples[i].i += tx_input.i * impulse_response[l].r + tx_input.r * impulse_response[l].i; for (int l = 0; l < channel_desc->channel_length; l++) {
int idx = i - l;
// TODO: Use AVX2 for this
c16_t tx_input = idx >= 0 ? input_samples[aatx][idx]
: channel_modelling_args->saved_samples[aatx][SAVED_SAMPLES_LEN + idx];
samples[i].r += tx_input.r * impulse_response[l].r - tx_input.i * impulse_response[l].i;
samples[i].i += tx_input.i * impulse_response[l].r + tx_input.r * impulse_response[l].i;
}
} }
} }
}
// Convert to c16_t // Convert to c16_t
c16_t samples_out[aligned_nsamps] __attribute__((aligned(64))); c16_t samples_out[aligned_nsamps] __attribute__((aligned(64)));
#if defined(__AVX512F__) #if defined(__AVX512F__)
for (int i = 0; i < aligned_nsamps / 8; i++) { for (int i = 0; i < aligned_nsamps / 8; i++) {
simde__m512 *in = (simde__m512 *)&samples[i * 8]; simde__m512 *in = (simde__m512 *)&samples[i * 8];
simde__m256i *out = (simde__m256i *)&samples_out[i * 8]; simde__m256i *out = (simde__m256i *)&samples_out[i * 8];
*out = simde_mm512_cvtsepi32_epi16(simde_mm512_cvtps_epi32(*in)); *out = simde_mm512_cvtsepi32_epi16(simde_mm512_cvtps_epi32(*in));
} }
#elif defined(__AVX2__) #elif defined(__AVX2__)
for (int i = 0; i < aligned_nsamps / 4; i++) { for (int i = 0; i < aligned_nsamps / 4; i++) {
simde__m256 *in = (simde__m256 *)&samples[i * 4]; simde__m256 *in = (simde__m256 *)&samples[i * 4];
simde__m128i *out = (simde__m128i *)&samples_out[i * 4]; simde__m128i *out = (simde__m128i *)&samples_out[i * 4];
*out = simde_mm256_cvtsepi32_epi16(simde_mm256_cvtps_epi32(*in)); *out = simde_mm256_cvtsepi32_epi16(simde_mm256_cvtps_epi32(*in));
} }
#else #else
for (int i = 0; i < nsamps; i++) { for (int i = 0; i < nsamps; i++) {
samples_out[i].r = lroundf(samples[i].r); samples_out[i].r = lroundf(samples[i].r);
samples_out[i].i = lroundf(samples[i].i); samples_out[i].i = lroundf(samples[i].i);
}
#endif
vrtsim_write_internal(channel_modelling_args->vrtsim_state,
channel_modelling_args->timestamp,
samples_out,
channel_modelling_args->nsamps,
aarx,
channel_modelling_args->flags,
aarx);
} }
#endif
vrtsim_write_internal(channel_modelling_args->vrtsim_state,
channel_modelling_args->timestamp,
samples_out,
channel_modelling_args->nsamps,
aarx,
channel_modelling_args->flags,
aarx);
} }
static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state, static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
...@@ -470,6 +479,7 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state, ...@@ -470,6 +479,7 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
static c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN] __attribute__((aligned(32))) = {0}; static c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN] __attribute__((aligned(32))) = {0};
// Indicates what samples are saves in saved_samples // Indicates what samples are saves in saved_samples
static openair0_timestamp last_timestamp = 0; static openair0_timestamp last_timestamp = 0;
const int batch_size = 4096;
AssertFatal(nbAnt <= MAX_NUM_ANTENNAS_TX, "Number of antennas %d exceeds maximum %d\n", nbAnt, MAX_NUM_ANTENNAS_TX); AssertFatal(nbAnt <= MAX_NUM_ANTENNAS_TX, "Number of antennas %d exceeds maximum %d\n", nbAnt, MAX_NUM_ANTENNAS_TX);
for (int aarx = 0; aarx < vrtsim_state->peer_info.num_rx_antennas; aarx++) { for (int aarx = 0; aarx < vrtsim_state->peer_info.num_rx_antennas; aarx++) {
...@@ -481,6 +491,8 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state, ...@@ -481,6 +491,8 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
args->nbAnt = nbAnt; args->nbAnt = nbAnt;
args->flags = flags; args->flags = flags;
args->aarx = aarx; args->aarx = aarx;
args->batch_size = batch_size;
args->num_batches = (nsamps + batch_size - 1) / batch_size;
for (int i = 0; i < nbAnt; i++) { for (int i = 0; i < nbAnt; i++) {
args->samples[i] = samplesVoid[i]; args->samples[i] = samplesVoid[i];
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment