Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,23 @@ jobs:
- name: Build wheel
uses: ./.github/actions/build-wheel

- name: Compile and run path helper fixture
run: |
g++ -std=c++20 -Wall -Werror src/interface/python/test/py_path_utils_test.cc -o /tmp/py_path_utils_test
/tmp/py_path_utils_test

- name: Smoke test installed wheel
run: |
python -m venv /tmp/wheel-smoke
/tmp/wheel-smoke/bin/pip install dist/wheel/repaired/*.whl pytest
# Run from outside the checkout so `import ecc_tools_bin` resolves
# to the installed wheel, not the source-tree package.
cd /tmp && /tmp/wheel-smoke/bin/python -m pytest "$GITHUB_WORKSPACE/tests/test_pathlike_contract.py" -q

- name: Upload repaired wheel
uses: actions/upload-artifact@v4
with:
name: ecc-tools-wheel
path: dist/wheel/repaired/*.whl
if-no-files-found: error

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"

[project]
name = "ecc-tools-bin"
version = "0.1.0-alpha.7"
version = "0.1.0-alpha.8"
requires-python = ">=3.11"
dependencies = [
"numpy",
Expand Down
68 changes: 45 additions & 23 deletions src/interface/python/py_config/py_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,52 +16,74 @@
// ***************************************************************************************
#include "py_config.h"

#include "../py_path_utils.h"
#include <flow.h>
#include <idm.h>
#include <tool_manager.h>

namespace python_interface {

bool flow_init(const std::string& flow_config)
bool flow_init(const std::filesystem::path& flow_config)
{
bool init_ok = iplf::plfInst->initFlow(flow_config);
const std::string flow_config_ = flow_config.string();
bool init_ok = iplf::plfInst->initFlow(flow_config_);
return init_ok;
}

bool db_init(const std::string& config_path, const std::string& tech_lef_path, const std::vector<std::string>& lef_paths,
const std::string& def_path, const std::string& verilog_path, const std::string& output_path, const std::string& feature_path,
const std::vector<std::string>& lib_paths, const std::string& sdc_path)
bool db_init(const std::optional<std::filesystem::path>& config_path, const std::optional<std::filesystem::path>& tech_lef_path,
const std::vector<std::filesystem::path>& lef_paths, const std::optional<std::filesystem::path>& def_path,
const std::optional<std::filesystem::path>& verilog_path, const std::optional<std::filesystem::path>& output_path,
const std::optional<std::filesystem::path>& feature_path, const std::vector<std::filesystem::path>& lib_paths,
const std::optional<std::filesystem::path>& sdc_path)
{
const std::string config_path_ = path_or_empty(config_path);
const std::string tech_lef_path_ = path_or_empty(tech_lef_path);
std::vector<std::string> lef_paths_;
lef_paths_.reserve(lef_paths.size());
for (const auto& lef_path : lef_paths) {
lef_paths_.push_back(lef_path.string());
}
const std::string def_path_ = path_or_empty(def_path);
const std::string verilog_path_ = path_or_empty(verilog_path);
const std::string output_path_ = path_or_empty(output_path);
const std::string feature_path_ = path_or_empty(feature_path);
std::vector<std::string> lib_paths_;
lib_paths_.reserve(lib_paths.size());
for (const auto& lib_path : lib_paths) {
lib_paths_.push_back(lib_path.string());
}
const std::string sdc_path_ = path_or_empty(sdc_path);

idm::DataConfig& dm_config = dmInst->get_config();
if (not config_path.empty()) {
bool init_ok = dm_config.initConfig(config_path);
if (not config_path_.empty()) {
bool init_ok = dm_config.initConfig(config_path_);
if (not init_ok) {
return false;
}
}
if (not tech_lef_path.empty()) {
dm_config.set_tech_lef_path(tech_lef_path);
if (not tech_lef_path_.empty()) {
dm_config.set_tech_lef_path(tech_lef_path_);
}
if (not lef_paths.empty()) {
dm_config.set_lef_paths(lef_paths);
if (not lef_paths_.empty()) {
dm_config.set_lef_paths(lef_paths_);
}
if (not def_path.empty()) {
dm_config.set_def_path(def_path);
if (not def_path_.empty()) {
dm_config.set_def_path(def_path_);
}
if (not verilog_path.empty()) {
dm_config.set_verilog_path(verilog_path);
if (not verilog_path_.empty()) {
dm_config.set_verilog_path(verilog_path_);
}
if (not output_path.empty()) {
dm_config.set_output_path(output_path);
if (not output_path_.empty()) {
dm_config.set_output_path(output_path_);
}
if (not lib_paths.empty()) {
dm_config.set_lib_paths(lib_paths);
if (not lib_paths_.empty()) {
dm_config.set_lib_paths(lib_paths_);
}
if (not sdc_path.empty()) {
dm_config.set_sdc_path(sdc_path);
if (not sdc_path_.empty()) {
dm_config.set_sdc_path(sdc_path_);
}
if (not feature_path.empty()) {
dm_config.set_feature_path(feature_path);
if (not feature_path_.empty()) {
dm_config.set_feature_path(feature_path_);
}
return true;
}
Expand Down
12 changes: 8 additions & 4 deletions src/interface/python/py_config/py_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@
// ***************************************************************************************
#pragma once

#include <filesystem>
#include <optional>
#include <string>
#include <vector>

namespace python_interface {
bool flow_init(const std::string& flow_config);
bool flow_init(const std::filesystem::path& flow_config);

bool db_init(const std::string& config_path, const std::string& tech_lef_path, const std::vector<std::string>& lef_paths,
const std::string& def_path, const std::string& verilog_path, const std::string& output_path, const std::string& feature_path,
const std::vector<std::string>& lib_paths, const std::string& sdc_path);
bool db_init(const std::optional<std::filesystem::path>& config_path, const std::optional<std::filesystem::path>& tech_lef_path,
const std::vector<std::filesystem::path>& lef_paths, const std::optional<std::filesystem::path>& def_path,
const std::optional<std::filesystem::path>& verilog_path, const std::optional<std::filesystem::path>& output_path,
const std::optional<std::filesystem::path>& feature_path, const std::vector<std::filesystem::path>& lib_paths,
const std::optional<std::filesystem::path>& sdc_path);
} // namespace python_interface
19 changes: 10 additions & 9 deletions src/interface/python/py_config/py_register_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#pragma once
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl/filesystem.h>
#include "py_config.h"
namespace python_interface {
namespace py = pybind11;
Expand All @@ -25,15 +26,15 @@ void register_config(pybind11::module& m){
m.def("flow_init", flow_init, py::arg("flow_config"));

m.def("db_init", db_init,
py::arg("config_path") = "",
py::arg("tech_lef_path") = "",
py::arg("lef_paths") = std::vector<std::string> {},
py::arg("def_path") = "",
py::arg("verilog_path") = "",
py::arg("output_path") = "",
py::arg("feature_path") = "",
py::arg("lib_paths") = std::vector<std::string>{},
py::arg("sdc_path") = ""
py::arg("config_path") = py::none(),
py::arg("tech_lef_path") = py::none(),
py::arg("lef_paths") = std::vector<std::filesystem::path>{},
py::arg("def_path") = py::none(),
py::arg("verilog_path") = py::none(),
py::arg("output_path") = py::none(),
py::arg("feature_path") = py::none(),
py::arg("lib_paths") = std::vector<std::filesystem::path>{},
py::arg("sdc_path") = py::none()
);
}
} // namespace python_interface
15 changes: 10 additions & 5 deletions src/interface/python/py_eval/py_eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,24 +178,29 @@ void eval_macro_channel(float die_size_ratio)
{
}

void eval_cell_hierarchy(const std::string& plot_path, int level, int forward)
void eval_cell_hierarchy(const std::filesystem::path& plot_path, int level, int forward)
{
[[maybe_unused]] const std::string plot_path_ = plot_path.string();
}

void eval_macro_hierarchy(const std::string& plot_path, int level, int forward)
void eval_macro_hierarchy(const std::filesystem::path& plot_path, int level, int forward)
{
[[maybe_unused]] const std::string plot_path_ = plot_path.string();
}

void eval_macro_connection(const std::string& plot_path, int level, int forward)
void eval_macro_connection(const std::filesystem::path& plot_path, int level, int forward)
{
[[maybe_unused]] const std::string plot_path_ = plot_path.string();
}

void eval_macro_pin_connection(const std::string& plot_path, int level, int forward)
void eval_macro_pin_connection(const std::filesystem::path& plot_path, int level, int forward)
{
[[maybe_unused]] const std::string plot_path_ = plot_path.string();
}

void eval_macro_io_pin_connection(const std::string& plot_path, int level, int forward)
void eval_macro_io_pin_connection(const std::filesystem::path& plot_path, int level, int forward)
{
[[maybe_unused]] const std::string plot_path_ = plot_path.string();
}


Expand Down
11 changes: 6 additions & 5 deletions src/interface/python/py_eval/py_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// ***************************************************************************************
#pragma once

#include <filesystem>
#include <string>
#include <vector>

Expand Down Expand Up @@ -50,11 +51,11 @@ ieval::TimingSummary timing_power_egr();
void eval_macro_margin();
void eval_macro_channel(float die_size_ratio = 0.5);
void eval_continuous_white_space();
void eval_cell_hierarchy(const std::string& plot_path, int level = 1, int forward = 1);
void eval_macro_hierarchy(const std::string& plot_path, int level = 1, int forward = 1);
void eval_macro_connection(const std::string& plot_path, int level = 1, int forward = 1);
void eval_macro_pin_connection(const std::string& plot_path, int level = 1, int forward = 1);
void eval_macro_io_pin_connection(const std::string& plot_path, int level = 1, int forward = 1);
void eval_cell_hierarchy(const std::filesystem::path& plot_path, int level = 1, int forward = 1);
void eval_macro_hierarchy(const std::filesystem::path& plot_path, int level = 1, int forward = 1);
void eval_macro_connection(const std::filesystem::path& plot_path, int level = 1, int forward = 1);
void eval_macro_pin_connection(const std::filesystem::path& plot_path, int level = 1, int forward = 1);
void eval_macro_io_pin_connection(const std::filesystem::path& plot_path, int level = 1, int forward = 1);

std::vector<float> eval_overflow();

Expand Down
47 changes: 29 additions & 18 deletions src/interface/python/py_eval/py_register_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
#pragma once
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl/filesystem.h>

#include <filesystem>
#include <optional>

#include "../py_path_utils.h"
#include "py_eval.h"

namespace python_interface {
Expand Down Expand Up @@ -46,37 +51,43 @@ void register_eval(py::module& m)


// density evaluation functions
m.def("cell_density", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::string& save_path = "") -> py::tuple {
auto [max_density, avg_density] = cell_density(bin_cnt_x, bin_cnt_y, save_path);
m.def("cell_density", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::optional<std::filesystem::path>& save_path = std::nullopt) -> py::tuple {
const std::string save_path_ = path_or_empty(save_path);
auto [max_density, avg_density] = cell_density(bin_cnt_x, bin_cnt_y, save_path_);
return py::make_tuple(max_density, avg_density);
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = "");
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = py::none());

m.def("pin_density", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::string& save_path = "") -> py::tuple {
auto [max_density, avg_density] = pin_density(bin_cnt_x, bin_cnt_y, save_path);
m.def("pin_density", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::optional<std::filesystem::path>& save_path = std::nullopt) -> py::tuple {
const std::string save_path_ = path_or_empty(save_path);
auto [max_density, avg_density] = pin_density(bin_cnt_x, bin_cnt_y, save_path_);
return py::make_tuple(max_density, avg_density);
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = "");
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = py::none());

m.def("net_density", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::string& save_path = "") -> py::tuple {
auto [max_density, avg_density] = net_density(bin_cnt_x, bin_cnt_y, save_path);
m.def("net_density", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::optional<std::filesystem::path>& save_path = std::nullopt) -> py::tuple {
const std::string save_path_ = path_or_empty(save_path);
auto [max_density, avg_density] = net_density(bin_cnt_x, bin_cnt_y, save_path_);
return py::make_tuple(max_density, avg_density);
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = "");
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = py::none());


// congestion evalation
m.def("rudy_congestion", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::string& save_path = "") -> py::tuple {
auto [max_congestion, total_congestion] = rudy_congestion(bin_cnt_x, bin_cnt_y, save_path);
m.def("rudy_congestion", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::optional<std::filesystem::path>& save_path = std::nullopt) -> py::tuple {
const std::string save_path_ = path_or_empty(save_path);
auto [max_congestion, total_congestion] = rudy_congestion(bin_cnt_x, bin_cnt_y, save_path_);
return py::make_tuple(max_congestion, total_congestion);
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = "");
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = py::none());

m.def("lut_rudy_congestion", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::string& save_path = "") -> py::tuple {
auto [max_congestion, total_congestion] = lut_rudy_congestion(bin_cnt_x, bin_cnt_y, save_path);
m.def("lut_rudy_congestion", [](int bin_cnt_x = 256, int bin_cnt_y = 256, const std::optional<std::filesystem::path>& save_path = std::nullopt) -> py::tuple {
const std::string save_path_ = path_or_empty(save_path);
auto [max_congestion, total_congestion] = lut_rudy_congestion(bin_cnt_x, bin_cnt_y, save_path_);
return py::make_tuple(max_congestion, total_congestion);
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = "");
}, py::arg("bin_cnt_x") = 256, py::arg("bin_cnt_y") = 256, py::arg("save_path") = py::none());

m.def("egr_congestion", [](const std::string& save_path = "") -> py::tuple {
auto [max_congestion, total_congestion] = egr_congestion(save_path);
m.def("egr_congestion", [](const std::optional<std::filesystem::path>& save_path = std::nullopt) -> py::tuple {
const std::string save_path_ = path_or_empty(save_path);
auto [max_congestion, total_congestion] = egr_congestion(save_path_);
return py::make_tuple(max_congestion, total_congestion);
}, py::arg("save_path") = "");
}, py::arg("save_path") = py::none());


// timing and power evaluation
Expand Down
Loading