lme() 不同的结果在 Revolution R 下运行(MKL 归咎于?)



更新(2014 年 8 月):我从未深入了解这一点,也从未在 Revolution 的论坛上得到任何反馈。然而,这个问题似乎已经在Revolution R 7.2(R 3.0.3,同样是学术版本)中得到了修复。我在下面运行了几百次 lme() 测试,正如预期的那样,所有测试都产生了相同的结果。[更新结束]

我刚刚在新PC上安装了Revolution R 7.0(R 3.0.2)的学术版本,并且下面的代码得到了奇怪的结果。每次运行代码时,都会给出不同的结果。在 CRAN-are 下,结果总是相同的(我认为应该是这样)。代码片段来自test.data.table()版本 1.8.10 的测试 527,它向我指出了错误。

library(nlme)
all.equal(lme(distance ~ age, data=Orthodont), lme(distance ~ age, data=Orthodont))

我得到如下的东西,但每次都不同。

> all.equal(lme(distance ~ age, data=Orthodont), lme(distance ~ age, data=Orthodont))
[1] "Component 4: Component 2: Component 1: Mean relative difference: 1.774149e-08"
[2] "Component 7: Mean relative difference: 0.0003335902"

"有趣"的是nlme包(lme()是其中的一部分)本身是相同的,我卸载并重新安装以确保(包的 nlme_3.1-113.zip 文件是逐位相同的)。

我还没有足够的知识来深入了解。任何指示或想法将不胜感激。我也在革命论坛上发过帖子,但它似乎比这里人口少得多......

这是在64位Windows 8.1,64位R以及Intel i7-4770 CPU下,如果它很重要。当前版本的 Revolution R (R 3.0.2) 和以前的版本(2.15.3)都产生了意外的(对我来说)行为。CRAN-R 3.0.1 和 3.0.2 产生相同的结果。

Revolution R 的 sessionInfo() 输出:

> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    
attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     
other attached packages:
[1] nlme_3.1-113     Revobase_7.0.0   RevoMods_7.0.0   RevoScaleR_7.0.0
[5] lattice_0.20-24  rpart_4.1-3     
loaded via a namespace (and not attached):
[1] codetools_0.2-8   foreach_1.4.1     grid_3.0.2        iterators_1.0.6  
[5] pkgXMLBuilder_1.0 revoIpe_1.0       tools_3.0.2       XML_3.98-1.1   

更新 1:我已经将问题(遵循下面答案和评论中的一些指示)追溯到Revolution R使用Intel MKL BLAS库的事实。如果我切换到 CRAN 提供的 BLAS 库,问题就会消失。(注意:我自己对编译R的知识还不够,所以我还没有测试OpenBLAS和其他替代方案。在Revolution R中,只需重命名两个dll-s即可。

似乎其他人也得到了不一致的MKL结果。机器收费内部存在差异,即 all.equal()为真,而identical()为假。在我的案例中,不同的结果似乎有意义地大。

我已经在Revolution R的论坛上发布了这个问题,如果我得到回应,我会在这里更新。我想在这一点上,我的问题应该修改为"何时使用 MKL BLAS 以及何时使用 CRAN-R BLAS"。这不是速度(*)的问题,而是一致和正确的结果的问题。我将花更多时间寻找一个标准的测试套件(不确定这里的术语?)来检查R的输出与已知的正确输出。这是我喜欢data.table的原因之一,它有自己的测试对最终用户可见。我知道我不应该期望一个包含所有(甚至大多数)包的单一测试,而是至少涵盖基本功能的东西。

(*) 速度取决于具体的工作流程。在这种特殊情况下,CRAN BLAS比MKL更快(两者都运行单线程)。在其他工作中,Revolution R的速度要快得多,这就是我研究它的原因。

猜测,Revo R 正在 CPU 内核上并行化它,并且重新组合并行事物的算术并不总是关联的。换句话说,这取决于操作的顺序。如果线程以不同的顺序完成,如果内核必须做其他事情,就会发生这种情况,那么结果会以不同的顺序相加,并且 (a+b)+c 并不总是等于浮点中的 a+(b+c)......

要检查一下,有没有办法告诉Revo R只使用一个CPU内核?

最新更新