gpt4 book ai didi

r - R 中线性代数的 MAGMA 和 Rcpp

转载 作者:行者123 更新时间:2023-12-02 21:52:03 25 4
gpt4 key购买 nike

我想知道是否有人尝试过使用RcppMAGMA使用CPU和GPU加速R中的线性代数运算?我试过culatools上个月,它与 Rcpp ( link ) 一起工作,但 culatools 是一种商业产品,需要花钱才能访问所有功能。

最佳答案

在修改了 culatools 之后,使用 RcppMAGMA 非常简单。这是 .cpp 文件:

#include<Rcpp.h>
#include<magma.h>

using namespace Rcpp;

RcppExport SEXP gpuQR_magma(SEXP X_)
{
// Input
NumericMatrix X(X_);

// Initialize magma and cublas
magma_init();
cublasInit();

// Declare variables
int info, lwork, n_rows = X.nrow(), n_cols = X.ncol(), min_mn = min(n_rows, n_cols);
double tmp[1];
NumericVector scale(min_mn);

// Query workspace size
magma_dgeqrf(n_rows, n_cols, &(X[0]), n_rows, &(scale[0]), &(work[0]), -1, &info);
lwork = work[0];
NumericVector work(lwork);

// Run QR decomposition
magma_dgeqrf(n_rows, n_cols, &(X[0]), n_rows, &(scale[0]), &(work[0]), lwork, &info);

// Scale factor result
for(int ii = 1; ii < n_rows; ii++)
{
for(int jj = 0; jj < n_cols; jj++)
{
if(ii > jj) { X[ii + jj * n_rows] *= scale[jj]; }
}
}

// Shutdown magma and cublas
magma_finalize();
cublasShutdown();

// Output
return wrap(X);
}

可以使用以下方法将文件从 R 编译为共享库:

library(Rcpp)  
PKG_LIBS <- sprintf('-Wl,-rpath,/usr/local/magma/lib -L/usr/local/magma/lib -lmagma /usr/local/magma/lib/libmagma.a -Wl,-rpath,/usr/local/cuda-5.5/lib64 %s', Rcpp:::RcppLdFlags())
PKG_CPPFLAGS <- sprintf('-DADD_ -DHAVE_CUBLAS -I/usr/local/magma/include -I/usr/local/cuda-5.5/include %s', Rcpp:::RcppCxxFlags())
Sys.setenv(PKG_LIBS = PKG_LIBS , PKG_CPPFLAGS = PKG_CPPFLAGS)
R <- file.path(R.home(component = 'bin'), 'R')
file <- '/path/gpuQR_magma.cpp'
cmd <- sprintf('%s CMD SHLIB %s', R, paste(file, collapse = ' '))
system(cmd)

现在可以在R中调用共享库。将结果与 Rqr() 进行比较得出:

dyn.load('/path/gpuQR_magma.so')

set.seed(100)
n_row <- 3; n_col <- 3
A <- matrix(rnorm(n_row * n_col), n_row, n_col)

qr(A)$qr

[,1] [,2] [,3]
[1,] 0.5250957 -0.8666925 0.8594266
[2,] -0.2504899 -0.3878643 -0.1277838
[3,] 0.1502909 0.4742033 -0.8804247

.Call('gpuQR_magma', A)

[,1] [,2] [,3]
[1,] 0.5250957 -0.8666925 0.8594266
[2,] -0.2504899 -0.3878643 -0.1277838
[3,] 0.1502909 0.4742033 -0.8804247

以下是使用具有 960 个 CUDA 核心和 OpenBLAS 的 NVIDIA GeForce GTX 675MX GPU 进行基准测试的结果:

n_row <- 3000; n_col <- 3000
A <- matrix(rnorm(n_row * n_col), n_row, n_col)
B <- A; dim(B) <- NULL

res <- benchmark(.Call('gpuQR_magma', A), .Call('gpuQR_cula', B, n_row, n_col), qr(A), columns = c('test', 'replications', 'elapsed', 'relative'), order = 'relative')

test replications elapsed relative
2 .Call("gpuQR_cula", B, n_row, n_col) 100 18.704 1.000
1 .Call("gpuQR_magma", A) 100 70.461 3.767
3 qr(A) 100 985.411 52.685

看起来MAGMAculatools(在本例中)要慢一些。然而,MAGMA 带有内存不足的实现,鉴于只有 1Gb 的 GPU 内存,这是我非常看重的一点。

关于r - R 中线性代数的 MAGMA 和 Rcpp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18402024/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com