将英特尔数学核心库(MKL)链接到Windows上的R

39

使用替代的BLAS库可以带来多个优势,例如请参考https://cran.r-project.org/web/packages/gcbd/vignettes/gcbd.pdf

Microsoft R Open https://mran.revolutionanalytics.com/documents/rro/installation/#sysreq 使用Intel的MKL库来加速计算,而不是默认的Reference BLAS库。

问题:

在Windows上,如何手动链接Intel的MKL库到R的最新版本中(https://cran.r-project.org/bin/windows/base/)?


更新 20-07-2016: 以下是如何为64位Windows上的R≥3.3.0构建基于OpenBLAS的Rblas.dll的详细说明:http://www.avrahamadler.com/r-tips/build-openblas-for-windows-r64/


我相信你需要编译R(链接已过时,抱歉),这可能会变得复杂;显然编译的版本是经过精心优化的。不过有时候也会有例外;在OS X上,你可以切换到内置的Accelerate BLAS而无需重新编译。我相信RcppArmadillo还具有更多的BLAS/LAPACK功能;如果你很幸运,Dirk可能会过来给你比我更好的建议。 - alistaire
1
是的,这个问题确实让人头疼,因为你所要求的实际上是一个非常大的问题,如果我们能做到的话,我们应该只需将最终产品品牌化并开始与微软竞争;) 我认为这是一个很好的问题,但我只希望我们能够创建一个社区赏金,例如500分,这样也许它就会得到答案。@alistaire 那个文档页面说:“也有适用于OS X和Windows的MKL版本,但在尝试时,它们无法与这些平台上使用的标准编译器一起工作。”顺便说一句,这个问题值得更多的赞。 - Hack-R
我想更正你问题中的一个前提。微软团队正在为每个R版本发布MRO,包括所有小版本。现在,发布版本存在一些延迟,但我们正在努力减少这种延迟的方式。我认为障碍更多是商业上的而不是技术上的。要重新分发MKL,您需要与英特尔签订允许您这样做的合同。 - Andrie
感谢澄清。我已经更新了问题。 - majom
@majom,这些指令对你有用吗? - Avraham
显示剩余7条评论
5个回答

17
安装Microsoft R Open(来自https://mran.microsoft.com/download),它附带了过时的R版本3.5.3,但也带有Intel MKL多线程BLAS库。 安装最新版本的R(来自https://cran.r-project.org/bin/windows/base/,当前是R 3.6.2)。 从C:\Program Files\Microsoft\R Open\R-3.5.3\bin\x64复制libiomp5md.dll、Rblas.dll和Rlapack.dll文件到C:\Program Files\R\R-3.6.2\bin\x64(如果需要备份您现有的默认非超线程Rblas.dll和Rlapack.dll文件,请先备份)。 将Microsoft R Open库/包MicrosoftR、RevoIOQ、RevoMods、RevoUtils、RevoUtilsMath和doParallel从C:\Program Files\Microsoft\R Open\R-3.5.5\library复制到您的默认包目录,例如C:\Documents\R\win-library\3.6。 从目录C:\Program Files\Microsoft\R Open\R-3.5.5\etc复制文件Rprofile.site和Renviron.site到C:\Progral Files\R\R-3.6.2\etc。 将文件Rprofile.site中的第24行 options(repos=r) 替换为 options(repos="https://cran.rstudio.com")(或您喜欢的CRAN存储库——您还可以使用 "https://cran.revolutionanalytics.com",该MRO存储库具有所有软件包的最新日常构建),以确保安装最新的CRAN软件包,而不是过时的mran.microsoft.com镜像,它的软件包版本已过期,冻结在2019年4月15日。同时请使用#注释掉第153、154和155行。 然后重新启动RStudio检查是否正常工作,在我的Intel Core i7-4700HQ 2.4GHz 4核/8线程笔记本电脑上进行小型SVD基准测试。
getMKLthreads()
4

# Singular Value Decomposition
m <- 10000
n <- 2000
A <- matrix (runif (m*n),m,n)
system.time (S <- svd (A,nu=0,nv=0))
   user  system elapsed 
  15.20    0.64    4.17

没有安装Intel MKL的同样基准测试在运行时得到了

   user  system elapsed 
  35.11    0.10   35.21 

因此我们在这里获得了>8倍的速度提升!

运行带有Intel MKL的Microsoft R Open 6.2的截图:

输入图像描述

或者,如果您不想将文件从MRO复制到最新的R安装程序中,则可以将免费的Intel MKL安装文件复制到R安装程序中以获得多线程操作(如下面的其他答案所述):

  1. https://software.intel.com/en-us/mkl/choose-download(免费)安装Intel MKL

将这些文件夹内的所有内容复制一份

C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\redist\intel64\mkl
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\redist\intel64\compiler
C:\Program Files\R\R-3.6.1\bin\x64
  1. 在目标文件夹中,创建 2 个 mkl_rt.dll 的副本,并将其中一个重命名为 Rblas.dll,另一个重命名为 Rlapack.dll,替换原始文件并保留 mkl_rt.dll。
  2. 这样做将不会提供 setMKLthreads() 和 getMKLthreads() 函数,以设置 Intel MKL 线程的数量,因为这些函数随 MRO 包 RevoUtilsMath 一起提供。但对于大多数人来说,默认线程数量设置为物理核心数量将足够......

不确定微软怎么回事,为什么他们不再更新 MRO...而且为什么他们也放弃了 Mac OS X 支持...

我希望鉴于现在 Intel MKL 是免费的,R 核心人员迟早会提供预编译的 R 版本,编译为使用 Intel MKL 库,或者在运行时检测是否安装了 Intel MKL,如果安装了,则使用它。我认为这很重要,特别是易得到一个好的多线程 BLAS 也决定了如何开发包 - 例如,如果所有操作系统都可用一个好的多线程 BLAS,那么就会倾向于使用 RcppArmadillo,它会退回到所安装的任何 BLAS(但在 Windows 上,如果未安装 Intel MKL,则会给出严重更差的时间),如果不是 RcppEigen 将是最佳选择,因为它具有自己的多线程矩阵代数,而与 R 编译时使用的 BLAS 无关......

顺便说一下,在 Ubuntu 上很容易使 R 使用 Intel MKL,而无需重新编译 R,如此处所述:https://github.com/eddelbuettel/mkl4deb

PS 轻微的问题是运行 setMKLthreads(4) 会使 RStudio 崩溃(尽管在官方 MRO 3.5.3 中已经存在这个问题),但在 R 控制台中可以正常工作...


2
将MKL库从MRO移动到普通R是违反许可协议的行为:https://mran.microsoft.com/assets/text/mkl-eula.txt - Hansi
@HongOoi 刚刚更新了关于如何获取R 3.6.2使用Intel MKL的信息,并再次确认只需复制几个文件就可以正常运行! - Tom Wenseleers
@hansi 刚刚更新了获取 R 3.6.2 使用 Intel MKL 的信息,并再次确认只需复制几个文件即可正常使用! - Tom Wenseleers
@kennyb 刚刚更新了有关如何获取 R 3.6.2 使用 Intel MKL 的信息,并再次确认只需复制几个文件即可正常工作! - Tom Wenseleers
1
我按照第一个步骤(即从MRO复制)进行了操作。它似乎可以在R版本4.1.1上运行。也就是说,RStudio启动没有错误,简单的基准测试(主要是chol)表明加速因子为4。有一个小问题:需要根据此SO答案修复Rprofile.site中的一些赋值。 - g g
显示剩余9条评论

15
我能够将您创建的自定义dll与R 3.6.0链接起来,使用builder。基本上您需要导出与 Rblas.dllRlapack.dll 相同的符号。启动 Compiler 19.0 Update 4 for Intel 64 Visual Studio 2017 environment 命令提示符:

获取符号:

dumpbin /exports Rblas.dll > Rblas_list
dumpbin /exports Rlapack.dll > Rlapack_list_R

编辑两个文件,删除"header"和"footer",并将所有带有符号名称的行(例如:248 F7 00138CE0 dgeevx_)都变成像dgeevx_这样的名称(只保留名称)。将builder目录复制到您的计算机上的某个位置,并在其中运行:

# blas links fine
nmake libintel64 export=..path..\Rblas_list name=Rblas 
# save lapack errors in another list
nmake libintel64 export=..path..\Rlapack_list_R name=Rlapack 1> undefined_symbols_list

编辑undefined_symbols_list,仅保留每行中的名称,然后创建一个新列表来存储差异。

findstr /v /g:undefined_symbols_list Rlapack_list_R > Rlapack_list
nmake libintel64 export=..path..\Rlapack_list name=Rlapack

通过运行 dumpbin /dependents Rlapack.dll 命令,您可以看到它们依赖于 libiomp5md.dll,您可以在 mkl 安装的 redist 文件夹中找到它。


方法 2

此方法使用更多的磁盘空间,但更加简单。将这些文件夹中的所有内容复制到内部。

C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\redist\intel64\mkl
C:\Program Files (x86)\IntelSWTools\compilers_and_libraries\windows\redist\intel64\compiler

to
C:\Program Files\R\R-3.6.1\bin\x64

在目标文件夹内,创建2个 mkl_rt.dll 的副本,并将其中一个重命名为 Rblas.dll,另一个重命名为 Rlapack.dll,替换原始文件并保留mkl_rt.dll

@kabammi 是的,从英特尔官网下载即可。方法2是将redist文件夹简单复制粘贴,所以如果您能在没有安装VS的情况下安装它,那么就可以开始使用了。请注意,将所有这些dll文件放在同一个文件夹中等同于将它们放在PATH文件夹中(假设只有该文件夹包含这些dll文件)。然而,将它们放在同一个文件夹中更加安全。 - Guilherme Higashi
Rblas.dll和Rlapack.dll都将是同一个mkl_rt.dll文件吗? - skan
我已经尝试了你的第二种方法,但R没有检测到MKL。 - skan
@skan 好的,启动消息和setMKLthreads(4)来自MRAN分发。在运行任何函数之前(在R加载blas/lapack之前),请使用Sys.setenv(MKL_VERBOSE=1)打开MKL详细模式,并运行一个简单的lm(dist~speed,cars),您应该会看到一些MKL函数调用。将时间与此基准脚本https://mac.r-project.org/benchmarks/R-benchmark-25.R进行比较。 - Guilherme Higashi
1
没关系 - 编译器文件现在位于 C:\Program Files (x86)\Intel\oneAPI\compiler\2022.0.3\windows\redist\intel64_win\compiler,我忘记了这些,因为它们现在在文件夹的不同部分! - Mooks
显示剩余9条评论

5

我刚刚尝试安装R 3.5.1。我在CRAN R旁边安装了Microsoft R Open,并从MRO MKL对应项中复制libiomp5md.dll并覆盖Rblas.dll、Rlapack.dll,以与Windows上的CRAN R链接(类似于上面的另一个答案,但需要同时复制文件libiomp5md.dll)。这很顺利,根据Github上的version.compare软件包,CRAN R的运行速度与MRO一样快(https://github.com/andrie/version.compare)。


在上面添加了更详细的说明并确认这个方法可行!谢谢! - Tom Wenseleers

1
Tom Weenseleers提供的解决方案对我最新版本的R有效。谢谢。
我想在此讨论中添加一些内容,因为它与此相关,但我不知道如何将其添加到更大的社区中。请原谅我的描述,我是个业余爱好者。
这个解决方法似乎会破坏至少两个其他R包,即igraph和clusterProfiler。Clusterprofiler依赖于igraph,所以根本原因是igraph。可能还有其他依赖于igraph的包也会受到影响。
我发帖是因为我找到了一个简单的解决方法,在广泛搜索后,我从未在任何论坛上明确地找到过这个问题,并且这可能会帮助其他人。
参考文献: clusterProfiler_4.4.4 和 igraph_1.3.4 R version 4.2.1,Platform: x86_64-w64-mingw32/x64 (64-bit) Windows 10 x64 (build 22000)
在实施上述解决方法后调用library(igraph)会弹出以下错误:
rsession-utf8.exe入口点未找到 动态链接库C:Program Files\R\R->4.2.1\library\graph\libs\x64\igraph.dll中找不到quadmath_snprintf入口点。
按下“确定”会在R中产生一个错误消息:
错误:无法为‘igraph’加载软件包或名称空间inDL(x, >as.logical(local), as.logical(now), ...)的失败: 无法加载共享对象'C:/Program Files/R/R->4.2.1/library/igraph/libs/x64/igraph.dll': LoadLibrary失败:指定的过程未找到。
解决方法是:在使用R中的MKL时,保留原始的Rlapack.dll和Rlablas.dll(我只是将它们重命名为Rblas_orig.dll)。要使用igraph或依赖项包,请交换.dll文件名,使得两个原始的R blas文件具有原始名称,而MKL文件则被重命名(即Rblas_mkl.dll)。重新启动R,igraph/clusterprofiler就可以正常加载了。
不幸的是,这将禁用MKL,直到您再次恢复.dll文件名并重新启动R,但只要您不需要同时使用igraph和MKL,它就可以工作,尽管有些令人沮丧。
如果有人发现更好的解决方案,请告诉我。

1

最新的igraph开发版本似乎已经解决了这个问题。要安装最新版本:

devtools::install_github("igraph/rigraph")

这似乎是R-core中的一个错误,它正在从Rlapack.dll中重新导出libquadmath的符号。修复方法似乎是在链接Rlapack之前链接libquadmath

这适用于最新的oneMKL和R 4.3.0,使用上面一些评论中提到的更正(由@Mooks提供)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接