使用共享内存 [bigmemory] ​​的并行化

Parallelization using shared memory [bigmemory]

我在尝试使其在并行场景 [doSNOW] 中工作时遇到了一些困难,涉及使用共享内存 [bigmemory]。总结是我在一些 foreach 工作人员中收到以下错误“{ 中的错误:任务 1 失败 - "cannot open the connection"”。更具体地说,检查集群输出日志,它与“'/temp/x_bigmatrix.desc':权限被拒绝”相关,就像并发访问big.matrix描述符文件。

请原谅,但由于代码有点复杂,我没有提供可重现的示例,但会尝试用要点解释工作流程。

我有一个矩阵X,通过:

转换成big.matrix
x_bigmatrix <- as.big.matrix(x_matrix, 
                             type = "double", 
                             separated = FALSE,
                             backingfile = "x_bigmatrix.bin",
                             descriptorfile = "x_bigmatrix.desc",
                             backingpath = "./temp/")

然后,我用 doSNOW 初始化 sock 集群 [我在 Windows 10 x64]:

cl <- parallel::makeCluster(N-1, outfile= "output.log")
registerDoSNOW(cl)

(showConnections() 正确显示已注册的连接)

现在我必须解释一下,我有每个工作人员的主循环 (foreach),然后有一个内部循环,每个工作人员在 X 中的行上循环。主要思想是,在主语料库中,每个工作人员通过内循环按顺序接收数据块,然后每个工作人员 可以存储 其中一些观察结果,而不是存储观察结果本身;他们存储行索引以供后验检索。为了使事情更加复杂,每个工作人员都修改了存储索引的关联 R6 class 环境。我这样说是因为对 big.matrix 描述符文件的访问发生在两个不同的地方:主 foreach 循环和每个 R6 环境中。 foreach主要语料如下:

workersOutput <- foreach(worker = workers, .verbose = TRUE) %dopar% {
    # In the main foreach loop I don't include the .packages argument because 
    # I do source with all the needed libraries at the beginning of the loop
    source(libs)

    # I attach the big.matrix using attach.big.matrix and the descriptor file
    x_bigmatrix <- attach.big.matrix("./temp/x_bigmatrix.desc")

    # Now the inner for loop is going to loop over the rows in X.
    # Each worker can store some of these indices for posterior retrieval
    for (i in seq(1, nrow(X)) {
        # Each R6 object associated with each worker is modified, storing indices...
        # Within these environments, there is read-only access through a getter using the same
        # procedure that above: x_bigmatrix <- attach.big.matrix("./temp/x_bigmatrix.desc")
    }
}
stopCluster(cl)

尝试访问 big.matrix 备份文件时,问题出现在内部循环中。因为如果我更改这些环境中的行为以显式存储观察结果而不是行索引(因此,无法再访问这些对象中的描述符文件),那么它可以毫无问题地工作。此外,如果我 运行 它没有并行化 [registerDoSEQ()] 但将行索引存储在对象中,也没有错误。因此,如果我在不同的 R6 环境中混合并行化和双重访问共享 big.matrix,就会出现问题。奇怪的是,有些工人可以 运行 比其他工人更长的时间,甚至最后至少有一个完成其 运行... 所以这让我想到了并发的问题访问 big.matrix 描述符文件。

我是不是在一些基础知识上失败了?

如果问题是对 big.matrix 描述符文件的并发访问,您可以只传递描述符对象(使用 describe)而不是包含该对象的描述符文件。

说明: 从描述符文件附加时,它首先创建 big.matrix.descriptor 对象,然后从该对象附加 big.matrix。所以,如果你直接使用这个对象,它会被复制到你所有的集群,你可以从它们附加 big.matrix