diff --git a/lib/include/srslte/phy/utils/vector.h b/lib/include/srslte/phy/utils/vector.h index a89aa1049..35dcb7c95 100644 --- a/lib/include/srslte/phy/utils/vector.h +++ b/lib/include/srslte/phy/utils/vector.h @@ -139,6 +139,7 @@ SRSLTE_API void srslte_vec_sub_bbb(const int8_t* x, const int8_t* y, int8_t* z, /* scalar product */ SRSLTE_API void srslte_vec_sc_prod_cfc(const cf_t* x, const float h, cf_t* z, const uint32_t len); +SRSLTE_API void srslte_vec_sc_prod_fcc(const float* x, const cf_t h, cf_t* z, const uint32_t len); SRSLTE_API void srslte_vec_sc_prod_ccc(const cf_t* x, const cf_t h, cf_t* z, const uint32_t len); SRSLTE_API void srslte_vec_sc_prod_fff(const float* x, const float h, float* z, const uint32_t len); diff --git a/lib/include/srslte/phy/utils/vector_simd.h b/lib/include/srslte/phy/utils/vector_simd.h index 3ae3eb001..0db7b9c11 100644 --- a/lib/include/srslte/phy/utils/vector_simd.h +++ b/lib/include/srslte/phy/utils/vector_simd.h @@ -42,6 +42,8 @@ SRSLTE_API void srslte_vec_sub_fff_simd(const float* x, const float* y, float* z /* SIMD Vector Scalar Product */ SRSLTE_API void srslte_vec_sc_prod_cfc_simd(const cf_t* x, const float h, cf_t* y, const int len); +SRSLTE_API void srslte_vec_sc_prod_fcc_simd(const float* x, const cf_t h, cf_t* y, const int len); + SRSLTE_API void srslte_vec_sc_prod_fff_simd(const float* x, const float h, float* z, const int len); SRSLTE_API void srslte_vec_sc_prod_ccc_simd(const cf_t* x, const cf_t h, cf_t* z, const int len); diff --git a/lib/src/phy/utils/test/vector_test.c b/lib/src/phy/utils/test/vector_test.c index 460e7a619..77b58f3d2 100644 --- a/lib/src/phy/utils/test/vector_test.c +++ b/lib/src/phy/utils/test/vector_test.c @@ -546,6 +546,20 @@ TEST(srslte_vec_sc_prod_cfc, MALLOC(cf_t, x); MALLOC(cf_t, z); cf_t gold; float free(x); free(z);) +TEST(srslte_vec_sc_prod_fcc, MALLOC(float, x); MALLOC(cf_t, z); cf_t gold; float h = RANDOM_CF(); + + for (int i = 0; i < block_size; i++) { x[i] = RANDOM_CF(); } + + TEST_CALL(srslte_vec_sc_prod_fcc(x, h, z, block_size)) + + for (int i = 0; i < block_size; i++) { + gold = x[i] * h; + mse += cabsf(gold - z[i]); + } + + free(x); + free(z);) + TEST( srslte_vec_div_ccc, MALLOC(cf_t, x); MALLOC(cf_t, y); MALLOC(cf_t, z); @@ -881,6 +895,10 @@ int main(int argc, char** argv) test_srslte_vec_sc_prod_cfc(func_names[func_count], &timmings[func_count][size_count], block_size); func_count++; + passed[func_count][size_count] = + test_srslte_vec_sc_prod_fcc(func_names[func_count], &timmings[func_count][size_count], block_size); + func_count++; + passed[func_count][size_count] = test_srslte_vec_div_ccc(func_names[func_count], &timmings[func_count][size_count], block_size); func_count++; diff --git a/lib/src/phy/utils/vector.c b/lib/src/phy/utils/vector.c index 2064ce65c..e8b8841e5 100644 --- a/lib/src/phy/utils/vector.c +++ b/lib/src/phy/utils/vector.c @@ -87,6 +87,11 @@ void srslte_vec_sc_prod_cfc(const cf_t* x, const float h, cf_t* z, const uint32_ srslte_vec_sc_prod_cfc_simd(x, h, z, len); } +void srslte_vec_sc_prod_fcc(const float* x, const cf_t h, cf_t* z, const uint32_t len) +{ + srslte_vec_sc_prod_fcc_simd(x, h, z, len); +} + // Chest UL void srslte_vec_sc_prod_ccc(const cf_t* x, const cf_t h, cf_t* z, const uint32_t len) { diff --git a/lib/src/phy/utils/vector_simd.c b/lib/src/phy/utils/vector_simd.c index 454902f5a..690e0299a 100644 --- a/lib/src/phy/utils/vector_simd.c +++ b/lib/src/phy/utils/vector_simd.c @@ -1331,6 +1331,29 @@ void srslte_vec_sc_prod_cfc_simd(const cf_t* x, const float h, cf_t* z, const in } } +void srslte_vec_sc_prod_fcc_simd(const float* x, const cf_t h, cf_t* z, const int len) +{ + int i = 0; + +#if SRSLTE_SIMD_F_SIZE + const simd_cf_t tap = srslte_simd_cf_set1(h); + + if (SRSLTE_IS_ALIGNED(x) && SRSLTE_IS_ALIGNED(z)) { + for (; i < len - SRSLTE_SIMD_F_SIZE + 1; i += SRSLTE_SIMD_F_SIZE) { + srslte_simd_cfi_store(&z[i], srslte_simd_cf_mul(tap, srslte_simd_f_load(&x[i]))); + } + } else { + for (; i < len - SRSLTE_SIMD_F_SIZE + 1; i += SRSLTE_SIMD_F_SIZE) { + srslte_simd_cfi_storeu(&z[i], srslte_simd_cf_mul(tap, srslte_simd_f_loadu(&x[i]))); + } + } +#endif + + for (; i < len; i++) { + z[i] = x[i] * h; + } +} + uint32_t srslte_vec_max_fi_simd(const float* x, const int len) { int i = 0;