mac和linux上安装Intel MKL2018(Math Kernel Library)

Intel MKL是多种blas库的一种。相比于open_blas,他的安装过程复杂很多,但据说优化效果也更好。
Interl MKL安装过程一波三折,分别尝试了在mac和两个ubuntu系统(虚拟机16.04,真实机14.04)上的安装,谨记如下:

Intel MKL的下载

第一个坑。和众多网上教程所说的不一样,intel官网似乎更改了下载流程。
1. 官网下载链接
2. 点击free download,填写自己的信息,学生用户可以有教育免费资格:

3. submit提交后,他会发给你一个邮件

4. 点击download,进入下载页面

5. 注意,如果他没有出现这个,而是又回到了注册页面,那么你需要先创建一个intel网站的账户并登陆(和刚才那个邮件不是一回事):

6. 如果intel没有出现这个bug,那么顺利的下载相应版本的软件即可。

安装

mac下的安装,2018版本并不需要你输入序列号了:可能在下载的时候已经附加了license?不管怎么说,安装过程一路向下即可。mac下intel mkl的软件会安装在/opt/intel目录下。

linux的安装基本一样,不管是界面安装(install_GUI.sh)还是命令行安装(install.sh)都问题不大,同样安装在/opt/intel下,但是两个系统的子文件夹组织可能略有不同。

接下来可以参考一个博客链接 来配置环境变量,不过不做好像也可以。

运行样例文件

官方的一个例子:

#define min(x,y) (((x) < (y)) ? (x) : (y))
#include <stdio.h>
#include <stdlib.h>
#include "mkl.h"

int main()
{
    double *A, *B, *C;
    int m, n, p, i, j;
    double alpha, beta;

    printf ("\n This example computes real matrix C=alpha*A*B+beta*C using \n"
            " Intel(R) MKL function dgemm, where A, B, and  C are matrices and \n"
            " alpha and beta are double precision scalars\n\n");

    m = 2000, p = 200, n = 1000;
    printf (" Initializing data for matrix multiplication C=A*B for matrix \n"
            " A(%ix%i) and matrix B(%ix%i)\n\n", m, p, p, n);
    alpha = 1.0; beta = 0.0;
    printf (" Allocating memory for matrices aligned on 64-byte boundary for better \n"
            " performance \n\n");
    A = (double *)mkl_malloc( m*p*sizeof( double ), 64 );
    B = (double *)mkl_malloc( p*n*sizeof( double ), 64 );
    C = (double *)mkl_malloc( m*n*sizeof( double ), 64 );
    if (A == NULL || B == NULL || C == NULL) {
        printf( "\n ERROR: Can't allocate memory for matrices. Aborting... \n\n");
        mkl_free(A);
        mkl_free(B);
        mkl_free(C);
        return 1;
    }

    printf (" Intializing matrix data \n\n");
    for (i = 0; i < (m*p); i++) {
        A[i] = (double)(i+1);
    }

    for (i = 0; i < (p*n); i++) {
        B[i] = (double)(-i-1);
    }

    for (i = 0; i < (m*n); i++) {
        C[i] = 0.0;
    }

    printf (" Computing matrix product using Intel(R) MKL dgemm function via CBLAS interface \n\n");
    cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 
                m, n, p, alpha, A, p, B, n, beta, C, n);
    printf ("\n Computations completed.\n\n");

    printf (" Top left corner of matrix A: \n");
    for (i=0; i<min(m,6); i++) {
        for (j=0; j<min(p,6); j++) {
            printf ("%12.0f", A[j+i*p]);
        }
        printf ("\n");
    }

    printf ("\n Top left corner of matrix B: \n");
    for (i=0; i<min(p,6); i++) {
        for (j=0; j<min(n,6); j++) {
            printf ("%12.0f", B[j+i*n]);
        }
        printf ("\n");
    }

    printf ("\n Top left corner of matrix C: \n");
    for (i=0; i<min(m,6); i++) {
        for (j=0; j<min(n,6); j++) {
            printf ("%12.5G", C[j+i*n]);
        }
        printf ("\n");
    }

    printf ("\n Deallocating memory \n\n");
    mkl_free(A);
    mkl_free(B);
    mkl_free(C);

    printf (" Example completed. \n\n");
    return 0;
}

在intel mkl的文档中,很贴心的附带了一个C语言命令行的参数生成器
file:///opt/intel/documentation_2018/en/mkl/common/mkl_link_line_advisor.htm.

基于这个,我们来分别在linux和mac下面运行并采坑。

linux下运行样例

MKLROOT是mkl的安装子目录,默认在/opt/intel/mkl,在该目录下有include、lib等编译需要用的文件。可以通过export设置,这个不多说。
linux的命令如下,这是不采用并发的版本(sequential)除了-I/opt/intel/mkl/include是手动添加的(否则报找不到mkl.h文件错误),其他都是参数生成网站给出的。这条语句我没有踩到坑:

g++ -o mkl_first.o dgemm_example.c -I/opt/intel/mkl/include -L${MKLROOT}/lib/intel64 -Wl,--no-as-needed -lmkl_intel_ilp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl
  • 1

除此之外,intel自动安装类omp类来实现并行,语句如下:

g++ -o mkl_first.o dgemm_example.c -I/opt/intel/mkl/include -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a ${MKLROOT}/lib/intel64/libmkl_core.a -Wl,--end-group -liomp5 -lpthread -lm -ldl
  • 1

这个运行的时候会出现-liomp5找不到的问题:

linux下面很好解决,这个lib在intel中包含了,把它做一个软连接到/lib文件夹下面就能找到:

ln -s /opt/intel/compilers_and_libraries/linux/lib/intel64_lin/libiomp5.so /lib/libiomp5.so
  • 1

mac下运行实例

mac的顺序执行命令没什么区别:

clang dgemm_example.c -I/opt/intel/mkl/include ${MKLROOT}/lib/libmkl_intel_ilp64.a ${MKLROOT}/lib/libmkl_sequential.a ${MKLROOT}/lib/libmkl_core.a -lpthread -lm -ldl

omp并发的版本如下,同样会报错,但是mac有两个问题。首先libiomp5.a的位置不同(小问题),其次mac寻找lib包并不通过/lib来寻找所需类库(大问题)。

  1. mac的libiomp5.a文件在另一个位置,我们手动加一条-L /opt/intel/compilers_and_libraries_2018.1.126/mac/compiler/lib/,如下:
clang -o mkl_first.o dgemm_example.c -I/opt/intel/mkl/include -L /opt/intel/compilers_and_libraries_2018.1.126/mac/compiler/lib/ -L${MKLROOT}/lib -Wl,-rpath,${MKLROOT}/lib -Wl,-rpath,/opt/intel/compilers_and_libraries_2017.4.xxx/mac/compiler/lib -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm -ldl  
  1. 此时可以编译通过,但是运行还会报错:
  2. intel似乎认为这是他们在mac上的一个bug,给出了一个解决方案,就是生成好文件后,运行下面这条语句:
install_name_tool -change @rpath/libiomp5.dylib /opt/intel/compilers_and_libraries_2018.1.126/mac/compiler/lib/libiomp5.dylib ./mkl_first.o
  1. 运行成功。

结果展示

如果样例代码运行结果如下,说明测试通过:

 XXXXXXX(省略)
 Computations completed.

 Top left corner of matrix A:
           1           2           3           4           5           6
         201         202         203         204         205         206
         401         402         403         404         405         406
         601         602         603         604         605         606
         801         802         803         804         805         806
        1001        1002        1003        1004        1005        1006

 Top left corner of matrix B:
          -1          -2          -3          -4          -5          -6
       -1001       -1002       -1003       -1004       -1005       -1006
       -2001       -2002       -2003       -2004       -2005       -2006
       -3001       -3002       -3003       -3004       -3005       -3006
       -4001       -4002       -4003       -4004       -4005       -4006
       -5001       -5002       -5003       -5004       -5005       -5006

 Top left corner of matrix C:
 -2.6666E+09 -2.6666E+09 -2.6667E+09 -2.6667E+09 -2.6667E+09 -2.6667E+09
 -6.6467E+09 -6.6467E+09 -6.6468E+09 -6.6468E+09 -6.6469E+09  -6.647E+09
 -1.0627E+10 -1.0627E+10 -1.0627E+10 -1.0627E+10 -1.0627E+10 -1.0627E+10
 -1.4607E+10 -1.4607E+10 -1.4607E+10 -1.4607E+10 -1.4607E+10 -1.4607E+10
 -1.8587E+10 -1.8587E+10 -1.8587E+10 -1.8587E+10 -1.8588E+10 -1.8588E+10
 -2.2567E+10 -2.2567E+10 -2.2567E+10 -2.2567E+10 -2.2568E+10 -2.2568E+10

 Deallocating memory

 Example completed.

总结

在两个ubuntu上,一个运行成功,另一个可以编译通过但总是报段错误Segmentation fault (core dumped),实在头疼,希望同样遇到这个问题并解决了的同侪多多指教。

--------------------- 作者:漫漫冬程 来源:CSDN 原文:https://blog.csdn.net/SoftPoeter/article/details/79569424?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/yanerhao/article/details/82986924