使用不同的参数运行实验,有效地保存输出



我的任务是:

  • 我有一个用Python编写的程序,它将一组变量(A,B,C(作为输入,并输出两个数字(X,Y(。
  • 我想在大范围的输入(A,B,C(上运行这个程序
    • 我将使用一组给定的变量运行程序称为"运行实验">
  • 我正在使用集群来执行此操作(我在 SLURM 中提交作业(
  • 然后,我想将实验结果保存到单个文件中,例如带有列 [A|B|C|X|Y],其中每一行都是不同实验的输出。

我目前的情况是:

  • 我以以下形式编写了我的程序:

    import io
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option("-f", "--file",action="store", type="string", dest="filename")
    parser.add_option("-a", "--input_a",type="int", dest="a")
    parser.add_option("-b", "--input_b",type="int", dest="b")
    parser.add_option("-c", "--input_c",type="int", dest="c")
    (options, args) = parser.parse_args()
    def F(a,b,c):
    return((a+b, b+c))
    Alice = options.input_a
    Bob = options.input_b
    Carol = options.input_c
    with io.open("results_a_{0}_b_{1}_c_{2}.txt".format(Alice, Bob, Carol), "a") as f:
    (x,y) = F(Alice, Bob, Carol)
    f.write(u"first output = {0}, second output = {1}".format(x,y))
    
  • 这允许我运行一次程序,并将结果保存在单个文件中。

  • 原则上,我可以为一系列 (A,B,C( 提交此作业,获取包含结果的大量文本文件,然后尝试将它们聚合到单个文件中。
  • 但是,我认为这不是最好的处理方式。

我想知道的是:

  • 有没有一种更自然的方式来运行这些实验并将所有结果保存在一个文件中,如果是这样,它是什么?
  • 我应该如何在 SLURM 上提交我的作业集合才能这样做?
    • 我目前正在(有效地(提交下面的脚本,该脚本实际上不起作用:

for a in 1 2 3; do
for b in 10 20 30; do
for c in 100 200 300; do
python toy_experiment.py -a $a -b $b -c $c &
done
done
done
wait

[我很谨慎,我在这里可能还有很多其他地方出错 - 我愿意使用 optparse 以外的其他东西将参数传递给我的程序,以不同的方式保存结果等 - 我的主要目标是有一个可行的解决方案。

TL;博士

您应该研究如何在系统中使用文件锁定,并使用它来安全地访问单个输出文件。

您还应该提交脚本对作业数组进行签名,并让数组中的每个作业运行单个试验。


这里发生了很多事情。

一个重要的问题:计算 F(( 通常需要多长时间?我假设您刚刚写了一个示例,但这是决定解决问题的最佳方法所必需的。

如果每个计算的时间跨度很短,也许您可以运行几个批处理,在单个脚本中聚合多个计算:在示例中,3 个批处理(对于 a==1、a==2 和 a==3(,每个批处理计算 b 和 c 的所有可能实验,并生成 3 个必须在最后聚合的文件。

如果时间跨度很长,那么创建数千个小文件的过载并不是什么大问题。之后将它们连接起来会很容易。

另一件事:将所有作业同时运行在后台,您可能会使一台机器过载。我不知道您如何向 SLURM 请求资源,但可以肯定的是,您将只使用一个节点。并过度使用它。如果那里有其他用户,他们可能会生气。您必须将节点中同时运行的作业数控制为该节点中授予的处理器数。可能,使用 srun 开始计算会有所帮助。

另一种方法是为每个计算创建一个作业。您可以将它们封装在作业数组中。在这种情况下,每个作业只需运行一个试验,无需在后台启动和等待任何操作。

最后,回到您的主要问题:哪种方法是将所有这些信息有效地保存在磁盘中。

创建数千个文件很容易且可行,但不是文件系统的最佳方法。也许您可以访问公共节点中的某些RAMdisk。在计算节点本地存储中写入一个小文件并将该文件复制到公共内存磁盘将效率大大提高。完成所有实验后,您可以轻松汇总结果。缺点是空间通常非常有限(我真的不知道您的数据的实际大小(,并且它将是一个内存中的磁盘:如果电源故障,它可能会丢失。

使用单个文件会是一种更好的方法,但正如 Dmitri Chubarov 指出的那样,您必须利用文件锁定机制。否则,您可能会得到好坏参半的结果。

最后,我认为最适合您的问题的方法是使用某种类似数据库的解决方案。如果您有权访问支持事务的关系数据库,只需创建一个包含所需字段的表,然后让您的代码连接并插入结果。最后提取它们将是轻而易举的。数据库可以是客户端/服务器(MySQL,PostgreSQL,Oracle...(或嵌入式(HSQLDB(。另一种选择是使用一些文件格式,如NetCDF,它正是针对这种科学数据而设计的,并且对并行访问有一些支持。

相关内容

  • 没有找到相关文章