changeset 24714:d2c727a438ab

Add "-blas" and "-lapack" options to "version" (bug #45659). * lo-sysinfo.h, lo-sysinfo.cc: New files. * liboctave/system/module.mk: Update. * sysdep.cc (F__blas_version__, F__lapack_version__): New functions. * version.m: Accept -blas and -lapack options. Make options case insensitive.
author Markus Mützel <markus.muetzel@gmx.de>
date Thu, 08 Feb 2018 17:15:13 -0500
parents 36cd70fc2d63
children 88bb3f086d9a
files libinterp/corefcn/sysdep.cc liboctave/system/lo-sysinfo.cc liboctave/system/lo-sysinfo.h liboctave/system/module.mk scripts/miscellaneous/version.m
diffstat 5 files changed, 255 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/sysdep.cc	Fri Feb 09 19:57:39 2018 +0100
+++ b/libinterp/corefcn/sysdep.cc	Thu Feb 08 17:15:13 2018 -0500
@@ -61,6 +61,7 @@
 #include "cmd-edit.h"
 #include "file-ops.h"
 #include "lo-mappers.h"
+#include "lo-sysinfo.h"
 #include "mach-info.h"
 #include "oct-env.h"
 #include "unistd-wrappers.h"
@@ -1229,3 +1230,21 @@
 %!   assert (get_home_directory (), getenv ("HOME"));
 %! endif
 */
+
+DEFUN (__blas_version__, , ,
+       doc: /* -*- texinfo -*-
+@deftypefn {} {} __blas_version__ ()
+Undocumented internal function.
+@end deftypefn */)
+{
+  return ovl (octave::sys::blas_version ());
+}
+
+DEFUN (__lapack_version__, , ,
+       doc: /* -*- texinfo -*-
+@deftypefn {} {} __lapack_version__ ()
+Undocumented internal function.
+@end deftypefn */)
+{
+  return ovl (octave::sys::lapack_version ());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/system/lo-sysinfo.cc	Thu Feb 08 17:15:13 2018 -0500
@@ -0,0 +1,186 @@
+/*
+
+Copyright (C) 2018 Markus Mützel
+
+This file is part of Octave.
+
+Octave is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Octave is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<https://www.gnu.org/licenses/>.
+
+*/
+
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include <sstream>
+#include <string>
+
+#include "f77-fcn.h"
+#include "lo-sysinfo.h"
+#include "oct-shlib.h"
+
+// Hack to stringize macro results.
+#define xSTRINGIZE(x) #x
+#define STRINGIZE(x) xSTRINGIZE(x)
+
+namespace octave
+{
+  namespace sys
+  {
+    std::string blas_version (void)
+    {
+      dynamic_library dyn_libs ("");
+
+      if (! dyn_libs)
+        return "unknown BLAS";
+
+      std::string retval;
+
+      // Check for functions that are specific to certain BLAS implementations.
+
+      // FlexiBLAS
+      typedef void (*flexi_f_type) (int*, int*, int*);
+      flexi_f_type flexi_f_ptr = reinterpret_cast<flexi_f_type>
+        (dyn_libs.search ("flexiblas_get_version"));
+
+      if (flexi_f_ptr)
+        {
+          int v_major = 0;
+          int v_minor = 0;
+          int v_patch = 0;
+          flexi_f_ptr (&v_major, &v_minor, &v_patch);
+
+          std::ostringstream s;
+          s << "FlexiBLAS Version "
+            << v_major << "." << v_minor << "." << v_patch;
+
+          if (! retval.empty ())
+            retval += "\n";
+
+          retval += s.str ();
+        }
+
+      // OpenBLAS
+      typedef char * (*open_fcn_type) (void);
+      open_fcn_type open_f_ptr = reinterpret_cast<open_fcn_type>
+        (dyn_libs.search ("openblas_get_config"));
+
+      if (open_f_ptr)
+        {
+          if (! retval.empty ())
+            retval += "\n";
+
+          retval += "OpenBLAS (config: " + std::string (open_f_ptr ()) + ")";
+        }
+
+      // GotoBLAS(2)
+      if (dyn_libs.search ("gotoblas_profile_init"))
+        {
+          if (! retval.empty ())
+            retval += "\n";
+
+          retval += "GotoBLAS(2)";
+        }
+
+      // ATLAS
+      // FIXME: If we are really interested, we could use a pipe to
+      // redirect the output of "ATL_buildinfo".
+      if (dyn_libs.search ("ATL_buildinfo"))
+        {
+          if (! retval.empty ())
+            retval += "\n";
+
+          retval += "ATLAS";
+        }
+
+      // ACML
+      typedef void (*acml_f_type) (int*, int*, int*);
+      acml_f_type acml_f_ptr = reinterpret_cast<acml_f_type>
+        (dyn_libs.search ("acmlversion"));
+
+      if (acml_f_ptr)
+        {
+          int v_major = 0;
+          int v_minor = 0;
+          int v_patch = 0;
+          acml_f_ptr (&v_major, &v_minor, &v_patch);
+
+          std::ostringstream s;
+          s << "ACML BLAS Version "
+            << v_major << "." << v_minor << "." << v_patch;
+
+          if (! retval.empty ())
+            retval += "\n";
+
+          retval += s.str ();
+        }
+
+      // Intel MKL
+      typedef void (*mkl_f_type) (char*, int);
+      mkl_f_type mkl_f_ptr = reinterpret_cast<mkl_f_type>
+        (dyn_libs.search ("mkl_get_version_string"));
+
+      if (mkl_f_ptr)
+        {
+          char buf[198];
+          int len = 198;
+          mkl_f_ptr (buf, len);
+
+          if (! retval.empty ())
+            retval += "\n";
+
+          retval += std::string (buf);
+        }
+
+      // Otherwise
+      if (retval.empty ())
+        retval = "unknown or reference BLAS";
+
+      return retval;
+    }
+
+    std::string lapack_version (void)
+    {
+      std::string retval = "unknown LAPACK";
+
+      dynamic_library dyn_libs ("");
+
+      if (! dyn_libs)
+        return retval;
+
+      // query LAPACK version
+      typedef F77_RET_T
+        (*ilaver_fcn_type) (const F77_INT&, const F77_INT&, const F77_INT&);
+      ilaver_fcn_type f_ptr = reinterpret_cast<ilaver_fcn_type>
+        (dyn_libs.search (STRINGIZE (F77_FUNC (ilaver, ILAVER))));
+
+      if (f_ptr)
+        {
+          int v_major = 0;
+          int v_minor = 0;
+          int v_patch = 0;
+          f_ptr (v_major, v_minor, v_patch);
+
+          std::ostringstream s;
+          s << "Linear Algebra PACKage Version "
+            << v_major << "." << v_minor << "." << v_patch;
+
+          retval = s.str ();
+        }
+
+      return retval;
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/system/lo-sysinfo.h	Thu Feb 08 17:15:13 2018 -0500
@@ -0,0 +1,40 @@
+/*
+
+Copyright (C) 2018 Markus Mützel
+
+This file is part of Octave.
+
+Octave is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Octave is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<https://www.gnu.org/licenses/>.
+
+*/
+
+#if ! defined (octave_lo_sysinfo_h)
+#define octave_lo_sysinfo_h 1
+
+#include "octave-config.h"
+
+#include <string>
+
+namespace octave
+{
+  namespace sys
+  {
+    extern std::string blas_version (void);
+
+    extern std::string lapack_version (void);
+  }
+}
+
+#endif
--- a/liboctave/system/module.mk	Fri Feb 09 19:57:39 2018 +0100
+++ b/liboctave/system/module.mk	Thu Feb 08 17:15:13 2018 -0500
@@ -4,6 +4,7 @@
   %reldir%/file-ops.h \
   %reldir%/file-stat.h \
   %reldir%/lo-sysdep.h \
+  %reldir%/lo-sysinfo.h \
   %reldir%/mach-info.h \
   %reldir%/oct-env.h \
   %reldir%/oct-group.h \
@@ -19,6 +20,7 @@
   %reldir%/file-ops.cc \
   %reldir%/file-stat.cc \
   %reldir%/lo-sysdep.cc \
+  %reldir%/lo-sysinfo.cc \
   %reldir%/mach-info.cc \
   %reldir%/oct-env.cc \
   %reldir%/oct-group.cc \
--- a/scripts/miscellaneous/version.m	Fri Feb 09 19:57:39 2018 +0100
+++ b/scripts/miscellaneous/version.m	Thu Feb 08 17:15:13 2018 -0500
@@ -45,10 +45,10 @@
 ## for version information for the linked @sc{fftw},
 ##
 ## @item @qcode{"-blas"}
-## for version information for the linked @sc{blas} (not implemented),
+## for version information for the linked @sc{blas},
 ##
 ## @item @qcode{"-lapack"}
-## for version information for the linked @sc{lapack} (not implemented).
+## for version information for the linked @sc{lapack}.
 ## @end table
 ##
 ## The variant with no input and output argument is an alias for the function
@@ -71,7 +71,7 @@
       d = __octave_config_info__ ("release_date");
     end
   else
-    switch (feature)
+    switch (lower (feature))
       case "-date"
         v = __octave_config_info__ ("release_date");
       case "-description"
@@ -90,16 +90,14 @@
                                  "java.vm.info");
           v = ["Java " jversion " with " jvendor " " jname " " jjitmode];
         catch
-          v = "no java available";
+          v = "no Java available";
         end_try_catch
       case "-fftw"
         v = __octave_config_info__ ("fftw_version");
       case "-blas"
-        v = "";
-        warning ("version: option '-blas' not implemented");
+        v = __blas_version__ ();
       case "-lapack"
-        v = "";
-        warning ("version: option '-lapack' not implemented");
+        v = __lapack_version__ ();
       otherwise
         error ("version: invalid FEATURE");
     endswitch
@@ -119,11 +117,11 @@
 
 %!assert (version ("-description"), "")
 %!assert (version ("-release"), "")
+%!assert (ischar (version ("-blas")))
+%!assert (ischar (version ("-LAPACK")))
 
 ## Test input validation
 %!error version ("-date", "-release")
 %!error [v, d] = version ("-date")
 %!error version (1)
-%!warning <option '-blas' not implemented> version ("-blas");
-%!warning <option '-lapack' not implemented> version ("-lapack");
 %!error <invalid FEATURE> version ("-foobar")