Skip to content

Commit b4ac6ad

Browse files
authored
Merge pull request #343 from SymbiFlow/master+wip-hackerfoo
recent lookahead sampling changes
2 parents 136ecda + 2a257ee commit b4ac6ad

File tree

8 files changed

+595
-384
lines changed

8 files changed

+595
-384
lines changed

libs/libvtrcapnproto/connection_map.capnp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@ struct VprVector2D {
1313
y @1 :Int64;
1414
}
1515

16+
struct VprFloatEntry {
17+
value @0 :Float32;
18+
}
19+
1620
struct VprCostMap {
1721
costMap @0 :Matrix.Matrix((Matrix.Matrix(VprCostEntry)));
1822
offset @1 :Matrix.Matrix(VprVector2D);
1923
segmentMap @2 :List(Int64);
24+
penalty @3 :Matrix.Matrix(VprFloatEntry);
2025
}

libs/libvtrutil/src/vtr_geometry.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#ifndef VTR_GEOMETRY_H
22
#define VTR_GEOMETRY_H
33
#include "vtr_range.h"
4+
#include "vtr_assert.h"
45

56
#include <vector>
67
#include <tuple>
78
#include <limits>
9+
#include <type_traits>
810

911
namespace vtr {
1012

@@ -78,7 +80,13 @@ class Rect {
7880
Rect();
7981
Rect(T left_val, T bottom_val, T right_val, T top_val);
8082
Rect(Point<T> bottom_left_val, Point<T> top_right_val);
81-
Rect(Point<T> bottom_left_val, T size);
83+
84+
//Constructs a rectangle that only contains the given point
85+
// Rect(p1).contains(p2) => p1 == p2
86+
//It is only enabled for integral types, because making this work for floating point types would be difficult and brittle.
87+
//The following line only enables the constructor if std::is_integral<T>::value == true
88+
template<typename U = T, typename std::enable_if<std::is_integral<U>::value>::type...>
89+
Rect(Point<U> point);
8290

8391
public: //Accessors
8492
//Co-ordinates
@@ -103,28 +111,41 @@ class Rect {
103111
bool coincident(Point<T> point) const;
104112

105113
//Returns true if no points are contained in the rectangle
114+
// rect.empty() => not exists p. rect.contains(p)
115+
// This also implies either the width or height is 0.
106116
bool empty() const;
107117

108118
friend bool operator== <>(const Rect<T>& lhs, const Rect<T>& rhs);
109119
friend bool operator!= <>(const Rect<T>& lhs, const Rect<T>& rhs);
110120

111-
template<class U>
112-
friend Rect<U> operator|(const Rect<U>& lhs, const Rect<U>& rhs);
113-
template<class U>
114-
friend Rect<U>& operator|=(Rect<U>& lhs, const Rect<U>& rhs);
115-
116121
public: //Mutators
117122
//Co-ordinates
118123
void set_xmin(T xmin_val);
119124
void set_ymin(T ymin_val);
120125
void set_xmax(T xmax_val);
121126
void set_ymax(T ymax_val);
122127

128+
//Equivalent to `*this = bounding_box(*this, other)`
129+
Rect<T>& expand_bounding_box(const Rect<T>& other);
130+
123131
private:
124132
Point<T> bottom_left_;
125133
Point<T> top_right_;
126134
};
127135

136+
//Return the smallest rectangle containing both given rectangles
137+
//Note that this isn't a union and the resulting rectangle may include points not in either given rectangle
138+
template<class T>
139+
Rect<T> bounding_box(const Rect<T>& lhs, const Rect<T>& rhs);
140+
141+
//Sample on a uniformly spaced grid within a rectangle
142+
// sample(vtr::Rect(l, h), 0, 0, M) == l
143+
// sample(vtr::Rect(l, h), M, M, M) == h
144+
//To avoid the edges, use `sample(r, x+1, y+1, N+1) for x, y, in 0..N-1
145+
//Only defined for integral types
146+
template<typename T, typename std::enable_if<std::is_integral<T>::value>::type...>
147+
Point<T> sample(const vtr::Rect<T>& r, T x, T y, T d);
148+
128149
//A 2D line
129150
template<class T>
130151
class Line {

libs/libvtrutil/src/vtr_geometry.tpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,13 @@ Rect<T>::Rect(Point<T> bottom_left_val, Point<T> top_right_val)
8080
//pass
8181
}
8282

83+
//Only defined for integral types
8384
template<class T>
84-
Rect<T>::Rect(Point<T> bottom_left_val, T size)
85-
: bottom_left_(bottom_left_val)
86-
, top_right_(bottom_left_val.x() + size,
87-
bottom_left_val.y() + size) {
85+
template<typename U, typename std::enable_if<std::is_integral<U>::value>::type...>
86+
Rect<T>::Rect(Point<U> point)
87+
: bottom_left_(point)
88+
, top_right_(point.x() + 1,
89+
point.y() + 1) {
8890
//pass
8991
}
9092

@@ -165,6 +167,22 @@ bool operator!=(const Rect<T>& lhs, const Rect<T>& rhs) {
165167
return !(lhs == rhs);
166168
}
167169

170+
template<class T>
171+
Rect<T> bounding_box(const Rect<T>& lhs, const Rect<T>& rhs) {
172+
return Rect<T>(std::min(lhs.xmin(), rhs.xmin()),
173+
std::min(lhs.ymin(), rhs.ymin()),
174+
std::max(lhs.xmax(), rhs.xmax()),
175+
std::max(lhs.ymax(), rhs.ymax()));
176+
}
177+
178+
//Only defined for integral types
179+
template<typename T, typename std::enable_if<std::is_integral<T>::value>::type...>
180+
Point<T> sample(const vtr::Rect<T>& r, T x, T y, T d) {
181+
VTR_ASSERT(d > 0);
182+
return Point<T>((r.xmin() * (d - x) + r.xmax() * x + d / 2) / d,
183+
(r.ymin() * (d - y) + r.ymax() * y + d / 2) / d);
184+
}
185+
168186
template<class T>
169187
void Rect<T>::set_xmin(T xmin_val) {
170188
bottom_left_.set_x(xmin_val);
@@ -186,16 +204,9 @@ void Rect<T>::set_ymax(T ymax_val) {
186204
}
187205

188206
template<class T>
189-
Rect<T> operator|(const Rect<T>& lhs, const Rect<T>& rhs) {
190-
return Rect<T>(std::min(lhs.xmin(), rhs.xmin()),
191-
std::min(lhs.ymin(), rhs.ymin()),
192-
std::max(lhs.xmax(), rhs.xmax()),
193-
std::max(lhs.ymax(), rhs.ymax()));
194-
}
195-
196-
template<class T>
197-
Rect<T>& operator|=(Rect<T>& lhs, const Rect<T>& rhs) {
198-
return lhs = lhs | rhs;
207+
Rect<T>& Rect<T>::expand_bounding_box(const Rect<T>& other) {
208+
*this = bounding_box(*this, other);
209+
return *this;
199210
}
200211

201212
/*

libs/libvtrutil/test/test_geometry.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ TEST_CASE("Rect", "[vtr_geometry/Rect]") {
6161
REQUIRE(r2.contains({6, 4}));
6262
REQUIRE_FALSE(r2.contains({100, 4}));
6363
REQUIRE_FALSE(r2.contains(pi_2));
64+
REQUIRE(vtr::Rect<int>(pi_1).contains(pi_1));
6465
}
6566

6667
SECTION("strictly_contains_int") {
@@ -78,7 +79,19 @@ TEST_CASE("Rect", "[vtr_geometry/Rect]") {
7879
}
7980

8081
SECTION("bounds_int") {
81-
REQUIRE(r1 == (r3 | r4));
82+
REQUIRE(r1 == bounding_box(r3, r4));
83+
}
84+
85+
SECTION("empty_int") {
86+
REQUIRE(vtr::Rect<int>().empty());
87+
}
88+
89+
SECTION("sample_int") {
90+
auto r = vtr::Rect<int>(pi_1, pi_2);
91+
REQUIRE(sample(r, 0, 0, 17) == pi_1);
92+
REQUIRE(sample(r, 17, 17, 17) == pi_2);
93+
auto inside = sample(r, 3, 11, 17);
94+
REQUIRE(r.contains(inside));
8295
}
8396
}
8497

@@ -92,6 +105,7 @@ TEST_CASE("Rect", "[vtr_geometry/Rect]") {
92105
vtr::Rect<float> r4(pf_1, pf_2);
93106
vtr::Rect<float> r5(pf_1, pf_3);
94107
vtr::Rect<float> r6(pf_3, pf_2);
108+
// vtr::Rect<float> r7(pf_1); // <-- will fail to compile
95109

96110
SECTION("equality_float") {
97111
REQUIRE(r3 == r4);
@@ -140,7 +154,11 @@ TEST_CASE("Rect", "[vtr_geometry/Rect]") {
140154
}
141155

142156
SECTION("bounds_float") {
143-
REQUIRE(r3 == (r5 | r6));
157+
REQUIRE(r3 == bounding_box(r5, r6));
158+
}
159+
160+
SECTION("empty_float") {
161+
REQUIRE(vtr::Rect<float>().empty());
144162
}
145163
}
146164
}

0 commit comments

Comments
 (0)