使用 Rcpp 在 C++ 函数的 R 中使用 for 循环的内存问题
Mermory issue by using a for loop in R of C++ function using Rcpp
将 for 循环与 Rcpp 函数一起使用时,有一些不清楚的地方。这是一个应该有所帮助的简单示例:
这是我在文件 test_cpp.cpp
中的 cpp 代码
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat test_Cpp(int n,
arma::vec my_vec,
Rcpp::List my_list,
int mat_size,
double lambda,
double beta) {
// Matrix of mat_size rows & mat_size columns (filled with 0)
arma::mat matrix_out(mat_size, mat_size) ;
for (int it = 0 ; it < n ; ++it) {
arma::mat temp_mat_flux_convol = my_list[it] ;
if (my_vec[it] != 0) {
matrix_out += lambda * my_vec[it] * beta * temp_mat_flux_convol ;
}
}
return matrix_out ;
}
那么从 R 代码来看,为什么 res1
和 res2
在 'useless' for 循环中使用时不同,而在没有 for 循环时相同?我猜有段错误的东西,但我没有得到它!
library(Rcpp)
library(RcppArmadillo)
sourceCpp(file = "src/test_cpp.cpp")
set.seed(123)
ls_rand = lapply(1:10, function(x) matrix(rnorm(9), ncol=3))
for(i in 1:1){
res1 <- test_Cpp(n = 10,
my_vec = 1:100,
my_list = ls_rand,
mat_size = 3,
lambda = 24,
beta = 0.4)
res2 <- test_Cpp(n = 10,
my_vec = 1:100,
my_list = ls_rand,
mat_size = 3,
lambda = 24,
beta = 0.4)
}
all.equal(res1, res2)
res1 ; res2 # here res2 is twice res1 !!!
## Without for loop
res1 <- test_Cpp(n = 10,
my_vec = 1:100,
my_list = ls_rand,
mat_size = 3,
lambda = 24,
beta = 0.4)
res2 <- test_Cpp(n = 10,
my_vec = 1:100,
my_list = ls_rand,
mat_size = 3,
lambda = 24,
beta = 0.4)
all.equal(res1, res2)
res1 ; res2 # here res1 and res2 are the same!
错误在这里:
// Matrix of mat_size rows & mat_size columns (filled with 0)
arma::mat matrix_out(mat_size, mat_size) ;
mat(n_rows, n_cols) (memory is not initialised)
mat(n_rows, n_cols, fill_type) (memory is initialised)
因此,如果您将代码更改为
// Matrix of mat_size rows & mat_size columns (filled with 0)
arma::mat matrix_out(mat_size, mat_size, arma::fill::zeros) ;
评论其实是对的,问题就解决了。
将 for 循环与 Rcpp 函数一起使用时,有一些不清楚的地方。这是一个应该有所帮助的简单示例:
这是我在文件 test_cpp.cpp
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat test_Cpp(int n,
arma::vec my_vec,
Rcpp::List my_list,
int mat_size,
double lambda,
double beta) {
// Matrix of mat_size rows & mat_size columns (filled with 0)
arma::mat matrix_out(mat_size, mat_size) ;
for (int it = 0 ; it < n ; ++it) {
arma::mat temp_mat_flux_convol = my_list[it] ;
if (my_vec[it] != 0) {
matrix_out += lambda * my_vec[it] * beta * temp_mat_flux_convol ;
}
}
return matrix_out ;
}
那么从 R 代码来看,为什么 res1
和 res2
在 'useless' for 循环中使用时不同,而在没有 for 循环时相同?我猜有段错误的东西,但我没有得到它!
library(Rcpp)
library(RcppArmadillo)
sourceCpp(file = "src/test_cpp.cpp")
set.seed(123)
ls_rand = lapply(1:10, function(x) matrix(rnorm(9), ncol=3))
for(i in 1:1){
res1 <- test_Cpp(n = 10,
my_vec = 1:100,
my_list = ls_rand,
mat_size = 3,
lambda = 24,
beta = 0.4)
res2 <- test_Cpp(n = 10,
my_vec = 1:100,
my_list = ls_rand,
mat_size = 3,
lambda = 24,
beta = 0.4)
}
all.equal(res1, res2)
res1 ; res2 # here res2 is twice res1 !!!
## Without for loop
res1 <- test_Cpp(n = 10,
my_vec = 1:100,
my_list = ls_rand,
mat_size = 3,
lambda = 24,
beta = 0.4)
res2 <- test_Cpp(n = 10,
my_vec = 1:100,
my_list = ls_rand,
mat_size = 3,
lambda = 24,
beta = 0.4)
all.equal(res1, res2)
res1 ; res2 # here res1 and res2 are the same!
错误在这里:
// Matrix of mat_size rows & mat_size columns (filled with 0)
arma::mat matrix_out(mat_size, mat_size) ;
mat(n_rows, n_cols) (memory is not initialised)
mat(n_rows, n_cols, fill_type) (memory is initialised)
因此,如果您将代码更改为
// Matrix of mat_size rows & mat_size columns (filled with 0)
arma::mat matrix_out(mat_size, mat_size, arma::fill::zeros) ;
评论其实是对的,问题就解决了。