为什么并行 运行 时提升的名称无效?
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 求解器实际上不会让您获得并行加速。
我正在尝试 运行 在 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 求解器实际上不会让您获得并行加速。