26

Is there a command which reveals which implementation of BLAS and LAPACK are used in Mathematica's matrix operations such as Eigensystem? I asked a related question on StackOverflow and one user mentioned that in Julia, the BLAS/LAPACK implementation can be found by executing versioninfo(). Several users who tried my code there had varying results, with some observing Mathematica to execute faster, and others observing Julia executing faster.

In my case, my Julia installation appears to make use of the OpenBLAS implementation, and it runs between 3 to 6 times slower than Mathematica's Eigensystem for randomly-generated arrays of size $1000\times1000$ to $2000\times2000$.

In the Mathematica documentation's tutorial/SomeNotesOnInternalImplementation, it mentions "For dense arrays, LAPACK algorithms extended for arbitrary precision are used when appropriate" and "BLAS technology is used to optimize for particular machine architectures", but nothing more.

EDIT: So in response to Kuba's comment, apparently one of the Julia devs noted that there is anomalous behavior in Julia with regards to eigenvector computation speed as a function of BLAS thread number. In short, using more threads in Julia's use of OpenBLAS appears to slow things down considerably. For reference, in Mathematica:

SetSystemOptions["MKLThreads" -> 1];
First@Timing@Eigensystem[RandomReal[{-500, 500}, {1000, 1000}]]
SetSystemOptions["MKLThreads" -> 2];
First@Timing@Eigensystem[RandomReal[{-500, 500}, {1000, 1000}]]
SetSystemOptions["MKLThreads" -> 3];
First@Timing@Eigensystem[RandomReal[{-500, 500}, {1000, 1000}]]
SetSystemOptions["MKLThreads" -> 4];
First@Timing@Eigensystem[RandomReal[{-500, 500}, {1000, 1000}]]
(*Out:*)
1.747211
1.466409
1.341609
1.357209

So I guess there's nothing wrong with Mathematica's implementation.

DumpsterDoofus
  • 11,857
  • 1
  • 29
  • 49
  • I believe on Windows and Linux it uses the MKL. I'm not sure about OS X. – Szabolcs Feb 08 '14 at 19:25
  • Okay, I'll assume it's Intel MKL for now. Is there any way to test it to verify? Like for determining which C compiler is in use you just execute CCompilers[]; is there any equivalent for determining BLAS architecture? – DumpsterDoofus Feb 08 '14 at 19:28
  • I don't know but I think it's unlikely. You can dig around in the installation directory and see what's there. Providing such a function wouldn't allow users to do anything useful they can't already do, so it doesn't make sense to include it in my opinion. We can't swap out the BLAS implementation anyway. Julia can use several libraries so there you do need it for debugging ... – Szabolcs Feb 08 '14 at 19:40
  • You might be able to get an answer about this from support. It might be worth a try. – Szabolcs Feb 08 '14 at 19:42
  • So in my Mathematica directory there's a bunch of files relating to the Intel Math Kernel Library, such as "mkl_vml_mc.dll", etc. I'll try asking support anyways just to make sure. – DumpsterDoofus Feb 08 '14 at 19:48
  • Check the timing of Eigenvalues and then use SetSystemOptions["MKLThreads" -> 1], check the timing again. – Kuba Feb 08 '14 at 22:29
  • MKL exists for Mac as well so I would expect it's MKL on all platforms. Since the BLAS/LAPACK/FFT implementation is fixed at compile time (if not before), I'm not certain it makes much sense to ask about this in detail. WRI will presumably just pick whichever implementation gives relatively good performance while being reasonably easy to use. MKL fits the bill on both counts. Personally I'd still be interested to know which MKL functions are used in Mathematica, and how. – Oleksandr R. Feb 08 '14 at 22:48
  • @Kuba: I edited my question to include your suggestion; apparently thread-number may have something to do with it. – DumpsterDoofus Feb 08 '14 at 23:16
  • I guess if it affects the timing then eigenvalues are using MKL. But I do not know much about internals or programming at all so that's all I can say :0 – Kuba Feb 08 '14 at 23:22
  • @DumpsterDoofus, in Linux we have Wolfram/Mathematica/10.0/SystemFiles/Libraries/Linux-x86-64/libmkl_*.so so it is also MKL. If you look at the binary, towards the end of the file, you can see all the functions names defined in the library. Maybe you can reverse engineer the version number. For example compile and link a program to that library and ask for the get_version function. It is likely that such internals are completely inaccesible from Mathematica but can be accessed from C. Didn't try myself. – alfC Oct 24 '14 at 05:54

1 Answers1

19

As indicated in the comments, machine-precision linear algebra operations in Mathematica use the Intel MKL library optimized implementation of BLAS/LAPACK.

That is the case for all platforms where MKL is available: Windows, Linux and Mac OS X (there will be no obvious MKL library files present in the layout on OS X in versions 10.1 through 11.2 due to static linking).

As of the version 11.3, the Raspberry Pi port is using OpenBLAS 0.2.20.

I am not aware of a built-in way to query the exact version of MKL being used. Generally, it tends to be the latest stable MKL available as of the Mathematica release date, and is the same version on all platforms (exceptions are of course possible).

The following LibraryLink snippet, which works only on Linux, will return the MKL version information.

src = "#include <stdio.h>
  #include <stdlib.h>
  #include <WolframLibrary.h>

  void mkl_get_version_string(char * buff, int len);

  DLLEXPORT mint WolframLibrary_getVersion( ) {
      return WolframLibraryVersion;
  }

  DLLEXPORT int WolframLibrary_initialize(WolframLibraryData libData) {
      return 0;
  }

  DLLEXPORT void WolframLibrary_uninitialize(WolframLibraryData libData) {
      return;
  }

  DLLEXPORT int mkl_version(WolframLibraryData libData, mint argc, MArgument * args, MArgument res) {
    char * buff = (char *)malloc(198 * sizeof(char));
    mkl_get_version_string(buff, 198);
    MArgument_setUTF8String(res, buff);
    return LIBRARY_NO_ERROR; 
  }";

Needs["CCompilerDriver`"];

lib = CreateLibrary[src, "mkl_version"];

LibraryFunctionLoad[lib, "mkl_version", {}, "UTF8String"][]

and, according to the results, the last few Mathematica versions have used

| 11.x.y | Intel(R) Math Kernel Library Version 2017.0.1 Product Build 20161005| 
| 11.0.x | Intel(R) Math Kernel Library Version 11.3.2 Product Build 20160120  |
| 10.4.x | Intel(R) Math Kernel Library Version 11.3.1 Product Build 20151021  |
| 10.3.x | Intel(R) Math Kernel Library Version 11.2.2 Product Build 20150120  |
| 10.2.0 | Intel(R) Math Kernel Library Version 11.2.2 Product Build 20150120  |
| 10.1.0 | Intel(R) Math Kernel Library Version 11.2.1 Product Build 20141023  |
| 10.0.x | Intel(R) Math Kernel Library Version 11.1.2 Product Build 20140122  |
|  9.0.x | Intel(R) Math Kernel Library Version 10.3.5 Product Build 20110720  |
ilian
  • 25,474
  • 4
  • 117
  • 186
  • This approach only works if you reference the appropriate headers and link with MKL, I believe, otherwise mkl_get_version_string has no definition. The other way to do it is to check the file metadata. For example, mkl_core.dll on Windows Mathematica 9.0.1 has version 10.3.5.1, which I think means MKL 10.3 update 5. – Oleksandr R. Jul 29 '15 at 00:26
  • @Oleksandr Yes, I think CreateLibrary takes care of linking. And since mkl_get_version_string is the only function used, I just included its signature. – ilian Jul 29 '15 at 00:31
  • My point is that unless you have the MKL installed (and possibly are using the Intel compiler, which will link it in automatically), these prerequisites cannot be fulfilled. For example, for me using GCC on Windows, your sample code cannot be compiled because there is nothing for mkl_get_version_string. Also, I'm not sure of the validity of linking different versions of MKL together, if that is what happens here, or at least using the headers inconsistently. If the interface changes, it could malfunction completely. – Oleksandr R. Jul 29 '15 at 00:37
  • @Oleksandr Yes, you are right. It works as is on Linux using only the MKL shared libraries included with Mathematica. I ran the exact example with several different versions of Mathematica, so no mixing of different MKLs. On Windows, one would probably need to have the MKL import libraries (.LIB) in addition to the DLLs. – ilian Jul 29 '15 at 00:58
  • Interesting. I would have thought at the least you would need to have the import libraries on Linux as well. They are not provided with Mathematica, as far as I know? This is why I thought perhaps it is coming from somewhere else on your system, thus the possibility of mixing MKL versions. – Oleksandr R. Jul 29 '15 at 01:46
  • Linux is different as all the information about exported symbols needed by the linker is already included in the .so files provided with Mathematica. Windows, on the other hand, uses separate import libraries for this purpose and they are not included. – ilian Jul 29 '15 at 04:07
  • Any chance you could give an update on which BLAS the RPi is using now, or post code for ARM to give that information the way you have for x64? Right now the linear algebra performance on the Pi is not only bad but getting worse due to poor BLAS tuning (Pi 2 is faster than Pi 3 is faster than Pi 3 B+ on the Benchmark[] matrix multiply). – Prodicus Apr 18 '18 at 16:42
  • @Prodicus The RPi port is going to be slow since it uses a reference BLAS currently, for some bizarre compatibility reason. I'm hoping this will be fixed soon. In the meantime, I removed the outdated mention of ATLAS. – ilian Apr 18 '18 at 19:37
  • The Raspberry Pi performance has been fixed as of version 11.3.0 by using OpenBLAS. I have updated the answer. – ilian Aug 02 '18 at 14:18