X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=o-du%2Fphy.git;a=blobdiff_plain;f=fhi_lib%2Ftest%2Fcommon%2Fcommon.cpp;h=9c004716e3034b0a8c2c5cccd45ca09858ac8962;hp=d94d993e49c22cd17e8e97d16be17fd840283de5;hb=2fbf70096f64af622da983e88c5a64e90ad9bdbd;hpb=9e108bb6d4caf2f6d4e920c640882fa49c15684c diff --git a/fhi_lib/test/common/common.cpp b/fhi_lib/test/common/common.cpp index d94d993..9c00471 100644 --- a/fhi_lib/test/common/common.cpp +++ b/fhi_lib/test/common/common.cpp @@ -1,195 +1,195 @@ -/****************************************************************************** -* -* 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. -* -*******************************************************************************/ - - -#include -#include -#include - -#ifndef _WIN64 -#include -#include -#else -#include -#endif - -#include "common.hpp" - -#ifndef CPU_ID -#define CPU_ID 4 -#endif - -/* Required to avoid linker errors */ -json KernelTests::conf; -std::string KernelTests::test_type; -unsigned long KernelTests::tsc; - - -long BenchmarkParameters::repetition = 40; -long BenchmarkParameters::loop = 30; -unsigned BenchmarkParameters::cpu_id = CPU_ID; - -int bind_to_cpu(const unsigned cpu) -{ -#ifndef _WIN64 - const auto pid = syscall(SYS_gettid); - cpu_set_t mask {}; - CPU_ZERO(&mask); - CPU_SET(cpu, &mask); - return sched_setaffinity(__pid_t(pid), sizeof(mask), &mask); -#else - return -1; -#endif -} - -std::pair calculate_statistics(const std::vector values) -{ - const auto sum = std::accumulate(values.begin(), values.end(), 0L); - - const auto number_of_iterations = BenchmarkParameters::repetition * - BenchmarkParameters::loop; - - const auto mean = sum / (double) number_of_iterations; - - auto stddev_accumulator = 0.0; - for (auto v : values) - stddev_accumulator = pow((v / BenchmarkParameters::loop) - mean, 2); - - const auto stddev = sqrt(stddev_accumulator / BenchmarkParameters::repetition); - - return {mean, stddev}; -} - -std::vector get_sequence(const unsigned number) -{ - std::vector sequence(number); - std::iota(sequence.begin(), sequence.end(), 0); - - return sequence; -} - -char* read_data_to_aligned_array(const std::string &filename) -{ - std::ifstream input_stream(filename, std::ios::binary); - - std::vector buffer((std::istreambuf_iterator(input_stream)), - std::istreambuf_iterator()); - - if(buffer.size() == 0) - throw reading_input_file_exception(); - - auto aligned_buffer = aligned_malloc((int) buffer.size(), 64); - - if(aligned_buffer == nullptr) - throw std::runtime_error("Failed to allocate memory for the test vector!"); - - std::copy(buffer.begin(), buffer.end(), aligned_buffer); - - return aligned_buffer; -} - -json read_json_from_file(const std::string &filename) -{ - json result; - - std::ifstream json_stream(filename); - if(!json_stream.is_open()) - throw missing_config_file_exception(); - - json_stream >> result; - - return result; -} - -unsigned long tsc_recovery() -{ -#ifndef _WIN64 - constexpr auto ns_per_sec = 1E9; - - struct timespec sleeptime = {.tv_nsec = __syscall_slong_t(5E8) }; - - struct timespec t_start, t_end; - - if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) - { - unsigned long start = tsc_tick(); - - nanosleep(&sleeptime,NULL); - clock_gettime(CLOCK_MONOTONIC_RAW, &t_end); - - unsigned long end = tsc_tick(); - - unsigned long ns = (unsigned long)((t_end.tv_sec - t_start.tv_sec) * ns_per_sec + t_end.tv_nsec - t_start.tv_nsec); - - double secs = (double) ns / ns_per_sec; - - unsigned long resolution_timer = (unsigned long)((end - start)/secs); - unsigned long tick_per_usec = (resolution_timer / 1000000); - - std::cout << "[----------] System clock (rdtsc) resolution " << resolution_timer << " [Hz]" << std::endl; - std::cout << "[----------] Ticks per us " << tick_per_usec << std::endl; - - return tick_per_usec; - } -#else - - LARGE_INTEGER tick_per_sec; - QueryPerformanceFrequency(&tick_per_sec); - - std::cout << "[----------] System clock (rdtsc) resolution unknown" << std::endl; - std::cout << "[----------] Ticks per us " << (tick_per_sec.QuadPart / 1000000) << std::endl; - return (unsigned long) tick_per_sec.QuadPart; - -#endif - return 0; -} - -unsigned long tsc_tick() -{ -#ifndef _WIN64 - unsigned long hi, lo; - - __asm volatile ("rdtsc" : "=a"(lo), "=d"(hi)); - - return lo | (hi << 32); -#else - return 0; -#endif -} - -void KernelTests::print_and_store_results(const std::string &isa, const std::string ¶meters, - const std::string &module_name, const std::string &test_name, - const std::string &unit, const int para_factor, - const double mean, const double stddev) -{ - std::cout << "[----------] " << "Mean" << " = " << std::fixed << mean << " us" << std::endl; - std::cout << "[----------] " << "Stddev" << " = " << stddev << " us" << std::endl; - -#ifndef _WIN64 - /* Two properties below should uniquely identify a test case */ - RecordProperty("kernelname", module_name); - RecordProperty("parameters", parameters); - - RecordProperty("isa", isa); - RecordProperty("unit", unit); - RecordProperty("parallelization_factor", para_factor); - - RecordProperty("mean", std::to_string(mean)); - RecordProperty("stddev", std::to_string(stddev)); -#endif -} +/****************************************************************************** +* +* 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. +* +*******************************************************************************/ + + +#include +#include +#include + +#ifndef _WIN64 +#include +#include +#else +#include +#endif + +#include "common.hpp" + +#ifndef CPU_ID +#define CPU_ID 4 +#endif + +/* Required to avoid linker errors */ +json KernelTests::conf; +std::string KernelTests::test_type; +unsigned long KernelTests::tsc; + + +long BenchmarkParameters::repetition = 40; +long BenchmarkParameters::loop = 30; +unsigned BenchmarkParameters::cpu_id = CPU_ID; + +int bind_to_cpu(const unsigned cpu) +{ +#ifndef _WIN64 + const auto pid = syscall(SYS_gettid); + cpu_set_t mask {}; + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + return sched_setaffinity(__pid_t(pid), sizeof(mask), &mask); +#else + return -1; +#endif +} + +std::pair calculate_statistics(const std::vector values) +{ + const auto sum = std::accumulate(values.begin(), values.end(), 0L); + + const auto number_of_iterations = BenchmarkParameters::repetition * + BenchmarkParameters::loop; + + const auto mean = sum / (double) number_of_iterations; + + auto stddev_accumulator = 0.0; + for (auto v : values) + stddev_accumulator = pow((v / BenchmarkParameters::loop) - mean, 2); + + const auto stddev = sqrt(stddev_accumulator / BenchmarkParameters::repetition); + + return {mean, stddev}; +} + +std::vector get_sequence(const unsigned number) +{ + std::vector sequence(number); + std::iota(sequence.begin(), sequence.end(), 0); + + return sequence; +} + +char* read_data_to_aligned_array(const std::string &filename) +{ + std::ifstream input_stream(filename, std::ios::binary); + + std::vector buffer((std::istreambuf_iterator(input_stream)), + std::istreambuf_iterator()); + + if(buffer.size() == 0) + throw reading_input_file_exception(); + + auto aligned_buffer = aligned_malloc((int) buffer.size(), 64); + + if(aligned_buffer == nullptr) + throw std::runtime_error("Failed to allocate memory for the test vector!"); + + std::copy(buffer.begin(), buffer.end(), aligned_buffer); + + return aligned_buffer; +} + +json read_json_from_file(const std::string &filename) +{ + json result; + + std::ifstream json_stream(filename); + if(!json_stream.is_open()) + throw missing_config_file_exception(); + + json_stream >> result; + + return result; +} + +unsigned long tsc_recovery() +{ +#ifndef _WIN64 + constexpr auto ns_per_sec = 1E9; + + struct timespec sleeptime = {.tv_nsec = __syscall_slong_t(5E8) }; + + struct timespec t_start, t_end; + + if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) + { + unsigned long start = tsc_tick(); + + nanosleep(&sleeptime,NULL); + clock_gettime(CLOCK_MONOTONIC_RAW, &t_end); + + unsigned long end = tsc_tick(); + + unsigned long ns = (unsigned long)((t_end.tv_sec - t_start.tv_sec) * ns_per_sec + t_end.tv_nsec - t_start.tv_nsec); + + double secs = (double) ns / ns_per_sec; + + unsigned long resolution_timer = (unsigned long)((end - start)/secs); + unsigned long tick_per_usec = (resolution_timer / 1000000); + + std::cout << "[----------] System clock (rdtsc) resolution " << resolution_timer << " [Hz]" << std::endl; + std::cout << "[----------] Ticks per us " << tick_per_usec << std::endl; + + return tick_per_usec; + } +#else + + LARGE_INTEGER tick_per_sec; + QueryPerformanceFrequency(&tick_per_sec); + + std::cout << "[----------] System clock (rdtsc) resolution unknown" << std::endl; + std::cout << "[----------] Ticks per us " << (tick_per_sec.QuadPart / 1000000) << std::endl; + return (unsigned long) tick_per_sec.QuadPart; + +#endif + return 0; +} + +unsigned long tsc_tick() +{ +#ifndef _WIN64 + unsigned long hi, lo; + + __asm volatile ("rdtsc" : "=a"(lo), "=d"(hi)); + + return lo | (hi << 32); +#else + return 0; +#endif +} + +void KernelTests::print_and_store_results(const std::string &isa, const std::string ¶meters, + const std::string &module_name, const std::string &test_name, + const std::string &unit, const int para_factor, + const double mean, const double stddev) +{ + std::cout << "[----------] " << "Mean" << " = " << std::fixed << mean << " us" << std::endl; + std::cout << "[----------] " << "Stddev" << " = " << stddev << " us" << std::endl; + +#ifndef _WIN64 + /* Two properties below should uniquely identify a test case */ + RecordProperty("kernelname", module_name); + RecordProperty("parameters", parameters); + + RecordProperty("isa", isa); + RecordProperty("unit", unit); + RecordProperty("parallelization_factor", para_factor); + + RecordProperty("mean", std::to_string(mean)); + RecordProperty("stddev", std::to_string(stddev)); +#endif +}