&引用;令人尴尬的平行”;在集群上使用python和PBS编程

&引用;令人尴尬的平行”;在集群上使用python和PBS编程,python,pbs,qsub,embarrassingly-parallel,Python,Pbs,Qsub,Embarrassingly Parallel,我有一个函数(神经网络模型),可以生成数字。我希望在带有Torque的标准集群上使用PBS测试python中的几个参数、方法和不同输入(意味着数百次函数运行) 注意:我尝试了parallelpython、ipython等等,但从未完全满意,因为我想要更简单的东西。集群处于我无法更改的给定配置中,这样一个集成python+qsub的解决方案肯定会使社区受益 为了简化,我有一个简单的函数,例如: import myModule def model(input, a= 1., N=100):

我有一个函数(神经网络模型),可以生成数字。我希望在带有Torque的标准集群上使用PBS测试python中的几个参数、方法和不同输入(意味着数百次函数运行)

注意:我尝试了parallelpython、ipython等等,但从未完全满意,因为我想要更简单的东西。集群处于我无法更改的给定配置中,这样一个集成python+qsub的解决方案肯定会使社区受益

为了简化,我有一个简单的函数,例如:

import myModule
def model(input, a= 1., N=100):
    do_lots_number_crunching(input, a,N)
    pylab.savefig('figure_' + input.name + '_' + str(a) + '_' + str(N) + '.png')
其中,
input
是表示输入的对象,
input.name
是字符串,
do\u lots\u number\u crunch
可能持续数小时

我的问题是:是否有一种正确的方法来转换像参数扫描这样的东西,例如

for a in pylab.linspace(0., 1., 100):
    model(input, a)
进入“某物”,它将为对
模型的每次调用启动PBS脚本
函数

#PBS -l ncpus=1
#PBS -l mem=i1000mb
#PBS -l cput=24:00:00
#PBS -V
cd /data/work/
python experiment_model.py

我正在考虑一个包含PBS模板的函数,并从python脚本中调用它,但还没有弄明白(decorator?)。

PBS_python[1]可以用于此。如果将experiment_model.py“a”作为参数,您可以

import pbs, os

server_name = pbs.pbs_default()
c = pbs.pbs_connect(server_name)

attopl = pbs.new_attropl(4)
attropl[0].name  = pbs.ATTR_l
attropl[0].resource = 'ncpus'
attropl[0].value = '1'

attropl[1].name  = pbs.ATTR_l
attropl[1].resource = 'mem'
attropl[1].value = 'i1000mb'

attropl[2].name  = pbs.ATTR_l
attropl[2].resource = 'cput'
attropl[2].value = '24:00:00'

attrop1[3].name = pbs.ATTR_V

script='''
cd /data/work/
python experiment_model.py %f
'''

jobs = []

for a in pylab.linspace(0.,1.,100):
    script_name = 'experiment_model.job' + str(a)
    with open(script_name,'w') as scriptf:
        scriptf.write(script % a)
    job_id = pbs.pbs_submit(c, attropl, script_name, 'NULL', 'NULL')
    jobs.append(job_id)
    os.remove(script_name)

 print jobs

[1] :pbs_python

您可以使用(我为类似的设置而开发的)轻松完成此操作

您可以在文件中编写(例如,
model.py
):

就这样

现在您可以在队列上启动“jug jobs:
jug execute model.py
,这将自动并行化。发生的情况是,每个作业将在一个循环中执行以下操作:

while not all_done():
    for t in tasks in tasks_that_i_can_run():
        if t.lock_for_me(): t.run()
(事实上比这更复杂,但你明白了)

它使用文件系统进行锁定(如果您在NFS系统上),或者如果您愿意,使用redis服务器。它还可以处理任务之间的依赖关系


这并不是你想要的,但我相信这是一种更干净的架构,可以将其与工作队列系统分开。

看起来我参加聚会有点晚了,但几年前我也遇到了同样的问题,即如何用python将令人尴尬的并行问题映射到集群上,并编写了自己的解决方案。我最近将其上传到github的以下位置:

要使用pbs_util编写程序,我首先在包含以下内容的工作目录中创建一个pbs_util.ini

[PBSUTIL]
numnodes=1
numprocs=1
mem=i1000mb
walltime=24:00:00
然后是这样的python脚本

import pbs_util.pbs_map as ppm

import pylab
import myModule

class ModelWorker(ppm.Worker):

    def __init__(self, input, N):
        self.input = input
        self.N = N

    def __call__(self, a):
        myModule.do_lots_number_crunching(self.input, a, self.N)
        pylab.savefig('figure_' + self.input.name + '_' + str(a) + '_' + str(self.N) + '.png')



# You need  "main" protection like this since pbs_map will import this file on the     compute nodes
if __name__ == "__main__":
    input, N = something, picklable
    # Use list to force the iterator
    list(ppm.pbs_map(ModelWorker, pylab.linspace(0., 1., 100),
                     startup_args=(input, N),
                     num_clients=100))

我刚刚开始使用集群和EP应用程序。我的目标(我在图书馆)是学习足够的知识,帮助校园内的其他研究人员使用EP应用程序访问HPC…特别是STEM以外的研究人员。我还是一个新手,但我认为指出在PBS脚本中使用来启动具有不同参数的基本python脚本可能有助于解决这个问题。在.pbs文件中,有两行需要指出:

module load gnu-parallel # this is required on my environment

parallel -j 4 --env PBS_O_WORKDIR --sshloginfile $PBS_NODEFILE \
--workdir $NODE_LOCAL_DIR --transfer --return 'output.{#}' --clean \
`pwd`/simple.py '{#}' '{}' ::: $INPUT_DIR/input.*

# `-j 4` is the number of processors to use per node, will be cluster-specific
# {#} will substitute the process number into the string
# `pwd`/simple.py `{#}` `{}`   this is the command that will be run multiple times
# ::: $INPUT_DIR/input.* all of the files in $INPUT_DIR/ that start with 'input.' 
#     will be substituted into the python call as the second(3rd) argument where the
#     `{}` resides.  These can be simple text files that you use in your 'simple.py'
#     script to pass the parameter sets, filenames, etc.
作为EP超级计算的新手,尽管我还不了解“parallel”上的所有其他选项,但该命令允许我使用不同的参数并行启动python脚本。如果您能够提前生成大量的参数文件来并行化您的问题,那么这将非常有效。例如,在参数空间中运行模拟。或者使用相同的代码处理多个文件

module load gnu-parallel # this is required on my environment

parallel -j 4 --env PBS_O_WORKDIR --sshloginfile $PBS_NODEFILE \
--workdir $NODE_LOCAL_DIR --transfer --return 'output.{#}' --clean \
`pwd`/simple.py '{#}' '{}' ::: $INPUT_DIR/input.*

# `-j 4` is the number of processors to use per node, will be cluster-specific
# {#} will substitute the process number into the string
# `pwd`/simple.py `{#}` `{}`   this is the command that will be run multiple times
# ::: $INPUT_DIR/input.* all of the files in $INPUT_DIR/ that start with 'input.' 
#     will be substituted into the python call as the second(3rd) argument where the
#     `{}` resides.  These can be simple text files that you use in your 'simple.py'
#     script to pass the parameter sets, filenames, etc.