为什么 Rcpp 仅在从 R 包调用时才运行段错误,而不是在直接通过 sourceCpp 调用时运行?
Why does Rcpp function segfault only when called from R package but not when sourced directly via sourceCpp?
当我使用 Rcpp 独立获取源代码时,我有一个在 R 中工作的 C++ 函数,但是当我将它包含在编译的 R 包中时,我不断收到以下错误:error: arma::memory::acquire(): out of memory
。在此 post 中,我提供了包含函数 Znew_gen2
的 C++ 代码,我想在已编译的 R 包中使用该函数。使用一个工作示例,我可以证明 Znew_gen2
函数在我独立获取它时(在 R 包之外)工作。但是,当我从名为 HelpWithZnewgen2
的示例 R 程序包中调用相同的函数时,该函数不再有效,并且出现错误 error: arma::memory::acquire(): out of memory
。 post 中提到的所有代码都可以在 GitHub 存储库 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 函数时,如下所示,函数 运行s 没有错误。
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
中 "using namespace Rcpp" 行之前的行、我的描述文件,或者可能是我的某些行我在 R 包的 Makevars
文件中丢失了。尽管我有怀疑(这可能不正确,因为我对编写 R 包还比较陌生),但我无法解决这个问题。因此,对于如何解决此问题的任何建议,我将不胜感激。
Znew_gen2
代码的更多详细信息(文件 Znew_gen2.cpp
、https://github.com/hheiling/myrepo_R/blob/master/Znew_gen2.cpp ) 和 HelpWithZnewgen2
包的组件由 Github 存储库 https://github.com/hheiling/myrepo_R 提供。由于我不确定这些细节中的哪些(如果有的话)与回答问题相关,因此此处未对它们进行 post 编辑。
以上所有代码都在文件 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
矩阵的使用中分解出来。
当我使用 Rcpp 独立获取源代码时,我有一个在 R 中工作的 C++ 函数,但是当我将它包含在编译的 R 包中时,我不断收到以下错误:error: arma::memory::acquire(): out of memory
。在此 post 中,我提供了包含函数 Znew_gen2
的 C++ 代码,我想在已编译的 R 包中使用该函数。使用一个工作示例,我可以证明 Znew_gen2
函数在我独立获取它时(在 R 包之外)工作。但是,当我从名为 HelpWithZnewgen2
的示例 R 程序包中调用相同的函数时,该函数不再有效,并且出现错误 error: arma::memory::acquire(): out of memory
。 post 中提到的所有代码都可以在 GitHub 存储库 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 函数时,如下所示,函数 运行s 没有错误。
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
.
# 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
中 "using namespace Rcpp" 行之前的行、我的描述文件,或者可能是我的某些行我在 R 包的 Makevars
文件中丢失了。尽管我有怀疑(这可能不正确,因为我对编写 R 包还比较陌生),但我无法解决这个问题。因此,对于如何解决此问题的任何建议,我将不胜感激。
Znew_gen2
代码的更多详细信息(文件 Znew_gen2.cpp
、https://github.com/hheiling/myrepo_R/blob/master/Znew_gen2.cpp ) 和 HelpWithZnewgen2
包的组件由 Github 存储库 https://github.com/hheiling/myrepo_R 提供。由于我不确定这些细节中的哪些(如果有的话)与回答问题相关,因此此处未对它们进行 post 编辑。
以上所有代码都在文件 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
矩阵的使用中分解出来。