A toolkit for working with phylogenetic data.
v0.20.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
options.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2018 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 <stdio.h>
44 # include <sys/ioctl.h>
45 # include <unistd.h>
46 #endif
47 
48 #ifdef GENESIS_OPENMP
49 # include <omp.h>
50 #endif
51 
52 #ifdef GENESIS_PTHREADS
53 # include <thread>
54 #endif
55 
56 namespace genesis {
57 namespace utils {
58 
59 // =================================================================================================
60 // Initialization
61 // =================================================================================================
62 
63 #if defined( DEBUG ) && defined( NDEBUG )
64  static_assert( false, "Cannot compile with both DEBUG and NDEBUG flags set." );
65 #endif
66 
67 #if ! defined( DEBUG ) && ! defined( NDEBUG )
68  static_assert( false, "Cannot compile with neiher DEBUG nor NDEBUG flag set." );
69 #endif
70 
71 Options::Options()
72 {
73 
74  #if defined( GENESIS_OPENMP )
75 
76  // Initialize threads to number of OpenMP threads, which might be set through the
77  // `OMP_NUM_THREADS` environment variable.
78  number_of_threads( omp_get_num_threads() );
79 
80  #elif defined( GENESIS_PTHREADS )
81 
82  // Initialize threads with actual number of cores.
83  number_of_threads( std::thread::hardware_concurrency() );
84 
85  #else
86 
87  // Set to single threaded.
88  number_of_threads( 1 );
89 
90  #endif
91 
92  // Initialize random seed with time.
93  random_seed( std::chrono::system_clock::now().time_since_epoch().count() );
94 }
95 
96 // =================================================================================================
97 // Command Line
98 // =================================================================================================
99 
100 std::string Options::command_line_string () const
101 {
102  std::string ret = "";
103  for (size_t i = 0; i < command_line_.size(); ++i) {
104  std::string a = command_line_[i];
105  ret += (i==0 ? "" : " ") + a;
106  }
107  return ret;
108 }
109 
110 void Options::command_line( int const argc, char const* const* argv )
111 {
112  // Store all arguments in the array.
113  command_line_.clear();
114  for (int i = 0; i < argc; i++) {
115  command_line_.push_back(argv[i]);
116  }
117 }
118 
119 // =================================================================================================
120 // Number of Threads
121 // =================================================================================================
122 
123 void Options::number_of_threads ( unsigned int number )
124 {
125  if( number == 0 ) {
126  #ifdef GENESIS_PTHREADS
127  number = std::thread::hardware_concurrency();
128  if( number == 0 ) {
129  number = 1;
130  }
131  #else
132  number = 1;
133  #endif
134  }
135  number_of_threads_ = number;
136 
137  #if defined( GENESIS_OPENMP )
138 
139  // If we use OpenMp, set the thread number there, too.
140  omp_set_num_threads( number );
141 
142  #endif
143 }
144 
146 {
147  #ifdef GENESIS_PTHREADS
148  return true;
149  #else
150  return false;
151  #endif
152 }
153 
155 {
156  #ifdef GENESIS_OPENMP
157  return true;
158  #else
159  return false;
160  #endif
161 }
162 
163 // =================================================================================================
164 // Random Seed & Engine
165 // =================================================================================================
166 
167 void Options::random_seed(const unsigned seed)
168 {
169  random_seed_ = seed;
170  random_engine_.seed( seed );
171 }
172 
173 // =================================================================================================
174 // Run Time Environment
175 // =================================================================================================
176 
178 {
179  // Using http://stackoverflow.com/a/1312957/4184258
180  #if defined( _WIN32 ) || defined( _WIN64 )
181  return _isatty( _fileno( stdin ));
182  #else
183  return isatty( fileno( stdin ));
184  #endif
185 }
186 
188 {
189  #if defined( _WIN32 ) || defined( _WIN64 )
190  return _isatty( _fileno( stdout ));
191  #else
192  return isatty( fileno( stdout ));
193  #endif
194 }
195 
197 {
198  #if defined( _WIN32 ) || defined( _WIN64 )
199  return _isatty( _fileno( stderr ));
200  #else
201  return isatty( fileno( stderr ));
202  #endif
203 }
204 
205 std::pair<int, int> Options::terminal_size() const
206 {
207  #if defined( _WIN32 ) || defined( _WIN64 )
208 
209  CONSOLE_SCREEN_BUFFER_INFO csbi;
210  int cols, rows;
211  GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
212  cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
213  rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
214  return { cols, rows };
215 
216  #else
217 
218  struct winsize w;
219  ioctl( STDOUT_FILENO, TIOCGWINSZ, &w );
220  return { w.ws_col, w.ws_row };
221 
222  #endif
223 }
224 
225 // =================================================================================================
226 // Compile Time Environment
227 // =================================================================================================
228 
230 {
231  static const uint16_t e = 0x1000;
232  return 0 == *reinterpret_cast< uint8_t const* >( &e );
233 }
234 
236 {
237  static const uint16_t e = 0x0001;
238  return 0 == *reinterpret_cast< uint8_t const* >( &e );
239 }
240 
241 std::string Options::platform()
242 {
243  #if defined _WIN64
244  return "Win64";
245  #elif defined _WIN32
246  return "Win32";
247  #elif defined __linux__
248  return "Linux";
249  #elif defined __APPLE__
250  return "Apple";
251  #elif defined __unix__
252  return "Unix";
253  #else
254  return "Unknown";
255  #endif
256 }
257 
259 {
260  #if defined(__clang__)
261  return "clang";
262  #elif defined(__ICC) || defined(__INTEL_COMPILER)
263  return "icc";
264  #elif defined(__GNUC__) || defined(__GNUG__)
265  return "gcc";
266  #elif defined(__HP_cc) || defined(__HP_aCC)
267  return "hp";
268  #elif defined(__IBMCPP__)
269  return "ilecpp";
270  #elif defined(_MSC_VER)
271  return "msvc";
272  #elif defined(__PGI)
273  return "pgcpp";
274  #elif defined(__SUNPRO_CC)
275  return "sunpro";
276  #else
277  return "unknown";
278  #endif
279 }
280 
282 {
283  #if defined(__clang__)
284  return __clang_version__;
285  #elif defined(__ICC) || defined(__INTEL_COMPILER)
286  return __INTEL_COMPILER;
287  #elif defined(__GNUC__) || defined(__GNUG__)
288  return std::to_string(__GNUC__) + "." +
289  std::to_string(__GNUC_MINOR__) + "." +
290  std::to_string(__GNUC_PATCHLEVEL__)
291  ;
292  #elif defined(__HP_cc) || defined(__HP_aCC)
293  return "";
294  #elif defined(__IBMCPP__)
295  return __IBMCPP__;
296  #elif defined(_MSC_VER)
297  return _MSC_VER;
298  #elif defined(__PGI)
299  return __PGI;
300  #elif defined(__SUNPRO_CC)
301  return __SUNPRO_CC;
302  #else
303  return "unknown";
304  #endif
305 }
306 
307 std::string Options::cpp_version()
308 {
309  #ifdef __cplusplus
310  return std::to_string(__cplusplus);
311  #else
312  return "unknown";
313  #endif
314 }
315 
316 // =================================================================================================
317 // Build Type
318 // =================================================================================================
319 
321 {
322  #ifdef DEBUG
323  return true;
324  #else
325  return false;
326  #endif
327 }
328 
330 {
331  #ifdef NDEBUG
332  return true;
333  #else
334  return false;
335  #endif
336 }
337 
338 std::string Options::build_type()
339 {
340  #if defined( DEBUG )
341  return "debug";
342  #elif defined( NDEBUG )
343  return "release";
344  #else
345  return "unknown";
346  #endif
347 }
348 
349 // =================================================================================================
350 // Dump & Overview
351 // =================================================================================================
352 
353 std::string Options::info() const
354 {
355  std::string res = genesis_header();
356 
357  res += "\n";
358  res += "Compile Time Options\n";
359  res += "=============================================\n\n";
360  res += "Platform: " + platform() + "\n";
361  res += "Compiler: " + compiler_family() + " " + compiler_version() + "\n";
362  res += "C++ version: " + cpp_version() + "\n";
363  res += "Build type: " + build_type() + "\n";
364  res += "Endianness: " + std::string( is_little_endian() ? "little endian" : "big endian" ) + "\n";
365  res += "Using Pthreads: " + std::string( using_pthreads() ? "true" : "false" ) + "\n";
366  res += "Using OpenMP: " + std::string( using_openmp() ? "true" : "false" ) + "\n";
367 
368  res += "\n";
369  res += "Run Time Options\n";
370  res += "=============================================\n\n";
371  auto const cli_str = command_line_string();
372  res += "Command line: " + ( cli_str.size() > 0 ? cli_str : "(not available)" ) + "\n";
373  res += "Number of threads: " + std::to_string( number_of_threads() ) + "\n";
374  res += "Random seed: " + std::to_string( random_seed_ ) + "\n";
375  return res;
376 }
377 
378 } // namespace utils
379 } // namespace genesis
static std::string cpp_version()
Return the CPP version that was used to compile genesis.
Definition: options.cpp:307
bool stdout_is_terminal() const
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:187
static std::string compiler_version()
Return the compiler version that was used to compile genesis.
Definition: options.cpp:281
static std::string platform()
Return the platform under which genesis was compiled.
Definition: options.cpp:241
unsigned int number_of_threads() const
Returns the number of threads.
Definition: options.hpp:98
static std::string compiler_family()
Return the compiler family (name) that was used to compile genesis.
Definition: options.cpp:258
bool using_pthreads() const
Return whether the binary was compiled using Pthreads.
Definition: options.cpp:145
static bool is_debug()
Return whether the binary was compiled with build type DEBUG.
Definition: options.cpp:320
std::vector< std::string > command_line() const
Returns an array of strings containing the program's command line arguments.
Definition: options.hpp:73
std::string to_string(T const &v)
Return a string representation of a given value.
Definition: string.hpp:381
std::pair< int, int > terminal_size() const
Return the width and height of the terminal that is used to run the program, in number of columns and...
Definition: options.cpp:205
std::string command_line_string() const
Returns a string containing the program's command line arguments.
Definition: options.cpp:100
static bool is_release()
Return whether the binary was compiled with build type RELEASE.
Definition: options.cpp:329
unsigned random_seed() const
Returns the random seed that was used to initialize the engine.
Definition: options.hpp:131
bool stdin_is_terminal() const
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:177
std::string info() const
Return a list with compile time and run time options with their values.
Definition: options.cpp:353
static std::string build_type()
Return the build type that was used to compile the binary, i.e., "debug" or "release".
Definition: options.cpp:338
static bool is_big_endian()
Return whether the system uses big endian memory.
Definition: options.cpp:235
bool using_openmp() const
Return whether the binary was compiled using OpenMP.
Definition: options.cpp:154
static bool is_little_endian()
Return whether the system uses little endian memory.
Definition: options.cpp:229
bool stderr_is_terminal() const
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:196
Some stuff that is totally not imporatant, but nice.
std::string genesis_header()
Return the header for genesis.
Definition: version.hpp:93