diff --git a/doc/co_recipe.rst b/doc/co_recipe.rst index 80fb9d47e1989f57c8a32d9cec652d4ebde0fb9d..be22cae55d0f34ae019485cad4ead66f06a19184 100644 --- a/doc/co_recipe.rst +++ b/doc/co_recipe.rst @@ -52,13 +52,16 @@ The steps of building a simulation from a recipe are: for more information about the cells assigned to it. .. Note:: - An example of how performance considerations impact Arbor's architecture: you will notice cell kind and cell description are separately added to a recipe. Consider the following conversation between an Arbor simulation, recipe and hardware back-end: + An example of how performance considerations impact Arbor's architecture: + you will notice cell kind and cell description are separately added to a recipe. + Consider the following conversation between an Arbor simulation, recipe and hardware back-end: | Simulator: give me cell 37. | Recipe: here you go, it's of C++ type s3cr1ts4uc3. | Simulator: wot? What is the cell kind for cell 37? | Recipe: it's a foobar. - | Simulator: Okay. Cell group implementations: which one of you lot deals with foobars? + | Simulator: Okay. + | Cell group implementations: which one of you lot deals with foobars? | Foobar_GPUFTW_lolz: That'd be me, if we've got GPU enabled. | Simulator: Okay it's up to you then to deal with this s3cr1ts4uc3 object. diff --git a/doc/cpp_cable_cell.rst b/doc/cpp_cable_cell.rst index 6e2db22ee3b5e43f20d26246e24bd19ea3400d55..cab2b45a57a68fba92fdf4e2114c170610014c16 100644 --- a/doc/cpp_cable_cell.rst +++ b/doc/cpp_cable_cell.rst @@ -142,7 +142,7 @@ by two stitches: stitched_morphology stitched(std::move(builder)); cable_cell cell(stitched.morphology(), stitched.labels()); - cell.paint("soma", "hh"); + cell.paint("\"soma\"", "hh"); .. _locsets-and-regions: @@ -287,7 +287,7 @@ Global properties .. cpp:member:: bool coalesce_synapses when synapse dynamics are sufficiently simple, the states of synapses within - the same discretized element can be combined for better performance. this + the same discretised element can be combined for better performance. this is true by default. .. cpp:member:: std::unordered_map<std::string, int> ion_species diff --git a/doc/cpp_recipe.rst b/doc/cpp_recipe.rst index ef3d121409b25dc3cc002e992785bc32fe21ad81..a71c290f38b11e24897066d0ae6997234d3cc3fc 100644 --- a/doc/cpp_recipe.rst +++ b/doc/cpp_recipe.rst @@ -126,7 +126,7 @@ Recipe Returns a vector containing (in order) all the probes on a given cell `gid`. - By default throws :cpp:type:`std::logic_error`. + By default returns an empty vector. .. cpp:function:: virtual std::any get_global_properties(cell_kind) const diff --git a/doc/gs_single_cell.rst b/doc/gs_single_cell.rst index ece7dc599d7343dd840b1dc9de612e72501ab1f8..75b6f89ea664372e9801524d6ebdeb6c5372218f 100644 --- a/doc/gs_single_cell.rst +++ b/doc/gs_single_cell.rst @@ -16,11 +16,11 @@ obtain some documentation. .. _single_soma: -Single compartment cell with HH dynamics +Single segment cell with HH dynamics ---------------------------------------------------- The most trivial representation of a cell in Arbor is to model the entire cell as a -cylinder. The following example shows the steps required to construct a model of a +single cylinder. The following example shows the steps required to construct a model of a cylindrical cell with radius 3 μm, Hodgkin–Huxley dynamics and a current clamp stimulus, then run the model for 30 ms. @@ -29,7 +29,7 @@ define a cell with branching "cable" morphology is a ``cable_cell``, which holds description of the cell's morphology, named regions and locations on the morphology, and descriptions of ion channels, synapses, spike detectors and electrical properties. -Our "single-compartment HH cell" has a simple morphology and dynamics, so the steps to +Our "single-segment HH cell" has a simple morphology and dynamics, so the steps to create the ``cable_cell`` that represents it are as follows: .. code-block:: python @@ -51,53 +51,52 @@ create the ``cable_cell`` that represents it are as follows: cell.place('"center"', arbor.iclamp( 10, 2, 0.8)) cell.place('"center"', arbor.spike_detector(-10)) - Let's unpack that. Step **(1)** above shows how the cell is represented using a :class:`arbor.segment_tree` to which a single segment is added. Arbor's cell morphologies are constructed from a -segment tree which is a list of segments, which are tapered cones with a *tag*. -:meth:`arbor.segment_tree.append` takes 4 arguments, starting with -the parent segment. The first segment added has no parent however, which is made clear by +:ref:`segment tree<morph-segment_tree>` which is a list of segments, which are tapered +cones with a *tag*. :meth:`arbor.segment_tree.append` takes 4 arguments, starting with +the parent segment. The first segment added has no parent, which is made clear by using :class:`arbor.mnpos`. Then two :class:`arbor.mpoint` s are supplied, the proximal -and distal endpoints of the segment. Finally, an integer value can be supplied to tag the +and distal endpoints of the segment. Finally, an integer value is supplied to tag the segment for future reference. In step **(2)** a dictionary of labels is created using :class:`arbor.label_dict<arbor.label_dict>`. -Cell builders need to refer to *regions* and *locations* on a cell -morphology. Arbor uses a domains specific language (DSL) to describe regions and -locations, which are given labels. We add two labels: +Cell builders need to refer to *regions* and *locations* on a cell morphology. Arbor uses a domain +specific language (DSL) to describe regions and locations, which are given labels. We add two labels: -* ``soma`` defines a *region* with ``(tag 2)``. Note that this corresponds to the +* ``soma`` defines a *region* with ``(tag 1)``. Note that this corresponds to the ``tag`` parameter that was used to define the single segment in step (1). * ``center`` defines a *location* at ``(location 0 0.5)``, which is the mid point ``0.5`` - of branch ``0``, which corresponds to the center of the soma on the morphology defined in Step (1). + of branch ``0``, which corresponds to the center of the soma on the morphology defined in step (1). In step **(3)** a :class:`arbor.cable_cell` is constructed by combining the segment tree with the named regions and locations. * "Cell-wide" properties are set through :meth:`arbor.cable_cell.set_properties`. Here, - the initial membrane potential everywhere on the cell is set to -40 mV. + the initial membrane potential is set to -40 mV everywhere on the cell. * Properties can also be set to a region of the cell, which Arbor calls 'painting'. This is meant to convey placement is not precise: we wouldn't want to manually place ion channels all over the surface of the cell. :meth:`arbor.cable_cell.paint` lets us instruct Arbor to use HH dynamics on the region we've labelled soma and sort the details out for us. -* Other properties we do want to :meth:`arbor.cable_cell.place<arbor.cable_cell.place>` - in a precise :class:`arbor.location<arbor.location>`. We place two things: - an :class:`arbor.iclamp<arbor.iclamp>` with a duration of 2 ms and a current of - 0.8 nA, starting at 10 ms. Then, add an :class:`arbor.spike_detector<arbor.spike_detector>` - with a threshold of -10 mV to the location we've labelled 'center'. - -Single cell network +* Other properties should be added to the cell on a precise :class:`arbor.location`. This is + done using the :meth:`arbor.cable_cell.place<arbor.cable_cell.place>` method. + We place a current stimulus :class:`arbor.iclamp<arbor.iclamp>` with a duration of 2 ms + and a current of 0.8 nA, starting at 10 ms on the location we've labelled 'center'. We also + place a :class:`arbor.spike_detector<arbor.spike_detector>` with a threshold of -10 mV on the + same location. + +Single cell model ---------------------------------------------------- -Great, we have defined our cell! Now, let's move to the network. Arbor can simulate -networks with multiple individual cells, connected together in a network. Single cell -models do not require the full *recipe* interface used to describing such network models, -with many unique cells, network and gap junctions. Arbor provides a -:class:`arbor.single_cell_model<arbor.single_cell_model>` helper that wraps a cell description, -and provides an interface for recording potentials and running the simulation. +Great, we have defined our cell! Now, let's move on to the simulation. Arbor is able to simulate +networks with multiple individual cells; this requires a *recipe* to describe the cells, +connections, gap junctions, etc. However, for single cell models, arbor does not require the recipe +to be provided by the user. Arbor provides a :class:`arbor.single_cell_model<arbor.single_cell_model>` +helper that wraps a cell description and creates a recipe under the hood, providing an interface for +recording potentials and running the simulation more easily. .. code-block:: python @@ -116,16 +115,15 @@ with our single-compartment cell. In step **(5)** a :meth:`arbor.single_cell_model.probe()<arbor.single_cell_model.probe>` is used to record variables from the model. Three pieces of information are provided: the type of quantity we want probed (voltage), the location where we want to -probe ('center'), and the frequency at which we want to sample (10kHz). +probe ('"center"'), and the frequency at which we want to sample (10kHz). Finally, step **(6)** starts the actual simulation for a duration of 30 ms. Results ---------------------------------------------------- -Our cell and network are defined; we have ran the simulation. However, we have not looked -at any results! We have added two things that should have recorded something, a -spike_detector and a voltage probe. Let's see what they have produced! +Our cell and model have been defined and we have run our simulation. However, we have not seen any +results! Let's take a look at what the spike detector and a voltage probes from our model have produced. .. code-block:: python @@ -144,12 +142,11 @@ spike_detector and a voltage probe. Let's see what they have produced! seaborn.relplot(data=df, kind="line", x="t/ms", y="U/mV").savefig('single_cell_model_result.svg') In step **(7)** we access :meth:`arbor.single_cell_model.spikes<arbor.single_cell_model.spikes>` -to access the spike time. A single spike at a little over 10 -ms should be printed, which matches the stimulus we have provided in step (3). +to access the spike time. A single spike at a little over 10 ms should be printed, +which matches the stimulus we have provided in step (3). The other measurement we have is that of the potential, which we plot in step **(8)**. -Arbor stores sampled quantities under -:meth:`arbor.single_cell_model.traces<arbor.single_cell_model.traces>`. +Arbor stores sampled quantities under :meth:`arbor.single_cell_model.traces<arbor.single_cell_model.traces>`. You should be seeing something like this: .. figure:: images/single_cell_model_result.svg diff --git a/doc/in_build_install.rst b/doc/in_build_install.rst index 9aad7293aa5949f8339267c10604781e6924f122..3f05513358e456efe99b16f4059c846694ae19f0 100644 --- a/doc/in_build_install.rst +++ b/doc/in_build_install.rst @@ -6,7 +6,7 @@ Build and install from source This guide covers building and installing Arbor using CMake, which is the recommended method for configuring Arbor for HPC applications and developers. We start with an overview of the building process, and the various options available to customize the build. -Then installation and running on `HPC clusters <cluster_>`_ is covered, followed by a `troubleshooting guide <troubleshooting_>`_ for common build problems. +Then we cover installing and running on `HPC clusters <cluster_>`_, followed by a `troubleshooting guide <troubleshooting_>`_ for common build problems. .. note:: To get help in case of problems installing Arbor, please make an issue on the Arbor `Github issues <https://github.com/arbor-sim/arbor/issues>`_ page. diff --git a/doc/in_install.rst b/doc/in_install.rst index 5b3d5da08a50491c0ede91ffbdff8c0a1aa88ac8..1d1c01a92ef120bf44303a8abbf0b587cede9d3a 100644 --- a/doc/in_install.rst +++ b/doc/in_install.rst @@ -5,7 +5,7 @@ Install Arbor Currently we offer three ways to get Arbor. -1. **Python Package**. To get started quickly experimenting with Arbor via its Python API on your personal machine, see the :ref:`Python installation guide <in_python>`. +1. **Python Package**. To get started quickly with Arbor using its Python API on your personal machine, see the :ref:`Python installation guide <in_python>`. 2. **Build and install from source**. To build and install Arbor, on your own machine or HPC environment, see :ref:`in_build_install`. -If you wish to use the C++ API, you'll need to build Arbor from source or use Spack. Note that you can build the Python bindings with both of those as well. +If you wish to use the C++ API, you'll need to build Arbor from source or using Spack. Note that you can also build the Python bindings using these methods. diff --git a/doc/in_python.rst b/doc/in_python.rst index aa787ccc84bcd10596ce1d1ce3f78841afed2dd7..d49b57d48c952e553864f1005efc67c2fac26deb 100644 --- a/doc/in_python.rst +++ b/doc/in_python.rst @@ -3,7 +3,8 @@ Python Installation =================== -Arbor's Python API will be the most convenient interface for most users. Note that we only support Python 3.6 and later. Any instruction hereafter assumes you're using `python` and `pip` no older than that. +Arbor's Python API will be the most convenient interface for most users. Note that we only support Python 3.6 and later. +Any instruction hereafter assumes you're using `python` and `pip` no older than that. Getting Arbor ------------- @@ -15,7 +16,8 @@ The easiest way to get Arbor is with pip3 install arbor --user -Every point release is pushed to the Python Package Index. If you wish to install another version, it is possible to use Setuptools directly on a local copy of the source code, or instruct `pip` to install directly from our git repository: +Every point release is pushed to the Python Package Index. If you wish to install another version, it is possible to use +Setuptools directly on a local copy of the source code, or instruct `pip` to install directly from our git repository: .. code-block:: bash @@ -43,10 +45,12 @@ to see information about the version and enabled features: >>> print(arbor.__version__) >>> print(arbor.__config__) -You are now ready to use Arbor! You can continue reading these documentation pages, have a look at the :mod:`Python API Reference<arbor._arbor>`, or visit the :ref:`Quick Start page<gs_single_cell>`. +You are now ready to use Arbor! You can continue reading these documentation pages, have a look at the +:ref:`Python API reference<pyoverview>` , or visit the :ref:`Quick Start page<gs_single_cell>`. .. Note:: - To get help in case of problems installing with pip, run pip with the ``--verbose`` flag, and attach the output (along with the pip command itself) to a ticket on `Arbor's issues page <https://github.com/arbor-sim/arbor/issues>`_. + To get help in case of problems installing with pip, run pip with the ``--verbose`` flag, and attach the output + (along with the pip command itself) to a ticket on `Arbor's issues page <https://github.com/arbor-sim/arbor/issues>`_. Advanced options ^^^^^^^^^^^^^^^^^^ diff --git a/doc/index.rst b/doc/index.rst index 2885f17766df327e550634c37d66b71b5971da17..71613323cf036a3652265742b7f83d8e0d1846af 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -4,7 +4,14 @@ Arbor .. image:: https://travis-ci.org/arbor-sim/arbor.svg?branch=master :target: https://travis-ci.org/arbor-sim/arbor -Arbor is a high-performance library for computational neuroscience simulations with multi-compartment, morphologically-detailed cells, from single cell models to very large networks. Arbor is written from the ground up with many-cpu and gpu architectures in mind, to help neuroscientists effectively use contemporary and future HPC systems to meet their simulation needs. The performance portability is by virtue of back-end specific optimizations for x86 multicore, Intel KNL, and NVIDIA GPUs. When coupled with low memory overheads, these optimizations make Arbor an order of magnitude faster than the most widely-used comparable simulation software. Arbor is open source and openly developed, and we use development practices such as unit testing, continuous integration, and validation. +Arbor is a high-performance library for computational neuroscience simulations with multi-compartment, morphologically-detailed cells, +from single cell models to very large networks. Arbor is written from the ground up with many-cpu and gpu architectures in mind, to +help neuroscientists effectively use contemporary and future HPC systems to meet their simulation needs. + +Arbor supports NVIDIA and AMD GPUs as well as explicit vectorization on CPUs from Intel (AVX, AVX2 and AVX512) and ARM (Neon and SVE). +When coupled with low memory overheads, this makes Arbor an order of magnitude faster than the most widely-used comparable simulation software. + +Arbor is open source and openly developed, and we use development practices such as unit testing, continuous integration, and validation. Citing Arbor ------------ diff --git a/doc/py_mechanisms.rst b/doc/py_mechanisms.rst index 2fffffda403ab8d1680062f4cc55837553080bd1..e31f137a2979f171ee10f3a83938406282e5d78b 100644 --- a/doc/py_mechanisms.rst +++ b/doc/py_mechanisms.rst @@ -90,19 +90,19 @@ mechanism that is to be painted or placed on the cable cell. import arbor # Create pas mechanism with default parameter values (set in NOMDL file). - m1 = arbor.mechanism('passive') + m1 = arbor.mechanism('pas') # Create default mechainsm with custom conductance (range). - m2 = arbor.mechanism('passive', {'g', 0.1}) + m2 = arbor.mechanism('pas', {'g', 0.1}) # Create a new pas mechanism with that changes reversal potential (global). - m3 = arbor.mechanism('passive/el=-45') + m3 = arbor.mechanism('pas/el=-45') # Create an instance of the same mechanism, that also sets conductance (range). - m4 = arbor.mechanism('passive/el=-45', {'g', 0.1}) + m4 = arbor.mechanism('pas/el=-45', {'g', 0.1}) # This is an equivalent to m4, using set method to specify range parameters. - m5 = arbor.mechanism('passive/el=-45') + m5 = arbor.mechanism('pas/el=-45') m5.set('g', 0.1) # Decorate the 'soma' on a cable_cell. @@ -110,7 +110,7 @@ mechanism that is to be painted or placed on the cable cell. cell.paint('"soma"', m1) cell.paint('"soma"', m2) # Error: can't place the same mechanism on overlapping regions cell.paint('"soma"', m3) # This would be ok: m3 is a new, derived mechanism by virtue of - # having a different name, i.e. 'passive/el=-45' vs. 'passive'. + # having a different name, i.e. 'pas/el=-45' vs. 'pas'. .. py:class:: mechanism_info diff --git a/doc/py_recipe.rst b/doc/py_recipe.rst index 78d97fe3f0f7f435cd3bdb051fc1daa422450676..7286c0c2a44940cf1f274a36aa21920ef42ef7db 100644 --- a/doc/py_recipe.rst +++ b/doc/py_recipe.rst @@ -84,24 +84,17 @@ Recipe By default returns 0. - .. function:: num_probes(gid) - - The number of probes attached to the cell with :attr:`arbor.cell_member.gid`. - - By default returns 0. - .. function:: num_gap_junction_sites(gid) Returns the number of gap junction sites on :attr:`arbor.cell_member.gid`. By default returns 0. - .. function:: get_probe(id) + .. function:: get_probes(gid) - Returns the probe(s) to allow monitoring. + Returns a list containing (in order) all the probes on a given cell `gid`. - By default throws a runtime error. If :func:`num_probes` - returns a non-zero value, this must also be overridden. + By default returns an empty list. Cells ------ @@ -304,10 +297,6 @@ helpers in cell_parameters and make_cable_cell for building cells are used. return [arbor.event_generator(arbor.cell_member(0,0), 0.1, sched)] return [] - # Define one probe (for measuring voltage at the soma) on the cell. - def num_probes(self, gid): - return 1 - - def get_probe(self, id): + def get_probes(self, id): loc = arbor.location(0, 0) # at the soma - return arbor.cable_probe('voltage', id, loc) + return [arbor.cable_probe('voltage', loc)] diff --git a/doc/py_simulation.rst b/doc/py_simulation.rst index bfecff2ba597d53451e2237236f37bfd2f03e7d4..34167ae59afbbcf300ea339002248061a78a3889 100644 --- a/doc/py_simulation.rst +++ b/doc/py_simulation.rst @@ -183,7 +183,8 @@ Definitions *********** probe - A location or component of a cell that is available for monitoring (see :attr:`arbor.recipe.num_probes`, :attr:`arbor.recipe.get_probe` and :attr:`arbor.cable_probe` as references). + A location or component of a cell that is available for monitoring (see :attr:`arbor.recipe.num_probes`, + :attr:`arbor.recipe.get_probes` and :attr:`arbor.cable_probe` as references). sample/record A record of data corresponding to the value at a specific *probe* at a specific time.