为什么 Rcpp 仅在从 R 包中调用时才起作用段错误,而在通过 sourceCpp 直接获取时却不起作用?

Hil*_*ing 5 r rcpp r-package rcpparmadillo

我有一个C ++函数,当源独立地使用RCPP R中的作品,但是当我包括它在一个编译ř包,我继续接收以下错误:error: arma::memory::acquire(): out of memory。在这篇文章中,我提供了包含Znew_gen2要在我编译的 R 包中使用的函数的 C++ 代码。使用一个工作示例,我可以证明该Znew_gen2函数在我独立获取它时(在 R 包之外)有效。但是,当我从名为 的示例 R 包中调用相同的函数时HelpWithZnewgen2,该函数不再起作用,并且出现错误error: arma::memory::acquire(): out of memory。本文中提到的所有代码都可以在 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
  }

Run Code Online (Sandbox Code Playgroud)

当我运行工作示例并使用 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)
Run Code Online (Sandbox Code Playgroud)
## Output:

# First For Loop 
# Second For Loop 
# End of Function 
Run Code Online (Sandbox Code Playgroud)

但是,当我将这个相同的 Znew_gen2 函数放在 R 包中并从 R 包调用此函数时,我收到错误:error: arma::memory::acquire(): out of memory. 出于说明目的,我创建了一个名为的 R 包,HelpWithZnewgen2并使用名为 的包装函数调用 Znew_gen2 Rcpp 函数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)
Run Code Online (Sandbox Code Playgroud)

收到的错误:

# error: arma::memory::acquire(): out of memory
# Error in Znew_gen2(U, Z, group, cols, n, q, d, pBigMat, J) : 
#   std::bad_alloc
Run Code Online (Sandbox Code Playgroud)

在另一个设置中,我尝试从 R 包中的另一个函数中调用 Znew_gen2 函数,并且在内存分配方面遇到了类似的错误。

因为代码本身在 R 包之外源时有效,所以我怀疑我的问题与我的 R 包的设置方式有关。在线路:从网上搜索,我也不会,如果有一个或多个以下组件的问题感到惊讶Znew_gen2.cpp,我中缺少“使用命名空间RCPP”前行,我的说明文件,或者可能还有一些线Makevars文件R 包。尽管我有怀疑(这可能不正确,因为我对编写 R 包比较陌生),但我还是没能解决这个问题。因此,我将不胜感激有关如何解决此问题的任何建议。

Znew_gen2代码(文件Znew_gen2.cpphttps://github.com/hheiling/myrepo_R/blob/master/Znew_gen2.cpp)和HelpWithZnewgen2包组件的更多详细信息由Github 存储库https://github.com/hheiling/myrepo_R 提供。由于我不确定这些详细信息中的哪些(如果有)与回答问题相关,因此未在此处发布。

以上所有代码都在文件Stack Overflow Example.R https://github.com/hheiling/myrepo_R/blob/master/Stack%20Overflow%20Example.R 中提供

Dir*_*tel 3

我在评论中暗示应该尝试将您的问题分解为更小的问题。我只是尝试了一点。鉴于坚持不懈

 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
Run Code Online (Sandbox Code Playgroud)

我添加了代码来检查你的参数,确实是为了

 Rcpp::Rcout << "n*nMC is " << n*nMC << ", J.ncols is " << J.n_cols << std::endl;
Run Code Online (Sandbox Code Playgroud)

我懂了

 n*nMC is 50000, J.ncols is 25769803830
Run Code Online (Sandbox Code Playgroud)

所以目前你的问题不是对象bigmemory而是稀疏矩阵。

稍后编辑:事实证明,问题可能是您使用的#define ARMA_64BIT_WORD矩阵尺寸超出了 int这些 YUGE 值的外观。如果我删除它,您的代码就会运行。

所以重新吸取教训:让问题变得越来越小,这意味着将稀疏矩阵的使用从bigmemory矩阵的使用中分解出来。