【问题标题】:mc.cores > 1 is not support on windowsWindows 不支持 mc.cores > 1
【发布时间】:2018-03-02 19:07:40
【问题描述】:

我是 R 编程新手,我有如下代码,我知道 windows 不支持多核但我不知道如何更改这部分代码。 有人可以在不使用 mc.cores 功能的情况下向我推荐一个等效代码吗?

rpl <- unlist( lapply( waydf$geometry$coordinates , nrow ) ) # row per line
 waydf <- waydf[ rpl > 1 , ]
ll <- parallel::mclapply( waydf$geometry$coordinates , st_linestring,
                         mc.cores =parallel::detectCores() - 1  )
outdf <- sf::st_sf(
line_geometry = sf::st_sfc( ll , crs = epsg ) ,
osm_id = waydf$id
)

【问题讨论】:

  • 什么是st_linestring?自定义函数?
  • 知道 Windows 不支持多核吗? forking 没有被使用,因为它比 multicore 处理慢几个数量级。分叉启动一个单独的单线程进程。在同一数据上使用多个线程要快得多。试试使用 real 多核和 SIMD 处理的 Revolution R 发行版。你会发现在 i7 (quad) 上 svd 会快 7 倍
  • 你真的在问如何在 Windows 上进行并行处理吗?这就是下面的答案试图回答的问题。还是您只是想将此代码更改为不并行运行?

标签: r windows parallel-processing multicore


【解决方案1】:

如果您只想让这段代码不并行运行,您只需要告诉它使用 1 个内核,然后它会在后台使用 lapply

ll <- parallel::mclapply(waydf$geometry$coordinates, st_linestring, mc.cores = 1)

或者只是将mclapply 换成lapply

ll <- lapply(waydf$geometry$coordinates, st_linestring)

【讨论】:

    【解决方案2】:

    您必须澄清st_linestring 是什么或做什么,因为您试图将waydf$geometry$coordinates 的内容传递给它,但没有指定任何参数,例如st_linestring(waydf$geometry$coordinates[i])

    在 Windows 中,您将使用 parLapply 而不是 mclapply

    # original
    ll <- parallel::mclapply( waydf$geometry$coordinates , st_linestring,
                             mc.cores =parallel::detectCores() - 1  )
    
    # replace the above with all of the below
    library(parallel)
    cl <- makeCluster(detectCores())
    cl <- clusterEvalQ(cl, { library(sf) })  # you need to export packages as well
    # cl <- clusterExport(cl, "st_linestring")  # each worker is a new environment, you will need to export variables/functions to
    ll <- parallel::parLapply(cl, waydf$geometry$coordinates, function(i) st_linestring)    # if st_linestring takes arguments then st_linestring(x)
    stopCluster(cl)
    

    编辑由于st_linestring是来自sf包的函数,导出sf就足够了

    第二次编辑

    rpl <- unlist( lapply( waydf$geometry$coordinates , nrow ) ) # row per line
     waydf <- waydf[ rpl > 1 , ]
    
    library(parallel)
    cl <- makeCluster(detectCores())
    cl <- clusterEvalQ(cl, { library(sf) })  # you need to export packages as well
    # cl <- clusterExport(cl, "st_linestring")  # each worker is a new environment, you will need to export variables/functions to
    ll <- parallel::parLapply(cl, waydf$geometry$coordinates, function(i) st_linestring)    # if st_linestring takes arguments then st_linestring(x)
    stopCluster(cl)
    
    outdf <- sf::st_sf(
    line_geometry = sf::st_sfc( ll , crs = epsg ) ,
    osm_id = waydf$id
    )
    

    【讨论】:

    • 我仍然得到同样的错误 :(。我如何在没有多核功能的情况下运行这个功能?
    • 抱歉,您是否将mclapply 替换为parLapply?你的错误是什么?请出示
    • makeCluster(detectCores()) 中的错误:找不到函数“makeCluster”
    • 现在,我收到此错误: checkCluster(cl) 中的错误:此行中不是有效的集群:cl
    • 由于st_linestringsf包中,所以不需要导出。我注释掉了这一行
    【解决方案3】:

    问题是你在所有这些行中都做了cl &lt;- ...;你不断地把那个变量重新定义为别的东西。您应该只分配一次cl,然后重复使用它。

    library("parallel")
    cl <- makeCluster(detectCores())
    clusterEvalQ(cl, { library("sf") })
    clusterExport(cl, "st_linestring")
    res <- parallel::parLapply(cl, X = waydf$geometry$coordinates, 
                             fun = function(i) st_linestring)
    stopCluster(cl)
    

    您使用代码收到的消息Error in checkCluster(cl): not a valid cluster 是因为在您执行cl &lt;- clusterEvalQ(cl, { library("sf") }) 之后,它不再是cluster 对象。

    【讨论】:

    • @HenrikB,嘿。感谢您的回答。我尝试运行您的代码,但出现此错误:get(name, envir = envir) 中的错误:找不到对象 'st_linestring'
    猜你喜欢
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    • 2022-11-23
    • 1970-01-01
    • 2012-09-12
    相关资源
    最近更新 更多