Getting started: The Basics¶
EBSP programs are written in SPMD (single-program multiple-data) style. This means that each core runs the same code, but obtains different data. Later we will see how we can transfer data to and from the Epiphany cores, but for now our first step will be to get the cores to output their designated core number (called pid
for processor identifier). Like all programs written for the Parallella, an EBSP program consists of two parts. One part contains the code that runs on the host processor, the ARM chip that hosts the Linux OS. The other part contains the code that runs on each Epiphany core. In heterogeneous computing it is common to call this second part the kernel.
Hello World!¶
A host program consists of at least four EBSP functions, which are generally used as in the following example::
// file: host_code.c
#include <host_bsp.h>
int main(int argc, char **argv)
{
bsp_init("ecore_program.srec", argc, argv);
bsp_begin(16);
ebsp_spmd();
bsp_end();
return 0;
}
The first call to bsp_init
initializes the EBSP library. The first argument is the filename of the (compiled) kernel program, and the second and third arguments are the program arguments. Next we tell the EBSP system how many cores we would like to use (in this case; all 16 cores for a standard Parallella board) by calling bsp_begin
passing 16
as its first argument. The call to ebsp_spmd
starts the execution of the kernel program on the 16 cores. When the execution has finished we finalize the EBSP system by calling bsp_end
without arguments.
Next we write the kernel for our Hello World program. Besides outputting “Hello World” we also show the processor number. The code looks like this::
// file: ecore_code.c
#include <e_bsp.h>
int main()
{
bsp_begin();
int s = bsp_pid();
int p = bsp_nprocs();
ebsp_message("Hello World from processor %d / %d", s, p);
bsp_end();
return 0;
}
Let us also go over the kernel code line by line. First we initialize the EBSP system on the core, by calling bsp_begin
. In a kernel program this call does not require any arguments, since there is no additional program to run! Next we obtain information about our own designated processor number (commonly called s
) using bsp_pid
, and the total number of processors (commonly called p
) by calling bsp_nprocs
. We then output a message to host using ebsp_message
. This function can be used completely identically to printf
in ordinary C programs. Again we finalize the system with a call to bsp_end
which cleans up the EBSP system.
You may have noticed that some EBSP functions, which we will refer to as primitives, are prefixed with bsp_
while others are prefixed by ebsp_
. This is because the EBSP library introduces some functions that are not in the BSPlib standard but that can be very helpful when programming for the Epiphany.
Running this program should result in output similar to the following::
$08: Hello World from processor 8 / 16
$01: Hello World from processor 1 / 16
$07: Hello World from processor 7 / 16
$02: Hello World from processor 2 / 16
$15: Hello World from processor 15 / 16
$03: Hello World from processor 3 / 16
$10: Hello World from processor 10 / 16
$06: Hello World from processor 6 / 16
$12: Hello World from processor 12 / 16
$13: Hello World from processor 13 / 16
$05: Hello World from processor 5 / 16
$04: Hello World from processor 4 / 16
$11: Hello World from processor 11 / 16
$14: Hello World from processor 14 / 16
$09: Hello World from processor 9 / 16
$00: Hello World from processor 0 / 16
The output has the form $[pid]: output
. As we see, indeed the EBSP kernel is being run on every core! Note that there are no guarantees about which core gets to the ebsp_message
statement first, and therefore the output need not be in order of processor number.
Interface (Basics)¶
Host¶
-
int
bsp_init
(const char *e_name, int argc, char **argv) Initializes the BSP system.
Sets up all the BSP variables and loads the epiphany BSP program.
- Return
- 1 on success, 0 on failure
- Parameters
e_name
: A string with the srec binary name of the Epiphany programargc
: The number of input argumentsargv
: An array of strings with the input arguments
The string
e_name
must be of the formmyprogram.srec
. This function will search for the file in the same directory as the host program, and not in the current working directory.Usage example:
int main(int argc, char** argv) { bsp_init("e_program.srec", argc, argv); ... return 0; }
- Remark
- The
argc
andargv
parameters are ignored in the current implementation.
-
int
bsp_begin
(int nprocs) Loads the BSP program onto the Epiphany cores.
Usage example:
int main(int argc, char** argv) { bsp_init("e_program.srec", argc, argv); bsp_begin(bsp_nprocs()); ... return 0; }
- Return
- 1 on success, 0 on failure
- Parameters
nprocs
: The number of processors to run on
- Remark
- The current implementation only allows
nprocs
to be a multiple of 4 on the 16-core Parallella. Other values ofnprocs
are rounded down.
-
int
ebsp_spmd
() Runs the Epiphany program on the Epiphany cores.
This function will block until the BSP kernel program is finished.
- Return
- 1 on success, 0 on failure (e.g. after
bsp_abort
is called on a core)
-
int
bsp_end
() Finalizes and cleans up the BSP program.
Usage example:
int main(int argc, char** argv) { bsp_init("e_program.srec", argc, argv); bsp_begin(bsp_nprocs()); ebsp_spmd(); bsp_end(); return 0; }
- Return
- 1 on success, 0 on failure
- Remark
- This function is different from the bsp_end function in e_bsp.h
Epiphany¶
-
void
bsp_begin
()¶ Denotes the start of a BSP program.
This initializes the BSP system on the core.
Must be called before calling any other BSP function. Should only be called once in a program.
-
int
bsp_pid
() Obtain the processor identifier of the local core.
- Return
- An integer with the id of the core The processor id is an integer in the range [0, .., bsp_nprocs() - 1].
-
int
bsp_nprocs
() Obtain the number of Epiphany cores currently in use.
- Return
- An integer indicating the number of cores on which the program runs.
-
void
bsp_end
() Denotes the end of a BSP program.
Finalizes and cleans up the BSP program. No other BSP functions are allowed to be called after this function is called.
- Remark
- Must be followed by a return statement in your main function if you want to call
ebsp_spmd()
multiple times.
-
void
ebsp_message
(const char *format, ...)¶ Output a debug message printf style.
ebsp_message() outputs a debug message by sending it to shared memory So that the host processor can output it to the terminal The attributes in this definition make sure that the compiler checks the arguments for errors.
- Parameters
format
: The formatting string in printf style