【问题标题】:Getting "node stack overflow" when cbind multiple sparse matricescbind 多个稀疏矩阵时出现“节点堆栈溢出”
【发布时间】:2016-06-02 01:51:07
【问题描述】:

我有 100,000 个稀疏矩阵(“dgCMatrix”)存储在一个列表对象中。每个矩阵的行数相同(8,000,000),列表大小约为 25 Gb。现在当我这样做时:

do.call(cbind, theListofMatrices)

将所有矩阵组合成一个大的稀疏矩阵,我得到了“节点堆栈溢出”。实际上,我什至不能只使用该列表中的 500 个元素来执行此操作,它应该输出一个大小仅为 100 Mb 的稀疏矩阵。

我对此的猜测是 cbind() 函数将稀疏矩阵转换为正常的密集矩阵,从而导致堆栈溢出?

其实我也试过这样的:

tmp = do.call(cbind, theListofMatrices[1:400])

这很好用,tmp 仍然是一个大小为 95 Mb 的稀疏矩阵,然后我尝试了:

> tmp = do.call(cbind, theListofMatrices[1:410])
Error in stopifnot(0 <= deparse.level, deparse.level <= 2) : 
  node stack overflow

然后发生错误。但是,我可以毫无困难地执行以下操作:

cbind(tmp, tmp, tmp, tmp)

因此,我认为它与 do.call() 有关

Reduce() 似乎解决了我的问题,虽然我仍然不知道 do.call() 崩溃的原因。

【问题讨论】:

标签: r sparse-matrix


【解决方案1】:

问题不在于do.call(),而在于Matrix 包中cbind 的实现方式。它使用递归将各个参数绑定在一起。例如,Matrix::cbind(mat1, mat2, mat3) 被翻译成类似于Matrix::cbind(mat1, Matrix::cbind(mat2, mat3)) 的东西。 由于do.call(cbind, theListofMatrices) 基本上是cbind(theListofMatrices[[1]], theListofMatrices[[2]], ...),因此cbind 函数的参数太多,最终会导致嵌套太深的递归而失败。

因此,Ben's comment 使用 Reduce() 是解决该问题的好方法,因为它避免了递归并将其替换为迭代:

tmp <- Reduce(cbind, theListofMatrices[-1], theListofMatrices[[1]])

【讨论】:

  • 出色的洞察力。确实堆栈溢出来自cbind的嵌套。
【解决方案2】:

在 R 中:2 列矩阵最多可以有 2^30-1 行 = 1073,741,823 行。所以,我会检查行号并检查 RAM 大小以确保它可以容纳大矩阵大小。

【讨论】:

  • 这是物理矩阵的局限;这种限制不应该应用于稀疏矩阵,除非它被转换为沿线某处的密集矩阵(尽管打印对象可能会导致错误)
猜你喜欢
  • 2020-07-02
  • 2023-03-30
  • 2022-01-22
  • 1970-01-01
  • 2016-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多