为什么并行 运行 时提升的名称无效?

Why are promoted names invalid when running in parallel?

我正在尝试 运行 在 OpenMDAO 2.5.0 中并行解决一个简单的数学问题。问题是在此处找到的 OpenMDAO 文档中示例的改编版本:http://openmdao.org/twodocs/versions/latest/features/core_features/grouping_components/parallel_group.html。它有一些额外的组件和连接,并使用促销而不是连接。

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.

所以我的问题是:为什么这个例子在并行 运行ning 时在提升名称中给出错误,而在串行 运行ning 时却没有问题?是否只允许在并行 运行ning 时使用连接,或者也可以提升变量?

从 OpenMDAO V2.5 开始,您必须小心处理如何并行访问问题变量。

如果您查看模型的完整堆栈轨迹,您会发现错误是在您调用

的最后抛出的
print(prob['y1'])
print(prob['y2'])

这里发生的事情是您设置了模型,以便 y1 仅存在于 proc 0 上并且 y2 仅存在于 proc 1 上。然后您尝试获取不存在的值t 存在于那个 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 上没有的值时,通过自动执行 MPI 广播,让事情更干净地工作。那将在V2.6 中发布。

另外一个小笔记。我将您的 NL 求解器更改为 NonLinearBlockJac. That is for Block Jacobi, which is designed to work in parallel. You could also use the Newton 并行求解器 Gauss-Seidel 求解器实际上不会让您获得并行加速。