Skip to content
/ doryta Public

Neuromorphic event-driven simulator in C and MPI (successor of NeMo https://github.com/markplagge/NeMo)

License

Notifications You must be signed in to change notification settings

helq/doryta

Repository files navigation

Doryta

Doryta (not an acronym) is a spiking neural network (SNN) simulator written in C using the (massively) parallelizable ROSS library for Parallel Discrete Event Simulation (PDES).

Compilation

Doryta requires CMake and a C compiler with support for MPI. To download and compile in as little steps, run the instructions below. (In order to keep Doryta as lean as possible, all example models are stored in a separate git submodule repo. That's why the slightly longer and complicated sequence of commands.)

git clone --recurse-submodules https://github.com/helq/doryta --depth=1
mkdir doryta/build && cd doryta/build
cmake .. -DBUILD_TESTING=OFF
make -j4

After compiling, you will find the executable under the folder: doryta/build/src

Optionally, you can run make install to copy doryta to the folder where binaries are stored in your computer (/usr/bin for example). If you wish to change the default directory, for example to doryta/build/bin instead of /usr/bin, run cmake with the flag -DCMAKE_INSTALL_PREFIX="$(pwd -P)/".

Execution

To check whether doryta has been compiled properly, run the following:

mpirun -np 2 src/doryta --sync=3 --five-example --probe-firing --probe-voltage --end=1

This will run a five-neuron fully connected network, on top of which a fully connected layer of two neurons is layered. The input to the network is a fixed set of spikes, and the parameters of the network are always the same, so that the execution of the network must always produce the same output.

The output of running the model can be found at output/. The small Python script plot_neuron_spikes_voltage.py under tools/general can be used to analyze the behaviour of neurons and their spikes.

MNIST example

Multiple network models for MNIST can be found under data/models/whetstone. Whetstone is a library for training SNNs using the Keras backend. The code to generate the model can be found under data/models/whetstone/code. The testing MNIST dataset has been spikified in order to be readable for Doryta (which only understands spikes as an input).

To inference the class of the first 20 images in the dataset, run the following command:

mpirun -np 2 src/doryta --spike-driven --synch=3 --extramem=1000000 \
    --load-model=../data/models/mnist/snn-models/ffsnn-mnist.doryta.bin \
    --load-spikes=../data/models/mnist/spikes/spikified-mnist/spikified-images-all.bin \
    --output-dir=fully-20 \
    --probe-firing --probe-firing-output-only --probe-firing-buffer=100000 --end=19.5

The output will be stored under the path fully-20. The script tools/whetstone-mnist/check_doryta_inference.py checks this output with the expected output from whetstone.

Conway's Game of Life example

A step of game of life can be simulated using two layers of convolutional neural networks. Luckily the translation into Spiking NNs is straightforward, and, even more, the output of the network can be fed back to the input layer, which means that doryta can simulate the game of life out of the box. To run a built-in example of GoL, run the following command:

src/doryta --gol-model --load-spikes=../data/models/gol-spikes/20x20/gol-blinker.bin --probe-firing --spike-driven --end=10.5
# or
src/doryta --gol-model --load-spikes=../data/models/gol-spikes/20x20/gol-glider.bin --probe-firing --spike-driven --end=40.5

To visualize the simulation use the script tools/gol/show_state.py.

Needy vs Spike-driven modes

Doryta comes with two modes of execution: needy and spike-driven. In Needy mode, Doryta will update the state of each neuron every delta time just as any other ordinary simulation framework. In spike-driven mode, Doryta will only update the state of the neuron when it receives a spike, and it's, thus, much faster than needy. The main assumption for spike-driven to behave as needy is that there must NEVER be positive leak on the system, ie, neurons cannot spike on their own if there don't have a input stimulous (spike).

The MNIST example (above) uses the spike-driven mode, which runs faster than the needy mode, but it doesn't compute the step by step change on voltage. This means that we cannot analyze the voltage behaviour of neurons. If you want to analyze the voltage change, remove the --spike-driven flag, activate the voltage probe (--probe-voltage) and assign enough buffer space (--probe-voltage-buffer) to store voltage for all neurons on the determined time step.

Note on custom models: There might be some discrepancies when running a model on the spike-driven mode opposed to needy mode. To reduce such discrepancies, we recommend to make the heartbeat interval (the delta of the approximation) small enough. By the very nature of simulation, breaking a continuous equation into discrete steps, there will always be a tradeoff between computation time and fidelity.

Release binary

To get the clean, non-debug, faster implementation use:

cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF

Testing

To run tests you have to compile them first and then run ctest:

cmake .. -DBUILD_TESTING=ON
make -j4
ctest -j4

Remember to run CMake again whenever a new test is added. CMake generates the rules to compile the tests and run them. Unfortunatelly, CMake is not triggered when new tests/folders are added to the test folder.