使用-snowfall-(或其他包)并行重复用户定义的函数

时间:2013-01-28 18:04:35

标签: r parallel-processing snowfall

这个问题与this one有关,我问的是如何复制用户定义的函数。现在我想并行化操作以节省时间。我初步做的是:

  1. 我定义了一个自定义函数my.fun(),它返回output,一个包含1000行和20列的矩阵。

  2. 我复制说5output,并将结果存储在名为final的单个矩阵中:final <- do.call(rbind, replicate(5, my.fun(), simplify=FALSE))。因此,在此示例中,final5000 - 行矩阵。

  3. 我现在要做的是在将结果绑定到output矩阵之前并行化5(甚至更多......)final次复制。

    你会怎么做?到目前为止我所做的(错误的)是:

        library(snowfall)
    
        sfInit(parallel = TRUE, cpus = 4, type = "SOCK")
    
        # previously defined objects manipulated within my.fun
        sfExport(...)
    
        my.fun = function() {
           ...
           return(output)
        }
    
        final <- do.call(rbind, sfSapply(1:5, fun=my.fun(), simplify=FALSE))
    
        sfStop()
    

    但它返回:

    Error in get(as.character(FUN), mode = "function", envir = envir) : 
      object 'fun' of mode 'function' was not found
    

    任何帮助将不胜感激!请考虑我没有必要使用-snowfall-:最终目标是以有效的方式并行化final的计算(实际上我必须进行大量的复制......)。

2 个答案:

答案 0 :(得分:3)

sfSapply期望fun成为一个函数,但您将一次调用的结果移交给my.fun。也就是说,您希望移交my.fun,而不是my.fun ()

答案 1 :(得分:1)

我对R中的并行计算没有任何经验 我必须在函数my.func中添加一个伪参数,否则sfSapply会抱怨此错误

 first error: unused argument(s) (X[[1]])

所以我添加x作为参数

  my.fun <- function(x) matrix(1:4, 2,2)

现在我尝试对并行和sapply解决方案进行基准测试

  sfInit(parallel = TRUE, cpus = 4)
  library(rbenchmark)
  benchmark(
  pp = sfSapply(1:20000, fun=my.fun, simplify=FALSE),
  nopp = sapply(1:20000, FUN=my.fun, simplify=FALSE))

并行解决方案比经典解决方案慢!!我真的很困惑。也许其他更有经验的R paraelle计算可以给我们一个逻辑解释..

 test replications elapsed relative user.self sys.self user.child sys.child
2 nopp          100   15.22    1.000     13.90     0.02         NA        NA
1   pp          100   27.28    1.792     11.95     2.04         NA        NA