Skip to content

Commit ff1c22d

Browse files
committed
Added more unit test cases for the partition regions intersection function
1 parent 92f267b commit ff1c22d

File tree

5 files changed

+224
-42
lines changed

5 files changed

+224
-42
lines changed

vpr/src/base/partition_regions.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
#include "partition_regions.h"
22

3-
PartitionRegions PartitionRegions::get_intersection(PartitionRegions region) {
4-
//region is a vector of regions, part_regions is another vector of regions
5-
//have to intersect the regions and return their intersection
3+
PartitionRegions PartitionRegions::get_intersection(PartitionRegions part_region) {
4+
/**for N regions in part_region and M in the calling object you can get anywhere from
5+
* 0 to M*N regions in the resulting vector. Only regions with non-zero area rectangles and
6+
* equivalent subtiles are put in the resulting vector
7+
* Rectangles are not merged even if it would be possible
8+
*/
69
PartitionRegions pr;
710
Region intersect_region;
811
bool regions_intersect;
912
for (unsigned int i = 0; i < partition_regions.size(); i++) {
10-
for (unsigned int j = 0; j < region.partition_regions.size(); j++) {
11-
regions_intersect = partition_regions[i].do_regions_intersect(region.partition_regions[j]);
13+
for (unsigned int j = 0; j < part_region.partition_regions.size(); j++) {
14+
regions_intersect = partition_regions[i].do_regions_intersect(part_region.partition_regions[j]);
1215
if (regions_intersect) {
13-
intersect_region = partition_regions[i].regions_intersection(region.partition_regions[j]);
16+
intersect_region = partition_regions[i].regions_intersection(part_region.partition_regions[j]);
1417
pr.partition_regions.push_back(intersect_region);
1518
}
1619
}

vpr/src/base/partition_regions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class PartitionRegions {
1515
/**
1616
* Returns the intersection of two PartitionRegions vectors that are passed to it.
1717
*/
18-
PartitionRegions get_intersection(PartitionRegions region);
18+
PartitionRegions get_intersection(PartitionRegions part_region);
1919

2020
//method to add to the partition_regions vector
2121
void add_to_part_regions(Region region);

vpr/src/base/region.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,19 @@ bool Region::do_regions_intersect(Region region) {
6969
Region Region::regions_intersection(Region region) {
7070
Region intersect;
7171

72-
vtr::Rect<int> region_rect = region.get_region_rect();
73-
vtr::Rect<int> intersect_rect;
74-
75-
intersect_rect = intersection(region_bounds, region_rect);
76-
77-
intersect.set_region_rect(intersect_rect.xmin(), intersect_rect.ymin(), intersect_rect.xmax(), intersect_rect.ymax());
72+
//if the subtiles do not match, there is no intersection
73+
//so, the control will go straight to returning intersect, which will just be a region with an empty rectangle
74+
//if the subtiles do match, then there will be an intersection as long as the rectangles overlap
75+
//and the intersection will be found by the code in the if statement
76+
//if they do not overlap, the intersection rectangle will still return an empty rectangle
7877
if (sub_tile == region.get_sub_tile()) {
7978
intersect.set_sub_tile(sub_tile);
79+
vtr::Rect<int> region_rect = region.get_region_rect();
80+
vtr::Rect<int> intersect_rect;
81+
82+
intersect_rect = intersection(region_bounds, region_rect);
83+
84+
intersect.set_region_rect(intersect_rect.xmin(), intersect_rect.ymin(), intersect_rect.xmax(), intersect_rect.ymax());
8085
}
8186

8287
return intersect;
@@ -99,3 +104,7 @@ bool Region::locked() {
99104

100105
return locked = true;
101106
}
107+
108+
bool Region::empty() {
109+
return region_bounds.empty();
110+
}

vpr/src/base/region.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ class Region {
2626

2727
void set_sub_tile(int _sub_tile);
2828

29+
//function to see if region is empty
30+
//checks if the Rect of the region is empty
31+
bool empty();
32+
2933
//function to see if two regions intersect anywhere
3034
bool do_regions_intersect(Region region);
3135

@@ -39,7 +43,7 @@ class Region {
3943
private:
4044
//may need to include zmin, zmax for future use in 3D FPGA designs
4145
vtr::Rect<int> region_bounds; //xmin, ymin, xmax, ymax inclusive
42-
int sub_tile; //users will optionally select a subtile, will select if they want to lock down block to specific location
46+
int sub_tile; //users will optionally select a subtile
4347
};
4448

4549
#endif /* REGION_H */

vpr/test/test_vpr_constraints.cpp

Lines changed: 194 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,34 @@ TEST_CASE("RegionIntersect", "[vpr]") {
159159
REQUIRE(rect_2.xmax() == 8);
160160
REQUIRE(rect_2.ymax() == 6);
161161

162-
//Test no intersection (rect is empty)
162+
//Test no intersection (rectangles don't overlap, intersect region will be returned empty)
163163

164164
Region int_reg_3;
165165

166166
int_reg_3 = region1.regions_intersection(region3);
167-
vtr::Rect<int> rect_3 = int_reg_3.get_region_rect();
168167

169-
REQUIRE(rect_3.empty() == TRUE);
168+
REQUIRE(int_reg_3.empty() == TRUE);
169+
170+
//Test no intersection (rectangles overlap but different subtiles are specified, intersect region will be returned empty)
171+
region1.set_sub_tile(5);
172+
region2.set_sub_tile(3);
173+
174+
Region int_reg_4;
175+
int_reg_4 = region1.regions_intersection(region2);
176+
177+
REQUIRE(int_reg_4.empty() == TRUE);
178+
179+
//Test intersection where subtiles are the same and equal to something other than the INVALID value
180+
region1.set_sub_tile(6);
181+
region2.set_sub_tile(6);
182+
183+
Region int_reg_5;
184+
int_reg_5 = region1.regions_intersection(region2);
185+
vtr::Rect<int> rect_5 = int_reg_5.get_region_rect();
186+
REQUIRE(rect_5.xmin() == 2);
187+
REQUIRE(rect_5.ymin() == 3);
188+
REQUIRE(rect_5.xmax() == 3);
189+
REQUIRE(rect_5.ymax() == 5);
170190
}
171191

172192
TEST_CASE("PartRegionIntersect", "[vpr]") {
@@ -201,61 +221,207 @@ TEST_CASE("PartRegionIntersect", "[vpr]") {
201221
REQUIRE(regions[1].get_ymax() == 2);
202222
}
203223

204-
TEST_CASE("RegionLocked", "[vpr]") {
224+
TEST_CASE("PartRegionIntersect2", "[vpr]") {
225+
PartitionRegions pr1;
226+
PartitionRegions pr2;
227+
205228
Region r1;
206-
bool is_r1_locked = false;
229+
Region r2;
230+
Region r3;
207231

208-
//set the region to a specific x, y, subtile location - region is locked
209-
r1.set_region_rect(2, 3, 2, 3); //point (2,3) to point (2,3) - locking to specific x, y location
210-
r1.set_sub_tile(3); //locking down to subtile 3
232+
r1.set_region_rect(0, 0, 2, 2);
233+
r2.set_region_rect(4, 4, 6, 6);
234+
r3.set_region_rect(0, 0, 2, 2);
211235

212-
is_r1_locked = r1.locked();
236+
pr1.add_to_part_regions(r1);
237+
pr1.add_to_part_regions(r2);
238+
pr2.add_to_part_regions(r3);
213239

214-
REQUIRE(is_r1_locked == true);
240+
PartitionRegions int_pr;
215241

216-
//do not set region to specific x, y location - region is not locked even if a subtile is specified
217-
r1.set_region_rect(2, 3, 5, 6); //point (2,3) to point (5,6) - not locking to specific x, y location
218-
r1.set_sub_tile(3); //locking down to subtile 3
242+
int_pr = pr1.get_intersection(pr2);
243+
std::vector<Region> regions = int_pr.get_partition_regions();
219244

220-
is_r1_locked = r1.locked();
245+
REQUIRE(regions.size() == 1);
246+
REQUIRE(regions[0].get_xmin() == 0);
247+
REQUIRE(regions[0].get_ymin() == 0);
248+
REQUIRE(regions[0].get_xmax() == 2);
249+
REQUIRE(regions[0].get_ymax() == 2);
250+
}
221251

222-
REQUIRE(is_r1_locked == false);
252+
//2x2 regions, no overlaps
253+
TEST_CASE("PartRegionIntersect3", "[vpr]") {
254+
PartitionRegions pr1;
255+
PartitionRegions pr2;
223256

224-
//do not specify a subtile for the region - region is not locked even if it is set at specific x, y location
257+
Region r1;
225258
Region r2;
226-
bool is_r2_locked = true;
259+
Region r3;
260+
Region r4;
227261

228-
r2.set_region_rect(2, 3, 2, 3);
262+
r1.set_region_rect(1, 2, 3, 5);
263+
r1.set_sub_tile(2);
229264

230-
is_r2_locked = r2.locked();
265+
r2.set_region_rect(4, 2, 6, 4);
231266

232-
REQUIRE(is_r2_locked == false);
267+
r3.set_region_rect(4, 5, 5, 7);
268+
269+
r4.set_region_rect(1, 2, 3, 5);
270+
r4.set_sub_tile(4);
271+
272+
pr1.add_to_part_regions(r1);
273+
pr1.add_to_part_regions(r2);
274+
pr2.add_to_part_regions(r3);
275+
pr2.add_to_part_regions(r4);
276+
277+
PartitionRegions int_pr;
278+
279+
int_pr = pr1.get_intersection(pr2);
280+
std::vector<Region> regions = int_pr.get_partition_regions();
281+
282+
REQUIRE(regions.size() == 0);
233283
}
234284

235-
TEST_CASE("PartRegionIntersect2", "[vpr]") {
285+
//2x2 regions, 1 overlap
286+
TEST_CASE("PartRegionIntersect4", "[vpr]") {
236287
PartitionRegions pr1;
237288
PartitionRegions pr2;
238289

239290
Region r1;
240291
Region r2;
241292
Region r3;
293+
Region r4;
242294

243-
r1.set_region_rect(0, 0, 2, 2);
244-
r2.set_region_rect(4, 4, 6, 6);
245-
r3.set_region_rect(0, 0, 2, 2);
295+
r1.set_region_rect(1, 2, 3, 5);
296+
r1.set_sub_tile(2);
297+
298+
r2.set_region_rect(4, 2, 6, 4);
299+
300+
r3.set_region_rect(4, 5, 5, 7);
301+
302+
r4.set_region_rect(1, 2, 3, 4);
303+
r4.set_sub_tile(2);
246304

247305
pr1.add_to_part_regions(r1);
248306
pr1.add_to_part_regions(r2);
249307
pr2.add_to_part_regions(r3);
308+
pr2.add_to_part_regions(r4);
250309

251310
PartitionRegions int_pr;
252311

253312
int_pr = pr1.get_intersection(pr2);
254313
std::vector<Region> regions = int_pr.get_partition_regions();
255314

315+
vtr::Rect<int> intersect(1, 2, 3, 4);
316+
256317
REQUIRE(regions.size() == 1);
257-
REQUIRE(regions[0].get_xmin() == 0);
258-
REQUIRE(regions[0].get_ymin() == 0);
259-
REQUIRE(regions[0].get_xmax() == 2);
260-
REQUIRE(regions[0].get_ymax() == 2);
318+
REQUIRE(regions[0].get_region_rect() == intersect);
319+
REQUIRE(regions[0].get_sub_tile() == 2);
320+
}
321+
322+
//2x2 regions, 2 overlap
323+
TEST_CASE("PartRegionIntersect5", "[vpr]") {
324+
PartitionRegions pr1;
325+
PartitionRegions pr2;
326+
327+
Region r1;
328+
Region r2;
329+
Region r3;
330+
Region r4;
331+
332+
r1.set_region_rect(1, 5, 5, 7);
333+
334+
r2.set_region_rect(6, 3, 8, 5);
335+
336+
r3.set_region_rect(2, 6, 4, 9);
337+
338+
r4.set_region_rect(6, 4, 8, 7);
339+
340+
pr1.add_to_part_regions(r1);
341+
pr1.add_to_part_regions(r2);
342+
pr2.add_to_part_regions(r3);
343+
pr2.add_to_part_regions(r4);
344+
345+
PartitionRegions int_pr;
346+
347+
int_pr = pr1.get_intersection(pr2);
348+
std::vector<Region> regions = int_pr.get_partition_regions();
349+
350+
vtr::Rect<int> int_r1r3(2, 6, 4, 7);
351+
vtr::Rect<int> int_r2r4(6, 4, 8, 5);
352+
353+
REQUIRE(regions.size() == 2);
354+
REQUIRE(regions[0].get_region_rect() == int_r1r3);
355+
REQUIRE(regions[1].get_region_rect() == int_r2r4);
356+
}
357+
358+
//2x2 regions, 4 overlap
359+
TEST_CASE("PartRegionIntersect6", "[vpr]") {
360+
PartitionRegions pr1;
361+
PartitionRegions pr2;
362+
363+
Region r1;
364+
Region r2;
365+
Region r3;
366+
Region r4;
367+
368+
r1.set_region_rect(2, 3, 4, 7);
369+
370+
r2.set_region_rect(5, 3, 7, 8);
371+
372+
r3.set_region_rect(2, 2, 7, 4);
373+
374+
r4.set_region_rect(2, 6, 7, 8);
375+
376+
pr1.add_to_part_regions(r1);
377+
pr1.add_to_part_regions(r2);
378+
pr2.add_to_part_regions(r3);
379+
pr2.add_to_part_regions(r4);
380+
381+
PartitionRegions int_pr;
382+
383+
int_pr = pr1.get_intersection(pr2);
384+
std::vector<Region> regions = int_pr.get_partition_regions();
385+
386+
vtr::Rect<int> int_r1r3(2, 3, 4, 4);
387+
vtr::Rect<int> int_r1r4(2, 6, 4, 7);
388+
vtr::Rect<int> int_r2r3(5, 3, 7, 4);
389+
vtr::Rect<int> int_r2r4(5, 6, 7, 8);
390+
391+
REQUIRE(regions.size() == 4);
392+
REQUIRE(regions[0].get_region_rect() == int_r1r3);
393+
REQUIRE(regions[1].get_region_rect() == int_r1r4);
394+
REQUIRE(regions[2].get_region_rect() == int_r2r3);
395+
REQUIRE(regions[3].get_region_rect() == int_r2r4);
396+
}
397+
398+
TEST_CASE("RegionLocked", "[vpr]") {
399+
Region r1;
400+
bool is_r1_locked = false;
401+
402+
//set the region to a specific x, y, subtile location - region is locked
403+
r1.set_region_rect(2, 3, 2, 3); //point (2,3) to point (2,3) - locking to specific x, y location
404+
r1.set_sub_tile(3); //locking down to subtile 3
405+
406+
is_r1_locked = r1.locked();
407+
408+
REQUIRE(is_r1_locked == true);
409+
410+
//do not set region to specific x, y location - region is not locked even if a subtile is specified
411+
r1.set_region_rect(2, 3, 5, 6); //point (2,3) to point (5,6) - not locking to specific x, y location
412+
r1.set_sub_tile(3); //locking down to subtile 3
413+
414+
is_r1_locked = r1.locked();
415+
416+
REQUIRE(is_r1_locked == false);
417+
418+
//do not specify a subtile for the region - region is not locked even if it is set at specific x, y location
419+
Region r2;
420+
bool is_r2_locked = true;
421+
422+
r2.set_region_rect(2, 3, 2, 3);
423+
424+
is_r2_locked = r2.locked();
425+
426+
REQUIRE(is_r2_locked == false);
261427
}

0 commit comments

Comments
 (0)