The Brian compiler
==================
These are a few notes about how to have Brian generate and compile C code
(and possibly GPU code).
There are several motivations/uses:
* Faster simulations, run from a Python script. This is especially important
for STDP simulations, which are currently extremely long.
* Embedded real-time simulations, for example running on a robot, or working
on real-time inputs (e.g. sounds).

In any case, to get very significant speed-ups, I believe it is necessary to
have the main loop (Network.run()) not in Python. This may be a problem because
some objects (network operations) are defined by the users. To deal with this,
we can simply ask the user to provide target code (C), possibly with a simple
API. Alternatively, these operations may not need to be called at each timestep.
This alternative is possible for the first application only, but perhaps
not for embedded simulations.

An overview of what we have and what needs to be done:
* Network (main loop)
	Each object in the network must have a target code. This could be a C object,
	with a run() method and various variables.
	We write a simple C
	code that calls these codes in turn. When a non-callable object must be
	processed, the C code exits.
* NeuronGroup
	The neuron group is a simple object, because it is independent of all other
	objects in the network. With code generation, we get a C update code from
	the equations. We also need code generation for threshold and reset.
	The neuron group does not need to know about other objects
	in the network.
* Synapses
	A Synapses object must read spikes from NeuronGroup. Therefore, the C code
	must have a reference to the corresponding object. These spikes are sent
	to a SpikeQueue. This could be a predefined, independent, object.
	Synaptic events are then obtained at every timestep. Operations are then
	applied, which involve local synaptic variables, a source or target neuron
	group. This also requires references to external objects.
* Monitor
	We will need to code the basic types of monitors.
	It could be important also to have a way to save to disk, either at the
	end of the simulation or during the simulation. A simple way could be
	to have an option in the monitor to save to disk.
* NetworkOperation
	Here we need a simple way for users to write C code.
	By the way, perhaps we can use packages that convert Python to C.
* Saving and analyzing
	Typically, after a run, the user analyses the results or plots things.
	If we have a complete Brian simulation running, it could be also important
	to save the status of the entire network, which could be retrieved by
	a Python script. This should be possible. Perhaps the script could not be
	resumed, but at least the state variables could loaded. This could also be
	a way to save the monitors.
* Inputs to the models
	One major problem I see is that in most cases we need inputs, which can
	be sounds or other types of stimulations that are much easier to program
	with Python. For sounds, this would require to also have a Brian Hears
	compiler.

Summary
-------
We need general mechanisms to produce code from strings:
* differential equations
* code (reset)
* conditions (threshold)

Each object must have
* a method providing C code for running one timestep.
* a method providing the C reference to the object (or name of instance).
* a number of standard variables and mechanisms (store spikes etc).

So in fact, I would suggest that what needs to be done is a complete C++ framework,
classes etc. Brian would simply produce additional C++ text that would be
compiled together with the framework.

Suggested plan
--------------
** We could start by writing a pure C++ simulator, for an example **
This means writing C++ classes for each Brian class.
For the update code we could just copy and paste code generated by Brian.
Then we go for option 2: running a *complete* Brian simulation in C. It makes
it less flexible because we cannot do any hybrid script. But it also makes the
design much simpler.

So what this will make is really a Brian compiler producing stand-alone code,
rather than doing code generation to accelerate some parts.

More ideas
----------
GPU: these C++ classes could also include GPU code, it might not be much more
difficult.
