{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "70ea9b51",
   "metadata": {},
   "source": [
    "# Compilers\n",
    "\n",
    "By default,\n",
    "the `Simulator` uses the `NumpyCompiler`,\n",
    "which compiles the model to solve as an ODE system.\n",
    "\n",
    "But the compiler can be changed,\n",
    "for instance,\n",
    "for other types of integration,\n",
    "such a stochastic simulations,\n",
    "\n",
    "For large models,\n",
    "we have implemented a `NumbaCompiler`,\n",
    "which compiles the RHS (right hand side) using `numba`,\n",
    "providing a significant speed boost.\n",
    "\n",
    "## NumbaCompiler\n",
    "\n",
    "When integrating a large model,\n",
    "such as `Corbat2018`,\n",
    "which has 82 mass-action reactions between 69 species,\n",
    "it is significantly faster to use the `NumbaCompiler`.\n",
    "\n",
    "Using the default `NumpyCompiler`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "827043d9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 5.72 s, sys: 73.6 ms, total: 5.8 s\n",
      "Wall time: 5.66 s\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from simbio.models.corbat2018 import Corbat2018_extrinsic\n",
    "from simbio.simulator import Simulator\n",
    "\n",
    "t = np.linspace(0, 30_000, 100)\n",
    "sim = Simulator(Corbat2018_extrinsic)\n",
    "%time df = sim.run(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5bde0aaa",
   "metadata": {},
   "source": [
    "To switch to the `NumbaCompiler`,\n",
    "we must import it from `simbio.compilers`,\n",
    "and pass it to `Simulator`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c0099d63",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/docs/checkouts/readthedocs.org/user_builds/simbio/envs/latest/lib/python3.10/site-packages/numba/core/utils.py:612: NumbaExperimentalFeatureWarning: \u001b[1mFirst-class function type feature is experimental\u001b[0m\n",
      "  warnings.warn(\"First-class function type feature is experimental\",\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 10.2 s, sys: 42.2 ms, total: 10.3 s\n",
      "Wall time: 10.3 s\n"
     ]
    }
   ],
   "source": [
    "from simbio.compilers.numba import NumbaCompiler\n",
    "\n",
    "sim = Simulator(Corbat2018_extrinsic, compiler=NumbaCompiler)\n",
    "%time df = sim.run(t)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c186d7e4",
   "metadata": {},
   "source": [
    "The first run is slower,\n",
    "as it includes the `numba` compilation time.\n",
    "But subsequent runs are lightning fast,\n",
    "as the compilation is cached:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e90a6939",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 365 ms, sys: 3.91 ms, total: 369 ms\n",
      "Wall time: 368 ms\n"
     ]
    }
   ],
   "source": [
    "%time df = sim.run(t)"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "text_representation": {
    "extension": ".md",
    "format_name": "myst",
    "format_version": 0.13,
    "jupytext_version": "1.14.0"
   }
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "source_map": [
   12,
   39,
   47,
   53,
   58,
   65
  ]
 },
 "nbformat": 4,
 "nbformat_minor": 5
}