26
$\begingroup$

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.

$\endgroup$
10
  • $\begingroup$ I believe on Windows and Linux it uses the MKL. I'm not sure about OS X. $\endgroup$
    – Szabolcs
    Feb 8, 2014 at 19:25
  • $\begingroup$ 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? $\endgroup$ Feb 8, 2014 at 19:28
  • $\begingroup$ 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 ... $\endgroup$
    – Szabolcs
    Feb 8, 2014 at 19:40
  • $\begingroup$ You might be able to get an answer about this from support. It might be worth a try. $\endgroup$
    – Szabolcs
    Feb 8, 2014 at 19:42
  • $\begingroup$ 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. $\endgroup$ Feb 8, 2014 at 19:48

1 Answer 1

19
$\begingroup$

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  |

$\endgroup$
9
  • $\begingroup$ 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. $\endgroup$ Jul 29, 2015 at 0:26
  • $\begingroup$ @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. $\endgroup$
    – ilian
    Jul 29, 2015 at 0:31
  • $\begingroup$ 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. $\endgroup$ Jul 29, 2015 at 0:37
  • $\begingroup$ @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. $\endgroup$
    – ilian
    Jul 29, 2015 at 0:58
  • $\begingroup$ 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. $\endgroup$ Jul 29, 2015 at 1:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.