Skip to content

checkConsistency of a comp document is linear in its model definitions (#505) - #507

Open
matthiaskoenig wants to merge 3 commits into
sbmlteam:developmentfrom
matthiaskoenig:fix-comp-check-linear
Open

matthiaskoenig wants to merge 3 commits into
sbmlteam:developmentfrom
matthiaskoenig:fix-comp-check-linear

Conversation

@matthiaskoenig

Copy link
Copy Markdown
Contributor

Part of #505: the check of a comp document is linear in the number of model definitions instead of quadratic.

Builds on #506, whose commit is the first one of this branch. Please merge #506 first; after that, this pull request shows only its own commit.

Cause

CompSBMLDocumentPlugin::checkConsistency checked every model definition as the model of a dummy document. The dummy was a copy of the whole document, made once per model definition. A document of N model definitions was therefore copied (and destroyed) N times. That is quadratic in N, and it happened even with every check category disabled. A callgrind profile of the issue's example with no checks put 55 % of the instructions into SBMLDocument::SBMLDocument(const SBMLDocument&) and 19 % into its destructor.

Change

The validation itself is unchanged; only the setup of the dummy document changes:

  • One dummy document is copied before the loop. Its comp plugin gets the dummy flags (as in A comp document checks its model definitions on every checkConsistency (#505) #506), and the model of the document is added to its model definitions once.
  • For each model definition, the dummy's model is set to it (setModel copies only that model definition). The dummy's own copy of that model definition is held out of its list during the check and put back at the same position afterwards. During each check the dummy therefore holds the same model and the same model definitions, in the same order, as the per-definition copy did before.
  • The error log of the dummy is cleared before each check, and the UnrequiredPackagePresent/RequiredPackagePresent entries are logged again, as the fresh copy had them.
  • The dummy keeps the documents of the external model definitions it resolved; every per-definition copy resolved them again.

On suggestion 2 of the issue: the comp validators of a document check only its model and its external model definitions, not the content of its model definitions. In the dummy they check the comp constructs (submodels, ports, replacements) of the model definition under check, so they are not redundant and still run.

Timing

The issue's reproduction in C++: one submodel for each of n model definitions with 200 parameters each, setOverrideCompFlattening(true). Built with RelWithDebInfo, single runs.

model definitions all checks, development all checks, this PR no checks, development no checks, this PR flat model, all checks
8 0.050 s 0.039 s 0.012 s 0.003 s 0.023 s
16 0.126 s 0.075 s 0.051 s 0.005 s 0.047 s
32 0.418 s 0.166 s 0.216 s 0.010 s 0.088 s
64 1.538 s 0.358 s 0.970 s 0.022 s 0.177 s
128 6.733 s 0.922 s 4.583 s 0.054 s 0.365 s

What remains with all checks is the core validation of each model definition. Its instruction count (callgrind) grows by 2.14x from 32 to 64 model definitions, against 2.0x for reading the document. The rest of the wall-clock growth comes from the 77k modeling-practice warnings of this artificial document.

Two physiologically based pharmacokinetic (PBPK) models built from many model definitions, checked with the default settings (flattening check included):

model model definitions before after failures
glimepiride_body.xml (3.1 MB) 14 1.671 s 0.768 s identical (1090106, 1090107)
hctz_body.xml (1.7 MB) 15 0.973 s 0.367 s identical (1090106, 1090107)

Tests

  • New test_comp_fail_nested_moddef: three model definitions that reference each other (md2 -> md1 -> md0), with an error inside md1. The test checks that the error is reported exactly once, that the submodel of md1 resolves (no CompSubmodelMustReferenceModel), and that the check leaves the model and the order of the model definitions of the document unchanged.
  • The libcheck suite was not available locally. TestCheckConsistency.cpp (all 7 tests) was compiled against a minimal stand-in for check.h and passes.
  • test_comp_validator passes all cases (280, 14 and 22 checks), built with comp, fbc and layout. It reports no memory errors under valgrind, and TestCheckConsistency.cpp has no leaks.
  • Submodel references to an existing model definition, to a missing one (1020615) and to the main model (1020617) give the same errors as before.

CompSBMLDocumentPlugin::checkConsistency set mCheckingDummyDoc and
mFlattenAndCheck on the plugin of the document it checks, to make the
dummy documents it copies from it skip their model definitions and their
flat model. mCheckingDummyDoc was never reset, and mFlattenAndCheck not
after an error in a model definition, so a second check of the document
and a copy of it skipped the model definitions, and after such an error
also the flat model. The flags are now set on the dummy document only.

Refs sbmlteam#505.
Every modelDefinition was checked in a copy of the whole document, so a
document of N modelDefinitions was copied N times and the check was
quadratic in N, also with every check category disabled. One dummy
document is copied now and used for all modelDefinitions: its model is
swapped for the modelDefinition under check, which is held out of its
modelDefinitions during the check and put back afterwards, and the model
of the document is added to its modelDefinitions once. The dummy also
keeps the documents of the externalModelDefinitions it resolved, which
every copy read again.

Refs sbmlteam#505.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants