编辑:rslurm
的新版本使解决方案变得非常简单。请参阅下面的答案。
对于比期望的MWE稍微长一些的道歉,以及在提交问题后我意识到的标题可能是不必要的复杂。我认为真正的问题是将RefClass对象的环境变为rslurm::slurm_apply
。
这里我定义了一个名为BankAccount
的玩具参考类。它有两个字段和两个方法。
字段为transactions
,与帐户关联的所有交易列表以及银行将调查交易的价值suspicion_threshold
。
这两种方法是is_suspicious
,用于比较本地计算机上的transactions
和suspicion_threshold
以及is_suspicious_slurm
,后者使用rslurm::slurm_apply
将多次调用分散到is_suspicious
在由SLURM管理的一组计算机上。您可以想象,如果有许多交易或is_suspicious
函数更复杂,这可能是必要的。
所以,这是设置
BankAccount <- setRefClass(
Class = 'BankAccount',
fields = list(
transactions = 'numeric',
suspicion_threshold = 'numeric'
)
)
BankAccount$methods(
is_suspicious = function(start_idx = 1, stop_idx = length(transactions)) {
return(start_idx + which(transactions[start_idx:stop_idx] > suspicion_threshold) - 1)
}
)
BankAccount$methods(
is_suspicious_slurm = function(num_nodes) {
usingMethods(is_suspicious)
t <- length(transactions)
t_per_n <- floor(t/num_nodes)
starts <- seq(from = 1, length.out = num_nodes, by = t_per_n)
stops <- seq(from = t_per_n, length.out = num_nodes, by = t_per_n)
stops[num_nodes] <- t
sjob <- rslurm::slurm_apply(f = is_suspicious,
params = data.frame(start_idx = starts,
stop_idx = stops),
nodes = num_nodes,
add_objects = .self)
results_list <- rslurm::get_slurm_out(slr_job = sjob,
outtype = "raw",
wait = TRUE)
return(unlist(results_list))
}
)
现在,在我的本地机器上我可以运行:
library(RCexampleforSE)
set.seed(27599)
b <- BankAccount$new()
b$transactions <- rnorm(n = 500)
b$suspicion_threshold <- 2
b$is_suspicious()
b$is_suspicious_slurm(num_nodes = 3)
它按预期工作:
62 103 155 171 182 188 297 398 493 499
如果我跑:
b$is_suspicious_slurm(num_nodes = 3)
我收到错误,因为我的个人计算机未连接到SLURM群集。
sh:squeue:找不到命令 不能提交;路径上没有SLURM工作负载管理器 提交脚本在目录_rslurm_13ba46e3c70b0中输出 rslurm :: get_slurm_out出错(slr_job = sjob,outtype =&#34; raw&#34;,wait = TRUE): slr_job尚未提交
如果我登录使用SLURM的大学集群并运行相同的脚本,则设置和本地方法的工作方式与在个人计算机上的方式相同。我跑的时候:
b$is_suspicious_slurm(num_nodes = 3)
它将作业发送到群集,如希望的那样:
提交的批处理作业6363868
但是这些作业立即出现错误,并在slurm_0.out
,slurm_1.out
和slurm_2.out
中显示以下错误消息:
attr(,&#34; mayCall&#34;)出错:参数1为空 执行暂停
我认为工作可能需要,但是没有BankAccount
对象可用。所以我尝试将add_objects
参数传递给rslurm::slurm_apply
:
sjob <- rslurm::slurm_apply(f = is_suspicious,
params = data.frame(start_idx = starts,
stop_idx = stops),
nodes = num_nodes,
add_objects = .self)
我也在引号和eval()
里面尝试过,但两者都没有用。
如何使用rslurm::slurm_apply
创建的辅助作业可以访问该对象?
答案 0 :(得分:1)
编辑:OP answer就是您需要知道的全部内容。
add_objects
参数用于传递字符向量,而不是对象本身。然后将所有对象保存在一个RData文件中,假设它们可以通过名称找到。理论上,您应该能够在方法定义中使用add_objects = c('.self')
。
这里的关键是,&#34;假设可以找到它们&#34;。一旦对rslurm软件包的挂起更新(应该使该查找更成功)发布,我将编辑此帖子。
小心地将对象传递给群集节点:它们不会返回。不仅会丢失任何副作用,而且rslurm也没有实现节点间通信。
另外请注意which
:)对于不以1开头的参数,您的is_suspicious
方法会出错。请尝试此版本:
BankAccount$methods(
is_suspicious = function(i = 1:length(transactions)) {
idx <- which(transactions[i] > suspicion_threshold)
i[idx]
}
)
答案 1 :(得分:0)
rslurm
版本0.4.0完全解决了这个问题。
将is_suspicious_slurm()
定义为:
BankAccount$methods(
is_suspicious_slurm = function(num_nodes) {
usingMethods(is_suspicious)
t <- length(transactions)
t_per_n <- floor(t/num_nodes)
starts <- seq(from = 1, length.out = num_nodes, by = t_per_n)
stops <- seq(from = t_per_n, length.out = num_nodes, by = t_per_n)
stops[num_nodes] <- t
sjob <- rslurm::slurm_apply(f = is_suspicious,
params = data.frame(start_idx = starts,
stop_idx = stops),
nodes = num_nodes)
results_list <- rslurm::get_slurm_out(slr_job = sjob,
outtype = "raw",
wait = TRUE)
return(unlist(results_list))
}
)
唯一的变化是,在调用rslurm::slurm_apply
时,未指定add_objects
参数。它不需要指定,因为@Ian pointed out:
“......当slurm_apply发送序列化函数时,你根本不需要传递self,这似乎在封闭环境中包含”.self“和”transactions“。”