Skip to content

Commit f725fea

Browse files
committed
flag to enable selectively dragon4 / errol3
1 parent a42b24c commit f725fea

File tree

1 file changed

+51
-37
lines changed

1 file changed

+51
-37
lines changed

benchmarks/benchmark.cpp

Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -58,38 +58,42 @@ concept arithmetic_float
5858
= std::is_same_v<T, float> || std::is_same_v<T, double>;
5959

6060
template <arithmetic_float T>
61-
void process(const std::vector<T> &lines) {
61+
void process(const std::vector<T> &lines, bool useDragon4, bool useErrol3) {
6262
using MantissaType = std::conditional_t<std::is_same_v<T, float>,
6363
uint32_t, uint64_t>;
6464
using IEEE754Type = std::conditional_t<std::is_same_v<T, float>,
6565
IEEE754f, IEEE754d>;
6666

6767
// No dragon4 implementation optimized for float instead of double ?
68-
pretty_print(lines, "dragon4", [](const std::vector<T> &lines) -> int {
69-
int volume = 0;
70-
for (const auto d : lines) {
71-
uint64_t dmantissa;
72-
int dexp;
73-
const IEEE754Type fields = decode_ieee754(d);
74-
dragon4::Dragon4(dmantissa, dexp, fields.mantissa, fields.exponent,
75-
true, true);
76-
char buffer[100];
77-
volume += to_chars(dmantissa, dexp, fields.sign, buffer);
78-
}
79-
return volume;
80-
}, 10);
68+
if(useDragon4) {
69+
pretty_print(lines, "dragon4", [](const std::vector<T> &lines) -> int {
70+
int volume = 0;
71+
for (const auto d : lines) {
72+
uint64_t dmantissa;
73+
int dexp;
74+
const IEEE754Type fields = decode_ieee754(d);
75+
dragon4::Dragon4(dmantissa, dexp, fields.mantissa, fields.exponent,
76+
true, true);
77+
char buffer[100];
78+
volume += to_chars(dmantissa, dexp, fields.sign, buffer);
79+
}
80+
return volume;
81+
}, 10);
82+
}
8183

8284
#ifdef ERROL_SUPPORTED
8385
// No errol3 implementation optimized for float instead of double ?
84-
pretty_print(lines, "errol3", [](const std::vector<T> &lines) -> int {
85-
int volume = 0;
86-
char buffer[100];
87-
for (const auto d : lines) {
88-
errol3_dtoa(d, buffer); // returns the exponent
89-
volume += std::strlen(buffer);
90-
}
91-
return volume;
92-
});
86+
if(useErrol3) {
87+
pretty_print(lines, "errol3", [](const std::vector<T> &lines) -> int {
88+
int volume = 0;
89+
char buffer[100];
90+
for (const auto d : lines) {
91+
errol3_dtoa(d, buffer); // returns the exponent
92+
volume += std::strlen(buffer);
93+
}
94+
return volume;
95+
});
96+
}
9397
#else
9498
std::cout << "# errol not supported" << std::endl;
9599
#endif
@@ -263,11 +267,11 @@ void process(const std::vector<T> &lines) {
263267
}
264268

265269
template <typename T>
266-
void fileload(const std::string &filename) {
270+
std::vector<T> fileload(const std::string &filename) {
267271
std::ifstream inputfile(filename);
268272
if (!inputfile) {
269273
std::cerr << "can't open " << filename << std::endl;
270-
return;
274+
return {};
271275
}
272276

273277
std::vector<T> lines;
@@ -284,11 +288,12 @@ void fileload(const std::string &filename) {
284288
}
285289
}
286290
std::cout << "# read " << lines.size() << " lines " << std::endl;
287-
process(lines);
291+
return lines;
288292
}
289293

290294
template <typename T>
291-
void parse_random_numbers(size_t howmany, const std::string &random_model) {
295+
std::vector<T> get_random_numbers(size_t howmany,
296+
const std::string &random_model) {
292297
std::cout << "# parsing random numbers" << std::endl;
293298
std::vector<T> lines;
294299
auto g = get_generator_by_name<T>(random_model);
@@ -299,7 +304,7 @@ void parse_random_numbers(size_t howmany, const std::string &random_model) {
299304
const T line = g->new_float();
300305
lines.push_back(line);
301306
}
302-
process(lines);
307+
return lines;
303308
}
304309

305310
cxxopts::Options
@@ -316,6 +321,10 @@ int main(int argc, char **argv) {
316321
cxxopts::value<std::string>()->default_value("uniform"))(
317322
"s,single", "Use single precision instead of double.",
318323
cxxopts::value<bool>()->default_value("false"))(
324+
"d,dragon", "Enable dragon4 (current impl. triggers some asserts)",
325+
cxxopts::value<bool>()->default_value("false"))(
326+
"e,errol", "Enable errol3 (current impl. returns invalid values, e.g., for 0)",
327+
cxxopts::value<bool>()->default_value("false"))(
319328
"h,help", "Print usage.");
320329
const auto result = options.parse(argc, argv);
321330

@@ -324,28 +333,33 @@ int main(int argc, char **argv) {
324333
return EXIT_SUCCESS;
325334
}
326335

336+
const bool useDragon4 = result["dragon"].as<bool>();
337+
const bool useErrol3 = result["errol"].as<bool>();
338+
327339
const bool single = result["single"].as<bool>();
328340
std::cout << "number type: " << (single ? "binary32 (float)" : "binary64 (double)") << std::endl;
329341

342+
std::variant<std::vector<float>, std::vector<double>> numbers;
330343
const auto filename = result["file"].as<std::string>();
331344
if (filename.empty()) {
332-
if(single) {
333-
parse_random_numbers<float>(result["volume"].as<size_t>(),
334-
result["model"].as<std::string>());
335-
} else {
336-
parse_random_numbers<double>(result["volume"].as<size_t>(),
337-
result["model"].as<std::string>());
338-
}
345+
const auto volume = result["volume"].as<size_t>();
346+
const auto model = result["model"].as<std::string>();
347+
if(single)
348+
numbers = get_random_numbers<float>(volume, model);
349+
else
350+
numbers = get_random_numbers<double>(volume, model);
339351
std::cout << "# You can also provide a filename (with the -f flag):"
340352
"it should contain one string per line corresponding to a number"
341353
<< std::endl;
342354
}
343355
else {
344356
if(single)
345-
fileload<float>(filename);
357+
numbers = fileload<float>(filename);
346358
else
347-
fileload<double>(filename);
359+
numbers = fileload<double>(filename);
348360
}
361+
362+
std::visit([&](auto &&arg) { process(arg, useDragon4, useErrol3); }, numbers);
349363
} catch (const std::exception &e) {
350364
std::cout << "error parsing options: " << e.what() << std::endl;
351365
return EXIT_FAILURE;

0 commit comments

Comments
 (0)