<commit_before>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Tutorial on JIT versus Scipy execution within Parcels"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "This very brief tutorial is meant to highlight the potentially very big difference between the computational time required to run Parcels in JIT (Just-In-Time compliation) versus in Scipy mode.\n",
    "\n",
    "In the code snippet below, we use `AdvectionRK4` to advect 100 particles in the peninsula `FieldSet`. We first do it in JIT mode (by setting `ptype=JITParticle` in the declaration of `pset`) and then we also do it in Scipy mode (by setting `ptype=ScipyParticle` in the declaration of `pset`).\n",
    "\n",
    "In both cases, we advect the particles for 1 hour, with a timestep of 30 seconds. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Compiled JITParticleAdvectionRK4 ==> /var/folders/r2/8593q8z93kd7t4j9kbb_f7p00000gn/T/parcels-501/4de448cefdb0e5792c912beafdd4470e.so\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "jit execution took 0.17 seconds\n",
      "scipy execution took 17.46 seconds\n"
     ]
    }
   ],
   "source": [
    "from parcels import FieldSet, ParticleSet, JITParticle, ScipyParticle\n",
    "from parcels import AdvectionRK4\n",
    "from datetime import timedelta as delta\n",
    "import time\n",
    "\n",
    "fieldset = FieldSet.from_parcels('Peninsula_data/peninsula', allow_time_extrapolation=True)\n",
    "\n",
    "ptype = {'scipy': ScipyParticle, 'jit': JITParticle}\n",
    "\n",
    "for p in ['jit', 'scipy']:\n",
    "    pset = ParticleSet.from_line(fieldset=fieldset, pclass=ptype[p], size=100, start=(0.1, 0.1), finish=(0.1, 0.4))\n",
    "\n",
    "    t0 =time.time()\n",
    "    pset.execute(AdvectionRK4, runtime=delta(hours=1), dt=delta(seconds=30))\n",
    "    print p, 'execution took', format(time.time()-t0, '.2f'), 'seconds'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "As you can see above, **Scipy mode took more than 100 times as long** (0.17 seconds versus 17.46 seconds) as the JIT mode!!\n",
    "\n",
    "This is just an illustrative example, depending on the number of calls to `AdvectionRK4`, the size of the `FieldSet`, the size of the `pset`, the ratio between `dt` and `outputdt` in the `.execute` etc, the difference between JIT and Scipy can vary significantly. However, JIT will almost always be faster!\n",
    "\n",
    "So why does Parcels support both JIT and Scipy mode then? Because Scipy is easier to debug when writing custom kernels, so can provide faster development of new features."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "*As an aside, you may wonder why we use the `time.time` module, and not the timeit module, to time the runs above. That's because it affects the AST of the kernels, causing errors in JIT mode.*"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",<commit_msg>jit vs scipy tutorial now uses the timer module<commit_after>{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tutorial on JIT versus Scipy execution within Parcels"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This very brief tutorial is meant to highlight the potentially very big difference between the computational time required to run Parcels in JIT (Just-In-Time compliation) versus in Scipy mode.\n",
    "\n",
    "In the code snippet below, we use `AdvectionRK4` to advect 100 particles in the peninsula `FieldSet`. We first do it in JIT mode (by setting `ptype=JITParticle` in the declaration of `pset`) and then we also do it in Scipy mode (by setting `ptype=ScipyParticle` in the declaration of `pset`).\n",
    "\n",
    "In both cases, we advect the particles for 1 hour, with a timestep of 30 seconds.\n",
    "\n",
    "To measure the computational time, we use the `timer` module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Compiled JITParticleAdvectionRK4 ==> /var/folders/h0/01fvrmn11qb62yjw7v1kn62r0000gq/T/parcels-503/5ef774699bca6dbc2741379ef921678b.so\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(100%)  Timer root                       : 1.809e+01 s\n",
      "(  0%)    (  0%) Timer fieldset creation : 4.157e-02 s\n",
      "( 95%)    ( 95%) Timer scipy             : 1.723e+01 s\n",
      "(  4%)    (  4%) Timer jit               : 7.917e-01 s\n"
     ]
    }
   ],
   "source": [
    "from parcels import FieldSet, ParticleSet, JITParticle, ScipyParticle\n",
    "from parcels import AdvectionRK4\n",
    "from parcels import timer\n",
    "from datetime import timedelta as delta\n",
    "\n",
    "timer.root = timer.Timer('root')\n",
    "\n",
    "timer.fieldset = timer.Timer('fieldset creation', parent=timer.root)\n",
    "fieldset = FieldSet.from_parcels('Peninsula_data/peninsula', allow_time_extrapolation=True)\n",
    "timer.fieldset.stop()\n",
    "\n",
    "ptype = {'scipy': ScipyParticle, 'jit': JITParticle}\n",
    "ptimer = {'scipy': timer.Timer('scipy', parent=timer.root, start=False),\n",
    "          'jit': timer.Timer('jit', parent=timer.root, start=False)}\n",
    "\n",
    "for p in ['scipy', 'jit']:\n",
    "    pset = ParticleSet.from_line(fieldset=fieldset, pclass=ptype[p], size=100, start=(0.1, 0.1), finish=(0.1, 0.4))\n",
    "\n",
    "    ptimer[p].start()\n",
    "    pset.execute(AdvectionRK4, runtime=delta(hours=1), dt=delta(seconds=30))\n",
    "    ptimer[p].stop()\n",
    "\n",
    "timer.root.stop()\n",
    "timer.root.print_tree()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you can see above, **Scipy mode took more than 20 times as long** (17.2 seconds versus 0.79 seconds) as the JIT mode!!\n",
    "\n",
    "This is just an illustrative example, depending on the number of calls to `AdvectionRK4`, the size of the `FieldSet`, the size of the `pset`, the ratio between `dt` and `outputdt` in the `.execute` etc, the difference between JIT and Scipy can vary significantly. However, JIT will almost always be faster!\n",
    "\n",
    "So why does Parcels support both JIT and Scipy mode then? Because Scipy is easier to debug when writing custom kernels, so can provide faster development of new features."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*As an aside, you may wonder why we use the `time.time` module, and not the timeit module, to time the runs above. That's because it affects the AST of the kernels, causing errors in JIT mode.*"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
{'fraction_non_alphanumeric': 0.15466938463498534, 'fraction_numerical': 0.024971333927888903, 'mean_word_length': 3.0547520661157024, 'pattern_counts': {'":': 85, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5516677', 'n_tokens_mistral': 2921, 'n_tokens_neox': 2753, 'n_words': 811}