从单个 PBS 作业启动多个进程并将它们分布在空闲的集群节点上

计算科学 并行计算 PBS
2021-12-18 21:05:40

我对 PBS 不是很熟悉(我们在这里安装了扭矩),到目前为止,我只用它来为每个作业运行一个进程,所以请多多包涵。

实际问题

我正在尝试在集群上使用 Mathematica。Mathematica 的并行处理是通过启动多个工作进程(称为子内核)并向它们发送命令以运行来实现的。

Mathematica 对 PBS 有一些支持,并且能够将子内核作为 PBS 作业启动。它使用qsub命令执行此操作。

虽然做大部分工作的是子内核(实际上我有一些 C 代码链接到它们),但收集结果的是主 Mathematica 内核。因此主内核也使用少量但非零的 CPU 时间。这意味着我无法在头节点上启动主内核,因为在它用完一定量的 CPU 时间后,它将自动终止(不允许在头节点上手动启动,只能通过qsub)。所以我也需要使用启动主内核qsub这将导致作业启动更多作业(qsub从提交的作业中调用qsub),这显然不起作用。

可以像这样轻松测试:

启动一个“交互式作业”qsub -I这实际上是我更喜欢启动主内核的方式,以便我可以手动监控计算的进度),然后在您尝试提交另一个作业的 shell 中qsub:这些嵌套qsub的导致qsub: Job rejected by all possible destinations错误。

问题 1: 有没有办法让嵌套qsub的 s 工作?一个作业可以排队更多作业吗?这将是理想的解决方案。

问题 2:如果不允许这样做,那么从一个作业启动多个进程并将它们分布在空闲集群节点上的正确方法是什么?我假设我需要以某种方式通过 PBS,询问哪些机器是空闲的,在这些机器上启动进程(如何?用ssh executablename?),然后告诉 PBS 我实际上在哪台机器上启动了多少进程。这个对吗?如果是,如何实施细节?

我宁愿不必走第二条路线,因为这将涉及使用不同的机制重新实现 Mathematica 的子内核启动qsub这是很多额外的工作。

2个回答

问题 1 的问题是,作为单独的作业,它们将无法相互通信,因为它们可能在不同的时间运行。这种方法更适合您完全控制的集群,并且可以在头节点上以半交互方式运行。

既然已经结束了,另一种选择是从在主内核上运行的脚本中自己启动内核。要从 PBS 脚本启动主内核,请编写带有标题行的mathematica 脚本

#!/path/to/mathkernel -script

如果集群上安装了 v.8,或者通过启动内核

/path/to/mathkernel -initfile "file-containing-script"

如果未安装 v.8。无论哪种情况,您的脚本都需要使用以下代码打开

Needs["SubKernels`RemoteKernels`"];
kernels = LaunchKernels[ RemoteMachine[#] ]& /@ Environment["PBS_NODEFILE"];

并且应该关闭

CloseKernels[ kernels ];

然后你就可以随意使用内核了。主内核已经在其中一个节点上工作,并且可以在从内核完成时进行处理。

我设法弄清楚嵌套qsub的 s 确实有效,但qsub只能在头节点上执行。因此需要使用ssh headnode qsub jobname,其中“headnode”是头节点的名称。

这仍然是一个 hack,更好(但更长)的解决方案是 @rcollyer 的建议。