-
Notifications
You must be signed in to change notification settings - Fork 0
/
LapackWrappersInfo.cpp
194 lines (176 loc) · 5.29 KB
/
LapackWrappersInfo.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include "LapackWrappers.h"
#ifndef DISABLE_LAPACK
#include "blas_lapack.h"
#endif
#include <algorithm>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iostream>
#include <limits>
#include <mutex>
#include <random>
#include <string.h>
#include <string>
#include <thread>
// Choose the OS
#if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 )
#define WINDOWS
#include <process.h>
#include <stdlib.h>
#include <windows.h>
#else
#define LINUX
#include <pthread.h>
#include <unistd.h>
#endif
// Null use macro
#define NULL_USE( variable ) \
do { \
if ( 0 ) { \
char *temp = (char *) &variable; \
temp++; \
} \
} while ( 0 )
// Function to replace all instances of a string with another
static inline std::string strrep(
const std::string &in, const std::string &s, const std::string &r )
{
std::string str( in );
size_t i = 0;
while ( i < str.length() ) {
i = str.find( s, i );
if ( i == std::string::npos ) {
break;
}
str.replace( i, s.length(), r );
i += r.length();
}
return str;
}
// Function to run a command and capture stdout
static inline std::string runCommand( std::function<void( void )> fun, const std::string &prefix )
{
fflush( stdout ); // clean everything first
char buffer[2048];
memset( buffer, 0, sizeof( buffer ) );
auto out = dup( STDOUT_FILENO );
auto tmp = freopen( "NUL", "a", stdout );
NULL_USE( tmp );
setvbuf( stdout, buffer, _IOFBF, 2048 );
fun();
tmp = freopen( "NUL", "a", stdout );
NULL_USE( tmp );
dup2( out, STDOUT_FILENO );
setvbuf( stdout, NULL, _IONBF, 2048 );
std::string str = prefix + strrep( buffer, "\n", "\n " );
while ( !str.empty() ) {
char tmp = str.back();
if ( tmp > 32 && tmp != ' ' )
break;
str.pop_back();
}
str += "\n";
return str;
}
/****************************************************************************
* Function to set an environemental variable *
****************************************************************************/
#if defined( USE_MKL ) || defined( USE_MATLAB_LAPACK )
static void setenv( const char *name, const char *value )
{
static std::mutex lock;
lock.lock();
#if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 ) || \
defined( _MSC_VER )
SetEnvironmentVariable( name, value ) != 0;
#else
if ( value != nullptr )
::setenv( name, value, 1 );
else
::unsetenv( name );
#endif
lock.unlock();
}
#endif
/******************************************************************
* Set the number of threads to use *
******************************************************************/
static int setThreads( int N )
{
int N2 = 0;
NULL_USE( N );
#if defined( USE_MKL )
setenv( "MKL_NUM_THREADS", std::to_string( N ).c_str() );
N2 = N;
#elif defined( USE_OPENBLAS )
openblas_set_num_threads( N );
N2 = openblas_get_num_threads();
#elif defined( USE_MATLAB_LAPACK )
setenv( "OMP_NUM_THREADS", std::to_string( N ).c_str() );
setenv( "MKL_NUM_THREADS", std::to_string( N ).c_str() );
N2 = N;
#endif
return N2;
}
template<>
int Lapack<float>::set_num_threads( int N )
{
return setThreads( N );
}
template<>
int Lapack<double>::set_num_threads( int N )
{
return setThreads( N );
}
static bool disable_threads()
{
setThreads( 1 );
return true;
}
bool global_lapack_threads_disabled = disable_threads();
/******************************************************************
* Set the vendor string *
******************************************************************/
// clang-format off
#ifdef DISABLE_LAPACK
static constexpr char LapackVendor[] = "Built-in lapack routines";
#elif defined( USE_ATLAS )
static constexpr char LapackVendor[] = "ATLAS";
#elif defined( USE_ACML )
static constexpr char LapackVendor[] = "ACML";
#elif defined( USE_MKL )
static constexpr char LapackVendor[] = "MKL";
#elif defined( USE_MATLAB_LAPACK )
static constexpr char LapackVendor[] = "MATLAB LAPACK";
#elif defined( USE_VECLIB )
static constexpr char LapackVendor[] = "VECLIB";
#elif defined( USE_OPENBLAS )
static constexpr char LapackVendor[] = "OpenBLAS";
#else
static constexpr char LapackVendor[] = "Unknown";
#endif
// clang-format on
/******************************************************************
* Print the lapack information *
******************************************************************/
template<typename TYPE>
std::string Lapack<TYPE>::info()
{
// Print the vendor info
std::string msg( LapackVendor );
msg += "\n";
// Use vendor-specific utility functions
#ifdef USE_OPENBLAS
msg += " " + std::string( openblas_get_config() );
#endif
// Get vendor specific output (capture stdout)
#ifdef USE_ACML
msg += runCommand( acmlinfo() );
#endif
return msg;
}
template std::string Lapack<double>::info();
template std::string Lapack<float>::info();