blob: 08624f33452cc9986a4e2c8c936ed1f29df1c764 [file] [log] [blame]
Moritz Pflanzer09e4f982017-08-30 12:47:06 +01001/*
2 * Copyright (c) 2017 ARM Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#ifndef ARM_COMPUTE_TEST_MEASUREMENT
25#define ARM_COMPUTE_TEST_MEASUREMENT
26
27#include "../Utils.h"
Anthony Barbierab14c152017-11-09 10:29:59 +000028#include "arm_compute/core/Error.h"
Moritz Pflanzer09e4f982017-08-30 12:47:06 +010029
Anthony Barbierab14c152017-11-09 10:29:59 +000030#include <list>
Moritz Pflanzer09e4f982017-08-30 12:47:06 +010031#include <ostream>
32#include <string>
33
34namespace arm_compute
35{
36namespace test
37{
38namespace framework
39{
Anthony Barbierab14c152017-11-09 10:29:59 +000040/** Generic measurement that stores values as either double or long long int. */
41struct Measurement
Moritz Pflanzer09e4f982017-08-30 12:47:06 +010042{
Anthony Barbierab14c152017-11-09 10:29:59 +000043 struct Value
Moritz Pflanzer09e4f982017-08-30 12:47:06 +010044 {
Anthony Barbierab14c152017-11-09 10:29:59 +000045 /** Constructor
46 *
47 * @param[in] is_floating Will the value stored be floating point ?
48 */
49 Value(bool is_floating)
50 : v{ 0 }, is_floating_point(is_floating)
51 {
52 }
53
54 /** Add the value stored to the stream as a string
55 */
56 friend std::ostream &operator<<(std::ostream &os, const Value &value)
57 {
58 if(value.is_floating_point)
59 {
60 os << arithmetic_to_string(value.v.floating_point);
61 }
62 else
63 {
64 os << arithmetic_to_string(value.v.integer);
65 }
66 return os;
67 }
68 /** Convert the value stored to string
69 */
70 std::string to_string() const
71 {
72 std::stringstream ss;
73 ss << *this;
74 return ss.str();
75 }
76 /** Add with another value and return the sum
77 *
78 * @param[in] b Other value
79 *
80 * @return Sum of the stored value + b
81 */
82 Value operator+(Value b) const
83 {
84 if(is_floating_point)
85 {
86 b.v.floating_point += v.floating_point;
87 }
88 else
89 {
90 b.v.integer += v.integer;
91 }
92 return b;
93 }
94
95 /** Return the stored value divided by an integer.
96 *
97 * @param[in] b Integer to divide the value by.
98 *
99 * @return Stored value / b
100 */
101 Value operator/(int b) const
102 {
103 Value res(is_floating_point);
104 if(is_floating_point)
105 {
106 res.v.floating_point = v.floating_point / b;
107 }
108 else
109 {
110 res.v.integer = v.integer / b;
111 }
112 return res;
113 }
114
115 /** Subtract another value and return the updated stored value.
116 *
117 * @param[in] b Other value
118 *
119 * @return The updated stored value
120 */
121 Value &operator-=(const Value &b)
122 {
123 if(is_floating_point)
124 {
125 v.floating_point -= b.v.floating_point;
126 }
127 else
128 {
129 v.integer -= b.v.integer;
130 }
131 return *this;
132 }
133
134 /** Compare the stored value with another value
135 *
136 * @param[in] b Value to compare against
137 *
138 * @return The result of stored value < b
139 */
140 bool operator<(const Value &b) const
141 {
142 if(is_floating_point)
143 {
144 return v.floating_point < b.v.floating_point;
145 }
146 else
147 {
148 return v.integer < b.v.integer;
149 }
150 }
151
152 /** Stored value */
153 union
154 {
155 double floating_point;
156 long long int integer;
157 } v;
158 bool is_floating_point; /**< Is the stored value floating point or integer ? */
159 };
160
161 /** Stream output operator to print the measurement.
162 *
163 * Prints value and unit.
164 */
165 friend inline std::ostream &operator<<(std::ostream &os, const Measurement &measurement)
166 {
167 os << measurement._value << " " << measurement._unit;
168 return os;
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100169 }
170
Anthony Barbierab14c152017-11-09 10:29:59 +0000171 /** Constructor to store a floating point value
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100172 *
Anthony Barbierab14c152017-11-09 10:29:59 +0000173 * @param[in] v Value to store
174 * @param[in] unit Unit of @p v
175 * @param[in] raw (Optional) The raw value(s) @p was generated from.
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100176 */
Anthony Barbierab14c152017-11-09 10:29:59 +0000177 template < typename Floating, typename std::enable_if < !std::is_integral<Floating>::value, int >::type = 0 >
178 Measurement(Floating v, std::string unit, std::list<std::string> raw = {})
179 : _unit(unit), _raw_data(std::move(raw)), _value(true)
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100180 {
Anthony Barbierab14c152017-11-09 10:29:59 +0000181 _value.v.floating_point = static_cast<double>(v);
182 if(_raw_data.empty())
183 {
184 _raw_data = { _value.to_string() };
185 }
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100186 }
187
Anthony Barbierab14c152017-11-09 10:29:59 +0000188 /** Constructor to store an integer value
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100189 *
Anthony Barbierab14c152017-11-09 10:29:59 +0000190 * @param[in] v Value to store
191 * @param[in] unit Unit of @p v
192 * @param[in] raw (Optional) The raw value(s) @p was generated from.
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100193 */
Anthony Barbierab14c152017-11-09 10:29:59 +0000194 template <typename Integer, typename std::enable_if<std::is_integral<Integer>::value, int>::type = 0>
195 Measurement(Integer v, std::string unit, std::list<std::string> raw = {})
196 : _unit(unit), _raw_data(std::move(raw)), _value(false)
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100197 {
Anthony Barbierab14c152017-11-09 10:29:59 +0000198 _value.v.integer = static_cast<long long int>(v);
199 if(_raw_data.empty())
200 {
201 _raw_data = { _value.to_string() };
202 }
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100203 }
Anthony Barbierab14c152017-11-09 10:29:59 +0000204
205 /** Accessor for the unit of the measurement
206 *
207 * @return Unit of the measurement
208 */
209 const std::string &unit() const
210 {
211 return _unit;
212 }
213
214 /** Accessor for the raw data
215 *
216 * @return The raw data
217 */
218 const std::list<std::string> &raw_data() const
219 {
220 return _raw_data;
221 }
222
223 /** Accessor for the stored value
224 *
225 * @return The stored value
226 */
227 const Value &value() const
228 {
229 return _value;
230 }
231
232private:
233 std::string _unit;
234 std::list<std::string> _raw_data;
235 Value _value;
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100236};
Anthony Barbierab14c152017-11-09 10:29:59 +0000237
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100238} // namespace framework
239} // namespace test
240} // namespace arm_compute
241#endif /* ARM_COMPUTE_TEST_MEASUREMENT */