From 7de464fe707722c0eb0a548ed6fc70158af665e0 Mon Sep 17 00:00:00 2001 From: osamahammad21 Date: Tue, 6 Aug 2024 17:05:20 +0300 Subject: [PATCH] drt: required updates in KDTree Signed-off-by: osamahammad21 --- src/drt/src/db/infra/KDTree.cpp | 139 +++++++++++++++++++++----------- src/drt/src/db/infra/KDTree.hpp | 86 +++++++++++++------- src/drt/src/dr/FlexDR.cpp | 2 +- 3 files changed, 149 insertions(+), 78 deletions(-) diff --git a/src/drt/src/db/infra/KDTree.cpp b/src/drt/src/db/infra/KDTree.cpp index 86a14e37f2b..c0e3714ac12 100644 --- a/src/drt/src/db/infra/KDTree.cpp +++ b/src/drt/src/db/infra/KDTree.cpp @@ -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 #include - -KDTree::KDTree(const std::vector>& points) +using odb::horizontal; +namespace drt { +KDTree::KDTree(const std::vector& points) { - std::vector>> points_with_ids; + std::vector> 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 KDTree::radiusSearch(const std::pair& target, - int radius) const -{ - std::vector result; - radiusSearchHelper(root, target, radius, 0, result); - return result; + root_ = buildTree(points_with_ids, horizontal); } -KDTreeNode* KDTree::buildTree( - const std::vector>>& points, - int depth) +std::unique_ptr KDTree::buildTree( + const std::vector>& 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>& a, - const std::pair>& 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& a, const std::pair& 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 node = std::make_unique( + sorted_points[median_index].first, sorted_points[median_index].second); - std::vector>> left_points( + std::vector> left_points( sorted_points.begin(), sorted_points.begin() + median_index); - std::vector>> right_points( + std::vector> 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 KDTree::radiusSearch(const Point& target, int radius) const +{ + std::vector result; + const frSquaredDistance radius_square + = radius * static_cast(radius); + radiusSearchHelper(root_.get(), target, radius_square, horizontal, result); + return result; +} + void KDTree::radiusSearchHelper(KDTreeNode* node, - const std::pair& target, - int radius, - int depth, + const Point& target, + const frSquaredDistance radius_square, + const Orientation2D& orient, std::vector& 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(dx) + + dy * static_cast(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(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 \ No newline at end of file diff --git a/src/drt/src/db/infra/KDTree.hpp b/src/drt/src/db/infra/KDTree.hpp index 237c20874b4..70e36643f18 100644 --- a/src/drt/src/db/infra/KDTree.hpp +++ b/src/drt/src/db/infra/KDTree.hpp @@ -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 #include +#include "frBaseTypes.h" +#include "odb/geom.h" + +using odb::Orientation2D; +using odb::Point; +namespace drt { + struct KDTreeNode { int id; - std::pair point; - KDTreeNode* left{nullptr}; - KDTreeNode* right{nullptr}; - - KDTreeNode(const int& idIn, const std::pair& pt) - : id(idIn), point(pt) - { - } + Point point; + std::unique_ptr left; + std::unique_ptr right; + + KDTreeNode(const int idIn, const Point& pt) : id(idIn), point(pt) {} }; class KDTree { public: - KDTree(const std::vector>& points); + KDTree(const std::vector& points); - ~KDTree() { destroyTree(root); } + ~KDTree() = default; - std::vector radiusSearch(const std::pair& target, - int radius) const; + std::vector radiusSearch(const Point& target, int radius) const; private: - KDTreeNode* root; - - KDTreeNode* buildTree( - const std::vector>>& points, - int depth); + std::unique_ptr buildTree( + const std::vector>& points, + const Orientation2D& orient); void radiusSearchHelper(KDTreeNode* node, - const std::pair& target, - int radius, - int depth, + const Point& target, + const frSquaredDistance radius_square, + const Orientation2D& orient, std::vector& result) const; - void destroyTree(KDTreeNode* node) - { - if (!node) { - return; - } - destroyTree(node->left); - destroyTree(node->right); - delete node; - } + std::unique_ptr root_; }; +} // namespace drt \ No newline at end of file diff --git a/src/drt/src/dr/FlexDR.cpp b/src/drt/src/dr/FlexDR.cpp index 26753d6cb96..f3b221cb5cf 100644 --- a/src/drt/src/dr/FlexDR.cpp +++ b/src/drt/src/dr/FlexDR.cpp @@ -1339,7 +1339,7 @@ std::vector FlexDR::getLonelyVias(frLayer* layer, return lonely_vias; } auto vias = getRegionQuery()->getVias(layer->getLayerNum()); - std::vector> via_positions; + std::vector via_positions; via_positions.reserve(vias.size()); for (auto [obj, box] : vias) { via_positions.emplace_back(box.xCenter(), box.yCenter());