3 Commits

Author SHA1 Message Date
  Emin f70f1b5015 !63 build: remove mt-kahypar submodule and update gitignore 5 months ago
  HelloXiao fd68c43f5c !62 fix(cmake): replace iPW with iPA to resolve build errors 5 months ago
  HelloXiao 1559e7222c !59 feat(ipl) add JSON output option 5 months ago
20 changed files with 109 additions and 22 deletions
Split View
  1. +4
    -1
      .gitignore
  2. +0
    -4
      .gitmodules
  3. +4
    -0
      cmake/operation/ipa.cmake
  4. +0
    -4
      cmake/operation/ipw.cmake
  5. +1
    -0
      scripts/design/ihp130_gcd/iEDA_config/pl_default_config.json
  6. +1
    -0
      scripts/design/sky130_gcd/iEDA_config/pl_default_config.json
  7. +1
    -1
      src/database/manager/CMakeLists.txt
  8. +10
    -1
      src/interface/tcl/tcl_ipl/tcl_ipl.cpp
  9. +1
    -0
      src/interface/tcl/tcl_ipl/tcl_ipl.h
  10. +8
    -1
      src/operation/iPL/api/PLAPI.cc
  11. +5
    -0
      src/operation/iPL/api/PLAPI.hh
  12. +7
    -0
      src/operation/iPL/source/config/Configurator.cc
  13. +48
    -1
      src/operation/iPL/source/module/global_placer/electrostatic_placer/NesterovPlace.cc
  14. +7
    -2
      src/operation/iPL/source/module/global_placer/electrostatic_placer/NesterovPlace.hh
  15. +3
    -1
      src/operation/iPL/source/module/global_placer/electrostatic_placer/config/NesterovPlaceConfig.hh
  16. +5
    -1
      src/platform/tool_manager/tool_api/ipl_io/ipl_io.cpp
  17. +1
    -1
      src/platform/tool_manager/tool_api/ipl_io/ipl_io.h
  18. +2
    -2
      src/platform/tool_manager/tool_manager.cpp
  19. +1
    -1
      src/platform/tool_manager/tool_manager.h
  20. +0
    -1
      src/third_party/mt-kahypar

+ 4
- 1
.gitignore View File

@@ -30,4 +30,7 @@ scripts
CMakePresets.json
.venv/
__pycache__
mcp_iEDA.egg-info/
mcp_iEDA.egg-info/

# Prevent accidental re-addition of removed submodules
src/third_party/mt-kahypar/

+ 0
- 4
.gitmodules View File

@@ -1,7 +1,3 @@
# [submodule "src/third_party/mt-kahypar"]
# url = https://gitee.com/i-eda/mt-kahypar
# path = src/third_party/mt-kahypar

[submodule "src/third_party/LSAssigner4iEDA"]
path = src/third_party/LSAssigner4iEDA
url = https://gitee.com/li-jinyuan/LSAssigner4iEDA


+ 4
- 0
cmake/operation/ipa.cmake View File

@@ -0,0 +1,4 @@
include_directories(${HOME_OPERATION}/iPA)
include_directories(${HOME_OPERATION}/iPA/source)
include_directories(${HOME_OPERATION}/iPA/source/module)
include_directories(${HOME_OPERATION}/iPA/source/module/include)

+ 0
- 4
cmake/operation/ipw.cmake View File

@@ -1,4 +0,0 @@
include_directories(${HOME_OPERATION}/iPW)
include_directories(${HOME_OPERATION}/iPW/source)
include_directories(${HOME_OPERATION}/iPW/source/module)
include_directories(${HOME_OPERATION}/iPW/source/module/include)

+ 1
- 0
scripts/design/ihp130_gcd/iEDA_config/pl_default_config.json View File

@@ -6,6 +6,7 @@
"is_congestion_effort": 0,
"ignore_net_degree": 100,
"num_threads": 16,
"info_iter_num": 10,
"GP": {
"Wirelength": {
"init_wirelength_coef": 0.25,


+ 1
- 0
scripts/design/sky130_gcd/iEDA_config/pl_default_config.json View File

@@ -6,6 +6,7 @@
"is_congestion_effort": 0,
"ignore_net_degree": 100,
"num_threads": 1,
"info_iter_num": 10,
"GP": {
"Wirelength": {
"init_wirelength_coef": 0.25,


+ 1
- 1
src/database/manager/CMakeLists.txt View File

@@ -1,5 +1,5 @@
include(${HOME_CMAKE}/operation/ista.cmake)
include(${HOME_CMAKE}/operation/ipw.cmake)
include(${HOME_CMAKE}/operation/ipa.cmake)

add_subdirectory(builder)
add_subdirectory(memory)


+ 10
- 1
src/interface/tcl/tcl_ipl/tcl_ipl.cpp View File

@@ -31,6 +31,9 @@ CmdPlacerAutoRun::CmdPlacerAutoRun(const char* cmd_name) : TclCmd(cmd_name)
{
auto* file_name_option = new TclStringOption(TCL_CONFIG, 1, nullptr);
addOption(file_name_option);

auto *json_output_option = new TclSwitchOption("-json");
addOption(json_output_option);
}

unsigned CmdPlacerAutoRun::check()
@@ -49,7 +52,13 @@ unsigned CmdPlacerAutoRun::exec()
TclOption* option = getOptionOrArg(TCL_CONFIG);
auto data_config = option->getStringVal();

if (iplf::tmInst->autoRunPlacer(data_config)) {
bool enable_json_output = false;
TclOption* json_output_option = getOptionOrArg("-json");
if (json_output_option->is_set_val()) {
enable_json_output = true;
}

if (iplf::tmInst->autoRunPlacer(data_config, enable_json_output)) {
std::cout << "iPL run successfully." << std::endl;
}



+ 1
- 0
src/interface/tcl/tcl_ipl/tcl_ipl.h View File

@@ -32,6 +32,7 @@
using ieda::TclCmd;
using ieda::TclOption;
using ieda::TclStringOption;
using ieda::TclSwitchOption;

namespace tcl {



+ 8
- 1
src/operation/iPL/api/PLAPI.cc View File

@@ -164,6 +164,13 @@ void PLAPI::createPLDirectory()
LOG_ERROR << "Cannot create " + pl_dir + "/pl/gui for iPL gui";
}
}
if (!std::filesystem::exists(pl_dir + "/pl/density")) {
if (std::filesystem::create_directories(pl_dir + "/pl/density")) {
LOG_INFO << "Create folder " + pl_dir + "/pl/density for iPL density map";
} else {
LOG_ERROR << "Cannot create " + pl_dir + "/pl/density for iPL density map";
}
}
}

void PLAPI::runIncrementalFlow()
@@ -471,7 +478,7 @@ void PLAPI::runGP()
{
// CenterPlace(&PlacerDBInst).runCenterPlace();
RandomPlace(&PlacerDBInst).runRandomPlace();
NesterovPlace nesterov_place(PlacerDBInst.get_placer_config(), &PlacerDBInst);
NesterovPlace nesterov_place(PlacerDBInst.get_placer_config(), &PlacerDBInst, isJsonOutputEnabled());
nesterov_place.printNesterovDatabase();
nesterov_place.runNesterovPlace();
}


+ 5
- 0
src/operation/iPL/api/PLAPI.hh View File

@@ -120,6 +120,9 @@ class PLAPI
bool insertSignalBuffer(std::pair<std::string, std::string> source_sink_net, std::vector<std::string> sink_pin_list,
std::pair<std::string, std::string> master_inst_buffer, std::pair<int, int> buffer_center_loc);

void enableJsonOutput() { _enable_json_output = true; }
bool isJsonOutputEnabled() { return _enable_json_output; }

/*****************************Timing-driven Placement: START*****************************/
double obtainPinEarlySlack(std::string pin_name);
double obtainPinLateSlack(std::string pin_name);
@@ -156,6 +159,8 @@ class PLAPI
ExternalAPI* _external_api;
PLReporter* _reporter;

bool _enable_json_output = false;

PLAPI() = default;
PLAPI(const PLAPI&) = delete;
PLAPI(PLAPI&&) = delete;


+ 7
- 0
src/operation/iPL/source/config/Configurator.cc View File

@@ -61,6 +61,7 @@ void Config::initConfigByJson(nlohmann::json json)
int32_t is_congestion_effort = getDataByJson(json, {"PL", "is_congestion_effort"});
int32_t ignore_net_degree = getDataByJson(json, {"PL", "ignore_net_degree"});
int32_t num_threads = getDataByJson(json, {"PL", "num_threads"});
int32_t info_iter_num = getDataByJson(json, {"PL", "info_iter_num"});

// Global Placer
float init_wirelength_coef = getDataByJson(json, {"PL", "GP", "Wirelength", "init_wirelength_coef"});
@@ -182,6 +183,12 @@ void Config::initConfigByJson(nlohmann::json json)
_nes_config.set_is_opt_congestion(false);
}

if (info_iter_num < 0) {
_nes_config.set_info_iter_num(10);
} else {
_nes_config.set_info_iter_num(info_iter_num);
}

// Buffer
_buffer_config.set_thread_num(num_threads);
_buffer_config.set_is_max_length_opt(is_max_length_opt);


+ 48
- 1
src/operation/iPL/source/module/global_placer/electrostatic_placer/NesterovPlace.cc View File

@@ -41,6 +41,7 @@
#include "tool_manager.h"
#include "usage/usage.hh"
#include "PLAPI.hh"
#include "json/json.hpp"


#ifdef BUILD_QT
@@ -1479,7 +1480,7 @@ namespace ipl {
_nes_database->_density_penalty *= phi_coef;

// print info.
if (iter_num == 1 || iter_num % 10 == 0) {
if (iter_num == 1 || iter_num % _nes_config.get_info_iter_num() == 0) {
LOG_INFO << "[NesterovSolve] Iter: " << iter_num << " overflow: " << sum_overflow << " HPWL: " << prev_hpwl;

if (PRINT_LONG_NET) {
@@ -1492,6 +1493,12 @@ namespace ipl {
plotInstImage("inst_" + std::to_string(iter_num));
plotBinForceLine("bin_" + std::to_string(iter_num));
}

if (isJsonOutputEnabled()) {
plotInstJson("inst_" + std::to_string(iter_num), iter_num, sum_overflow);

printDensityMapToCsv("density/density_map_" + std::to_string(iter_num));
}
}

if (iter_num == 1 || iter_num % 5 == 0) {
@@ -1654,6 +1661,46 @@ namespace ipl {
#endif
}

void NesterovPlace::plotInstJson(std::string file_name, int32_t cur_iter, float overflow)
{
auto core_shape = _nes_database->_placer_db->get_layout()->get_core_shape();
std::vector<NesInstance*>& inst_list = _nes_database->_nInstance_list;
nlohmann::json plot = nlohmann::json::object();

// Initialize the plot object
plot["instances"] = nlohmann::json::array();
plot["real_width"] = core_shape.get_width();
plot["real_height"] = core_shape.get_height();
plot["num_obj"] = _nes_database->_nInstance_list.size();
plot["ll_x"] = core_shape.get_ll_x();
plot["ll_y"] = core_shape.get_ll_y();
plot["iter"] = cur_iter;

int32_t core_shift_x = core_shape.get_ll_x();
int32_t core_shift_y = core_shape.get_ll_y();

for (auto* inst : inst_list) {
int32_t inst_real_width = inst->get_origin_shape().get_width();
int32_t inst_real_height = inst->get_origin_shape().get_height();
auto inst_center = inst->get_density_center_coordi();
inst_center.set_x(inst_center.get_x() - core_shift_x);
inst_center.set_y(inst_center.get_y() - core_shift_y);

plot["instances"].push_back({{"id", inst->get_inst_id()},
{"name", inst->get_name()},
{"x", inst_center.get_x()},
{"y", inst_center.get_y()},
{"width", inst_real_width},
{"height", inst_real_height},
{"is_macro", inst->isMacro()},
{"is_filler", inst->isFiller()}});
}

std::ofstream out_file(iPLAPIInst.obtainTargetDir() + "/pl/plot/" + file_name + ".json");
out_file << plot.dump(2);
out_file.close();
}

void NesterovPlace::plotBinForceLine(std::string file_name)
{
#ifdef BUILD_QT


+ 7
- 2
src/operation/iPL/source/module/global_placer/electrostatic_placer/NesterovPlace.hh View File

@@ -43,7 +43,7 @@ class NesterovPlace
{
public:
NesterovPlace() = delete;
NesterovPlace(Config* config, PlacerDB* placer_db);
NesterovPlace(Config* config, PlacerDB* placer_db, bool enableJsonOutput = false);
NesterovPlace(const NesterovPlace&) = delete;
NesterovPlace(NesterovPlace&&) = delete;
~NesterovPlace();
@@ -54,6 +54,8 @@ class NesterovPlace
void runNesterovPlace();
void printNesterovDatabase();

bool isJsonOutputEnabled() { return _enable_json_output; }

private:
NesterovPlaceConfig _nes_config;
NesterovDatabase* _nes_database;
@@ -65,6 +67,7 @@ class NesterovPlace
std::vector<float> _hpwl_record_list;
float _quad_penalty_coeff = 0.005;
int64_t _total_inst_area = 0;
bool _enable_json_output = false;

void resetOverflowRecordList();
void resetHPWLRecordList();
@@ -137,6 +140,7 @@ class NesterovPlace
void printIterationCoordi(std::ofstream& file_stream, int32_t cur_iter);
void saveNesterovPlaceData(int32_t cur_iter);
void plotInstImage(std::string file_name);
void plotInstJson(std::string file_name, int32_t cur_iter, float overflow);
void plotBinForceLine(std::string file_name);
void printIterInfoToCsv(std::ofstream& file_stream, int32_t iter_num);
void printDensityMapToCsv(std::string file_name);
@@ -155,7 +159,8 @@ class NesterovPlace
void notifyPLOverflowInfo(float final_overflow);
void notifyPLPlaceDensity();
};
inline NesterovPlace::NesterovPlace(Config* config, PlacerDB* placer_db) : _nes_database(nullptr)
inline NesterovPlace::NesterovPlace(Config* config, PlacerDB* placer_db, bool enableJsonOutput)
: _nes_database(nullptr), _enable_json_output(enableJsonOutput)
{
initNesConfig(config);
initNesDatabase(placer_db);


+ 3
- 1
src/operation/iPL/source/module/global_placer/electrostatic_placer/config/NesterovPlaceConfig.hh View File

@@ -45,6 +45,7 @@ class NesterovPlaceConfig

// getter.
int32_t get_thread_num() const { return _thread_num;}
int32_t get_info_iter_num() const { return _info_iter_num; }
float get_init_wirelength_coef() const { return _init_wirelength_coef; }
float get_reference_hpwl() const { return _reference_hpwl; }
float get_min_wirelength_force_bar() const { return _min_wirelength_force_bar; }
@@ -68,6 +69,7 @@ class NesterovPlaceConfig

// setter.
void set_thread_num(int32_t num_thread) { _thread_num = num_thread; }
void set_info_iter_num(int32_t info_iter_num) { _info_iter_num = info_iter_num; }
void set_init_wirelength_coef(float coef) { _init_wirelength_coef = coef; }
void set_reference_hpwl(float hpwl) { _reference_hpwl = hpwl; }
void set_min_wirelength_force_bar(float bar) { _min_wirelength_force_bar = bar; }
@@ -91,7 +93,7 @@ class NesterovPlaceConfig

private:
int32_t _thread_num;
int32_t _info_iter_num;
// about wirelength.
float _init_wirelength_coef;
float _reference_hpwl;


+ 5
- 1
src/platform/tool_manager/tool_api/ipl_io/ipl_io.cpp View File

@@ -49,7 +49,7 @@ void PlacerIO::destroyPlacer()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool PlacerIO::runPlacement(std::string config)
bool PlacerIO::runPlacement(std::string config, bool enableJsonOutput)
{
if (!iPLAPIInst.isPlacerDBStarted()) {
this->initPlacer(config);
@@ -57,6 +57,10 @@ bool PlacerIO::runPlacement(std::string config)
iPLAPIInst.updatePlacerDB();
}

if (enableJsonOutput) {
iPLAPIInst.enableJsonOutput();
}

ieda::Stats stats;
iPLAPIInst.runFlow();



+ 1
- 1
src/platform/tool_manager/tool_api/ipl_io/ipl_io.h View File

@@ -69,7 +69,7 @@ class PlacerIO
/// io
void initPlacer(std::string config);
void destroyPlacer();
bool runPlacement(std::string config);
bool runPlacement(std::string config, bool enableJsonOutput = false);
bool runIncrementalLegalization();
bool runIncrementalLegalization(std::vector<std::string>& changed_inst_list);
bool runFillerInsertion(std::string config);


+ 2
- 2
src/platform/tool_manager/tool_manager.cpp View File

@@ -173,12 +173,12 @@ void ToolManager::guiCaptrueDesign(std::string path)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// iPL
bool ToolManager::autoRunPlacer(std::string config)
bool ToolManager::autoRunPlacer(std::string config, bool enableJsonOutput)
{
// plInst->initPlacer(config);
// bool flag = plInst->runPlacement(config);
// plInst->destroyPlacer();
return plInst->runPlacement(config);
return plInst->runPlacement(config, enableJsonOutput);
;
}
bool ToolManager::runPlacerFiller(std::string config)


+ 1
- 1
src/platform/tool_manager/tool_manager.h View File

@@ -76,7 +76,7 @@ class ToolManager
// bool floorplanInit();

/// iPL
bool autoRunPlacer(std::string config = "");
bool autoRunPlacer(std::string config = "", bool enableJsonOutput = false);
bool runPlacerFiller(std::string config = "");
bool runPlacerIncrementalFlow(std::string config);
bool runPlacerIncrementalLegalization();


+ 0
- 1
src/third_party/mt-kahypar

@@ -1 +0,0 @@
Subproject commit 736068120cdd2d7ca91cb98bbaaf8a8b8c4bf0f1

Loading…
Cancel
Save
Baidu
map