我是 Rcpp 和 OpenMP 的新用户。
我已经编写了将两个数组相乘的代码。
我也想使用 omp 来检查它在大矩阵上的性能。
我在 Visual Studio 2015 中使用 R 工具来工作并运行此代码:
当我在 r tools for Visual Studio 2015 中编译它时,我得到这个错误:
c:/Rtools/mingw_64/bin/g++ -m64 -I"C:/PROGRA~1/MIE74D~1/ROPEN~1/R-35~1.1/include" -DNDEBUG -I"C:/Users/amaa11/Documents/R/win-library/3.5/Rcpp/include" -I"C:/Users/amaa11/DOCUME~1/VISUAL~1/Projects/RPROJE~1/RPROJE~1" -I"C:/swarm/workspace/External-R-3.5.1/vendor/extsoft/include" -O2 -Wall -mtune=core2 -c mul_mat.cpp -o mul_mat.o
mul_mat.cpp:10:4: error: stray '#' in program
/ /#pragma omp parallel for
^
mul_mat.cpp:4:1: error: expected unqualified-id before '/' token
/ / [[Rcpp::export(mul_mat)]]<br>
^
make: *** [mul_mat.o] Error 1
我该如何解决?
快速简单的答案是:删除评论正斜杠之间的空格。例如,改变
/ /#pragma omp parallel for
到
//#pragma omp parallel for
不过,我也有其他意见/提示,以后可以在这里提问:
RcppArmadillo
!正如此处其他问题的几个答案所指出的,这是矩阵乘法的明显选择并且已经使用“多线程 OpenBLAS 和 OpenMP”。mult
的元素初始化为0;例如,如 Rcpp 快速参考指南 中所述,以 NumericMatrix
等方式构造的 Rcpp::NumericMatrix x(n, m)
创建一个 n × m 矩阵,该矩阵已经填充了 0.所以,为了完整起见,这是为我编译好的固定代码:
#include <Rcpp.h>
#include <omp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix mul_mat(int n, NumericMatrix A, NumericMatrix B) {
int i, j, k;
NumericMatrix mult(n, n);
for ( i = 0; i < n; ++i ) {
//#pragma omp parallel for
for ( j = 0; j < n; ++j ) {
mult(i, j) = 0;
}
}
for ( i = 0; i < n; ++i ) {
for ( j = 0; j < n; ++j ) {
for ( k = 0; k < n; ++k ) {
mult(i, j) += A(i, k) * B(k, j);
}
}
}
return mult;
}
我们可以看到它将函数导出到 R(添加这部分是为了响应现在已删除的关于将函数导出到 R 的正确方法的评论):
> Rcpp::sourceCpp("so-answer.cpp")
> ls()
[1] "mul_mat"
您最初在
#pragma omp parallel for
之前有一个(n个错误输入的)评论分隔符;如果你真的想使用它,请删除注释分隔符并添加// [[Rcpp::plugins(openmp)]]
;这是在 Rcpp Gallery post: 中讨论的(以及其他地方)
此外,我们可以利用 OpenMP 库来使用多个 核心。对于 OpenMP 实现,我们需要启用 OpenMP 支持。这样做的一种方法是添加所需的编译器和 链接器标志如下:
Sys.setenv("PKG_CXXFLAGS"="-fopenmp")
Sys.setenv("PKG_LIBS"="-fopenmp")Rcpp 0.10.5 及以后版本也会提供一个插件来设置这些 我们的变量:
// [[Rcpp::plugins(openmp)]]
所以,试试:
#include <Rcpp.h>
#include <omp.h>
// [[Rcpp::plugins(openmp)]]
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix mul_mat(int n, NumericMatrix A, NumericMatrix B) {
int i, j, k;
NumericMatrix mult(n, n);
for ( i = 0; i < n; ++i ) {
omp_set_num_threads(2); // For example
#pragma omp parallel for
for ( j = 0; j < n; ++j ) {
mult(i, j) = 0;
}
}
for ( i = 0; i < n; ++i ) {
for ( j = 0; j < n; ++j ) {
for ( k = 0; k < n; ++k ) {
mult(i, j) += A(i, k) * B(k, j);
}
}
}
return mult;
}
在我的机器上也编译得很好。