请参阅底部添加的示例,他们查明错误比原始错误略好。
我一直试图让附加代码并行运行。此代码旨在模仿我希望在大型集群上运行的更大优化代码的结构。这里的错误出现在我们尝试过的几个不同的脚本中,其中一个脚本并行工作,除非连接是在configure方法的循环中从数组元素连接的组件。这个例子在串行中运行得很好,但是当我运行命令mpirun -n 4 python test2_forParallel_floats.py
时,我得到以下输出:
Traceback (most recent call last):
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/component.py", line 549, in run
self._pre_execute()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/component.py", line 469, in _pre_execute
self._setup()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/assembly.py", line 1701, in _setup
self.setup_variables()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/assembly.py", line 1105, in setup_variables
self._system.setup_variables()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 2387, in setup_variables
super(DriverSystem, self).setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 2122, in setup_variables
sub = list(self.local_subsystems())[0]
IndexError: list index out of range
Traceback (most recent call last):
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/component.py", line 549, in run
self._pre_execute()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/component.py", line 469, in _pre_execute
self._setup()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/assembly.py", line 1701, in _setup
Traceback (most recent call last):
File "test2_forParallel_floats.py", line 170, in <module>
test.run()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/component.py", line 549, in run
self._pre_execute()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/component.py", line 469, in _pre_execute
self._setup()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/assembly.py", line 1701, in _setup
self.setup_variables()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/assembly.py", line 1105, in setup_variables
self.setup_variables()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/assembly.py", line 1105, in setup_variables
self._system.setup_variables()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 2387, in setup_variables
super(DriverSystem, self).setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 2122, in setup_variables
sub = list(self.local_subsystems())[0]
IndexError: list index out of range
self._system.setup_variables()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 2387, in setup_variables
Traceback (most recent call last):
File "test2_forParallel_floats.py", line 170, in <module>
test.run()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/component.py", line 549, in run
super(DriverSystem, self).setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
self._pre_execute()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/component.py", line 469, in _pre_execute
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
self._setup()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/assembly.py", line 1701, in _setup
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 2122, in setup_variables
self.setup_variables()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/assembly.py", line 1105, in setup_variables
self._system.setup_variables()
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 2387, in setup_variables
super(DriverSystem, self).setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub = list(self.local_subsystems())[0]
IndexError: list index out of range
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 433, in setup_variables
sub.setup_variables(resid_state_map)
File "/Users/thomas95/OpenMDAO/openmdao-0.13.0/lib/python2.7/site-packages/openmdao.main-0.13.0-py2.7.egg/openmdao/main/systems.py", line 2122, in setup_variables
sub = list(self.local_subsystems())[0]
IndexError: list index out of range
任何人都可以给我任何见解,为什么这不会并行运行?
注意:注释掉的q
元素也是我们需要的附加功能。一次在这里一件事
from openmdao.main.api import Assembly, Component
from openmdao.lib.datatypes.api import Float, Array, List
from openmdao.lib.drivers.api import DOEdriver, SLSQPdriver, COBYLAdriver, CaseIteratorDriver
from pyopt_driver.pyopt_driver import pyOptDriver
import numpy as np
class component1(Component):
x = Float(iotype='in')
y = Float(iotype='in')
term1 = Float(iotype='out')
a = Float(iotype='in', default_value=1)
def execute(self):
x = self.x
a = self.a
term1 = a*x**2
self.term1 = term1
print "In comp1", self.name, self.a, self.x, self.term1
def list_deriv_vars(self):
return ('x',), ('term1',)
def provideJ(self):
x = self.x
a = self.a
dterm1_dx = 2.*a*x
J = np.array([[dterm1_dx]])
# print 'In comp1, J = %s' % J
return J
class component2(Component):
x = Float(iotype='in')
y = Float(iotype='in')
term1 = Float(iotype='in')
f = Float(iotype='out')
# q = Array(np.zeros(2), iotype='in', dtype='float')
def execute(self):
# y = self.y + self.q[0]
# x = self.x + self.q[1]
y = self.y
x = self.x
term1 = self.term1
f = term1 + x + y**2
# print 'in comp2 q = %s' % self.q
self.f = f
print "In comp2", self.name, self.x, self.y, self.term1, self.f
class summer(Component):
total = Float(iotype='out', desc='sum of all f values')
def __init__(self, size):
super(summer, self).__init__()
self.size = size
self.add('fs', Array(np.zeros(size), iotype='in', desc='f values from all cases'))
def execute(self):
self.total = sum(self.fs)
print 'In summer, fs = %s and total = %s' % (self.fs, self.total)
class assembly(Assembly):
x = Float(iotype='in')
y = Float(iotype='in')
total = Float(iotype='out')
def __init__(self, size):
super(assembly, self).__init__()
self.size = size
for i in range(0, size):
self.add('a_vals_%d' % i, Float(iotype='in'))
# self.add('q_%d' % i, Array(np.zeros(2), iotype='in', dtype='float'))
a = str()
exec("a = self.a_vals_%d" % i)
print 'in init, a_vals_%d = %s' % (i, a)
self.add('fs', Array(np.zeros(size), iotype='out', dtype='float'))
print 'in init, fs = %s' % self.fs
def configure(self):
self.add('driver', SLSQPdriver())
# self.add('driver', pyOptDriver())
# self.driver.optimizer = 'SNOPT'
# self.driver.pyopt_diff = True
#create this first, so we can connect to it
self.add('summer', summer(size=self.size))
self.connect('summer.total', 'total')
for i in range(0, self.size):
a = str()
exec("a = self.a_vals_%d" % i)
print 'in configure, a_vals_%d = %s' % (i, a)
# create instances of components
for i in range(0, self.size):
c1 = self.add('comp1_%d' % i, component1())
c1.missing_deriv_policy = 'assume_zero'
c2 = self.add('comp2_%d'%i, component2())
self.connect('a_vals_%d' % i, 'comp1_%d.a' % i)
self.connect('x', ['comp1_%d.x' % i, 'comp2_%d.x' % i])
self.connect('y', ['comp1_%d.y' % i, 'comp2_%d.y' % i])
self.connect('comp1_%d.term1' % i, 'comp2_%d.term1' % i)
# self.connect('q_%d' % i, 'comp2_%d.q' % i)
self.connect('comp2_%d.f' % i, 'summer.fs[%d]' % i)
self.driver.workflow.add(['comp1_%d' % i, 'comp2_%d' % i])
# self.connect('summer.fs[:]', 'fs[:]')
self.driver.workflow.add(['summer'])
# set up main driver (optimizer)
self.driver.iprint = 1
self.driver.maxiter = 100
self.driver.accuracy = 1.0e-6
self.driver.add_parameter('x', low=-5., high=5.)
self.driver.add_parameter('y', low=0., high=5.)
# for i in range(0, self.size):
# self.driver.add_parameter('q_%d' % i, low=0., high=5.)
self.driver.add_objective('summer.total')
if __name__ == "__main__":
""" the result should be -1 at (x, y) = (-0.5, 0) """
import time
from openmdao.main.api import set_as_top
a_vals = np.array([1., 1., 1., 1.])
test = set_as_top(assembly(size=len(a_vals)))
# test.a_vals = a_vals
# print 'in main, test.a_vals = %s, test.fs = %s' % (test.a_vals, test.fs)
test.x = 2.
test.y = 5
# q = np.tile(np.arange(1., 3.), (4, 1))
for i in range(0, len(a_vals)):
exec('test.a_vals_%d = a_vals[%d]' % (i, i))
# exec('test.q_%d = q[%d]' % (i, i))
# exec('print test.q_%d' % i)
a = str()
exec("a = test.a_vals_%d" % i)
print 'in main, a_vals_%d = %s' % (i, a)
tt = time.time()
test = set_as_top(test)
test.run()
print "Elapsed time: ", time.time()-tt, "seconds"
print 'result = ', test.summer.total
print '(x, y) = (%s, %s)' % (test.x, test.y)
print 'fs = %s' % test.fs
print test.fs
# for i in range(0, len(a_vals)):
# exec('print test.q_%d' % i)
此示例可以更好地显示导致错误的原因。以下脚本以串行或并行方式运行默认驱动程序,但在使用SLSLQPdriver和pyOptDriver与SNOPT时失败。错误如下:
使用SLSQPdriver():AttributeError: 'SerialSystem' object has no attribute 'options'
将pyOptDriver()与SNOPT一起使用:IndexError: index 0 is out of bounds for axis 1 with size 0
结果应该是x * = [0,0,0]时的y * = 0。
编辑:我现在为SNOPT收到一个不同的错误:IOError: Failed to properly open SNOPT_print.out, ierror = 17
。我不确定是什么改变
import numpy as np
import time
from openmdao.main.api import Component, Assembly
from openmdao.lib.datatypes.api import Float, Array
from openmdao.lib.drivers.api import FixedPointIterator, SLSQPdriver, COBYLAdriver
from pyopt_driver.pyopt_driver import pyOptDriver
class SimpleComp(Component):
x = Float(iotype="in")
y = Float(iotype="out")
def execute(self):
# print 'print'
print 'In SimpleComp, x = %s' % self.x
# time.sleep(2) #slow things down to make the parallization more clear
self.y = self.x*self.x
class Summer(Component):
def __init__(self, size):
super(Summer, self).__init__()
self.size = int(size)
for i in xrange(size):
self.add('y_%d'%i, Float(iotype="in"))
self.add('tot', Float(iotype="out"))
def execute(self):
tot = 0
for i in xrange(self.size):
tot += getattr(self, 'y_%d'%i)
self.tot = tot
class Sim(Assembly):
def __init__(self, size):
super(Sim, self).__init__()
# self.add('x', Array(np.zeros(size), dtype='float', iotype='in'))
# self.add('x', Float(iotype='in'))
for i in range(0, size):
self.add('x_%d' % i, Float(iotype='in'))
def configure(self):
#you'll need one process per point
# self.add('driver', SLSQPdriver())
self.add('driver', pyOptDriver())
self.driver.optimizer = 'SNOPT'
self.add('summer', Summer(size))
# print self.x
for i in xrange(size):
# print 'x = ', self.x[i]
self.add('point_%d'%i, SimpleComp())
self.connect('x_%d' % i, 'point_%d.x' % i)
self.connect('point_%d.y'%i, 'summer.y_%d'%i)
self.driver.workflow.add('point_%d'%i)
self.driver.add_parameter('x_%d' % i, high=10, low=-10)
self.driver.workflow.add('summer')
self.driver.add_objective('summer.tot')
if __name__ == "__main__":
from openmdao.main.api import set_as_top
size = 3
x = np.arange(0, size)
# x = 1.
print x
sim = set_as_top(Sim(size))
for i in range(0, size):
exec('sim.x_%d = x[%d]' % (i, i))
st = time.time()
sim.run()
print "runtime: ", time.time() - st
print 'y* = %s' % sim.summer.tot
答案 0 :(得分:2)
所以,我运行你的模型并看到了你所做的相同的事情。从那时起,我就能够成功地运行以下变更(我的修改后的代码如下)。
MPI似乎不支持组件的有限差异。特别是,让它将模型划分为用于有限差分的块,并行地引起一些奇怪的错误。有两种方法可以解决这个问题。我选择为SimpleComp
和Summer
组件定义分析衍生物,因为它们很容易。您还可以将driver.gradient_options.force_fd
设置为True,以使整个模型具有有限差异。
最初你使用的是PyOptDriver,但是对于某些优化器,该驱动程序不能并行工作。具体来说,SNOPT会写出一个文本文件,所以你看到的ioError
是所有3个进程都试图写入同一个文件而不能写入的。我们有PyOptDriver的并行版本(称为mdolab-pyoptsparse),这是我使用的。 OpenMDAO包装器隐藏在pyMission存储库中:
https://github.com/OpenMDAO-Plugins/pyMission
和pyoptsparse可以在这里找到:
https://bitbucket.org/mdolab/pyoptsparse
如果你有这些,你可以在适当的位置提供SNOPT。
最后,我需要更严格地控制并行放置哪些组件,因此我在工作流层次结构中添加了另一个级别。驱动程序parallel_stuff
只包含我们想要并行运行的SimpleComps。然后我将system_type
的{{1}}设置为serial,以便它不会尝试在并行组中放置任何其他内容。
通过这些修复,我让你的模型进行优化并达到(0,0,0)。
driver