在 OpenMDAO 的 ExecComp 中,shape_by_conn 与 has_diag_partials 兼容吗?
In OpenMDAO's ExecComp, is shape_by_conn compatible with has_diag_partials?
我有一个执行简单操作的 om.ExecComp
:
"d_sq = x**2 + y**2"
其中 x
、y
和 d_sq
始终是一维 np.array
。我希望能够在不分配大型密集矩阵的情况下将其用于大型阵列。我还希望根据连接的形状配置阵列的长度。
但是,如果我指定 x={"shape_by_conn": True}
而不是 x={"shape":100000}
,即使我也有 has_diag_partials=True
,它也会尝试分配一个 100000^2 数组。有没有办法让这两个选项兼容?
首先,我会注意到您使用 ExecComp
有点超出其设计预期目的。这并不是说你是完全无效的东西,但一般来说 ExecComp 是为小型、廉价的计算而设计的。向它传递巨型数组不是我们要测试的。
话虽这么说,我想你想要的会奏效。当您在此使用 shape_by_conn
时,您需要确保调整输入和输出的大小。我提供了一个示例,以及一个手动定义的组件来执行相同的操作。由于您的方程式非常简单,因此总体上会更快一些。
import numpy as np
import openmdao.api as om
class SparseCalc(om.ExplicitComponent):
def setup(self):
self.add_input('x', shape_by_conn=True)
self.add_input('y', shape_by_conn=True)
self.add_output('d_sq', shape_by_conn=True, copy_shape='x')
def setup_partials(self):
# when using shape_by_conn, you need to delcare partials
# in this secondary method
md = self.get_io_metadata(iotypes='input')
# everything should be the same shape, so just need this one
x_shape = md['x']['shape']
row_col = np.arange(x_shape[0])
self.declare_partials('d_sq', 'x', rows=row_col, cols=row_col)
self.declare_partials('d_sq', 'y', rows=row_col, cols=row_col)
def compute(self, inputs, outputs):
outputs['d_sq'] = inputs['x']**2 + inputs['y']**2
def compute_partials(self, inputs, J):
J['d_sq', 'x'] = 2*inputs['x']
J['d_sq', 'y'] = 2*inputs['y']
if __name__ == "__main__":
p = om.Problem()
# use IVC here, because you have to have something connected to
# in order to use shape_by_conn. Normally IVC is not needed
ivc = p.model.add_subsystem('ivc', om.IndepVarComp(), promotes=['*'])
ivc.add_output('x', 3*np.ones(10))
ivc.add_output('y', 2*np.ones(10))
# p.model.add_subsystem('sparse_calc', SparseCalc(), promotes=['*'])
p.model.add_subsystem('sparse_exec_calc',
om.ExecComp('d_sq = x**2 + y**2',
x={'shape_by_conn':True},
y={'shape_by_conn':True},
d_sq={'shape_by_conn':True,
'copy_shape':'x'},
has_diag_partials=True),
promotes=['*'])
p.setup(force_alloc_complex=True)
p.run_model()
如果您仍然发现这没有按预期工作,请随时 submit a bug report 使用一个可以清楚地显示问题的测试用例(即会引发您看到的错误)。在这种情况下,提供的手动组件可以作为解决方法。
我有一个执行简单操作的 om.ExecComp
:
"d_sq = x**2 + y**2"
其中 x
、y
和 d_sq
始终是一维 np.array
。我希望能够在不分配大型密集矩阵的情况下将其用于大型阵列。我还希望根据连接的形状配置阵列的长度。
但是,如果我指定 x={"shape_by_conn": True}
而不是 x={"shape":100000}
,即使我也有 has_diag_partials=True
,它也会尝试分配一个 100000^2 数组。有没有办法让这两个选项兼容?
首先,我会注意到您使用 ExecComp
有点超出其设计预期目的。这并不是说你是完全无效的东西,但一般来说 ExecComp 是为小型、廉价的计算而设计的。向它传递巨型数组不是我们要测试的。
话虽这么说,我想你想要的会奏效。当您在此使用 shape_by_conn
时,您需要确保调整输入和输出的大小。我提供了一个示例,以及一个手动定义的组件来执行相同的操作。由于您的方程式非常简单,因此总体上会更快一些。
import numpy as np
import openmdao.api as om
class SparseCalc(om.ExplicitComponent):
def setup(self):
self.add_input('x', shape_by_conn=True)
self.add_input('y', shape_by_conn=True)
self.add_output('d_sq', shape_by_conn=True, copy_shape='x')
def setup_partials(self):
# when using shape_by_conn, you need to delcare partials
# in this secondary method
md = self.get_io_metadata(iotypes='input')
# everything should be the same shape, so just need this one
x_shape = md['x']['shape']
row_col = np.arange(x_shape[0])
self.declare_partials('d_sq', 'x', rows=row_col, cols=row_col)
self.declare_partials('d_sq', 'y', rows=row_col, cols=row_col)
def compute(self, inputs, outputs):
outputs['d_sq'] = inputs['x']**2 + inputs['y']**2
def compute_partials(self, inputs, J):
J['d_sq', 'x'] = 2*inputs['x']
J['d_sq', 'y'] = 2*inputs['y']
if __name__ == "__main__":
p = om.Problem()
# use IVC here, because you have to have something connected to
# in order to use shape_by_conn. Normally IVC is not needed
ivc = p.model.add_subsystem('ivc', om.IndepVarComp(), promotes=['*'])
ivc.add_output('x', 3*np.ones(10))
ivc.add_output('y', 2*np.ones(10))
# p.model.add_subsystem('sparse_calc', SparseCalc(), promotes=['*'])
p.model.add_subsystem('sparse_exec_calc',
om.ExecComp('d_sq = x**2 + y**2',
x={'shape_by_conn':True},
y={'shape_by_conn':True},
d_sq={'shape_by_conn':True,
'copy_shape':'x'},
has_diag_partials=True),
promotes=['*'])
p.setup(force_alloc_complex=True)
p.run_model()
如果您仍然发现这没有按预期工作,请随时 submit a bug report 使用一个可以清楚地显示问题的测试用例(即会引发您看到的错误)。在这种情况下,提供的手动组件可以作为解决方法。