我正在尝试在OpenMDAO 2.5.0中并行运行一个简单的数学问题。问题是在http://openmdao.org/twodocs/versions/latest/features/core_features/grouping_components/parallel_group.html处找到的OpenMDAO文档中的示例的改编版本。它具有一些额外的组件和连接,并使用促销代替连接。
from openmdao.api import Problem, IndepVarComp, ParallelGroup, ExecComp, Group, NonlinearBlockGS
prob = Problem()
model = prob.model
model.add_subsystem('p1', IndepVarComp('x1', 1.0), promotes=['x1'])
model.add_subsystem('p2', IndepVarComp('x2', 1.0), promotes=['x2'])
cycle = model.add_subsystem('cycle', Group(), promotes=['*'])
parallel = cycle.add_subsystem('parallel', ParallelGroup(), promotes=['*'])
parallel.add_subsystem('c1', ExecComp(['y1=(-2.0*x1+z)/3']), promotes=['x1', 'y1', 'z'])
parallel.add_subsystem('c2', ExecComp(['y2=(5.0*x2-z)/6']), promotes=['x2', 'y2', 'z'])
cycle.add_subsystem('c3', ExecComp(['z=(3.0*y1+7.0*y2)/10']), promotes=['y1', 'y2', 'z'])
model.add_subsystem('c4', ExecComp(['z2 = y1+y2']), promotes=['z2', 'y1', 'y2'])
cycle.nonlinear_solver = NonlinearBlockGS()
prob.setup(mode='fwd')
prob.set_solver_print(level=2)
prob.run_model()
print(prob['z2'])
print(prob['z'])
print(prob['y1'])
print(prob['y2'])
当我连续运行此代码时,它按预期运行,没有错误。
但是,当我与以下代码并行运行此代码时:
mpirun -n 2 python Test.py
我在第一个过程中遇到此错误:
RuntimeError: The promoted name y1 is invalid because it refers to multiple inputs: [cycle.c3.y1 ,c4.y1]. Access the value from the connected output variable cycle.parallel.c1.y1 instead.
第二个过程中出现此错误:
RuntimeError: The promoted name y2 is invalid because it refers to multiple inputs: [cycle.c3.y2 ,c4.y2]. Access the value from the connected output variable cycle.parallel.c2.y2 instead.
所以我的问题是:为什么这个示例在并行运行而没有连续问题的情况下为什么在提升名称中出现错误?是仅允许在并行运行时使用连接,还是可以提升变量?
答案 0 :(得分:0)
从OpenMDAO V2.5开始,对于如何并行访问问题变量,您必须要格外小心。
如果您查看模型的完整堆栈轨迹,则可以看到调用
时,错误恰好在最后抛出print(prob['y1'])
print(prob['y2'])
这里发生的事情是,您已经设置了模型,使得y1
仅存在于proc 0上,y2
仅存在于proc 1上。然后,您尝试获取不存在的值在该proc上,您会得到(公认的不是很清楚)错误。
您可以通过对脚本进行以下较小的修改来解决此问题:
from openmdao.api import Problem, IndepVarComp, ParallelGroup, ExecComp, Group, NonlinearBlockJac
prob = Problem()
model = prob.model
model.add_subsystem('p1', IndepVarComp('x1', 1.0), promotes=['x1'])
model.add_subsystem('p2', IndepVarComp('x2', 1.0), promotes=['x2'])
cycle = model.add_subsystem('cycle', Group(), promotes=['*'])
parallel = cycle.add_subsystem('parallel', ParallelGroup(), promotes=['*'])
parallel.add_subsystem('c1', ExecComp(['y1=(-2.0*x1+z)/3']), promotes=['x1', 'y1', 'z'])
parallel.add_subsystem('c2', ExecComp(['y2=(5.0*x2-z)/6']), promotes=['x2', 'y2', 'z'])
cycle.add_subsystem('c3', ExecComp(['z=(3.0*y1+7.0*y2)/10']), promotes=['y1', 'y2', 'z'])
model.add_subsystem('c4', ExecComp(['z2 = y1+y2']), promotes=['z2', 'y1', 'y2'])
cycle.nonlinear_solver = NonlinearBlockJac()
prob.setup(mode='fwd')
prob.set_solver_print(level=2)
prob.run_model()
print(prob['z2'])
print(prob['z'])
if prob.model.comm.rank == 0:
print(prob['y1'])
if prob.model.comm.rank == 0:
print(prob['y2'])
这有一些小问题。 1)这意味着您的脚本现在在串行和并行方面有所不同。 2)烦人。因此,我们正在研究一种修复程序,当您尝试在proc上获得no时,将自动进行MPI广播,从而使工作更清洁。该版本将在V2.6中发布。
另一个小音符。我将您的NL解算器更改为NonLinearBlockJac。那是为了可并行工作的Block Jacobi。您也可以并行使用Newton求解器Gauss-Seidel求解器实际上不允许您并行加速。