用rvienacl实现矩阵乘法

用rvienacl实现矩阵乘法,r,matrix,rcpp,viennacl,R,Matrix,Rcpp,Viennacl,我是一个新手,使用rvienacl软件包,尝试执行GPU矩阵乘法 尝试一个简单的案例,我在我创建的包(gpuUtils)的src文件夹中创建了一个cpp文件,代码如下: #include "viennacl/ocl/backend.hpp" #include "viennacl/linalg/prod.hpp" #include "viennacl/tools/random.hpp" #include "viennacl/matrix.hpp" //' PU matrix multiplic

我是一个新手,使用
rvienacl
软件包,尝试执行
GPU
矩阵乘法

尝试一个简单的案例,我在我创建的包(
gpuUtils
)的
src
文件夹中创建了一个
cpp
文件,代码如下:

#include "viennacl/ocl/backend.hpp"
#include "viennacl/linalg/prod.hpp"
#include "viennacl/tools/random.hpp"
#include "viennacl/matrix.hpp"


//' PU matrix multiplication
//'
//' @export
// [[Rcpp::export]]
SEXP matMult(){

  viennacl::tools::uniform_random_numbers<float> randomNumber;

  viennacl::matrix<float> vcl_A(400, 400);
  viennacl::matrix<float> vcl_B(400, 400);

  for (unsigned int i = 0; i < vcl_A.size1(); ++i)
    for (unsigned int j = 0; j < vcl_A.size2(); ++j)
      vcl_A(i,j) = randomNumber();
  for (unsigned int i = 0; i < vcl_B.size1(); ++i)
    for (unsigned int j = 0; j < vcl_B.size2(); ++j)
      vcl_B(i,j) = randomNumber();
  viennacl::matrix<float> vcl_C = viennacl::linalg::prod(vcl_A, vcl_B);
  return Rcpp::wrap(vcl_C);
}
但在尝试安装时,我得到:

$ R CMD INSTALL gpuUtils_0.0.0.9000.tar.gz
* installing to library ‘/home/usr/R’
* installing *source* package ‘gpuUtils’ ...
** libs
g++  -I/opt/ohpc/pub/libs/gnu7/R/3.4.2/lib64/R/include -DNDEBUG -I/usr/local/cuda-9.0/include/ -I"/home/usr/R/Rcpp/include" -I"/home/usr/R/RViennaCL/include" -I/usr/local/include   -fpic  -g -O2  -c gpuUtils.cpp -o gpuUtils.o
In file included from /home/usr/R/Rcpp/include/RcppCommon.h:195:0,
                 from /home/usr/R/Rcpp/include/Rcpp.h:27,
                 from /home/usr/R/RViennaCL/include/viennacl/ocl/forwards.h:29,
                 from /home/usr/R/RViennaCL/include/viennacl/ocl/context.hpp:36,
                 from /home/usr/R/RViennaCL/include/viennacl/ocl/backend.hpp:26,
                 from gpuUtils.cpp:1:
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h: In instantiation of ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown_iterable(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<float, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’:
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:732:43:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<float, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:770:41:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_eigen(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<float, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:787:39:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown_importable(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<float, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:807:52:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch(const T&, Rcpp::traits::wrap_type_unknown_tag) [with T = viennacl::matrix<float, viennacl::row_major>; SEXP = SEXPREC*]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap_end.h:30:38:   required from ‘SEXPREC* Rcpp::wrap(const T&) [with T = viennacl::matrix<float, viennacl::row_major>; SEXP = SEXPREC*]’
gpuUtils.cpp:25:26:   required from here
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:523:17: error: static assertion failed: cannot convert type to SEXP
                 static_assert(!sizeof(T), "cannot convert type to SEXP");
                 ^~~~~~~~~~~~~
make: *** [gpuUtils.o] Error 1
ERROR: compilation failed for package ‘gpuUtils’
* removing ‘/home/usr/R/gpuUtils’
* restoring previous ‘/home/usr/R/gpuUtils’
建筑精品:

$ R CMD build gpuUtils
* checking for file ‘gpuUtils/DESCRIPTION’ ... OK
* preparing ‘gpuUtils’:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
* building ‘gpuUtils_0.0.0.9000.tar.gz’
但仍然得到相同的错误:

$ R CMD INSTALL gpuUtils_0.0.0.9000.tar.gz
* installing to library ‘/home/usr/R’
* installing *source* package ‘gpuUtils’ ...
** libs
g++  -I/opt/ohpc/pub/libs/gnu7/R/3.4.2/lib64/R/include -DNDEBUG -I/usr/local/cuda-9.0/include/ -I"/home/usr/R/Rcpp/include" -I"/home/usr/R/RViennaCL/include" -I/usr/local/include   -fpic  -g -O2  -c gpuUtils.cpp -o gpuUtils.o
In file included from /home/usr/R/Rcpp/include/RcppCommon.h:195:0,
                 from gpuUtils.cpp:1:
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h: In instantiation of ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown_iterable(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’:
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:732:43:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:770:41:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_eigen(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:787:39:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown_importable(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:807:52:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch(const T&, Rcpp::traits::wrap_type_unknown_tag) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap_end.h:30:38:   required from ‘SEXPREC* Rcpp::wrap(const T&) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*]’
gpuUtils.cpp:68:56:   required from here
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:523:17: error: static assertion failed: cannot convert type to SEXP
                 static_assert(!sizeof(T), "cannot convert type to SEXP");
                 ^~~~~~~~~~~~~
make: *** [gpuUtils.o] Error 1
ERROR: compilation failed for package ‘gpuUtils’
* removing ‘/home/usr/R/gpuUtils’
* restoring previous ‘/home/usr/R/gpuUtils’
$R CMD安装gpuUtils_0.0.0.9000.tar.gz
*安装到库“/home/usr/R”
*正在安装*source*包“gpuUtils”。。。
**自由基
g++-I/opt/ohpc/pub/libs/gnu7/R/3.4.2/lib64/R/include-DNDEBUG-I/usr/local/cuda-9.0/include/-I”/home/usr/Rcpp/include“-I”/home/usr/R/RViennaCL/include“-I/usr/local/include-fpic-g-O2-c gpuUtils.cpp-o gpuUtils.o
在从/home/usr/R/Rcpp/include/RcppCommon.h:195:0包含的文件中,
从gpuUtils.cpp:1:
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:在“SEXPREC*Rcpp::internal::wrap_dispatch_unknown_iterable(const T&,Rcpp::traits::false_type)”的实例化中(使用T=viennacl::matrix;SEXP=SEXPREC*;Rcpp::traits::false_type=Rcpp::traits::integral_constant]:
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:732:43:来自“sexprc*Rcpp::internal::wrap\u dispatch\u未知(常量T&,Rcpp::traits::false\u type)[带T=viennacl::matrix;SEXP=sexprc*;Rcpp::traits::false\u type=Rcpp::traits::integral\u常量]”的必填项
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:770:41:来自“sexprc*Rcpp::internal::wrap\u dispatch\u eigen(const T&,Rcpp::traits::false\u type)[带T=viennacl::matrix;SEXP=sexprc*;Rcpp::traits::false\u type=Rcpp::traits::integral\u常量]的必填项
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:787:39:必须来自“sexprc*Rcpp::internal::wrap\u dispatch\u unknown\u importable(const T&,Rcpp::traits::false\u type)[with T=viennacl::matrix;SEXP=sexprc*;Rcpp::traits::false\u type=Rcpp::traits::integral\u常量]”
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:807:52:来自“sexperc*Rcpp::internal::wrap_dispatch(const T&,Rcpp::traits::wrap_type_unknown_tag)”的必填项[带T=viennacl::matrix;SEXP=sexperc*]
/home/usr/R/Rcpp/include/Rcpp/internal/wrap_end.h:30:38:需要从“SEXPREC*Rcpp::wrap(const T&)[带T=viennacl::matrix;SEXP=SEXPREC*]”
gpuUtils.cpp:68:56:从这里开始需要
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:523:17:错误:静态断言失败:无法将类型转换为SEXP
静态断言(!sizeof(T),“无法将类型转换为SEXP”);
^~~~~~~~~~~~~
make:**[gpuUtils.o]错误1
错误:包“gpuUtils”的编译失败
*正在删除“/home/usr/R/gpuUtils”
*恢复以前的“/home/usr/R/gpuUtils”

简短回答:是。RvinAcl只提供ViNANACL头,而没有<代码>()/<代码>和 WrAPP()/<代码>函数,用于R和C++数据结构之间的通信。而使用RViennaCl的
gpuR
包使用了一种不同的方法,将适当的对象暴露给R,并在这些对象上执行适当的函数。当然,您可以使用这些对象在GPU上进行矩阵乘法

因此,如果您对R和ViennaCl数据结构之间的通信感兴趣,您必须自己编写这些函数。不过,这不是一项简单的任务,因为RViennaCL对ViennaCL头进行了修补,以包括
Rcpp.h
(例如)。这使得您不可能像上面尝试的那样使用通常的扩展机制。我认为Rvienacl包含
RcppCommon.h
就足够了,这样可以实现扩展。但我没有试过。我已经申请了

对于ViennaCL,您不必编写
as()
wrap()
,还可以与一个转换为R数据结构的包结合使用。因此,在使用
链接到:Rcpp、RViennaCL、RcppEigen
的包中,此函数适用于我:

\define VIENNACL\u HAVE\u EIGEN
#包括
#包括
#包括
//“维也纳矩阵交叉产品”
//'
//“@出口
//[[Rcpp::导出]]
特征::矩阵xXD vclCrossprod(常数特征::矩阵xD&in_densematrix){
int rows=in_densematrix.rows();
int cols=in_densematrix.cols();
viennacl::矩阵viennacl_densematrix(行,列);
viennacl::副本(在densematrix,viennacl_densematrix中);
viennacl::矩阵viennacl_结果=viennacl::linalg::prod(
viennacl::trans(viennacl_densematrix),
维也纳(densematrix);
特征值::矩阵XXD特征值结果(cols,cols);
viennacl::复制(viennacl_结果,本征_结果);
返回本征结果;
}
然而,对于我尝试过的示例,这种方法并不是真正有效的。如果你正在做比矩阵乘法更复杂的事情,这可能会改变


或者,如果您主要对GPGPU感兴趣,而不是特别对ViennaCl感兴趣,您也可以尝试一下,我正在进行这项工作

/[[Rcpp::depends(RViennaCL)]
用于
cppFunction()
,它不用于包构建。更仔细地查看Rcpp属性渐晕图——您可能希望
链接到:RViennaCL
。删除
/[[Rcpp::depends(RViennaCL)]
行没有什么区别。在第二个示例中,我的“描述”文件中确实有
LinkingTo:RViennaCL
,您缺少示例中第77行的
typedef float ScalarType
。。。。更重要的是,在这两个例子中,
viennacl/matrix.hpp的导入。非常感谢。我已经相应地更新了我的帖子。
$ R CMD build gpuUtils
* checking for file ‘gpuUtils/DESCRIPTION’ ... OK
* preparing ‘gpuUtils’:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
* building ‘gpuUtils_0.0.0.9000.tar.gz’
$ R CMD INSTALL gpuUtils_0.0.0.9000.tar.gz
* installing to library ‘/home/usr/R’
* installing *source* package ‘gpuUtils’ ...
** libs
g++  -I/opt/ohpc/pub/libs/gnu7/R/3.4.2/lib64/R/include -DNDEBUG -I/usr/local/cuda-9.0/include/ -I"/home/usr/R/Rcpp/include" -I"/home/usr/R/RViennaCL/include" -I/usr/local/include   -fpic  -g -O2  -c gpuUtils.cpp -o gpuUtils.o
In file included from /home/usr/R/Rcpp/include/RcppCommon.h:195:0,
                 from gpuUtils.cpp:1:
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h: In instantiation of ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown_iterable(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’:
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:732:43:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:770:41:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_eigen(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:787:39:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown_importable(const T&, Rcpp::traits::false_type) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*; Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool, false>]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:807:52:   required from ‘SEXPREC* Rcpp::internal::wrap_dispatch(const T&, Rcpp::traits::wrap_type_unknown_tag) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*]’
/home/usr/R/Rcpp/include/Rcpp/internal/wrap_end.h:30:38:   required from ‘SEXPREC* Rcpp::wrap(const T&) [with T = viennacl::matrix<double, viennacl::row_major>; SEXP = SEXPREC*]’
gpuUtils.cpp:68:56:   required from here
/home/usr/R/Rcpp/include/Rcpp/internal/wrap.h:523:17: error: static assertion failed: cannot convert type to SEXP
                 static_assert(!sizeof(T), "cannot convert type to SEXP");
                 ^~~~~~~~~~~~~
make: *** [gpuUtils.o] Error 1
ERROR: compilation failed for package ‘gpuUtils’
* removing ‘/home/usr/R/gpuUtils’
* restoring previous ‘/home/usr/R/gpuUtils’