5
5
#include < sstream>
6
6
#include < iomanip>
7
7
#include < cctype>
8
+ #include < cmath>
8
9
#include < stdexcept>
9
10
#include < boost/filesystem.hpp>
10
11
#include < cxxopts.hpp>
@@ -63,29 +64,51 @@ void print_intruction_set()
63
64
64
65
// / Float-to-humanized string for better output
65
66
template <typename T>
66
- std::string humanize (T num)
67
+ std::string to_human_readable (T num)
67
68
{
68
69
std::ostringstream oss;
69
- oss.precision (1 );
70
70
71
- if (num < 1000.0 )
71
+ if (num < 1024 )
72
72
{
73
73
oss << std::fixed << num;
74
74
}
75
- else if (num < 1000000.0 )
76
- {
77
- oss << std::fixed << num / 1000.0 << " K" ;
78
- }
79
- else if (num < 1000000000.0 )
80
- {
81
- oss << std::fixed << num / 1000000.0 << " M" ;
82
- }
83
75
else
84
76
{
85
- oss << std::fixed << num / 1000000000.0 << " B" ;
77
+ double value;
78
+ std::string suffix;
79
+
80
+ if (num < 1024 * 1024 )
81
+ {
82
+ value = num / 1024.0 ;
83
+ suffix = " K" ;
84
+ }
85
+ else if (num < 1024 * 1024 * 1024 )
86
+ {
87
+ value = num / (1024.0 * 1024.0 );
88
+ suffix = " M" ;
89
+ }
90
+ else
91
+ {
92
+ value = num / (1024.0 * 1024.0 * 1024.0 );
93
+ suffix = " B" ;
94
+ }
95
+
96
+ // Check if the fractional part is zero
97
+ double int_part;
98
+ double frac_part = std::modf (value, &int_part);
99
+ if (frac_part == 0.0 )
100
+ {
101
+ oss << static_cast <long long >(int_part) << suffix;
102
+ }
103
+ else
104
+ {
105
+ oss.precision (1 );
106
+ oss << std::fixed << value << suffix;
107
+ }
86
108
}
87
109
88
110
return oss.str ();
111
+
89
112
}
90
113
91
114
// / Size_t-to-string that translates milliseconds to humanized time
@@ -128,9 +151,9 @@ std::string humanize_time(size_t milliseconds)
128
151
return oss.str ();
129
152
}
130
153
131
- // / Parse the humanized RAM size to a number.
132
- // / I know that the name of this function is unfortunate .
133
- size_t dehumanize_ram (const std::string& max_ram)
154
+ // / Parse a human-readable --max-ram value as the number of bytes
155
+ // / e.g. 128K, 50M, 4.2Gb etc .
156
+ size_t parse_human_readable (const std::string& max_ram)
134
157
{
135
158
double value;
136
159
char unit = 0 ;
@@ -140,7 +163,7 @@ size_t dehumanize_ram(const std::string& max_ram)
140
163
ss >> value;
141
164
if (ss.fail ())
142
165
{
143
- throw std::runtime_error (" Can't parse max_ram parameter: wrong numerical part" );
166
+ throw std::runtime_error (" Could not parse --max-ram parameter: wrong numerical part" );
144
167
}
145
168
146
169
// Check if there is a memory unit
@@ -149,7 +172,7 @@ size_t dehumanize_ram(const std::string& max_ram)
149
172
ss >> unit;
150
173
if (ss.fail ())
151
174
{
152
- throw std::runtime_error (" Can't parse max_ram parameter: wrong unit" );
175
+ throw std::runtime_error (" Could not parse --max-ram parameter: wrong unit" );
153
176
}
154
177
}
155
178
@@ -230,10 +253,15 @@ int main(int argc, char** argv)
230
253
if (parsed_options.count (" max-ram" ))
231
254
{
232
255
const auto max_ram_string = parsed_options[" max-ram" ].as <std::string>();
233
- const auto max_ram = dehumanize_ram (max_ram_string);
234
- max_entries = max_ram / sizeof (i2l::pkdb_value);
256
+ const auto max_ram = parse_human_readable (max_ram_string);
257
+ max_entries = static_cast <size_t >(max_ram / sizeof (i2l::pkdb_value));
258
+
259
+ if (max_entries == 0 )
260
+ {
261
+ throw std::runtime_error (" Memory limit is too low" );
262
+ }
235
263
std::cout << " Max-RAM provided: will be loaded not more than "
236
- << humanize (max_entries) << " phylo-k-mers." << std::endl;
264
+ << to_human_readable (max_entries) << " phylo-k-mers." << std::endl;
237
265
}
238
266
239
267
#ifndef EPIK_OMP
@@ -259,8 +287,8 @@ int main(int argc, char** argv)
259
287
<< " \t k: " << db.kmer_size () << std::endl
260
288
<< " \t omega: " << db.omega () << std::endl
261
289
<< " \t Positions loaded: " << (db.positions_loaded () ? " true" : " false" ) << std::endl << std::endl;
262
- std::cout << " Loaded " << humanize (db.get_num_entries_loaded ())
263
- << " of " << humanize (db.get_num_entries_total ())
290
+ std::cout << " Loaded " << to_human_readable (db.get_num_entries_loaded ())
291
+ << " of " << to_human_readable (db.get_num_entries_total ())
264
292
<< " phylo-k-mers. " << std::endl << std::endl;
265
293
266
294
const auto tree = i2l::io::parse_newick (db.tree ());
@@ -325,7 +353,7 @@ int main(int argc, char** argv)
325
353
average_speed += seq_per_second;
326
354
327
355
// Update progress bar
328
- bar.set_option (option::PrefixText{humanize (seq_per_second) + " seq/s " });
356
+ bar.set_option (option::PrefixText{to_human_readable (seq_per_second) + " seq/s " });
329
357
bar.set_option (option::PostfixText{std::to_string (num_seq_placed) + " / ?" });
330
358
bar.set_progress (reader.bytes_read ());
331
359
@@ -339,12 +367,12 @@ int main(int argc, char** argv)
339
367
340
368
average_speed /= (double )num_iterations;
341
369
bar.set_option (option::PrefixText{" Done. " });
342
- bar.set_option (option::PostfixText{std::to_string (num_seq_placed)});
370
+ bar.set_option (option::PostfixText{to_human_readable (num_seq_placed)});
343
371
bar.set_progress (reader.bytes_read ());
344
372
345
373
std::cout << std::endl << termcolor::bold << termcolor::white
346
374
<< " Placed " << num_seq_placed << " sequences.\n Average speed: "
347
- << humanize (average_speed) << " seq/s.\n " ;
375
+ << to_human_readable (average_speed) << " seq/s.\n " ;
348
376
std::cout << " Output: " << jplace_filename << std::endl;
349
377
350
378
const auto placement_time = std::chrono::duration_cast<std::chrono::milliseconds>(
0 commit comments