01: Hello World

In this classic example we make a SpiNNaker application which simply prints “Hello, world!” on one core and then exits.

The source files used in this tutorial can be downloaded below:

As is traditional, our first application will simply print ‘Hello, world!’ and exit. In this example our SpiNNaker application kernel will simply write its greeting into memory on a SpiNNaker chip and then terminate. Our host program will:

  • Load the application kernel
  • Instruct SpiNNaker to run it
  • Wait for the kernel to terminate
  • Retrieve the message from SpiNNaker’s memory and print it
  • Clean up and quit

SpiNNaker Application Kernel

We start by writing the SpiNNaker application kernel itself which consists of a single call to io_printf in hello.c.

#include "sark.h"
void c_main(void)
{
  io_printf(IO_BUF, "Hello, world!\n");
}

This call writes our famous message to the “IO buffer”, an area of system memory in each SpiNNaker chip which we can later read back from the host.

To compile our application we can use the standard two-line makefile:

APP := hello
include $(SPINN_DIRS)/make/app.make

To produce a compiled hello.aplx file ready for loading onto SpiNNaker, simply type:

$ make

Note

This makefile presumes your shell environment is set up correctly to use the ‘spinnaker_tools’. This can be done by running:

$ source /path/to/spinnaker_tools/setup

Host-side application

Now that we have our compiled binary we must boot our SpiNNaker machine, load the application onto a core and then read back the IO buffer. We could do this using the ybug tool included with ‘spinnaker_tools’ but since we’re building toward a real application we’ll write a Python program which will automate all these steps.

Note

Even though we’ll be writing our host programs in Python without using ‘ybug’, the ‘ybug’ tool remains a very useful debugging aid during development can can be safely used alongside your host application.

In our host program we’ll use a part of the ‘Rig’ library called MachineController which provides a high-level interface for communicating with and controlling SpiNNaker machines. The first step in our program is to create an instance of the MachineController class to communicate with our SpiNNaker board:

import sys
from rig.machine_control import MachineController
mc = MachineController(sys.argv[1])

Note that we take the hostname/IP of the board as a command-line argument to avoid hard-coding it into our script.

To boot the machine we use the boot() method. If the machine is already booted, this command does nothing.

mc.boot()

Next we’ll load our application using the load_application() method. This method loads our application onto core 1 of chip (0, 0), checks it was loaded successfully and then starts the program executing.

mc.load_application("hello.aplx", {(0, 0): {1}})

Note

load_application() can load an application onto many cores on many chips at once, hence the slightly unusual syntax.

When a SpiNNaker application kernel’s c_main function returns, the application goes into the exit state. By using wait_for_cores_to_reach_state() we can wait for our hello world application to finish executing.

mc.wait_for_cores_to_reach_state("exit", 1)

After our application has exited we can fetch and print out the contents of the IO buffer to see the message printed by the application kernel. The buffer can be read using get_iobuf(). By convention Rig uses the name p – for processor – when identifying cores.

print(mc.get_iobuf(x=0, y=0, p=1))

As a final step we must send the “stop” signal to SpiNNaker using send_signal(). This frees up any resources allocated during the running of our application.

mc.send_signal("stop")

Running our application

Our script is now finished and can then be executed like so:

$ python hello.py BOARD_IP_HERE
Hello, world!

Note

The boot() command can take a few seconds to complete if the machine is not already booted. If the machine is already booted, the script should run almost instantaneously.

Once the excitement of being greeted by a super computer has worn off, it’s time to set SpiNNaker to work on some ‘real’ computation. Let’s head onward to part 02.