* INTC Contribution to the O-RAN F Release for O-DU Low
[o-du/phy.git] / fhi_lib / test / common / common.hpp
index 90b320a..2516dba 100644 (file)
@@ -1,21 +1,8 @@
-/******************************************************************************
-*
-*   Copyright (c) 2019 Intel.
-*
-*   Licensed under the Apache License, Version 2.0 (the "License");
-*   you may not use this file except in compliance with the License.
-*   You may obtain a copy of the License at
-*
-*       http://www.apache.org/licenses/LICENSE-2.0
-*
-*   Unless required by applicable law or agreed to in writing, software
-*   distributed under the License is distributed on an "AS IS" BASIS,
-*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-*   See the License for the specific language governing permissions and
-*   limitations under the License.
-*
-*******************************************************************************/
-
+/*******************************************************************************
+ *
+ * <COPYRIGHT_TAG>
+ *
+ *******************************************************************************/
 
 /* This is the new utility file for all tests, all new common functionality has to go here.
    When contributing to the common.hpp please focus on readability and maintainability rather than
@@ -242,6 +229,29 @@ protected:
         parallelization_factor = factor;
     }
 
+    /*!
+        \brief Run the given function and return the mean run time and stddev.
+        \param [in] function Function to benchmark.
+        \param [in] args Function's arguments.
+        \return std::pair where the first element is mean and the second one is standard deviation.
+    */
+    template <typename F, typename ... Args>
+    std::pair<double, double> run_benchmark(F function, Args ... args)
+    {
+        std::vector<long> results((unsigned long) BenchmarkParameters::repetition);
+
+        for(unsigned int outer_loop = 0; outer_loop < BenchmarkParameters::repetition; outer_loop++) {
+            const auto start_time =  __rdtsc();
+            for (unsigned int inner_loop = 0; inner_loop < BenchmarkParameters::loop; inner_loop++) {
+                    function(args ...);
+            }
+            const auto end_time = __rdtsc();
+            results.push_back(end_time - start_time);
+        }
+
+        return calculate_statistics(results);
+    };
+
     /*!
         \brief Run performance test case for a given function.
         \param [in] isa Used Instruction Set.
@@ -308,6 +318,92 @@ protected:
         }
     }
 
+    template <typename T>
+    T get_input_parameter(const std::string &subsection_name, const std::string &parameter_name)
+    {
+        try
+        {
+            return get_parameter<T>("parameters", subsection_name, parameter_name);
+        }
+        catch (std::domain_error &e)
+        {
+            std::cout << "[----------] get_input_parameter (" << subsection_name << "." << parameter_name
+                      << ") failed: " << e.what()
+                      << ". Did you mispell the parameter name?" << std::endl;
+            throw;
+        }
+        catch(reading_input_file_exception &e)
+        {
+            std::cout << "[----------] get_input_parameter (" << subsection_name << "." << parameter_name
+                      << ") failed: " << e.what() << std::endl;
+            throw;
+        }
+    }
+    
+    template <typename T>
+    T get_input_parameter(const std::string &subsection_name, const int index, const std::string &parameter_name)
+    {
+        try
+        {
+            return get_parameter<T>("parameters", subsection_name, index, parameter_name);
+        }
+        catch (std::domain_error &e)
+        {
+            std::cout << "[----------] get_input_parameter (" << subsection_name << "[" << index << "]." << parameter_name
+                      << ") failed: " << e.what()
+                      << ". Did you mispell the parameter name?" << std::endl;
+            throw;
+        }
+        catch(reading_input_file_exception &e)
+        {
+            std::cout << "[----------] get_input_parameter (" << subsection_name << "[" << index << "]." << parameter_name
+                      << ") failed: " << e.what() << std::endl;
+            throw;
+        }
+    }
+    int get_input_parameter_size(const std::string &subsection_name, const std::string &parameter_name)
+    {
+        try
+        {
+            auto array_size = conf[test_type][GetParam()]["parameters"][subsection_name][parameter_name].size();
+            return (array_size);
+        }
+        catch (std::domain_error &e)
+        {
+            std::cout << "[----------] get_input_parameter_size (" << subsection_name << "." << parameter_name
+                      << ") failed: " << e.what()
+                      << ". Did you mispell the parameter name?" << std::endl;
+            return (-1);
+        }
+        catch(reading_input_file_exception &e)
+        {
+            std::cout << "[----------] get_input_parameter_size (" << subsection_name << "." << parameter_name
+                      << ") failed: " << e.what() << std::endl;
+            throw;
+        }
+    }
+    int get_input_subsection_size(const std::string &subsection_name)
+    {
+        try
+        {
+            auto array_size = conf[test_type][GetParam()]["parameters"][subsection_name].size();
+            return (array_size);
+        }
+        catch (std::domain_error &e)
+        {
+            std::cout << "[----------] get_input_subsection_size (" << subsection_name 
+                      << ") failed: " << e.what()
+                      << ". Did you mispell the subsection name?" << std::endl;
+            return (-1);
+        }
+        catch(reading_input_file_exception &e)
+        {
+            std::cout << "[----------] get_input_subsection_size (" << subsection_name
+                      << ") failed: " << e.what() << std::endl;
+            throw;
+        }
+    }
+
     template <typename T>
     T get_reference_parameter(const std::string &parameter_name)
     {
@@ -405,6 +501,93 @@ private:
         return data_reader<T>::read_parameter(GetParam(), type, parameter_name);
     }
 
+    template<typename T>
+    struct data_reader2 {
+        static T read_parameter(const int index, const std::string &type,
+                                const std::string &subsection_name,
+                                const std::string &parameter_name)
+        {
+            return conf[test_type][index][type][subsection_name][parameter_name];
+        }
+    };
+
+    template<typename T>
+    struct data_reader2<std::vector<T>> {
+        static std::vector<T> read_parameter(const int index, const std::string &type,
+                                             const std::string &subsection_name,
+                                             const std::string &parameter_name)
+        {
+            auto array_size = conf[test_type][index][type][subsection_name][parameter_name].size();
+
+            std::vector<T> result(array_size);
+
+            for(unsigned number = 0; number < array_size; number++)
+                result.at(number) = conf[test_type][index][type][subsection_name][parameter_name][number];
+
+            return result;
+        }
+    };
+
+    template<typename T>
+    struct data_reader2<T*> {
+        static T* read_parameter(const int index, const std::string &type,
+                                 const std::string &subsection_name,
+                                 const std::string &parameter_name)
+        {
+            return (T*) read_data_to_aligned_array(conf[test_type][index][type][subsection_name][parameter_name]);
+        }
+    };
+    template <typename T>
+    T get_parameter(const std::string &type, const std::string &subsection_name, const std::string &parameter_name)
+    {
+        return data_reader2<T>::read_parameter(GetParam(), type, subsection_name, parameter_name);
+    }
+
+    template<typename T>
+    struct data_reader3 {
+        static T read_parameter(const int index, const std::string &type,
+                                const std::string &subsection_name,
+                                const int subindex,
+                                const std::string &parameter_name)
+        {
+            return conf[test_type][index][type][subsection_name][subindex][parameter_name];
+        }
+    };
+
+    template<typename T>
+    struct data_reader3<std::vector<T>> {
+        static std::vector<T> read_parameter(const int index, const std::string &type,
+                                             const std::string &subsection_name,
+                                             const int subindex,
+                                             const std::string &parameter_name)
+        {
+            auto array_size = conf[test_type][index][type][subsection_name][subindex][parameter_name].size();
+
+            std::vector<T> result(array_size);
+
+            for(unsigned number = 0; number < array_size; number++)
+                result.at(number) = conf[test_type][index][type][subsection_name][subindex][parameter_name][number];
+
+            return result;
+        }
+    };
+
+    template<typename T>
+    struct data_reader3<T*> {
+        static T* read_parameter(const int index, const std::string &type,
+                                 const std::string &subsection_name,
+                                 const int subindex,
+                                 const std::string &parameter_name)
+        {
+            return (T*) read_data_to_aligned_array(conf[test_type][index][type][subsection_name][subindex][parameter_name]);
+        }
+    };
+    template <typename T>
+    T get_parameter(const std::string &type, const std::string &subsection_name, const int subindex, const std::string &parameter_name)
+    {
+        return data_reader3<T>::read_parameter(GetParam(), type, subsection_name, subindex, parameter_name);
+    }
+
     void print_and_store_results(const std::string &isa,
                                  const std::string &parameters,
                                  const std::string &module_name,
@@ -415,29 +598,6 @@ private:
                                  const double stddev);
 };
 
-/*!
-    \brief Run the given function and return the mean run time and stddev.
-    \param [in] function Function to benchmark.
-    \param [in] args Function's arguments.
-    \return std::pair where the first element is mean and the second one is standard deviation.
-*/
-template <typename F, typename ... Args>
-std::pair<double, double> run_benchmark(F function, Args ... args)
-{
-    std::vector<long> results((unsigned long) BenchmarkParameters::repetition);
-
-    for(unsigned int outer_loop = 0; outer_loop < BenchmarkParameters::repetition; outer_loop++) {
-        const auto start_time =  __rdtsc();
-        for (unsigned int inner_loop = 0; inner_loop < BenchmarkParameters::loop; inner_loop++) {
-                function(args ...);
-        }
-        const auto end_time = __rdtsc();
-        results.push_back(end_time - start_time);
-    }
-
-    return calculate_statistics(results);
-};
-
 /*!
     \brief Assert elements of two arrays. It calls ASSERT_EQ for each element of the array.
     \param [in] reference Array with reference values.
@@ -445,7 +605,7 @@ std::pair<double, double> run_benchmark(F function, Args ... args)
     \param [in] size Size of the array.
 */
 template <typename T>
-void assert_array_eq(const T* reference, const T* actual, const int size)
+inline void assert_array_eq(const T* reference, const T* actual, const int size)
 {
     for(int index = 0; index < size ; index++)
     {
@@ -462,7 +622,7 @@ void assert_array_eq(const T* reference, const T* actual, const int size)
     \param [in] precision Precision fo the comparision used by ASSERT_NEAR.
 */
 template <typename T>
-void assert_array_near(const T* reference, const T* actual, const int size, const double precision)
+inline void assert_array_near(const T* reference, const T* actual, const int size, const double precision)
 {
     for(int index = 0; index < size ; index++)
     {
@@ -472,7 +632,7 @@ void assert_array_near(const T* reference, const T* actual, const int size, cons
 }
 
 template <>
-void assert_array_near<complex_float>(const complex_float* reference, const complex_float* actual, const int size, const double precision)
+inline void assert_array_near<complex_float>(const complex_float* reference, const complex_float* actual, const int size, const double precision)
 {
     for(int index = 0; index < size ; index++)
     {
@@ -491,7 +651,7 @@ void assert_array_near<complex_float>(const complex_float* reference, const comp
     \param [in] precision Precision for the comparison used by ASSERT_GT.
 */
 template<typename T>
-void assert_avg_greater_complex(const T* reference, const T* actual, const int size, const double precision)
+inline void assert_avg_greater_complex(const T* reference, const T* actual, const int size, const double precision)
 {
     float mseDB, MSE;
     double avgMSEDB = 0.0;
@@ -541,7 +701,7 @@ void assert_avg_greater_complex(const T* reference, const T* actual, const int s
     \return Pointer to the allocated memory.
 */
 template <typename T>
-T* aligned_malloc(const int size, const unsigned alignment)
+inline T* aligned_malloc(const int size, const unsigned alignment)
 {
 #ifdef _BBLIB_DPDK_
     return (T*) rte_malloc(NULL, sizeof(T) * size, alignment);
@@ -563,7 +723,7 @@ T* aligned_malloc(const int size, const unsigned alignment)
     \param [in] ptr Pointer to the allocated memory.
 */
 template <typename T>
-void aligned_free(T* ptr)
+inline void aligned_free(T* ptr)
 {
 #ifdef _BBLIB_DPDK_
     rte_free((void*)ptr);
@@ -590,7 +750,7 @@ void aligned_free(T* ptr)
     \return Pointer to the allocated memory with random data.
 */
 template <typename T, typename U>
-T* generate_random_numbers(const long size, const unsigned alignment, U& distribution)
+inline T* generate_random_numbers(const long size, const unsigned alignment, U& distribution)
 {
     auto array = (T*) aligned_malloc<char>(size * sizeof(T), alignment);
 
@@ -615,7 +775,7 @@ T* generate_random_numbers(const long size, const unsigned alignment, U& distrib
     \return Pointer to the allocated memory with random data.
 */
 template <typename T>
-T* generate_random_data(const long size, const unsigned alignment)
+inline T* generate_random_data(const long size, const unsigned alignment)
 {
     std::uniform_int_distribution<> random(0, 255);
 
@@ -637,7 +797,7 @@ T* generate_random_data(const long size, const unsigned alignment)
     \return Pointer to the allocated memory with random data.
 */
 template <typename T>
-T* generate_random_int_numbers(const long size, const unsigned alignment, const T lo_range,
+inline T* generate_random_int_numbers(const long size, const unsigned alignment, const T lo_range,
                                const T up_range)
 {
     std::uniform_int_distribution<T> random(lo_range, up_range);
@@ -660,7 +820,7 @@ T* generate_random_int_numbers(const long size, const unsigned alignment, const
     \return Pointer to the allocated memory with random data.
 */
 template <typename T>
-T* generate_random_real_numbers(const long size, const unsigned alignment, const T lo_range,
+inline T* generate_random_real_numbers(const long size, const unsigned alignment, const T lo_range,
                                 const T up_range)
 {
     std::uniform_real_distribution<T> distribution(lo_range, up_range);