|
11 | 11 |
|
12 | 12 | #include "task/include/task.hpp" |
13 | 13 |
|
| 14 | +using namespace ppc::task; |
| 15 | + |
14 | 16 | namespace ppc::performance { |
15 | 17 |
|
| 18 | +/** |
| 19 | + * @brief Default timer function used for performance measurement. |
| 20 | + * @return A fake time value (-1.0). |
| 21 | + */ |
16 | 22 | inline double DefaultTimer() { return -1.0; } |
17 | 23 |
|
| 24 | +/** |
| 25 | + * @brief Attributes used to configure performance measurement. |
| 26 | + */ |
18 | 27 | struct PerfAttr { |
19 | | - /// @brief Number of times the task is run for performance evaluation. |
| 28 | + /** |
| 29 | + * @brief Number of repetitions of the task for averaging performance. |
| 30 | + */ |
20 | 31 | uint64_t num_running = 5; |
21 | | - /// @brief Timer function returning current time in seconds. |
22 | | - /// @cond |
| 32 | + |
| 33 | + /** |
| 34 | + * @brief Timer function returning current time in seconds. |
| 35 | + * Default is a fake function returning -1.0. |
| 36 | + */ |
23 | 37 | std::function<double()> current_timer = DefaultTimer; |
24 | | - /// @endcond |
25 | 38 | }; |
26 | 39 |
|
| 40 | +/** |
| 41 | + * @brief Stores the results of a performance test. |
| 42 | + */ |
27 | 43 | struct PerfResults { |
28 | | - /// @brief Measured execution time in seconds. |
| 44 | + /** |
| 45 | + * @brief Measured execution time in seconds (average over runs). |
| 46 | + */ |
29 | 47 | double time_sec = 0.0; |
30 | | - enum TypeOfRunning : uint8_t { kPipeline, kTaskRun, kNone } type_of_running = kNone; |
| 48 | + |
| 49 | + /** |
| 50 | + * @brief Type of performance test performed. |
| 51 | + */ |
| 52 | + enum TypeOfRunning : uint8_t { |
| 53 | + kPipeline, ///< Full pipeline: Validation → PreProcessing → Run → PostProcessing |
| 54 | + kTaskRun, ///< Only Run() function is measured |
| 55 | + kNone ///< No performance test was executed |
| 56 | + } type_of_running = kNone; |
| 57 | + |
| 58 | + /** |
| 59 | + * @brief Maximum allowed execution time in seconds. |
| 60 | + */ |
31 | 61 | constexpr static double kMaxTime = 10.0; |
32 | 62 | }; |
33 | 63 |
|
| 64 | +/** |
| 65 | + * @brief Converts a TypeOfRunning enum value to its string representation. |
| 66 | + * @param type_of_running Enum value indicating which performance type was run. |
| 67 | + * @return String name corresponding to the enum. |
| 68 | + */ |
| 69 | +inline std::string GetStringParamName(PerfResults::TypeOfRunning type_of_running) { |
| 70 | + switch (type_of_running) { |
| 71 | + case PerfResults::kTaskRun: |
| 72 | + return "task_run"; |
| 73 | + case PerfResults::kPipeline: |
| 74 | + return "pipeline"; |
| 75 | + default: |
| 76 | + return "none"; |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +/** |
| 81 | + * @brief Measures performance of a given task using configured attributes. |
| 82 | + * @tparam InType Input type of the task. |
| 83 | + * @tparam OutType Output type of the task. |
| 84 | + */ |
34 | 85 | template <typename InType, typename OutType> |
35 | 86 | class Perf { |
36 | 87 | public: |
37 | | - // Init performance analysis with an initialized task and initialized data |
38 | | - explicit Perf(const ppc::task::TaskPtr<InType, OutType>& task_ptr) : task_(task_ptr) { |
39 | | - task_ptr->GetStateOfTesting() = ppc::task::StateOfTesting::kPerf; |
| 88 | + /** |
| 89 | + * @brief Constructs a performance tester for the given task. |
| 90 | + * @param task_ptr Shared pointer to a task object. |
| 91 | + */ |
| 92 | + explicit Perf(const ::TaskPtr<InType, OutType>& task_ptr) : task_(task_ptr) { |
| 93 | + task_ptr->GetStateOfTesting() = ::StateOfTesting::kPerf; |
40 | 94 | } |
41 | | - // Check performance of full task's pipeline: PreProcessing() -> |
42 | | - // Validation() -> Run() -> PostProcessing() |
| 95 | + |
| 96 | + /** |
| 97 | + * @brief Runs the full task pipeline and measures its performance. |
| 98 | + * The full pipeline includes: Validation → PreProcessing → Run → PostProcessing. |
| 99 | + * @param perf_attr Performance measurement configuration. |
| 100 | + */ |
43 | 101 | void PipelineRun(const PerfAttr& perf_attr) { |
44 | | - perf_results_.type_of_running = PerfResults::TypeOfRunning::kPipeline; |
45 | | - |
46 | | - CommonRun(perf_attr, [&] { |
47 | | - task_->Validation(); |
48 | | - task_->PreProcessing(); |
49 | | - task_->Run(); |
50 | | - task_->PostProcessing(); |
51 | | - }, perf_results_); |
| 102 | + perf_results_.type_of_running = PerfResults::kPipeline; |
| 103 | + CommonRun(perf_attr, RunFullPipeline<::Task<InType, OutType>>); |
52 | 104 | } |
53 | | - // Check performance of task's Run() function |
| 105 | + |
| 106 | + /** |
| 107 | + * @brief Measures only the Run() part of the task. |
| 108 | + * Pre/Post-processing and validation are still invoked before and after. |
| 109 | + * @param perf_attr Performance measurement configuration. |
| 110 | + */ |
54 | 111 | void TaskRun(const PerfAttr& perf_attr) { |
55 | | - perf_results_.type_of_running = PerfResults::TypeOfRunning::kTaskRun; |
| 112 | + perf_results_.type_of_running = PerfResults::kTaskRun; |
56 | 113 |
|
57 | 114 | task_->Validation(); |
58 | 115 | task_->PreProcessing(); |
59 | | - CommonRun(perf_attr, [&] { task_->Run(); }, perf_results_); |
| 116 | + CommonRun(perf_attr, RunOnly<::Task<InType, OutType>>); |
60 | 117 | task_->PostProcessing(); |
61 | 118 |
|
| 119 | + // Ensure correctness after performance run |
62 | 120 | task_->Validation(); |
63 | 121 | task_->PreProcessing(); |
64 | 122 | task_->Run(); |
65 | 123 | task_->PostProcessing(); |
66 | 124 | } |
67 | | - // Pint results for automation checkers |
| 125 | + |
| 126 | + /** |
| 127 | + * @brief Prints formatted performance results or throws if too slow. |
| 128 | + * Prints output in format: test_id:type:time_in_seconds |
| 129 | + * @param test_id Identifier for the current test (e.g., "omp_4_threads"). |
| 130 | + * @throws std::runtime_error if execution time exceeds allowed maximum. |
| 131 | + */ |
68 | 132 | void PrintPerfStatistic(const std::string& test_id) const { |
69 | | - std::string type_test_name; |
70 | | - if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kTaskRun) { |
71 | | - type_test_name = "task_run"; |
72 | | - } else if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kPipeline) { |
73 | | - type_test_name = "pipeline"; |
74 | | - } else { |
75 | | - std::stringstream err_msg; |
76 | | - err_msg << '\n' << "The type of performance check for the task was not selected.\n"; |
77 | | - throw std::runtime_error(err_msg.str().c_str()); |
| 133 | + const auto& type = perf_results_.type_of_running; |
| 134 | + const std::string type_name = GetStringParamName(type); |
| 135 | + |
| 136 | + if (type == PerfResults::kNone) { |
| 137 | + throw std::runtime_error("The type of performance check for the task was not selected.\n"); |
78 | 138 | } |
79 | 139 |
|
80 | | - auto time_secs = perf_results_.time_sec; |
81 | | - std::stringstream perf_res_str; |
| 140 | + std::stringstream ss; |
| 141 | + double time_secs = perf_results_.time_sec; |
| 142 | + |
82 | 143 | if (time_secs < PerfResults::kMaxTime) { |
83 | | - perf_res_str << std::fixed << std::setprecision(10) << time_secs; |
84 | | - std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; |
| 144 | + ss << std::fixed << std::setprecision(10) << time_secs; |
85 | 145 | } else { |
86 | | - std::stringstream err_msg; |
87 | | - err_msg << '\n' << "Task execute time need to be: "; |
88 | | - err_msg << "time < " << PerfResults::kMaxTime << " secs." << '\n'; |
89 | | - err_msg << "Original time in secs: " << time_secs << '\n'; |
90 | | - perf_res_str << std::fixed << std::setprecision(10) << -1.0; |
91 | | - std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n'; |
92 | | - throw std::runtime_error(err_msg.str().c_str()); |
| 146 | + ss << std::fixed << std::setprecision(10) << -1.0; |
| 147 | + std::stringstream err; |
| 148 | + err << "Task execute time need to be: time < " << PerfResults::kMaxTime |
| 149 | + << " secs.\nOriginal time in secs: " << time_secs << '\n'; |
| 150 | + std::cout << test_id << ":" << type_name << ":" << ss.str() << '\n'; |
| 151 | + throw std::runtime_error(err.str()); |
93 | 152 | } |
| 153 | + |
| 154 | + std::cout << test_id << ":" << type_name << ":" << ss.str() << '\n'; |
94 | 155 | } |
95 | | - /// @brief Retrieves the performance test results. |
96 | | - /// @return The latest PerfResults structure. |
| 156 | + |
| 157 | + /** |
| 158 | + * @brief Retrieves performance test results. |
| 159 | + * @return Struct containing latest performance data. |
| 160 | + */ |
97 | 161 | [[nodiscard]] PerfResults GetPerfResults() const { return perf_results_; } |
98 | 162 |
|
99 | 163 | private: |
100 | | - PerfResults perf_results_; |
101 | | - std::shared_ptr<ppc::task::Task<InType, OutType>> task_; |
102 | | - static void CommonRun(const PerfAttr& perf_attr, const std::function<void()>& pipeline, PerfResults& perf_results) { |
103 | | - auto begin = perf_attr.current_timer(); |
104 | | - for (uint64_t i = 0; i < perf_attr.num_running; i++) { |
105 | | - pipeline(); |
106 | | - } |
107 | | - auto end = perf_attr.current_timer(); |
108 | | - perf_results.time_sec = (end - begin) / static_cast<double>(perf_attr.num_running); |
| 164 | + PerfResults perf_results_; ///< Stores measurement results and mode. |
| 165 | + std::shared_ptr<::Task<InType, OutType>> task_; ///< Pointer to task being tested. |
| 166 | + |
| 167 | + /** |
| 168 | + * @brief Executes the full pipeline for the given task. |
| 169 | + * @tparam TaskType Type of the task. |
| 170 | + * @param task Shared pointer to the task instance. |
| 171 | + */ |
| 172 | + template <typename TaskType> |
| 173 | + static void RunFullPipeline(const std::shared_ptr<TaskType>& task) { |
| 174 | + task->Validation(); |
| 175 | + task->PreProcessing(); |
| 176 | + task->Run(); |
| 177 | + task->PostProcessing(); |
109 | 178 | } |
110 | | -}; |
111 | 179 |
|
112 | | -inline std::string GetStringParamName(PerfResults::TypeOfRunning type_of_running) { |
113 | | - if (type_of_running == PerfResults::kTaskRun) { |
114 | | - return "task_run"; |
| 180 | + /** |
| 181 | + * @brief Executes only the Run() method of the given task. |
| 182 | + * @tparam TaskType Type of the task. |
| 183 | + * @param task Shared pointer to the task instance. |
| 184 | + */ |
| 185 | + template <typename TaskType> |
| 186 | + static void RunOnly(const std::shared_ptr<TaskType>& task) { |
| 187 | + task->Run(); |
115 | 188 | } |
116 | | - if (type_of_running == PerfResults::kPipeline) { |
117 | | - return "pipeline"; |
| 189 | + |
| 190 | + /** |
| 191 | + * @brief Measures execution time of a given function over multiple runs. |
| 192 | + * @tparam Func Type of callable taking shared_ptr to task. |
| 193 | + * @param perf_attr Attributes controlling the number of runs and timer. |
| 194 | + * @param func Callable that invokes the desired part of the task. |
| 195 | + */ |
| 196 | + template <typename Func> |
| 197 | + void CommonRun(const PerfAttr& perf_attr, Func func) { |
| 198 | + double begin = perf_attr.current_timer(); |
| 199 | + for (uint64_t i = 0; i < perf_attr.num_running; ++i) { |
| 200 | + func(task_); |
| 201 | + } |
| 202 | + double end = perf_attr.current_timer(); |
| 203 | + perf_results_.time_sec = (end - begin) / static_cast<double>(perf_attr.num_running); |
118 | 204 | } |
119 | | - return "none"; |
120 | | -} |
| 205 | +}; |
121 | 206 |
|
122 | 207 | } // namespace ppc::performance |
0 commit comments