cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cpu.h
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2013 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 
4 #ifndef CPU_H_
5 #define CPU_H_
6 
9 /* disable conditional expressions is constant */
10 #ifdef _MSC_VER
11 #pragma warning( disable : 4127 )
12 #endif
13 
15 #ifndef INT16_MAX
16 #define INT16_MAX 32767
17 #endif
18 #ifndef INT16_MIN
19 #define INT16_MIN (-INT16_MAX - 1)
20 #endif
21 
22 #if SHRT_MAX == INT16_MAX
23 typedef short int int16;
24 #elif INT_MAX == INT16_MAX
25 typedef int int16;
26 #else
27 #error failed to define int16, please report this to gary@pa.uky.edu
28 #endif
29 
30 #ifndef UINT16_MAX
31 #define UINT16_MAX 65535
32 #endif
33 
34 #if USHRT_MAX == UINT16_MAX
35 typedef unsigned short int uint16;
36 #elif UINT_MAX == UINT16_MAX
37 typedef unsigned int uint16;
38 #else
39 #error failed to define uint16, please report this to gary@pa.uky.edu
40 #endif
41 
42 #ifndef INT32_MAX
43 #define INT32_MAX 2147483647L
44 #endif
45 #ifndef INT32_MIN
46 #define INT32_MIN (-INT32_MAX - 1)
47 #endif
48 
49 #if INT_MAX == INT32_MAX
50 typedef int int32;
51 #elif LONG_MAX == INT32_MAX
52 typedef long int int32;
53 #else
54 #error failed to define int32, please report this to gary@pa.uky.edu
55 #endif
56 
57 #ifndef UINT32_MAX
58 #define UINT32_MAX 4294967295UL
59 #endif
60 
61 #if UINT_MAX == UINT32_MAX
62 typedef unsigned int uint32;
63 #elif ULONG_MAX == UINT32_MAX
64 typedef unsigned long int uint32;
65 #else
66 #error failed to define uint32, please report this to gary@pa.uky.edu
67 #endif
68 
69 #if LONG_MAX > INT32_MAX
70 
71 /* this will only be defined on LP64 systems
72  * ILP32 systems may have long long support, but that is not
73  * part of the ISO/ANSI standard, so we don't use it here... */
74 
75 /* INT64_MAX, etc, may be defined as long long, so avoid system definitions! */
76 
77 #undef INT64_MAX
78 #define INT64_MAX 9223372036854775807L
79 
80 #undef INT64_MIN
81 #define INT64_MIN (-INT64_MAX - 1L)
82 
83 #if LONG_MAX == INT64_MAX
84 #define HAVE_INT64 1
85 typedef long int int64;
86 #endif
87 
88 #endif
89 
90 #if ULONG_MAX > UINT32_MAX
91 
92 #undef UINT64_MAX
93 #define UINT64_MAX 18446744073709551615UL
94 
95 #if ULONG_MAX == UINT64_MAX
96 #define HAVE_UINT64 1
97 typedef unsigned long int uint64;
98 #endif
99 
100 #endif
101 
123 #ifdef cray
124 #ifndef __cray
125 #define __cray 1
126 #endif
127 #endif
128 
130 #ifdef __x86_64
131 #ifndef __amd64
132 #define __amd64 1
133 #endif
134 #endif
135 
136 #if defined(_ARCH_PPC) || defined(__POWERPC__) || defined(__powerpc__) || defined(PPC)
137 #ifndef __ppc__
138 #define __ppc__ 1
139 #endif
140 #endif
141 
147 #if defined(unix) || defined(__unix__)
148 #ifndef __unix
149 #define __unix 1
150 #endif
151 #endif
152 
154 #ifdef __ECC
155 #ifndef __ICC
156 #define __ICC __ECC
157 #endif
158 #endif
159 
161 #undef __GNUC_EXCL__
162 #if defined(__GNUC__) && ! ( defined(__ICC) || defined(__PATHSCALE__) || defined(__OPENCC__) || defined(__clang__) )
163 #define __GNUC_EXCL__ 1
164 #endif
165 
166 /* make sure __func__ is defined, this can be removed once C++0x is in effect */
167 #ifndef HAVE_FUNC
168 #undef __func__
169 #define __func__ DEBUG_ENTRY.name()
170 #endif
171 
172 /* safe, small, numbers for the float and double */
175 /*FLT_MAX is 3.40e38 on wintel, so BIGFLOAT is 3.40e36 */
179 
181 const double BIGDOUBLE = DBL_MAX/100.;
182 const double SMALLDOUBLE = DBL_MIN*100.;
183 
184 const int STDLEN = 32;
185 
196 
197 // the C++ openmodes below give the exact equivalent of the C modes "r", "w", "a", etc.
198 // the "+" sign in the C mode has been replaced by "p", so, e.g., mode_rpb is equivalent to "r+b"
199 const ios_base::openmode mode_r = ios_base::in;
200 const ios_base::openmode mode_w = ios_base::out | ios_base::trunc;
201 const ios_base::openmode mode_a = ios_base::out | ios_base::app;
202 const ios_base::openmode mode_rp = ios_base::in | ios_base::out;
203 const ios_base::openmode mode_wp = ios_base::in | ios_base::out | ios_base::trunc;
204 const ios_base::openmode mode_ap = ios_base::in | ios_base::out | ios_base::app;
205 
206 const ios_base::openmode mode_rb = mode_r | ios_base::binary;
207 const ios_base::openmode mode_wb = mode_w | ios_base::binary;
208 const ios_base::openmode mode_ab = mode_a | ios_base::binary;
209 const ios_base::openmode mode_rpb = mode_rp | ios_base::binary;
210 const ios_base::openmode mode_wpb = mode_wp | ios_base::binary;
211 const ios_base::openmode mode_apb = mode_ap | ios_base::binary;
212 
213 FILE* open_data( const char* fname, const char* mode, access_scheme scheme=AS_DATA_ONLY );
214 void open_data( fstream& stream, const char* fname, ios_base::openmode mode, access_scheme scheme=AS_DATA_ONLY );
215 
216 /* this class is deliberately kept global so that the constructor is executed before
217  * any of the user code; this assures a correct FP environment right from the start */
218 class t_cpu_i
219 {
222  union
223  {
224  char c[4];
225  int32 i;
226  } endian;
227 
229  double test_double;
230 
232 # ifdef HAVE_INT64
233  int64 Double_SNaN_Value;
234 # else
236 # endif
237 
238 # ifdef __unix
239  struct sigaction p_action;
240  struct sigaction p_default;
241 # endif
242 
245 
249  bool p_lgMPI;
256  long n_rank;
260  vector<string> chSearchPath;
264 
265  void enable_traps() const;
266  static void signal_handler(int sig);
267 
268  vector<string> p_exit_status;
269 
270  void getPathList( const char* fname, vector<string>& PathList, access_scheme scheme ) const;
271 public:
272  t_cpu_i();
273 
274  bool big_endian() const { return ( endian.i == 0x12345678 ); }
275  bool little_endian() const { return ( endian.i == 0x78563412 ); }
276 
277  sys_float min_float() const { return test_float; }
278  double min_double() const { return test_double; }
279 
280 # ifdef __unix
281  const struct sigaction* action() const { return &p_action; }
282  const struct sigaction* deflt() const { return &p_default; }
283 # endif
284 
285  void set_signal_handlers();
286 
287  void setAssertAbort(bool val)
288  {
289  p_lgAssertAbort = val;
290 #ifdef CATCH_SIGNAL
291 # ifdef __unix
292  if( val )
293  sigaction( SIGABRT, deflt(), NULL );
294  else
295  sigaction( SIGABRT, action(), NULL );
296 # endif
297 # ifdef _MSC_VER
298  if( val )
299  signal( SIGABRT, SIG_DFL );
300  else
301  signal( SIGABRT, &signal_handler );
302 # endif
303 #endif
304  }
305  bool lgAssertAbort() const { return p_lgAssertAbort; }
306 
307  void set_nCPU(long n) { n_avail_CPU = n; }
308  long nCPU() const { return n_avail_CPU; }
309  bool lgMPI() const { return p_lgMPI; }
310  void set_MPISingleRankMode( bool mode ) { p_lgMPISingleRankMode = mode; }
312  void set_nRANK(long n) { n_rank = n; }
313  long nRANK() const { return n_rank; }
314  bool lgMaster() const { return ( n_rank == 0 ); }
315  bool lgMPI_talk() const { return lgMaster() || lgMPISingleRankMode(); }
316  const char *host_name() const { return HostName; }
317  void printDataPath() const;
318  char chDirSeparator() const { return p_chDirSeparator; }
319  bool firstOpen() const { return ( nFileDone == 0 ); }
320  const string& chExitStatus(exit_type s) const { return p_exit_status[s]; }
321 
322  friend FILE* open_data( const char* fname, const char* mode, access_scheme scheme );
323  friend void open_data( fstream& stream, const char* fname, ios_base::openmode mode, access_scheme scheme );
324 
325  friend void set_NaN(sys_float &x);
326  friend void set_NaN(sys_float x[], long n);
327  friend void set_NaN(double &x);
328  friend void set_NaN(double x[], long n);
329 };
330 class t_cpu
331 {
332  static t_cpu_i *m_i;
333 public:
335  {
336  return *m_i;
337  }
338  t_cpu();
339  ~t_cpu();
340 };
341 // Generate a (static) instance of this variable in *every* file.
342 static t_cpu cpu;
343 
344 // The static (class) pointer is set in the first of these. Obviously
345 // this is not thread safe...
346 
347 // Better engineered variants are available in Alexandrescu's book;
348 // better yet to reduce the number of globals and file-statics so
349 // this can just be initialized at the start of main().
350 
352 void set_NaN(sys_float &x);
353 void set_NaN(sys_float x[], /* x[n] */
354  long n);
355 void set_NaN(double &x);
356 void set_NaN(double x[], /* x[n] */
357  long n);
358 
360 bool MyIsnan(const sys_float &x);
361 bool MyIsnan(const double &x);
362 
363 /* Apply compiler directive saying that current routine does not
364  return as modifier, as in "NORETURN void MyExit() { ... }" */
365 #ifdef _MSC_VER
366 #define NORETURN __declspec(noreturn) /*@noreturn@*/
367 #elif defined(__GNUC__) || ( defined(__INTEL_COMPILER) && defined(__linux) )
368 #define NORETURN __attribute__ ((noreturn)) /*@noreturn@*/
369 #else
370 #define NORETURN /*@noreturn@*/
371 #endif
372 
373 #define RESTRICT
374 #define UNLIKELY(x) (x)
375 #ifdef __GNUC__
376 #if (__GNUC__ >= 3)
377 #undef UNLIKELY
378 #define UNLIKELY(x) __builtin_expect((x),0)
379 #endif
380 #undef RESTRICT
381 #define RESTRICT __restrict
382 #define UNUSED __attribute__ ((unused)) /*@unused@*/
383 #else
384 #define UNUSED /*@unused@*/
385 #endif
386 
387 /* Some hackery needed to test if a preprocessor macro is empty. Use as follows:
388  * #if EXPAND(SOME_DODGY_MACRO) == 1
389  * get here if SOME_DODGY_MACRO expands to empty string
390  * #endif */
391 #define DO_EXPAND(VAL) VAL ## 1
392 #define EXPAND(VAL) DO_EXPAND(VAL)
393 
394 /* Define __COMP and __COMP_VER macros for all systems */
395 /* the Intel compiler */
396 /* this needs to be before g++ since icc also sets __GNUC__ */
397 #if defined __INTEL_COMPILER
398 # define __COMP "icc"
399 # define __COMP_VER __INTEL_COMPILER
400 
401 /* PathScale EKOPath compiler */
402 /* this needs to be before g++ since pathCC also sets __GNUC__ */
403 #elif defined __PATHSCALE__
404 # define __COMP "pathCC"
405 # define __COMP_VER __PATHCC__ * 100 + __PATHCC_MINOR__ * 10 + __PATHCC_PATCHLEVEL__
406 
407 /* Open64 compiler */
408 /* this needs to be before g++ since openCC also sets __GNUC__ */
409 #elif defined __OPENCC__
410 # define __COMP "Open64"
411 # if EXPAND(__OPENCC_PATCHLEVEL__) == 1
412 # define __COMP_VER __OPENCC__ * 100 + __OPENCC_MINOR__ * 10
413 # else
414 # define __COMP_VER __OPENCC__ * 100 + __OPENCC_MINOR__ * 10 + __OPENCC_PATCHLEVEL__
415 # endif
416 
417 /* LLVM clang++ */
418 /* this needs to be before g++ since clang++ also sets __GNUC__ */
419 #elif defined __clang__
420 # define __COMP "clang++"
421 # define __COMP_VER __clang_major__ * 100 + __clang_minor__ * 10 + __clang_patchlevel__
422 
423 /* g++ */
424 #elif defined __GNUC__
425 # define __COMP "g++"
426 # if defined(__GNUC_PATCHLEVEL__)
427 # define __COMP_VER (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
428 # else
429 # define __COMP_VER (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
430 # endif
431 
432 #elif defined __PGI
433 # define __COMP "Portland Group"
434 # if defined(__PGIC__)
435 # define __COMP_VER (__PGIC__ * 100 + __PGIC_MINOR__ * 10 + __PGIC_PATCHLEVEL__)
436 # else
437 # define __COMP_VER 0
438 # endif
439 
440 /* SGI MIPSpro */
441 /* this needs to be after g++, since g++ under IRIX also sets _COMPILER_VERSION */
442 #elif defined(__sgi) && defined(_COMPILER_VERSION)
443 # define __COMP "MIPSpro"
444 # define __COMP_VER _COMPILER_VERSION
445 
446 /* HP */
447 #elif defined __HP_aCC
448 # define __COMP "HP aCC"
449 # define __COMP_VER __HP_aCC
450 
451 /* DEC - this one may be broken for C++, no way to test it... */
452 #elif defined __DECC
453 # define __COMP "DEC CC"
454 # define __COMP_VER __DECC_VER
455 
456 /* MS VS */
457 #elif defined _MSC_VER
458 # define __COMP "vs"
459 # define __COMP_VER _MSC_VER
460 
461 /* Oracle Solaris Studio */
462 #elif defined __SUNPRO_CC
463 # define __COMP "Solaris Studio"
464 # define __COMP_VER __SUNPRO_CC
465 
466 /* unknown */
467 #else
468 # define __COMP "unknown"
469 # define __COMP_VER 0
470 #endif
471 
472 /* ---------------------------- OS ---------------------------- */
473 /* linux */
474 #if defined __linux
475 # if defined __i386
476 # define __OS "Linux (IA32)"
477 # elif defined __amd64
478 # define __OS "Linux (AMD64)"
479 # elif defined __ia64
480 # define __OS "Linux (IA64)"
481 # elif defined __ppc__
482 # define __OS "Linux (PowerPC)"
483 # else
484 # define __OS "Linux (other)"
485 # endif
486 
487 /* macintosh */
488 #elif defined macintosh
489 # define __OS "Mac OS 9"
490 
491 /* macintosh */
492 #elif defined __MACOSX__
493 # define __OS "Mac OS X"
494 
495 /* apple mac, ... */
496 #elif defined __APPLE__
497 # define __OS "Apple MacOS"
498 
499 /* HP */
500 #elif defined hpux
501 # define __OS "HP-UX"
502 
503 /* Oracle Solaris */
504 #elif defined __sun
505 # define __OS "Solaris"
506 
507 /* IBM AIX */
508 #elif defined _AIX
509 # define __OS "AIX"
510 
511 /* Compaq alpha */
512 #elif defined ultrix
513 # define __OS "Ultrix"
514 
515 /* the BSD variants */
516 #elif defined __FreeBSD__
517 # define __OS "FreeBSD"
518 
519 #elif defined __NetBSD__
520 # define __OS "NetBSD"
521 
522 #elif defined __OpenBSD__
523 # define __OS "OpenBSD"
524 
525 /* Windows64 */
526 /* this needs to be before _WIN32 since Windows64 also sets _WIN32 */
527 #elif defined _WIN64
528 # define __OS "Win64"
529 
530 /* Windows */
531 #elif defined _WIN32
532 # define __OS "Win32"
533 
534 /* Cygwin */
535 #elif defined __CYGWIN__
536 # define __OS "Cygwin"
537 
538 /* SGI */
539 #elif defined __sgi
540 # define __OS "IRIX"
541 
542 /* unknown */
543 #else
544 # define __OS "unknown"
545 #endif
546 
547 /* don't perform this check when we are generating dependencies */
548 #ifndef MM
549 /* bomb out if the compiler is broken.... */
550 #if defined(__GNUC_EXCL__) && ((__GNUC__ == 2 && __GNUC_MINOR__ == 96) || (__GNUC__ == 3 && __GNUC_MINOR__ == 4))
551 #error "This g++ version cannot compile Cloudy and must not be used! Please update g++ to a functional version. See http://wiki.nublado.org/wiki/CompilingCloudy for more details."
552 #endif
553 
554 #if __INTEL_COMPILER >= 1200 && __INTEL_COMPILER < 1300
555 #error "This icc version cannot compile Cloudy and must not be used! Please use a functional version of icc, or g++. See http://wiki.nublado.org/wiki/CompilingCloudy for more details."
556 #endif
557 #endif
558 
559 #ifdef _MSC_VER
560 #pragma warning( default : 4127 )/* disable warning that conditional expression is constant*/
561 #endif
562 
563 #endif /* CPU_H_ */
long nRANK() const
Definition: cpu.h:313
const ios_base::openmode mode_wpb
Definition: cpu.h:210
long n_rank
Definition: cpu.h:256
const ios_base::openmode mode_wp
Definition: cpu.h:203
FILE * open_data(const char *fname, const char *mode, access_scheme scheme)
Definition: cpu.cpp:616
static void signal_handler(int sig)
Definition: cpu.cpp:503
void getPathList(const char *fname, vector< string > &PathList, access_scheme scheme) const
Definition: cpu.cpp:523
bool p_lgMPISingleRankMode
Definition: cpu.h:254
const ios_base::openmode mode_apb
Definition: cpu.h:211
double test_double
Definition: cpu.h:229
const double BIGDOUBLE
Definition: cpu.h:181
union t_cpu_i::@3 endian
void set_NaN(sys_float &x)
Definition: cpu.cpp:673
friend void set_NaN(sys_float &x)
Definition: cpu.cpp:673
const realnum SMALLFLOAT
Definition: cpu.h:178
const ios_base::openmode mode_rb
Definition: cpu.h:206
t_cpu_i & i()
Definition: cpu.h:334
int32 Double_SNaN_Value[2]
Definition: cpu.h:235
const double SMALLDOUBLE
Definition: cpu.h:182
access_scheme
Definition: cpu.h:194
Definition: cpu.h:218
const int STDLEN
Definition: cpu.h:184
static t_cpu_i * m_i
Definition: cpu.h:332
void setAssertAbort(bool val)
Definition: cpu.h:287
bool big_endian() const
Definition: cpu.h:274
bool MyIsnan(const sys_float &x)
Definition: cpu.cpp:744
void set_nRANK(long n)
Definition: cpu.h:312
double min_double() const
Definition: cpu.h:278
char HostName[STDLEN]
Definition: cpu.h:258
exit_type
Definition: cddefines.h:119
bool little_endian() const
Definition: cpu.h:275
~t_cpu()
Definition: cpu.cpp:59
bool lgAssertAbort() const
Definition: cpu.h:305
friend FILE * open_data(const char *fname, const char *mode, access_scheme scheme)
Definition: cpu.cpp:616
long n_avail_CPU
Definition: cpu.h:247
const ios_base::openmode mode_a
Definition: cpu.h:201
const ios_base::openmode mode_r
Definition: cpu.h:199
int nFileDone
Definition: cpu.h:263
const ios_base::openmode mode_rpb
Definition: cpu.h:209
float realnum
Definition: cddefines.h:107
float sys_float
Definition: cddefines.h:110
t_cpu_i()
Definition: cpu.cpp:68
const realnum BIGFLOAT
Definition: cpu.h:176
void printDataPath() const
Definition: cpu.cpp:515
bool lgMaster() const
Definition: cpu.h:314
int32 Float_SNaN_Value
Definition: cpu.h:231
long max(int a, long b)
Definition: cddefines.h:779
bool firstOpen() const
Definition: cpu.h:319
bool lgMPI_talk() const
Definition: cpu.h:315
char p_chDirSeparator
Definition: cpu.h:262
long min(int a, long b)
Definition: cddefines.h:727
vector< string > p_exit_status
Definition: cpu.h:268
const ios_base::openmode mode_ap
Definition: cpu.h:204
const ios_base::openmode mode_w
Definition: cpu.h:200
sys_float min_float() const
Definition: cpu.h:277
void set_signal_handlers()
Definition: cpu.cpp:468
bool lgMPI() const
Definition: cpu.h:309
bool p_lgAssertAbort
Definition: cpu.h:244
void set_MPISingleRankMode(bool mode)
Definition: cpu.h:310
void set_nCPU(long n)
Definition: cpu.h:307
char c[4]
Definition: cpu.h:224
Definition: cpu.h:330
long nCPU() const
Definition: cpu.h:308
int32 i
Definition: cpu.h:225
void enable_traps() const
Definition: cpu.cpp:289
sys_float test_float
Definition: cpu.h:228
static t_cpu cpu
Definition: cpu.h:342
bool p_lgMPI
Definition: cpu.h:249
vector< string > chSearchPath
Definition: cpu.h:260
const ios_base::openmode mode_ab
Definition: cpu.h:208
const ios_base::openmode mode_wb
Definition: cpu.h:207
const ios_base::openmode mode_rp
Definition: cpu.h:202
t_cpu()
Definition: cpu.cpp:52
char chDirSeparator() const
Definition: cpu.h:318
bool lgMPISingleRankMode() const
Definition: cpu.h:311
const char * host_name() const
Definition: cpu.h:316
const string & chExitStatus(exit_type s) const
Definition: cpu.h:320