Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gradient checks for SBML test suite #2093

Draft
wants to merge 26 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9cf5823
add pytest-xdist to setup.cfg
dilpath May 16, 2023
069dbc7
fail on missing sbml files
dilpath May 16, 2023
ef1347c
add fiddy to sbml test suite
dilpath May 16, 2023
fa7ede0
add fsa gradient checks
dilpath May 16, 2023
1afa02d
run on gha
dweindl May 16, 2023
153de46
fix yaml
dweindl May 16, 2023
175c716
venv
dweindl May 16, 2023
7dff2b4
add fiddy to installAmiciSource; disabling caching for now; fix resha…
dilpath May 18, 2023
99d9a94
Merge branch 'develop' into check_grad_sbml_test_suite
dilpath May 22, 2023
5846b85
Merge branch 'develop' into check_grad_sbml_test_suite
dilpath May 23, 2023
4351ca1
temp skip DAEs (#2102); skip models with no parameters
dilpath May 23, 2023
2a699e2
skip sens.eq. for dae+event
dweindl May 23, 2023
459c1ad
fix semantic suite check
dweindl May 23, 2023
147039b
Fix cblas error for models without solver states in combination with …
dweindl May 23, 2023
98c19f1
Expected failures
dweindl May 23, 2023
fcd467d
Fix DAE check
dweindl May 23, 2023
f278b8e
Fix compilation error for models with events and xdot=0
dweindl May 23, 2023
c9f37da
Unskip 01355
dweindl May 23, 2023
af7fd07
additional eps
dilpath May 23, 2023
7de0769
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl May 25, 2023
731ad05
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl Jun 6, 2023
78e4f3c
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl Jun 26, 2023
cf34778
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl Sep 20, 2023
22722e7
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl Nov 16, 2023
ec5ba6c
Merge branch 'develop' into check_grad_sbml_test_suite
dweindl Feb 27, 2024
179be29
Update test_sbml_semantic_test_suite.yml
dweindl Feb 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/test_sbml_semantic_test_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
- develop
- master
- release**
- check_grad_sbml_test_suite
pull_request:
paths:
- .github/workflows/test_sbml_semantic_test_suite.yml
Expand Down Expand Up @@ -45,6 +46,8 @@ jobs:
uses: ./.github/actions/install-apt-dependencies

- run: AMICI_PARALLEL_COMPILE="" ./scripts/installAmiciSource.sh
- run: |
source build/venv/bin/activate && pip install git+https://github.com/ICB-DCM/fiddy.git
- run: AMICI_PARALLEL_COMPILE="" ./scripts/run-SBMLTestsuite.sh ${{ matrix.cases }}

- name: "Upload artifact: SBML semantic test suite results"
Expand Down
1 change: 1 addition & 0 deletions python/sdist/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ test =
pytest
pytest-cov
pytest-rerunfailures
pytest-xdist
coverage
shyaml
antimony>=2.13
Expand Down
2 changes: 1 addition & 1 deletion scripts/installAmiciSource.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ else
fi

python -m pip install --upgrade pip wheel
python -m pip install --upgrade pip setuptools cmake_build_extension numpy
python -m pip install --upgrade pip setuptools cmake_build_extension numpy git+https://github.com/ICB-DCM/fiddy.git
python -m pip install git+https://github.com/FFroehlich/pysb@fix_pattern_matching # pin to PR for SPM with compartments
AMICI_BUILD_TEMP="${AMICI_PATH}/python/sdist/build/temp" \
python -m pip install --verbose -e "${AMICI_PATH}/python/sdist[petab,test,vis]" --no-build-isolation
Expand Down
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ def pytest_generate_tests(metafunc):
# Get CLI option
cases = metafunc.config.getoption("cases")
if cases:
# iff specific case IDs are given and the SBML semantic test suite is not there, we should fail.
if not SBML_SEMANTIC_CASES_DIR.exists():
raise ValueError(
"The SBML semantic cases are missing. You can install them with "
"'AMICI/scripts/run-SBMLTestsuite.sh'."
)

# Run selected tests
last_id = int(list(get_all_semantic_case_ids())[-1])
test_numbers = sorted(set(parse_selection(cases, last_id)))
Expand Down
89 changes: 81 additions & 8 deletions tests/testSBMLSuite.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
import pandas as pd
import pytest
from amici.constants import SymbolId
from amici.gradient_check import check_derivatives
from fiddy import MethodId, get_derivative
from fiddy.extensions.amici import reshape, run_amici_simulation_to_cached_functions
from fiddy.success import Consistency
from numpy.testing import assert_allclose


Expand Down Expand Up @@ -73,13 +75,29 @@ def test_sbml_testsuite_case(
inplace=True,
)

# TODO remove after https://github.com/AMICI-dev/AMICI/pull/2101
# and https://github.com/AMICI-dev/AMICI/issues/2106
# Don't attempt to generate sensitivity code for models with events+algebraic rules, which will fail
sbml_file = find_model_file(current_test_path, test_id)
sbml_document = sbml.SBMLReader().readSBMLFromFile(str(sbml_file))
sbml_model = sbml_document.getModel()
has_events = sbml_model.getNumEvents() > 0
has_algebraic_rules = any(
rule.getTypeCode() == sbml.SBML_ALGEBRAIC_RULE
for rule in sbml_model.getListOfRules()
)
generate_sensitivity_code = not (has_events and has_algebraic_rules)
# TODO https://github.com/AMICI-dev/AMICI/issues/2109
generate_sensitivity_code &= test_id not in {"01240"}
# ^^^^^^^^

# setup model
model_dir = Path(__file__).parent / "SBMLTestModels" / test_id
model, solver, wrapper = compile_model(
current_test_path,
test_id,
model_dir,
generate_sensitivity_code=test_id in sensitivity_check_cases,
generate_sensitivity_code=generate_sensitivity_code,
)
settings = read_settings_file(current_test_path, test_id)

Expand All @@ -93,19 +111,74 @@ def test_sbml_testsuite_case(
else:
raise RuntimeError("Simulation failed unexpectedly")

# verify
# verify simulation results
simulated = verify_results(
settings, rdata, results, wrapper, model, atol, rtol
)

# record results
write_result_file(simulated, test_id, result_path)

# check sensitivities for selected models
if epsilon := sensitivity_check_cases.get(test_id):
solver.setSensitivityOrder(amici.SensitivityOrder.first)
solver.setSensitivityMethod(amici.SensitivityMethod.forward)
check_derivatives(model, solver, epsilon=epsilon)
# test sensitivities
if not model.getParameters():
pytest.skip("No parameters -> no sensitivities to check")

# TODO see https://github.com/AMICI-dev/AMICI/pull/2101
if not generate_sensitivity_code:
pytest.skip("Sensitivity analysis is known to fail.")
if any(id_ == 0 for id_ in model.idlist):
pytest.skip("Sensitivity analysis for DAE is known to fail.")

solver.setSensitivityOrder(amici.SensitivityOrder.first)
solver.setSensitivityMethod(amici.SensitivityMethod.forward)
# currently only checking "x"/"sx" for FSA
(
amici_function_f,
amici_derivative_f,
structures_f,
) = run_amici_simulation_to_cached_functions(
amici_model=model,
amici_solver=solver,
derivative_variables=["x"],
cache=False,
)
rdata_f = amici.runAmiciSimulation(model, solver)

# solver.setSensitivityMethod(amici.SensitivityMethod.adjoint)
# (
# amici_function_a,
# amici_derivative_a,
# structures_a,
# ) = run_amici_simulation_to_cached_functions(
# amici_model=model,
# amici_solver=solver,
# derivative_variables=["x"],
# cache=False,
# )
# rdata_a = amici.runAmiciSimulation(model, solver)

point = np.asarray(model.getParameters())

derivative = get_derivative(
# can use `_f` or `_a` here, should be no difference
function=amici_function_f,
point=point,
sizes=[1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1],
direction_ids=model.getParameterIds(),
method_ids=[MethodId.FORWARD, MethodId.BACKWARD, MethodId.CENTRAL],
relative_sizes=True,
success_checker=Consistency(rtol=1e-2, atol=1e-4),
)

derivative_fd = reshape(
derivative.value.flat, structures_f["derivative"], sensitivities=True
)["x"]
derivative_fsa = rdata_f.sx
# derivative_asa = rdata_a.sllh # currently None, define some objective?

# could alternatively use a `fiddy.DerivativeCheck` class
if not np.isclose(derivative_fd, derivative_fsa, rtol=5e-2, atol=5e-2).all():
raise ValueError("Gradients were not validated.")

except amici.sbml_import.SBMLException as err:
pytest.skip(str(err))
Expand Down
Loading