slurm_apply来自RefClass方法中的RefClass方法

时间:2017-06-21 16:13:44

标签: r slurm reference-class

编辑:rslurm的新版本使解决方案变得非常简单。请参阅下面的答案。

对于比期望的MWE稍微长一些的道歉,以及在提交问题后我意识到的标题可能是不必要的复杂。我认为真正的问题是将RefClass对象的环境变为rslurm::slurm_apply

MWE

这里我定义了一个名为BankAccount的玩具参考类。它有两个字段和两个方法。

字段为transactions,与帐户关联的所有交易列表以及银行将调查交易的价值suspicion_threshold

这两种方法是is_suspicious,用于比较本地计算机上的transactionssuspicion_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.outslurm_1.outslurm_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创建的辅助作业可以访问该对象?

2 个答案:

答案 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“。”