0

我的任务是:

  • 我有一个用 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 以外的其他方法将参数传递给我的程序,以不同的方式保存结果等-我的主要目标是一个可行的解决方案。]

4

1 回答 1

0

TL;博士

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

您还应该使用作业数组提交脚本,并让数组中的每个作业运行一个实验。


这里发生了很多事情。

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

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

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

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

另一种方法是为每个计算创建一个作业。您可以将它们封装在作业数组中。在这种情况下,您将只对每个作业运行一个实验,并且您不必在后台启动和等待任何内容。

最后,解决您的主要问题:这是将所有这些信息有效地保存在磁盘中的最佳方式。

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

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

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

于 2018-07-06T09:31:11.397 回答