代码之家  ›  专栏  ›  技术社区  ›  Ahmed El-Gabbas

在函数内运行时,仅将特定对象导出到处理节点

  •  0
  • Ahmed El-Gabbas  · 技术社区  · 1 年前

    我想在R中使用并行计算。当在全局环境(函数之外)上运行时,行为正如预期的那样:例如。, parSapply 作用

    在下文中,变量 V2 没有出口,然后第二个 parSapply 调用失败。

    V1 <- 4
    V2 <- 7
    cl <- snow::makeCluster(2)
    snow::clusterExport(cl,'V1', envir = environment())
    x <- snow::parSapply(cl, 1, function(x) paste("value = ", V1))
    print(x)
    
    # V2 was not exported
    # expected error!
    x <- snow::parSapply(cl, 1, function(x) paste("value = ", V2))
    # Error in checkForRemoteErrors(val) : 
    #  one node produced an error: object 'V2' not found
    print(x)
    
    snow::stopCluster(cl)
    

    但是,在函数中工作时,函数中的所有对象都会导出并可访问 parSapply 作用

    testfunc3 <- function(){
       V1 <- 4
       V2 <- 7
       
       cl <- snow::makeCluster(2)
       snow::clusterExport(cl,'V1', envir = environment())
    
       print(unlist(snow::clusterEvalQ(cl, {ls()})))
    
       x <- snow::parSapply(cl, 1, function(x) paste("value = ", V1))
       print(x)
       
       # I expect an error if V2 not exported
       x <- snow::parSapply(cl, 1, function(x) paste("value = ", V2))
       print(x)
       
       snow::stopCluster(cl)
       return(invisible(NULL))
    }
    
    testfunc3()
    # [1] "V1" "V1"
    # [1] "value =  4"
    # [1] "value =  7"
    

    这条线 print(unlist(snow::clusterEvalQ(cl, {ls()}))) 显示在使用的两个内核中只有v1可用,但我仍然可以使用变量V2。这种行为是意料之中的事吗?

    这里的问题是,当函数中的对象非常大时,所有变量都被分布到1)不需要的核心中;2) 花时间将它们分发到核心;3) 由于内存限制,该函数可能会崩溃。

    有没有一种方法可以明确地允许某些对象分布到处理核心?


    使现代化

    我使用了 snowfall 具有的包 except 显式不导出特定对象的参数。然而,我也有同样的行为;即,函数内的所有变量都分布到核心中。

    V1 <- 4
    V2 <- 7
    snowfall::sfInit(parallel = TRUE, cpus = 2)
    snowfall::sfExportAll(except = c("V2"))
    
    x = snowfall::sfLapply(1:2, function(x) paste("value = ", V1))
    print(x)
    x = snowfall::sfLapply(1:2, function(x) paste("value = ", V2))
    print(x)
    snowfall::sfStop()
    
    testfunc4 <- function(){
       V1 <- 4
       V2 <- 7
       require(snowfall)
       snowfall::sfInit(parallel = TRUE, cpus = 2)
       snowfall::sfExportAll(except = c("V2"))
       
       x = snowfall::sfLapply(1:2, function(x) paste("value = ", V1))
       print(x)
       x = snowfall::sfLapply(1:2, function(x) paste("value = ", V2))
       print(x)
       snowfall::sfStop()
       
       # snow::stopCluster(cl)
       return(invisible(NULL))
    }
    testfunc4()
    
    0 回复  |  直到 1 年前
    推荐文章