我一直在讨论multicore包和大对象的问题.基本思想是我使用Bioconductor函数(readBamGappedAlignments)来读取大对象.我有一个文件名的字符向量,我一直在使用mclapply循环文件并将它们读入列表.该函数看起来像这样:
objects <- mclapply(files, function(x) {
on.exit(message(sprintf("Completed: %s", x)))
message(sprintf("Started: '%s'", x))
readBamGappedAlignments(x)
}, mc.cores=10)
Run Code Online (Sandbox Code Playgroud)
但是,我不断收到以下错误:Error: serialization is too large to store in a raw vector.但是,似乎我可以单独读取相同的文件而不会出现此错误.我在这里找到了这个问题的提法,没有解决.
任何并行的解决方案建议都将受到赞赏 - 这必须并行完成.我可以看看雪,但我有一个非常强大的服务器,有15个处理器,每个8核,256GB的内存,我可以做到这一点.我宁愿在这台机器上跨核心进行,而不是使用我们的一个集群.
sendMaster据传,R 中的整数限制很快就会得到解决。根据我的经验,该限制可能会阻止包含 20 亿个以下单元格(大约最大整数)的数据集,并且包中的低级函数依赖于multicore传递原始向量。我有大约 100 万个进程,代表大约 4 亿行数据和 data.table 格式的 8 亿个单元格,当 mclapply 发送回结果时,它遇到了这个限制。
分而治之的策略并不难,而且很有效。我意识到这是一种 hack,人们应该能够依赖 mclapply。
不要创建一个大列表,而是创建一个列表列表。每个子列表都小于损坏的版本,然后将它们逐个拆分地输入到 mclapply 中。就叫这个吧file_map。结果是列表的列表,因此您可以使用特殊的双连接do.call函数。因此,每次 mclapply 完成时,序列化原始向量的大小都是可管理的大小。
只需循环较小的部分即可:
collector = vector("list", length(file_map)) # more complex than normal for speed
for(index in 1:length(file_map)) {
reduced_set <- mclapply(file_map[[index]], function(x) {
on.exit(message(sprintf("Completed: %s", x)))
message(sprintf("Started: '%s'", x))
readBamGappedAlignments(x)
}, mc.cores=10)
collector[[index]]= reduced_set
}
output = do.call("c",do.call('c', collector)) # double concatenate of the list of lists
Run Code Online (Sandbox Code Playgroud)
或者,随时将输出保存到数据库,例如 SQLite。
| 归档时间: |
|
| 查看次数: |
2106 次 |
| 最近记录: |