我正在使用基于 PBS 的集群并在一组节点上并行运行 IPython,每个节点有 24 或 32 个内核,内存范围从 24G 到 72G;这种异质性是由于我们的集群有它的历史。此外,我有一些作业要发送到 IPython 集群,这些作业具有不同的资源要求(内核和内存)。我正在寻找一种将作业提交到 ipython 集群的方法,该集群了解它们的资源需求和可用引擎的资源需求。我想有一种方法可以使用 IPython 功能优雅地处理这种情况,但我还没有找到。关于如何进行的任何建议?
1 回答
除了您指出您已经获得的图形依赖关系之外,IPython 任务还可以具有功能依赖关系。这些可以是任意函数,例如任务本身。功能依赖在实际任务之前运行,如果它返回 False 或引发特殊parallel.UnmetDependency
异常,则该任务将不会在该引擎上运行,并将在其他地方重试。
所以要使用它,你需要一个函数来检查你需要的任何指标。例如,假设我们只想在您的节点上以最少的内存运行一个任务。这是一个检查系统总内存(以字节为单位)的函数:
def minimum_mem(limit):
import sys
if sys.platform == 'darwin': # or BSD in general?
from subprocess import check_output
mem = int(check_output(['sysctl', '-n', 'hw.memsize']))
else: # linux
with open("/proc/meminfo") as f:
for line in f:
if line.startswith("MemTotal"):
mem = 1024 * int(line.split()[1])
break
return mem >= limit
kB = 1024.
MB = 1024 * kB
GB = 1024 * MB
所以minimum_mem(4 * GB)
如果您的系统上至少有 4GB 内存,则返回 True。如果您想检查可用内存而不是总内存,您可以使用 /proc/meminfo 中的 MemFree 和 Inactive 值来确定尚未使用的内存。
@parallel.depend
现在,您可以通过应用装饰器仅将任务提交给具有足够 RAM 的引擎:
@parallel.depend(minimum_mem, 8 * GB)
def big_mem_task(n):
import os, socket
return "big", socket.gethostname(), os.getpid(), n
amr = view.map(big_mem_task, range(10))
同样,您可以根据 CPU 数量应用限制(multiprocessing.cpu_count
这是一个有用的功能)。
这是一个笔记本,它使用这些来限制一些愚蠢任务的分配。
通常,该模型是为每个核心(而不是每个节点)运行一个 IPython 引擎,但如果您有特定的多核任务,那么您可能希望使用较小的数量(例如 N/2 或 N/4)。如果您的任务非常大,那么您实际上可能希望将其限制为每个节点一个引擎。如果您在每个节点上运行更多引擎,那么在同时运行高资源任务时需要小心。正如我所写的那样,这些检查不考虑同一节点上的其他任务,因此如果一个节点为 16 GB RAM,并且您有两个任务,每个任务需要 10 个,您将需要更加小心如何跟踪可用资源。