mod: unit test code to compare CM and SIMD results on both antennas
This commit is contained in:
committed by
Matthias Mehlhose
parent
7d27592b4f
commit
905a8a495e
@@ -63,6 +63,7 @@ TEST(NrLayerPrecoderTest, Basic)
|
|||||||
{
|
{
|
||||||
constexpr int n_layers = 2;
|
constexpr int n_layers = 2;
|
||||||
constexpr int symbol_size = 24;
|
constexpr int symbol_size = 24;
|
||||||
|
constexpr int n_ants = 2;
|
||||||
constexpr int ant = 1;
|
constexpr int ant = 1;
|
||||||
constexpr int re_cnt = 24;
|
constexpr int re_cnt = 24;
|
||||||
|
|
||||||
@@ -72,6 +73,8 @@ TEST(NrLayerPrecoderTest, Basic)
|
|||||||
|
|
||||||
for (int i = 0; i < n_layers * symbol_size; ++i) {
|
for (int i = 0; i < n_layers * symbol_size; ++i) {
|
||||||
buffer_in[i] = {static_cast<int16_t>(i + 1), static_cast<int16_t>(-i - 1)};
|
buffer_in[i] = {static_cast<int16_t>(i + 1), static_cast<int16_t>(-i - 1)};
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n_ants * symbol_size; ++i) {
|
||||||
buffer_out[i] = {static_cast<int16_t>(0), static_cast<int16_t>(0)};
|
buffer_out[i] = {static_cast<int16_t>(0), static_cast<int16_t>(0)};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +110,7 @@ TEST(NrLayerPrecoderTest, SIMD)
|
|||||||
{
|
{
|
||||||
constexpr int n_layers = 2;
|
constexpr int n_layers = 2;
|
||||||
constexpr int symbol_size = 24;
|
constexpr int symbol_size = 24;
|
||||||
|
constexpr int n_ants = 2;
|
||||||
constexpr int ant = 1;
|
constexpr int ant = 1;
|
||||||
constexpr int re_cnt = 24;
|
constexpr int re_cnt = 24;
|
||||||
|
|
||||||
@@ -116,6 +120,8 @@ TEST(NrLayerPrecoderTest, SIMD)
|
|||||||
|
|
||||||
for (int i = 0; i < n_layers * symbol_size; ++i) {
|
for (int i = 0; i < n_layers * symbol_size; ++i) {
|
||||||
buffer_in[i] = {static_cast<int16_t>(i + 1), static_cast<int16_t>(-i - 1)};
|
buffer_in[i] = {static_cast<int16_t>(i + 1), static_cast<int16_t>(-i - 1)};
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n_ants * symbol_size; ++i) {
|
||||||
buffer_out[i] = {static_cast<int16_t>(0), static_cast<int16_t>(0)};
|
buffer_out[i] = {static_cast<int16_t>(0), static_cast<int16_t>(0)};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +152,64 @@ TEST(NrLayerPrecoderTest, SIMD)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(NrLayerPrecoderTest, Compare_CM_SIMD)
|
||||||
|
{
|
||||||
|
constexpr int n_layers = 1;
|
||||||
|
constexpr int symbol_size = 24;
|
||||||
|
constexpr int n_ants = 2;
|
||||||
|
constexpr int re_cnt = 24;
|
||||||
|
|
||||||
|
// Initialize the 2D input data buffer
|
||||||
|
std::vector<c16_t> buffer_in(n_layers * symbol_size);
|
||||||
|
std::vector<c16_t> buffer_out(n_ants * symbol_size);
|
||||||
|
std::vector<c16_t> buffer_out2(n_ants * symbol_size);
|
||||||
|
|
||||||
|
for (int i = 0; i < n_layers * symbol_size; ++i) {
|
||||||
|
buffer_in[i] = {static_cast<int16_t>(i + 1), static_cast<int16_t>(-i - 1)};
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n_ants * symbol_size; ++i) {
|
||||||
|
buffer_out[i] = {static_cast<int16_t>(0), static_cast<int16_t>(0)};
|
||||||
|
buffer_out2[i] = {static_cast<int16_t>(0), static_cast<int16_t>(0)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast flat buffer to the required 2D Variable-Length Array (VLA) style pointer
|
||||||
|
c16_t(*dataF_in)[symbol_size] = reinterpret_cast<c16_t(*)[symbol_size]>(buffer_in.data());
|
||||||
|
c16_t(*dataF_out)[symbol_size] = reinterpret_cast<c16_t(*)[symbol_size]>(buffer_out.data());
|
||||||
|
c16_t(*dataF_out2)[symbol_size] = reinterpret_cast<c16_t(*)[symbol_size]>(buffer_out2.data());
|
||||||
|
|
||||||
|
// Create and populate the pmi_pdu structure
|
||||||
|
nfapi_nr_pm_pdu_t pmi_pdu = {0};
|
||||||
|
pmi_pdu.pm_idx = 4;
|
||||||
|
for (int layer = 0; layer < n_layers; ++layer) {
|
||||||
|
// Could not use convert_precoder_weight() as complex.h could not be used in googletest
|
||||||
|
// Use the logic in convert_precoder_weight()
|
||||||
|
// precoder [−1,−j]
|
||||||
|
pmi_pdu.weights[layer][0].precoder_weight_Re = round(-32767 * 1.0);
|
||||||
|
pmi_pdu.weights[layer][0].precoder_weight_Im = 0x0000; // Q15 representation of 0
|
||||||
|
pmi_pdu.weights[layer][1].precoder_weight_Re = 0x0000; // Q15 representation of 0
|
||||||
|
pmi_pdu.weights[layer][1].precoder_weight_Im = round(-32767 * 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the results for all the antenna
|
||||||
|
for (int ant = 0; ant < n_ants; ant++) {
|
||||||
|
|
||||||
|
// Call the C function
|
||||||
|
for (int symbol = 0; symbol < re_cnt; symbol++)
|
||||||
|
dataF_out[ant][symbol] = nr_layer_precoder_cm(n_layers, symbol_size, dataF_in, ant, &pmi_pdu, symbol);
|
||||||
|
|
||||||
|
// Call the C function
|
||||||
|
nr_layer_precoder_simd(n_layers, symbol_size, dataF_in, ant, &pmi_pdu, 0, re_cnt, dataF_out2[ant]);
|
||||||
|
|
||||||
|
// Compare the result from both C function
|
||||||
|
for (int symbol = 0; symbol < re_cnt; symbol++) {
|
||||||
|
EXPECT_EQ(dataF_out_cm[ant][symbol].r, dataF_out_simd[ant][symbol].r)
|
||||||
|
<< " at [" << ant << "][" << symbol << "] got real part: " << dataF_out_cm[ant][symbol].r << " result " << dataF_out_simd[ant][symbol].r;
|
||||||
|
EXPECT_EQ(dataF_out_cm[ant][symbol].i, dataF_out_simd[ant][symbol].i)
|
||||||
|
<< " at [" << ant << "][" << symbol << "] got imag part: " << dataF_out_cm[ant][symbol].i << " result " << dataF_out_simd[ant][symbol].i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ extern "C" {
|
|||||||
__attribute__((always_inline)) inline c16_t c16conj(const c16_t a) {
|
__attribute__((always_inline)) inline c16_t c16conj(const c16_t a) {
|
||||||
return (c16_t) {
|
return (c16_t) {
|
||||||
.r = a.r,
|
.r = a.r,
|
||||||
.i = (int16_t)-a.i
|
.i = (int16_t)-a.i
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,13 +61,7 @@
|
|||||||
|
|
||||||
c16_t convert_precoder_weight(double complex c_in)
|
c16_t convert_precoder_weight(double complex c_in)
|
||||||
{
|
{
|
||||||
double cr = creal(c_in) * 32768 + 0.5;
|
return (c16_t) {.r = round(32767*creal(c_in)), .i = round(32767*cimag(c_in))};
|
||||||
if (cr < 0)
|
|
||||||
cr -= 1;
|
|
||||||
double ci = cimag(c_in) * 32768 + 0.5;
|
|
||||||
if (ci < 0)
|
|
||||||
ci -= 1;
|
|
||||||
return (c16_t) {.r = (short)cr, .i = (short)ci};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers)
|
void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers)
|
||||||
|
|||||||
Reference in New Issue
Block a user