MCL
A C++ library mirroring some of the most common Matlab functions.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
mcltypes.h
Go to the documentation of this file.
1 /*
2  MCL
3  Copyright (c) 2012-18, Enzo De Sena
4  All rights reserved.
5 
6  Authors: Enzo De Sena, enzodesena@gmail.com
7  */
8 
9 #include <assert.h>
10 
11 #ifndef MCL_MCLTYPES_H
12 #define MCL_MCLTYPES_H
13 
14 #ifndef PI
15  #define PI 3.141592653589793238462643383279502884197169399375105820974944
16 #endif
17 
18 #define ASSERT(arg) assert(arg)
19 #define ASSERT_WITH_MESSAGE(condition, message) ASSERT(condition && message)
20 #define AVOID_UNUSED_WARNING(arg) (void)(arg);
21 
22 #include <complex>
23 #include <vector>
24 #include <iostream>
25 #include <fstream>
26 
27 
28 #if _WIN32 || _WIN64
29  #if _WIN64
30  #define MCL_ENV64BIT 1
31  #else
32  #define MCL_ENV32BIT 1
33  #endif
34 #elif __GNUC__
35  #if __x86_64__ || __ppc64__
36  #define MCL_ENV64BIT 1
37  #else
38  #define MCL_ENV32BIT 1
39  #endif
40 #endif
41 
42 
43 #if _WIN32 || _WIN64
44  #define MCL_ENVWINDOWS 1
45 #elif __APPLE__
46  #define MCL_ENVAPPLE 1
47 #elif __arm__ || __aarch64__ // Since this elif comes second, priority is given to APPLE descriptor
48  #define MCL_ENVARM 1
49 #else
50  #define MCL_ENVOTHER 1
51 #endif
52 
53 #ifdef MCL_ENVAPPLE
54  #define MCL_APPLE_ACCELERATE 1
55 #elif MCL_ENVARM
56  #define MCL_NEON_ACCELERATE 1
57 #elif MCL_ENVWINDOWS
58  #define MCL_AVX_ACCELERATE 1
59 #else // MCL_ENVOTHER
60  #define MCL_NO_ACCELERATE 1
61 #endif
62 
63 // Exclude multiply and multiply-add as the compiler is able to do a better job
64 #define MCL_APPLE_ACCELERATE_MMA 0
65 
66 #define MCL_MAX_VLA_LENGTH 16384
67 
68 #if MCL_ENVWINDOWS
69  #define MCL_STACK_ALLOCATE(type, variable, size) type* variable = (type*)alloca((size)*sizeof(type));
70 #else
71  #define MCL_STACK_ALLOCATE(type, variable, size) type variable[(size)];
72 #endif
73 
74 #if MCL_ENVWINDOWS
75  #include <intrin.h>
76 #endif
77 
78 namespace mcl {
79 
80 #define MCL_DATA_TYPE_DOUBLE 1
81 
82 #if MCL_DATA_TYPE_DOUBLE
83  typedef double Real;
84 #else
85  typedef float Real;
86 #endif
87 
88 typedef std::complex<Real> Complex;
90 #ifdef MCL_ENV64BIT
91  typedef unsigned long long UInt;
92  typedef long long Int;
93 #else // If it is 32 bits or unknown then...
94  typedef unsigned long UInt;
95  typedef long Int;
96 #endif
97 
98 
101 public:
103  static RuntimeArchInfo instance;
104  return instance;
105  }
106 
107  bool IsAvxSupported() {
108 #if defined(MCL_ENVWINDOWS)
109  if (! system_has_been_polled_) {
110  int cpu_info[4];
111  __cpuid(cpu_info, 0);
112  if (cpu_info[0] >= 1) {
113  __cpuidex(cpu_info, 1, 0);
114  if ((cpu_info[2] & (1 << 28)) != 0) {
115  avx_supported_ = true;
116  }
117  }
118  system_has_been_polled_ = true;
119  }
120 #endif
121 
122  return avx_supported_;
123  }
124 
125 private:
126  bool avx_supported_ = false;
127  bool system_has_been_polled_ = false;
128 };
129 
130 
131 
133 class Logger {
134 public:
135  static Logger& GetInstance() {
136  static Logger instance;
137  return instance;
138  }
139 
140  enum OutputType {
144  };
145 
146  void LogErrorToCerr(std::string output) {
147  std::cerr<<output<<std::endl;
148  }
149 
150  void LogErrorToCerr(const char* output) {
151  std::cerr<<output<<std::endl;
152  }
153 
154  void LogError(const char* format) {
155  if (output_type_ == kNone) { return; }
156 
157  const size_t SIZE = snprintf( NULL, 0, "%s", format);
158 
159  std::string output;
160  output.resize(SIZE+1);
161  snprintf( &(output[0]), SIZE+1, "%s", format);
162 
163  if (output_type_ == kCerr) {
164  std::cerr<<output<<std::endl;
165  } else if (output_type_ == kOutputFile) {
166  log_string_.append("\n");
167  log_string_.append(format);
168  }
169  }
170 
171  template< typename... argv >
172  void LogError(const char* format, argv... args) {
173  if (output_type_ == kNone) { return; }
174 
175  const size_t SIZE = snprintf( NULL, 0, format, args... );
176 
177  std::string output;
178  output.resize(SIZE+1);
179  snprintf( &(output[0]), SIZE+1, format, args... );
180 
181  if (output_type_ == kCerr) {
182  std::cerr<<output<<std::endl;
183  } else if (output_type_ == kOutputFile) {
184  log_string_.append("\n");
185  log_string_.append(format);
186  }
187  }
188 
189  void SetOutputType(OutputType output_type) {
190  output_type_ = output_type;
191  }
192 
193  void SetOutputFile(const std::string& log_output_file) {
194  log_output_file_ = log_output_file;
195  }
196 
197 private:
198  Logger() : output_type_(kCerr), log_output_file_("err.log") {}
199  ~Logger() {
200  if (log_string_.length() > 0) {
201  std::cerr<<"Writing logger out to "<<log_output_file_<<std::endl;
202  std::ofstream output_stream(log_output_file_);
203  output_stream<<log_string_;
204  output_stream.close();
205  }
206  }
207 
208  Logger(const Logger&) = delete;
209  const Logger& operator= (const Logger&) = delete;
210 
211  OutputType output_type_;
212 
213  std::string log_string_;
214  std::string log_output_file_;
215 };
216 
217 
218 } // namespace mcl
219 
220 
221 
222 #endif