Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
macroplacement
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
macroplacement
Commits
91c4afa6
Commit
91c4afa6
authored
Aug 29, 2022
by
Dinple
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
restore placement WIP
parent
fc82171e
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
235 additions
and
64 deletions
+235
-64
CodeElements/Plc_client/plc_client_os.py
+164
-27
CodeElements/Plc_client/plc_client_os_test.py
+71
-37
No files found.
CodeElements/Plc_client/plc_client_os.py
View file @
91c4afa6
...
...
@@ -9,6 +9,22 @@ from collections import namedtuple
import
matplotlib.pyplot
as
plt
from
matplotlib.patches
import
Rectangle
import
numpy
as
np
from
optax
import
smooth_labels
"""plc_client_os docstrings.
Open-sourced effort for plc_client and Google's API, plc_wrapper_main. This module
is used to initialize a PlacementCost object that computes the meta-information and
proxy cost function for RL agent's reward signal at the end of each placement.
Example:
For testing, please refer to plc_client_os_test.py for more information.
Todo:
* Add Documentation
* Clean up
"""
Block
=
namedtuple
(
'Block'
,
'x_max y_max x_min y_min'
)
...
...
@@ -317,30 +333,151 @@ class PlacementCost(object):
# mapping connection degree to each macros
self
.
__update_connection
()
def
__read_plc
(
self
):
def
__read_plc
(
self
,
plc_pth
:
str
):
"""
Plc file Parser
"""
with
open
(
self
.
init_plc
)
as
fp
:
line
=
fp
.
readline
()
while
line
:
# skip comments
if
re
.
search
(
r"\S"
,
line
)[
0
]
==
'#'
:
# IMPORTANT: Advance pt
line
=
fp
.
readline
()
continue
# words itemize into list
# meta information
_columns
=
0
_rows
=
0
_width
=
0.0
_height
=
0.0
_area
=
0.0
_block
=
None
_routes_per_micron_hor
=
0.0
_routes_per_micron_ver
=
0.0
_routes_used_by_macros_hor
=
0.0
_routes_used_by_macros_ver
=
0.0
_smoothing_factor
=
0
_overlap_threshold
=
0.0
# node information
_hard_macros_cnt
=
0
_hard_macro_pins_cnt
=
0
_macro_cnt
=
0
_macro_pin_cnt
=
0
_port_cnt
=
0
_soft_macros_cnt
=
0
_soft_macro_pins_cnt
=
0
_stdcells_cnt
=
0
# node placement
_node_plc
=
{}
for
cnt
,
line
in
enumerate
(
open
(
plc_pth
,
'r'
)):
line_item
=
re
.
findall
(
r'[0-9A-Za-z\.\-]+'
,
line
)
# skip empty lines
if
len
(
line_item
)
==
0
:
# IMPORTANT: Advance pt
line
=
fp
.
readline
()
continue
line
=
fp
.
readline
()
# # skip comments
# if re.search(r"\S", line)[0] == '#':
# continue
if
'Columns'
in
line_item
and
'Rows'
in
line_item
:
# Columns and Rows should be defined on the same one-line
print
(
"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
)
_columns
=
int
(
line_item
[
1
])
_rows
=
int
(
line_item
[
3
])
elif
"Area"
in
line_item
:
print
(
"WTFFFFFFFFFf"
)
# Total core area of modules
_area
=
float
(
line_item
[
1
])
elif
"Block"
in
line_item
:
# The block name of the testcase
_block
=
str
(
line_item
[
1
])
elif
all
(
it
in
line_item
for
it
in
\
[
'Routes'
,
'per'
,
'micron'
,
'hor'
,
'ver'
]):
print
(
"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
)
# For routing congestion computation
_routes_per_micron_hor
=
float
(
line_item
[
4
])
_routes_per_micron_ver
=
float
(
line_item
[
6
])
elif
all
(
it
in
line_item
for
it
in
\
[
'Routes'
,
'used'
,
'by'
,
'macros'
,
'hor'
,
'ver'
]):
# For MACRO congestion computation
_routes_used_by_macros_hor
=
float
(
line_item
[
5
])
_routes_used_by_macros_ver
=
float
(
line_item
[
7
])
elif
all
(
it
in
line_item
for
it
in
[
'Smoothing'
,
'factor'
]):
# smoothing factor for routing congestion
_smoothing_factor
=
int
(
line_item
[
2
])
elif
all
(
it
in
line_item
for
it
in
[
'Overlap'
,
'threshold'
]):
# overlap
_overlap_threshold
=
float
(
line_item
[
2
])
elif
all
(
it
in
line_item
for
it
in
[
'HARD'
,
'MACROs'
])
\
and
len
(
line_item
)
==
3
:
_hard_macros_cnt
=
int
(
line_item
[
2
])
elif
all
(
it
in
line_item
for
it
in
[
'HARD'
,
'MACRO'
,
'PINs'
])
\
and
len
(
line_item
)
==
4
:
_hard_macro_pins_cnt
=
int
(
line_item
[
3
])
elif
all
(
it
in
line_item
for
it
in
[
'PORTs'
])
\
and
len
(
line_item
)
==
2
:
_port_cnt
=
int
(
line_item
[
1
])
elif
all
(
it
in
line_item
for
it
in
[
'SOFT'
,
'MACROs'
])
\
and
len
(
line_item
)
==
3
:
_soft_macros_cnt
=
int
(
line_item
[
2
])
elif
all
(
it
in
line_item
for
it
in
[
'SOFT'
,
'MACRO'
,
'PINs'
])
\
and
len
(
line_item
)
==
4
:
_soft_macros_pin_cnt
=
int
(
line_item
[
3
])
elif
all
(
it
in
line_item
for
it
in
[
'STDCELLs'
])
\
and
len
(
line_item
)
==
2
:
_stdcells_cnt
=
int
(
line_item
[
1
])
elif
all
(
it
in
line_item
for
it
in
[
'MACROs'
])
\
and
len
(
line_item
)
==
2
:
_macros_cnt
=
int
(
line_item
[
1
])
elif
all
(
re
.
match
(
r'[0-9N\.\-]+'
,
it
)
for
it
in
line_item
):
# NOTE: [node_index] [x] [y] [orientation] [fixed]
_node_plc
[
int
(
line_item
[
0
])]
=
line_item
[
1
:]
# return as dictionary
info_dict
=
{
"columns"
:
_columns
,
"rows"
:
_rows
,
"width"
:
_width
,
"height"
:
_height
,
"area"
:
_area
,
"block"
:
_block
,
"routes_per_micron_hor"
:
_routes_per_micron_hor
,
"routes_per_micron_ver"
:
_routes_per_micron_ver
,
"routes_used_by_macros_hor"
:
_routes_used_by_macros_hor
,
"routes_used_by_macros_ver"
:
_routes_used_by_macros_ver
,
"smoothing_factor"
:
_smoothing_factor
,
"overlap_threshold"
:
_overlap_threshold
,
"hard_macros_cnt"
:
_hard_macros_cnt
,
"hard_macro_pins_cnt"
:
_hard_macro_pins_cnt
,
"macro_cnt"
:
_macro_cnt
,
"macro_pin_cnt"
:
_macro_pin_cnt
,
"port_cnt"
:
_port_cnt
,
"soft_macros_cnt"
:
_soft_macros_cnt
,
"soft_macro_pins_cnt"
:
_soft_macro_pins_cnt
,
"stdcells_cnt"
:
_stdcells_cnt
,
"node_plc"
:
_node_plc
}
return
info_dict
def
restore_placement
(
self
,
plc_pth
:
str
,
ifInital
=
True
,
ifValidate
=
False
):
"""
Read and retrieve .plc file information
NOTE: DO NOT always set self.init_plc because
this function is also used to read final placement file
"""
# if plc is an initial placement
if
ifInital
:
self
.
init_plc
=
plc_pth
# extracted information from .plc file
info_dict
=
self
.
__read_plc
(
plc_pth
)
# validate netlist.pb.txt is on par with .plc
if
ifValidate
:
print
(
self
.
hard_macro_cnt
,
info_dict
[
'hard_macros_cnt'
])
assert
(
self
.
hard_macro_cnt
==
info_dict
[
'hard_macros_cnt'
])
assert
(
self
.
hard_macro_pin_cnt
==
info_dict
[
'hard_macro_pins_cnt'
])
assert
(
self
.
soft_macro_cnt
==
info_dict
[
'soft_macros_cnt'
])
assert
(
self
.
soft_macro_pin_cnt
==
info_dict
[
'soft_macro_pins_cnt'
])
assert
(
self
.
port_cnt
==
info_dict
[
'ports_cnt'
])
# TODO restore placement for each module
def
__update_connection
(
self
):
"""
...
...
@@ -372,11 +509,6 @@ class PlacementCost(object):
weight
=
pin
.
get_weight
()
macro
.
add_connections
(
inputs
[
k
],
weight
)
def
__update_placement
(
self
):
# assign modules to grid cells
pass
def
get_cost
(
self
)
->
float
:
"""
Compute wirelength cost from wirelength
...
...
@@ -1238,13 +1370,6 @@ class PlacementCost(object):
def
is_node_fixed
(
self
):
pass
def
restore_placement
(
self
,
init_plc_pth
:
str
):
"""
Read and retrieve .plc file information
"""
self
.
init_plc
=
init_plc_pth
self
.
__read_plc
()
def
optimize_stdcells
(
self
):
pass
...
...
@@ -1473,6 +1598,18 @@ class PlacementCost(object):
plt
.
show
()
plt
.
close
(
'all'
)
# Internal Util Function For Testing, Not visible at original CT
def
__random_swap_placement
(
self
,
final_plc
,
same_block
=
False
):
"""
Swapping HARD MACRO placement from final_plc file.
- swapping between i_icache, tag sram
- swapping between i_icache, data sram
- swapping between i_nbdcache, tag sram
- swapping between i_nbdcache, data sram
"""
pass
# Board Entity Definition
class
Port
:
...
...
CodeElements/Plc_client/plc_client_os_test.py
View file @
91c4afa6
...
...
@@ -9,35 +9,37 @@ import time
import
math
np
.
set_printoptions
(
threshold
=
sys
.
maxsize
)
FLAGS
=
flags
.
FLAGS
import
argparse
class
CircuitDataBaseTest
():
# NETLIST_PATH = "./Plc_client/test/sample_clustered_uniform_two_soft/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/ariane_hard2soft/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/ariane_soft2hard/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/ariane_port2soft/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/sample_clustered_nomacro/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/sample_clustered_macroxy/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/ariane/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/ariane133/netlist.pb.txt"
NETLIST_PATH
=
"./Plc_client/test/testcases/TC1_MP1_0_0_P2_0_1.pb.txt"
# NETLIST_PATH = "./Plc_client/test/testcases/TC24_MP1_0_0_MP2_4_4.pb.txt"
# NETLIST_PATH = "./Plc_client/test/0P1M1m/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/0P2M0m/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/0P3M0m/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/0P4M0m/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/testcases_xm/TC_MP1_4_1_MP2_2_2_MP3_3_4_MP4_0_0.pb.txt"
"""plc_client_os_test docstrings
Test Utility Class for Google's API plc_wrapper_main with plc_client.py and plc_client_os.py
Example:
At ./MacroPlacement/CodeElement, run the following command:
$ python -m Plc_client.plc_client_os_test
Todo:
* Clean up code
* Extract argument from command line
* Report index for each mismatch array entry
"""
class
PlacementCostTest
():
# Google's Ariane
#
CANVAS_WIDTH = 356.592
#
CANVAS_HEIGHT = 356.640
#
GRID_COL = 35
#
GRID_ROW = 33
CANVAS_WIDTH
=
356.592
CANVAS_HEIGHT
=
356.640
GRID_COL
=
35
GRID_ROW
=
33
# Ariane133
CANVAS_WIDTH
=
1599.99
CANVAS_HEIGHT
=
1600.06
GRID_COL
=
24
GRID_ROW
=
21
#
CANVAS_WIDTH = 1599.99
#
CANVAS_HEIGHT = 1600.06
#
GRID_COL = 24
#
GRID_ROW = 21
# Sample clustered
# CANVAS_WIDTH = 400
...
...
@@ -51,11 +53,23 @@ class CircuitDataBaseTest():
# GRID_COL = 5
# GRID_ROW = 5
def
__init__
(
self
,
NETLIST_PATH
)
->
None
:
def
__init__
(
self
,
NETLIST_PATH
,
PLC_PATH
=
None
)
->
None
:
self
.
NETLIST_PATH
=
NETLIST_PATH
if
PLC_PATH
:
self
.
PLC_PATH
=
PLC_PATH
def
test_input
(
self
):
self
.
plc
=
plc_client
.
PlacementCost
(
self
.
NETLIST_PATH
)
self
.
plc_os
=
plc_client_os
.
PlacementCost
(
netlist_file
=
self
.
NETLIST_PATH
,
macro_macro_x_spacing
=
50
,
macro_macro_y_spacing
=
50
)
if
self
.
PLC_PATH
:
self
.
plc_os
.
restore_placement
(
self
.
PLC_PATH
,
ifInital
=
True
,
ifValidate
=
True
)
def
test_proxy_congestion
(
self
):
# Google's
Binary Executable
# Google's
API
self
.
plc
=
plc_client
.
PlacementCost
(
self
.
NETLIST_PATH
)
self
.
plc_os
=
plc_client_os
.
PlacementCost
(
self
.
NETLIST_PATH
)
...
...
@@ -66,8 +80,8 @@ class CircuitDataBaseTest():
# self.plc.set_macro_routing_allocation(5, 5)
# self.plc_os.set_macro_routing_allocation(5, 5)
self
.
plc
.
set_macro_routing_allocation
(
0
,
0
)
self
.
plc_os
.
set_macro_routing_allocation
(
0
,
0
)
self
.
plc
.
set_macro_routing_allocation
(
10
,
1
0
)
self
.
plc_os
.
set_macro_routing_allocation
(
10
,
1
0
)
self
.
plc
.
set_congestion_smooth_range
(
0.0
)
self
.
plc_os
.
set_congestion_smooth_range
(
0.0
)
...
...
@@ -87,8 +101,8 @@ class CircuitDataBaseTest():
print
(
temp_gl_h
.
reshape
(
self
.
GRID_COL
,
self
.
GRID_ROW
))
print
(
temp_os_h
.
reshape
(
self
.
GRID_COL
,
self
.
GRID_ROW
))
print
(
"GL H Congestion: "
,
temp_gl_h
)
print
(
"OS H Congestion: "
,
temp_os_h
)
print
(
"GL H Congestion: "
,
self
.
plc
.
get_horizontal_routing_congestion
()
)
print
(
"OS H Congestion: "
,
self
.
plc_os
.
get_horizontal_routing_congestion
()
)
temp_gl_v
=
np
.
array
(
self
.
plc
.
get_vertical_routing_congestion
())
temp_os_v
=
np
.
array
(
self
.
plc_os
.
get_vertical_routing_congestion
())
...
...
@@ -145,6 +159,18 @@ class CircuitDataBaseTest():
# print("congestion summation gl os", sum(temp_gl_h), sum(temp_os_h), sum(temp_gl_v), sum(temp_os_v))
def
view_canvas
(
self
):
self
.
plc_os
=
plc_client_os
.
PlacementCost
(
netlist_file
=
self
.
NETLIST_PATH
,
macro_macro_x_spacing
=
50
,
macro_macro_y_spacing
=
50
)
self
.
plc
.
set_canvas_size
(
self
.
CANVAS_WIDTH
,
self
.
CANVAS_HEIGHT
)
self
.
plc
.
set_placement_grid
(
self
.
GRID_COL
,
self
.
GRID_ROW
)
self
.
plc_os
.
set_canvas_size
(
self
.
CANVAS_WIDTH
,
self
.
CANVAS_HEIGHT
)
self
.
plc_os
.
set_placement_grid
(
self
.
GRID_COL
,
self
.
GRID_ROW
)
# show canvas
self
.
plc_os
.
display_canvas
()
def
test_proxy_cost
(
self
):
# Google's Binary Executable
self
.
plc
=
plc_client
.
PlacementCost
(
self
.
NETLIST_PATH
)
...
...
@@ -154,13 +180,12 @@ class CircuitDataBaseTest():
macro_macro_x_spacing
=
50
,
macro_macro_y_spacing
=
50
)
print
(
"************ SETTING UP CANVAS ************"
)
self
.
plc
.
set_canvas_size
(
self
.
CANVAS_WIDTH
,
self
.
CANVAS_HEIGHT
)
self
.
plc
.
set_placement_grid
(
self
.
GRID_COL
,
self
.
GRID_ROW
)
self
.
plc_os
.
set_canvas_size
(
self
.
CANVAS_WIDTH
,
self
.
CANVAS_HEIGHT
)
self
.
plc_os
.
set_placement_grid
(
self
.
GRID_COL
,
self
.
GRID_ROW
)
# print(self.plc_os.display_canvas())
print
(
self
.
plc_os
.
get_wirelength
(),
self
.
plc
.
get_wirelength
())
assert
int
(
self
.
plc_os
.
get_wirelength
())
==
int
(
self
.
plc
.
get_wirelength
())
...
...
@@ -262,11 +287,19 @@ class CircuitDataBaseTest():
def
main
(
argv
):
args
=
sys
.
argv
[
1
:]
temp
=
CircuitDataBaseTest
(
args
[
0
])
temp
.
test_proxy_congestion
()
# temp.test_proxy_cost()
# temp.test_metadata()
# temp.test_miscellaneous()
if
len
(
args
)
>
1
:
# netlist+plc file
PCT
=
PlacementCostTest
(
args
[
0
],
args
[
1
])
else
:
# netlist
PCT
=
PlacementCostTest
(
args
[
0
])
PCT
.
test_input
()
# PCT.test_proxy_congestion()
# PCT.test_proxy_cost()
# PCT.test_metadata()
# PCT.test_miscellaneous()
if
__name__
==
"__main__"
:
app
.
run
(
main
)
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment