Skip to content

Commit

Permalink
Overhaul (#34)
Browse files Browse the repository at this point in the history
* fix: `find_object()`Attribute Error

Initializing a synapse with a tag for src or dst neuron group, requires
tag seach to obtain the src or dst object.
e.g. SynapseGroup(src='pop1', dst=pop2, ...)
this search calls `find_objects()` for all objects, Therefore since
a recoder haven't yet been initialized there's no attribute `variables`

* style: each setting as argument for network

* doc: fix missing keyword and new setup method

* fix: test cuda device

* feat: default  for parameter

* relase: bump version to 0.1.3
  • Loading branch information
saeedark committed Aug 16, 2023
1 parent acce998 commit b2df5fd
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 33 deletions.
13 changes: 12 additions & 1 deletion HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@
History
=======

0.1.3 (2023-08-16)

* BREAKING CHANGE: `Network` no longer accept settings. Individual setting are now argument for Network.
* Bugg fixes.


0.1.2 (2023-06-14)

* `tensor` method for NetworkObject


0.1.1 (2023-05-26)
------------------

* Every NetworkObject can have a recorder behavior.
* Netowrk settings accept "index" entry.
* Network settings accept "index" entry.
* Bug fixes and general improvement.


Expand Down
10 changes: 5 additions & 5 deletions docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Just like ``PymoNNto``, each ``Network`` in ``PymoNNtorch`` is composed of ``Neu
ng = NeuronGroup(net=net, size=1000, behavior={})
syn = SynapseGroup(net=net, src=ng, dst=ng, tag='GLUTAMATE')

So far, ``ng`` has been added to network ``net`` and synaptic connection has been defined to connect ``ng`` to itself, i.e. both afferent and efferent synapses of ``ng`` are ``syn``. By default, each network and its components are created on CPU and the data type of any tensor inside the objects is set to ``torch.float32``. Pass an argument ``settings`` to the ``Network`` to change these default setups. ``settings`` is a dictionary with keys ``device`` and ``dtype`` which indicate the device and data type of everything within the network, respectively.
So far, ``ng`` has been added to network ``net`` and synaptic connection has been defined to connect ``ng`` to itself, i.e. both afferent and efferent synapses of ``ng`` are ``syn``. By default, each network and its components are created on CPU and the data type of any tensor inside the objects is set to ``torch.float32``. To change these settings on creation, simply, fill the arguments of the network with your desired device and dtype.

To have a functioning network, we can write ``Behavior`` (s) for different network objects to define dynamics and attributes for them. To do so, we can proceed as follows: ::

Expand All @@ -29,7 +29,7 @@ To have a functioning network, we can write ``Behavior`` (s) for different netwo
firing = neurons.voltage >= self.threshold
neurons.spike = firing.byte()
neurons.voltage[firing] = 0.0 # reset

neurons.voltage *= 0.9 # voltage decay
neurons.voltage += neurons.vector(mode="uniform", density=0.1)

Expand All @@ -52,7 +52,7 @@ Note that each behavior is given an index upon being assigned to a network objec
neurons.voltage += [email protected]() / synapse.src.size * 10

Now, assume we have defined ``ng`` by::

ng = NeuronGroup(net=net,
size=1000,
behavior={
Expand All @@ -74,11 +74,11 @@ In most simulations, we need to keep track of variables through time. To do so,

net = Network()
ng = NeuronGroup(net=net,
size=1000,
size=1000,
behavior={
1: BasicBehavior(),
2: InputBehavior(),
9: Recorder(['voltage', 'mean(voltage)']),
9: Recorder(['voltage', 'torch.mean(voltage)']),
10: EventRecorder(['spike'])
})
SynapseGroup(ng, ng, net, tag='GLUTAMATE')
Expand Down
2 changes: 1 addition & 1 deletion pymonntorch/NetworkBehavior/Recorder/Recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(
tag=tag,
**kwargs,
)
self.variables = {}

def initialize(self, object):
super().initialize(object)
Expand All @@ -71,7 +72,6 @@ def initialize(self, object):
self.auto_annotate = self.parameter("auto_annotate", True)
self.counter = 0
self.new_data_available = False
self.variables = {}
self.compiled = {}

self.add_variables(variables)
Expand Down
2 changes: 1 addition & 1 deletion pymonntorch/NetworkCore/Behavior.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def check_unused_attrs(self):
def parameter(
self,
key,
default,
default=None,
object=None,
do_not_diversify=False,
search_other_behaviors=False,
Expand Down
50 changes: 27 additions & 23 deletions pymonntorch/NetworkCore/Network.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
from pymonntorch.NetworkCore.Behavior import Behavior
from pymonntorch.NetworkCore.SynapseGroup import *

SxD = False
DxS = True


class Network(NetworkObject):
"""This is the class to construct a neural network.
Expand All @@ -20,26 +17,41 @@ class Network(NetworkObject):
NeuronGroups (list): List of all NeuronGroups in the network.
SynapseGroups (list): List of all SynapseGroups in the network.
behavior (list or dict): List of all network-specific behaviors.
def_dtype (type): Floating point precision of tensors. Defaults to `torch.float32`; can be changed via setttings with "dtype" key.
device (string): The device to allocate tensors' memory on. Defaults to `'cpu'`; can be changed via setttings with "device" key.
transposed_synapse_matrix_mode (bool): If `True`, in the matrix created by synapse, each row corresponds to a neuron from the source neuron group. Defaults to `False`; can be changed via settings with the "synapse_mode" key, which can have `DxS` and `SxD` as possible values.
index_neurons (bool): If True, the `id` attribute for neuron groups refers to neuron indices. Defaults to `True`; can be changed via setttings with "index" key.
def_dtype (type): Floating point precision of tensors. Defaults to `torch.float32`.
device (string): The device to allocate tensors on. Defaults to `'cpu'`.
transposed_synapse_matrix_mode (bool): If `True`, in the matrix created by synapse, each row corresponds to a neuron from the source neuron group. Defaults to `False`.
index_neurons (bool): If True, the `id` attribute for neuron groups refers to neuron indices. Defaults to `True`.
"""

def __init__(self, tag=None, behavior=None, settings=None):
def __init__(
self,
tag=None,
behavior=None,
dtype=torch.float32,
device="cpu",
synapse_mode="SxD",
index=True,
):
"""Initialize the network.
Args:
tag (str): Tag to add to the network. It can also be a comma-separated string of multiple tags.
behavior (list or dict): List or dictionary of behaviors. If a dictionary is used, the keys must be integers.
settings (dict): Dictionary of network-wide settings, e.g. `dtype`, `synapse_mode`, `device` and `index`.
`dtype`: Floating point precision of tensors. Defaults to `torch.float32`.
`synapse_mode`: If `SxD`, rows of matrix created by a synapse referes to the source neuron group and columns referes to the Destination neurpn group. Possible values `DxS` and `SxD`.
`device`: The device to allocate tensors' data on. Defaults to `'cpu'`.
`index`: If True, create an indexing tensor as `id` attribute for each neuron group.
dtype (torch.dtype): Floating point precision of tensors.
synapse_mode (string): If `SxD`, rows of matrix created by a synapse referes to the source neuron group and columns referes to the Destination neurpn group. Possible values `DxS` and `SxD`.
device (string): The device to allocate tensors' data on. Defaults to `'cpu'`.
index (bool): If True, create an indexing tensor as `id` attribute for each neuron group.
"""
settings = settings if settings is not None else {}
self.apply_settings(settings)
self.device = device
self._def_dtype = dtype
self.index_neurons = index
if synapse_mode not in ["SxD", "DxS"]:
print(
f"""warning: synapse_mode should be either "SxD" or "DxS". using "DxS"."""
)
self.transposed_synapse_matrix_mode = (
False if synapse_mode == "DxS" else synapse_mode == "SxD"
)

self.NeuronGroups = []
self.SynapseGroups = []
Expand All @@ -52,14 +64,6 @@ def __init__(self, tag=None, behavior=None, settings=None):

super().__init__(tag, self, behavior, device=self.device)

def apply_settings(self, settings):
self.device = settings.setdefault("device", "cpu")
self._def_dtype = settings.setdefault("dtype", torch.float32)
self.index_neurons = settings.setdefault("index", True)
self.transposed_synapse_matrix_mode = (
settings.setdefault("synapse_mode", DxS) != DxS
)

def set_behaviors(self, tag, enabled):
"""Set behaviors of specific tag to be enabled or disabled.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@
test_suite="tests",
tests_require=test_requirements,
url="https://github.com/cnrl/PymoNNtorch",
version="0.1.2",
version="0.1.3",
zip_safe=False,
)
2 changes: 1 addition & 1 deletion tests/test_pymonntorch.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def forward(self, neurons):
synapse.W @ synapse.src.spike.float() / synapse.src.size * 10
)

net = Network(settings={"device": "cuda"})
net = Network(device="cuda")
ng = NeuronGroup(
net=net,
size=100,
Expand Down

0 comments on commit b2df5fd

Please sign in to comment.