├── LICENSE ├── README.md ├── cpp ├── CMakeLists.txt └── src │ ├── api │ └── api.cpp │ ├── db │ ├── cstr │ │ ├── dbNetPrioCstr.hpp │ │ ├── dbPlaceAlignCstr.hpp │ │ ├── dbPlaceArrayCstr.hpp │ │ ├── dbPlaceClusterCstr.hpp │ │ ├── dbPlaceDisjointCstr.hpp │ │ ├── dbPlaceEdgeDistCstr.hpp │ │ ├── dbPlaceExtCstr.hpp │ │ ├── dbPlaceOrderCstr.hpp │ │ ├── dbPlaceRowCstr.hpp │ │ ├── dbPlaceSymCstr.hpp │ │ ├── dbPrePlaceCstr.hpp │ │ ├── dbRoutePathMatchCstr.hpp │ │ └── dbRouteSymCstr.hpp │ ├── dbBasic.cpp │ ├── dbBasic.hpp │ ├── dbCell.cpp │ ├── dbCell.hpp │ ├── dbCir.cpp │ ├── dbCir.hpp │ ├── dbDevMap.hpp │ ├── dbGrid.hpp │ ├── dbLayer.cpp │ ├── dbLayer.hpp │ ├── dbNet.cpp │ ├── dbNet.hpp │ ├── dbObs.hpp │ ├── dbPin.hpp │ ├── dbPrim.hpp │ ├── dbRegion.hpp │ └── dbVia.hpp │ ├── drc │ ├── drcMgr.cpp │ └── drcMgr.hpp │ ├── ds │ ├── array2d.hpp │ ├── array3d.hpp │ ├── disjointSet.hpp │ ├── hash.hpp │ └── pqueue.hpp │ ├── geo │ ├── box.hpp │ ├── box2polygon.hpp │ ├── geometry.hpp │ ├── interval.hpp │ ├── kdTree.hpp │ ├── point.hpp │ ├── point3d.hpp │ ├── polygon.hpp │ ├── polygon2box.hpp │ ├── segment.hpp │ ├── segment3d.hpp │ ├── spatial.hpp │ └── spatial3d.hpp │ ├── global │ ├── define.hpp │ ├── global.hpp │ ├── namespace.hpp │ └── type.hpp │ ├── graph │ └── mst.hpp │ ├── io │ ├── parGds.cpp │ ├── parGds.hpp │ ├── parHspice.cpp │ ├── parHspice.hpp │ ├── parLef.cpp │ ├── parLef.hpp │ ├── parser.cpp │ └── parser.hpp │ ├── main │ └── main.cpp │ ├── place │ ├── placeMgr.cpp │ ├── placeMgr.hpp │ ├── placeSMT.cpp │ └── placeSMT.hpp │ ├── rl │ ├── rlUtil.cpp │ └── rlUtil.hpp │ ├── route │ ├── routeDrAstar.cpp │ ├── routeDrAstar.hpp │ ├── routeDrMgr.cpp │ ├── routeDrMgr.hpp │ ├── routeDrPS.cpp │ ├── routeDrPS.hpp │ ├── routeDrPost.cpp │ ├── routeDrPost.hpp │ ├── routeMgr.cpp │ └── routeMgr.hpp │ ├── thirdparty │ └── spdlog.cpp │ └── util │ ├── util.cpp │ └── util.hpp └── python ├── main ├── __init__.py ├── config.yaml ├── main.py ├── rl_route_path_match_flat.py ├── rl_route_path_match_flat_group.py └── rl_route_path_match_hier.py └── rl ├── autocraft-rl ├── __init__.py ├── autocraft_rl │ ├── __init__.py │ ├── envs │ │ ├── __init__.py │ │ ├── ac_multicir_env.py │ │ ├── ac_multicir_env_layer_match.py │ │ ├── ac_multicir_env_match.py │ │ ├── ac_multicir_env_path_match.py │ │ ├── ac_multicir_env_path_match_group.py │ │ └── ac_multicir_hier_env_path_match.py │ ├── models │ │ ├── __init__.py │ │ ├── ac_dqn_model.py │ │ ├── ac_dqn_model_match.py │ │ ├── ac_dqn_model_path.py │ │ ├── ac_ppo_hier_model_path.py │ │ ├── ac_ppo_model.py │ │ ├── ac_ppo_model_match.py │ │ ├── ac_ppo_model_path.py │ │ └── ac_ppo_model_path_group.py │ └── utils │ │ ├── __init__.py │ │ ├── callbacks.py │ │ ├── callbacks_layer_match.py │ │ ├── callbacks_match.py │ │ ├── callbacks_path_match.py │ │ ├── callbacks_path_match_group.py │ │ ├── callbacks_path_match_group_hier.py │ │ ├── helper.py │ │ └── load_agent.py └── setup.py ├── conf ├── arch │ └── magic_array_dff_0.yaml └── config.yaml ├── train.py └── util ├── __init__.py ├── config.py └── util.py /LICENSE: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | SPDX-License-Identifier: Apache-2.0 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AutoCRAFT: Layout Automation for Custom Circuits in Advanced FinFET Technologies 2 | 3 | AutoCRAFT is a semi-automated custom layout framework to improve the productivity of analog and high-speed custom digital circuit layout implementation. 4 | AutoCRAFT has been developed and tested on x64 linux machines. 5 | 6 | ## Modules Overview 7 | ``` 8 | AutoCRAFT 9 | |---- Circuit 10 | | |---- Placement grid 11 | | |---- Routing grid 12 | | |---- Device mapping 13 | | |---- Primitive lib 14 | | |---- Region 15 | | |---- Cell 16 | | | |---- Pin 17 | | | |---- Obs (obstacle) 18 | | |---- Net 19 | | | |---- Pin 20 | | | |---- Via 21 | | | |---- Wire 22 | | | |---- TopoTree 23 | | | |---- Routable 24 | | |---- Layer 25 | | | |---- Metal layer 26 | | | |---- Cut layer 27 | | |---- Cstr (Constraint) 28 | | |---- Placement cstr 29 | | | |---- Net weighting 30 | | | |---- Array 31 | | | |---- Alignment (row/col) 32 | | | |---- Cluster 33 | | | |---- Disjoint (row/col) 34 | | | |---- Edge distance (to left/right/top/bottom boundaries) 35 | | | |---- Extension 36 | | | |---- Row (odd/even) 37 | | | |---- Symmetry 38 | | | |---- Pre-placed cell 39 | | |---- Routing cstr 40 | | |---- Symmetry 41 | | |---- Path matching (developing) 42 | |---- Placer 43 | | |---- SMT placer 44 | |---- Router 45 | | |---- Global routing manager (deprecated) 46 | | |---- Detailed routing manager 47 | | | |---- Path searching detailed router 48 | | |---- Post routing 49 | |---- I/O 50 | |---- Parser 51 | | |---- LEF primitive templates parser 52 | | |---- Hspice netlist parser 53 | | |---- Grid file parser 54 | | |---- Constraint file parser 55 | 56 | ``` 57 | 58 | ## Dependencies 59 | * [CMake](https://cmake.org) >= 3.14.0 60 | * [pybind11](https://github.com/pybind/pybind11) >= 2.7.0 (Python 3.7/3.8) 61 | * [Boost](https://www.boost.org/) >= 1.6 62 | * [spdlog](https://github.com/gabime/spdlog) 63 | * [Limbo](https://github.com/limbo018/Limbo) 64 | * [phmap](https://github.com/greg7mdp/parallel-hashmap) 65 | * [z3](https://github.com/Z3Prover/z3) >= 4.8.11 66 | * [nanoflann](https://github.com/jlblancoc/nanoflann) 67 | * [lemon](https://lemon.cs.elte.hu/trac/lemon) >= 1.3.1 68 | * [zlib](https://github.com/madler/zlib) 69 | * [cxxopts](https://github.com/jarro2783/cxxopts) == 2.2.0 70 | * [lef/def](https://si2.org/oa-tools-utils-libs/) >= 5.8 71 | 72 | ## Installation 73 | 74 | Recommended GCC version: >= 8.3.0 (Tested on 8.3.0) 75 | 76 | ```sh 77 | mkdir -p cpp/build/ && cd cpp/build/ 78 | cmake .. -DPYTHON_EXECUTABLE= -DPYTHON_LIBRARY= 79 | make 80 | ``` 81 | A binary executable `autocraftE` and a python library `autocraft.cpython-3x-x86_64-linux-gnu.so` will be generated after compilation. Copy the file to your python site-packages path by 82 | 83 | ```sh 84 | cp autocraft.cpython-3x-x86_64-linux-gnu.so 85 | ``` 86 | 87 | or put it under the path with the files importing `autocraft`. 88 | 89 | 90 | ## Usage 91 | 92 | Using the Python interface is recommended. 93 | The binary executable `autocraftE` can still be used for debugging purpose. Run 94 | ```sh 95 | autocraftE [OPTION...] 96 | --laygo_config= # laygo configuration (.yml) 97 | --tech_grid= # placement anf routing grids definition (.yml) 98 | --tech_map= # device-to-primitive mapping (.yml) 99 | --constraint= # constraint specification 100 | --lef= # primitive and via templates (.lef) 101 | --netlist= # spice netlist (.cir) 102 | --drc= # abstracted drc rules (.yml) 103 | --in_place= # placement input (optional) 104 | --out_place= # cells location after placement (optional) 105 | --out_gv= # gated verilog netlist output (optional) 106 | --out_tcl= # ICC2 Tcl commands output (optional) 107 | --threads= # number of CPU threads for placement (optional, not necessarily faster) 108 | --place_ar= # user-defined aspect ratio of the design area 109 | --place_ur= # user-defined utilization ratio of the design 110 | --place_ur_reg_name= # utilization ratio for some regions (should be used together with --place_ur_reg_val) 111 | --place_ur_reg_val= # utilization ratio values for some regions 112 | --place_bbox= # design bounding box 113 | --place_iter= # placemnt WL optimization iterations 114 | -h, --help # print usage 115 | 116 | Example: 117 | autocraftE --laygo_config=laygo_config.yaml \ 118 | --tech_grid=dv5t_crg_fll_ana_obsd.grid.yaml \ 119 | --tech_map=dv5t_crg_fll_ana_obsd.map.yaml \ 120 | --constraint=dv5t_crg_fll_ana_obsd.constraint.yaml \ 121 | --lef=dv5t_crg_fll_ana_obsd.template.lef,dv5t_crg_fll_ana_obsd.via.lef \ 122 | --netlist=dv5t_crg_fll_ana_obsd.cir \ 123 | --drc=layers.drc.yaml \ 124 | --threads=1 \ 125 | --place_ar=1.1 \ 126 | --place_ur=0.4 \ 127 | --place_ur_reg_name=region1 \ 128 | --place_ur_reg_val=0.4 \ 129 | --place_iter=2 \ 130 | --out_gv=dv5t_crg_fll_ana_obsd.gv \ 131 | --out_tcl=dv5t_crg_fll_ana_obsd_pnr.tcl 132 | ``` 133 | to execute the program 134 | 135 | -------------------------------------------------------------------------------- /cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | #set(CMAKE_VERBOSE_MAKEFILE ON) 3 | 4 | set(PROJECT_NAME "autocraft") 5 | project(${PROJECT_NAME}) 6 | 7 | set(PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) 8 | 9 | ################################################# 10 | # Dependencies # 11 | ################################################# 12 | #pybind11 13 | if (PYBIND11_DIR) 14 | set(PYBIND11_ROOT_DIR ${PYBIND11_DIR}) 15 | else() 16 | set(PYBIND11_ROOT_DIR $ENV{PYBIND11_DIR}) 17 | endif() 18 | message(STATUS "pybind11: ${PYBIND11_ROOT_DIR}") 19 | unset(PYBIND11_DIR CACHE) 20 | 21 | add_subdirectory(${PYBIND11_ROOT_DIR} "./pybind11") 22 | 23 | # boost 24 | set(Boost_USE_STATIC_LIBS ON) 25 | find_package(Boost 1.6 REQUIRED COMPONENTS system graph) 26 | 27 | # Python 28 | find_package(PythonLibs REQUIRED) 29 | 30 | 31 | # yaml-cpp 32 | if (YAML_CPP_DIR) 33 | set(YAML_CPP_ROOT_DIR ${YAML_CPP_DIR}) 34 | else() 35 | set(YAML_CPP_ROOT_DIR $ENV{YAML_CPP_DIR}) 36 | endif() 37 | message(STATUS "yaml-cpp: ${YAML_CPP_ROOT_DIR}") 38 | unset(YAML_CPP_DIR CACHE) 39 | 40 | # z3 41 | #find_package(Z3 CONFIG REQUIRED) 42 | if (Z3_DIR) 43 | set(Z3_ROOT_DIR ${Z3_DIR}) 44 | else() 45 | set(Z3_ROOT_DIR $ENV{Z3_DIR}) 46 | endif() 47 | message(STATUS "z3: ${Z3_ROOT_DIR}") 48 | unset(Z3_DIR CACHE) 49 | 50 | # spdlog 51 | if (SPDLOG_DIR) 52 | set(SPDLOG_ROOT_DIR ${SPDLOG_DIR}) 53 | else() 54 | set(SPDLOG_ROOT_DIR $ENV{SPDLOG_DIR}) 55 | endif() 56 | message(STATUS "spdlog: ${SPDLOG_ROOT_DIR}") 57 | unset(SPDLOG_DIR CACHE) 58 | 59 | # phmap 60 | if (PHMAP_DIR) 61 | set(PHMAP_ROOT_DIR ${PHMAP_DIR}) 62 | else() 63 | set(PHMAP_ROOT_DIR $ENV{PHMAP_DIR}) 64 | endif() 65 | message(STATUS "phmap: ${PHMAP_ROOT_DIR}") 66 | unset(PHMAP_DIR CACHE) 67 | 68 | # nanoflann 69 | if (NANOFLANN_DIR) 70 | set(NANOFLANN_ROOT_DIR ${NANOFLANN_DIR}) 71 | else() 72 | set(NANOFLANN_ROOT_DIR $ENV{NANOFLANN_DIR}) 73 | endif() 74 | message(STATUS "nanoflann: ${NANOFLANN_ROOT_DIR}") 75 | unset(NANOFLANN_DIR CACHE) 76 | 77 | # limbo 78 | if (LIMBO_DIR) 79 | set(LIMBO_ROOT_DIR ${LIMBO_DIR}) 80 | else() 81 | set(LIMBO_ROOT_DIR $ENV{LIMBO_DIR}) 82 | endif() 83 | message(STATUS "limbo: ${LIMBO_ROOT_DIR}") 84 | unset(LIMBO_DIR CACHE) 85 | 86 | # lefdef 87 | if (LEF_DIR) 88 | set(LEF_ROOT_DIR ${LEF_DIR}) 89 | else() 90 | set(LEF_ROOT_DIR $ENV{LEF_DIR}) 91 | endif() 92 | message(STATUS "lef: ${LEF_ROOT_DIR}") 93 | unset(LEF_DIR CACHE) 94 | if (DEF_DIR) 95 | set(DEF_ROOT_DIR ${DEF_DIR}) 96 | else() 97 | set(DEF_ROOT_DIR $ENV{DEF_DIR}) 98 | endif() 99 | message(STATUS "def: ${DEF_ROOT_DIR}") 100 | unset(DEF_DIR CACHE) 101 | 102 | # lemon 103 | if (LEMON_DIR) 104 | set(LEMON_ROOT_DIR ${LEMON_DIR}) 105 | else() 106 | set(LEMON_ROOT_DIR $ENV{LEMON_DIR}) 107 | endif() 108 | message(STATUS "lemon: ${LEMON_ROOT_DIR}") 109 | unset(LEMON_DIR CACHE) 110 | 111 | # cxxopts 112 | if (CXXOPTS_DIR) 113 | set(CXXOPTS_ROOT_DIR ${CXXOPTS_DIR}) 114 | else() 115 | set(CXXOPTS_ROOT_DIR $ENV{CXXOPTS_DIR}) 116 | endif() 117 | message(STATUS "cxxopts: ${CXXOPTS_ROOT_DIR}") 118 | unset(CXXOPTS_DIR CACHE) 119 | 120 | # zlib 121 | if (ZLIB_DIR) 122 | set(ZLIB_ROOT_DIR ${ZLIB_DIR}) 123 | else() 124 | set(ZLIB_ROOT_DIR $ENV{ZLIB_DIR}) 125 | endif() 126 | message(STATUS "zlib: ${ZLIB_ROOT_DIR}") 127 | unset(ZLIB_DIR CACHE) 128 | 129 | ################################################# 130 | 131 | 132 | # set(CMAKE_BUILD_TYPE Debug) 133 | set(CMAKE_BUILD_TYPE Release) 134 | message(STATUS "Using build type ${CMAKE_BUILD_TYPE}") 135 | 136 | set(CMAKE_CXX_FLAGS "-std=c++2a -Wall -fopenmp -fPIC -fconcepts -lz") 137 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g -fno-inline") 138 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3") 139 | set(CMAKE_EXE_LINKER_FLAGS "-pthread") 140 | 141 | add_definitions(-DSPDLOG_COMPILED_LIB) 142 | 143 | ################################################# 144 | # Include library path 145 | ################################################# 146 | include_directories ( 147 | ${CMAKE_CURRENT_SOURCE_DIR}/src 148 | ${SPDLOG_ROOT_DIR}/include 149 | ${YAML_CPP_ROOT_DIR}/include 150 | ${SPDLOG_ROOT_DIR}/include 151 | ${PHMAP_ROOT_DIR}/include 152 | ${NANOFLANN_ROOT_DIR}/include 153 | ${LIMBO_ROOT_DIR}/include 154 | ${LEF_ROOT_DIR}/include 155 | ${DEF_ROOT_DIR}/include 156 | ${Z3_ROOT_DIR}/include 157 | ${LEMON_ROOT_DIR}/include 158 | ${CXXOPTS_ROOT_DIR}/include 159 | ) 160 | 161 | file(GLOB LIB 162 | ${SPDLOG_ROOT_DIR}/lib/libspdlog.a 163 | ${YAML_CPP_ROOT_DIR}/lib/libyaml-cpp.a 164 | ${LIMBO_ROOT_DIR}/lib/libgdsdb.a 165 | ${LIMBO_ROOT_DIR}/lib/libgdsparser.a 166 | ${LIMBO_ROOT_DIR}/lib/libgzstream.a 167 | ${LEF_ROOT_DIR}/lib/liblef.a 168 | ${DEF_ROOT_DIR}/lib/libdef.a 169 | ${Z3_ROOT_DIR}/lib/libz3.a 170 | ${LEMON_ROOT_DIR}/lib/libemon.a 171 | #${ZLIB_DIR}/lib/libz.a 172 | ) 173 | 174 | link_libraries ( 175 | ${PYTHON_LIBRARIES} 176 | ) 177 | 178 | 179 | ############################################### 180 | # SRC 181 | ############################################### 182 | set(SRC 183 | src/thirdparty/spdlog.cpp 184 | src/util/util.cpp 185 | src/io/parser.cpp 186 | src/io/parHspice.cpp 187 | src/io/parLef.cpp 188 | src/io/parGds.cpp 189 | src/io/writer.cpp 190 | src/db/dbBasic.cpp 191 | src/db/dbCell.cpp 192 | src/db/dbCir.cpp 193 | src/db/dbNet.cpp 194 | src/db/dbLayer.cpp 195 | src/place/placeMgr.cpp 196 | src/place/placeSMT.cpp 197 | src/route/routeMgr.cpp 198 | # src/route/routeGrMgr.cpp 199 | src/route/routeDrMgr.cpp 200 | src/route/routeDrPS.cpp 201 | src/route/routeDrAstar.cpp 202 | src/route/routeDrPost.cpp 203 | src/drc/drcMgr.cpp 204 | src/rl/rlUtil.cpp 205 | ) 206 | 207 | # executable 208 | add_executable(${PROJECT_NAME}E ${SRC} src/main/main.cpp) 209 | #target_link_libraries(${PROJECT_NAME}E PUBLIC Boost::system Boost::graph ${LIB} ortools::ortools z3::libz3) 210 | target_link_libraries(${PROJECT_NAME}E PUBLIC Boost::system Boost::graph ${LIB}) 211 | 212 | # Add modules to pybind 213 | pybind11_add_module(${PROJECT_NAME} ${SRC} src/api/api.cpp) 214 | target_link_libraries(${PROJECT_NAME} PUBLIC ${Boost_LIBRARIES} ${LIB}) 215 | 216 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbNetPrioCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbBasic.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class Net; 25 | 26 | class NetPrioCstr { 27 | friend class Parser; 28 | 29 | public: 30 | NetPrioCstr() 31 | : _idx(-1), _priority(0) 32 | {} 33 | 34 | const String& name() const { return _name; } 35 | Int idx() const { return _idx; } 36 | 37 | Net& net(const Int i) { return *_vpNets.at(i); } 38 | const Net& net(const Int i) const { return *_vpNets.at(i); } 39 | Net* pNet(const Int i) { return _vpNets.at(i); } 40 | const Net* pNet(const Int i) const { return _vpNets.at(i); } 41 | Vector& vpNets() { return _vpNets; } 42 | const Vector& vpNets() const { return _vpNets; } 43 | Int numNets() const { return _vpNets.size(); } 44 | 45 | Int priority() const { return _priority; } 46 | 47 | private: 48 | String _name; 49 | Int _idx; 50 | 51 | Vector _vpNets; 52 | Int _priority; 53 | 54 | }; 55 | 56 | PROJECT_NAMESPACE_END 57 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPlaceAlignCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | #include "db/dbRegion.hpp" 22 | #include "db/cstr/dbPlaceArrayCstr.hpp" 23 | 24 | PROJECT_NAMESPACE_START 25 | 26 | class PlaceAlignCstr { 27 | friend class Parser; 28 | 29 | public: 30 | PlaceAlignCstr() 31 | : _idx(-1), _isHor(false), _isHigh(false) 32 | {} 33 | ~PlaceAlignCstr() {} 34 | 35 | const String& name() const { return _name; } 36 | Int idx() const { return _idx; } 37 | 38 | Cell& cell(const Int i) { return *_vpCells.at(i); } 39 | const Cell& cell(const Int i) const { return *_vpCells.at(i); } 40 | Cell* pCell(const Int i) { return _vpCells.at(i); } 41 | const Cell* pCell(const Int i) const { return _vpCells.at(i); } 42 | Vector& vpCells() { return _vpCells; } 43 | const Vector& vpCells() const { return _vpCells; } 44 | Int numCells() const { return _vpCells.size(); } 45 | 46 | Region& region(const Int i) { return *_vpRegions.at(i); } 47 | const Region& region(const Int i) const { return *_vpRegions.at(i); } 48 | Region* pRegion(const Int i) { return _vpRegions.at(i); } 49 | const Region* pRegion(const Int i) const { return _vpRegions.at(i); } 50 | Vector& vpRegions() { return _vpRegions; } 51 | const Vector& vpRegions() const { return _vpRegions; } 52 | Int numRegions() const { return _vpRegions.size(); } 53 | 54 | PlaceArrayCstr& placeArrayCstr(const Int i) { return *_vpArrays.at(i); } 55 | const PlaceArrayCstr& placeArrayCstr(const Int i) const { return *_vpArrays.at(i); } 56 | PlaceArrayCstr* pPlaceArrayCstr(const Int i) { return _vpArrays.at(i); } 57 | const PlaceArrayCstr* pPlaceArrayCstr(const Int i) const { return _vpArrays.at(i); } 58 | Vector& vpPlaceArrayCstrs() { return _vpArrays; } 59 | const Vector& vpPlaceArrayCstrs() const { return _vpArrays; } 60 | Int numPlaceArrayCstrs() const { return _vpArrays.size(); } 61 | 62 | bool isHor() const { return _isHor; } 63 | bool isVer() const { return !_isHor; } 64 | 65 | bool isHigh() const { return _isHigh; } 66 | bool isLow() const { return !_isHigh; } 67 | 68 | 69 | private: 70 | String _name; 71 | Int _idx; 72 | Vector _vpCells; 73 | Vector _vpRegions; 74 | Vector _vpArrays; 75 | bool _isHor; 76 | bool _isHigh; 77 | }; 78 | 79 | PROJECT_NAMESPACE_END 80 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPlaceArrayCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class PlaceArrayCstr { 25 | friend class Parser; 26 | 27 | public: 28 | PlaceArrayCstr() : _idx(-1), _col(0), _row(0), _size(0), _pattern(ArrayPatternE::undef) {} 29 | ~PlaceArrayCstr() {} 30 | 31 | const String& name() const { return _name; } 32 | Int idx() const { return _idx; } 33 | 34 | Int col() const { return _col; } 35 | Int row() const { return _row; } 36 | bool hasCol() const { return _col > 0; } 37 | bool hasRow() const { return _row > 0; } 38 | 39 | Int size() const { return _size; } 40 | bool hasSize() const { return _size > 0; } 41 | bool useAutoSize() const { return _size == 0; } 42 | 43 | ArrayPatternE pattern() const { return _pattern; } 44 | bool isID() const { return _pattern == ArrayPatternE::id; } 45 | bool isCC() const { return _pattern == ArrayPatternE::cc; } 46 | bool isCS() const { return _pattern == ArrayPatternE::cs; } 47 | bool hasPattern() const { return _pattern != ArrayPatternE::undef; } 48 | 49 | Cell& cell(const Int i) { return *_vpCells.at(i); } 50 | const Cell& cell(const Int i) const { return *_vpCells.at(i); } 51 | Cell* pCell(const Int i) { return _vpCells.at(i); } 52 | const Cell* pCell(const Int i) const { return _vpCells.at(i); } 53 | Vector& vpCells() { return _vpCells; } 54 | const Vector& vpCells() const { return _vpCells; } 55 | Int numCells() const { return _vpCells.size(); } 56 | 57 | ArrayPartE arrayPart(const Int i) const { return _vArrayPartEs.at(i); } 58 | ArrayPartE arrayPart(const Cell& c) const { return _vArrayPartEs.at(cellIdx2Idx(c.idx())); } 59 | bool isPartA(const Int i) const { return arrayPart(i) == ArrayPartE::a; } 60 | bool isPartA(const Cell& c) const { return arrayPart(c) == ArrayPartE::a; } 61 | bool isPartB(const Int i) const { return arrayPart(i) == ArrayPartE::b; } 62 | bool isPartB(const Cell& c) const { return arrayPart(c) == ArrayPartE::b; } 63 | 64 | Int cellIdx2Idx(const Int idx) const { return _mCellIdx2Idx.at(idx); } 65 | 66 | PlaceArrayCstr& placeArrayCstr(const Int i) { return *_vpArrays.at(i); } 67 | const PlaceArrayCstr& placeArrayCstr(const Int i) const { return *_vpArrays.at(i); } 68 | PlaceArrayCstr* pPlaceArrayCstr(const Int i) { return _vpArrays.at(i); } 69 | const PlaceArrayCstr* pPlaceArrayCstr(const Int i) const { return _vpArrays.at(i); } 70 | Vector& vpPlaceArrayCstrs() { return _vpArrays; } 71 | const Vector& vpPlaceArrayCstrs() const { return _vpArrays; } 72 | Int numPlaceArrayCstrs() const { return _vpArrays.size(); } 73 | 74 | Int arrayIdx2Idx(const Int idx) const { return _mArrayIdx2Idx.at(idx); } 75 | bool hasArray(const PlaceArrayCstr& arr) const { return _mArrayIdx2Idx.find(arr.idx()) != _mArrayIdx2Idx.end(); } 76 | 77 | const Region& region() const { return _vpCells.size() ? const_cast(_vpCells.at(0)->region()) : _vpArrays.at(0)->region(); } 78 | const Region* pRegion() const { return _vpCells.size() ? const_cast(_vpCells.at(0)->pRegion()) : _vpArrays.at(0)->pRegion(); } 79 | 80 | bool hasCell(const Cell& c) const { 81 | std::function 82 | hasCellImpl = [&] (const PlaceArrayCstr& ac, const Cell& c) -> bool { 83 | if (!ac._mCellIdx2Idx.empty()) { 84 | return ac._mCellIdx2Idx.find(c.idx()) != ac._mCellIdx2Idx.end(); 85 | } 86 | else { 87 | assert(ac._vpArrays.size() > 0); 88 | for (const PlaceArrayCstr* pArr : ac._vpArrays) { 89 | if (hasCellImpl(*pArr, c)) { 90 | return true; 91 | } 92 | } 93 | return false; 94 | } 95 | }; 96 | return hasCellImpl(*this, c); 97 | } 98 | 99 | private: 100 | String _name; 101 | Int _idx; 102 | Int _col; 103 | Int _row; 104 | Int _size; 105 | ArrayPatternE _pattern; 106 | 107 | Vector _vpCells; 108 | Vector _vArrayPartEs; 109 | FlatHashMap _mCellIdx2Idx; 110 | 111 | Vector _vpArrays; // for array of array constraints 112 | FlatHashMap _mArrayIdx2Idx; 113 | }; 114 | 115 | 116 | PROJECT_NAMESPACE_END 117 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPlaceClusterCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class PlaceClusterCstr { 25 | friend class Parser; 26 | 27 | public: 28 | PlaceClusterCstr() 29 | : _idx(-1), _weight(0) 30 | {} 31 | ~PlaceClusterCstr() {} 32 | 33 | const String& name() const { return _name; } 34 | Int idx() const { return _idx; } 35 | 36 | Cell& cell(const Int i) { return *_vpCells.at(i); } 37 | const Cell& cell(const Int i) const { return *_vpCells.at(i); } 38 | Cell* pCell(const Int i) { return _vpCells.at(i); } 39 | const Cell* pCell(const Int i) const { return _vpCells.at(i); } 40 | Vector& vpCells() { return _vpCells; } 41 | const Vector& vpCells() const { return _vpCells; } 42 | Int numCells() const { return _vpCells.size(); } 43 | 44 | Int weight() const { return _weight; } 45 | 46 | private: 47 | String _name; 48 | Int _idx; 49 | Vector _vpCells; 50 | Int _weight; 51 | }; 52 | 53 | PROJECT_NAMESPACE_END 54 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPlaceDisjointCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class PlaceDisjointCstr { 25 | friend class Parser; 26 | 27 | public: 28 | PlaceDisjointCstr() 29 | : _idx(-1), _isRow(false) 30 | {} 31 | ~PlaceDisjointCstr() {} 32 | 33 | const String& name() const { return _name; } 34 | Int idx() const { return _idx; } 35 | 36 | Cell& cell(const Int i) { return *_vpCells.at(i); } 37 | const Cell& cell(const Int i) const { return *_vpCells.at(i); } 38 | Cell* pCell(const Int i) { return _vpCells.at(i); } 39 | const Cell* pCell(const Int i) const { return _vpCells.at(i); } 40 | Vector& vpCells() { return _vpCells; } 41 | const Vector& vpCells() const { return _vpCells; } 42 | Int numCells() const { return _vpCells.size(); } 43 | 44 | bool isRow() const { return _isRow; } 45 | bool isCol() const { return !_isRow; } 46 | 47 | 48 | private: 49 | String _name; 50 | Int _idx; 51 | Vector _vpCells; 52 | bool _isRow; 53 | }; 54 | 55 | PROJECT_NAMESPACE_END 56 | 57 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPlaceEdgeDistCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class Cell; 25 | class Region; 26 | 27 | class PlaceEdgeDistCstr { 28 | friend class Parser; 29 | 30 | public: 31 | PlaceEdgeDistCstr() : _idx(-1), _distL(0), _distR(0), _distB(0), _distT(0) {} 32 | ~PlaceEdgeDistCstr() {} 33 | 34 | const String& name() const { return _name; } 35 | Int idx() const { return _idx; } 36 | 37 | Cell& cell(const Int i) { return *_vpCells.at(i); } 38 | const Cell& cell(const Int i) const { return *_vpCells.at(i); } 39 | Cell* pCell(const Int i) { return _vpCells.at(i); } 40 | const Cell* pCell(const Int i) const { return _vpCells.at(i); } 41 | Vector& vpCells() { return _vpCells; } 42 | const Vector& vpCells() const { return _vpCells; } 43 | Int numCells() const { return _vpCells.size(); } 44 | 45 | Int distL() const { return _distL; } 46 | Int distR() const { return _distR; } 47 | Int distB() const { return _distB; } 48 | Int distT() const { return _distT; } 49 | 50 | const Region& region() const { return _vpCells.at(0)->region(); } 51 | const Region* pRegion() const { return _vpCells.at(0)->pRegion(); } 52 | 53 | private: 54 | String _name; 55 | Int _idx; 56 | Vector _vpCells; 57 | Int _distL; 58 | Int _distR; 59 | Int _distB; 60 | Int _distT; 61 | }; 62 | 63 | PROJECT_NAMESPACE_END 64 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPlaceExtCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class Primitive; 25 | class Cell; 26 | class PlaceArrayCstr; 27 | class Region; 28 | 29 | class PlaceExtCstr { 30 | friend class Parser; 31 | 32 | public: 33 | PlaceExtCstr() 34 | : _idx(0), _type(ExtTypeE::undef) 35 | {} 36 | ~PlaceExtCstr() {} 37 | 38 | const String& name() const { return _name; } 39 | Int idx() const { return _idx; } 40 | ExtTypeE type() const { return _type; } 41 | bool isCell() const { return _type == ExtTypeE::cell; } 42 | bool isRegion() const { return _type == ExtTypeE::region; } 43 | bool isArray() const { return _type == ExtTypeE::array; } 44 | 45 | Cell& cell(const Int i) { return *_vpCells.at(i); } 46 | const Cell& cell(const Int i) const { return *_vpCells.at(i); } 47 | Cell* pCell(const Int i) { return _vpCells.at(i); } 48 | const Cell* pCell(const Int i) const { return _vpCells.at(i); } 49 | Vector& vpCells() { return _vpCells; } 50 | const Vector& vpCells() const { return _vpCells; } 51 | Int numCells() const { return _vpCells.size(); } 52 | 53 | Region& region(const Int i) { return *_vpRegions.at(i); } 54 | const Region& region(const Int i) const { return *_vpRegions.at(i); } 55 | Region* pRegion(const Int i) { return _vpRegions.at(i); } 56 | const Region* pRegion(const Int i) const { return _vpRegions.at(i); } 57 | Vector& vpRegions() { return _vpRegions; } 58 | const Vector& vpRegions() const { return _vpRegions; } 59 | Int numRegions() const { return _vpRegions.size(); } 60 | 61 | PlaceArrayCstr& placeArrayCstr(const Int i) { return *_vpPlaceArrayCstrs.at(i); } 62 | const PlaceArrayCstr& placeArrayCstr(const Int i) const { return *_vpPlaceArrayCstrs.at(i); } 63 | PlaceArrayCstr* pPlaceArrayCstr(const Int i) { return _vpPlaceArrayCstrs.at(i); } 64 | const PlaceArrayCstr* pPlaceArrayCstr(const Int i) const { return _vpPlaceArrayCstrs.at(i); } 65 | Vector& vpPlaceArrayCstrs() { return _vpPlaceArrayCstrs; } 66 | const Vector& vpPlaceArrayCstrs() const { return _vpPlaceArrayCstrs; } 67 | Int numPlaceArrayCstrs() const { return _vpPlaceArrayCstrs.size(); } 68 | 69 | const Pair& leftExt() const { return _left; } 70 | const Pair& rightExt() const { return _right; } 71 | const Pair& bottomExt() const { return _bottom; } 72 | const Pair& topExt() const { return _top; } 73 | Pair leftExtIdx() const { return std::make_pair(_left.first->idx(), _left.second); } 74 | Pair rightExtIdx() const { return std::make_pair(_right.first->idx(), _right.second); } 75 | Pair bottomExtIdx() const { return std::make_pair(_bottom.first->idx(), _bottom.second); } 76 | Pair topExtIdx() const { return std::make_pair(_top.first->idx(), _top.second); } 77 | 78 | private: 79 | String _name; 80 | Int _idx; 81 | 82 | ExtTypeE _type; 83 | 84 | Vector _vpCells; 85 | Vector _vpRegions; 86 | Vector _vpPlaceArrayCstrs; 87 | 88 | Pair _left; // (prim, numGrids) 89 | Pair _right; 90 | Pair _bottom; 91 | Pair _top; 92 | }; 93 | 94 | PROJECT_NAMESPACE_END 95 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPlaceOrderCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class PlaceOrderCstr { 25 | friend class Parser; 26 | 27 | public: 28 | PlaceOrderCstr() : _idx(-1), _dir(Direction2dE::undef), _isStrict(false) {} 29 | ~PlaceOrderCstr() {} 30 | 31 | const String& name() const { return _name; } 32 | Int idx() const { return _idx; } 33 | 34 | Cell& cell(const Int i, const Int j) { return *_vvpCells.at(i).at(j); } 35 | const Cell& cell(const Int i, const Int j) const { return *_vvpCells.at(i).at(j); } 36 | Cell* pCell(const Int i, const Int j) { return _vvpCells.at(i).at(j); } 37 | const Cell* pCell(const Int i, const Int j) const { return _vvpCells.at(i).at(j); } 38 | Vector& vpCells(const Int i) { return _vvpCells.at(i); } 39 | const Vector& vpCells(const Int i) const { return _vvpCells.at(i); } 40 | Int numCells(const Int i) const { return _vvpCells.at(i).size(); } 41 | Vector>& vvpCells() { return _vvpCells; } 42 | const Vector>& vvpCells() const { return _vvpCells; } 43 | Int numCellGroups() const { return _vvpCells.size(); } 44 | 45 | Direction2dE dir() const { return _dir; } 46 | bool isStrict() const { return _isStrict; } 47 | bool isWeak() const { return !_isStrict; } 48 | 49 | private: 50 | String _name; 51 | Int _idx; 52 | Vector> _vvpCells; // should be in the desired order 53 | Direction2dE _dir; 54 | bool _isStrict; 55 | }; 56 | 57 | PROJECT_NAMESPACE_END 58 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPlaceRowCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class PlaceRowCstr { 25 | friend class Parser; 26 | 27 | public: 28 | PlaceRowCstr() 29 | : _idx(-1), _isOdd(false) 30 | {} 31 | ~PlaceRowCstr() {} 32 | 33 | const String& name() const { return _name; } 34 | Int idx() const { return _idx; } 35 | 36 | Cell& cell(const Int i) { return *_vpCells.at(i); } 37 | const Cell& cell(const Int i) const { return *_vpCells.at(i); } 38 | Cell* pCell(const Int i) { return _vpCells.at(i); } 39 | const Cell* pCell(const Int i) const { return _vpCells.at(i); } 40 | Vector& vpCells() { return _vpCells; } 41 | const Vector& vpCells() const { return _vpCells; } 42 | Int numCells() const { return _vpCells.size(); } 43 | 44 | bool isOdd() const { return _isOdd; } 45 | bool isEven() const { return !_isOdd; } 46 | 47 | 48 | private: 49 | String _name; 50 | Int _idx; 51 | Vector _vpCells; 52 | bool _isOdd; 53 | }; 54 | 55 | PROJECT_NAMESPACE_END 56 | 57 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPlaceSymCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class PlaceSymCstr { 25 | friend class Parser; 26 | 27 | public: 28 | PlaceSymCstr() : _idx(-1), _axis(SymAxisE::undef), _numPartAs(0), _numSelfSyms(0) {} 29 | ~PlaceSymCstr() {} 30 | 31 | const String& name() const { return _name; } 32 | Int idx() const { return _idx; } 33 | 34 | SymAxisE axis() const { return _axis; } 35 | bool isHor() const { return _axis == SymAxisE::hor; } 36 | bool isVer() const { return _axis == SymAxisE::ver; } 37 | 38 | Cell& cell(const Int i) { return *_vpCells.at(i); } 39 | const Cell& cell(const Int i) const { return *_vpCells.at(i); } 40 | Cell* pCell(const Int i) { return _vpCells.at(i); } 41 | const Cell* pCell(const Int i) const { return _vpCells.at(i); } 42 | Vector& vpCells() { return _vpCells; } 43 | const Vector& vpCells() const { return _vpCells; } 44 | Int numCells() const { return _vpCells.size(); } 45 | 46 | SymPartE symPart(const Int i) const { return _vSymPartEs.at(i); } 47 | SymPartE symPart(const Cell& c) const { return _vSymPartEs.at(cellIdx2Idx(c.idx())); } 48 | bool isPartA(const Int i) const { return symPart(i) == SymPartE::a; } 49 | bool isPartA(const Cell& c) const { return symPart(c) == SymPartE::a; } 50 | bool isPartB(const Int i) const { return symPart(i) == SymPartE::b; } 51 | bool isPartB(const Cell& c) const { return symPart(c) == SymPartE::b; } 52 | bool isSelfSym(const Int i) const { return symPart(i) == SymPartE::self; } 53 | bool isSelfSym(const Cell& c) const { return symPart(c) == SymPartE::self; } 54 | Int numSelfSyms() const { return _numSelfSyms; } 55 | Int numPartAs() const { return _numPartAs; } 56 | bool hasSelfSym() const { return _numSelfSyms > 0; } 57 | 58 | Int cellIdx2Idx(const Int idx) const { return _mCellIdx2Idx.at(idx); } 59 | Int cellIdx2SymIdx(const Int idx) const { return _vSymCellIds.at(cellIdx2Idx(idx)); } 60 | bool hasCell(const Cell& c) const { return _mCellIdx2Idx.find(c.idx()) != _mCellIdx2Idx.end(); } 61 | 62 | Cell& symCell(const Int i) { return *_vpCells.at(_vSymCellIds.at(i)); } 63 | Cell& symCell(const Cell& c) { return *_vpCells.at(cellIdx2SymIdx(c.idx())); } 64 | const Cell& symCell(const Int i) const { return *_vpCells.at(_vSymCellIds.at(i)); } 65 | const Cell& symCell(const Cell& c) const { return *_vpCells.at(cellIdx2SymIdx(c.idx())); } 66 | Cell* pSymCell(const Int i) { return _vpCells.at(_vSymCellIds.at(i)); } 67 | Cell* pSymCell(const Cell& c) { return _vpCells.at(cellIdx2SymIdx(c.idx())); } 68 | const Cell* pSymCell(const Int i) const { return _vpCells.at(_vSymCellIds.at(i)); } 69 | const Cell* pSymCell(const Cell& c) const { return _vpCells.at(cellIdx2SymIdx(c.idx())); } 70 | 71 | const Region& region() const { return _vpCells.at(0)->region(); } 72 | const Region* pRegion() const { return _vpCells.at(0)->pRegion(); } 73 | 74 | // for debug 75 | bool check() { 76 | bool b = true; 77 | const Region* pReg = _vpCells.at(0)->pRegion(); 78 | for (Int i = 1; i < (Int)_vpCells.size(); ++i) { 79 | Cell& c = *_vpCells.at(i); 80 | if (c.pRegion() != pReg) { 81 | b = false; 82 | } 83 | } 84 | return b; 85 | } 86 | 87 | private: 88 | 89 | String _name; 90 | Int _idx; 91 | SymAxisE _axis; 92 | 93 | Vector _vpCells; 94 | Vector _vSymPartEs; 95 | Vector _vSymCellIds; 96 | Int _numPartAs; 97 | Int _numSelfSyms; 98 | 99 | FlatHashMap _mCellIdx2Idx; // cell.idx() -> idx in _vpCells 100 | 101 | }; 102 | 103 | PROJECT_NAMESPACE_END 104 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbPrePlaceCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCell.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class Cell; 25 | class Region; 26 | 27 | class PrePlaceCstr { 28 | friend class Parser; 29 | 30 | public: 31 | PrePlaceCstr() 32 | : _idx(-1) 33 | {} 34 | ~PrePlaceCstr() {} 35 | 36 | const String& name() const { return _name; } 37 | Int idx() const { return _idx; } 38 | 39 | Cell& cell(const Int i) { return *_vpCells.at(i); } 40 | const Cell& cell(const Int i) const { return *_vpCells.at(i); } 41 | Cell* pCell(const Int i) { return _vpCells.at(i); } 42 | const Cell* pCell(const Int i) const { return _vpCells.at(i); } 43 | Vector& vpCells() { return _vpCells; } 44 | const Vector& vpCells() const { return _vpCells; } 45 | Int numCells() const { return _vpCells.size(); } 46 | 47 | Point cellLoc(const Int i) const { return _vCellLocs.at(i); } 48 | bool hasCellLoc(const Int i) const { return _vCellLocs.at(i) != Point(-1, -1); } 49 | 50 | Orient2dE cellOrient(const Int i) const { return _vCellOrients.at(i); } 51 | bool hasCellOrient(const Int i) const { return _vCellOrients.at(i) != Orient2dE::undef; } 52 | 53 | Region& region(const Int i) { return *_vpRegions.at(i); } 54 | const Region& region(const Int i) const { return *_vpRegions.at(i); } 55 | Region* pRegion(const Int i) { return _vpRegions.at(i); } 56 | const Region* pRegion(const Int i) const { return _vpRegions.at(i); } 57 | Vector& vpRegions() { return _vpRegions; } 58 | const Vector& vpRegions() const { return _vpRegions; } 59 | Int numRegions() const { return _vpRegions.size(); } 60 | 61 | Point regLoc(const Int i) const { return _vRegLocs.at(i); } 62 | bool hasRegLoc(const Int i) const { return _vRegLocs.at(i) != Point(-1, -1); } 63 | 64 | 65 | private: 66 | String _name; 67 | Int _idx; 68 | Vector _vpCells; 69 | Vector> _vCellLocs; 70 | Vector _vCellOrients; 71 | 72 | Vector _vpRegions; 73 | Vector> _vRegLocs; 74 | 75 | }; 76 | 77 | PROJECT_NAMESPACE_END 78 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbRoutePathMatchCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbBasic.hpp" 21 | #include "ds/hash.hpp" 22 | 23 | PROJECT_NAMESPACE_START 24 | 25 | class Pin; 26 | class Net; 27 | 28 | 29 | class RoutePathMatchCstr { 30 | friend class Parser; 31 | public: 32 | 33 | class PathCstr { 34 | friend class Parser; 35 | public: 36 | PathCstr() : _idx(-1) {} 37 | ~PathCstr() {} 38 | 39 | Int idx() const { return _idx; } 40 | 41 | Pin& srcPin(const Int i) { return *_vConns.at(i).first; } 42 | const Pin& srcPin(const Int i) const { return *_vConns.at(i).first; } 43 | Pin* pSrcPin(const Int i) { return _vConns.at(i).first; } 44 | const Pin* pSrcPin(const Int i) const { return _vConns.at(i).first; } 45 | 46 | Pin& tarPin(const Int i) { return *_vConns.at(i).second; } 47 | const Pin& tarPin(const Int i) const { return *_vConns.at(i).second; } 48 | Pin* pTarPin(const Int i) { return _vConns.at(i).second; } 49 | const Pin* pTarPin(const Int i) const { return _vConns.at(i).second; } 50 | 51 | Pair& conn(const Int i) { return _vConns.at(i); } 52 | const Pair& conn(const Int i) const { return _vConns.at(i); } 53 | 54 | Vector>& vConns() { return _vConns; } 55 | const Vector>& vConns() const { return _vConns; } 56 | Int numConns() const { return _vConns.size(); } 57 | 58 | bool hasNet(const Net* p) const { return _spNets.find(p) != _spNets.end(); } 59 | 60 | private: 61 | Int _idx; // idx in its parent cstr (the "idx"-th path cstr in the parent cstr) 62 | Vector> _vConns; 63 | FlatHashSet _spNets; 64 | }; 65 | 66 | RoutePathMatchCstr() 67 | : _idx(-1) 68 | {} 69 | ~RoutePathMatchCstr() {} 70 | 71 | const String& name() const { return _name; } 72 | Int idx() const { return _idx; } 73 | 74 | 75 | Net& net(const Int i) { return *_vpNets.at(i); } 76 | const Net& net(const Int i) const { return *_vpNets.at(i); } 77 | Net* pNet(const Int i) { return _vpNets.at(i); } 78 | const Net* pNet(const Int i) const { return _vpNets.at(i); } 79 | Vector& vpNets() { return _vpNets; } 80 | const Vector& vpNets() const { return _vpNets; } 81 | Int numNets() const { return _vpNets.size(); } 82 | 83 | PathCstr& pathCstr(const Int i) { return _vPathCstrs.at(i); } 84 | const PathCstr& pathCstr(const Int i) const { return _vPathCstrs.at(i); } 85 | PathCstr& pathCstr(const Net* p) { return _vPathCstrs.at(netIdx(p)); } 86 | const PathCstr& pathCstr(const Net* p) const { return _vPathCstrs.at(netIdx(p)); } 87 | Vector& vPathCstrs() { return _vPathCstrs; } 88 | const Vector& vPathCstrs() const { return _vPathCstrs; } 89 | Int numPathCstrs() const { return _vPathCstrs.size(); } 90 | 91 | Int netIdx(const Net* p) const { return _mNet2NetIdx.at(p); } 92 | bool hasNet(const Net* p) const { return _mNet2NetIdx.find(p) != _mNet2NetIdx.end(); } 93 | 94 | private: 95 | String _name; 96 | Int _idx; 97 | Vector _vpNets; 98 | Vector _vPathCstrs; 99 | FlatHashMap _mNet2NetIdx; 100 | }; 101 | 102 | PROJECT_NAMESPACE_END 103 | -------------------------------------------------------------------------------- /cpp/src/db/cstr/dbRouteSymCstr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbNet.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class RouteSymCstr { 25 | friend class Parser; 26 | 27 | public: 28 | RouteSymCstr() 29 | : _idx(-1), _axis(SymAxisE::undef), 30 | _numPartAs(0), _numSelfSyms(0) 31 | {} 32 | ~RouteSymCstr() {} 33 | 34 | const String& name() const { return _name; } 35 | Int idx() const { return _idx; } 36 | 37 | SymAxisE axis() const { return _axis; } 38 | 39 | Net& net(const Int i) { return *_vpNets.at(i); } 40 | const Net& net(const Int i) const { return *_vpNets.at(i); } 41 | Net* pNet(const Int i) { return _vpNets.at(i); } 42 | const Net* pNet(const Int i) const { return _vpNets.at(i); } 43 | Vector& vpNets() { return _vpNets; } 44 | const Vector& vpNets() const { return _vpNets; } 45 | Int numNets() const { return _vpNets.size(); } 46 | 47 | SymPartE symPart(const Int i) const { return _vSymPartEs.at(i); } 48 | SymPartE symPart(const Net& n) const { return _vSymPartEs.at(netIdx2Idx(n.idx())); } 49 | bool isPartA(const Int i) const { return symPart(i) == SymPartE::a; } 50 | bool isPartA(const Net& n) const { return symPart(n) == SymPartE::a; } 51 | bool isPartB(const Int i) const { return symPart(i) == SymPartE::b; } 52 | bool isPartB(const Net& n) const { return symPart(n) == SymPartE::b; } 53 | bool isSelfSym(const Int i) const { return symPart(i) == SymPartE::self; } 54 | bool isSelfSym(const Net& n) const { return symPart(n) == SymPartE::self; } 55 | Int numSelfSyms() const { return _numSelfSyms; } 56 | Int numPartAs() const { return _numPartAs; } 57 | bool hasSelfSym() const { return _numSelfSyms > 0; } 58 | 59 | Int netIdx2Idx(const Int idx) const { return _mNetIdx2Idx.at(idx); } 60 | Int netIdx2SymIdx(const Int idx) const { return _vSymNetIds.at(netIdx2Idx(idx)); } 61 | 62 | Net& symNet(const Int i) { return *_vpNets.at(_vSymNetIds.at(i)); } 63 | Net& symNet(const Net& n) { return *_vpNets.at(netIdx2SymIdx(n.idx())); } 64 | const Net& symNet(const Int i) const { return *_vpNets.at(_vSymNetIds.at(i)); } 65 | const Net& symNet(const Net& n) const { return *_vpNets.at(netIdx2SymIdx(n.idx())); } 66 | Net* pSymNet(const Int i) { return _vpNets.at(_vSymNetIds.at(i)); } 67 | Net* pSymNet(const Net& n) { return _vpNets.at(netIdx2SymIdx(n.idx())); } 68 | const Net* pSymNet(const Int i) const { return _vpNets.at(_vSymNetIds.at(i)); } 69 | const Net* pSymNet(const Net& n) const { return _vpNets.at(netIdx2SymIdx(n.idx())); } 70 | 71 | const Region& region() const { return _vpNets.at(0)->region(); } 72 | const Region* pRegion() const { return _vpNets.at(0)->pRegion(); } 73 | 74 | private: 75 | String _name; 76 | Int _idx; 77 | 78 | SymAxisE _axis; 79 | 80 | Vector _vpNets; 81 | Vector _vSymPartEs; 82 | Vector _vSymNetIds; 83 | Int _numPartAs; 84 | Int _numSelfSyms; 85 | 86 | FlatHashMap _mNetIdx2Idx; // net.idx() -> idx in _vpNets; 87 | }; 88 | 89 | PROJECT_NAMESPACE_END 90 | -------------------------------------------------------------------------------- /cpp/src/db/dbBasic.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #include "dbBasic.hpp" 19 | 20 | PROJECT_NAMESPACE_START 21 | 22 | namespace orient2d { 23 | 24 | Orient2dE rotate90(const Orient2dE o) 25 | { 26 | switch (o) { 27 | case Orient2dE::n: return Orient2dE::w; 28 | case Orient2dE::w: return Orient2dE::s; 29 | case Orient2dE::s: return Orient2dE::e; 30 | case Orient2dE::e: return Orient2dE::n; 31 | case Orient2dE::fn: return Orient2dE::fe; 32 | case Orient2dE::fw: return Orient2dE::fn; 33 | case Orient2dE::fs: return Orient2dE::fw; 34 | case Orient2dE::fe: return Orient2dE::fs; 35 | default: assert(false); 36 | } 37 | return Orient2dE::undef; 38 | } 39 | 40 | Orient2dE rotate180(const Orient2dE o) 41 | { 42 | switch (o) { 43 | case Orient2dE::n: return Orient2dE::s; 44 | case Orient2dE::w: return Orient2dE::e; 45 | case Orient2dE::s: return Orient2dE::n; 46 | case Orient2dE::e: return Orient2dE::w; 47 | case Orient2dE::fn: return Orient2dE::fs; 48 | case Orient2dE::fw: return Orient2dE::fe; 49 | case Orient2dE::fs: return Orient2dE::fn; 50 | case Orient2dE::fe: return Orient2dE::fw; 51 | default: assert(false); 52 | } 53 | return Orient2dE::undef; 54 | } 55 | 56 | Orient2dE rotate270(const Orient2dE o) 57 | { 58 | switch (o) { 59 | case Orient2dE::n: return Orient2dE::e; 60 | case Orient2dE::w: return Orient2dE::n; 61 | case Orient2dE::s: return Orient2dE::w; 62 | case Orient2dE::e: return Orient2dE::s; 63 | case Orient2dE::fn: return Orient2dE::fw; 64 | case Orient2dE::fw: return Orient2dE::fs; 65 | case Orient2dE::fs: return Orient2dE::fe; 66 | case Orient2dE::fe: return Orient2dE::fn; 67 | default: assert(false); 68 | } 69 | return Orient2dE::undef; 70 | } 71 | 72 | Orient2dE flipX(const Orient2dE o) 73 | { 74 | switch (o) { 75 | case Orient2dE::n: return Orient2dE::fn; 76 | case Orient2dE::w: return Orient2dE::fw; 77 | case Orient2dE::s: return Orient2dE::fs; 78 | case Orient2dE::e: return Orient2dE::fe; 79 | case Orient2dE::fn: return Orient2dE::n; 80 | case Orient2dE::fw: return Orient2dE::w; 81 | case Orient2dE::fs: return Orient2dE::s; 82 | case Orient2dE::fe: return Orient2dE::e; 83 | default: assert(false); 84 | } 85 | return Orient2dE::undef; 86 | } 87 | 88 | Orient2dE flipY(const Orient2dE o) 89 | { 90 | switch (o) { 91 | case Orient2dE::n: return Orient2dE::fs; 92 | case Orient2dE::w: return Orient2dE::fe; 93 | case Orient2dE::s: return Orient2dE::fn; 94 | case Orient2dE::e: return Orient2dE::fw; 95 | case Orient2dE::fn: return Orient2dE::s; 96 | case Orient2dE::fw: return Orient2dE::e; 97 | case Orient2dE::fs: return Orient2dE::n; 98 | case Orient2dE::fe: return Orient2dE::w; 99 | default: assert(false); 100 | } 101 | return Orient2dE::undef; 102 | } 103 | 104 | } 105 | 106 | namespace direction3d { 107 | 108 | Direction3dE findDir(const Point3d& u, const Point3d& v) 109 | { 110 | if (u.z() == v.z()) { 111 | if (u.x() == v.x()) { 112 | assert(u.y() != v.y()); 113 | return u.y() < v.y() ? Direction3dE::up : Direction3dE::down; 114 | } 115 | else { 116 | assert(u.x() != v.x()); 117 | return u.x() < v.x() ? Direction3dE::right : Direction3dE::left; 118 | } 119 | } 120 | else { 121 | assert(u.x() == v.x() and u.y() == v.y()); 122 | return u.z() < v.z() ? Direction3dE::via_up : Direction3dE::via_down; 123 | } 124 | } 125 | 126 | } 127 | 128 | PROJECT_NAMESPACE_END 129 | -------------------------------------------------------------------------------- /cpp/src/db/dbDevMap.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "dbPrim.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class DevMap { // device to primitives mapping 25 | friend class Parser; 26 | 27 | public: 28 | DevMap() 29 | : _name(""), _pPrim(nullptr), _multiplier(1), _bAbutment(false) {} 30 | ~DevMap() {} 31 | 32 | const String& name() const { return _name; } 33 | 34 | const Primitive& prim() const { return *_pPrim; } 35 | const Primitive* pPrim() const { return _pPrim; } 36 | Int multiplier() const { return _multiplier; } 37 | 38 | bool isAbutment() const { return _bAbutment; } 39 | 40 | const String& devNet(const Int i) const { return _vNetMaps.at(i).first; } 41 | const String& primNet(const Int i) const { return _vNetMaps.at(i).second; } 42 | const String& devNet2PrimNet(const String& n) const { return _vNetMaps.at(_mDevNetMap2Idx.at(n)).second; } 43 | const String& primNet2DevNet(const String& n) const { return _vNetMaps.at(_mPrimNetMap2Idx.at(n)).first; } 44 | Int numNets() const { return _vNetMaps.size(); } 45 | 46 | private: 47 | String _name; 48 | const Primitive* _pPrim; 49 | Int _multiplier; // number of prims to use 50 | bool _bAbutment; 51 | Vector> _vNetMaps; 52 | FlatHashMap _mDevNetMap2Idx; 53 | FlatHashMap _mPrimNetMap2Idx; 54 | }; 55 | 56 | PROJECT_NAMESPACE_END 57 | -------------------------------------------------------------------------------- /cpp/src/db/dbLayer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #include "dbLayer.hpp" 19 | 20 | PROJECT_NAMESPACE_START 21 | 22 | Int MetalLayer::eolIdx(const Int eolWidth) const 23 | { 24 | //Int idx = 0; 25 | //for (size_t i = 0; i < _vEolWidths.size(); ++i) { 26 | //if (_vEolWidths.at(i) < eolWidth) { 27 | //idx = i; 28 | //} 29 | //else { 30 | //break; 31 | //} 32 | //} 33 | //return idx; 34 | const Int idx = std::upper_bound(_vEolWidths.begin(), _vEolWidths.end(), eolWidth) - _vEolWidths.begin(); 35 | return idx >= static_cast(_vEolWidths.size()) ? _vEolWidths.size() - 1 : idx; 36 | } 37 | 38 | Int MetalLayer::prlSpacing(const Int width, const Int prl) const 39 | { 40 | 41 | // find prl 42 | Int prlIdx = std::upper_bound(_vSpacingTablePrl.begin(), _vSpacingTablePrl.end(), prl) - _vSpacingTablePrl.begin() - 1; 43 | if (prlIdx >= static_cast(_vSpacingTablePrl.size())) { 44 | prlIdx = _vSpacingTablePrl.size() - 1; 45 | } 46 | assert(_vSpacingTablePrl.at(prlIdx) <= prl); 47 | 48 | // find width 49 | Int wIdx = std::upper_bound(_vSpacingTableWidth.begin(), _vSpacingTableWidth.end(), width) - _vSpacingTableWidth.begin() - 1; 50 | if (wIdx >= static_cast(_vSpacingTableWidth.size())) { 51 | wIdx = _vSpacingTableWidth.size() - 1; 52 | } 53 | assert(_vSpacingTableWidth.at(wIdx) <= width); 54 | 55 | return _spacingTable.at(wIdx, prlIdx); 56 | 57 | } 58 | 59 | Int MetalLayer::validWidthIdx(const Int w) const 60 | { 61 | //Int idx = 0; 62 | //for (size_t i = 0; i < _vValidWidths.size(); ++i) { 63 | //if (_vValidWidths.at(i) >= w) { 64 | //idx = i; 65 | //break; 66 | //} 67 | //} 68 | //return idx; 69 | 70 | return std::lower_bound(_vValidWidths.begin(), _vValidWidths.end(), w) - _vValidWidths.begin(); 71 | } 72 | 73 | Int MetalLayer::validLengthIdx(const Int l) const 74 | { 75 | //Int idx = 0; 76 | //for (size_t i = 0; i < _vValidLengths.size(); ++i) { 77 | //if (_vValidLengths.at(i) >= l) { 78 | //idx = i; 79 | //break; 80 | //} 81 | //} 82 | //return idx; 83 | 84 | return std::lower_bound(_vValidLengths.begin(), _vValidLengths.end(), l) - _vValidLengths.begin(); 85 | } 86 | 87 | 88 | PROJECT_NAMESPACE_END 89 | -------------------------------------------------------------------------------- /cpp/src/db/dbObs.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "geo/box.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class Cell; 25 | 26 | class Obs { 27 | friend class Cell; 28 | friend class Parser; 29 | friend class LefReader; 30 | 31 | public: 32 | Obs() 33 | : _pCell(nullptr), _layerIdx(-1) {} 34 | Obs(const Box& b, const Int z) 35 | : _pCell(nullptr), _box(b), _layerIdx(z) {} 36 | ~Obs() {} 37 | Cell& cell() { return *_pCell; } 38 | const Cell& cell() const { return *_pCell; } 39 | Cell* pCell() { return _pCell; } 40 | const Cell* pCell() const { return _pCell; } 41 | 42 | Box& box() { return _box; } 43 | const Box& box() const { return _box; } 44 | Int layerIdx() const { return _layerIdx; } 45 | 46 | private: 47 | Cell* _pCell; 48 | Box _box; 49 | Int _layerIdx; 50 | }; 51 | 52 | PROJECT_NAMESPACE_END 53 | -------------------------------------------------------------------------------- /cpp/src/db/dbPrim.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "ds/hash.hpp" 21 | #include "dbPin.hpp" 22 | #include "dbObs.hpp" 23 | 24 | PROJECT_NAMESPACE_START 25 | 26 | 27 | class Primitive { 28 | friend class Parser; 29 | friend class LefReader; 30 | 31 | public: 32 | 33 | Primitive() 34 | : _idx(-1), _originX(0), _originY(0), _sizeX(0), _sizeY(0), _foreignX(0), _foreignY(0), 35 | _isXSym(false), _isYSym(false), _is90Sym(false) {} 36 | ~Primitive() {} 37 | 38 | const String& name() const { return _name; } 39 | Int idx() const { return _idx; } 40 | const String& classType() const { return _classType; } 41 | 42 | Int originX() const { return _originX; } 43 | Int originY() const { return _originY; } 44 | Int sizeX() const { return _sizeX; } 45 | Int sizeY() const { return _sizeY; } 46 | Int area() const { return _sizeX * _sizeY; } 47 | 48 | const String& foreignCellName() const { return _foreignCellName; } 49 | Int foreignX() const { return _foreignX; } 50 | Int foreignY() const { return _foreignY; } 51 | 52 | const Pin& pin(const Int i) const { return _vPins.at(i); } 53 | const Pin& pin(const String& n) const { return _vPins.at(pinName2Idx(n)); } 54 | Int pinName2Idx(const String& n) const { return _mPinName2Idx.at(n); } 55 | const Vector& vPins() const { return _vPins; } 56 | Int numPins() const { return _vPins.size(); } 57 | 58 | const Obs& obs(const Int i) const { return _vObs.at(i); } 59 | const Vector& vObs() const { return _vObs; } 60 | Int numObs() const { return _vObs.size(); } 61 | 62 | private: 63 | String _name; 64 | Int _idx; 65 | String _classType; 66 | Int _originX, _originY; 67 | Int _sizeX, _sizeY; 68 | String _foreignCellName; 69 | Int _foreignX, _foreignY; 70 | bool _isXSym; 71 | bool _isYSym; 72 | bool _is90Sym; 73 | 74 | Vector _vPins; 75 | FlatHashMap _mPinName2Idx; 76 | 77 | Vector _vObs; 78 | }; 79 | 80 | 81 | PROJECT_NAMESPACE_END 82 | -------------------------------------------------------------------------------- /cpp/src/db/dbVia.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "geo/box.hpp" 21 | #include "dbBasic.hpp" 22 | 23 | PROJECT_NAMESPACE_START 24 | 25 | class Via { 26 | friend class Parser; 27 | friend class LefReader; 28 | 29 | public: 30 | Via() 31 | : _name(""), _idx(-1), _type(ViaTypeE::undef), 32 | _minLayerIdx(MAX_INT), _maxLayerIdx(0) 33 | {} 34 | ~Via() {} 35 | 36 | const String& name() const { return _name; } 37 | Int idx() const { return _idx; } 38 | 39 | ViaTypeE type() const { return _type; } 40 | bool isDefault() const { return _type == ViaTypeE::def; } 41 | bool isGenerated() const { return _type == ViaTypeE::generated; } 42 | 43 | Box& box(const Int i) { return _vBoxes.at(i); } 44 | const Box& box(const Int i) const { return _vBoxes.at(i); } 45 | Box& box(const Int l, const Int i) { return _vBoxes.at(_vvBoxIds.at(l).at(i)); } 46 | const Box& box(const Int l, const Int i) const { return _vBoxes.at(_vvBoxIds.at(l).at(i)); } 47 | Vector>& vBoxes() { return _vBoxes; } 48 | const Vector>& vBoxes() const { return _vBoxes; } 49 | Int boxLayerIdx(const Int i) const { return _vBoxLayerIds.at(i); } 50 | Int numBoxes() const { return _vBoxes.size(); } 51 | Int numBoxes(const Int l) const { return _vvBoxIds.at(l).size(); } 52 | 53 | Int minLayerIdx() const { return _minLayerIdx; } 54 | Int maxLayerIdx() const { return _maxLayerIdx; } 55 | 56 | 57 | private: 58 | String _name; 59 | Int _idx; 60 | ViaTypeE _type; 61 | 62 | Vector> _vBoxes; 63 | Vector _vBoxLayerIds; 64 | Vector> _vvBoxIds; 65 | Int _minLayerIdx; 66 | Int _maxLayerIdx; 67 | 68 | }; 69 | 70 | #define Via_ForEachLayerIdx(via, i) \ 71 | for (i = via.minLayerIdx(); i <= via.maxLayerIdx(); ++i) 72 | 73 | #define Via_ForEachMetalLayerIdx(via, i) \ 74 | for (i = via.minLayerIdx(); i <= via.maxLayerIdx(); i += 2) 75 | 76 | #define Via_ForEachCutLayerIdx(via, i) \ 77 | for (i = via.minLayerIdx() + 1; i < via.maxLayerIdx(); i += 2) 78 | 79 | #define Via_ForEachLayerBox(via, layerIdx, pBox_, i) \ 80 | for (i = 0; i < via.numBoxes(layerIdx) and (pBox_ = &via.box(layerIdx, i)); ++i) 81 | 82 | PROJECT_NAMESPACE_END 83 | -------------------------------------------------------------------------------- /cpp/src/drc/drcMgr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCir.hpp" 21 | #include "geo/polygon.hpp" 22 | 23 | PROJECT_NAMESPACE_START 24 | 25 | class DrcMgr { 26 | public: 27 | DrcMgr(CirDB& cir) 28 | : _cir(cir) 29 | {} 30 | ~DrcMgr() {} 31 | 32 | //////////////////////////////////////// 33 | // Wire level checking // 34 | //////////////////////////////////////// 35 | 36 | // min/max width 37 | bool checkWireValidWidth(const Int layerIdx, const Box& b) const; 38 | 39 | // min/max length 40 | bool checkWireValidLength(const Int layerIdx, const Box& b) const; 41 | 42 | // spacing 43 | bool checkWireMetalSpacing(const Net& net, const Int layerIdx, const Box& b) const; 44 | bool checkWireMetalPrlSpacing(const Net& net, const Int layerIdx, const Box& b, const Int prl = 0) const; 45 | bool checkWireMetalEolSpacing(const Net& net, const Int layerIdx, const Box& b) const; 46 | bool checkWireCutSpacing(const Net& net, const Int layerIdx, const Box& b) const; 47 | 48 | // min area 49 | bool checkWireMinArea(const Int layerIdx, const Box& b) const; 50 | 51 | // via 52 | bool checkViaSpacing(const Net& net, const Int x, const Int y, const Via& via, const Orient2dE orient) const; 53 | 54 | // min step 55 | bool checkWireMinStep(const Int layerIdx, const Box& b) const; 56 | bool checkWireMinStep(const Int layerIdx, const Polygon& p) const; 57 | 58 | // total 59 | bool checkWire(const Net& net, const Pair, Int>& wire) const; 60 | //////////////////////////////////////// 61 | // Net level checking // 62 | //////////////////////////////////////// 63 | DrvE checkNet(const Net& net) const; 64 | 65 | //////////////////////////////////////// 66 | // Fix Funcs // 67 | //////////////////////////////////////// 68 | void fitWire2ValidLength(const Int layerIdx, Box& b) const; 69 | 70 | private: 71 | CirDB& _cir; 72 | }; 73 | 74 | PROJECT_NAMESPACE_END 75 | -------------------------------------------------------------------------------- /cpp/src/ds/array2d.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "global/global.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | template 25 | class Array2d { 26 | public: 27 | Array2d() : _numX(0), _numY(0) {} 28 | Array2d(const Int x, const Int y) : _numX(x), _numY(y), _vec(x * y) {} 29 | Array2d(const Int x, const Int y, const T& val) : _numX(x), _numY(y), _vec(x * y, val) {} 30 | ~Array2d() {} 31 | 32 | // get 33 | Int numX() const { return _numX; } 34 | Int numY() const { return _numY; } 35 | Int size() const { return _vec.size(); } 36 | T& at(const Int i) { return _vec.at(i); } 37 | const T& at(const Int i) const { return _vec.at(i); } 38 | T& at(const Int x, const Int y) { return _vec.at(flatIdx(x, y)); } 39 | const T& at(const Int x, const Int y) const { return _vec.at(flatIdx(x, y)); } 40 | 41 | // iterator 42 | inline typename Vector::iterator begin() { return _vec.begin(); } 43 | inline typename Vector::const_iterator cbegin() const { return _vec.cbegin(); } 44 | inline typename Vector::iterator end() { return _vec.end(); } 45 | inline typename Vector::const_iterator cend() const { return _vec.cend(); } 46 | 47 | // set 48 | void clear() { _numX = _numY = 0; _vec.clear(); } 49 | void resize(const Int x, const Int y) { _numX = x; _numY = y; _vec.resize(x * y); } 50 | void resize(const Int x, const Int y, const T& val) { _numX = x; _numY = y; _vec.resize(x * y, val); } 51 | void set(const Int x, const Int y, const T& val) { _vec[flatIdx(x, y)] = val; } 52 | 53 | T& operator [] (const Int i) { return _vec.at(i); } 54 | 55 | private: 56 | Int _numX; 57 | Int _numY; 58 | Vector _vec; 59 | 60 | Int flatIdx(const Int x, const Int y) const { 61 | assert(0 <= x and x < _numX); 62 | assert(0 <= y and y < _numY); 63 | return x * _numY + y; 64 | } 65 | Pair nestedIdx(const Int i) const { return std::make_pair(i / _numY, i % _numY); } 66 | }; 67 | 68 | 69 | #define Array2d_ForEachEntryX(a2d, y, pEntry_, i) \ 70 | for (i = 0; i < a2d.numX() and (pEntry_ = &a2d.at(i, y)); ++i) 71 | 72 | #define Array2d_ForEachEntryY(a2d, x, pEntry_, i) \ 73 | for (i = 0; i < a2d.numY() and (pEntry_ = &a2d.at(x, i)); ++i) 74 | 75 | 76 | PROJECT_NAMESPACE_END 77 | 78 | -------------------------------------------------------------------------------- /cpp/src/ds/array3d.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "global/global.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | template 25 | class Array3d { 26 | public: 27 | Array3d() : _numX(0), _numY(0), _numZ(0), _numYZ(0) {} 28 | Array3d(const Int x, const Int y, const Int z) : _numX(x), _numY(y), _numZ(z), _numYZ(y * z), _vec(x * y * z) {} 29 | Array3d(const Int x, const Int y, const Int z, const T& val) : _numX(x), _numY(y), _numZ(z), _numYZ(y * z), _vec(x * y * z, val) {} 30 | ~Array3d() {} 31 | 32 | // get 33 | Int numX() const { return _numX; } 34 | Int numY() const { return _numY; } 35 | Int numZ() const { return _numZ; } 36 | Int size() const { return _vec.size(); } 37 | T& at(const Int i) { return _vec.at(i); } 38 | const T& at(const Int i) const { return _vec.at(i); } 39 | T& at(const Int x, const Int y, const Int z) { return _vec.at(flatIdx(x, y, z)); } 40 | const T& at(const Int x, const Int y, const Int z) const { return _vec.at(flatIdx(x, y, z)); } 41 | 42 | // iterator 43 | inline typename Vector::iterator begin() { return _vec.begin(); } 44 | inline typename Vector::const_iterator cbegin() const { return _vec.cbegin(); } 45 | inline typename Vector::iterator end() { return _vec.end(); } 46 | inline typename Vector::const_iterator cend() const { return _vec.cend(); } 47 | 48 | // set 49 | void clear() { _numX = _numY = _numZ = _numYZ = 0; _vec.clear(); } 50 | void resize(const Int x, const Int y, const Int z) { _numX = x; _numY = y; _numZ = z; _numYZ = y * z; _vec.resize(x * y * z); } 51 | void resize(const Int x, const Int y, const Int z, const T& val) { _numX = x; _numY = y; _numZ = z; _numYZ = y * z; _vec.resize(x * y * z, val); } 52 | void set(const Int x, const Int y, const Int z, const T& val) { _vec[flatIdx(x, y, z)] = val; } 53 | 54 | T& operator [] (const Int i) { return _vec.at(i); } 55 | 56 | private: 57 | Int _numX; 58 | Int _numY; 59 | Int _numZ; 60 | Int _numYZ; 61 | Vector _vec; 62 | 63 | Int flatIdx(const Int x, const Int y, const Int z) const { 64 | assert(0 <= x and x < _numX); 65 | assert(0 <= y and y < _numY); 66 | assert(0 <= z and z < _numZ); 67 | return x * _numYZ + y * _numZ + z; 68 | } 69 | }; 70 | 71 | #define Array3d_ForEachEntryX(a3d, y, z, pEntry_, i) \ 72 | for (i = 0; i < a3d.numX() and (pEntry_ = &a3d.at(i, y, z)); ++i) 73 | 74 | #define Array3d_ForEachEntryY(a3d, x, z, pEntry_, i) \ 75 | for (i = 0; i < a3d.numY() and (pEntry_ = &a3d.at(x, i, z)); ++i) 76 | 77 | #define Array3d_ForEachEntryZ(a3d, x, y, pEntry_, i) \ 78 | for (i = 0; i < a3d.numZ() and (pEntry_ = &a3d.at(x, y, i)); ++i) 79 | 80 | PROJECT_NAMESPACE_END 81 | 82 | -------------------------------------------------------------------------------- /cpp/src/ds/disjointSet.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "global/namespace.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class DisjointSet { 25 | public: 26 | DisjointSet() 27 | : parent(0), rnk(0), n(0) {} 28 | DisjointSet(Int n) { init(n); } 29 | ~DisjointSet() { 30 | delete [] parent; 31 | delete [] rnk; 32 | } 33 | 34 | void init(Int n) { 35 | this->n = n; 36 | parent = new Int[n]; 37 | rnk = new Int[n]; 38 | for (Int i = 0; i < n; ++i) { 39 | rnk[i] = 0; 40 | parent[i] = i; 41 | } 42 | } 43 | // Find set 44 | Int find(Int u) { 45 | return (u == parent[u] ? u : parent[u] = find(parent[u])); 46 | } 47 | 48 | // Union by rank 49 | void merge(Int x, Int y) { 50 | x = find(x), y = find(y); 51 | if (x == y) 52 | return; 53 | if (rnk[x] > rnk[y]) 54 | parent[y] = x; 55 | else // If rnk[x] <= rnk[y] 56 | parent[x] = y; 57 | if (rnk[x] == rnk[y]) 58 | rnk[y]++; 59 | } 60 | 61 | // Number of disjoint sets 62 | Int nSets() { 63 | Int nSets = 0; 64 | for (Int i = 0; i < n; ++i) 65 | if (parent[i] == i) ++nSets; 66 | return nSets; 67 | } 68 | 69 | private: 70 | Int *parent, *rnk; 71 | Int n; 72 | }; 73 | 74 | PROJECT_NAMESPACE_END 75 | 76 | -------------------------------------------------------------------------------- /cpp/src/ds/hash.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | 22 | #include "global/namespace.hpp" 23 | 24 | PROJECT_NAMESPACE_START 25 | 26 | template 27 | using FlatHashSet = phmap::flat_hash_set; 28 | 29 | template 30 | using FlatHashMap = phmap::flat_hash_map; 31 | 32 | template 33 | using ParallelFlatHashSet = phmap::parallel_flat_hash_set; 34 | 35 | template 36 | using ParallelFlatHashMap = phmap::parallel_flat_hash_map; 37 | 38 | template 39 | using NodeHashSet = phmap::node_hash_set; 40 | 41 | template 42 | using NodeHashMap = phmap::node_hash_map; 43 | 44 | template 45 | using ParallelNodeHashSet = phmap::parallel_node_hash_set; 46 | 47 | template 48 | using ParallelNodeHashMap = phmap::parallel_node_hash_map; 49 | 50 | PROJECT_NAMESPACE_END 51 | 52 | -------------------------------------------------------------------------------- /cpp/src/ds/pqueue.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | 22 | #include "global/namespace.hpp" 23 | 24 | PROJECT_NAMESPACE_START 25 | 26 | 27 | template > 28 | using Pqueue = __gnu_pbds::priority_queue; 29 | 30 | template > 31 | using BinaryHeap = __gnu_pbds::priority_queue; 32 | 33 | template > 34 | using BinomialHeap = __gnu_pbds::priority_queue; 35 | 36 | template > 37 | using RCBinomialHeap = __gnu_pbds::priority_queue; 38 | 39 | template > 40 | using PairingHeap = __gnu_pbds::priority_queue; 41 | 42 | template > 43 | using ThinHeap = __gnu_pbds::priority_queue; 44 | 45 | PROJECT_NAMESPACE_END 46 | 47 | -------------------------------------------------------------------------------- /cpp/src/geo/box2polygon.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include "polygon2box.hpp" 22 | #include "polygon.hpp" 23 | #include "ds/hash.hpp" 24 | 25 | PROJECT_NAMESPACE_START 26 | 27 | namespace geo { 28 | template 29 | inline boost::polygon::polygon_90_set_data box2NativePolygon(const Vector>& vBoxes) 30 | { 31 | typedef boost::polygon::property_merge_90 PropertyMergeType; // use Int as property_type 32 | typedef boost::polygon::polygon_90_set_data PolygonSetType; 33 | typedef Map, PolygonSetType> PropertyMergeResultType; 34 | PropertyMergeType pm; 35 | for (size_t idx = 0; idx < vBoxes.size(); ++idx) { 36 | pm.insert(vBoxes[idx], 0); // Use 0 as property -> do not distinguish shapes 37 | } 38 | PropertyMergeResultType result; 39 | pm.merge(result); 40 | for (const auto& mapPair : result) { 41 | return mapPair.second; 42 | } 43 | assert(false); 44 | return (*result.begin()).second; 45 | } 46 | 47 | template 48 | void box2Polygon(const Vector>& vBoxes, Vector>& polygonVec) 49 | { 50 | if (vBoxes.empty()) { 51 | return; 52 | } 53 | const auto& polygonSet = box2NativePolygon(vBoxes); 54 | polygonSet.get_polygons(polygonVec); 55 | } 56 | 57 | // convert the boxes into nonoverlapping boxes 58 | template 59 | inline void boxes2Boxes(const Vector>& vBoxes, Vector>& results) 60 | { 61 | if (vBoxes.empty()) { 62 | return; 63 | } 64 | const auto& polygon = box2NativePolygon(vBoxes); 65 | polygon.get_rectangles(results); 66 | } 67 | 68 | // convert the boxes into nonoverlapping boxes 69 | template 70 | inline void boxes2BoxesEmplace(Vector>& vBoxes) 71 | { 72 | if (vBoxes.empty()) { 73 | return; 74 | } 75 | const auto& polygon = box2NativePolygon(vBoxes); 76 | vBoxes.clear(); 77 | polygon.get_rectangles(vBoxes); 78 | } 79 | 80 | 81 | // do difference on two vector of boxes 82 | template 83 | inline void boxesDiffAssign(Vector>& lhs, const Vector>& rhs) 84 | { 85 | typedef boost::polygon::polygon_90_set_data PolygonSetType; 86 | PolygonSetType lps, rps; 87 | for (const auto& rect : lhs) { 88 | lps.insert(rect); 89 | } 90 | for (const auto& rect : rhs) { 91 | rps.insert(rect); 92 | } 93 | boost::polygon::operators::operator-=(lps, rps); 94 | lhs.clear(); 95 | lps.get_rectangles(lhs); 96 | } 97 | 98 | /// @brief do difference on two vector of boxes 99 | template 100 | inline void boxesAddAssign(Vector>& lhs, const Vector>& rhs) 101 | { 102 | typedef boost::polygon::polygon_90_set_data PolygonSetType; 103 | PolygonSetType lps, rps; 104 | for (const auto &rect : lhs) 105 | { 106 | lps.insert(rect); 107 | } 108 | for (const auto &rect : rhs) 109 | { 110 | rps.insert(rect); 111 | } 112 | boost::polygon::operators::operator+=(lps, rps); 113 | lhs.clear(); 114 | lps.get_rectangles(lhs); 115 | } 116 | }; 117 | 118 | PROJECT_NAMESPACE_END 119 | 120 | -------------------------------------------------------------------------------- /cpp/src/geo/geometry.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | #include "point.hpp" 20 | #include "point3d.hpp" 21 | #include "segment.hpp" 22 | #include "segment3d.hpp" 23 | #include "box.hpp" 24 | #include "kdtree.hpp" 25 | #include "intervaltree.hpp" 26 | #include "spatial.hpp" 27 | #include "spatial3d.hpp" 28 | #include "polygon2box.hpp" 29 | 30 | -------------------------------------------------------------------------------- /cpp/src/geo/interval.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | #include /// std::max std::min 20 | //#include 21 | #include "global/namespace.hpp" 22 | #include 23 | #include 24 | 25 | PROJECT_NAMESPACE_START 26 | 27 | template class Interval { 28 | public: 29 | explicit Interval() = default; 30 | explicit Interval(const T &begin, const T &end) { 31 | _begin = std::min(begin, end); 32 | _end = std::max(begin, end); 33 | } 34 | 35 | // Getters 36 | const T &begin() const { return _begin; } 37 | T &begin() { return _begin; } 38 | const T &end() const { return _end; } 39 | T &end() { return _end; } 40 | /// @brief get the length of the interval 41 | /// @return the length of the interval 42 | T length() const { return _end - _begin; } 43 | 44 | // setters 45 | void setBegin(const T &begin) { 46 | _begin = std::min(begin, _end); 47 | _end = std::max(begin, _end); 48 | } 49 | void setEnd(const T &end) { 50 | _begin = std::min(_begin, end); 51 | _end = std::max(_begin, end); 52 | } 53 | 54 | /*------------------------------*/ 55 | /* Useful operations */ 56 | /*------------------------------*/ 57 | /// @brief determine if two interval are adjacent 58 | /// @param another Interval want to compare 59 | /// @return true if two intervals are adjacent to each other, false if not 60 | bool adjacent(const Interval &other) const; 61 | /// @brief operator < 62 | /// @param another Interval 63 | bool operator<(const Interval &rhs) const { 64 | return this->begin() == rhs.begin() ? this->end() < rhs.end() 65 | : this->begin() < rhs.end(); 66 | } 67 | /// @brief operator == 68 | /// @pararm another Interval 69 | bool operator==(const Interval &rhs) const { 70 | return this->begin() == rhs.begin() && this->end() == rhs.end(); 71 | } 72 | 73 | private: 74 | T _begin; 75 | T _end; 76 | }; 77 | 78 | template 79 | bool Interval::adjacent(const Interval &other) const { 80 | 81 | if (this->end() == other.begin()) { 82 | return true; 83 | } 84 | if (this->begin() == other.end()) { 85 | return true; 86 | } 87 | if (this->begin() == other.begin()) { 88 | return true; 89 | } 90 | if (this->end() == other.end()) { 91 | return true; 92 | } 93 | return false; 94 | } 95 | 96 | PROJECT_NAMESPACE_END 97 | 98 | /// @brief hash function for PROJECT_NAMASPACE::Interval 99 | namespace std { 100 | template struct hash> { 101 | typedef PROJECT_NAMESPACE::Interval argumentType; 102 | typedef std::size_t resultType; 103 | resultType operator()(argumentType const &s) const noexcept { 104 | resultType seed = 0; 105 | boost::hash_combine(seed, hash(s.begin())); 106 | boost::hash_combine(seed, hash(s.end())); 107 | return seed; 108 | } 109 | }; 110 | } // namespace std 111 | 112 | #include 113 | #include 114 | 115 | namespace boost { 116 | namespace polygon { 117 | template 118 | struct geometry_concept> { 119 | typedef interval_concept type; 120 | }; 121 | // The semantic of an interval is that it has a low and high coordinate and 122 | // there is an invariant that low is less than or equal to high. This invariant 123 | // is enforced by the generic library functions that operate on intervals, and 124 | // is not expected of the data type itself or the concept mapping of that data 125 | // type to the interval concept through its traits. In this way a 126 | // std::pair, boost::tuple or boost::array could all 127 | // be made models of interval by simply providing indirect access to their 128 | // elements through traits. In other words, the invariant checking in the 129 | // Interval class is redundant 130 | template 131 | struct interval_traits> { 132 | typedef CoordType coordinate_type; 133 | static inline coordinate_type 134 | get(const PROJECT_NAMESPACE::Interval &interval, 135 | direction_1d dir) { 136 | if (dir == LOW) { 137 | return interval.begin(); 138 | } else { 139 | return interval.end(); 140 | } 141 | } 142 | }; 143 | template 144 | struct interval_mutable_traits> { 145 | typedef CoordType coordinate_type; 146 | static inline void set(PROJECT_NAMESPACE::Interval &interval, 147 | direction_1d dir, CoordType value) { 148 | if (dir == LOW) { 149 | interval.setBegin(value); 150 | } else { 151 | interval.setEnd(value); 152 | } 153 | } 154 | static inline PROJECT_NAMESPACE::Interval 155 | construct(CoordType low_value, CoordType high_value) { 156 | return PROJECT_NAMESPACE::Interval(low_value, high_value); 157 | } 158 | }; 159 | } // namespace polygon 160 | }; // namespace boost 161 | -------------------------------------------------------------------------------- /cpp/src/geo/polygon2box.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Hao Chen 2020 - 2022. 3 | * Distributed under the Boost Software License, Version 1.0. 4 | * (See accompanying file LICENSE_1_0.txt or copy at 5 | * https://www.boost.org/LICENSE_1_0.txt) 6 | */ 7 | 8 | /* 9 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 10 | * SPDX-License-Identifier: Apache-2.0 11 | * 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "box.hpp" 28 | #include 29 | 30 | namespace limbo::geometry { 31 | //////////////////////////////////////// 32 | // point_traits // 33 | //////////////////////////////////////// 34 | template 35 | struct point_traits> { 36 | typedef PROJECT_NAMESPACE::Point point_type; 37 | typedef T coordinate_type; 38 | 39 | static coordinate_type get(const point_type& point, orientation_2d orient) 40 | { 41 | if (orient == HORIZONTAL) 42 | return point.x(); 43 | else if (orient == VERTICAL) 44 | return point.y(); 45 | else 46 | assert(false); 47 | } 48 | 49 | static void set(point_type& point, orientation_2d orient, coordinate_type value) 50 | { 51 | if (orient == HORIZONTAL) 52 | return point.setX(value); 53 | else if (orient == VERTICAL) 54 | return point.setY(value); 55 | else 56 | assert(false); 57 | } 58 | 59 | static point_type construct(coordinate_type x, coordinate_type y) 60 | { 61 | return point_type(x, y); 62 | } 63 | }; 64 | //////////////////////////////////////// 65 | // rectangle_traits // 66 | //////////////////////////////////////// 67 | template 68 | struct rectangle_traits> { 69 | typedef PROJECT_NAMESPACE::Box rectangle_type; 70 | typedef T coordinate_type; 71 | 72 | static coordinate_type get(const rectangle_type& rect, direction_2d dir) 73 | { 74 | switch (dir) { 75 | case LEFT: 76 | return rect.xl(); 77 | case BOTTOM: 78 | return rect.yl(); 79 | case RIGHT: 80 | return rect.xh(); 81 | case TOP: 82 | return rect.yh(); 83 | default: 84 | assert(false); 85 | } 86 | } 87 | 88 | static void set(rectangle_type& rect, direction_2d dir, coordinate_type value) 89 | { 90 | switch (dir) { 91 | case LEFT: 92 | rect.setXL(value); 93 | break; 94 | case BOTTOM: 95 | rect.setYL(value); 96 | break; 97 | case RIGHT: 98 | rect.setXH(value); 99 | break; 100 | case TOP: 101 | rect.setYH(value); 102 | break; 103 | default: 104 | assert(false); 105 | } 106 | } 107 | 108 | static rectangle_type construct(coordinate_type xl, coordinate_type yl, coordinate_type xh, coordinate_type yh) 109 | { 110 | return rectangle_type(xl, yl, xh, yh); 111 | } 112 | }; 113 | } 114 | 115 | PROJECT_NAMESPACE_START 116 | 117 | namespace geo { 118 | template 119 | inline bool polygon2Box(const Vector>& vPts, Vector>& vBoxes) { 120 | limbo::geometry::Polygon2Rectangle>, Vector>> p2r(vBoxes, vPts.begin(), vPts.end(), limbo::geometry::HOR_VER_SLICING); 121 | return p2r(); 122 | } 123 | } 124 | 125 | PROJECT_NAMESPACE_END 126 | 127 | -------------------------------------------------------------------------------- /cpp/src/geo/segment.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file segment.hpp 3 | * @brief Geometric Data Structure: 2D segment type 4 | * @author Hao Chen 5 | * @date 09/05/2019 6 | * 7 | **/ 8 | 9 | 10 | #pragma once 11 | 12 | #include "point.hpp" 13 | 14 | PROJECT_NAMESPACE_START 15 | 16 | template 17 | class Segment { 18 | public: 19 | Segment(T x0 = 0, T y0 = 0, T x1 = 0, T y1 = 0) 20 | : _p0(x0, y0), _p1(x1, y1) {} 21 | Segment(const Point& p0, const Point& p1) 22 | : _p0(p0), _p1(p1) {} 23 | ~Segment() {} 24 | 25 | // Basic access functions 26 | Point& p0() { return _p0; } 27 | const Point& p0() const { return _p0; } 28 | Point& p1() { return _p1; } 29 | const Point& p1() const { return _p1; } 30 | 31 | T length() const { return Point::Mdistance(_p0, _p1); } 32 | T xl() const { return std::min(_p0.x(), _p1.x()); } 33 | T xh() const { return std::max(_p0.x(), _p1.x()); } 34 | T yl() const { return std::min(_p0.y(), _p1.y()); } 35 | T yh() const { return std::max(_p0.y(), _p1.y()); } 36 | T centerX() const { return (xl() + xh()) / 2; } 37 | T centerY() const { return (yl() + yh()) / 2; } 38 | Point center() const { return Point(centerX(), centerY()); } 39 | Point min_corner() const { return Point(xl(), yl()); } 40 | Point max_corner() const { return Point(xh(), yh()); } 41 | bool bHor() const { return _p0.x() != _p1.x() && _p0.y() == _p1.y(); } 42 | bool bVer() const { return _p0.x() == _p1.x() && _p0.y() != _p1.y(); } 43 | bool b90() const { return bHor() or bVer(); } 44 | 45 | // util functions 46 | void shiftX(const T x) { _p0.shiftX(x); _p1.shiftX(x); } 47 | void shiftY(const T y) { _p0.shiftY(y); _p1.shiftY(y); } 48 | void shiftXY(const T x, const T y) { shiftX(x); shiftY(y); } 49 | 50 | // operators 51 | friend std::ostream& operator << (std::ostream& os, const Segment& s) { os << s._p0 << s._p1; return os; } 52 | bool operator == (const Segment& s) const { return _p0 == s._p0 && _p1 == s._p1; } 53 | bool operator != (const Segment& s) const { return !(*this == s); } 54 | void operator = (const Segment& s) { _p0 = s._p0; _p1 = s._p1; } 55 | bool operator < (const Segment& s) const { return std::tie(_p0, _p1) < std::tie(s._p0, s._p1); } 56 | bool operator > (const Segment& s) const { return std::tie(_p0, _p1) > std::tie(s._p0, s._p1); } 57 | bool operator <= (const Segment& s) const { return !(*this > s); } 58 | bool operator >= (const Segment& s) const { return !(*this < s); } 59 | 60 | // static funcs 61 | static bool bConnect(const Segment& s0, const Segment& s1); 62 | 63 | // hasher 64 | struct hasher { 65 | size_t operator() (const Segment& s) const { 66 | size_t seed = 0; 67 | boost::hash_combine(seed, s._p0.x()); 68 | boost::hash_combine(seed, s._p0.y()); 69 | boost::hash_combine(seed, s._p1.x()); 70 | boost::hash_combine(seed, s._p1.y()); 71 | return seed; 72 | } 73 | }; 74 | friend size_t hash_value(const Segment& s) { 75 | return phmap::HashState().combine(0, s._p0.x(), s._p0.y(), s._p1.x(), s._p1.y()); 76 | } 77 | 78 | private: 79 | Point _p0, _p1; 80 | }; 81 | 82 | template 83 | bool Segment::bConnect(const Segment& s0, const Segment& s1) { 84 | Int o1 = Point::orientation(s0.p0(), s0.p1(), s1.p0()); 85 | Int o2 = Point::orientation(s0.p0(), s0.p1(), s1.p1()); 86 | Int o3 = Point::orientation(s1.p0(), s1.p1(), s0.p0()); 87 | Int o4 = Point::orientation(s1.p0(), s1.p1(), s0.p1()); 88 | 89 | // general case 90 | if (o1 != o2 and o3 != o4) 91 | return true; 92 | 93 | // special cases 94 | if (o1 == 0 and Point::bOnSegment(s0.p0(), s1.p0(), s0.p1())) 95 | return true; 96 | if (o2 == 0 and Point::bOnSegment(s0.p0(), s1.p1(), s0.p1())) 97 | return true; 98 | if (o3 == 0 and Point::bOnSegment(s1.p0(), s0.p0(), s1.p1())) 99 | return true; 100 | if (o4 == 0 and Point::bOnSegment(s1.p0(), s0.p1(), s1.p1())) 101 | return true; 102 | 103 | return false; 104 | } 105 | 106 | 107 | PROJECT_NAMESPACE_END 108 | 109 | -------------------------------------------------------------------------------- /cpp/src/global/define.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | #include 20 | 21 | #define assertm(exp, msg) assert((exp, (void)msg)) 22 | 23 | //#define NDEBUG 24 | -------------------------------------------------------------------------------- /cpp/src/global/global.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "define.hpp" 26 | #include "type.hpp" 27 | 28 | 29 | PROJECT_NAMESPACE_START 30 | 31 | 32 | 33 | PROJECT_NAMESPACE_END 34 | -------------------------------------------------------------------------------- /cpp/src/global/namespace.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | // Namespace of the project 20 | #define PROJECT_NAMESPACE AUTOCRAFT 21 | #define PROJECT_NAMESPACE_START namespace PROJECT_NAMESPACE { 22 | #define PROJECT_NAMESPACE_END } 23 | -------------------------------------------------------------------------------- /cpp/src/global/type.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | #include "namespace.hpp" 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | PROJECT_NAMESPACE_START 38 | 39 | using Int = std::int32_t; 40 | using Uint = std::uint32_t; 41 | using Real = double; 42 | using Byte = char; 43 | 44 | constexpr Int MAX_INT = std::numeric_limits::max() / 3; 45 | constexpr Int MIN_INT = std::numeric_limits::lowest() / 3; 46 | constexpr Uint MAX_UINT = std::numeric_limits::max() / 3; 47 | constexpr Uint MIN_UINT = std::numeric_limits::lowest() / 3; 48 | constexpr Real MAX_REAL = std::numeric_limits::max() / 3; 49 | constexpr Real MIN_REAL = std::numeric_limits::lowest() / 3; 50 | constexpr Real EPSILON = 1e-8; 51 | constexpr Real TIME_SCALE = 1000000.00; 52 | constexpr Real MEM_SCALE = 1024.0; 53 | 54 | // Type aliases 55 | using String = std::string; 56 | template using Pair = std::pair; 57 | template using Tuple = std::tuple; 58 | template using Queue = std::queue; 59 | template using Stack = std::stack; 60 | template using Array = std::array; 61 | template > using Vector = std::vector; 62 | template using List = std::list; 63 | template using Set = std::set; 64 | template using Map = std::map; 65 | template using Uset = std::unordered_set; 66 | template using Umap = std::unordered_map; 67 | template using UniquePtr = std::unique_ptr; 68 | template using SharedPtr = std::shared_ptr; 69 | template using WeakPtr = std::weak_ptr; 70 | template using Variant = std::variant; 71 | PROJECT_NAMESPACE_END 72 | -------------------------------------------------------------------------------- /cpp/src/graph/mst.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | 23 | #include "global/global.hpp" 24 | 25 | PROJECT_NAMESPACE_START 26 | 27 | template 28 | class MinimumSpanningTree { 29 | 30 | using Graph = GraphType; 31 | using Node = typename GraphType::Node; 32 | using Edge = typename GraphType::Edge; 33 | using EdgeMap = typename GraphType::template EdgeMap; 34 | 35 | public: 36 | explicit MinimumSpanningTree(const Int numNodes) : _edgeMap(_graph) { 37 | _vNodes.reserve(numNodes); 38 | for (Int i = 0; i < numNodes; ++i) { 39 | _vNodes.emplace_back(_graph.addNode()); 40 | } 41 | } 42 | 43 | ~MinimumSpanningTree() {} 44 | 45 | void addEdge(const Int u, const Int v, const CostType c) { 46 | Edge edge = _graph.addEdge(_vNodes[u], _vNodes[v]); 47 | _edgeMap[edge] = c; 48 | } 49 | 50 | // return the cost of the mst 51 | CostType solve(Vector>& vEdges) { 52 | Vector vRes; 53 | const Int cost = lemon::kruskal(_graph, _edgeMap, std::back_inserter(vRes)); 54 | 55 | for (size_t i = 0; i < vRes.size(); ++i) { 56 | const Edge& edge = vRes[i]; 57 | vEdges.emplace_back(_graph.id(_graph.u(edge)), _graph.id(_graph.v(edge))); 58 | } 59 | return cost; 60 | } 61 | 62 | private: 63 | Graph _graph; 64 | EdgeMap _edgeMap; 65 | Vector _vNodes; 66 | }; 67 | 68 | PROJECT_NAMESPACE_END 69 | -------------------------------------------------------------------------------- /cpp/src/io/parGds.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #include "parGds.hpp" 18 | #include "geo/polygon2box.hpp" 19 | #include "geo/box2polygon.hpp" 20 | #include "geo/spatial.hpp" 21 | #include "ds/disjointSet.hpp" 22 | 23 | PROJECT_NAMESPACE_START 24 | 25 | void GdsReader::parseRouting(const String& filename, const Vector& vNetIds) 26 | { 27 | // Flatten Gds by the last cell 28 | GdsParser::GdsDB::GdsDB unflatenDB; 29 | GdsParser::GdsDB::GdsReader limboReader(unflatenDB); 30 | if (!limboReader(filename)) { 31 | spdlog::error("GdsReader::{} ERROR: Cannot open file {}!!\n", __func__, filename.c_str()); 32 | exit(0); 33 | } 34 | 35 | 36 | // Flatten gds 37 | String topCellName = topCell(unflatenDB); 38 | auto flatCell = unflatenDB.extractCell(topCellName); 39 | //GdsParser::GdsDB::GdsDB gdsDB; 40 | //gdsDB.addCell(flatCell); 41 | 42 | // Build the mapping between the gds layer and the router layers 43 | buildLayerMap(); 44 | 45 | // Process the shapes in gds 46 | for (const auto& obj : flatCell.objects()) { 47 | GdsParser::GdsDB::GdsObjectHelpers()(obj.first, obj.second, ExtractShapeLayerAction(_maskIdx2LayerIdx, _vPolygonLayers)); 48 | } 49 | 50 | // scale the design 51 | const Real sc = 5e-10 / 1e-6 / _cir.physRes(); 52 | 53 | if (std::fabs(sc - 1) > EPSILON) { 54 | for (auto& polygon : _vPolygonLayers) { 55 | polygon.scale(sc, sc); 56 | } 57 | } 58 | // save to db 59 | saveShapes(vNetIds); 60 | } 61 | 62 | ///////////////////////////////////////// 63 | // Private functions // 64 | ///////////////////////////////////////// 65 | String GdsReader::topCell(const GdsParser::GdsDB::GdsDB& db) 66 | { 67 | // Whether each cell is found as the subcell of the other 68 | FlatHashMap mNameFound; 69 | // Iterate all the cells and record their names 70 | // Add reversely 71 | for (Int i = db.cells().size() - 1; i >= 0; --i) { 72 | mNameFound[db.cells().at(i).name()] = false; 73 | } 74 | for (const auto& cell : db.cells()) { 75 | for (const auto& obj : cell.objects()) { 76 | String name = ""; 77 | GdsParser::GdsDB::GdsObjectHelpers()(obj.first, obj.second, GetSRefNameActionParser(name)); 78 | if (name != "") { 79 | mNameFound[name] = true; 80 | } 81 | } 82 | } 83 | // Return the name that was not included in the other cells 84 | for (const auto& pair : mNameFound) { 85 | if (pair.first != "" and pair.second == false) { 86 | return pair.first; 87 | } 88 | } 89 | return ""; 90 | } 91 | 92 | void GdsReader::buildLayerMap() 93 | { 94 | for (Int i = 0; i < _cir.numLayers(); ++i) { 95 | const auto& layer = _cir.layer(i); 96 | _maskIdx2LayerIdx.emplace(layer.gdsLayerDrawing(), layer.idx()); 97 | } 98 | } 99 | 100 | void GdsReader::saveShapes(const Vector& vNetIds) 101 | { 102 | 103 | // build tmp spatial shapes 104 | Vector, Int>>> vLayerWireIds(_cir.numLayers()); 105 | Vector, Int>> vWires; 106 | for (const auto& poly : _vPolygonLayers) { 107 | const Int layerIdx = poly.layer; 108 | if (layerIdx != MAX_INT) { // ignore non routing layers 109 | Vector> vBoxes; 110 | geo::polygon2Box(poly.pts, vBoxes); 111 | assert(vBoxes.size() == 1); 112 | const auto& box = vBoxes.front(); 113 | vLayerWireIds[layerIdx].emplace_back(box, vWires.size()); 114 | vWires.emplace_back(box, layerIdx); 115 | } 116 | } 117 | Vector> vSpatialWireIds(_cir.numLayers()); 118 | for (size_t i = 0; i < vSpatialWireIds.size(); ++i) { 119 | vSpatialWireIds[i] = SpatialMap(vLayerWireIds[i]); 120 | } 121 | 122 | // group net shapes 123 | Vector vis(vWires.size()); 124 | 125 | DisjointSet ds(vWires.size()); 126 | for (size_t i = 0; i < vWires.size(); ++i) { 127 | const auto& wire = vWires.at(i); 128 | const Int l = wire.second; 129 | const auto& layer = _cir.layer(l); 130 | if (layer.isMetal()) { 131 | const auto& b = wire.first; 132 | Vector vTouchedWireIds; 133 | vSpatialWireIds[l].query(b, vTouchedWireIds); 134 | for (const Int wireIdx : vTouchedWireIds) { 135 | ds.merge(i, wireIdx); 136 | } 137 | } 138 | else if (layer.isCut()) { 139 | const auto& b = wire.first; 140 | Vector vUpperWireIds, vLowerWireIds; 141 | vSpatialWireIds[l - 1].query(b, vLowerWireIds); 142 | vSpatialWireIds[l + 1].query(b, vUpperWireIds); 143 | for (const Int wireIdx : vLowerWireIds) { 144 | ds.merge(i, wireIdx); 145 | } 146 | for (const Int wireIdx : vUpperWireIds) { 147 | ds.merge(i, wireIdx); 148 | } 149 | } 150 | } 151 | 152 | // assign wire group to net idx 153 | auto touchNetIdx = [&] (const auto& wire) -> Int { 154 | Vector vpPins; 155 | _cir.spatialPins(wire.second).query(wire.first, vpPins); 156 | if (vpPins.empty()) { 157 | return -1; 158 | } 159 | const Int netIdx = vpPins.at(0)->net().idx(); 160 | //#ifndef NDEBUG 161 | //for (const auto pPin : vpPins) { 162 | //assert(pPin->net().idx() == netIdx); 163 | //} 164 | //#endif 165 | return netIdx; 166 | }; 167 | 168 | 169 | FlatHashMap> rootIdx2WireIds; 170 | FlatHashMap netIdx2RootIdx; 171 | for (size_t i = 0; i < vWires.size(); ++i) { 172 | const Int rootIdx = ds.find(i); 173 | if (rootIdx2WireIds.find(rootIdx) == rootIdx2WireIds.end()) { 174 | rootIdx2WireIds.emplace(rootIdx, Vector()); 175 | } 176 | const auto& wire = vWires.at(i); 177 | rootIdx2WireIds[rootIdx].emplace_back(i); 178 | const Int netIdx = touchNetIdx(wire); 179 | if (netIdx > -1) { 180 | if (netIdx2RootIdx.find(netIdx) == netIdx2RootIdx.end()) { 181 | netIdx2RootIdx[netIdx] = rootIdx; 182 | } 183 | } 184 | } 185 | 186 | FlatHashSet sNetIds; 187 | sNetIds.insert(vNetIds.begin(), vNetIds.end()); 188 | 189 | for (const auto& item : netIdx2RootIdx) { 190 | const Int netIdx = item.first; 191 | if (sNetIds.empty() or sNetIds.find(netIdx) != sNetIds.end()) { 192 | const Int rootIdx = item.second; 193 | const auto& vWireIds = rootIdx2WireIds.at(rootIdx); 194 | Net& net = _cir.net(netIdx); 195 | net.setRouted(true); 196 | for (const Int wireIdx : vWireIds) { 197 | const auto& wire = vWires.at(wireIdx); 198 | net.sWires().emplace(wire); 199 | _cir.spatialNets(wire.second).insert(wire.first, &net); 200 | } 201 | } 202 | } 203 | 204 | 205 | } 206 | 207 | PROJECT_NAMESPACE_END 208 | -------------------------------------------------------------------------------- /cpp/src/io/parHspice.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #include "parHspice.hpp" 18 | #include "util/util.hpp" 19 | 20 | #include 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | void HspiceReader::parse(const String& fileName) 25 | { 26 | std::ifstream ifs(fileName, std::ios::in); 27 | 28 | String buf; 29 | Vector vTokens; 30 | 31 | FlatHashMap mDevices; 32 | 33 | while (std::getline(ifs, buf)) { 34 | if (buf.empty() or buf[0] == '*') // comments 35 | continue; 36 | util::str::split(buf, " ", vTokens); 37 | if (vTokens.at(0) == ".subckt" or vTokens.at(0) == ".topckt") { 38 | String tok = vTokens.at(1); 39 | 40 | const bool hasSpiceType = (tok.size() > 5 and tok.substr(0, 5) == "type:"); 41 | 42 | size_t pos = hasSpiceType ? 2 : 1; 43 | const String name = vTokens.at(pos); 44 | const String spiceType = hasSpiceType ? tok.substr(5) : ""; 45 | const NodeType type = 46 | vTokens.at(0) == ".subckt" ? NodeType::subckt : NodeType::topckt; 47 | 48 | const Int idx = _vNodes.size(); 49 | _mNodeName2Idx.emplace(name, idx); 50 | _vNodes.emplace_back(name, name, spiceType, type); 51 | Node& node = _vNodes.back(); 52 | 53 | ++pos; 54 | node._numPorts = vTokens.size() - pos; 55 | node._idx = idx; 56 | for (size_t i = pos; i < vTokens.size(); ++i) { 57 | const String& netName = vTokens.at(i); 58 | if (node._mNetName2Idx.find(netName) == node._mNetName2Idx.end()) { 59 | node._mNetName2Idx.emplace(netName, node._vNets.size()); 60 | node._vNets.emplace_back(netName); 61 | } 62 | } 63 | // handle this node block 64 | FlatHashMap mAttrVars; 65 | while (std::getline(ifs, buf)) { 66 | if (buf.empty() or buf[0] == '*') // comments 67 | continue; 68 | if (buf.find('$') != String::npos) // ignore $.model=.... 69 | continue; 70 | 71 | util::str::split(buf, " ", vTokens); 72 | if (vTokens.at(0) == ".ends") { 73 | assert(vTokens.size() == 1 or (vTokens.size() == 2 and vTokens.at(1) == name)); 74 | break; 75 | } 76 | if (vTokens.at(0) == "+") { // attr vals 77 | for (size_t i = 1; i < vTokens.size(); ++i) { 78 | const String& attr = vTokens.at(i); 79 | size_t eqPos = attr.find_first_of('='); 80 | const String& attrVarName = attr.substr(0, eqPos); 81 | const String& attrVarVal = attr.substr(eqPos + 1); 82 | mAttrVars.emplace(attrVarName, attrVarVal); 83 | } 84 | } 85 | 86 | size_t i = 1, j = i, k = 1; 87 | for (; j < vTokens.size() and vTokens.at(j).find('=') == String::npos; ++j) 88 | ; 89 | k = j; 90 | // construct a child node and set its connection 91 | const String& instName = vTokens.at(0); 92 | const String& tmplName = vTokens.at(--j); 93 | 94 | const bool hasTemplate = hasTmpl(tmplName); 95 | const String& st = hasTemplate ? this->node(tmplName).spiceType() : ""; 96 | const NodeType t = hasTemplate ? NodeType::subckt : NodeType::device; 97 | 98 | if (mDevices.find(tmplName) == mDevices.end()) { 99 | Node devNode(tmplName, tmplName, st, t); 100 | mDevices.emplace(tmplName, devNode); 101 | } 102 | 103 | node._vChilds.emplace_back(instName, tmplName, st, t); 104 | Node& child = node._vChilds.back(); 105 | for (; k < vTokens.size(); ++k) { 106 | const String& attr = vTokens.at(k); 107 | size_t eqPos = attr.find_first_of('='); 108 | const String& attrName = attr.substr(0, eqPos); 109 | const String& attrVal = attr.substr(eqPos + 1); 110 | if (attrVal.front() == '\'' and attrVal.back() == '\'') { 111 | const String& attrVar = attrVal.substr(1, attrVal.size() - 2); 112 | assert(mAttrVars.find(attrVar) != mAttrVars.end()); 113 | child._mAttrs.emplace(attrName, mAttrVars.at(attrVar)); 114 | } 115 | else { 116 | child._mAttrs.emplace(attrName, attrVal); 117 | } 118 | } 119 | 120 | for (; i < j; ++i) { 121 | const String& netName = vTokens.at(i); 122 | child._vNets.emplace_back(netName); 123 | if (node._mNetName2Idx.find(netName) == node._mNetName2Idx.end()) { 124 | node._mNetName2Idx.emplace(netName, node._vNets.size()); 125 | node._vNets.emplace_back(netName); 126 | } 127 | } 128 | child._numPorts = child._vNets.size(); 129 | // attributes: add something here if needed 130 | // for (; ++j < vTokens.size();) { 131 | //} 132 | } 133 | } 134 | else { 135 | assert(false); 136 | } 137 | } 138 | 139 | _numSubCkts = _vNodes.size(); 140 | 141 | // add device nodes (must be transistors) 142 | for (auto& item : mDevices) { 143 | const String& tmplName = item.first; 144 | const Int idx = _vNodes.size(); 145 | Node& node = item.second; 146 | node._idx = idx; 147 | node._numPorts = 4; 148 | node._mNetName2Idx.emplace("D", node._vNets.size()); 149 | node._vNets.emplace_back("D"); 150 | node._mNetName2Idx.emplace("G", node._vNets.size()); 151 | node._vNets.emplace_back("G"); 152 | node._mNetName2Idx.emplace("S", node._vNets.size()); 153 | node._vNets.emplace_back("S"); 154 | node._mNetName2Idx.emplace("B", node._vNets.size()); 155 | node._vNets.emplace_back("B"); 156 | _mNodeName2Idx.emplace(tmplName, idx); 157 | _vNodes.emplace_back(node); 158 | } 159 | 160 | } 161 | 162 | PROJECT_NAMESPACE_END 163 | -------------------------------------------------------------------------------- /cpp/src/io/parHspice.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #pragma once 18 | 19 | #include "global/global.hpp" 20 | #include "ds/hash.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class HspiceReader { 25 | public: 26 | enum class NodeType : Byte { undef = 0, device = 1, subckt = 2, topckt = 3 }; 27 | 28 | class Node { 29 | friend class HspiceReader; 30 | 31 | public: 32 | Node(const String& n, const String& tn, const String& s, 33 | NodeType t = NodeType::undef, const Int np = 0) 34 | : _instName(n), _tmplName(tn), _spiceType(s), _type(t), _numPorts(np), _idx(-1) 35 | { 36 | } 37 | ~Node() {} 38 | 39 | const String& instName() const { return _instName; } 40 | const String& tmplName() const { return _tmplName; } 41 | const String& spiceType() const { return _spiceType; } 42 | NodeType type() const { return _type; } 43 | bool isDevice() const { return _type == NodeType::device; } 44 | bool isSubCkt() const { return _type == NodeType::subckt; } 45 | bool isTopCkt() const { return _type == NodeType::topckt; } 46 | 47 | const Node& child(const Int i) const { return _vChilds.at(i); } 48 | const Vector& vChilds() const { return _vChilds; } 49 | Int numChilds() const { return _vChilds.size(); } 50 | 51 | const String& net(const Int i) const { return _vNets.at(i); } 52 | const Vector& vNets() const { return _vNets; } 53 | Int netName2Idx(const String& n) const { return _mNetName2Idx.at(n); } 54 | Int numNets() const { return _vNets.size(); } 55 | Int numPorts() const { return _numPorts; } 56 | 57 | const String& attrVal(const String& n) const { return _mAttrs.at(n); } 58 | const FlatHashMap& mAttrs() const { return _mAttrs; } 59 | Int numAttrs() const { return _mAttrs.size(); } 60 | bool hasAttrs() const { return _mAttrs.size() > 0; } 61 | 62 | Int idx() const { return _idx; } 63 | 64 | private: 65 | String _instName; 66 | String _tmplName; 67 | String _spiceType; // type attr in hspice netlists: analog, digital... 68 | NodeType _type; 69 | Vector _vChilds; 70 | Int _numPorts; // [0, _numPorts) in _vNets are ports 71 | Vector _vNets; // includes ports and internal nets 72 | FlatHashMap _mNetName2Idx; 73 | 74 | FlatHashMap _mAttrs; 75 | // helper 76 | Int _idx; 77 | }; 78 | 79 | HspiceReader() : _numSubCkts(0) {} 80 | ~HspiceReader() {} 81 | 82 | void parse(const String& fileName); 83 | 84 | 85 | const Node& node(const Int i) const { return _vNodes.at(i); } 86 | const Node& node(const String& s) const { return _vNodes.at(_mNodeName2Idx.at(s)); } 87 | const Node& topNode() const { return _vNodes.at(_numSubCkts - 1); } 88 | Int numNodes() const { return _vNodes.size(); } 89 | Int numSubCkts() const { return _numSubCkts; } 90 | Int numDevices() const { return numNodes() - numSubCkts(); } 91 | const Vector& vNodes() const { return _vNodes; } 92 | 93 | private: 94 | Vector _vNodes; 95 | FlatHashMap _mNodeName2Idx; 96 | Int _numSubCkts; 97 | 98 | bool hasTmpl(const String& s) const 99 | { 100 | return _mNodeName2Idx.find(s) != _mNodeName2Idx.end(); 101 | } 102 | }; 103 | 104 | PROJECT_NAMESPACE_END 105 | -------------------------------------------------------------------------------- /cpp/src/io/parLef.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "global/global.hpp" 27 | #include "db/dbCir.hpp" 28 | 29 | PROJECT_NAMESPACE_START 30 | 31 | class LefReader { 32 | public: 33 | LefReader(CirDB& cir) : _cir(cir), _dbUnit(2000) {} 34 | ~LefReader() {} 35 | 36 | void parse(const Vector& vFileNames); 37 | 38 | // callback impls 39 | void parseManufacturing(const Real num); 40 | void parseUnits(const lefiUnits* p); 41 | 42 | void parsePropDefs(const lefiProp* p); 43 | 44 | void parseLayer(const lefiLayer* p); 45 | void parseRoutingLayer(const lefiLayer* p); 46 | void parseCutLayer(const lefiLayer* p); 47 | 48 | void parseMacroBegin(const String& macroName); 49 | void parseMacroClassType(const String& macroClassType); 50 | void parseMacroOrigin(const lefiNum& macroNum); 51 | void parseMacroSize(const lefiNum& macroNum); 52 | void parseMacroForeign(const lefiMacroForeign* p); 53 | void parseMacroSite(const lefiMacroSite* p); 54 | void parseMacro(const lefiMacro* p); 55 | void parseMacroEnd(const String& macroName); 56 | void parsePin(const lefiPin* p); 57 | void parseObstruction(const lefiObstruction* p); 58 | void parsePinGeometry(Pin& pin, const Int originX, const Int originY, const lefiGeometries* pGeo); 59 | void parseObsGeometry(const lefiGeometries* pGeo); 60 | void parseVia(const lefiVia* p); 61 | 62 | 63 | private: 64 | CirDB& _cir; 65 | 66 | FlatHashMap _mLibraryPropName2Idx; 67 | Vector _vLibraryPropDataTypes; 68 | Vector> _vLibraryPropIntRanges; 69 | Vector> _vLibraryPropRealRanges; 70 | Vector _vLibraryPropNumberValues; 71 | Vector _vLibraryPropStringValues; 72 | 73 | FlatHashMap _mLayerPropName2Idx; 74 | Vector _vLayerPropDataTypes; 75 | Vector> _vLayerPropIntRanges; 76 | Vector> _vLayerPropRealRanges; 77 | Vector _vLayerPropNumberValues; 78 | 79 | FlatHashMap _mMacroPropName2Idx; 80 | Vector _vMacroPropDataTypes; 81 | Vector> _vMacroPropIntRanges; 82 | Vector> _vMacroPropRealRanges; 83 | Vector _vMacroPropNumberValues; 84 | 85 | FlatHashMap _mNonDefaultPropName2Idx; 86 | Vector _vNonDefaultPropDataTypes; 87 | Vector> _vNonDefaultPropIntRanges; 88 | Vector> _vNonDefaultPropRealRanges; 89 | Vector _vNonDefaultPropNumberValues; 90 | 91 | FlatHashMap _mPinPropName2Idx; 92 | Vector _vPinPropDataTypes; 93 | Vector> _vPinPropIntRanges; 94 | Vector> _vPinPropRealRanges; 95 | Vector _vPinPropNumberValues; 96 | 97 | FlatHashMap _mViaPropName2Idx; 98 | Vector _vViaPropDataTypes; 99 | Vector> _vViaPropIntRanges; 100 | Vector> _vViaPropRealRanges; 101 | Vector _vViaPropNumberValues; 102 | 103 | FlatHashMap _mViaRulePropName2Idx; 104 | Vector _vViaRulePropDataTypes; 105 | Vector> _vViaRulePropIntRanges; 106 | Vector> _vViaRulePropRealRanges; 107 | Vector _vViaRulePropNumberValues; 108 | 109 | Int toDBUnit(const Real val) const; 110 | Int toDBUnit2d(const Real val) const; 111 | Int _dbUnit; 112 | 113 | // LEF58 114 | enum class Lef58SpacingType1 { 115 | undef, 116 | EOLPERPENDICULAR, 117 | AREA, 118 | LAYER, 119 | NOTCHLENGTH, 120 | NOTCHSPAN, 121 | ENDOFLINE, 122 | CONVEXCORNERS 123 | }; 124 | enum class Lef58SpacingType2 { 125 | undef, 126 | TOCONCAVECORNER, 127 | TONOTCHLENGTH 128 | }; 129 | void parseLef58Area(MetalLayer& layer, const String& s); 130 | void parseLef58Spacing(MetalLayer& layer, const String& s); 131 | void parseLef58SpacingEol(MetalLayer& layer, const String& s); 132 | //void parseLef58SpacingTable(MetalLayer& layer, const String& s); 133 | //void parseLef58SpacingTablePrl(MetalLayer& layer, const String& s); 134 | void parseLef58EolKeepOut(MetalLayer& layer, const String& s); 135 | void parseLef58MinStep(MetalLayer& layer, const String& s); 136 | void parseLef58WidthTable(MetalLayer& layer, const String& s); 137 | }; 138 | 139 | PROJECT_NAMESPACE_END 140 | -------------------------------------------------------------------------------- /cpp/src/io/parser.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | 22 | #include "db/dbCir.hpp" 23 | #include "parHspice.hpp" 24 | #include "parLef.hpp" 25 | #include "parGds.hpp" 26 | 27 | PROJECT_NAMESPACE_START 28 | 29 | 30 | class Parser { 31 | public: 32 | Parser(CirDB& cir) : _cir(cir) {} 33 | 34 | void parse(const String& laygoConfig, 35 | const String& techGrid, 36 | const String& techMap, 37 | const String& constraint, 38 | const Vector& vLefs, 39 | const String& netlist, 40 | const String& layerRules); 41 | 42 | void parseLef(const Vector& vFileNames); 43 | void parsePlace(const String& fileName); 44 | void parseRouteGds(const String& fileName, const Vector& vNetIds = {}); 45 | 46 | private: 47 | CirDB& _cir; 48 | 49 | void parsePhysRes(const YAML::Node& cfg); 50 | 51 | void parseLayers(const YAML::Node& cfg, const YAML::Node& drc); 52 | void parseMetalLayerRules(const YAML::Node& drc, MetalLayer& layer); 53 | void parseCutLayerRules(const YAML::Node& drc, CutLayer& layer); 54 | 55 | Int parsePlacementGrid(const YAML::Node& data, const YAML::Node& grd); 56 | 57 | void parseRoutingGrids(const YAML::Node& data, const YAML::Node& grd, const bool isPower, Vector& vGridIds); 58 | void parseRoutingGrid(const YAML::Node& grd, const String& gridName, RouteGrid& rg); 59 | 60 | void parseDevPrimMap(const YAML::Node& map); 61 | 62 | // netlist 63 | void parseNetlist(const String& fileName); 64 | void parseCells(const HspiceReader& hsr, const HspiceReader::Node& topNode); 65 | void parseNets(const HspiceReader& hsr, const HspiceReader::Node& topNode); 66 | void parseNetListPost(); 67 | 68 | // constraint: design 69 | void parseCstrDesign(const String& name, const YAML::Node& data, const YAML::Node& grd); 70 | 71 | // constraint: placement - region 72 | void parseCstrRegion(const String& name, const YAML::Node& data, const YAML::Node& grd); 73 | void parseEdgePrims(const YAML::Node& data, Region& reg); 74 | void parseDummyPrims(const YAML::Node& data, Region& reg); 75 | 76 | // constraint: placement - symmetry 77 | void parseCstrPlaceSymmetry(const String& name, const YAML::Node& data); 78 | // constraint: placement - array 79 | void parseCstrPlaceArray(const String& name, const YAML::Node& data); 80 | // constraint: placement - cluster 81 | void parseCstrPlaceCluster(const String& name, const YAML::Node& data); 82 | // constraint: placement - preplace 83 | void parseCstrPlacePreplace(const String& name, const YAML::Node& data); 84 | // constraint: placement - (io)pin assignment 85 | void parseCstrPinAssignment(const String& name, const YAML::Node& data, const YAML::Node& grd); 86 | // constraint: placement - extension 87 | void parseCstrPlaceExtension(const String& name, const YAML::Node& data); 88 | // constraint: placement - edge dist 89 | void parseCstrPlaceEdgeDist(const String& name, const YAML::Node& data); 90 | // constraint: placement - order 91 | void parseCstrPlaceOrder(const String& name, const YAML::Node& data); 92 | // constraint: placement - align 93 | void parseCstrPlaceAlign(const String& name, const YAML::Node& data); 94 | // constraint: placement - disjoint 95 | void parseCstrPlaceDisjoint(const String& name, const YAML::Node& data); 96 | // constraint: placement - row 97 | void parseCstrPlaceRow(const String& name, const YAML::Node& data); 98 | 99 | // constraint: routing - net assignment 100 | void parseCstrNetAssignment(const String& name, const YAML::Node& data, const YAML::Node& grd); 101 | // constraint: routing - power 102 | void parseCstrPower(const String& name, const YAML::Node& data); 103 | // constraint: routing - matching 104 | void parseCstrRouteMatching(const String& name, const YAML::Node& data, const YAML::Node& grd); 105 | void parseCstrRoutePathMatching(const String& name, const YAML::Node& data, const YAML::Node& grd); 106 | // constraint: routing - priority 107 | void parseCstrNetPriority(const String& name, const YAML::Node& data); 108 | 109 | // helper 110 | Int toDBUnit(const Real val); 111 | Int toDBUnit2d(const Real val); 112 | 113 | //const FlatHashSet _sVddNames{"vdd", "vddl"}; 114 | //const FlatHashSet _sVssNames{"gnd"}; 115 | 116 | }; 117 | 118 | PROJECT_NAMESPACE_END 119 | -------------------------------------------------------------------------------- /cpp/src/place/placeMgr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCir.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class PlaceMgr { 25 | public: 26 | PlaceMgr(CirDB& cir) : _cir(cir) {} 27 | ~PlaceMgr() {} 28 | 29 | bool solveSMT(const Int numThreads, 30 | const Real ar = 1, 31 | const Real fcUtil = 0.7, 32 | const Vector& vRegNames = Vector(), 33 | const Vector& vFcRegUtils = Vector(), 34 | const Vector& vBounds = Vector(), 35 | const Int iter = 1); 36 | bool solveCP(const Int numThreads, const Real ar = 1); 37 | bool solveMILP(); 38 | 39 | void genEdgeCells(); 40 | void genFillCells(); 41 | 42 | void setSymCellOrients(); 43 | void setRowCellOrients(); 44 | 45 | private: 46 | CirDB& _cir; 47 | }; 48 | 49 | PROJECT_NAMESPACE_END 50 | -------------------------------------------------------------------------------- /cpp/src/rl/rlUtil.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "route/routeDrPS.hpp" 21 | #include "drc/drcMgr.hpp" 22 | #include "ds/array3d.hpp" 23 | 24 | 25 | PROJECT_NAMESPACE_START 26 | 27 | class RlUtils { 28 | public: 29 | RlUtils() {} 30 | ~RlUtils() {} 31 | 32 | void genFeatsEdgesMasks(const CirDB& cir, const Net& net, const DrPsRouter& ps, const DrcMgr& drcMgr, 33 | Vector>& feats, Vector>& edges, Vector& masks, 34 | const Real normConstWL, const Real normConstHis) const; 35 | 36 | void genPathFeatsEdges(const CirDB& cir, const Net& net, 37 | Vector>& pathFeats, Vector>& pathEdges, 38 | const Real normConstPathSegs, 39 | const Real normConstWL, const Real normConstVia, const Real normConstRes) const; 40 | 41 | void genFeatsEdgesMasksWithPathInfo(const CirDB& cir, const Net& net, const DrPsRouter& ps, const DrcMgr& drcMgr, 42 | Vector>& segFeats, Vector>& pathFeats, 43 | Vector>& seg2SegEdges, Vector>& path2SegEdges, 44 | Vector& segMasks, 45 | const Real normConstPathSegs, 46 | const Real normConstWL, const Real normConstVia, const Real normConstRes, 47 | const Real normConstHis) const; 48 | 49 | void genFeatsEdgesMasksWithSuperPathInfo(const CirDB& cir, const Net& net, const DrPsRouter& ps, const DrcMgr& drcMgr, 50 | Vector>& segFeats, Vector>& pathFeats, 51 | Vector>& seg2SegEdges, Vector>& path2SegEdges, 52 | Vector& segMasks, 53 | Vector>& superPathFeats, Vector>& path2SuperEdges, 54 | const Real normConstPathSegs, 55 | const Real normConstWL, const Real normConstVia, const Real normConstRes, 56 | const Real normConstHis) const; 57 | 58 | 59 | 60 | Pair getWlVia(const Net& net, const bool isScaled = false) const; 61 | Tuple getWlViaDrv(const CirDB& cir, const Net& net, const DrPsRouter& ps, const DrcMgr& drcMgr, const bool isScaled = false) const; 62 | void addCurSol2History(const Net& net, DrPsRouter& ps, const Int cost) const; 63 | Pair getMinWlVia(Net& net, DrPsRouter& ps, const bool isScaled = false) const; 64 | 65 | Pair getLayersWlVia(const CirDB& cir, const Net& net, const DrPsRouter& ps, const DrcMgr& drcMgr, 66 | Vector& vWls, Vector& vVias, const bool isScaled = false) const; 67 | Tuple getLayersWlViaDrv(const CirDB& cir, const Net& net, const DrPsRouter& ps, const DrcMgr& drcMgr, 68 | Vector& vWls, Vector& vVias, const bool isScaled = false) const; 69 | 70 | Vector getPathRes(const CirDB& cir, const Net& net) const; 71 | 72 | void getSurroundingImage(const CirDB& cir, const Net& net, const DrPsRouter& ps, 73 | const Int xSize, const Int ySize, 74 | const Int xStep, const Int yStep, 75 | const Real expandFc, Vector>>>& image) const; 76 | 77 | void toVisGds(const CirDB& cir, const Net& net, const String& fileName) const; 78 | void toVisGds(const CirDB& cir, const Vector& vNetIds, const String& fileName) const; 79 | 80 | 81 | void genSuperPathFeatsEdgesImpl(const CirDB& cir, const Net& net, 82 | Vector>& superFeats, 83 | Vector>& path2SuperEdges) const; 84 | 85 | private: 86 | void genPathFeatsEdgesImpl(const CirDB& cir, const Net& net, const Vector>& vSegs, 87 | Vector>& pathFeats, Vector>& pathEdges, 88 | const Real normConstPathSegs, 89 | const Real normConstWL, const Real normConstVia, const Real normConstRes) const; 90 | 91 | 92 | void genFeatsEdgesMasksImpl(const CirDB& cir, const Net& net, const Vector>& vSegs, 93 | const DrPsRouter& ps, const DrcMgr& drcMgr, 94 | Vector>& feats, Vector>& edges, Vector& masks, 95 | const Real normConstWL, const Real normConstHis) const; 96 | }; 97 | 98 | 99 | 100 | PROJECT_NAMESPACE_END 101 | -------------------------------------------------------------------------------- /cpp/src/route/routeDrPost.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #include "routeDrPost.hpp" 19 | #include "geo/box2polygon.hpp" 20 | #include "drc/drcMgr.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | void PostRoute::patch() 25 | { 26 | spdlog::info("[PostRoute] Patch wires"); 27 | Int i; 28 | Region* pReg; 29 | 30 | Cir_ForEachRegion(_cir, pReg, i) { 31 | patch(*pReg); 32 | } 33 | } 34 | 35 | void PostRoute::patch(Region& reg) 36 | { 37 | Int i; 38 | Net* pNet; 39 | 40 | Reg_ForEachNet(reg, pNet, i) { 41 | Vector>> vvBoxes(_cir.numLayers()); 42 | Vector>> vvPatches(_cir.numLayers()); 43 | initShapes(*pNet, vvBoxes); 44 | checkShapes(vvBoxes, vvPatches); 45 | addPatches2Nets(*pNet, vvPatches); 46 | } 47 | 48 | 49 | } 50 | 51 | void PostRoute::initShapes(const Net& net, Vector>>& vvBoxes) 52 | { 53 | 54 | Int i, j, layerIdx; 55 | const Pin* pPin; 56 | const Box* pBox; 57 | 58 | Net_ForEachPin(net, pPin, i) { 59 | Pin_ForEachLayerIdx((*pPin), layerIdx) { 60 | Pin_ForEachLayerBox((*pPin), layerIdx, pBox, j) { 61 | vvBoxes[layerIdx].emplace_back(*pBox); 62 | } 63 | } 64 | } 65 | for (const auto& wire : net.sWires()) { 66 | vvBoxes[wire.second].emplace_back(wire.first); 67 | } 68 | 69 | } 70 | 71 | void PostRoute::checkShapes(const Vector>>& vvBoxes, Vector>>& vvPatches) 72 | { 73 | 74 | DrcMgr drc(_cir); 75 | 76 | 77 | Vector>> vvPolygons(_cir.numLayers()); 78 | for (Int layerIdx = 0; layerIdx < _cir.numLayers(); ++layerIdx) { 79 | const Layer& layer = _cir.layer(layerIdx); 80 | auto& vBoxes = vvBoxes.at(layerIdx); 81 | auto& vPolygons = vvPolygons.at(layerIdx); 82 | if (vBoxes.size()) { 83 | geo::box2Polygon(vBoxes, vPolygons); 84 | //if (layerIdx <= _cir.layer("m5t").idx()) { // lower layers 85 | for (const Polygon& polygon : vPolygons) { 86 | const Ring& ring = polygon.outer(); 87 | assert(ring.size() == 4); // must be rectangular shape // ring[0] is lower right cornera // clockwise 88 | const Box b(ring[1].x(), ring[1].y(), ring[3].x(), ring[3].y()); 89 | 90 | 91 | Box extBox(b); 92 | if (layer.isMetal()) { 93 | const MetalLayer& metalLayer = *static_cast(_cir.pLayer(layerIdx)); 94 | if (metalLayer.isHor()) { 95 | if (!drc.checkWireMinArea(layerIdx, extBox)) { 96 | const Int minL = std::ceil(metalLayer.area() / extBox.height()); 97 | extBox.expandX((minL - extBox.width()) / 2); 98 | } 99 | if (!drc.checkWireMinStep(layerIdx, extBox)) { 100 | const Int minL = metalLayer.minStep(); 101 | extBox.expandX((minL - extBox.width()) / 2); 102 | } 103 | if (!drc.checkWireValidLength(layerIdx, extBox)) { 104 | const Int minL = metalLayer.length2ValidLength(extBox.width()); 105 | extBox.expandX((minL - extBox.width()) / 2); 106 | } 107 | if (extBox.xl() < b.xl()) { 108 | vvPatches[layerIdx].emplace_back(extBox.xl(), b.yl(), b.xl(), b.yh()); 109 | } 110 | if (extBox.xh() > b.xh()){ 111 | vvPatches[layerIdx].emplace_back(b.xh(), b.yl(), extBox.xh(), b.yh()); 112 | } 113 | } 114 | else { 115 | if (!drc.checkWireMinArea(layerIdx, extBox)) { 116 | const Int minL = std::ceil(metalLayer.area() / extBox.width()); 117 | extBox.expandY((minL - extBox.height()) / 2); 118 | } 119 | if (!drc.checkWireMinStep(layerIdx, extBox)) { 120 | const Int minL = metalLayer.minStep(); 121 | extBox.expandY((minL - extBox.height()) / 2); 122 | } 123 | if (!drc.checkWireValidLength(layerIdx, extBox)) { 124 | const Int minL = metalLayer.length2ValidLength(extBox.height()); 125 | extBox.expandY((minL - extBox.height()) / 2); 126 | } 127 | if (extBox.yl() < b.yl()) { 128 | vvPatches[layerIdx].emplace_back(b.xl(), extBox.yl(), b.xh(), b.yl()); 129 | } 130 | if (extBox.yh() > b.yh()){ 131 | vvPatches[layerIdx].emplace_back(b.xl(), b.yh(), b.xh(), extBox.yh()); 132 | } 133 | 134 | } 135 | 136 | } 137 | } 138 | //} 139 | //else { // upper layers 140 | 141 | //} 142 | } 143 | } 144 | 145 | } 146 | 147 | void PostRoute::addPatches2Nets(Net& net, const Vector>>& vvPatches) 148 | { 149 | for (size_t layerIdx = 0; layerIdx < vvPatches.size(); ++layerIdx) { 150 | for (const auto& box : vvPatches.at(layerIdx)) { 151 | //std::cerr << box << " " << layerIdx << std::endl; 152 | net.sPatchWires().emplace(box, layerIdx); 153 | } 154 | } 155 | 156 | } 157 | 158 | PROJECT_NAMESPACE_END 159 | -------------------------------------------------------------------------------- /cpp/src/route/routeDrPost.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCir.hpp" 21 | 22 | PROJECT_NAMESPACE_START 23 | 24 | class PostRoute { 25 | public: 26 | PostRoute(CirDB& cir) 27 | : _cir(cir) 28 | {} 29 | ~PostRoute() {} 30 | 31 | void patch(); 32 | void patch(Region& reg); 33 | 34 | private: 35 | CirDB& _cir; 36 | 37 | 38 | void initShapes(const Net& net, Vector>>& vvBoxes); 39 | void checkShapes(const Vector>>& vvBoxes, Vector>>& vvPatches); 40 | void addPatches2Nets(Net& net, const Vector>>& vvPatches); 41 | }; 42 | 43 | PROJECT_NAMESPACE_END 44 | -------------------------------------------------------------------------------- /cpp/src/route/routeMgr.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "db/dbCir.hpp" 21 | #include "routeDrMgr.hpp" 22 | #include "drc/drcMgr.hpp" 23 | 24 | PROJECT_NAMESPACE_START 25 | 26 | class RouteMgr { 27 | public: 28 | RouteMgr(CirDB& cir) 29 | : _cir(cir), _drc(cir) 30 | { 31 | 32 | } 33 | ~RouteMgr() {} 34 | 35 | //////////////////////////////////// 36 | // PG // 37 | //////////////////////////////////// 38 | void genPg(); 39 | void genPgGrid(const Region& reg, const RouteGrid& rg, Net& net); 40 | void connectPgGrid(const Region& reg, Net& net); 41 | 42 | //////////////////////////////////// 43 | // GR // 44 | //////////////////////////////////// 45 | 46 | //////////////////////////////////// 47 | // DR // 48 | //////////////////////////////////// 49 | 50 | private: 51 | CirDB& _cir; 52 | DrcMgr _drc; 53 | }; 54 | 55 | PROJECT_NAMESPACE_END 56 | -------------------------------------------------------------------------------- /cpp/src/thirdparty/spdlog.cpp: -------------------------------------------------------------------------------- 1 | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. 2 | // Distributed under the MIT License (http://opensource.org/licenses/MIT) 3 | 4 | #ifndef SPDLOG_COMPILED_LIB 5 | #error Please define SPDLOG_COMPILED_LIB to compile this file. 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | // template instantiate logger constructor with sinks init list 24 | template SPDLOG_API spdlog::logger::logger(std::string name, sinks_init_list::iterator begin, sinks_init_list::iterator end); 25 | template class SPDLOG_API spdlog::sinks::base_sink; 26 | template class SPDLOG_API spdlog::sinks::base_sink; -------------------------------------------------------------------------------- /cpp/src/util/util.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #include "util.hpp" 18 | #include 19 | 20 | PROJECT_NAMESPACE_START 21 | 22 | namespace util::fs { 23 | 24 | bool existFile(const String& fileName) 25 | { 26 | struct stat buf; 27 | return stat(fileName.c_str(), &buf) == 0; 28 | } 29 | 30 | String getDirName(const String& fileName) 31 | { 32 | String retStr = fileName; 33 | String::size_type pos = retStr.rfind("/"); 34 | if (pos != String::npos) 35 | retStr = retStr.substr(0, pos); 36 | return retStr; 37 | } 38 | 39 | String getFileName(const String& fileName) 40 | { 41 | String retStr = fileName; 42 | String::size_type pos = retStr.rfind("/"); 43 | if (pos != String::npos) 44 | retStr = retStr.substr(pos + 1); 45 | return retStr; 46 | } 47 | 48 | } // namespace util::fs 49 | 50 | namespace util::str { 51 | 52 | void split(const String& str, const String& delims, Vector& tokens) 53 | { 54 | tokens.clear(); 55 | String s(str), token; 56 | s.erase(std::remove(s.begin(), s.end(), '\n'), s.end()); 57 | size_t cur, prev = 0; 58 | cur = s.find_first_of(delims); 59 | while (cur != String::npos) { 60 | token = s.substr(prev, cur - prev); 61 | if (token != "") { 62 | tokens.emplace_back(token); 63 | } 64 | prev = cur + 1; 65 | cur = s.find_first_of(delims, prev); 66 | } 67 | token = s.substr(prev, cur - prev); 68 | if (token != "") { 69 | tokens.emplace_back(token); 70 | } 71 | } 72 | 73 | } // namespace util::str 74 | 75 | PROJECT_NAMESPACE_END 76 | -------------------------------------------------------------------------------- /cpp/src/util/util.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 | * SPDX-License-Identifier: Apache-2.0 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "global/global.hpp" 21 | #include 22 | 23 | PROJECT_NAMESPACE_START 24 | 25 | namespace util { 26 | 27 | namespace fs { 28 | 29 | extern bool existFile(const String& fileName); 30 | extern String getDirName(const String& fileName); 31 | extern String getFileName(const String& fileName); 32 | } // namespace fs 33 | 34 | namespace str { 35 | extern void split(const String& s, const String& delims, Vector& tokens); 36 | } 37 | 38 | namespace enumUtil { 39 | 40 | template constexpr auto getVal(E e) { 41 | return static_cast::type>(e); 42 | } 43 | 44 | template struct StrValPair { 45 | static_assert(std::is_enum::value); 46 | using value_type = T; 47 | const T value; 48 | const char* const str; 49 | }; 50 | 51 | // Templated helper functions. 52 | // Mapping is some type of standard container that supports find_if() 53 | // V is the type of the enum whose value we wish to look up 54 | template String val2Str(Mapping a, V value) { 55 | auto pos = std::find_if( 56 | std::begin(a), std::end(a), 57 | [&value](const typename Mapping::value_type& t) { return (t.value == value); }); 58 | if (pos != std::end(a)) { 59 | return pos->str; 60 | } 61 | return ""; 62 | } 63 | 64 | template 65 | typename Mapping::value_type::value_type str2Val(Mapping a, const String& str) { 66 | static_assert(std::is_enum::value); 67 | auto pos = std::find_if( 68 | std::begin(a), std::end(a), 69 | [&str](const typename Mapping::value_type& t) { return (t.str == str); }); 70 | if (pos != std::end(a)) { 71 | return pos->value; 72 | } 73 | typename Mapping::value_type::value_type val{}; 74 | return val; 75 | } 76 | 77 | } // namespace enumUtil 78 | 79 | } // namespace util 80 | 81 | PROJECT_NAMESPACE_END 82 | -------------------------------------------------------------------------------- /python/main/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVlabs/AutoCRAFT/9086ce22203426b94b1ea7bbab26d4e0d0f0d2f5/python/main/__init__.py -------------------------------------------------------------------------------- /python/main/rl_route_path_match_flat_group.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import numpy as np 17 | import torch as th 18 | import pickle 19 | import ujson 20 | 21 | import ray 22 | from ray.rllib.agents import dqn, ppo, impala 23 | from ray.tune.registry import register_env 24 | from ray.rllib.env.env_context import EnvContext 25 | from ray.rllib.models import ModelCatalog 26 | from ray.rllib.agents.callbacks import DefaultCallbacks 27 | 28 | import autocraft as ac 29 | from autocraft_rl.envs.ac_multicir_env_path_match_group import AcRouteMultiCirPathMatchGroupEnv 30 | from autocraft_rl.utils.helper import * 31 | 32 | import ast 33 | from pprint import pprint 34 | 35 | 36 | def rl_route_path_match_group(bench, 37 | cir: ac.cir_db, 38 | path_match_cstr, 39 | dr_mgr: ac.route_dr_mgr, 40 | dr_ps: ac.route_dr_ps, 41 | drc_mgr: ac.drc_mgr, 42 | agent, 43 | config): 44 | 45 | env = AcRouteMultiCirPathMatchGroupEnv(config['env_config'], 46 | options={ 47 | 'cir': cir, 48 | 'dr_mgr': dr_mgr, 49 | 'dr_ps': dr_ps, 50 | 'drc_mgr': drc_mgr, 51 | 'drc_cost': bench.route_dr_ps_drc_cost, 52 | 'his_cost': bench.route_dr_ps_his_cost, 53 | }) 54 | 55 | obs = env.reset(options={ 56 | 'cir': cir, 57 | 'path_match_cstr': path_match_cstr, 58 | 'reroute': False, 59 | }) 60 | done = False 61 | 62 | rew_tot = 0 63 | 64 | while not done: 65 | action = agent.compute_action(obs) 66 | obs, rew, done, _ = env.step(action) 67 | rew_tot += rew 68 | print(f'step: {env.steps}, rew: {rew:.4f}') 69 | 70 | print(f'Total rew: {rew_tot:.4f}') 71 | 72 | -------------------------------------------------------------------------------- /python/main/rl_route_path_match_hier.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import numpy as np 17 | import torch as th 18 | import pickle 19 | import ujson 20 | 21 | import ray 22 | from ray.rllib.agents import dqn, ppo, impala 23 | from ray.tune.registry import register_env 24 | from ray.rllib.env.env_context import EnvContext 25 | from ray.rllib.models import ModelCatalog 26 | from ray.rllib.agents.callbacks import DefaultCallbacks 27 | 28 | import autocraft as ac 29 | from autocraft_rl.envs.ac_multicir_env import * 30 | from autocraft_rl.envs.ac_multicir_env_match import * 31 | from autocraft_rl.envs.ac_multicir_env_layer_match import * 32 | from autocraft_rl.envs.ac_multicir_env_path_match import * 33 | from autocraft_rl.envs.ac_multicir_hier_env_path_match import * 34 | 35 | from autocraft_rl.utils.helper import * 36 | 37 | import ast 38 | from pprint import pprint 39 | 40 | 41 | def compute_action(agent, policy_mapping_fn, obs, done): 42 | action = {} 43 | for agent_id, agent_obs in obs.items(): 44 | if agent_id not in done and not done['__all__']: 45 | policy_id = policy_mapping_fn(agent_id, None, None) 46 | action[policy_id] = agent.compute_action(agent_obs, policy_id=policy_id) 47 | return action 48 | 49 | def rl_route_path_match_hier(bench, 50 | cir: ac.cir_db, 51 | match_group: list, 52 | dr_mgr: ac.route_dr_mgr, 53 | dr_ps: ac.route_dr_ps, 54 | drc_mgr: ac.drc_mgr, 55 | agent, 56 | config): 57 | 58 | # initialization 59 | # rl_route = RLRoutePathMatchHier(bench, cir, match_group, dr_mgr, dr_ps, drc_mgr, agent, config) 60 | env = AcRouteMultiCirHierPathMatchEnv(config['env_config'], 61 | options={ 62 | 'cir': cir, 63 | 'route_dr_mgr': dr_mgr, 64 | 'route_dr_ps': dr_ps, 65 | 'drc_mgr': drc_mgr, 66 | 'route_dr_ps_drc_cost': bench.route_dr_ps_drc_cost, 67 | 'route_dr_ps_his_cost': bench.route_dr_ps_his_cost, 68 | }) 69 | 70 | obs = env.reset(options={ 71 | 'cir': cir, 72 | 'match_group': match_group, 73 | 'reroute': False, 74 | }) 75 | done = {'__all__': False} 76 | 77 | rew_tot = 0 78 | 79 | # ac_rl = ac.rl_utils() 80 | # ac_rl.to_vis_gds(cir, ac.VectorInt([cir.net(n).idx() for n in match_group]), 'test_before.gds') 81 | 82 | policy_mapping_fn = config['multiagent']['policy_mapping_fn'] 83 | 84 | while True: 85 | action = compute_action(agent, policy_mapping_fn, obs, done) 86 | if 'top_level_policy' in action and env.top_level_steps == 0: 87 | action = {'top_level_policy': 0} 88 | obs, rew, done, _ = env.step(action) 89 | print('top: {}, mid: {}, low: {}'.format(env.top_level_steps, 90 | env.mid_level_steps, 91 | env.flat_env.steps), rew) 92 | if 'top_level_agent' in rew: 93 | rew_tot += list(rew.values())[0] 94 | 95 | if done['__all__'] == True: 96 | break 97 | 98 | print('Total rew: {:.4f}'.format(rew_tot)) 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /python/rl/autocraft-rl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVlabs/AutoCRAFT/9086ce22203426b94b1ea7bbab26d4e0d0f0d2f5/python/rl/autocraft-rl/__init__.py -------------------------------------------------------------------------------- /python/rl/autocraft-rl/autocraft_rl/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVlabs/AutoCRAFT/9086ce22203426b94b1ea7bbab26d4e0d0f0d2f5/python/rl/autocraft-rl/autocraft_rl/__init__.py -------------------------------------------------------------------------------- /python/rl/autocraft-rl/autocraft_rl/envs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVlabs/AutoCRAFT/9086ce22203426b94b1ea7bbab26d4e0d0f0d2f5/python/rl/autocraft-rl/autocraft_rl/envs/__init__.py -------------------------------------------------------------------------------- /python/rl/autocraft-rl/autocraft_rl/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVlabs/AutoCRAFT/9086ce22203426b94b1ea7bbab26d4e0d0f0d2f5/python/rl/autocraft-rl/autocraft_rl/models/__init__.py -------------------------------------------------------------------------------- /python/rl/autocraft-rl/autocraft_rl/models/ac_ppo_model.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import gym 17 | from typing import Dict, List 18 | 19 | import numpy as np 20 | 21 | import torch as th 22 | 23 | from ray.tune.logger import pretty_print 24 | from ray.rllib.models.torch.torch_modelv2 import TorchModelV2 25 | from ray.rllib.utils.annotations import override 26 | from ray.rllib.utils.typing import ModelConfigDict, TensorType 27 | 28 | import dgl 29 | from dgl.nn import SAGEConv, GATConv 30 | 31 | 32 | class AcRoutePPOModel(TorchModelV2, th.nn.Module): 33 | def __init__(self, 34 | obs_space: gym.spaces.Space, 35 | action_space: gym.spaces.Space, 36 | num_outputs: int, 37 | model_config: ModelConfigDict, 38 | name: str, 39 | **customized_model_kwargs): 40 | 41 | TorchModelV2.__init__(self, obs_space, action_space, num_outputs, model_config, name) 42 | th.nn.Module.__init__(self) 43 | 44 | # print(pretty_print(customized_model_kwargs)) 45 | 46 | self.max_segs = model_config['custom_model_config']['max_segs'] 47 | self.input_dim = model_config['custom_model_config']['seg_feat_dim'] 48 | self.gnn_feat_dim = model_config['custom_model_config']['seg_to_seg_gnn_feat_dim'] 49 | self.q_module_hiddens = model_config['custom_model_config']['advantage_module_hiddens'] 50 | self.value_module_hiddens = model_config['custom_model_config']['value_module_hiddens'] 51 | self.gnn_sage_aggregator = model_config['custom_model_config']['seg_to_seg_gnn_sage_aggregator'] 52 | 53 | # custom embedding module 54 | assert len(self.gnn_feat_dim) > 0 55 | self.embed_gnn_module = dgl.nn.Sequential() 56 | in_feats = self.input_dim 57 | for i, n in enumerate(self.gnn_feat_dim): 58 | self.embed_gnn_module.add_module('sage_{}'.format(i), SAGEConv(in_feats=in_feats, out_feats=n, aggregator_type=self.gnn_sage_aggregator, activation=th.nn.ReLU())) 59 | in_feats = n 60 | 61 | 62 | embed_dim = in_feats 63 | 64 | # model to action 65 | self.q_module = th.nn.Sequential() 66 | in_feats = embed_dim * 2 67 | for i, n in enumerate(self.q_module_hiddens): 68 | self.q_module.add_module('fc_{}'.format(i), th.nn.Linear(in_features=in_feats, out_features=n)) 69 | self.q_module.add_module('relu_{}'.format(i), th.nn.ReLU()) 70 | in_feats = n 71 | self.q_module.add_module('fc_final', th.nn.Linear(in_features=in_feats, out_features=1)) 72 | 73 | # value 74 | self.value_module = th.nn.Sequential() 75 | in_feats = embed_dim 76 | for i, n in enumerate(self.value_module_hiddens): 77 | self.value_module.add_module('fc_{}'.format(i), th.nn.Linear(in_features=in_feats, out_features=n)) 78 | self.value_module.add_module('relu_{}'.format(i), th.nn.ReLU()) 79 | in_feats = n 80 | self.value_module.add_module('fc_final', th.nn.Linear(in_features=in_feats, out_features=1)) 81 | 82 | 83 | self._last_batch_size = None 84 | self._max_batch_size = model_config['custom_model_config']['batch_size'] 85 | 86 | self.max_edges = 12 * self.max_segs 87 | 88 | self.edges_shift_mask = th.zeros(self._max_batch_size * self.max_edges, dtype=th.int32) 89 | for i in range(self._max_batch_size): 90 | self.edges_shift_mask[i * self.max_edges : (i + 1) * self.max_edges] = th.full((1, self.max_edges), i * self.max_segs) 91 | 92 | # to train or not 93 | # if 'fixed_weights' in model_config['custom_model_config'] and model_config['custom_model_config']['fixed_weights']: 94 | # for _, param in self._parameters.items(): 95 | # param.requires_grad = False 96 | 97 | 98 | @override(TorchModelV2) 99 | def forward(self, 100 | input_dict: Dict[str, TensorType], 101 | state: List[TensorType], 102 | seq_lens: TensorType): 103 | 104 | obs = input_dict['obs'] 105 | # obs = input_dict['obs_flat'].float() 106 | # new_obs = restore_original_dimensions(obs, self.obs_space, 'torch') 107 | # print(new_obs) 108 | 109 | action_mask = obs['action_mask'] 110 | feats = obs['feats'] 111 | edges = obs['edges'] 112 | valid_nodes = obs['valid_nodes'] 113 | valid_edges = obs['valid_edges'] 114 | 115 | self._last_batch_size = feats.shape[0] 116 | 117 | device = feats.device 118 | 119 | edges = th.as_tensor(edges, dtype=th.int32) 120 | edges = th.flatten(edges, start_dim=0, end_dim=1) 121 | edges = th.transpose(edges, 0, 1) 122 | 123 | edges_shift_mask = self.edges_shift_mask[:edges.shape[1]].to(device) 124 | 125 | edges = th.add(edges, edges_shift_mask) 126 | 127 | valid_edges = th.as_tensor(valid_edges, dtype=bool) 128 | valid_edges = th.flatten(valid_edges) 129 | 130 | edges = edges[:, valid_edges] 131 | 132 | 133 | bg = dgl.graph((edges[0], edges[1]), num_nodes=self._last_batch_size * feats.shape[1]) 134 | 135 | feats = th.flatten(feats, start_dim=0, end_dim=1) 136 | bg.ndata['feat'] = feats 137 | 138 | 139 | h = self.embed_gnn_module(bg, bg.ndata['feat']) 140 | # if self.embed_fc_module is not None: 141 | # h = self.embed_fc_module(h) 142 | 143 | h = h.view(self._last_batch_size, self.max_segs, -1) 144 | 145 | valid_nodes = th.as_tensor(valid_nodes, dtype=bool) 146 | vn = th.zeros(h.shape, dtype=bool).to(device) 147 | vn[valid_nodes] = True 148 | avg = (th.sum(h * vn.float(), dim=1) / th.sum(vn, dim=1)) 149 | avg[avg != avg] = 0 # nan -> 0 150 | avg = avg.view(avg.shape[0], 1, -1) 151 | 152 | h = th.cat((h, avg), dim=1) 153 | avg_repeat = avg.repeat(1, h.shape[1], 1) 154 | h = th.cat((h, avg_repeat), dim=-1) 155 | 156 | h = self.q_module(h) 157 | h = th.squeeze(h, -1) 158 | 159 | action_mask = (action_mask == 1) 160 | assert action_mask.shape == h.shape 161 | 162 | h[action_mask] = float('-inf') 163 | 164 | y = th.squeeze(avg, 1) 165 | self._value_out = th.flatten(self.value_module(y)) 166 | 167 | return h, state 168 | 169 | @override(TorchModelV2) 170 | def value_function(self) -> TensorType: 171 | return self._value_out 172 | -------------------------------------------------------------------------------- /python/rl/autocraft-rl/autocraft_rl/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVlabs/AutoCRAFT/9086ce22203426b94b1ea7bbab26d4e0d0f0d2f5/python/rl/autocraft-rl/autocraft_rl/utils/__init__.py -------------------------------------------------------------------------------- /python/rl/autocraft-rl/autocraft_rl/utils/callbacks.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from ray.rllib.evaluation import MultiAgentEpisode, RolloutWorker 17 | from ray.rllib.agents.callbacks import DefaultCallbacks 18 | from ray.rllib.env import BaseEnv 19 | from typing import Callable, Dict, List, Optional, Tuple, Type, Union 20 | from ray.rllib.policy import Policy 21 | from ray.rllib.policy.sample_batch import SampleBatch 22 | from ray.rllib.utils.typing import AgentID, PolicyID 23 | from ray.rllib.evaluation.episode import Episode 24 | 25 | import autocraft as ac 26 | from autocraft_rl.utils.helper import segs_to_str, str_to_segs 27 | 28 | import os 29 | import ujson 30 | # import yaml 31 | import pickle as pk 32 | 33 | 34 | class AcRouteCallbacks(DefaultCallbacks): 35 | # this callback add historgram of x,y positions of episodic state space 36 | def __init__(self, 37 | *args, 38 | **kwargs): 39 | super().__init__(*args, **kwargs) 40 | 41 | # self.logdir_gds = './gds/' 42 | # self.logdir_gds_start = './gds/episode_start' 43 | # self.logdir_gds_end = './gds/episode_end' 44 | # self.logdir_topo = './topo/' 45 | # os.makedirs(self.logdir_gds, exist_ok=True) 46 | # os.makedirs(self.logdir_gds_start, exist_ok=True) 47 | # os.makedirs(self.logdir_gds_end, exist_ok=True) 48 | # os.makedirs(self.logdir_topo, exist_ok=True) 49 | os.makedirs('./topo_dict/', exist_ok=True) 50 | 51 | self.topo_dict = {} 52 | self.max_topo = 80000 53 | 54 | def on_episode_start(self, 55 | *, 56 | worker: RolloutWorker, 57 | base_env: BaseEnv, 58 | policies: Dict[str, Policy], 59 | episode: Episode, 60 | env_index: int, 61 | **kwargs): 62 | # reset 63 | env_list = base_env.get_sub_environments() 64 | env = env_list[env_index] 65 | 66 | cir = env.cir 67 | net = env.net 68 | 69 | (wl, via, drv) = env.ac_rl.get_wl_via_drv(cir, net, env.route_dr_ps, env.drc_mgr, False) 70 | path_res = env.ac_rl.get_path_res(cir, net) 71 | 72 | episode.user_data['wl_start'] = wl 73 | episode.user_data['via_start'] = via 74 | episode.user_data['drv_start'] = drv 75 | 76 | if env.cfg.collect_topo and drv == 0: 77 | segs = ac.VectorSegment3dInt() 78 | net.v_arcs(segs) 79 | num_segs = len(segs) 80 | segs = segs_to_str(sorted(segs)) 81 | 82 | if cir.name() not in self.topo_dict: 83 | self.topo_dict[cir.name()] = {} 84 | if net.name() not in self.topo_dict[cir.name()]: 85 | self.topo_dict[cir.name()][net.name()] = { 86 | # 'num_pins': net.num_pins() 87 | } 88 | if segs not in self.topo_dict[cir.name()][net.name()]: 89 | self.topo_dict[cir.name()][net.name()][segs] = { 90 | 'wl': wl, 91 | 'via': via, 92 | 'drv': drv, 93 | 'num_segs': num_segs, 94 | } 95 | 96 | def on_episode_step(self, 97 | *, 98 | worker: RolloutWorker, 99 | base_env: BaseEnv, 100 | policies: Dict[str, Policy], 101 | episode: Episode, 102 | env_index: int, 103 | **kwargs): 104 | 105 | env_list = base_env.get_sub_environments() 106 | env = env_list[env_index] 107 | 108 | if env.cfg.collect_topo: 109 | 110 | cir = env.cir 111 | net = env.net 112 | 113 | (wl, via, drv) = env.ac_rl.get_wl_via_drv(cir, net, env.route_dr_ps, env.drc_mgr, False) 114 | 115 | if drv == 0: 116 | segs = ac.VectorSegment3dInt() 117 | net.v_arcs(segs) 118 | num_segs = len(segs) 119 | segs = segs_to_str(sorted(segs)) 120 | 121 | if cir.name() not in self.topo_dict: 122 | self.topo_dict[cir.name()] = {} 123 | if net.name() not in self.topo_dict[cir.name()]: 124 | self.topo_dict[cir.name()][net.name()] = { 125 | # 'num_pins': net.num_pins() 126 | } 127 | if segs not in self.topo_dict[cir.name()][net.name()]: 128 | self.topo_dict[cir.name()][net.name()][segs] = { 129 | 'wl': wl, 130 | 'via': via, 131 | 'drv': drv, 132 | 'num_segs': num_segs, 133 | } 134 | 135 | 136 | def on_episode_end(self, 137 | worker: RolloutWorker, 138 | base_env: BaseEnv, 139 | policies: Dict[str, Policy], 140 | episode: Episode, 141 | env_index: int, 142 | **kwargs): 143 | env_list = base_env.get_sub_environments() 144 | env = env_list[env_index] 145 | 146 | cir = env.cir 147 | net = env.net 148 | 149 | (wl, via, drv) = env.ac_rl.get_wl_via_drv(cir, net, env.route_dr_ps, env.drc_mgr, False) 150 | 151 | episode.custom_metrics['wl_improvements'] = episode.user_data['wl_start'] - wl 152 | episode.custom_metrics['via_improvements'] = episode.user_data['via_start'] - via 153 | episode.custom_metrics['drv_improvements'] = episode.user_data['drv_start'] - drv 154 | 155 | if env.cfg.collect_topo: 156 | # print(yaml.dump(self.topo_dict, sort_keys=True, default_flow_style=False)) 157 | # with open('topo_dict.json', 'w', encoding='utf-8') as f: 158 | # json.dump(self.topo_dict, f, ensure_ascii=False, indent=4) 159 | 160 | # with open('./topo_dict/topo_dict_{}.pkl'.format(worker.worker_index), 'wb') as f: 161 | # pk.dump(self.topo_dict, f, protocol=pk.HIGHEST_PROTOCOL) 162 | 163 | with open('./topo_dict/topo_dict_{}.json'.format(worker.worker_index), 'w', encoding='utf-8') as f: 164 | ujson.dump(self.topo_dict, f, ensure_ascii=False, indent=4) 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /python/rl/autocraft-rl/autocraft_rl/utils/callbacks_path_match_group.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from ray.rllib.evaluation import MultiAgentEpisode, RolloutWorker 17 | from ray.rllib.agents.callbacks import DefaultCallbacks 18 | from ray.rllib.env import BaseEnv 19 | from typing import Callable, Dict, List, Optional, Tuple, Type, Union 20 | from ray.rllib.policy import Policy 21 | from ray.rllib.policy.sample_batch import SampleBatch 22 | from ray.rllib.utils.typing import AgentID, PolicyID 23 | from ray.rllib.evaluation.episode import Episode 24 | 25 | import autocraft as ac 26 | from autocraft_rl.utils.helper import segs_to_str, str_to_segs 27 | 28 | import os 29 | import pickle as pk 30 | # import ujson 31 | import orjson 32 | import numpy as np 33 | 34 | 35 | class AcRoutePathMatchGroupCallbacks(DefaultCallbacks): 36 | # this callback add historgram of x,y positions of episodic state space 37 | def __init__(self, 38 | *args, 39 | **kwargs): 40 | super().__init__(*args, **kwargs) 41 | 42 | 43 | def on_episode_start(self, 44 | *, 45 | worker: RolloutWorker, 46 | base_env: BaseEnv, 47 | policies: Dict[str, Policy], 48 | episode: Episode, 49 | env_index: int, 50 | **kwargs): 51 | # env_list = base_env.get_sub_environments() 52 | # env = env_list[env_index] 53 | 54 | # cir = env.cir 55 | # match_group = env.match_group 56 | 57 | # wls = [] 58 | # vias = [] 59 | # drvs = [] 60 | # pd = {} 61 | # for net in match_group: 62 | # path_data = env.ac_rl.get_path_res(cir, net) 63 | # wl, via, drv = env.ac_rl.get_wl_via_drv(cir, 64 | # net, 65 | # env.flat_env.route_dr_ps, 66 | # env.flat_env.drc_mgr, 67 | # False) 68 | # wls.append(wl) 69 | # vias.append(via) 70 | # drvs.append(drv) 71 | # for j in range(net.num_conns()): 72 | # cstr = net.conn_cstr_const(j) 73 | # if cstr.idx() not in pd: 74 | # pd[cstr.idx()] = [] 75 | # pd[cstr.idx()].append(path_data[j]) 76 | 77 | # ptp = np.array([np.ptp(x) for x in pd.values()]) 78 | # std = np.array([np.std(x) for x in pd.values()]) 79 | 80 | # wls = np.array(wls) 81 | # vias = np.array(vias) 82 | # drvs = np.array(drvs) 83 | 84 | # episode.user_data['ptp_start'] = ptp 85 | # episode.user_data['wl_start'] = wls 86 | # episode.user_data['via_start'] = vias 87 | # episode.user_data['drvs_start'] = drvs 88 | pass 89 | 90 | 91 | def on_episode_step(self, 92 | *, 93 | worker: RolloutWorker, 94 | base_env: BaseEnv, 95 | policies: Dict[str, Policy], 96 | episode: Episode, 97 | env_index: int, 98 | **kwargs): 99 | pass 100 | 101 | 102 | def on_episode_end(self, 103 | worker: RolloutWorker, 104 | base_env: BaseEnv, 105 | policies: Dict[str, Policy], 106 | episode: Episode, 107 | env_index: int, 108 | **kwargs): 109 | env_list = base_env.get_sub_environments() 110 | env = env_list[env_index] 111 | 112 | cir = env.cir 113 | match_group = env.match_group 114 | 115 | wls = [] 116 | vias = [] 117 | drvs = [] 118 | pd = {} 119 | for net in match_group: 120 | path_data = env.ac_rl.get_path_res(cir, net) 121 | wl, via, drv = env.ac_rl.get_wl_via_drv(cir, 122 | net, 123 | env.dr_ps, 124 | env.drc_mgr, 125 | False) 126 | wls.append(wl) 127 | vias.append(via) 128 | drvs.append(drv) 129 | for j in range(net.num_conns()): 130 | cstr = net.conn_cstr_const(j) 131 | if cstr.idx() not in pd: 132 | pd[cstr.idx()] = [] 133 | pd[cstr.idx()].append(path_data[j]) 134 | 135 | ptp = np.array([np.ptp(x) for x in pd.values()]) 136 | std = np.array([np.std(x) for x in pd.values()]) 137 | 138 | wls = np.array(wls) 139 | vias = np.array(vias) 140 | drvs = np.array(drvs) 141 | 142 | # paths 143 | max_ptp = ptp.max() 144 | min_ptp = ptp.min() 145 | avg_ptp = ptp.mean() 146 | episode.custom_metrics['max_ptp'] = max_ptp 147 | episode.custom_metrics['min_ptp'] = min_ptp 148 | episode.custom_metrics['avg_ptp'] = avg_ptp 149 | episode.hist_data['max_ptp'] = [max_ptp] 150 | episode.hist_data['min_ptp'] = [min_ptp] 151 | episode.hist_data['avg_ptp'] = [avg_ptp] 152 | 153 | 154 | # wl, via, drv 155 | avg_wl = wls.mean() 156 | avg_via = vias.mean() 157 | max_drv, min_drv, avg_drv = drvs.max(), drvs.min(), drvs.mean() 158 | 159 | episode.custom_metrics['avg_wl'] = avg_wl 160 | episode.custom_metrics['avg_via'] = avg_via 161 | episode.custom_metrics['max_drv'] = max_drv 162 | episode.custom_metrics['min_drv'] = min_drv 163 | episode.custom_metrics['avg_drv'] = avg_drv 164 | episode.hist_data['avg_wl'] = [avg_wl] 165 | episode.hist_data['avg_via'] = [avg_via] 166 | episode.hist_data['max_drv'] = [max_drv] 167 | episode.hist_data['min_drv'] = [min_drv] 168 | episode.hist_data['avg_drv'] = [avg_drv] 169 | 170 | 171 | -------------------------------------------------------------------------------- /python/rl/autocraft-rl/autocraft_rl/utils/callbacks_path_match_group_hier.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from ray.rllib.evaluation import MultiAgentEpisode, RolloutWorker 17 | from ray.rllib.agents.callbacks import DefaultCallbacks 18 | from ray.rllib.env import BaseEnv 19 | from typing import Callable, Dict, List, Optional, Tuple, Type, Union 20 | from ray.rllib.policy import Policy 21 | from ray.rllib.policy.sample_batch import SampleBatch 22 | from ray.rllib.utils.typing import AgentID, PolicyID 23 | from ray.rllib.evaluation.episode import Episode 24 | 25 | import autocraft as ac 26 | from autocraft_rl.utils.helper import segs_to_str, str_to_segs 27 | 28 | import os 29 | import pickle as pk 30 | # import ujson 31 | import orjson 32 | import numpy as np 33 | 34 | 35 | class AcRoutePathMatchGroupHierCallbacks(DefaultCallbacks): 36 | # this callback add historgram of x,y positions of episodic state space 37 | def __init__(self, 38 | *args, 39 | **kwargs): 40 | super().__init__(*args, **kwargs) 41 | 42 | 43 | def on_episode_start(self, 44 | *, 45 | worker: RolloutWorker, 46 | base_env: BaseEnv, 47 | policies: Dict[str, Policy], 48 | episode: Episode, 49 | env_index: int, 50 | **kwargs): 51 | pass 52 | 53 | 54 | def on_episode_step(self, 55 | *, 56 | worker: RolloutWorker, 57 | base_env: BaseEnv, 58 | policies: Dict[str, Policy], 59 | episode: Episode, 60 | env_index: int, 61 | **kwargs): 62 | pass 63 | 64 | 65 | def on_episode_end(self, 66 | worker: RolloutWorker, 67 | base_env: BaseEnv, 68 | policies: Dict[str, Policy], 69 | episode: Episode, 70 | env_index: int, 71 | **kwargs): 72 | env_list = base_env.get_sub_environments() 73 | env = env_list[env_index] 74 | 75 | cir = env.flat_env.cir 76 | match_group = env.match_group 77 | 78 | wls = [] 79 | vias = [] 80 | drvs = [] 81 | pd = {} 82 | for net in match_group: 83 | path_data = env.ac_rl.get_path_res(cir, net) 84 | wl, via, drv = env.ac_rl.get_wl_via_drv(cir, 85 | net, 86 | env.flat_env.route_dr_ps, 87 | env.flat_env.drc_mgr, 88 | False) 89 | wls.append(wl) 90 | vias.append(via) 91 | drvs.append(drv) 92 | for j in range(net.num_conns()): 93 | cstr = net.conn_cstr_const(j) 94 | if cstr.idx() not in pd: 95 | pd[cstr.idx()] = [] 96 | pd[cstr.idx()].append(path_data[j]) 97 | 98 | ptp = np.array([np.ptp(x) for x in pd.values()]) 99 | std = np.array([np.std(x) for x in pd.values()]) 100 | 101 | wls = np.array(wls) 102 | vias = np.array(vias) 103 | drvs = np.array(drvs) 104 | 105 | # paths 106 | max_ptp = ptp.max() 107 | min_ptp = ptp.min() 108 | avg_ptp = ptp.mean() 109 | episode.custom_metrics['max_ptp'] = max_ptp 110 | episode.custom_metrics['min_ptp'] = min_ptp 111 | episode.custom_metrics['avg_ptp'] = avg_ptp 112 | episode.hist_data['max_ptp'] = [max_ptp] 113 | episode.hist_data['min_ptp'] = [min_ptp] 114 | episode.hist_data['avg_ptp'] = [avg_ptp] 115 | 116 | # wl, via, drv 117 | avg_wl = wls.mean() 118 | avg_via = vias.mean() 119 | max_drv, min_drv, avg_drv = drvs.max(), drvs.min(), drvs.mean() 120 | 121 | episode.custom_metrics['avg_wl'] = avg_wl 122 | episode.custom_metrics['avg_via'] = avg_via 123 | episode.custom_metrics['max_drv'] = max_drv 124 | episode.custom_metrics['min_drv'] = min_drv 125 | episode.custom_metrics['avg_drv'] = avg_drv 126 | episode.hist_data['avg_wl'] = [avg_wl] 127 | episode.hist_data['avg_via'] = [avg_via] 128 | episode.hist_data['max_drv'] = [max_drv] 129 | episode.hist_data['min_drv'] = [min_drv] 130 | episode.hist_data['avg_drv'] = [avg_drv] 131 | 132 | # print('total steps:', env.env_steps) 133 | # print('total top-level steps:', env.env_top_level_steps) 134 | # print('total mid-level steps:', env.env_mid_level_steps) 135 | # print('total low-level steps:', env.env_low_level_steps) 136 | 137 | -------------------------------------------------------------------------------- /python/rl/autocraft-rl/autocraft_rl/utils/load_agent.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import numpy as np 17 | import torch as th 18 | import pickle 19 | import ujson 20 | 21 | import ray 22 | from ray.rllib.agents import dqn, ppo, impala 23 | from ray.tune.registry import register_env 24 | from ray.rllib.env.env_context import EnvContext 25 | from ray.rllib.models import ModelCatalog 26 | from ray.rllib.agents.callbacks import DefaultCallbacks 27 | 28 | import autocraft as ac 29 | from autocraft_rl.models.ac_dqn_model import AcRouteDQNModel 30 | from autocraft_rl.models.ac_dqn_model_match import AcRouteDQNMatchModel 31 | from autocraft_rl.models.ac_dqn_model_path import AcRouteDQNPathModel 32 | 33 | from autocraft_rl.models.ac_ppo_model import AcRoutePPOModel 34 | from autocraft_rl.models.ac_ppo_model_match import AcRoutePPOMatchModel 35 | from autocraft_rl.models.ac_ppo_model_path import AcRoutePPOPathModel 36 | from autocraft_rl.models.ac_ppo_hier_model_path import AcRoutePPOPathTopLevelModel, AcRoutePPOPathMidLevelModel 37 | 38 | from autocraft_rl.envs.ac_multicir_env import AcRouteMultiCirFakeEnv 39 | from autocraft_rl.envs.ac_multicir_env_match import AcRouteMultiCirMatchFakeEnv 40 | from autocraft_rl.envs.ac_multicir_env_layer_match import AcRouteMultiCirLayerMatchFakeEnv 41 | from autocraft_rl.envs.ac_multicir_env_path_match import AcRouteMultiCirPathMatchFakeEnv 42 | from autocraft_rl.envs.ac_multicir_hier_env_path_match import AcRouteMultiCirHierPathMatchFakeEnv 43 | 44 | def load_trained_agent(config_path, 45 | checkpoint_path): 46 | 47 | with open(config_path, 'rb') as f: 48 | config = pickle.load(f) 49 | config['num_workers'] = 0 50 | config['num_gpus'] = 0 51 | config['evaluation_num_workers'] = 0 52 | 53 | 54 | cfg = config['env_config']['cfg'] 55 | 56 | # register model 57 | models = { 58 | 'ac_route_dqn_model': AcRouteDQNModel, 59 | 'ac_route_dqn_model_match': AcRouteDQNMatchModel, 60 | 'ac_route_dqn_model_path': AcRouteDQNPathModel, 61 | 'ac_route_ppo_model': AcRoutePPOModel, 62 | 'ac_route_ppo_model_match': AcRoutePPOMatchModel, 63 | 'ac_route_ppo_model_path': AcRoutePPOPathModel, 64 | 'ac_route_ppo_top_level_model_path': AcRoutePPOPathTopLevelModel, 65 | 'ac_route_ppo_mid_level_model_path': AcRoutePPOPathMidLevelModel, 66 | } 67 | for m_name, m in models.items(): 68 | ModelCatalog.register_custom_model(m_name, m) 69 | 70 | # register env 71 | envs = { 72 | 'ac_route_rl_multicir_env_path_match': AcRouteMultiCirPathMatchFakeEnv, 73 | 'ac_route_rl_multicir_hier_env_path_match': AcRouteMultiCirHierPathMatchFakeEnv, 74 | } 75 | if config['env'] in envs: 76 | register_env(config['env'], lambda c: envs[config['env']](c)) 77 | else: 78 | assert False, 'No valid env specified!' 79 | 80 | trainers = { 81 | 'apex': (dqn.ApexTrainer, dqn.APEX_DEFAULT_CONFIG), 82 | 'ppo': (ppo.PPOTrainer, ppo.DEFAULT_CONFIG), 83 | 'impala': (impala.ImpalaTrainer, impala.DEFAULT_CONFIG), 84 | } 85 | if cfg['rl_policy'] in trainers: 86 | trainer = trainers[cfg['rl_policy']][0] 87 | else: 88 | assert False, 'No valid trainer specified!' 89 | 90 | config['callbacks'] = DefaultCallbacks 91 | config['log_level'] = "ERROR" 92 | agent = trainer(env=config['env'], config=config) 93 | agent.restore(checkpoint_path) 94 | 95 | return agent, config 96 | -------------------------------------------------------------------------------- /python/rl/autocraft-rl/setup.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | from setuptools import setup 17 | 18 | setup( 19 | name='autocraft_rl', 20 | version='1.0.0', 21 | author='Hao Chen', 22 | author_email='haochen@nvidia.com', 23 | install_requires=['gym', 'dgl'], 24 | packages=['autocraft_rl/envs', 'autocraft_rl/models', 'autocraft_rl/utils'] 25 | ) 26 | -------------------------------------------------------------------------------- /python/rl/conf/arch/magic_array_dff_0.yaml: -------------------------------------------------------------------------------- 1 | magic_array_dff_0: 2 | laygo_config: ${root_dir}/bench/laygo_config.yaml 3 | grid: ${root_dir}/bench/magic_array_dff/magic_array_dff.grid.yaml 4 | map: ${root_dir}/bench/magic_array_dff/magic_array_dff.map.yaml 5 | constraint: ${root_dir}/bench/magic_array_dff/magic_array_dff.0.yaml 6 | 7 | lef: 8 | - ${root_dir}/bench/magic_array_dff/magic_array_dff.template.lef 9 | - ${root_dir}/bench/magic_array_dff/magic_array_dff.via.lef 10 | 11 | drc: ${root_dir}/bench/magic_array_dff/layers.drc.yaml 12 | netlist: ${root_dir}/bench/magic_array_dff/magic_array_dff.0.cir 13 | in_place: ${root_dir}/out/magic_array_dff.place" 14 | #out_place: "" 15 | route_dr_ps_drc_cost: 12000 16 | route_dr_ps_his_cost: 600 17 | 18 | -------------------------------------------------------------------------------- /python/rl/util/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVlabs/AutoCRAFT/9086ce22203426b94b1ea7bbab26d4e0d0f0d2f5/python/rl/util/__init__.py -------------------------------------------------------------------------------- /python/rl/util/config.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import argparse 17 | import json 18 | import logging 19 | 20 | from util.util import create_dir, check_path_exists 21 | 22 | def args_setup(): 23 | parser = argparse.ArgumentParser() 24 | parser.add_argument('--mode', type=str, default='train') 25 | parser.add_argument('--out_dir', type=str, default='./out') 26 | parser.add_argument('--save_model', type=str, default='') 27 | parser.add_argument('--load_model', type=str, default='') 28 | parser.add_argument('--laygo_config', type=str, default='') 29 | parser.add_argument('--grid', type=str, default='') 30 | parser.add_argument('--map', type=str, default='') 31 | parser.add_argument('--constraint', type=str, default='') 32 | parser.add_argument('--lef', type=str, nargs='*', default='') 33 | parser.add_argument('--netlist', type=str, default='') 34 | parser.add_argument('--drc', type=str, default='') 35 | parser.add_argument('--embed_dim', type=int, default=128) 36 | parser.add_argument('--n_head', type=int, default=4) 37 | # placemnt 38 | parser.add_argument('--in_place', type=str, default='') 39 | parser.add_argument('--out_place', type=str, default='') 40 | parser.add_argument('--place_threads', type=int, default=1) 41 | parser.add_argument('--place_ar', type=int, default=1) 42 | parser.add_argument('--place_ur', type=float, default=0.4) 43 | parser.add_argument('--place_ur_reg_name', type=str, nargs='*', default=list()) 44 | parser.add_argument('--place_ur_reg_val', type=float, nargs='*', default=list()) 45 | parser.add_argument('--place_bbox', type=float, nargs='*', default=list()) 46 | parser.add_argument('--place_iter', type=int, default=1) 47 | # routing 48 | parser.add_argument('--route_dr_ps_threads', type=int, default=1) 49 | parser.add_argument('--route_use_io', type=bool, default=False) 50 | 51 | 52 | args = parser.parse_args() 53 | 54 | args.logging_level = logging.INFO 55 | 56 | create_dir(args.out_dir) 57 | 58 | json_path = args.out_dir + '/parameters.json' 59 | json.dump(vars(args), open(json_path, 'w'), indent=4) 60 | return args 61 | 62 | def logging_setup(args): 63 | if args.file_output == 0: 64 | logging.basicConfig( 65 | level=args.logging_level, format='%(levelname)-8s - %(message)s') 66 | else: 67 | logging.basicConfig( 68 | level=args.logging_level, 69 | format='%(levelname)-8s - %(message)s', 70 | filename=args.out_dir + '/progress.txt') 71 | logging.getLogger().addHandler(logging.StreamHandler()) 72 | 73 | 74 | -------------------------------------------------------------------------------- /python/rl/util/util.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import os 17 | import numpy as np 18 | import requests 19 | from tqdm import tqdm 20 | 21 | 22 | def check_path_exists(path): 23 | return os.path.exists(path) 24 | 25 | 26 | def create_dir(path): 27 | try: 28 | os.makedirs(path) 29 | except os.error: 30 | pass 31 | 32 | 33 | def download_file(url, destination): 34 | if check_path_exists(destination): 35 | return 36 | r = requests.get(url, stream=True) 37 | with open(destination, 'wb') as f: 38 | for chunk in r.iter_content(chunk_size=1024): 39 | if chunk: 40 | f.write(chunk) 41 | r.close() 42 | 43 | 44 | def download_file_from_google_drive(id, destination): 45 | if check_path_exists(destination): 46 | return 47 | 48 | def get_confirm_token(response): 49 | for key, value in response.cookies.items(): 50 | if key.startswith('download_warning'): 51 | return value 52 | return None 53 | 54 | def save_response_content(response, destination): 55 | CHUNK_SIZE = 32768 56 | 57 | with open(destination, "wb") as f: 58 | for chunk in tqdm(response.iter_content(CHUNK_SIZE)): 59 | if chunk: # filter out keep-alive new chunks 60 | f.write(chunk) 61 | 62 | URL = "https://docs.google.com/uc?export=download" 63 | 64 | session = requests.Session() 65 | 66 | response = session.get(URL, params={'id': id}, stream=True) 67 | token = get_confirm_token(response) 68 | 69 | if token: 70 | params = {'id': id, 'confirm': token} 71 | response = session.get(URL, params=params, stream=True) 72 | 73 | save_response_content(response, destination) 74 | --------------------------------------------------------------------------------