Example system, consisting of processes (rectangles), outputs (circles), and links (arrows). The rules of this connectivity are pretty standard: each process takes zero or more inputs, generates zero or more outputs, and each process output can be linked to zero or more process inputs.

What is BRAHMS?

BRAHMS is a Modular Execution Framework (MEF) for executing integrated systems built from component software processes (a SystemML-ready execution client). Its operation is conceptually similar to that of Simulink, for example. Such tools allow the connection of processes together into systems, by linking the outputs of some processes into the inputs of others (see Figure). In this way, the design and implementation of a system is separated from the design and implementation of each process is separated from the design and implementation of the framework that facilitates their connection. Thus, they solve the problem of connecting pieces of software written by different researchers (who are generally not software engineers).

An MEF effectively encapsulates the specification and implementation of a particular model engine (be it spiking neural network or time-invariant filter), allowing it to be shared between complex system models without the respective authors having to intuit each other's (usually undocumented) interfaces or port/modify each other's code. The modules compute mathematical models, whilst the MEF takes charge of synchronization, data transport and various infrastructure facets such as data logging, performance analysis, etc.

Modular Computation

The concept we are working with is very similar to that supported by Simulink or Labview: the linking together of separate software modules into a single meaningful (computable) "system". If you are wondering why we should be using such tools at all, we aren't going to rehearse all the arguments here, but here are the main points...

Making it possible
Platform-independent, language-independent, style-independent software integration (for example, across multi-centre multi-discipline research projects). Your code can easily be shared now or in the future with other members of your group, or with other groups.
Making it value-for-money
Advanced functionality offered by the framework so you don't have to author it (coarse-grained parallelisation, performance monitoring, Pause-And-Continue execution, data logging, software distribution, etc.).
Making it high performance
Framework authored and optimised in a low-level language (C++), for high-performance. The only thing slowing you down should be your computations.

Specific Benefits

Code reuse and maintainability
Breaking up software development into pieces of minimal size is considered to maximize reusability and maintainability. In our case, individual modules can be logically considered as closed systems, and thus their (re)development straightforward.
Shared support code
Developing the framework as an independent module itself offers the same benefits for reuse and maintainability with respect to this code. Framework reuse is particularly beneficial because we may confer huge advantages on the model developer from quite advanced facilities made available by the framework (e.g. transparent parallelisation, asynchronous processing, inter-process synchronisation, data logging, Pause-And-Continue execution model), whereas it would be quite unreasonable for a developer to code these facilities for each individual model built.
In modular systems, the individual modules can be distributed across available compute resources by a framework that knows nothing of their internal workings, because the framework has charge of data transport. Thus, coarse-grained parallelisation can be achieved without (a) the process developer expending any effort towards parallelisation, or (b) the parallelisation developer having any involvement or setting any additional constraints on process development.
Fringe benefits
By encouraging a common development context, we will comprehend each other's code that much more easily, over and above the benefit in this regard that we achieve by keeping modules minimal. By encouraging proper versioning and documentation as well (through inclusion in a framework), we should be able to modify or extend our own code, and that of others, a long-term personal goal of mine that i achieve only on rare occasions.

Potential for parallelisation

The granular size of modules needs to be balanced between too small (introduce computational overhead) and too large (gain no modular advantage). So far, and in line with previous work in this area, this has given us modules that act as engines for particular processes (filter, sum, network). Project-bespoke engines (e.g. a physical world model) may not suffer further granulation. However, network engines, our workhorses, lend themselves to it, since the individual nodes generally have the same conditions of independence given above, so a large network can still be efficiently computed if broken up into smaller pieces. This fact gives us granulation of network models when those models are otherwise monolithic, allowing us to gain the parallel computation advantage even when the model being computed does not naturally break into modules.


Assuming you're sold on modular computation: why BRAHMS rather than Simulink or Labview, say?

  • BRAHMS is free software, both in the free speech sense and in the free beer sense. This makes the software and, thus, any models you publish using it accessible to everyone. For a scientific tool, that is a desirable property. Plus, of course, all the usual fringe benefits of open source.
  • BRAHMS is built on SystemML, so your models get the benefits of the SystemML infrastructure and file format:
    • Open storage format derived from XML offering self-documentation (readability), long-term stability, and extensibility: your models can be accessed and modified using any SystemML-ready tools, not just BRAHMS.
    • An infrastructure for transparent distribution of your software implementations of the models you publish.
    • Advanced features, like Pause-And-Continue execution, event-driven data logging, and managed transparently distributed utility modules.
  • BRAHMS offers varied deployment options. BRAHMS flavours already exist that sit well in resource-poor (e.g. embedded) environments or that take advantage of resource-rich (e.g. multi-processing) environments.

BRAHMS and you

Developing Systems

The simplest relationship you can have with BRAHMS is that of someone who wishes to execute a System, where that System is built of Processes that already exist. You specify the required Process classes (e.g. source, sum, product), the parameters of those processes (configuration, initial state), the connectivity between them (which outputs go to which inputs), and the parameters of the Execution itself (stop time, parallelisation, which data objects are being logged). You then call BRAHMS with this Execution, the System is executed, and the logged outputs are returned to you. To get started on this track, look at the section Developing Systems in the User Guide.

Developing Processes

What this relationship does not offer is the development of bespoke computation. The effectiveness, then, of this relationship hinges on the flexibility designed into the processes. For instance, a spiking neuron network simulator exists, but currently it does not support shunting inhibition. To perform a simulation involving shunting inhibition under BRAHMS, then, we will have to modify an existing process, or develop a new one. BRAHMS is written in C++, but processes can be developed in a variety of languages (at time of writing, C, C++, Matlab and Python). To get started on this track, look at the section Developing Processes in the User Guide.

Developing BRAHMS

Finally, if you are on the BRAHMS development team, you may be getting involved in developing the framework itself. This is currently by invite only, though we welcome detailed bug reports and suggested source-code patches from anyone who wants to get involved at this level. Alternatively, you may want to modify BRAHMS slightly for your particular application. For either of these uses, you should look at the section Framework in the Reference Manual.


  1. We prefer the term "Execution" to "Simulation" since not all systems run on BRAHMS will be simulations of anything. We prefer to keep the word "simulation" on this page, however, so that those who, as yet, disagree can still find it.