这相对来说很简单。
在您要求每个主机只请求一个进程的简化假设下,Slurm将提供您所需的所有信息,具体而言是环境变量SLURM_PROCID、SLURM_NPROCS和SLURM_NODELIST。
例如,您可以按照以下方式初始化任务索引、任务数和节点列表:
from hostlist import expand_hostlist
task_index = int( os.environ['SLURM_PROCID'] )
n_tasks = int( os.environ['SLURM_NPROCS'] )
tf_hostlist = [ ("%s:22222" % host) for host in
expand_hostlist( os.environ['SLURM_NODELIST']) ]
请注意,Slurm以其压缩格式(例如“myhost[11-99]”)提供主机列表,您需要扩展它。我使用Kent Engström的模块hostlist来完成这项工作,可以在此处获得
https://pypi.python.org/pypi/python-hostlist。
此时,您可以根据可用信息直接创建TensorFlow集群规范和服务器,例如:
cluster = tf.train.ClusterSpec( {"your_taskname" : tf_hostlist } )
server = tf.train.Server( cluster.as_cluster_def(),
job_name = "your_taskname",
task_index = task_index )
好的!现在您可以使用通常的语法,在您的分配的特定主机上执行TensorFlow节点放置:
for idx in range(n_tasks):
with tf.device("/job:your_taskname/task:%d" % idx ):
...
上述代码存在一个缺陷,即所有的作业都会指示Tensorflow在固定端口22222上安装服务器。如果多个这样的作业恰好被调度到同一节点,则第二个作业将无法侦听22222端口。
更好的解决方案是让Slurm为每个作业保留端口。您需要让Slurm管理员加入并要求他配置Slurm,以允许您使用--resv-ports选项请求端口。实际上,这需要向他们的slurm.conf中添加以下类似行:
MpiParams=ports=15000-19999
在向你的slurm管理员提问之前,请先检查已经配置了哪些选项,例如使用以下命令:
scontrol show config | grep MpiParams
如果您的网站已经使用旧版的OpenMPI,那么很有可能已经存在这样一个选项。然后,请按照以下方式修改我的第一段代码片段:
from hostlist import expand_hostlist
task_index = int( os.environ['SLURM_PROCID'] )
n_tasks = int( os.environ['SLURM_NPROCS'] )
port = int( os.environ['SLURM_STEP_RESV_PORTS'].split('-')[0] )
tf_hostlist = [ ("%s:%s" % (host,port)) for host in
expand_hostlist( os.environ['SLURM_NODELIST']) ]
祝你好运!
所有作业都在Docker容器中运行
,并检查Docker是否可以与Slurm一起工作。我发现了Slurm和docker/containers。我不认为你会得到答案,所以我给出了我所拥有的最好信息。带着一点点怀疑,但希望这能导致成功的结果。 - Guy Coder