R 中的矩阵运算:并行化、稀疏运算、GPU 计算

Matrix operations in R: parallelization, sparse operations, GPU computation

我的问题的基本目的是如何使用 Matrix 包在 R 中实现矩阵运算的最佳性能。特别是我想并行化操作(乘法)并使用 CUDA GPU 上的计算来处理稀疏矩阵。

详情

根据 Matrix 包的文档 R cran

A rich hierarchy of matrix classes, including triangular, symmetric, and diagonal matrices, both dense and sparse and with pattern, logical and numeric entries. Numerous methods for and operations on these matrices, using 'LAPACK' and 'SuiteSparse' libraries.

看来,多亏了 SuiteSparse,我应该能够使用 GPU (CUDA) 对稀疏矩阵执行基本操作。特别是 SuiteSparse 的文档列出了以下内容:

SSMULT and SFMULT: sparse matrix multiplication.

在我的 Gentoo 上,我安装了 suitesparse-4.2.1suitesparseconfig-4.2.1-r1。我还有 lapackscalapackblas。 R sessionInfo() 看起来如下:

R version 3.4.1 (2017-06-30)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Gentoo/Linux

Matrix products: default
BLAS: /usr/lib64/blas/reference/libblas.so.0.0.0
LAPACK: /usr/lib64/lapack/reference/liblapack.so.0.0.0

locale:
 [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=en_GB.UTF-8        LC_COLLATE=en_GB.UTF-8
 [5] LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8
 [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] Matrix_1.2-10

loaded via a namespace (and not attached):
[1] compiler_3.4.1  grid_3.4.1      lattice_0.20-35

我也设置了环境变量:

export CHOLMOD_USE_GPU=1

我在一个论坛上找到的,可能应该允许使用 GPU。

基本上,一切看起来都准备就绪,但是,当我 运行 一个简单的测试时:

library(Matrix)
M1<-rsparsematrix(10000,10000,0.01) 
M<-M1%*%t(M1)

似乎 GPU 不工作,好像 R 忽略了 suitesparse 功能。

我知道问题很广泛,但是:

据我浏览 Stack 和其他论坛,这个问题不应该重复。

  1. 并不像你描述的那么容易。 Matrix 包包含 SuiteSparse 子集 ,并且此子集内置于包中。所以Matrix不使用你的系统SuiteSparse(你可以轻松浏览Matrix源代码here)。
  2. sparse_matrix * sparse_matrix 乘法很难有效地并行化 - 策略因两个矩阵的结构而异。
  3. 在许多情况下,计算是内存限制的,而不是 CPU 限制
  4. 由于上述内存问题 + 内存访问模式,与 CPU 相比,您在 GPU 上的性能可能更差。
  5. 据我所知,有几个库实现了多线程 SSMULT - Intel MKL 和 librsb,但我还没有听说过 R 接口。
  6. 如果矩阵很大,您可以手动划分矩阵并使用标准 mclapply。我怀疑这会有所帮助。
  7. 您可以尝试使用 EigenRcppEigen 并在那里执行 SSMULT。我相信它可能会更快(但仍然是单线程的)。
  8. 最终我会考虑如何重新表述问题并避免 SSMULT