GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
lo-sysinfo.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2018-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <sstream>
31 #include <string>
32 
33 #include "f77-fcn.h"
34 #include "lo-sysinfo.h"
35 #include "oct-shlib.h"
36 
37 // Hack to stringize macro results.
38 #define xSTRINGIZE(x) #x
39 #define STRINGIZE(x) xSTRINGIZE(x)
40 
41 namespace octave
42 {
43  namespace sys
44  {
45  std::string blas_version (void)
46  {
47  dynamic_library dyn_libs ("");
48 
49  if (! dyn_libs)
50  return "unknown BLAS";
51 
52  std::string retval;
53 
54  // Check for functions that are specific to certain BLAS implementations.
55 
56  // FlexiBLAS
57  typedef void (*flexi_f_type) (int*, int*, int*);
58  flexi_f_type flexi_f_ptr = reinterpret_cast<flexi_f_type>
59  (dyn_libs.search ("flexiblas_get_version"));
60 
61  if (flexi_f_ptr)
62  {
63  int v_major = 0;
64  int v_minor = 0;
65  int v_patch = 0;
66  flexi_f_ptr (&v_major, &v_minor, &v_patch);
67 
68  std::ostringstream s;
69  s << "FlexiBLAS Version "
70  << v_major << "." << v_minor << "." << v_patch;
71 
72  retval = s.str ();
73  }
74 
75  // OpenBLAS
76  typedef char * (*open_fcn_type) (void);
77  open_fcn_type open_f_ptr = reinterpret_cast<open_fcn_type>
78  (dyn_libs.search ("openblas_get_config"));
79 
80  if (open_f_ptr)
81  {
82  if (! retval.empty ())
83  retval += "\n";
84 
85  retval += "OpenBLAS (config: " + std::string (open_f_ptr ()) + ")";
86  }
87 
88  // OpenBLAS with minimal extension functions included in the library
89  else if (dyn_libs.search ("openblas_get_num_threads"))
90  {
91  if (! retval.empty ())
92  retval += "\n";
93 
94  retval += "OpenBLAS (config: unknown)";
95  }
96 
97  // GotoBLAS(2)
98  if (dyn_libs.search ("gotoblas_profile_init"))
99  {
100  if (! retval.empty ())
101  retval += "\n";
102 
103  retval += "GotoBLAS(2)";
104  }
105 
106  // ATLAS
107  // FIXME: If we are really interested, we could use a pipe to
108  // redirect the output of "ATL_buildinfo".
109  if (dyn_libs.search ("ATL_buildinfo"))
110  {
111  if (! retval.empty ())
112  retval += "\n";
113 
114  retval += "ATLAS";
115  }
116 
117  // ACML
118  typedef void (*acml_f_type) (int*, int*, int*);
119  acml_f_type acml_f_ptr = reinterpret_cast<acml_f_type>
120  (dyn_libs.search ("acmlversion"));
121 
122  if (acml_f_ptr)
123  {
124  int v_major = 0;
125  int v_minor = 0;
126  int v_patch = 0;
127  acml_f_ptr (&v_major, &v_minor, &v_patch);
128 
129  std::ostringstream s;
130  s << "ACML BLAS Version "
131  << v_major << "." << v_minor << "." << v_patch;
132 
133  if (! retval.empty ())
134  retval += "\n";
135 
136  retval += s.str ();
137  }
138 
139  // Intel MKL
140  typedef void (*mkl_f_type) (char*, int);
141  mkl_f_type mkl_f_ptr = reinterpret_cast<mkl_f_type>
142  (dyn_libs.search ("mkl_get_version_string"));
143 
144  if (mkl_f_ptr)
145  {
146  char buf[198];
147  int len = 198;
148  mkl_f_ptr (buf, len);
149 
150  if (! retval.empty ())
151  retval += "\n";
152 
153  retval += std::string (buf);
154  }
155 
156  // Otherwise
157  if (retval.empty ())
158  retval = "unknown or reference BLAS";
159 
160  return retval;
161  }
162 
163  std::string lapack_version (void)
164  {
165  std::string retval = "unknown LAPACK";
166 
167  dynamic_library dyn_libs ("");
168 
169  if (! dyn_libs)
170  return retval;
171 
172  // query LAPACK version
173  typedef F77_RET_T
174  (*ilaver_fcn_type) (const F77_INT&, const F77_INT&, const F77_INT&);
175  ilaver_fcn_type f_ptr = reinterpret_cast<ilaver_fcn_type>
176  (dyn_libs.search (STRINGIZE (F77_FUNC (ilaver, ILAVER))));
177 
178  if (f_ptr)
179  {
180  int v_major = 0;
181  int v_minor = 0;
182  int v_patch = 0;
183  f_ptr (v_major, v_minor, v_patch);
184 
185  std::ostringstream s;
186  s << "Linear Algebra PACKage Version "
187  << v_major << "." << v_minor << "." << v_patch;
188 
189  retval = s.str ();
190  }
191 
192  return retval;
193  }
194  }
195 }
void * search(const std::string &nm, const name_mangler &mangler=name_mangler()) const
Definition: oct-shlib.h:175
octave_f77_int_type F77_INT
Definition: f77-fcn.h:305
F77_RET_T(F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, F77_CONST_CHAR_ARG_DECL, const F77_INT &, const F77_INT &, const F77_INT &, F77_INT &, F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, F77_DBLE *, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, const F77_INT &, F77_DBLE *, F77_INT *, F77_INT &F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL F77_CHAR_ARG_LEN_DECL)
#define STRINGIZE(x)
Definition: lo-sysinfo.cc:39
std::string blas_version(void)
Definition: lo-sysinfo.cc:45
std::string lapack_version(void)
Definition: lo-sysinfo.cc:163
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
F77_RET_T F77_FUNC(xerbla, XERBLA)(F77_CONST_CHAR_ARG_DEF(s_arg
F77_RET_T len
Definition: xerbla.cc:61