[英]Why does Rcpp function segfault only when called from R package but not when sourced directly via sourceCpp?
我有一个C ++函数,当使用Rcpp独立源代码时在R中工作,但当我将它包含在已编译的R包中时,我不断收到以下错误: error: arma::memory::acquire(): out of memory
。 在这篇文章中,我提供了包含函数Znew_gen2
的C ++代码,我想在我编译的R包中使用它。 使用一个工作示例,我可以证明Znew_gen2
函数在我独立地(在R包之外)来源时有效。 但是,当我从名为HelpWithZnewgen2
的示例R包调用此相同函数时,该函数不再起作用,我得到错误error: arma::memory::acquire(): out of memory
。 本文中提到的所有代码都可以在GitHub repo https://github.com/hheiling/myrepo_R中找到 。
我的工作示例如下:
# Working Example:
library(bigmemory)
library(Matrix)
set.seed(1)
U = matrix(rnorm(3000), nrow=100, ncol=30)
Z = matrix(rnorm(15000), nrow = 500, ncol = 30)
group = rep(1:10, each = 50)
cols = c(1,11,21)
n = 500
q = 3
d = 10
Znew = big.matrix(nrow = nrow(Z)*nrow(U), ncol = 6)
J_SpMat = Matrix(0, 9, 6, sparse = TRUE)
sumy = 0
sumx = 0
zeros = 0
for(i in 1:3){
J_SpMat[ sumx + zeros + 1:(3 - (i-1)), sumy + 1:(3 - (i-1))] = diag((3 - (i-1)))
sumy = sumy + (3 - (i-1))
sumx = sumy
zeros = zeros + i
}
当我运行工作示例并使用sourceCPP调用Znew_gen2函数时,如下所示,该函数运行时没有错误。
library(Rcpp)
## Code to download the "Znew_gen2.cpp" file from the GitHub repo and
## specify where you want the file to download to:
destination_file = "Source_Code_Znew_gen2.cpp"
# Can specify however you like, but must not have spaces in the filename
download.file(url = "https://raw.githubusercontent.com/hheiling/myrepo_R/master/Znew_gen2.cpp",
destfile = destination_file)
sourceCpp(file = destination_file)
# Calling the sourced `Znew_gen2` function:
Znew_gen2(U, Z, group, cols, n, q, d, Znew@address, J_SpMat)
## Output:
# First For Loop
# Second For Loop
# End of Function
但是,当我将相同的Znew_gen2函数放在R包中并从R包调用此函数时,我得到错误: error: arma::memory::acquire(): out of memory
。 为了便于说明,我创建了一个名为HelpWithZnewgen2
的R包,并使用名为Znew_gen2.Rfunction
的包装函数调用Znew_gen2 Rcpp函数。
# Instructions to download the `HelpWithZnewgen2` package:
library(devtools)
library(remotes)
install_github("hheiling/myrepo_R", subdir = "HelpWithZnewgen2")
library(HelpWithZnewgen2)
# Calling the function from the compiled package:
Znew_gen2.Rfunction(U, Z, group, cols, n, q, d, Znew@address, J_SpMat)
收到的错误:
# error: arma::memory::acquire(): out of memory
# Error in Znew_gen2(U, Z, group, cols, n, q, d, pBigMat, J) :
# std::bad_alloc
在另一个设置中,我尝试从R包中的另一个函数中调用Znew_gen2函数,并且我得到了关于内存分配的类似错误。
因为代码本身在R包外部工作时,我怀疑我的问题与我的R包的设置方式有关。 在线路:从网上搜索,如果有一个或多个以下组件的问题,我也不会感到惊讶Znew_gen2.cpp
我缺少的“使用命名空间RCPP”前行,我的说明文件,或者可能还有一些线在R包的Makevars
文件中。 尽管我怀疑(这可能不正确,因为我对编写R软件包相对较新),但我无法解决这个问题。 因此,我非常感谢有关如何解决此问题的任何建议。
有关Znew_gen2
代码(文件Znew_gen2.cpp
, https://github.com/hheiling/myrepo_R/blob/master/Znew_gen2.cpp )和HelpWithZnewgen2
包的组件的更多详细信息, 请参阅Github repo https://github.com / hheiling / myrepo_R 。 由于我不确定这些细节中哪些(如果有的话)与回答问题相关,因此不会在此处发布。
上面的所有代码都在Stack Overflow Example.R
提供Stack Overflow Example.R
https://github.com/hheiling/myrepo_R/blob/master/Stack%20Overflow%20Example.R 。
我在评论中暗示应该尝试将您的问题分解为较小的问题。 我只是试了一下。 鉴于持久性
error: arma::memory::acquire(): out of memory
Error in Znew_gen2(U, Z, group, cols, n, q, d, Znew@address, J_SpMat) :
std::bad_alloc
Execution halted
我添加了代码来检查你的参数,的确如此
Rcpp::Rcout << "n*nMC is " << n*nMC << ", J.ncols is " << J.n_cols << std::endl;
我懂了
n*nMC is 50000, J.ncols is 25769803830
所以目前你的问题不是大bigmemory
对象而是稀疏矩阵。
稍后编辑:结果证明问题可能是你使用#define ARMA_64BIT_WORD
,这使得矩阵尺寸在int
之外,因此出现了这些YUGE值。 如果我删除了它,你的代码就会运行。
所以重新学习的教训:使问题bigmemory
小,这意味着分解你使用大bigmemory
矩阵稀疏矩阵的使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.