Skip to content

Commit

Permalink
Create Tips on NEST.md
Browse files Browse the repository at this point in the history
  • Loading branch information
saq10002 committed Jan 23, 2015
1 parent dff783b commit 9c704e7
Showing 1 changed file with 180 additions and 0 deletions.
180 changes: 180 additions & 0 deletions Tips on NEST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
Tips on NEST
============
This document contains tips on how to build, install, and modify the source of the [NEST project](http://nest-initiative.org). NEST is written in C++ and wonderfully documented.

Preparations
============

I am assuming that the reader wants to research/understand how NEST works.

You must have a Linux/Mac system having GCC-toolchain. On Windows machines, I recommend installing Ubuntu 12.10 with [Wubi](https://wiki.ubuntu.com/WubiGuide).

When your Linux system is up and running, do the following:
* Have ```GCC``` version >= 4.7.2.
* Install Python, and make sure it is compiled with the same version of ```GCC``` that you have. When you run Python from shell, it tells which GCC was used to compile it.
* Along with Python, it is recommended that you have ```Cython, NumPy, SciPy,``` and ```Matplotlib``` installed.
* Have ```GSL``` (GNU Scientific Library) installed.
* Have your favorite MPI library (e.g., OpenMPI) installed.
* Have ```GNU Autotools, Autoconf,``` and ```Automake``` installed.
* Have ```doxygen``` installed.

Create a virtual environment for experimenting with NEST. For example, on my machine I created the directory ```/home/saad/venv``` and inside that I created the virtual environment ```nest-dbg```. You can use [```pyvenv```](https://docs.python.org/3/library/venv.html) for this purpose. A virtual environment is nothing but a directory containing a copy of a Python distribution. When you create a virtual environment, your currently active python gets copied to that location. That way, when you *activate* this virtual environment, this directory will be placed at the beginning of your ```PATH``` environment variable and anyone looking for the program ```python``` will find this Python even if there are other Python versions present in your system.

Create a new directory called ```nest```. Then, download the latest version of [NEST source code](http://nest-initiative.org/Software:Download). and extract the source inside this directory. This should add the subdirectory ```nest-2.6.0``` inside the ```nest``` directory assuming you downloaded ```nest-2.6.0```.

I recommend you add this folder in a version control system, such as ```git```.

Build from Source
=================
* Inside the ```nest``` directory, create a directory ```build```. Now, the ```nest``` directory contains two subdirectories: ```nest-2.6.0``` and ```build```.
* First, we need to figure out where the NEST will be installed. This is called the ```prefix``` directory. This should be the virtual environment we created for NEST in the preparation step. In my case, the ```prefix``` is ```/home/saad/venv/nest-dbg```.
* Now we need to know which options shall we use to build NEST. For our purpose, we must use MPI and OpenMP, use debugging enabled without any optimization. Together with ```prefix```, our configuration options are as follows:
```--prefix=/home/saad/venv/nest-dbg --with-mpi --with-openmp --with-debug --with-optimize=-O0```.
* If you want to build without Python support, you should add the option ```--without-python``` to the above.
* Open a command window (shell). Then activate our virtual environment by the command ```/home/saad/venv/nest-dbg/bin/activate```. This makes our Python available to for the NEST installation. From now on, whenever we are going to work with NEST, this environment must be activated.
* In the shell, type ```cd /home/saad/nest/build```. Now we are inside the ```build``` directory.
* Now we should ```configure``` NEST, by typing ```../nest-2.6.0/configure --prefix=/home/saad/venv/nest-dbg --with-mpi --with-openmp --with-debug --with-optimize=-O0 | tee nest-configure.out```. ```configure``` is a shell script in the NEST distribution which examines your system and create necessary ```Makefile```s inside the ```build``` directory. The program ```tee``` is used to show us the output of the configure script while also saving the output to the file ```nest-configure.out```.
* Examine the last bits of the above output. If everything is fine, it should tell something like the following:
```
--------------------------------------------------------------------------------
NEST Configuration Summary
--------------------------------------------------------------------------------
C compiler : gcc
C compiler flags : -W -Wall -pedantic -Wno-long-long -g -O0 -g -O2 -fopenmp
C++ compiler : mpicxx
C++ compiler flags : -W -Wall -pedantic -Wno-long-long -g -O0 -fopenmp
Python bindings : Yes (Python 3.4: /home/saad/venv/nest-dbg/bin/python)
User modules : None
Extra modules : models precise topology
Dynamic modules : None
Use threading : Yes (OpenMP)
Use GSL : Yes
Use MPI : Yes
Use MUSIC : No
Use libneurosim : No
--------------------------------------------------------------------------------
The NEST executable will be installed to:
/home/saad/venv/nest-dbg/bin/
Documentation and examples will be installed to:
/home/saad/venv/nest-dbg/share/doc/nest/
PyNEST will be installed to:
/home/saad/venv/nest-dbg/lib/python3.4/site-packages
To set necessary environment variables, add the following line
to your ~/.bashrc :
source /home/saad/venv/nest-dbg/bin/nest_vars.sh
--------------------------------------------------------------------------------
You can now build and install NEST with
make
make install
make installcheck
```
It is important to check that the NEST is going to be installed in the location we want (in our virtual environment), and that it has detected MPI, OpenMP, Python and GSL. If something is wrong/missing, NEST will tell you and you should fix these before you proceed.
* Now we are ready to build (```make```) NEST from source. In the shell, just write ```make```, and hope that everything will be fine. If there are no error messages, you have successfully built NEST from source. The binaries (executables and libraries) are still inside the ```build``` directory.
* In the shell, type ```make install```. The executables/libraries will now be copied to the ```prefix``` directory we specified during running the ```configure``` script.
* You can now type ```nest``` and if everything was alright, you should see the following prompt:
```
saad@ubuntu:~/nest/build-2.6.0-gpu/nest$ ./nest
-- N E S T --
Copyright (C) 2004 The NEST Initiative
Version 2.6.0 Jan 22 2015 00:42:35
This program is provided AS IS and comes with
NO WARRANTY. See the file LICENSE for details.
Problems or suggestions?
Website : http://www.nest-initiative.org
Mailing list: nest_user@nest-initiative.org
Type 'help' to get more information.
Type 'quit' or CTRL-D to quit NEST.
SLI ]
```
SLI means Simulation Language Interface, which is NEST's interactive command prompt. You can type ```quit``` and the program will exit. You can also try examples from the [NEST documentation](http://nest-initiative.org/Neural_simulations).

Errors During Build
===================
Here is a possible linking error during building NEST.

**A linking error:**
- NEST Version: 2.6.0
- Source: Downloaded from (http://www.nest-simulator.org/download/gplreleases/nest-2.6.0.tar.gz) on Jan 21, 2015
- When: Attempting to build from source: bootstrap.sh => configure => make
- Compiler: gcc-4.7.2 with OpenMPI
- OS: Ubuntu 12.10, Red Hat Enterprise Server 5.7 (two machines)

**Error Details:**
- Linker Error Message: "Undefined reference to Time::LimitPosInf::tics in Time::Time(...)". The same happened also with Time::LimitNegInf on all constructors Time::Time(...) for members tics and delays.
- While Linking: libnest.la
- Error at Source File: nestkernel/nest_time.h (Time constructors)
- Consequences: Build failed

**Reason of the linker error:**
The error happened because the class Time::LimitPosInf (likewise, Time::LimitNegInf) has static const members. However, although similar static const members of Time::Range had been defined in nest_time.cpp, the static const members of Time::LimitPosInf (likewise, Time::LimitNegInf) were not defined in the cpp file.

See http://stackoverflow.com/questions/272900/vectorpush-back-odr-uses-the-value-causing-undefined-reference-to-static-clas

**Resolution:**
After adding the following code in nestkernel/nest_time.cpp (at line 58), the linker errors were resolved and the build succeeded.

const tic_t Time::LimitPosInf::tics;
const delay Time::LimitPosInf::steps;
const tic_t Time::LimitNegInf::tics;
const delay Time::LimitNegInf::steps;

Debugging the NEST Project
==========================
You can set up a project with your favourite IDE (e.g., NetBeans or Eclipse) and create a ```C++``` project with existing source from the ```nest/nest-2.6.0``` directory. Because we have built NEST with debug information, you will be use your IDE's debugging facilities.

Adding Your Own Code to NEST
============================
* If you want to add a new library inside NEST, createa a new directory inside ```nest/nest-2.6.0```. In my case, I created the directory ```nest/nest-2.6.0/nestgpu``` and wanted my new code to be inside the new library ```libnestgpu```. Inside this directory, you add your new source/header files.
* However, your code is still not part of the NEST build system. To have your code be built with NEST, you need to do few more things.
* First, create a file named ```Makefile.am``` inside this new directory. Every source directory of NEST contains a ```Makefile.am``` file of its own. This file contains instructions for the ```automake``` tool so that it knows what to build, from which files, using which libraries, etc. For example, I had two source files: ```GpuDataAdapter.h`` and ```GpuDataAdapter.cpp`` which I wanted to be built into my new library ```libnestgpu```. For this purpose, my ```nest/nest-2.6.0/nestgpu/Makefile.am``` file contained the following lines:
```
# Automake file for the GPU-port of the NEST simulation kernel library
#
# Saad Quader, January 2015
#
defs= @SLI_THREAD_DEFS@ $defs
MAKEFLAGS= @MAKE_FLAGS@
noinst_LTLIBRARIES=libnestgpu.la
libnestgpu_la_SOURCES=\
gpu_data_adapter.h gpu_data_adapter.cpp
# do not change anything below this line ------------------------------
libnestgpu_la_CXXFLAGS= @AM_CXXFLAGS@
libnestgpu_la_LIBADD= @LIBLTDL@ @LIBADD_DL@
AM_CPPFLAGS= -I$(top_srcdir)/libnestutil\
-I$(top_srcdir)/librandom\
-I$(top_srcdir)/sli\
-I$(top_srcdir)/nestkernel\
@INCLTDL@ @GSL_CFLAGS@ @MUSIC_INCLUDE@ @MPI_INCLUDE@
```
* Suppose you want to use your code from any part of the original NEST code. In my case, I wanted to call ```GpuDataAdapter::init()``` from within the function ```neststartup()``` in the file ```nest/nest-2.6.0/nest/neststartup.cpp```. For this, inside the ```cpp``` file, I added ```#include "gpudataadapter.h"``` and inside the definition of the function ```neststartup()```, I added ```nest::gpu::GpuDataAdapter::init();```.
* Editing the existing source code was easy. However, how does the compiler/linker know where to find the declaration/definition of the code for the ```GpuDataAdapter::init()``` function? This is the hard part. For this, I had to modify the ```nest/nest-2.6.0/nest/Makefile.am``` file as follows: I added ```nestgpu/libnestgpu.la``` to the existing definition of the variables ```nest_LDADD``` and ```nest_DEPENDENCIES``` so that the linker knows where to find the definition of my new functions. I also added ```-I$(top_srcdir)/nestgpu``` to the existing value of the variable ```AM_CPPFLAGS``` so that the compiler knows where to look for the ```#include``` headers for my new code. However, it turned out that the module ```nest/nest-2.6.0/pynest``` also uses the file ```nest/nest-2.6.0/nest/neststartup.cpp``` and its header. Therefore, I had to specify the ```nest/nest-2.6.0/nestgpu``` directory as an include directory in the file ```nest/nest-2.6.0/pynest/Makefile.am``` as well. However, I did not need to specify the library ```libnestgpu``` because the library ```pynestkernel.la``` was already linked to the library ```libnest.la``` which was also already linked to my library ```libnestgpu.la```.
* Next, you should tell the NEST build system to actually visit this subdirectory and build your code. For this, you have to edit the ```nest/nest-2.6.0/configure.ac.in```. In particular, you need to edit two things:
[x] You have to specify that you have a new source directory. You do this by editing the existing value of the variable ```SLI_CORE_LIBS``` and adding the word ```nestgpu``` in its existing list of directories.
[x] You have to specify that you have a new ```Makefile``` to be created by the configure script. You do this by adding the following line: ```AC_CONFIG_FILES(nestgpu/Makefile)``` after the list of existing Makefiles. (Just search for the text ```AC_CONFIG_FILES```) inside the file ```configure.ac.in```.)
* Now that we have specified that we have new code, we need to rebuild the system, by generating a new ```configure``` script using our recently modified ```configure.ac.in``` file. To do this, just run the script ```nest/nest-2.6.0/bootstrap.sh``` which would generate a new ```configure``` script.
* Then, reconfigure NEST by typing ``` cd /home/saad/nest/build && ../nest-2.6.0/configure ../nest-2.6.0/configure --prefix=/home/saad/venv/nest-dbg --with-mpi --with-openmp --with-debug --with-optimize=-O0```.
* Then, build NEST by running ```make``` and ```make install```.
* Now, when NEST runs, it does so with the modified code.

0 comments on commit 9c704e7

Please sign in to comment.