我试图将一个对象(即R6
类;这个特定的对象)传递给使用创建的许多工作人员parallel::makePSOCKcluster()
,我得到:
Error in checkForRemoteErrors(val) :
one node produced an error: external pointer is not valid
[...] 有一组对象类型不能被传递到另一个 R 进程并且可以在那里工作。
我想了解我试图传递的对象是否属于这一类,如果是,我的选择是什么。
这是一个MRE:
场景1:( 工作)model
在每个工人内部创建对象。
(function() {
# Create cluster.
cluster <- parallel::makePSOCKcluster(parallel::detectCores() - 1)
# Stop cluster.
on.exit(parallel::stopCluster(cluster))
# Bare minimum data.
x <- matrix(rnorm(100), 10, 10)
y <- runif(10)
# Run operation.
result <- parallel::parSapply(cluster, c(1), function(i) {
# The 'osqp' object.
model <- osqp::osqp(P = crossprod(x), q = -crossprod(x, y), pars = list(verbose = FALSE))
# Calling the solver.
return(model$Solve()$x)
})
# Inspect result.
print(result)
})()
场景 2:( 不工作)主要创建model
对象并将其传递给工作人员。
(function() {
# Create cluster.
cluster <- parallel::makePSOCKcluster(parallel::detectCores() - 1)
# Stop cluster.
on.exit(parallel::stopCluster(cluster))
# Bare minimum data.
x <- matrix(rnorm(100), 10, 10)
y <- runif(10)
# The 'osqp' object.
model <- osqp::osqp(P = crossprod(x), q = -crossprod(x, y), pars = list(verbose = FALSE))
# Run operation.
result <- parallel::parSapply(cluster, c(1), function(i) {
# Calling the solver.
return(model$Solve()$x)
})
# Inspect result.
print(result)
})()
方案 1有效,所以我似乎可以osqp
在工人内部使用。但是,当我在外部创建该对象并将其传递给工作人员(即场景 2)时,它失败了。
为了提供更多的上下文,我无法控制model
创建。我收到一个在别处创建的实例,我只被允许在该实例上调用几个方法(例如,$Update()
)。
更新 1
这似乎与R6
实例是环境这一事实无关。以下仍然按预期工作。
# Create mock model class.
ModelMock <- R6::R6Class("ModelMock",
public = list(
Solve = function() {
return(list(x = "Mocked model output."))
}
)
)
(function() {
# Create cluster.
cluster <- parallel::makePSOCKcluster(parallel::detectCores() - 1)
# Stop cluster.
on.exit(parallel::stopCluster(cluster))
# The mocked 'osqp' object.
model <- ModelMock$new()
# Run operation.
result <- parallel::parSapply(cluster, c(1), function(i) {
# Calling the solver.
return(model$Solve()$x)
})
# Inspect result.
print(result)
})()