A toolkit for working with phylogenetic data.
v0.24.0
options.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2019 Lucas Czech and HITS gGmbH
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Contact:
19  Lucas Czech <lucas.czech@h-its.org>
20  Exelixis Lab, Heidelberg Institute for Theoretical Studies
21  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
22 */
23 
32 
34 
35 #include <chrono>
36 #include <cstdint>
37 #include <cstdio>
38 
39 #if defined( _WIN32 ) || defined( _WIN64 )
40 # include <io.h>
41 # include <windows.h>
42 #else
43 # include <cpuid.h>
44 # include <stdio.h>
45 # include <sys/ioctl.h>
46 # include <unistd.h>
47 #endif
48 
49 #ifdef GENESIS_OPENMP
50 # include <omp.h>
51 #endif
52 
53 #ifdef GENESIS_PTHREADS
54 # include <thread>
55 #endif
56 
57 namespace genesis {
58 namespace utils {
59 
60 // =================================================================================================
61 // Initialization
62 // =================================================================================================
63 
64 #if defined( DEBUG ) && defined( NDEBUG )
65  static_assert( false, "Cannot compile with both DEBUG and NDEBUG flags set." );
66 #endif
67 
68 #if ! defined( DEBUG ) && ! defined( NDEBUG )
69  static_assert( false, "Cannot compile with neiher DEBUG nor NDEBUG flag set." );
70 #endif
71 
72 Options::Options()
73 {
74  // Initialize number of threads to hardware cores.
76 
77  // Initialize random seed with time.
78  random_seed( std::chrono::system_clock::now().time_since_epoch().count() );
79 }
80 
81 // =================================================================================================
82 // Command Line
83 // =================================================================================================
84 
85 std::string Options::command_line_string () const
86 {
87  std::string ret = "";
88  for (size_t i = 0; i < command_line_.size(); ++i) {
89  std::string a = command_line_[i];
90  ret += (i==0 ? "" : " ") + a;
91  }
92  return ret;
93 }
94 
95 void Options::command_line( int const argc, char const* const* argv )
96 {
97  // Store all arguments in the array.
98  command_line_.clear();
99  for (int i = 0; i < argc; i++) {
100  command_line_.push_back(argv[i]);
101  }
102 }
103 
104 // =================================================================================================
105 // Number of Threads
106 // =================================================================================================
107 
108 void Options::number_of_threads ( unsigned int number )
109 {
110  if( number == 0 ) {
111  #ifdef GENESIS_PTHREADS
112  number = std::thread::hardware_concurrency();
113  if( number == 0 ) {
114  number = 1;
115  }
116  #else
117  number = 1;
118  #endif
119  }
120  number_of_threads_ = number;
121 
122  #if defined( GENESIS_OPENMP )
123 
124  // If we use OpenMp, set the thread number there, too.
125  omp_set_num_threads( number );
126 
127  #endif
128 }
129 
131 {
132  // Get CPU info.
133  int32_t info[4];
134  #ifdef _WIN32
135  __cpuid( info, 1 );
136  #else
137  __cpuid_count( 1, 0, info[0], info[1], info[2], info[3] );
138  #endif
139 
140  return (bool) (info[3] & (0x1 << 28));
141 }
142 
143 unsigned int Options::guess_number_of_threads( bool use_openmp ) const
144 {
145  // Dummy to avoid compiler warnings.
146  (void) use_openmp;
147 
148  #if defined( GENESIS_OPENMP )
149 
150  // Use number of OpenMP threads, which might be set through the
151  // `OMP_NUM_THREADS` environment variable.
152  if( use_openmp ) {
153  return omp_get_max_threads();
154  }
155 
156  #endif
157 
158  #if defined( GENESIS_PTHREADS )
159 
160  // Initialize threads with actual number of cores.
161  // return std::thread::hardware_concurrency();
162 
163  auto const lcores = std::thread::hardware_concurrency();
164  auto const threads_per_core = hyperthreads_enabled() ? 2 : 1;
165  return lcores / threads_per_core;
166 
167  #else
168 
169  // Default to single threaded.
170  return 1;
171 
172  #endif
173 }
174 
175 // =================================================================================================
176 // Random Seed & Engine
177 // =================================================================================================
178 
179 void Options::random_seed(const unsigned long seed)
180 {
181  random_seed_ = seed;
182  random_engine_.seed( seed );
183 }
184 
185 // =================================================================================================
186 // Run Time Environment
187 // =================================================================================================
188 
190 {
191  // Using http://stackoverflow.com/a/1312957/4184258
192  #if defined( _WIN32 ) || defined( _WIN64 )
193  return _isatty( _fileno( stdin ));
194  #else
195  return isatty( fileno( stdin ));
196  #endif
197 }
198 
200 {
201  #if defined( _WIN32 ) || defined( _WIN64 )
202  return _isatty( _fileno( stdout ));
203  #else
204  return isatty( fileno( stdout ));
205  #endif
206 }
207 
209 {
210  #if defined( _WIN32 ) || defined( _WIN64 )
211  return _isatty( _fileno( stderr ));
212  #else
213  return isatty( fileno( stderr ));
214  #endif
215 }
216 
217 std::pair<int, int> Options::terminal_size()
218 {
219  #if defined( _WIN32 ) || defined( _WIN64 )
220 
221  CONSOLE_SCREEN_BUFFER_INFO csbi;
222  int cols, rows;
223  GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
224  cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
225  rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
226  return { cols, rows };
227 
228  #else
229 
230  struct winsize w;
231  ioctl( STDOUT_FILENO, TIOCGWINSZ, &w );
232  return { w.ws_col, w.ws_row };
233 
234  #endif
235 }
236 
237 // =================================================================================================
238 // Compile Time Environment
239 // =================================================================================================
240 
242 {
243  #ifdef DEBUG
244  return true;
245  #else
246  return false;
247  #endif
248 }
249 
251 {
252  #ifdef NDEBUG
253  return true;
254  #else
255  return false;
256  #endif
257 }
258 
259 std::string Options::build_type()
260 {
261  #if defined( DEBUG )
262  return "debug";
263  #elif defined( NDEBUG )
264  return "release";
265  #else
266  return "unknown";
267  #endif
268 }
269 
271 {
272  static const uint16_t e = 0x1000;
273  return 0 == *reinterpret_cast< uint8_t const* >( &e );
274 }
275 
277 {
278  static const uint16_t e = 0x0001;
279  return 0 == *reinterpret_cast< uint8_t const* >( &e );
280 }
281 
282 std::string Options::platform()
283 {
284  #if defined _WIN64
285  return "Win64";
286  #elif defined _WIN32
287  return "Win32";
288  #elif defined __linux__
289  return "Linux";
290  #elif defined __APPLE__
291  return "Apple";
292  #elif defined __unix__
293  return "Unix";
294  #else
295  return "Unknown";
296  #endif
297 }
298 
300 {
301  #if defined(__clang__)
302  return "clang";
303  #elif defined(__ICC) || defined(__INTEL_COMPILER)
304  return "icc";
305  #elif defined(__GNUC__) || defined(__GNUG__)
306  return "gcc";
307  #elif defined(__HP_cc) || defined(__HP_aCC)
308  return "hp";
309  #elif defined(__IBMCPP__)
310  return "ilecpp";
311  #elif defined(_MSC_VER)
312  return "msvc";
313  #elif defined(__PGI)
314  return "pgcpp";
315  #elif defined(__SUNPRO_CC)
316  return "sunpro";
317  #else
318  return "unknown";
319  #endif
320 }
321 
323 {
324  #if defined(__clang__)
325  return __clang_version__;
326  #elif defined(__ICC) || defined(__INTEL_COMPILER)
327  return __INTEL_COMPILER;
328  #elif defined(__GNUC__) || defined(__GNUG__)
329  return std::to_string(__GNUC__) + "." +
330  std::to_string(__GNUC_MINOR__) + "." +
331  std::to_string(__GNUC_PATCHLEVEL__)
332  ;
333  #elif defined(__HP_cc) || defined(__HP_aCC)
334  return "";
335  #elif defined(__IBMCPP__)
336  return __IBMCPP__;
337  #elif defined(_MSC_VER)
338  return _MSC_VER;
339  #elif defined(__PGI)
340  return __PGI;
341  #elif defined(__SUNPRO_CC)
342  return __SUNPRO_CC;
343  #else
344  return "unknown";
345  #endif
346 }
347 
348 std::string Options::cpp_version()
349 {
350  #ifdef __cplusplus
351  return std::to_string(__cplusplus);
352  #else
353  return "unknown";
354  #endif
355 }
356 
358 {
359  return std::string( __DATE__ " " __TIME__ );
360 }
361 
363 {
364  #ifdef GENESIS_PTHREADS
365  return true;
366  #else
367  return false;
368  #endif
369 }
370 
372 {
373  #ifdef GENESIS_OPENMP
374  return true;
375  #else
376  return false;
377  #endif
378 }
379 
381 {
382  #ifdef GENESIS_ZLIB
383  return true;
384  #else
385  return false;
386  #endif
387 }
388 
389 // =================================================================================================
390 // Dump & Overview
391 // =================================================================================================
392 
393 std::string Options::info() const
394 {
395  std::string res;
396  res += genesis_header() + "\n";
397  res += info_compile_time() + "\n";
398  res += info_run_time() + "\n";
399  return res;
400 }
401 
402 std::string Options::info_compile_time() const
403 {
404  std::string res;
405  res += "Compile Time Options\n";
406  res += "=============================================\n\n";
407  res += "Platform: " + platform() + "\n";
408  res += "Compiler: " + compiler_family() + " " + compiler_version() + "\n";
409  res += "C++ version: " + cpp_version() + "\n";
410  res += "Build type: " + build_type() + "\n";
411  res += "Endianness: " + std::string( is_little_endian() ? "little endian" : "big endian" ) + "\n";
412  res += "Using Pthreads: " + std::string( using_pthreads() ? "true" : "false" ) + "\n";
413  res += "Using OpenMP: " + std::string( using_openmp() ? "true" : "false" ) + "\n";
414  return res;
415 }
416 
417 std::string Options::info_run_time() const
418 {
419  std::string res;
420  res += "Run Time Options\n";
421  res += "=============================================\n\n";
422  auto const cli_str = command_line_string();
423  res += "Command line: " + ( cli_str.size() > 0 ? cli_str : "(not available)" ) + "\n";
424  res += "Number of threads: " + std::to_string( number_of_threads() ) + "\n";
425  res += "Random seed: " + std::to_string( random_seed_ ) + "\n";
426  return res;
427 }
428 
429 } // namespace utils
430 } // namespace genesis
unsigned long random_seed() const
Returns the random seed that was used to initialize the engine.
Definition: options.hpp:134
std::vector< std::string > command_line() const
Returns an array of strings containing the program&#39;s command line arguments.
Definition: options.hpp:73
static std::string cpp_version()
Return the CPP version that was used to compile genesis.
Definition: options.cpp:348
unsigned int guess_number_of_threads(bool use_openmp=true) const
Try to guess the number of hardware threads of the current system.
Definition: options.cpp:143
std::string info_run_time() const
Return a list of run time options.
Definition: options.cpp:417
static bool stderr_is_terminal()
Return true iff the standard error stream is a terminal, and false if not, i.e., if it is a file or a...
Definition: options.cpp:208
static bool using_zlib()
Return whether the binary was compiled using zlib.
Definition: options.cpp:380
static bool stdout_is_terminal()
Return true iff the standard output stream is a terminal, and false if not, i.e., if it is a file or ...
Definition: options.cpp:199
static std::string compiler_version()
Return the compiler version that was used to compile genesis.
Definition: options.cpp:322
static std::string platform()
Return the platform under which genesis was compiled.
Definition: options.cpp:282
static std::string compiler_family()
Return the compiler family (name) that was used to compile genesis.
Definition: options.cpp:299
static bool is_debug()
Return whether the binary was compiled with build type DEBUG.
Definition: options.cpp:241
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
static std::pair< int, int > terminal_size()
Return the width and height of the terminal that is used to run the program, in number of columns and...
Definition: options.cpp:217
std::string info_compile_time() const
Return a list of compile time options.
Definition: options.cpp:402
bool hyperthreads_enabled() const
Try to get whether hyperthreads are enabled in the current system.
Definition: options.cpp:130
static bool using_openmp()
Return whether the binary was compiled using OpenMP.
Definition: options.cpp:371
static std::string compile_date_time()
Return the date and time when genesis was compiled.
Definition: options.cpp:357
unsigned int number_of_threads() const
Returns the number of threads.
Definition: options.hpp:98
static bool is_release()
Return whether the binary was compiled with build type RELEASE.
Definition: options.cpp:250
std::string command_line_string() const
Returns a string containing the program&#39;s command line arguments.
Definition: options.cpp:85
static bool stdin_is_terminal()
Return true iff the standard input stream is a terminal, and false if not, i.e., if it is a file or a...
Definition: options.cpp:189
static std::string build_type()
Return the build type that was used to compile the binary, i.e., "debug" or "release".
Definition: options.cpp:259
static bool is_big_endian()
Return whether the system uses big endian memory.
Definition: options.cpp:276
std::shared_ptr< BaseOutputTarget > to_string(std::string &target_string)
Obtain an output target for writing to a string.
std::string info() const
Return a list with compile time and run time options with their values.
Definition: options.cpp:393
static bool is_little_endian()
Return whether the system uses little endian memory.
Definition: options.cpp:270
static bool using_pthreads()
Return whether the binary was compiled using Pthreads.
Definition: options.cpp:362
Some stuff that is totally not imporatant, but nice.
std::string genesis_header()
Return the header for genesis.
Definition: version.hpp:94