0

我正在尝试通过在 Linux 上使用多核计划来使用未来包加速我的 R 代码。在未来的定义中,我正在创建一个 java 对象并尝试将其传递给 .jcall(),但将来我会为 java 对象获得一个空值。谁能帮我解决这个问题。以下是示例代码-

    library("future")
    plan(multicore)

    library(rJava)
    .jinit()

    # preprocess is a user defined function
    my_value <- preprocess(a = value){
      # some preprocessing task here
      # time consuming statistical analysis here
      return(lreturn) # return a list of 3 components
    }
    obj=.jnew("java.custom.class")

    f <- future({
      .jcall(obj, "V", "CustomJavaMethod", my_value)
    })

基本上我正在处理大型流数据。在上面的代码中,我将流数据字符串发送到用户定义的函数进行统计分析并返回 3 个组件的列表。然后想将此列表发送到自定义 java 类 [java.custom.class] 以使用自定义 Java 方法 [CustomJavaMethod] 进行进一步处理。不使用未来我的代码运行良好。但是我在一分钟内获得了 12 条流记录,然后我的代码变慢了,观察到处理延迟。

目前我使用的是 16 核的 Unix。使用 future 包后,我的过程很快完成。我已经追溯了我的代码,在 .jcall 中发生了错误。

希望这能澄清我的痛苦。

4

2 回答 2

2

(未来包的作者在这里:)

不幸的是,R 中有某些类型的对象无法发送到另一个 R 进程进行进一步处理。澄清一下,这是对那些类型的对象的限制——而不是并行框架的使用(这里是未来的框架)。这种对象的这个最简单的例子可以是文件连接,例如con <- file("my-local-file.txt", open = "wb"). 我在“解决方案的常见问题”小插图(https://cran.r-project.org/web/packages/future/vignettes/future-4-issues. html ).

如小插图中所述,您可以设置一个选项 (*),以便未来框架在尝试启动未来(“提前停止”)之前查找这些类型的对象并给出信息错误。这是您激活此检查的示例:

library("future")
plan(multisession)

## Assert that global objects can be sent back and forth between
## the main R process and background R processes ("workers")
options(future.globals.onReference = "error")

library("rJava")
.jinit()

end <- .jnew("java/lang/String", " World!")

f <- future({
  start <- .jnew("java/lang/String", "Hello")
  .jcall(start, "Ljava/lang/String;", "concat", end)
})

# Error in FALSE : 
#  Detected a non-exportable reference ('externalptr') in one of the
#  globals ('end' of class 'jobjRef') used in the future expression

所以,是的,您的示例在使用plan(multicore). 原因是“多核”使用分叉进程(在 Unix 和 macOS 上可用,但在 Windows 上不可用)。但是,我会尽力限制您的软件仅在“可分叉”系统上并行化;如果你能找到一种替代方法,我会为此而努力。这样你的代码也可以在一个巨大的云集群上运行。

(*) 默认情况下未启用这些检查的原因是 (a) 它仍处于 beta 测试中,并且 (b) 它带有开销,因为我们基本上需要在所有全局变量中扫描不支持的对象。这些检查是否会在未来默认启用,将在https://github.com/HenrikBengtsson/future进行讨论。

于 2018-04-24T18:57:06.077 回答
0

问题中的代码正在调用未知Method1方法,my_value未定义,......很难知道您真正想要实现的目标。

看看下面这个例子,或许你能从中得到启发:

library(future)
plan(multicore)

library(rJava)
.jinit()

end = .jnew("java/lang/String", " World!")

f <- future({
  start = .jnew("java/lang/String", "Hello")
  .jcall(start, "Ljava/lang/String;", "concat", end)
})

value(f)
[1] "Hello World!"
于 2018-04-24T18:14:25.660 回答