@@ -58,38 +58,42 @@ concept arithmetic_float
5858 = std::is_same_v<T, float > || std::is_same_v<T, double >;
5959
6060template <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
265269template <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
290294template <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
305310cxxopts::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