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

时间:2018-07-05 12:59:59

标签: python cluster-computing slurm experimental-design

我的任务是:

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

1 个答案:

答案 0 :(得分:0)

TL; DR

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

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


这里发生了很多事情。

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

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

如果时间跨度很长,那么创建数千个小文件的负担就不大了。然后将它们串联起来很容易。

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

另一种方法是为每个计算创建一个作业。您可以将它们封装在作业数组中。在这种情况下,每个作业只需要运行一个实验,而不必在后台开始等待任何事情。

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

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

使用单个文件是一种更好的方法,但是正如Dmitri Chubarov指出的那样,您必须使用文件锁定机制。否则,您可能会面临混合结果的风险。

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