Skip to content

Commit

Permalink
notebooks
Browse files Browse the repository at this point in the history
  • Loading branch information
dweindl committed Nov 22, 2023
1 parent 6b652ce commit 2c66820
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"from IPython.display import Image\n",
"\n",
"fig = Image(\n",
" filename=(\"../../../documentation/gfx/steadystate_solver_workflow.png\")\n",
" filename=\"../../../documentation/gfx/steadystate_solver_workflow.png\"\n",
")\n",
"fig"
]
Expand Down Expand Up @@ -97,12 +97,9 @@
],
"source": [
"import libsbml\n",
"import importlib\n",
"import amici\n",
"import os\n",
"import sys\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# SBML model we want to import\n",
"sbml_file = \"model_constant_species.xml\"\n",
Expand Down Expand Up @@ -397,7 +394,7 @@
" * `-5`: Error: The model was simulated past the timepoint `t=1e100` without finding a steady state. Therefore, it is likely that the model has not steady state for the given parameter vector.\n",
"\n",
"Here, only the second entry of `posteq_status` contains a positive integer: The first run of Newton's method failed due to a Jacobian, which oculd not be factorized, but the second run (simulation) contains the entry 1 (success). The third entry is 0, thus Newton's method was not launched for a second time.\n",
"More information can be found in`posteq_numsteps`: Also here, only the second entry contains a positive integer, which is smaller than the maximum number of steps taken (<1000). Hence steady state was reached via simulation, which corresponds to the simulated time written to `posteq_time`.\n",
"More information can be found in`posteq_numsteps`: Also here, only the second entry contains a positive integer, which is smaller than the maximum number of steps taken (<1000). Hence, steady state was reached via simulation, which corresponds to the simulated time written to `posteq_time`.\n",
"\n",
"We want to demonstrate a complete failure if inferring the steady state by reducing the number of integration steps to a lower value:"
]
Expand Down Expand Up @@ -951,7 +948,7 @@
}
],
"source": [
"# Singluar Jacobian, use simulation\n",
"# Singular Jacobian, use simulation\n",
"model.setSteadyStateSensitivityMode(\n",
" amici.SteadyStateSensitivityMode.integrateIfNewtonFails\n",
")\n",
Expand Down Expand Up @@ -1207,7 +1204,7 @@
}
],
"source": [
"# Non-singular Jacobian, use simulaiton\n",
"# Non-singular Jacobian, use simulation\n",
"model_reduced.setSteadyStateSensitivityMode(\n",
" amici.SteadyStateSensitivityMode.integrateIfNewtonFails\n",
")\n",
Expand Down
29 changes: 15 additions & 14 deletions python/examples/example_errors.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@
"source": [
"%matplotlib inline\n",
"import os\n",
"from contextlib import suppress\n",
"from pathlib import Path\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"\n",
"import amici\n",
"from amici.petab_import import import_petab_problem\n",
"from amici.petab_objective import simulate_petab, RDATAS, EDATAS\n",
"from amici.petab.petab_import import import_petab_problem\n",
"from amici.petab.simulations import simulate_petab, RDATAS, EDATAS\n",
"from amici.plotting import plot_state_trajectories, plot_jacobian\n",
"import petab\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from pathlib import Path\n",
"from contextlib import suppress\n",
"\n",
"try:\n",
" import benchmark_models_petab\n",
Expand Down Expand Up @@ -153,7 +154,7 @@
" [amici.simulation_status_to_str(rdata.status) for rdata in res[RDATAS]],\n",
")\n",
"assert all(rdata.status == amici.AMICI_SUCCESS for rdata in res[RDATAS])\n",
"print(\"Simulations finished succesfully.\")\n",
"print(\"Simulations finished successfully.\")\n",
"print()\n",
"\n",
"\n",
Expand All @@ -174,7 +175,7 @@
" [amici.simulation_status_to_str(rdata.status) for rdata in res[RDATAS]],\n",
")\n",
"assert all(rdata.status == amici.AMICI_SUCCESS for rdata in res[RDATAS])\n",
"print(\"Simulations finished succesfully.\")"
"print(\"Simulations finished successfully.\")"
]
},
{
Expand Down Expand Up @@ -339,7 +340,7 @@
"**What happened?**\n",
"\n",
"AMICI failed to integrate the forward problem. The problem occurred for only one simulation condition, `condition_step_00_3`. The issue occurred at $t = 429.232$, where the error test failed.\n",
"This means, the solver is unable to take a step of non-zero size without violating the choosen error tolerances."
"This means, the solver is unable to take a step of non-zero size without violating the chosen error tolerances."
]
},
{
Expand Down Expand Up @@ -400,7 +401,7 @@
" [amici.simulation_status_to_str(rdata.status) for rdata in res[RDATAS]],\n",
")\n",
"assert all(rdata.status == amici.AMICI_SUCCESS for rdata in res[RDATAS])\n",
"print(\"Simulations finished succesfully.\")"
"print(\"Simulations finished successfully.\")"
]
},
{
Expand Down Expand Up @@ -457,7 +458,7 @@
"source": [
"**What happened?**\n",
"\n",
"The simulation failed because the initial step-size after an event or heaviside function was too small. The error occured during simulation of condition `model1_data1` after successful preequilibration (`model1_data2`)."
"The simulation failed because the initial step-size after an event or heaviside function was too small. The error occurred during simulation of condition `model1_data1` after successful preequilibration (`model1_data2`)."
]
},
{
Expand Down Expand Up @@ -646,7 +647,7 @@
"id": "62d82971",
"metadata": {},
"source": [
"Considering that `n_par` occurrs as exponent, it's magnitude looks pretty high.\n",
"Considering that `n_par` occurs as exponent, it's magnitude looks pretty high.\n",
"This term is very likely causing the problem - let's check:"
]
},
Expand Down Expand Up @@ -909,7 +910,7 @@
"source": [
"**What happened?**\n",
"\n",
"All given experimental conditions require pre-equilibration, i.e., finding a steady state. AMICI first tries to find a steady state using the Newton solver, if that fails, it tries simulating until steady state, if that also failes, it tries the Newton solver from the end of the simulation. In this case, all three failed. Neither Newton's method nor simulation yielded a steady state satisfying the required tolerances.\n",
"All given experimental conditions require pre-equilibration, i.e., finding a steady state. AMICI first tries to find a steady state using the Newton solver, if that fails, it tries simulating until steady state, if that also fails, it tries the Newton solver from the end of the simulation. In this case, all three failed. Neither Newton's method nor simulation yielded a steady state satisfying the required tolerances.\n",
"\n",
"This can also be seen in `ReturnDataView.preeq_status` (the three statuses corresponds to Newton \\#1, Simulation, Newton \\#2):"
]
Expand Down
8 changes: 4 additions & 4 deletions python/examples/example_jax/ExampleJax.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@
"metadata": {},
"outputs": [],
"source": [
"from amici.petab_import import import_petab_problem\n",
"from amici.petab.petab_import import import_petab_problem\n",
"\n",
"amici_model = import_petab_problem(\n",
" petab_problem, force_compile=True, verbose=False\n",
Expand All @@ -276,7 +276,7 @@
"source": [
"# JAX implementation\n",
"\n",
"For full jax support, we would have to implement a new [primitive](https://jax.readthedocs.io/en/latest/notebooks/How_JAX_primitives_work.html), which would require quite a bit of engineering, and in the end wouldn't add much benefit since AMICI can't run on GPUs. Instead will interface AMICI using the experimental jax module [host_callback](https://jax.readthedocs.io/en/latest/jax.experimental.host_callback.html)."
"For full jax support, we would have to implement a new [primitive](https://jax.readthedocs.io/en/latest/notebooks/How_JAX_primitives_work.html), which would require quite a bit of engineering, and in the end wouldn't add much benefit since AMICI can't run on GPUs. Instead, will interface AMICI using the experimental jax module [host_callback](https://jax.readthedocs.io/en/latest/jax.experimental.host_callback.html)."
]
},
{
Expand All @@ -294,7 +294,7 @@
"metadata": {},
"outputs": [],
"source": [
"from amici.petab_objective import simulate_petab\n",
"from amici.petab.simulations import simulate_petab\n",
"import amici\n",
"\n",
"amici_solver = amici_model.getSolver()\n",
Expand Down Expand Up @@ -341,7 +341,7 @@
"id": "98e819bd",
"metadata": {},
"source": [
"Now we can finally define the JAX function that runs amici simulation using the host callback. We add a `custom_jvp` decorater so that we can define a custom jacobian vector product function in the next step. More details about custom jacobian vector product functions can be found in the [JAX documentation](https://jax.readthedocs.io/en/latest/notebooks/Custom_derivative_rules_for_Python_code.html)"
"Now we can finally define the JAX function that runs amici simulation using the host callback. We add a `custom_jvp` decorator so that we can define a custom jacobian vector product function in the next step. More details about custom jacobian vector product functions can be found in the [JAX documentation](https://jax.readthedocs.io/en/latest/notebooks/Custom_derivative_rules_for_Python_code.html)"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
"\n",
"**Objective:** Give some hints to speed up import and simulation of larger models\n",
"\n",
"This notebook gives some hints that may help to speed up import and simulation of (mostly) larger models. While some of these settings may also yield slight performance improvements for smaller models, other settings may make things slower. The impact may be highly model-dependent (number of states, number of parameters, rate expressions) or system-dependent and it's worthile doing some benchmarking.\n",
"This notebook gives some hints that may help to speed up import and simulation of (mostly) larger models. While some of these settings may also yield slight performance improvements for smaller models, other settings may make things slower. The impact may be highly model-dependent (number of states, number of parameters, rate expressions) or system-dependent, and it's worthwhile doing some benchmarking.\n",
"\n",
"To simulate models in AMICI, a model specified in a high-level format needs to be imported first, as shown in the following figure. This rougly involves the following steps:\n",
"To simulate models in AMICI, a model specified in a high-level format needs to be imported first, as shown in the following figure. This roughly involves the following steps:\n",
"\n",
"1. Generating the ODEs\n",
"2. Computing derivatives\n",
Expand All @@ -21,7 +21,7 @@
"\n",
"![AMICI workflow](https://raw.githubusercontent.com/AMICI-dev/AMICI/master/documentation/gfx/amici_workflow.png)\n",
"\n",
"There are various options to speed up individual steps of this process. Generally, faster import comes with slower simulation and vice versa. During parameter estimation, a model is often imported only once, and then millions of simulations are run. Therefore, faster simulation will easily compensate for slower import (one-off cost). In other cases, many models may to have to be imported, but only few simulations will be executed. In this case, faster import may bee more relevant.\n",
"There are various options to speed up individual steps of this process. Generally, faster import comes with slower simulation and vice versa. During parameter estimation, a model is often imported only once, and then millions of simulations are run. Therefore, faster simulation will easily compensate for slower import (one-off cost). In other cases, many models may to have to be imported, but only few simulations will be executed. In this case, faster import may be more relevant.\n",
"\n",
"In the following, we will present various settings that (may) influence import and simulation time. We will follow the order of steps outlined above.\n",
"\n",
Expand All @@ -35,7 +35,7 @@
"metadata": {},
"outputs": [],
"source": [
"from IPython.core.pylabtools import figsize, getfigs\n",
"from IPython.core.pylabtools import figsize\n",
"import matplotlib.pyplot as plt\n",
"import pandas as pd\n",
"\n",
Expand Down Expand Up @@ -78,7 +78,7 @@
"See also the following section for the case that no sensitivities are required at all.\n",
"\n",
"\n",
"#### Not generating sensivitiy code\n",
"#### Not generating sensitivity code\n",
"\n",
"If only forward simulations of a model are required, a modest import speedup can be obtained from not generating sensitivity code. This can be enabled via the `generate_sensitivity_code` argument of [amici.sbml_import.SbmlImporter.sbml2amici](https://amici.readthedocs.io/en/latest/generated/amici.sbml_import.SbmlImporter.html#amici.sbml_import.SbmlImporter.sbml2amici) or [amici.pysb_import.pysb2amici](https://amici.readthedocs.io/en/latest/generated/amici.pysb_import.html?highlight=pysb2amici#amici.pysb_import.pysb2amici).\n",
"\n",
Expand Down Expand Up @@ -160,7 +160,7 @@
"source": [
"#### Parallelization\n",
"\n",
"For large models or complex model expressions, symbolic computation of the derivatives can be quite time consuming. This can be parallelized by setting the environment variable `AMICI_IMPORT_NPROCS` to the number of parallel processes that should be used. The impact strongly depends on the model. Note that setting this value too high may have a negative performance impact (benchmark!).\n",
"For large models or complex model expressions, symbolic computation of the derivatives can be quite time-consuming. This can be parallelized by setting the environment variable `AMICI_IMPORT_NPROCS` to the number of parallel processes that should be used. The impact strongly depends on the model. Note that setting this value too high may have a negative performance impact (benchmark!).\n",
"\n",
"Impact for a large and a tiny model:"
]
Expand Down Expand Up @@ -241,7 +241,7 @@
"\n",
"Simplification of model expressions can be disabled by passing `simplify=None` to [amici.sbml_import.SbmlImporter.sbml2amici](https://amici.readthedocs.io/en/latest/generated/amici.sbml_import.SbmlImporter.html#amici.sbml_import.SbmlImporter.sbml2amici) or [amici.pysb_import.pysb2amici](https://amici.readthedocs.io/en/latest/generated/amici.pysb_import.html?highlight=pysb2amici#amici.pysb_import.pysb2amici).\n",
"\n",
"Depending on the given model, different simplification schemes may be cheaper or more beneficial than the default. SymPy's simplifcation functions are [well documentated](https://docs.sympy.org/latest/modules/simplify/simplify.html)."
"Depending on the given model, different simplification schemes may be cheaper or more beneficial than the default. SymPy's simplification functions are [well documented](https://docs.sympy.org/latest/modules/simplify/simplify.html)."
]
},
{
Expand Down Expand Up @@ -384,11 +384,11 @@
"source": [
"#### Compiler flags\n",
"\n",
"For most compilers, different machine code optimizations can be enabled/disabled by the `-O0`, `-O1`, `-O2`, `-O3` flags, where a higher number enables more optimizations. For fastet simulation, `-O3` should be used. However, these optimizations come at the cost of increased compile times. If models grow very large, some optimizations (especially with `g++`, see above) become prohibitively slow. In this case, a lower optimization level may be necessary to be able to compile models at all.\n",
"For most compilers, different machine code optimizations can be enabled/disabled by the `-O0`, `-O1`, `-O2`, `-O3` flags, where a higher number enables more optimizations. For faster simulation, `-O3` should be used. However, these optimizations come at the cost of increased compile times. If models grow very large, some optimizations (especially with `g++`, see above) become prohibitively slow. In this case, a lower optimization level may be necessary to be able to compile models at all.\n",
"\n",
"Another potential performance gain can be obtained from using CPU-specific instructions using `-march=native`. The disadvantage is, that the compiled model extension will only run on CPUs supporting the same instruction set. This may be become problematic when attempting to use an AMICI model on a machine other than on which it was compiled (e.g. on hetergenous compute clusters).\n",
"Another potential performance gain can be obtained from using CPU-specific instructions using `-march=native`. The disadvantage is, that the compiled model extension will only run on CPUs supporting the same instruction set. This may be become problematic when attempting to use an AMICI model on a machine other than on which it was compiled (e.g. on heterogeneous compute clusters).\n",
"\n",
"These compiler flags should be set for both, AMICI installation installation and model compilation. \n",
"These compiler flags should be set for both, AMICI installation and model compilation. \n",
"\n",
"For AMICI installation, e.g.,\n",
"```bash\n",
Expand Down Expand Up @@ -475,7 +475,7 @@
"source": [
"#### Using some optimized BLAS\n",
"\n",
"You might have access to some custom [BLAS](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms) optimized for your hardware which might speed up your simulations somewhat. We are not aware of any systematic evaluation and cannot make any recomendation. You pass the respective compiler and linker flags via the environment variables `BLAS_CFLAGS` and `BLAS_LIBS`, respectively."
"You might have access to some custom [BLAS](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms) optimized for your hardware which might speed up your simulations somewhat. We are not aware of any systematic evaluation and cannot make any recommendation. You pass the respective compiler and linker flags via the environment variables `BLAS_CFLAGS` and `BLAS_LIBS`, respectively."
]
},
{
Expand All @@ -487,7 +487,7 @@
"\n",
"A major determinant of simulation time for a given model is the required accuracy and the selected solvers. This has been evaluated, for example, in https://doi.org/10.1038/s41598-021-82196-2 and is not covered further here. \n",
"\n",
"### Adjoint *vs.* forward sensivities\n",
"### Adjoint *vs.* forward sensitivities\n",
"\n",
"If only the objective function gradient is required, adjoint sensitivity analysis are often preferable over forward sensitivity analysis. As a rule of thumb, adjoint sensitivity analysis seems to outperform forward sensitivity analysis for models with more than 20 parameters:\n",
"\n",
Expand Down
Loading

0 comments on commit 2c66820

Please sign in to comment.