Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Nov 25, 2018. It is now read-only.

Commit 0d4a853

Browse files
author
Jan-Willem Buurlage
committed
Finalize release 1.0.0
2 parents 9be368e + 5b40a47 commit 0d4a853

28 files changed

Lines changed: 1680 additions & 705 deletions

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Changelog
22

3+
## 1.0.0 - 2017-18-01
4+
5+
### Added
6+
- BSP variable list is stored distributed over all cores instead of in external memory
7+
- Implement `bsp_pop_reg`
8+
- New streaming API
9+
10+
### Fixed
11+
- `bsp_begin` no longer uses divide and modulus operator which take up large amounts of memory
12+
- `bsp_begin` no longer initializes coredata to zero since this is already done in the loader
13+
- `bsp_end` no longer executes TRAP so that `main` can finish properly
14+
15+
### Removed
16+
17+
318
## 1.0.0-beta.2 - 2016-04-21
419

520
### Added

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ E_SRCS = \
2121
e_bsp_mp.c \
2222
e_bsp_memory.c\
2323
e_bsp_buffer.c \
24+
e_bsp_buffer_deprecated.c \
2425
e_bsp_dma.c
2526

2627
E_ASM_SRCS = \
@@ -40,8 +41,10 @@ HOST_SRCS = \
4041
host_bsp.c \
4142
host_bsp_memory.c \
4243
host_bsp_buffer.c \
44+
host_bsp_buffer_deprecated.c \
4345
host_bsp_mp.c \
44-
host_bsp_utility.c
46+
host_bsp_utility.c \
47+
host_bsp_debug.c
4548

4649
#First include directory is only for cross-compiling
4750
INCLUDES = -I/usr/include/esdk \

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ In particular this library has been implemented and tested on the [Parallella](
2121

2222
int main(int argc, char **argv)
2323
{
24-
bsp_init("ecore_program.srec", argc, argv);
24+
bsp_init("ecore_program.elf", argc, argv);
2525
bsp_begin(16);
2626
ebsp_spmd();
2727
bsp_end();
@@ -92,7 +92,7 @@ HOST_LIB_NAMES = -lhost-bsp -le-hal -le-loader
9292
9393
E_LIB_NAMES = -le-bsp -le-lib
9494
95-
all: bin bin/host_program bin/ecore_program.srec
95+
all: bin bin/host_program bin/ecore_program.elf
9696
9797
bin:
9898
@mkdir -p bin
@@ -105,9 +105,6 @@ bin/ecore_program.elf: src/ecore_code.c
105105
@echo "CC $<"
106106
@e-gcc $(CFLAGS) -T ${ELDF} $(INCLUDES) -o $@ $< $(E_LIBS) $(E_LIB_NAMES)
107107
108-
bin/%.srec: bin/%.elf
109-
@e-objcopy --srec-forceS3 --output-target srec $< $@
110-
111108
clean:
112109
rm -r bin
113110
```

docs/api_reference.rst

Lines changed: 16 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,10 @@ ebsp_hpmove
8080
.. doxygenfunction:: ebsp_hpmove
8181
:project: ebsp_host
8282

83-
ebsp_create_down_stream
84-
^^^^^^^^^^^^^^^^^^^^^^^
83+
bsp_stream_create
84+
^^^^^^^^^^^^^^^^^
8585

86-
.. doxygenfunction:: ebsp_create_down_stream
87-
:project: ebsp_host
88-
89-
ebsp_create_up_stream
90-
^^^^^^^^^^^^^^^^^^^^^
91-
92-
.. doxygenfunction:: ebsp_create_up_stream
86+
.. doxygenfunction:: bsp_stream_create
9387
:project: ebsp_host
9488

9589
ebsp_write
@@ -251,68 +245,32 @@ bsp_hpmove
251245
.. doxygenfunction:: bsp_hpmove
252246
:project: ebsp_e
253247

254-
ebsp_send_up
255-
^^^^^^^^^^^^
248+
bsp_stream_open
249+
^^^^^^^^^^^^^^^
256250

257-
.. doxygenfunction:: ebsp_send_up
251+
.. doxygenfunction:: bsp_stream_open
258252
:project: ebsp_e
259253

260-
ebsp_move_chunk_down
261-
^^^^^^^^^^^^^^^^^^^^
254+
bsp_stream_close
255+
^^^^^^^^^^^^^^^^
262256

263-
.. doxygenfunction:: ebsp_move_chunk_down
257+
.. doxygenfunction:: bsp_stream_close
264258
:project: ebsp_e
265259

266-
ebsp_move_chunk_up
260+
bsp_stream_move_up
267261
^^^^^^^^^^^^^^^^^^
268262

269-
.. doxygenfunction:: ebsp_move_chunk_up
263+
.. doxygenfunction:: bsp_stream_move_up
270264
:project: ebsp_e
271265

272-
ebsp_move_down_cursor
273-
^^^^^^^^^^^^^^^^^^^^^
274-
275-
.. doxygenfunction:: ebsp_move_down_cursor
276-
:project: ebsp_e
277-
278-
ebsp_reset_down_cursor
279-
^^^^^^^^^^^^^^^^^^^^^^
280-
281-
.. doxygenfunction:: ebsp_reset_down_cursor
282-
:project: ebsp_e
283-
284-
ebsp_open_up_stream
285-
^^^^^^^^^^^^^^^^^^^
286-
287-
.. doxygenfunction:: ebsp_open_up_stream
288-
:project: ebsp_e
289-
290-
ebsp_open_down_stream
291-
^^^^^^^^^^^^^^^^^^^^^
292-
293-
.. doxygenfunction:: ebsp_open_down_stream
294-
:project: ebsp_e
295-
296-
ebsp_close_up_stream
266+
bsp_stream_move_down
297267
^^^^^^^^^^^^^^^^^^^^
298268

299-
.. doxygenfunction:: ebsp_close_up_stream
300-
:project: ebsp_e
301-
302-
ebsp_close_down_stream
303-
^^^^^^^^^^^^^^^^^^^^^^
304-
305-
.. doxygenfunction:: ebsp_close_down_stream
306-
:project: ebsp_e
307-
308-
ebsp_set_up_chunk_size
309-
^^^^^^^^^^^^^^^^^^^^^^
310-
311-
.. doxygenfunction:: ebsp_set_up_chunk_size
269+
.. doxygenfunction:: bsp_stream_move_down
312270
:project: ebsp_e
313271

314-
bsp_abort
315-
^^^^^^^^^
272+
bsp_stream_seek
273+
^^^^^^^^^^^^^^^
316274

317-
.. doxygenfunction:: bsp_abort
275+
.. doxygenfunction:: bsp_stream_seek
318276
:project: ebsp_e

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070

7171
# General information about the project.
7272
project = 'Epiphany BSP'
73-
copyright = '2015, Coduin'
73+
copyright = '2015-2017, Coduin'
7474
author = 'Coduin'
7575

7676
# The version info for the project you're documenting, acts as replacement for
@@ -80,7 +80,7 @@
8080
# The short X.Y version.
8181
version = '1.0'
8282
# The full version, including alpha/beta/rc tags.
83-
release = '1.0-beta'
83+
release = '1.0'
8484

8585
# google analytics ID
8686
googleanalytics_id = 'UA-59249373-1'

docs/streaming.rst

Lines changed: 50 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -9,127 +9,107 @@ Streaming
99

1010
When dealing with problems that involve a lot of data such as images or large matrices, it is often the case that the data for the problem does not fit on the combined local memory of the Epiphany processor. In order to work with the data we must then use the larger (but much slower) external memory, which slows the programs down tremendously.
1111

12-
For these situations we provide a *streaming* mechanism. When writing your program to use streams, it will work on smaller chunks of the problem at any given time -- such that the data currently being treated is always local to the core. The EBSP library prepares the next chunk to work on while the previous chunk is being processed such that there is minimal downtime because the Epiphany cores are waiting for the slow external memory.
12+
For these situations we provide a *streaming* mechanism. When writing your program to use streams, it will work on smaller tokens of the problem at any given time -- such that the data currently being treated is always local to the core. The EBSP library prepares the next token to work on while the previous token is being processed such that there is minimal downtime because the Epiphany cores are waiting for the slow external memory.
1313

1414
Making and using down streams
1515
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1616

17-
There are two types of streams, *up* and *down* streams. A *down* stream contains data to be processed by an Epiphany core, while an *up* stream contains results from computations performed by the Epiphany core. Every stream (both up and down) has a *target processor*, *total size* and a *chunk size*. The target processor is simply the processor id of the core that should receive the content of the stream. The total size is the total number of bytes of the entire set of data. This set of data then gets partitioned into chunks consisting of the number of bytes set by the chunk size. This size need not be constant (i.e. it may vary over a single stream), but for our discussion here we will assume that it is constant.
17+
A stream contains data to be processed by an Epiphany core, and can also be used to obtain results from computations performed by the Epiphany core. Every stream has a *total size* and a *token size*. The total size is the total number of bytes of the entire set of data. This set of data then gets partitioned into tokens consisting of the number of bytes set by the token size. This size need not be constant (i.e. it may vary over a single stream), but for our discussion here we will assume that it is constant.
1818

19-
A stream is created before the call to ``ebsp_spmd`` on the host processor. The host prepares the data to be processed by the Epiphany cores, and the EBSP library then performs the necessary work needed for each core to receives its chunk. Note that this data is copied efficiently to the external memory upon creation of the stream, so that the user data should be stored in the ordinary RAM, e.g. allocated by a call to ``malloc``. A stream is created as follows::
19+
A stream is created before the call to ``ebsp_spmd`` on the host processor. The host prepares the data to be processed by the Epiphany cores, and the EBSP library then performs the necessary work needed for each core to receives its token. Note that this data is copied efficiently to the external memory upon creation of the stream, so that the user data should be stored in the ordinary RAM, e.g. allocated by a call to ``malloc``. A stream is created as follows::
2020

21-
// on the host
21+
// (on the host)
2222
int count = 256;
23-
int count_in_chunk = 32;
23+
int count_in_token = 32;
2424
float* data = malloc(count * sizeof(float));
2525
// ... fill data
26-
for (int s = 0; s < bsp_nprocs(); s++) {
27-
ebsp_create_down_stream(&data, s, count * sizeof(float),
28-
count_in_chunk * sizeof(float));
29-
}
30-
31-
This will create ``bsp_nprocs()`` identical streams containing user data, one for each core. These streams are chopped up in ``256/32 = 8`` chunks. If you want to use these streams in the kernel you need to *open* them and *move chunks* from a stream to the local memory. Every stream you create on the host gets is identified by the order in which they are created. For example, the stream we created above will obtain the id ``0`` on every core. A second stream (regardless of whether it is up or down) will be identified with ``1``, etc. *These identifiers are shared between up and down streams, but not between cores*. Opening a stream is done by using this identifier::
26+
bsp_stream_create(count * sizeof(float), count_in_token * sizeof(float), data);
3227

33-
// in the kernel
34-
float* address = NULL;
35-
ebsp_open_down_stream(&(void*)address, // a pointer to the address store
36-
0); // the stream identifier
28+
This will create a stream containing user data. This stream is chopped up in ``256/32 = 8`` tokens. If you want to use this streams in the kernel of a core you need to *open* it and *move tokens* from a stream to the local memory. Every stream you create on the host gets is identified by the order in which they are created, starting from index ``0``. For example, the stream we created above will obtain the id ``0``. A second stream (regardless of whether it is up or down) will be identified with ``1``, etc. *These identifiers are shared between cores*. Opening a stream is done by using this identifier, for example, to open a stream with identifier ``3``::
3729

38-
After this call, address will contain the location in the local memory of the first chunk, but the data is not necessarily there yet (it might still be copying). To ensure that the data has been received we *move* a chunk::
30+
bsp_stream mystream;
31+
if(bsp_stream_open(&mystream, 3)) {
32+
// ...
33+
}
3934

40-
int double_buffer = 1;
41-
ebsp_move_chunk_down(&(void*)address, 0, double_buffer);
35+
After this call, the stream will start copying data to the core, but the data is not necessarily there yet (it might still be copying). A stream can only be opened by *a single core at a time*. To access this data we *move* a token::
4236

43-
The first two arguments are identical to those of ``ebsp_open_down_stream``. The ``double_buffer`` argument gives you the option to start writing the next chunk to local memory (using the DMA engine), while you process the current chunk that just moved down. This can be done simultaneously to your computations, but will take up twice as much memory. It depends on the specific situation whether double_buffered mode should be turned on or off. Subsequent blocks are obtained using repeated calls to ``ebsp_move_chunk_down``.
37+
// Get some data
38+
void* buffer = NULL;
39+
bsp_stream_move_down(&mystream, &buffer, 0);
40+
// The data is now in buffer
4441

45-
If you want to use a chunk multiple times at different stages of your algorithm, you need to be able to instruct EBSP to change which chunk you want to obtain. Internally the EBSP system has a *cursor* for each stream which points to the next chunk that should be obtained. You can modify this cursor using the following two functions::
42+
The first argument is the stream object that was filled using ``bsp_stream_open``. The second argument is a pointer to a pointer that will be set to the data location. The final ``double_buffer`` argument, gives you the option to start writing the next token to local memory (using the DMA engine), while you process the current token that you just moved down. This can be done simultaneously to your computations, but will take up twice as much memory. It depends on the specific situation whether double buffered mode should be turned on or off. Subsequent blocks are obtained using repeated calls to ``bsp_stream_move_down``.
4643

47-
// reset the cursor of the first stream to its first chunk
48-
ebsp_reset_down_cursor(0);
44+
If you want to use a token multiple times at different stages of your algorithm, you need to be able to instruct EBSP to change which token you want to obtain. Internally the EBSP system has a *cursor* for each stream which points to the next token that should be obtained. You can modify this cursor using the following two functions::
4945

50-
// move the cursor of the first stream forward by 5 chunks
51-
ebsp_move_down_cursor(0, 5);
46+
// move the cursor of the stream forward by 5 tokens
47+
bsp_stream_seek(&mystream, 5);
5248

53-
// move the cursor of the first stream back by 3 chunks
54-
ebsp_move_down_cursor(0, -3);
49+
// move the cursor of the stream back by 3 tokens
50+
bsp_stream_seek(&mystream, -3);
5551

56-
Note that this gives you random access inside your streams. Therefore our streaming approach should actually be called *pseudo-streaming*, because formally streaming algorithms only process chunks in a stream a constant number of times. However on the Epiphany we can provide random-access in our streams, leading to different semantics such as moving the cursor.
52+
When you exceed the bounds of the stream, it will be set to the final or first token respectively. Note that this gives you random access inside your streams. Therefore our streaming approach should actually be called *pseudo-streaming*, because formally streaming algorithms only process tokens in a stream a constant number of times. However on the Epiphany we can provide random-access in our streams, opening the door to different semantics such as moving the cursor.
5753

5854
Moving results back up
5955
^^^^^^^^^^^^^^^^^^^^^^
6056

61-
Up streams work very similar to down streams, however no data has to be supplied by the host since it is generated by the Epiphany. We construct an up stream in the following way::
62-
63-
// on the host
64-
// .. create up stream (see above)
65-
void* upstream_data = malloc(sizeof(void*) * bsp_nprocs());
66-
for (int s = 0; s < bsp_nprocs(); s++) {
67-
upstream_data[s] = ebsp_create_up_stream(
68-
s, chunks * chunksize, chunks);
69-
}
57+
A stream can also be used to move results back up, for example::
7058

71-
The array ``upstream_data`` holds pointers to the generated data by each processor. In the kernel you can *open* these streams similarly to down streams::
59+
int* buffer1 = ebsp_malloc(100 * sizeof(int));
60+
int* buffer2 = ebsp_malloc(100 * sizeof(int));
61+
int* curbuffer = buffer1;
62+
int* otherbuffer = buffer2;
7263

73-
// in the kernel
74-
float* up_address = NULL;
75-
ebsp_open_up_stream(&(void*)up_address, // a pointer to the address store
76-
1); // the stream identifier
64+
ebsp_stream s;
65+
bsp_stream_open(&s, 0); // open stream 0
66+
while (...) {
67+
// Fill curbuffer
68+
for (int i = 0; i < 100; i++)
69+
curbuffer[i] = 5;
7770

78-
Note that this stream has the identifier ``1`` on each core. The up_address now points to a portion of *local memory* that you can fill with data from the kernel. To move a chunk of results up we use::
79-
80-
int double_buffer = 1;
81-
ebsp_move_chunk_up(&(void*)up_address, 1, double_buffer);
71+
// Send up
72+
bsp_stream_move_up(&s, curbuffer, 100 * sizeof(int), 0);
73+
// Use other bufferfer
74+
swap(curbuffer, otherbuffer);
75+
}
76+
ebsp_free(buffer1);
77+
ebsp_free(buffer2);
8278

83-
If we use a double buffer, then after this call ``up_address`` will point to a new portion of memory, such that you can continue your operations while the previous chunk is being copied up. Again, this uses more local memory, but does allow you to continue processing the next chunk.
79+
Here, we have two buffers containing data. While filling one of the buffers with data, we move the other buffer up. We do this using the ``bsp_stream_move_up`` function which has as arguments respectively: the stream handle, the data to send up, the size of the data to send up, and a flag that indicates whether we want to *wait for completion*. In this case, we do not wait, but use two buffers to perform computations and to send data up to the host simulatenously.
8480

8581
Closing streams
8682
^^^^^^^^^^^^^^^
8783

8884
The EBSP stream system allocates buffers for you on the cores. When you are done with a stream you should tell the EBSP system by calling::
8985

90-
ebsp_close_down_stream(0);
91-
ebsp_close_up_stream(0);
86+
bsp_stream_close(&my_stream);
9287

93-
which will free the buffers for other use.
88+
which will free the buffers for other use, and allow other cores to use the streams.
9489

9590
Interface
9691
------------------
9792

9893
Host
9994
^^^^
10095

101-
.. doxygenfunction:: ebsp_create_down_stream
102-
:project: ebsp_host
103-
104-
.. doxygenfunction:: ebsp_create_up_stream
96+
.. doxygenfunction:: bsp_stream_create
10597
:project: ebsp_host
10698

10799
Epiphany
108100
^^^^^^^^
109101

110-
.. doxygenfunction:: ebsp_open_down_stream
111-
:project: ebsp_e
112-
113-
.. doxygenfunction:: ebsp_open_up_stream
114-
:project: ebsp_e
115-
116-
.. doxygenfunction:: ebsp_close_down_stream
117-
:project: ebsp_e
118-
119-
.. doxygenfunction:: ebsp_close_up_stream
120-
:project: ebsp_e
121-
122-
.. doxygenfunction:: ebsp_move_chunk_up
102+
.. doxygenfunction:: bsp_stream_open
123103
:project: ebsp_e
124104

125-
.. doxygenfunction:: ebsp_move_chunk_down
105+
.. doxygenfunction:: bsp_stream_close
126106
:project: ebsp_e
127107

128-
.. doxygenfunction:: ebsp_move_down_cursor
108+
.. doxygenfunction:: bsp_stream_move_up
129109
:project: ebsp_e
130110

131-
.. doxygenfunction:: ebsp_reset_down_cursor
111+
.. doxygenfunction:: bsp_stream_move_down
132112
:project: ebsp_e
133113

134-
.. doxygenfunction:: ebsp_set_up_chunk_size
114+
.. doxygenfunction:: bsp_stream_seek
135115
:project: ebsp_e

0 commit comments

Comments
 (0)