在从Python通过qsub提交的集群上运行作业。这有意义吗?

在从Python通过qsub提交的集群上运行作业。这有意义吗?,python,cluster-computing,qsub,Python,Cluster Computing,Qsub,在这种情况下,我正在用Python进行一些计算,根据计算结果,我有一个目标文件列表,这些文件是要传递给第二个程序的候选文件 例如,我有50000个文件,每个文件包含约2000项。我想筛选某些项目,并调用命令行程序对其中一些项目进行计算 这个程序#2可以通过shell命令行使用,但也需要一组冗长的参数。由于性能原因,我必须在集群上运行程序2 现在,我正在运行程序#2 via “subprocess.call(“…”,shell=True) 但我想在将来通过qsub运行它。 我对如何以合理有效的方式

在这种情况下,我正在用Python进行一些计算,根据计算结果,我有一个目标文件列表,这些文件是要传递给第二个程序的候选文件

例如,我有50000个文件,每个文件包含约2000项。我想筛选某些项目,并调用命令行程序对其中一些项目进行计算

这个程序#2可以通过shell命令行使用,但也需要一组冗长的参数。由于性能原因,我必须在集群上运行程序2

现在,我正在运行程序#2 via “
subprocess.call(“…”,shell=True)
但我想在将来通过qsub运行它。 我对如何以合理有效的方式做到这一点没有多少经验

直接从Python脚本编写临时“qsub”文件并通过subprocess()运行它们有意义吗?有没有更好的,也许更通灵的解决方案


欢迎提出任何意见和建议

显然,您已经为自己构建了一个字符串
cmd
,其中包含一个命令,您可以在shell中输入该命令以运行第二个程序。您当前正在使用
subprocess.call(cmd,shell=True)
从Python脚本执行第二个程序(然后在与调用脚本相同的机器上的进程中执行)

我知道您正在询问如何向集群提交作业,以便在集群上而不是在调用机器上运行第二个程序。好的,这非常简单,而且该方法独立于Python,因此没有“pythonic”解决方案,只有一个显而易见的解决方案:-):用一个将繁重的工作推迟到集群的命令替换当前的
cmd

首先,深入研究集群的
qsub
命令的文档(底层批处理系统可能是SGE或LSF,或者其他,您需要获得相应的文档),并尝试找到shell命令行,该命令行可以将您的示例作业正确提交到集群。它可能看起来像
qsub…args。。。cmd
,而
cmd
这里是原始
cmd
字符串的内容。我假设您现在已经拥有了所需的整个qsub命令,让我们称之为
qsubcmd
(您必须自己想出这个命令,我们在这方面无能为力)。现在,在原始Python脚本中需要做的就是调用

subprocess.call(qsubcmd,shell=True)

而不是

subprocess.call(cmd,shell=True)

请注意,
qsub
可能只在极少数机器上工作,通常称为集群的“头节点”。这意味着您想要提交这些作业的Python脚本应该在这台机器上运行(如果不可能,您需要向提交过程添加ssh登录过程,我们不想在这里讨论)


还请注意,如果您有时间,您应该研究您的
子流程
用法的
shell=True
含义。如果您可以绕过
shell=True
,这将是更安全的解决方案。但是,这在您的环境中可能不是问题。

这非常有意义,尽管我会选择另一种解决方案

据我所知,你有一个程序#1,它决定了你的50000个文件中哪一个需要由程序#2计算。 程序#1和#2都是用Python编写的。很好的选择

顺便说一句,我有一个Python模块可能会派上用场:

如果您正在运行与我相同的qsub系统(不知道我们的系统叫什么),那么您不能在提交的脚本上使用命令参数。相反,任何选项都通过
-v
选项提交,该选项将它们放入环境变量中,例如:

[me@local ~] $ python isprime.py 1
1: True 
[me@local ~] $ head -n 5 isprime.py
#!/usr/bin/python
### This is a python script ...
import os
os.chdir(os.environ.get('PBS_O_WORKDIR','.'))

[me@local ~] $ qsub -v isprime='1 2 3' isprime.py
123456.cluster.control.com
[me@local ~]
在这里,
isprime.py
可以使用
argparse
处理命令行参数。然后,您只需要检查脚本是否作为提交的作业运行,然后从环境变量(
os.environ
)检索所述参数

当程序#2被修改为在集群上运行时,程序#1可以通过使用
subprocess.call(['qsub','-v options=…','programme2.py',shell=FALSE)

另一种方法是将数据库(比如SQLite数据库)中的所有文件排队。然后,您可以让程序#1检查数据库中所有未处理的条目,确定结果(运行、不运行、使用特殊选项运行)。 您现在有机会在集群上并行运行程序#2,它只需检查数据库中的文件以进行分析

编辑:当程序#2是可执行文件时

我们不使用python脚本,而是使用一个bash脚本,它获取环境变量并将它们放在程序的命令行上:

#!/bin/bash
cd .
# put options into context/flags etc.
if [ -n $option1 ]; then _opt1="--opt1 $option1"; fi
# we can even define our own defaults
_opt2='--no-verbose'
if [ -n $opt2 ]; then _opt2="-o $opt2"; fi
/path/to/exe $_opt1 $opt2

如果您要使用数据库解决方案,则需要一个python脚本来检查数据库中是否有未处理的文件,将文件标记为正在处理(在单个事务中执行这些操作),获取选项,使用
子流程调用可执行文件,完成后,将文件标记为已完成,检查新文件,等等。

请看这里:非常感谢您的详细解释!不幸的是,程序#2是商业软件,我无法获得源代码。你的脚本看起来很酷,绝对是一个很好的跟踪解决方案!也许我已经可以使用
subprocess.call(['qsub','-voptions=…','programme2.py',shell=FALSE)
,那么。那很有帮助!关于第二种方法:好主意,事实上有关文件的信息已经在SQLite数据库中,只需添加另一列进行排队!听起来很直白,谢谢!:)我将尝试
shell=False