Skip to content

Commit

Permalink
drt: required updates in KDTree
Browse files Browse the repository at this point in the history
Signed-off-by: osamahammad21 <[email protected]>
  • Loading branch information
osamahammad21 committed Aug 6, 2024
1 parent 84322f6 commit 7de464f
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 78 deletions.
139 changes: 91 additions & 48 deletions src/drt/src/db/infra/KDTree.cpp
Original file line number Diff line number Diff line change
@@ -1,88 +1,131 @@
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, Precision Innovations Inc.
// All rights reserved.
//
// BSD 3-Clause License
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
///////////////////////////////////////////////////////////////////////////////

#include "KDTree.hpp"

#include <algorithm>
#include <cmath>

KDTree::KDTree(const std::vector<std::pair<int, int>>& points)
using odb::horizontal;
namespace drt {
KDTree::KDTree(const std::vector<Point>& points)
{
std::vector<std::pair<int, std::pair<int, int>>> points_with_ids;
std::vector<std::pair<int, Point>> points_with_ids;
points_with_ids.reserve(points.size());
for (int i = 0; i < points.size(); i++) {
for (int i = 0; i < points.size(); ++i) {
points_with_ids.emplace_back(i, points[i]);
}
root = buildTree(points_with_ids, 0);
}

std::vector<int> KDTree::radiusSearch(const std::pair<int, int>& target,
int radius) const
{
std::vector<int> result;
radiusSearchHelper(root, target, radius, 0, result);
return result;
root_ = buildTree(points_with_ids, horizontal);
}

KDTreeNode* KDTree::buildTree(
const std::vector<std::pair<int, std::pair<int, int>>>& points,
int depth)
std::unique_ptr<KDTreeNode> KDTree::buildTree(
const std::vector<std::pair<int, Point>>& points,
const Orientation2D& orient)
{
if (points.empty()) {
return nullptr;
}

auto sorted_points = points;
size_t axis = depth % 2;
std::sort(sorted_points.begin(),
sorted_points.end(),
[axis](const std::pair<int, std::pair<int, int>>& a,
const std::pair<int, std::pair<int, int>>& b) {
return axis == 0 ? a.second.first < b.second.first
: a.second.second < b.second.second;
});
std::sort(
sorted_points.begin(),
sorted_points.end(),
[orient](const std::pair<int, Point>& a, const std::pair<int, Point>& b) {
return orient == horizontal ? a.second.x() < b.second.x()
: a.second.y() < b.second.y();
});

size_t median_index = sorted_points.size() / 2;
KDTreeNode* node = new KDTreeNode(sorted_points[median_index].first,
sorted_points[median_index].second);
const size_t median_index = sorted_points.size() / 2;
std::unique_ptr<KDTreeNode> node = std::make_unique<KDTreeNode>(
sorted_points[median_index].first, sorted_points[median_index].second);

std::vector<std::pair<int, std::pair<int, int>>> left_points(
std::vector<std::pair<int, Point>> left_points(
sorted_points.begin(), sorted_points.begin() + median_index);
std::vector<std::pair<int, std::pair<int, int>>> right_points(
std::vector<std::pair<int, Point>> right_points(
sorted_points.begin() + median_index + 1, sorted_points.end());

node->left = buildTree(left_points, depth + 1);
node->right = buildTree(right_points, depth + 1);
const auto next_orient = orient.turn_90();
node->left = buildTree(left_points, next_orient);
node->right = buildTree(right_points, next_orient);

return node;
}

std::vector<int> KDTree::radiusSearch(const Point& target, int radius) const
{
std::vector<int> result;
const frSquaredDistance radius_square
= radius * static_cast<frSquaredDistance>(radius);
radiusSearchHelper(root_.get(), target, radius_square, horizontal, result);
return result;
}

void KDTree::radiusSearchHelper(KDTreeNode* node,
const std::pair<int, int>& target,
int radius,
int depth,
const Point& target,
const frSquaredDistance radius_square,
const Orientation2D& orient,
std::vector<int>& result) const
{
if (!node) {
return;
}

int distance = std::sqrt(std::pow(node->point.first - target.first, 2)
+ std::pow(node->point.second - target.second, 2));
if (distance <= radius) {
const frCoord dx = target.x() - node->point.x();
const frCoord dy = target.y() - node->point.y();
const frSquaredDistance distance_square
= dx * static_cast<frSquaredDistance>(dx)
+ dy * static_cast<frSquaredDistance>(dy);
if (distance_square <= radius_square) {
result.push_back(node->id);
}

size_t axis = depth % 2;
int diff = (axis == 0 ? target.first - node->point.first
: target.second - node->point.second);
const frCoord diff = (orient == horizontal) ? dx : dy;
const frSquaredDistance diff_square
= diff * static_cast<frSquaredDistance>(diff);

const auto next_orient = orient.turn_90();

if (diff < 0) {
radiusSearchHelper(node->left, target, radius, depth + 1, result);
if (std::abs(diff) <= radius) {
radiusSearchHelper(node->right, target, radius, depth + 1, result);
radiusSearchHelper(
node->left.get(), target, radius_square, next_orient, result);
if (diff_square <= radius_square) {
radiusSearchHelper(
node->right.get(), target, radius_square, next_orient, result);
}
} else {
radiusSearchHelper(node->right, target, radius, depth + 1, result);
if (std::abs(diff) <= radius) {
radiusSearchHelper(node->left, target, radius, depth + 1, result);
radiusSearchHelper(
node->right.get(), target, radius_square, next_orient, result);
if (diff_square <= radius_square) {
radiusSearchHelper(
node->left.get(), target, radius_square, next_orient, result);
}
}
}
} // namespace drt
86 changes: 57 additions & 29 deletions src/drt/src/db/infra/KDTree.hpp
Original file line number Diff line number Diff line change
@@ -1,50 +1,78 @@
/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, Precision Innovations Inc.
// All rights reserved.
//
// BSD 3-Clause License
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
///////////////////////////////////////////////////////////////////////////////

#pragma once

#include <memory>
#include <vector>

#include "frBaseTypes.h"
#include "odb/geom.h"

using odb::Orientation2D;
using odb::Point;
namespace drt {

struct KDTreeNode
{
int id;
std::pair<int, int> point;
KDTreeNode* left{nullptr};
KDTreeNode* right{nullptr};

KDTreeNode(const int& idIn, const std::pair<int, int>& pt)
: id(idIn), point(pt)
{
}
Point point;
std::unique_ptr<KDTreeNode> left;
std::unique_ptr<KDTreeNode> right;

KDTreeNode(const int idIn, const Point& pt) : id(idIn), point(pt) {}
};

class KDTree
{
public:
KDTree(const std::vector<std::pair<int, int>>& points);
KDTree(const std::vector<Point>& points);

~KDTree() { destroyTree(root); }
~KDTree() = default;

std::vector<int> radiusSearch(const std::pair<int, int>& target,
int radius) const;
std::vector<int> radiusSearch(const Point& target, int radius) const;

private:
KDTreeNode* root;

KDTreeNode* buildTree(
const std::vector<std::pair<int, std::pair<int, int>>>& points,
int depth);
std::unique_ptr<KDTreeNode> buildTree(
const std::vector<std::pair<int, Point>>& points,
const Orientation2D& orient);

void radiusSearchHelper(KDTreeNode* node,
const std::pair<int, int>& target,
int radius,
int depth,
const Point& target,
const frSquaredDistance radius_square,
const Orientation2D& orient,
std::vector<int>& result) const;

void destroyTree(KDTreeNode* node)
{
if (!node) {
return;
}
destroyTree(node->left);
destroyTree(node->right);
delete node;
}
std::unique_ptr<KDTreeNode> root_;
};
} // namespace drt
2 changes: 1 addition & 1 deletion src/drt/src/dr/FlexDR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1339,7 +1339,7 @@ std::vector<frVia*> FlexDR::getLonelyVias(frLayer* layer,
return lonely_vias;
}
auto vias = getRegionQuery()->getVias(layer->getLayerNum());
std::vector<std::pair<int, int>> via_positions;
std::vector<Point> via_positions;
via_positions.reserve(vias.size());
for (auto [obj, box] : vias) {
via_positions.emplace_back(box.xCenter(), box.yCenter());
Expand Down

0 comments on commit 7de464f

Please sign in to comment.