Python 使用Concurrent.Futures.ProcessPoolExecutor运行同步&;独立ABAQUS模型

Python 使用Concurrent.Futures.ProcessPoolExecutor运行同步&;独立ABAQUS模型,python,multiprocessing,python-multiprocessing,concurrent.futures,abaqus,Python,Multiprocessing,Python Multiprocessing,Concurrent.futures,Abaqus,我希望总共运行nAnalysis=25Abaqus模型,每个模型使用X个内核,并且我可以同时运行这些模型中的nParallelLoops=5。如果当前5项分析中的一项完成,则应开始另一项分析,直到完成所有分析 我根据1和2中发布的解决方案实现了下面的代码。然而,我遗漏了一些东西,因为所有nAnalysis都试图“一次”开始,代码死锁,并且没有任何分析完成,因为其中许多人可能希望使用与已开始分析使用的内核相同的内核 def runABQfile(*args): 导入子流程 导入操作系统 inp

我希望总共运行nAnalysis=25Abaqus模型,每个模型使用X个内核,并且我可以同时运行这些模型中的nParallelLoops=5。如果当前5项分析中的一项完成,则应开始另一项分析,直到完成所有分析

我根据12中发布的解决方案实现了下面的代码。然而,我遗漏了一些东西,因为所有nAnalysis都试图“一次”开始,代码死锁,并且没有任何分析完成,因为其中许多人可能希望使用与已开始分析使用的内核相同的内核

  • def runABQfile(*args):
    导入子流程
    导入操作系统
    inpFile,path,jobVars=args
    prcStr1=(路径+'/runJob.sh')
    进程=子进程。检查调用(prcStr1,stdin=None,stdout=None,stderr=None,shell=True,cwd=path)
    def safeABQrun(*参数):
    导入操作系统
    尝试:
    runABQfile(*args)
    例外情况除外,如e:
    打印(“胎面花纹错误:%s runABQfile(*%r)”%(e,args))
    定义错误功能(ppos,*args):
    导入操作系统
    从concurrent.futures导入ProcessPoolExecutor
    从concurrent.futures导入完成
    从concurrent.futures导入等待
    以ProcessPoolExecutor(max_workers=nParallelLoops)作为执行器:
    future_to_file=dict((executor.submit(safeABQrun,inpFiles[k],aPath[k],jobVars),k)范围内的k(0,n分析))#5个节点
    等待(future\u to\u file,timeout=None,在='ALL\u COMPLETED'时返回\u)
    
    到目前为止,我能够运行该功能的唯一方法是修改
    errFunction
    ,以便在以下时间使用5个分析。但是,这种方法有时会导致每个组(每个
    ProcessPoolExecutor
    调用)中的一个分析比其他4个分析花费更长的时间,因此,即使资源(核心)可用,下一组5个分析也不会启动。最终,完成所有25款车型需要更多的时间

    def errFunction(ppos,*args):
    导入操作系统
    从concurrent.futures导入ProcessPoolExecutor
    从concurrent.futures导入完成
    从concurrent.futures导入等待
    #第一组
    以ProcessPoolExecutor(max_workers=nParallelLoops)作为执行器:
    future_to_file=范围(0,5)内k的dict((executor.submit(safeABQrun,inpFiles[k],aPath[k],jobVars),k))#5个节点
    等待(future\u to\u file,timeout=None,在='ALL\u COMPLETED'时返回\u)
    #第2组
    以ProcessPoolExecutor(max_workers=nParallelLoops)作为执行器:
    future_to_file=dict((executor.submit(safeABQrun,inpFiles[k],aPath[k],jobVars),k)表示范围(5,10)内的k个节点)#5
    等待(future\u to\u file,timeout=None,在='ALL\u COMPLETED'时返回\u)
    #第3组
    以ProcessPoolExecutor(max_workers=nParallelLoops)作为执行器:
    future_to_file=dict((executor.submit(safeABQrun,inpFiles[k],aPath[k],jobVars),k)范围内的k(10,15))#5个节点
    等待(future\u to\u file,timeout=None,在='ALL\u COMPLETED'时返回\u)
    #第4组
    以ProcessPoolExecutor(max_workers=nParallelLoops)作为执行器:
    future_to_file=范围(15,20)内k的dict((executor.submit(safeABQrun,inpFiles[k],aPath[k],jobVars),k))#5个节点
    等待(future\u to\u file,timeout=None,在='ALL\u COMPLETED'时返回\u)
    #第5组
    以ProcessPoolExecutor(max_workers=nParallelLoops)作为执行器:
    future_to_file=dict((executor.submit(safeABQrun,inpFiles[k],aPath[k],jobVars),k)范围内的k(20,25))#5个节点
    等待(future\u to\u file,timeout=None,在='ALL\u COMPLETED'时返回\u)
    
    我试着使用
    as_completed
    函数,但它似乎也不起作用

    请你帮我找出正确的并行化方法,这样我就可以运行一个Nanallysis,同时运行nParallelLoops? 非常感谢你的帮助。 我正在使用Python 2.7

    最好的, 大卫P


    2016年7月30日更新


    我在
    safeABQrun
    中引入了一个循环,用于管理5个不同的“队列”。循环是必要的,以避免当另一个节点仍在运行时,分析尝试在节点中运行。在开始任何实际分析之前,分析将预先配置为在请求的节点之一中运行

    def safeABQrun(*列表参数):
    导入操作系统
    输入文件、路径、作业变量=列表参数
    nA=len(inp文件)
    对于范围(0,nA)内的k:
    args=(输入文件[k],路径[k],作业变量[k])
    尝试:
    runABQfile(*args)#实际运行函数
    例外情况除外,如e:
    打印(“胎面花纹错误:%s runABQfile(*%r)”%(e,args))
    定义错误功能(ppos,*args):
    以ProcessPoolExecutor(max_workers=nParallelLoops)作为执行器:
    期货=清单参数中inpF、aPth、jVrs、k的dict((执行人提交(安全ABQRUN、inpF、aPth、jVrs)、k)#5个节点
    对于已完成的f(期货):
    打印(“|===完成处理序列%d===|%f])
    如果f.exception()不是无:
    打印(“%r”生成了一个异常:%s”“(未来[f],f.exception())
    
    我觉得没问题,但我无法按原样运行您的代码。试一试简单得多的东西,然后添加一些东西,直到“问题”出现,怎么样?例如,下面是否显示了您想要的行为类型?它在我的机器上运行,但我正在运行Python 3.5.2。您说您正在运行2.7,但Python 2中不存在并发的期货,因此如果您使用2.7,您必须运行库的某个后台端口,问题可能就出在这一点上。尝试以下内容有助于回答是否是这种情况:

    from concurrent.futures import ProcessPoolExecutor, wait, as_completed
    
    def worker(i):
        from time import sleep
        from random import randrange
        s = randrange(1, 10)
        print("%d started and sleeping for %d" % (i, s))
        sleep(s)
    
    if __name__ == "__main__":
        nAnalysis = 25
        nParallelLoops = 5
        with ProcessPoolExecutor(max_workers=nParallelLoops) as executor:
            futures = dict((executor.submit(worker, k), k) for k in range(nAnalysis))
            for f in as_completed(futures):
                print("got %d" % futures[f])
    
    典型输出:

    0 started and sleeping for 4
    1 started and sleeping for 1
    2 started and sleeping for 1
    3 started and sleeping for 6
    4 started and sleeping for 5
    5 started and sleeping for 9
    got 1
    6 started and sleeping for 5
    got 2
    7 started and sleeping for 6
    got 0
    8 started and sleeping for 6
    got 4
    9 started and sleeping for 8
    got 6
    10 started and sleeping for 9
    got 3
    11 started and sleeping for 6
    got 7
    12 started and sleeping for 9
    got 5
    ...
    

    我在
    safeABQrun
    中引入了一个循环,用于管理5个不同的“队列”。循环是必要的,以避免