2

I am developing a linear algebra tool in C++, which relies heavily on matrix multiplication and decompositions (like LU, SVD), and is meant to be applied to large matrices. I developed it using Intel MKL for peak performance, but I don't want to release an Intel MKL only version, as I assume it will not work for people without Intel or who don't want to install MKL. Instead, I should release a more general code that is not Intel MKL-specific, but rather allows the user to specify which implementation of BLAS and LAPACK they would like to use (e.g. OpenBLAS, or ATLAS).

Although the function prototypes seem to be the same across implementations, there are several (helper?) functions and types that are specific to Intel MKL. For example, there is the MKL_INT type that I use, and also the mkl_malloc. This article suggests using macros to redefine the types, which was also my first thought. I assume I would also then have macros for the headers as well.

I believe it is standard for code to be written such that it is agnostic to the BLAS/LAPACK implementation, and I wanted to know if there was a cleaner way than relying on macros--particularly since the latter would require recompiling the code to switch, which does not seem to be necessary for other tools I have used.

Community
  • 1
  • 1
The_Anomaly
  • 2,385
  • 3
  • 18
  • 22

1 Answers1

1

Most scientific codes that rely on BLAS/LAPACK calls are implementation-agnostic. They usually require that the library is just linked as appropriate.

You've commented that the function prototypes are the same across implementations. This allows you to just have the prototypes in some myblas.h and mylapack.h headers then link whichever library you'd like to use.

It sounds like your primary concern is the implementation-specific stuff that you've utilized for MKL. The solution is to just not use this stuff. For example, the MKL types like MKL_INT are not special. They are C datatypes that have been defined to allow generalize between LP32/LP64/ILP64 libraries which MKL provides. See this table.

Also, stuff like mkl_malloc isn't special. It was introduced before the C standard had a thread-safe aligned alloc. In fact, that is all mkl_malloc is. So instead, just use aligned_alloc, or if you don't want to commit to C11 use _mm_malloc, memalign, etc...

On the other hand, MKL does provide some useful extensions to BLAS/LAPACK which aren't standardized (like transpositions, for example). However, this type of stuff is usually easy to implement with a special case BLAS/LAPACK call or easy enough to implement by yourself. MKL also has internal threading if you choose to use it, however, many BLAS/LAPACK libraries offer this.

Gavin Portwood
  • 1,217
  • 8
  • 9
  • This is excellent, thank you Gavin. How about for header files that are specific to MKL, such as mkl.h and mkl_lapacke.h? – The_Anomaly Jun 07 '16 at 22:03
  • Most folks have a generic lapack.h/blas1.h/blas2.h/etc that you can snag from any implementation and keep in your own code base. Some people opt to specify it to the implementation header at compile time (i.e. ` gcc -I$(MY_LAPACK_HEADER_DIR) ...`). I usually opt for the former... Then you shouldn't need mkl.h for anything – Gavin Portwood Jun 07 '16 at 23:08
  • Your latter option is not immediately clear to me...you are passing the directory, but where do you specify the actual name of the file (mkl.h)? Would you use macros in that case? – The_Anomaly Jun 08 '16 at 14:59
  • Well you wouldn't use mkl.h, but you'd have the standard `#include "lapack.h"` in your source code but include it from Netlib's/scalapack's/MKL's include directory. Just as you typically do for any shared library – Gavin Portwood Jun 08 '16 at 17:57