Updated 2022-03-23

Intel Math Kernel Library (MKL)

The Intel Math Kernel Library (MKL) provides optimized implementations of BLAS, LAPACK, and other linear algebra routines for C, C++, and Fortran. MKL is optimized for both serial and mulithreaded execution. The MKL functions have the same interfaces as other BLAS/LAPACK implementations (such as OpenBLAS and Netlib), and applications that use other BLAS/LAPACK implementations can be easily re-compiled/re-linked with MKL.

This document summarizes how to compile and link a program to MKL on PACE clusters. It will demonstrate:

  • A simple C program that uses a generic CBLAS routine
  • Determining the correct MKL compiler/linker flags using the Intel MKL Link Line Advisor
  • Compiling a program with MKL on the command line
  • Using MKL in GNU make
  • Using MKL in CMake

For more information on using MKL, see these docs from Intel:

Writing the Program

We will compile the following C program, hello_ddot.c. It computes the dot product between two vectors x and y. Note that the code itself does not use any capabilities specific to MKL. It simply uses the cblas_ddot routine from cblas.h, which is provided by any CBLAS implementation (including MKL, OpenBLAS, Netlib, and others).

// hello_ddot.c
#include <stdio.h>
#include "cblas.h"

int main() {
  double x[] = {1.0, 2.0, 3.0};
  double y[] = {4.0, 5.0, 6.0};
  double ans = cblas_ddot(3, x, 1, y, 1);
  printf("%f\n", ans);

Determining Compiler and Linker Flags

At this point, we have the ability to compile/link the program using any CBLAS implementation. To use MKL in particular, we must determine the correct compiler and linker flags using the MKL Link Line Advisor.

The MKL Link Line Advisor has options for many different use cases. On PACE, you will always select "Intel® Parallel Studio XE 2019" for the "Select Intel® product" option. The other options will vary based on your particular program.

Our hello_ddot.c program only requires BLAS, so we will use the options shown below. Hence, the Link Line Advisor informs us that the relevant compiler/linker flags for this particular program are:

  • The compiler flags: -I"${MKLROOT}/include"
  • The linker flags: -L${MKLROOT}/lib/intel64 -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl

MKL Screenshot

Compiling the Program

To compile the hello_ddot.c with MKL on PACE, we must first load the intel/19.0.5 module. In addition to loading the Intel compilers, it will also set the correct environment for MKL, including the $MKLROOT environment variable.

module load intel/19.0.5

We must then use the compiler/linker flags that we determined from the MKL Link Line Advisor (see "Determining Compiler and Linker Flags", above).

For this simple program with one source file, we can compile the program with this command. Remember to use the correct MKL flags your particular program.

$ module load intel/19.0.5
$ icc hello_ddot.c -o hello_ddot -I"${MKLROOT}/include" -L${MKLROOT}/lib/intel64 -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl

This produces the executable hello_ddot, which should report 32.0 as the correct answer from the dot product:

$ ./hello_ddot

Using MKL in GNU Make

Makefiles vary greatly between different projects. A common standard (but not universal!) convention is to use the following variables to organize the makefile:

  • CPATH : Contains -I flags and is used in compiler command only
  • LDFLAGS: Contains -L flags and is used in linker command only
  • LIBS: Contains -l flags and is used in linker command only

Following these conventions, we can write the makefile below. We use the compiler/linker flags reported by the the MKL Link Line Advisor (see "Determining Compiler and Linker Flags", above). Remember to use the correct MKL flags for your particular program.

CC = icc
CFLAGS = -I"${MKLROOT}/include"
LDFLAGS = -L${MKLROOT}/lib/intel64
LIBS = -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl

hello_ddot: hello_ddot.o
    $(CC) $^ -o $@ $(LDFLAGS) $(LIBS)

%.o: %.c
    $(CC) $@ -c $^ $(CFLAGS)

Using MKL in CMake

CMake is a robust, high-level tool for configuring and compiling programs. Its FindBLAS and FindLAPACK routines can detect and validate many specific BLAS/LAPACK implementations, including MKL.

In the CMakeLists.txt shown below, we force CMake to use MKL BLAS by specifying set(BLA_VENDOR Intel10_64lp) before calling find_package(BLAS REQUIRED). Note that we didn't have to use the Intel Link Line Advisor! 🥳

For more information on using MKL in CMake projects, see the "Intel MKL" section in the FindBLAS docs.

cmake_minimum_required(VERSION 3.18)

set(BLA_VENDOR Intel10_64lp)
find_package(BLAS REQUIRED)

add_executable(hello_ddot hello_ddot.c)
target_link_libraries(hello_ddot BLAS::BLAS)