Skip to content

Commit 63ed30d

Browse files
committed
Added 2nd Flooding Example
1 parent 8c9cf47 commit 63ed30d

File tree

2 files changed

+337
-1
lines changed

2 files changed

+337
-1
lines changed

EXAMPLES/EX_DREG_FLOODING2.hpp

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
#include <scamp5.hpp>
2+
#include <random>
3+
#include "MISC/MISC_FUNCS.hpp"
4+
using namespace SCAMP5_PE;
5+
6+
vs_stopwatch frame_timer;
7+
vs_stopwatch output_timer;
8+
vs_stopwatch flooding_timer;
9+
vs_stopwatch drawing_timer;
10+
11+
int main()
12+
{
13+
vs_init();
14+
15+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16+
//SETUP IMAGE DISPLAYS
17+
18+
const int disp_size = 2;
19+
auto display_00 = vs_gui_add_display("Flooding source",0,0,disp_size);
20+
auto display_01 = vs_gui_add_display("Mask",0,disp_size,disp_size);
21+
auto display_02 = vs_gui_add_display("Source After Flooding",0,disp_size*2,disp_size);
22+
23+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24+
//SETUP GUI ELEMENTS & CONTROLLABLE VARIABLES
25+
26+
bool generate_boxes = true;
27+
vs_handle gui_button_generate_boxes = vs_gui_add_button("generate boxes");
28+
vs_on_gui_update(gui_button_generate_boxes,[&](int32_t new_value)//function that will be called whenever button is pressed
29+
{
30+
generate_boxes = true;//trigger generation of boxes
31+
});
32+
33+
//control the box drawn into DREG & used as the flooding Source
34+
int flood_source_box_x, flood_source_box_y,flood_source_box_width,flood_source_box_height;
35+
vs_gui_add_slider("flood_source_box_x: ",1,255,64,&flood_source_box_x);
36+
vs_gui_add_slider("flood_source_box_y: ",1,255,125,&flood_source_box_y);
37+
vs_gui_add_slider("flood_source_box_width: ",1,100,20,&flood_source_box_width);
38+
vs_gui_add_slider("flood_source_box_height: ",1,100,20,&flood_source_box_height);
39+
40+
//The number of iterations performed, determines the extent/distance flooding can reach
41+
int flood_iterations = 10;
42+
vs_gui_add_slider("flood_iterations", 0,20,flood_iterations,&flood_iterations);
43+
44+
//Select if the borders of the PE array/image act as Sources of 1s during flooding
45+
int flood_from_borders = 0;
46+
vs_gui_add_switch("flood_from_borders",false,&flood_from_borders);
47+
48+
//Add switches for selecting the content of the RN,RS,RE,RW DREG
49+
//These registers control the directions from which each PE can be flooded with 1s from
50+
int set_RN = 1;
51+
vs_gui_add_switch("set_RN",set_RN == 1,&set_RN);
52+
int set_RS = 1;
53+
vs_gui_add_switch("set_RS",set_RS == 1,&set_RS);
54+
int set_RE = 1;
55+
vs_gui_add_switch("set_RE",set_RE == 1,&set_RE);
56+
int set_RW = 1;
57+
vs_gui_add_switch("set_RW",set_RW == 1,&set_RW);
58+
59+
//Switch between performing flooding using native commands or with the library Macro
60+
int use_api = 0;
61+
vs_gui_add_switch("use_api",use_api == 1,&use_api);
62+
63+
//Use a fixed single kernel flooding routine to demonstrate maximum speed
64+
int single_kernel_flood_example = 0;
65+
vs_gui_add_switch("use_single_kernel",single_kernel_flood_example == 1,&single_kernel_flood_example);
66+
67+
int negate_mask = 0;
68+
vs_gui_add_switch("negate_mask",negate_mask == 1,&negate_mask);
69+
70+
//Setup objects for random number generation
71+
//This code looks like nonsense as the std classes here overload the function call operator...
72+
std::random_device rd;//A true random number
73+
std::mt19937 gen(rd()); // Mersenne Twister pseudo random number generator, seeded with a true random number
74+
int random_min_value = 0;
75+
int random_max_value = 255;
76+
//Create distribution object that can be used to map a given random value to a value of the distribution
77+
std::uniform_int_distribution<> distr(random_min_value, random_max_value);
78+
79+
//CONTINOUS FRAME LOOP
80+
while(true)
81+
{
82+
frame_timer.reset();//reset frame_timer
83+
84+
vs_disable_frame_trigger();
85+
vs_frame_loop_control();
86+
87+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
88+
//GENERATES RANDOM BOXES IN DREG S0 IF BUTTON WAS PRESSED (OR PROGRAM JUST STARTED)
89+
90+
if(generate_boxes)
91+
{
92+
const int boxes_to_add = 50;
93+
const int boxes_to_subtract = 25;
94+
95+
//Generate a set of random rectangles across DREG plane S0
96+
{
97+
scamp5_kernel_begin();
98+
CLR(S0); //Clear content of S0
99+
scamp5_kernel_end();
100+
for(int n = 0 ; n < boxes_to_add ; n++)
101+
{
102+
//Load box of random location and dimensions into S5
103+
int pos_x = distr(gen);
104+
int pos_y = distr(gen);
105+
int width = 1+distr(gen)/6;
106+
int height = 1+distr(gen)/6;
107+
DREG_load_centered_rect(S5,pos_x,pos_y,width,height);
108+
scamp5_kernel_begin();
109+
OR(S0,S5);//Add box in S5 to content of S0
110+
scamp5_kernel_end();
111+
}
112+
}
113+
//
114+
// //Generate another set of random rectangles across DREG plane S1
115+
// scamp5_kernel_begin();
116+
// CLR(S6); //Clear content of S1
117+
// scamp5_kernel_end();
118+
// for(int n = 0 ; n < boxes_to_subtract ; n++)
119+
// {
120+
// //Load box of random location and dimensions into S5
121+
// int pos_x = distr(gen);
122+
// int pos_y = distr(gen);
123+
// int width = 1+distr(gen)/5;
124+
// int height = 1+distr(gen)/5;
125+
// DREG_load_centered_rect(S5,pos_x,pos_y,width,height);
126+
// scamp5_kernel_begin();
127+
// OR(S6,S5);//Add box in S5 to content of S0
128+
// scamp5_kernel_end();
129+
// }
130+
//
131+
// //Subtract the rectangles in S1 from those of S2
132+
// scamp5_kernel_begin();
133+
// NOT(S5,S6);//S5 = Inverted content of S1
134+
// AND(S0,S5,S0);//perform AND to "Subtract" S1 rectangles from S0
135+
// scamp5_kernel_end();
136+
137+
generate_boxes = false;
138+
}
139+
140+
//Create a copy or negated copy of these rectangles to use as the flooding mask
141+
if(negate_mask)
142+
{
143+
scamp5_kernel_begin();
144+
NOT(S4,S0);
145+
scamp5_kernel_end();
146+
}
147+
else
148+
{
149+
scamp5_kernel_begin();
150+
MOV(S4,S0);
151+
scamp5_kernel_end();
152+
}
153+
154+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
155+
//DRAW CONTENT INTO DIGITAL REGISTERS FOR FLOODING EXAMPLE
156+
157+
drawing_timer.reset();
158+
159+
//Draw content to use as the Flooding Source, Flooding orginates from PEs in which Source = 1
160+
DREG_load_centered_rect(S1,flood_source_box_x,flood_source_box_y,flood_source_box_width,flood_source_box_height);
161+
scamp5_kernel_begin();
162+
MOV(S3,S1);
163+
scamp5_kernel_end();
164+
165+
int time_spent_drawing = drawing_timer.get_usec();
166+
167+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
168+
//SET DNEWS DREG WHICH CONTROL THE DIRECTIONS IN WHICH FLOODING MAY OCCUR WITHIN EACH PE
169+
170+
scamp5_kernel_begin();
171+
CLR(RN,RS,RE,RW);//Set all DNEWS DREG = 0 in all PEs
172+
scamp5_kernel_end();
173+
174+
if(set_RN)
175+
{
176+
scamp5_kernel_begin();
177+
SET(RN);//Set all RN = 1 in all PEs
178+
scamp5_kernel_end();
179+
}
180+
if(set_RS)
181+
{
182+
scamp5_kernel_begin();
183+
SET(RS);//Set all RS = 1 in all PEs
184+
scamp5_kernel_end();
185+
}
186+
if(set_RE)
187+
{
188+
scamp5_kernel_begin();
189+
SET(RE);//Set all RE = 1 in all PEs
190+
scamp5_kernel_end();
191+
}
192+
if(set_RW)
193+
{
194+
scamp5_kernel_begin();
195+
SET(RW);//Set all RW = 1 in all PEs
196+
scamp5_kernel_end();
197+
}
198+
199+
200+
201+
202+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
203+
//DEMONSTRATE FLOODING
204+
205+
flooding_timer.reset();
206+
207+
//FLOODING USING SCAMP LIBRARY FUNCTION
208+
if(!use_api && !single_kernel_flood_example)
209+
{
210+
//Perform flooding using native instructions
211+
//RF acts as the Source register, PEs where RF = 1 will spread 1s into RF registers of neighbouring PEs during flooding
212+
//RP acts as the Mask register, which restricts flooding to only those PEs where RP = 1
213+
scamp5_kernel_begin();
214+
MOV(RP,S1);//Copy the content of S1 into the Flooding Source RP
215+
MOV(RF,S4);//Copy the content of S2 into the Flooding Mask RF
216+
scamp5_kernel_end();
217+
218+
if(flood_from_borders)
219+
{
220+
for(int n = 0 ; n < flood_iterations ; n++)
221+
{
222+
scamp5_kernel_begin();
223+
PROP1();//Propagate 1s from both Flooding Source and boundaries of the Array
224+
scamp5_kernel_end();
225+
}
226+
}
227+
else
228+
{
229+
for(int n = 0 ; n < flood_iterations ; n++)
230+
{
231+
scamp5_kernel_begin();
232+
PROP0();//Propagate 1s from both Flooding Source
233+
scamp5_kernel_end();
234+
}
235+
}
236+
237+
scamp5_kernel_begin();
238+
MOV(S1,RP);//Copy the result of Flooding into S1
239+
SET(RF);//Reset RF = 1 in all PEs
240+
scamp5_kernel_end();
241+
}
242+
243+
244+
245+
246+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
247+
248+
249+
250+
251+
//FLOODING USING A SINGLE SCAMP KERNEL
252+
if(!use_api && single_kernel_flood_example)
253+
{
254+
//Example of performing flooding using native instructions
255+
//By only using a single Kernel this code is more efficient however the number of flooding iterations is fixed
256+
scamp5_kernel_begin();
257+
MOV(RP,S1);//Copy the content of S1 into the Flooding Source RP
258+
MOV(RF,S4);//Copy the content of S2 into the Flooding Mask RF
259+
for(int n = 0 ; n < 12 ; n++)
260+
{
261+
PROP0();//Propagate 1s from both Flooding Source
262+
}
263+
MOV(S1,RP);//Copy the result of Flooding into S1
264+
SET(RF);//Reset RF = 1 in all PEs
265+
scamp5_kernel_end();
266+
}
267+
268+
269+
270+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
271+
272+
273+
274+
275+
//FLOODING USING SCAMP LIBRARY FUNCTION
276+
if(use_api)
277+
{
278+
//Perform flooding using provided scamp library function
279+
//Floods the Source DREG (S1), restricted by the Mask DREG, for a given number of steps/iterations
280+
scamp5_flood(S1,S4,flood_from_borders,flood_iterations);
281+
}
282+
283+
284+
int time_spent_flooding = flooding_timer.get_usec();
285+
286+
287+
scamp5_kernel_begin();
288+
REFRESH(S0);
289+
REFRESH(S1);
290+
REFRESH(S2);
291+
scamp5_kernel_end();
292+
293+
294+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
295+
//OUTPUT THE BOUNDING BOX OF THE FLOODED SHAPE
296+
297+
uint8_t bb_data [4];
298+
scamp5_output_boundingbox(S1,display_00,bb_data);
299+
scamp5_display_boundingbox(display_01,bb_data,1);
300+
scamp5_display_boundingbox(display_02,bb_data,1);
301+
302+
int bb_top = bb_data[0];
303+
int bb_bottom = bb_data[2];
304+
int bb_left = bb_data[1];
305+
int bb_right = bb_data[3];
306+
307+
int bb_width = bb_right-bb_left;
308+
int bb_height = bb_bottom-bb_top;
309+
int bb_center_x = (bb_left+bb_right)/2;
310+
int bb_center_y = (bb_top+bb_bottom)/2;
311+
312+
vs_post_text("bounding box data X:%d Y:%d W:%d H:%d\n",bb_center_x,bb_center_y,bb_width,bb_height);
313+
314+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
315+
//OUTPUT IMAGES
316+
317+
output_timer.reset();
318+
319+
scamp5_output_image(S3,display_00);
320+
scamp5_output_image(S0,display_01);
321+
scamp5_output_image(S1,display_02);
322+
int output_time_microseconds = output_timer.get_usec();//get the time taken for image output
323+
324+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
325+
//OUTPUT TEXT INFO
326+
327+
int frame_time_microseconds = frame_timer.get_usec(); //get the time taken this frame
328+
int max_possible_frame_rate = 1000000/frame_time_microseconds; //calculate the possible max FPS
329+
int image_output_time_percentage = (output_time_microseconds*100)/frame_time_microseconds; //calculate the % of frame time which is used for image output
330+
vs_post_text("time spent drawing %d \n",time_spent_drawing);
331+
vs_post_text("time spent flooding %d \n",time_spent_flooding);
332+
vs_post_text("frame time %d microseconds(%%%d image output), potential FPS ~%d \n",frame_time_microseconds,image_output_time_percentage,max_possible_frame_rate); //display this values on host
333+
}
334+
return 0;
335+
}

scamp5_main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//#include "EXAMPLES/EX_AREG_SATURATION.hpp"
77
//#include "EXAMPLES/EX_DREG_BOUNDING_BOX.hpp"
88
//#include "EXAMPLES/EX_DREG_FLOODING.hpp"
9+
#include "EXAMPLES/EX_DREG_FLOODING2.hpp"
910
//#include "EXAMPLES/EX_DREG_LOAD_PATTERN.hpp"
1011
//#include "EXAMPLES/EX_DREG_SHIFTING1.hpp"
1112
//#include "EXAMPLES/EX_DREG_SHIFTING2.hpp"
@@ -16,7 +17,7 @@
1617
//#include "EXAMPLES/EX_OPTIMIZING_AREG_SHIFT.hpp"
1718
//#include "EXAMPLES/EX_RF_AND_RM.hpp"
1819
//#include "EXAMPLES/EX_SHAPE_EXTRACTION.hpp"
19-
#include "EXAMPLES/EX00_IMAGE_CAPTURE.hpp"
20+
//#include "EXAMPLES/EX00_IMAGE_CAPTURE.hpp"
2021
//#include "EXAMPLES/EX01_IMAGE_CAPTURE_AND_AREG.hpp"
2122
//#include "EXAMPLES/EX02_DREG_BASICS.hpp"
2223
//#include "EXAMPLES/EX03_FLAG.hpp"

0 commit comments

Comments
 (0)