Feature: High-level network specification (#2050)
Implement a high-level network specification as proposed in
#418. It does not include support for gap junctions to allow the use of
domain decomposition for some distributed network generation.
The general idea is a DSL based on set algebra, which operates on the
set of all possible connections, by selecting based on different
criteria, such as the distance between cells or lists of labels. By
operating on all possible connections, a separate definition of cell
populations becomes unnecessary. An example for selecting all inter-cell
connections with a certain source and destination label is:
`(intersect (inter-cell) (source-label \"detector\") (destination-label
\"syn\"))`
For parameters such as weight and delay, a value can be defined in the
DSL in a similar way with the usual mathematical operations available.
An example would be:
`(max 0.1 (exp (mul -0.5 (distance))))`
The position of each connection site is calculated by resolving the
local position on the cell and applying an isometry, which is provided
by a new optional function of the recipe. In contrast to the usage of
policies to select a member within a locset, each site is treated
individually and can be distinguished by its position.
Internally, some steps have been implemented in an attempt to reduce the
overhead of generating connections:
- Pre-select source and destination sites based on the selection to
reduce the sampling space when possible
- If selection is limited to a maximum distance, use an octree for
efficient spatial sampling
- When using MPI, only instantiate local cells and exchange source sites
in a ring communication pattern to overlap communication and sampling.
In addition, this reduces memory usage, since only the current and next
source sites have to be stored in memory during the exchange process.
Custom selection and value functions can still be provided by storing
the wrapped function in a dictionary with an associated label, which can
then be used in the DSL.
Some challenges remain. In particular, how to handle combined explicit
connections returned by `connections_on` and the new way to describe a
network. Also, the use of non-blocking MPI is not easily integrated into
the current context types, and the dry-run context is not supported so
far.
# Example
A (trimmed) example in Python, where a ring connection combined with
random connections based on the distance:
```py
class recipe(arbor.recipe):
def cell_isometry(self, gid):
# place cells with equal distance on a circle
radius = 500.0 # μm
angle = 2.0 * math.pi * gid / self.ncells
return arbor.isometry.translate(radius * math.cos(angle), radius * math.sin(angle), 0)
def network_description(self):
seed = 42
# create a chain
ring = f"(chain (gid-range 0 {self.ncells}))"
# connect front and back of chain to form ring
ring = f"(join {ring} (intersect (source-cell {self.ncells - 1}) (destination-cell 0)))"
# Create random connections with probability inversely proportional to the distance within a
# radius
max_dist = 400.0 # μm
probability = f"(div (sub {max_dist} (distance)) {max_dist})"
rand = f"(intersect (random {seed} {probability}) (distance-lt {max_dist}))"
# combine ring with random selection
s = f"(join {ring} {rand})"
# restrict to inter-cell connections and certain source / destination labels
s = f"(intersect {s} (inter-cell) (source-label \"detector\") (destination-label \"syn\"))"
# normal distributed weight with mean 0.02 μS, standard deviation 0.01 μS
# and truncated to [0.005, 0.035]
w = f"(truncated-normal-distribution {seed} 0.02 0.01 0.005 0.035)"
# fixed delay
d = "(scalar 5.0)" # ms delay
return arbor.network_description(s, w, d, {})
```
Co-authored-by:
Thorsten Hater <24411438+thorstenhater@users.noreply.github.com>
Showing
- arbor/CMakeLists.txt 2 additions, 0 deletionsarbor/CMakeLists.txt
- arbor/communication/communicator.cpp 35 additions, 18 deletionsarbor/communication/communicator.cpp
- arbor/communication/communicator.hpp 6 additions, 7 deletionsarbor/communication/communicator.hpp
- arbor/communication/distributed_for_each.hpp 185 additions, 0 deletionsarbor/communication/distributed_for_each.hpp
- arbor/communication/dry_run_context.cpp 17 additions, 0 deletionsarbor/communication/dry_run_context.cpp
- arbor/communication/mpi.hpp 57 additions, 0 deletionsarbor/communication/mpi.hpp
- arbor/communication/mpi_context.cpp 68 additions, 0 deletionsarbor/communication/mpi_context.cpp
- arbor/connection.hpp 3 additions, 3 deletionsarbor/connection.hpp
- arbor/distributed_context.hpp 86 additions, 0 deletionsarbor/distributed_context.hpp
- arbor/domain_decomposition.cpp 17 additions, 6 deletionsarbor/domain_decomposition.cpp
- arbor/include/arbor/common_types.hpp 13 additions, 0 deletionsarbor/include/arbor/common_types.hpp
- arbor/include/arbor/domain_decomposition.hpp 4 additions, 2 deletionsarbor/include/arbor/domain_decomposition.hpp
- arbor/include/arbor/math.hpp 13 additions, 0 deletionsarbor/include/arbor/math.hpp
- arbor/include/arbor/network.hpp 331 additions, 0 deletionsarbor/include/arbor/network.hpp
- arbor/include/arbor/network_generation.hpp 20 additions, 0 deletionsarbor/include/arbor/network_generation.hpp
- arbor/include/arbor/recipe.hpp 11 additions, 1 deletionarbor/include/arbor/recipe.hpp
- arbor/include/arbor/simulation.hpp 1 addition, 1 deletionarbor/include/arbor/simulation.hpp
- arbor/network.cpp 1453 additions, 0 deletionsarbor/network.cpp
- arbor/network_impl.cpp 308 additions, 0 deletionsarbor/network_impl.cpp
- arbor/network_impl.hpp 67 additions, 0 deletionsarbor/network_impl.hpp
Please register or sign in to comment