Skip to content

Commit

Permalink
Merge fcfca25 into 956f8fc
Browse files Browse the repository at this point in the history
  • Loading branch information
hschilling committed Jun 29, 2020
2 parents 956f8fc + fcfca25 commit 345857c
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 39 deletions.
4 changes: 0 additions & 4 deletions openmdao/core/driver.py
Expand Up @@ -452,10 +452,6 @@ def _setup_recording(self):

self._rec_mgr.startup(self)

# record the system metadata to the recorders attached to this Driver
for sub in self._problem().model.system_iter(recurse=True, include_self=True):
self._rec_mgr.record_metadata(sub)

def _get_voi_val(self, name, meta, remote_vois, driver_scaling=True, rank=None):
"""
Get the value of a variable of interest (objective, constraint, or design var).
Expand Down
4 changes: 3 additions & 1 deletion openmdao/core/problem.py
Expand Up @@ -25,7 +25,8 @@
from openmdao.solvers.solver import SolverInfo
from openmdao.error_checking.check_config import _default_checks, _all_checks
from openmdao.recorders.recording_iteration_stack import _RecIteration
from openmdao.recorders.recording_manager import RecordingManager, record_viewer_data
from openmdao.recorders.recording_manager import RecordingManager, record_viewer_data, \
record_system_options
from openmdao.utils.record_util import create_local_meta
from openmdao.utils.general_utils import ContainsAll, pad_name, simple_warning, warn_deprecation

Expand Down Expand Up @@ -825,6 +826,7 @@ def final_setup(self):
driver._setup_recording()
self._setup_recording()
record_viewer_data(self)
record_system_options(self)

if self._setup_status < 2:
self._setup_status = 2
Expand Down
8 changes: 0 additions & 8 deletions openmdao/core/system.py
Expand Up @@ -707,14 +707,6 @@ def _final_setup(self, comm, force_alloc_complex=False):

self.set_initial_values()

# Tell all subsystems to record their metadata if they have recorders attached
for sub in self.system_iter(recurse=True, include_self=True):
sub._rec_mgr.record_metadata(sub)

# Also, record to the recorders attached to this System,
# the system metadata for all the subsystems
self._rec_mgr.record_metadata(sub)

def use_fixed_coloring(self, coloring=_STD_COLORING_FNAME, recurse=True):
"""
Use a precomputed coloring for this System.
Expand Down
10 changes: 5 additions & 5 deletions openmdao/docs/features/recording/reading_metadata.rst
Expand Up @@ -21,8 +21,11 @@ a `CaseReader`.
System Options
--------------

Systems record both scaling factors and options within 'scaling_factors' and 'component_options',
respectively, in :code:`system_options`.
All case recorders record the component options and scaling factors for all systems in the model.
These values are accessible using code such as this, where :code:`cr` is a case reader object.

- :code:`cr.system_options['root']['component_options']`
- :code:`cr.system_options['root']['scaling_factors']`

The component options include user-defined options that were defined
through the :code:`system.options.declare` method. By default, everything in options is
Expand All @@ -33,9 +36,6 @@ to record, they can be excluded using the 'options_excludes' recording option on
openmdao.recorders.tests.test_sqlite_recorder.TestFeatureSqliteRecorder.test_feature_recording_system_options
:layout: interleave

.. note::
Each system object must have a recorder explicitly attached in order for its metadata and options to be recorded.


Solver Metadata
---------------
Expand Down
23 changes: 23 additions & 0 deletions openmdao/recorders/recording_manager.py
Expand Up @@ -217,6 +217,12 @@ def _get_all_viewer_data_recorders(problem):
yield r


def _get_all_recorders(problem):
for req in _get_all_requesters(problem):
for r in req._rec_mgr._recorders:
yield r


def record_viewer_data(problem):
"""
Record model viewer data for all recorders that have that option enabled.
Expand All @@ -240,3 +246,20 @@ def record_viewer_data(problem):
viewer_data.pop('abs2prom', None) # abs2prom already recorded in metadata table
for recorder in recorders:
recorder.record_viewer_data(viewer_data)


def record_system_options(problem):
"""
Record the system options for all systems in the model.
Parameters
----------
problem : Problem
The problem for which all its systems' options are to be recorded.
"""
# get all recorders in the problem
recorders = set(_get_all_recorders(problem))
if recorders:
for recorder in recorders:
for sub in problem.model.system_iter(recurse=True, include_self=True):
recorder.record_metadata_system(sub)
4 changes: 0 additions & 4 deletions openmdao/recorders/sqlite_recorder.py
Expand Up @@ -650,10 +650,6 @@ def record_metadata_system(self, recording_requester):
pickled_metadata = sqlite3.Binary(pickled_metadata)

with self.connection as c:
# Because we can have a recorder attached to multiple Systems,
# and because we are now recording System metadata recursively,
# we can store System metadata multiple times. Need to ignore when that happens
# so we don't get database errors. So use OR IGNORE
c.execute("INSERT OR IGNORE INTO system_metadata"
"(id, scaling_factors, component_metadata) "
"VALUES(?,?,?)", (path, scaling_factors, pickled_metadata))
Expand Down
58 changes: 41 additions & 17 deletions openmdao/recorders/tests/test_sqlite_recorder.py
Expand Up @@ -463,41 +463,65 @@ def test_system_record_model_metadata(self):
value = cr.system_options['root']['component_options']['assembled_jac_type']
self.assertEqual(value, 'csc') # quick check only. Too much to check exhaustively

def test_driver_record_model_metadata(self):
def test_record_system_options(self):
# Regardless what object the case recorder is attached to, system options
# should be recorded for all systems in the model

expected_system_options_keys = ['root', 'px', 'pz', 'd1', 'd2', 'obj_cmp', 'con_cmp1', 'con_cmp2']

# Recorder on Driver
prob = om.Problem(model=SellarDerivatives())
prob.setup()

recorder = om.SqliteRecorder("cases.sql")
recorder = om.SqliteRecorder("cases_driver.sql")
prob.driver.add_recorder(recorder)

prob.set_solver_print(level=0)
prob.run_model()
prob.cleanup()

cr = om.CaseReader("cases.sql")
cr = om.CaseReader("cases_driver.sql")
# Quick check to see that keys and values were recorded
for key in ['root', 'px', 'pz', 'd1', 'd2', 'obj_cmp', 'con_cmp1', 'con_cmp2']:
self.assertTrue(key in cr.system_options.keys())
self.assertEqual(sorted(expected_system_options_keys), sorted(cr.system_options.keys()))
value = cr.system_options['root']['component_options']['assembled_jac_type']
self.assertEqual('csc', value) # quick check only. Too much to check exhaustively

# Recorder on Problem
prob = om.Problem(model=SellarDerivatives())
prob.setup()
recorder = om.SqliteRecorder("cases_problem.sql")
prob.add_recorder(recorder)
prob.set_solver_print(level=0)
prob.run_model()
prob.cleanup()
cr = om.CaseReader("cases_problem.sql")
# Quick check to see that keys and values were recorded
self.assertEqual(sorted(expected_system_options_keys), sorted(cr.system_options.keys()))
value = cr.system_options['root']['component_options']['assembled_jac_type']
self.assertEqual(value, 'csc') # quick check only. Too much to check exhaustively

def test_driver_record_metadata(self):
# Recorder on a subsystem
prob = om.Problem(model=SellarDerivatives())
prob.setup()

recorder = om.SqliteRecorder("cases.sql")
prob.driver.add_recorder(recorder)

recorder = om.SqliteRecorder("cases_subsystem.sql")
prob.model.d1.add_recorder(recorder)
prob.set_solver_print(level=0)
prob.run_model()
prob.cleanup()

cr = om.CaseReader("cases.sql")
cr = om.CaseReader("cases_subsystem.sql")
# Quick check to see that keys and values were recorded
for key in ['root', 'px', 'pz', 'd1', 'd2', 'obj_cmp', 'con_cmp1', 'con_cmp2']:
self.assertTrue(key in cr.system_options.keys())
self.assertEqual(sorted(expected_system_options_keys), sorted(cr.system_options.keys()))
value = cr.system_options['root']['component_options']['assembled_jac_type']
self.assertEqual(value, 'csc') # quick check only. Too much to check exhaustively

# Recorder on a solver
prob = om.Problem(model=SellarDerivatives())
prob.setup()
recorder = om.SqliteRecorder("cases_solver.sql")
prob.model.nonlinear_solver.add_recorder(recorder)
prob.set_solver_print(level=0)
prob.run_model()
prob.cleanup()
cr = om.CaseReader("cases_solver.sql")
# Quick check to see that keys and values were recorded
self.assertEqual(sorted(expected_system_options_keys), sorted(cr.system_options.keys()))
value = cr.system_options['root']['component_options']['assembled_jac_type']
self.assertEqual(value, 'csc') # quick check only. Too much to check exhaustively

Expand Down

0 comments on commit 345857c

Please sign in to comment.