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
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
241 additions
and
70 deletions
+241
-70
CodeElements/Plc_client/plc_client_os.py
+170
-33
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
...
@@ -9,6 +9,22 @@ from collections import namedtuple
import
matplotlib.pyplot
as
plt
import
matplotlib.pyplot
as
plt
from
matplotlib.patches
import
Rectangle
from
matplotlib.patches
import
Rectangle
import
numpy
as
np
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'
)
Block
=
namedtuple
(
'Block'
,
'x_max y_max x_min y_min'
)
...
@@ -317,30 +333,151 @@ class PlacementCost(object):
...
@@ -317,30 +333,151 @@ class PlacementCost(object):
# mapping connection degree to each macros
# mapping connection degree to each macros
self
.
__update_connection
()
self
.
__update_connection
()
def
__read_plc
(
self
):
def
__read_plc
(
self
,
plc_pth
:
str
):
"""
"""
Plc file Parser
Plc file Parser
"""
"""
with
open
(
self
.
init_plc
)
as
fp
:
# meta information
line
=
fp
.
readline
()
_columns
=
0
_rows
=
0
while
line
:
_width
=
0.0
# skip comments
_height
=
0.0
if
re
.
search
(
r"\S"
,
line
)[
0
]
==
'#'
:
_area
=
0.0
# IMPORTANT: Advance pt
_block
=
None
line
=
fp
.
readline
()
_routes_per_micron_hor
=
0.0
continue
_routes_per_micron_ver
=
0.0
_routes_used_by_macros_hor
=
0.0
# words itemize into list
_routes_used_by_macros_ver
=
0.0
line_item
=
re
.
findall
(
r'[0-9A-Za-z\.\-]+'
,
line
)
_smoothing_factor
=
0
_overlap_threshold
=
0.0
# skip empty lines
if
len
(
line_item
)
==
0
:
# node information
# IMPORTANT: Advance pt
_hard_macros_cnt
=
0
line
=
fp
.
readline
()
_hard_macro_pins_cnt
=
0
continue
_macro_cnt
=
0
_macro_pin_cnt
=
0
line
=
fp
.
readline
()
_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
:
continue
# # 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
):
def
__update_connection
(
self
):
"""
"""
...
@@ -371,11 +508,6 @@ class PlacementCost(object):
...
@@ -371,11 +508,6 @@ class PlacementCost(object):
if
macro_type
==
"MACRO"
or
macro_type
==
"macro"
:
if
macro_type
==
"MACRO"
or
macro_type
==
"macro"
:
weight
=
pin
.
get_weight
()
weight
=
pin
.
get_weight
()
macro
.
add_connections
(
inputs
[
k
],
weight
)
macro
.
add_connections
(
inputs
[
k
],
weight
)
def
__update_placement
(
self
):
# assign modules to grid cells
pass
def
get_cost
(
self
)
->
float
:
def
get_cost
(
self
)
->
float
:
"""
"""
...
@@ -1238,13 +1370,6 @@ class PlacementCost(object):
...
@@ -1238,13 +1370,6 @@ class PlacementCost(object):
def
is_node_fixed
(
self
):
def
is_node_fixed
(
self
):
pass
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
):
def
optimize_stdcells
(
self
):
pass
pass
...
@@ -1473,6 +1598,18 @@ class PlacementCost(object):
...
@@ -1473,6 +1598,18 @@ class PlacementCost(object):
plt
.
show
()
plt
.
show
()
plt
.
close
(
'all'
)
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
# Board Entity Definition
class
Port
:
class
Port
:
...
...
CodeElements/Plc_client/plc_client_os_test.py
View file @
91c4afa6
...
@@ -9,35 +9,37 @@ import time
...
@@ -9,35 +9,37 @@ import time
import
math
import
math
np
.
set_printoptions
(
threshold
=
sys
.
maxsize
)
np
.
set_printoptions
(
threshold
=
sys
.
maxsize
)
FLAGS
=
flags
.
FLAGS
FLAGS
=
flags
.
FLAGS
import
argparse
class
CircuitDataBaseTest
():
"""plc_client_os_test docstrings
# NETLIST_PATH = "./Plc_client/test/sample_clustered_uniform_two_soft/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/ariane_hard2soft/netlist.pb.txt"
Test Utility Class for Google's API plc_wrapper_main with plc_client.py and plc_client_os.py
# NETLIST_PATH = "./Plc_client/test/ariane_soft2hard/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/ariane_port2soft/netlist.pb.txt"
Example:
# NETLIST_PATH = "./Plc_client/test/sample_clustered_nomacro/netlist.pb.txt"
At ./MacroPlacement/CodeElement, run the following command:
# NETLIST_PATH = "./Plc_client/test/sample_clustered_macroxy/netlist.pb.txt"
# NETLIST_PATH = "./Plc_client/test/ariane/netlist.pb.txt"
$ python -m Plc_client.plc_client_os_test
# NETLIST_PATH = "./Plc_client/test/ariane133/netlist.pb.txt"
NETLIST_PATH
=
"./Plc_client/test/testcases/TC1_MP1_0_0_P2_0_1.pb.txt"
Todo:
# NETLIST_PATH = "./Plc_client/test/testcases/TC24_MP1_0_0_MP2_4_4.pb.txt"
* Clean up code
# NETLIST_PATH = "./Plc_client/test/0P1M1m/netlist.pb.txt"
* Extract argument from command line
# NETLIST_PATH = "./Plc_client/test/0P2M0m/netlist.pb.txt"
* Report index for each mismatch array entry
# 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"
class
PlacementCostTest
():
# Google's Ariane
# Google's Ariane
#
CANVAS_WIDTH = 356.592
CANVAS_WIDTH
=
356.592
#
CANVAS_HEIGHT = 356.640
CANVAS_HEIGHT
=
356.640
#
GRID_COL = 35
GRID_COL
=
35
#
GRID_ROW = 33
GRID_ROW
=
33
# Ariane133
# Ariane133
CANVAS_WIDTH
=
1599.99
#
CANVAS_WIDTH = 1599.99
CANVAS_HEIGHT
=
1600.06
#
CANVAS_HEIGHT = 1600.06
GRID_COL
=
24
#
GRID_COL = 24
GRID_ROW
=
21
#
GRID_ROW = 21
# Sample clustered
# Sample clustered
# CANVAS_WIDTH = 400
# CANVAS_WIDTH = 400
...
@@ -51,11 +53,23 @@ class CircuitDataBaseTest():
...
@@ -51,11 +53,23 @@ class CircuitDataBaseTest():
# GRID_COL = 5
# GRID_COL = 5
# GRID_ROW = 5
# GRID_ROW = 5
def
__init__
(
self
,
NETLIST_PATH
)
->
None
:
def
__init__
(
self
,
NETLIST_PATH
,
PLC_PATH
=
None
)
->
None
:
self
.
NETLIST_PATH
=
NETLIST_PATH
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
):
def
test_proxy_congestion
(
self
):
# Google's
Binary Executable
# Google's
API
self
.
plc
=
plc_client
.
PlacementCost
(
self
.
NETLIST_PATH
)
self
.
plc
=
plc_client
.
PlacementCost
(
self
.
NETLIST_PATH
)
self
.
plc_os
=
plc_client_os
.
PlacementCost
(
self
.
NETLIST_PATH
)
self
.
plc_os
=
plc_client_os
.
PlacementCost
(
self
.
NETLIST_PATH
)
...
@@ -66,8 +80,8 @@ class CircuitDataBaseTest():
...
@@ -66,8 +80,8 @@ class CircuitDataBaseTest():
# self.plc.set_macro_routing_allocation(5, 5)
# self.plc.set_macro_routing_allocation(5, 5)
# self.plc_os.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
.
set_macro_routing_allocation
(
10
,
1
0
)
self
.
plc_os
.
set_macro_routing_allocation
(
0
,
0
)
self
.
plc_os
.
set_macro_routing_allocation
(
10
,
1
0
)
self
.
plc
.
set_congestion_smooth_range
(
0.0
)
self
.
plc
.
set_congestion_smooth_range
(
0.0
)
self
.
plc_os
.
set_congestion_smooth_range
(
0.0
)
self
.
plc_os
.
set_congestion_smooth_range
(
0.0
)
...
@@ -87,8 +101,8 @@ class CircuitDataBaseTest():
...
@@ -87,8 +101,8 @@ class CircuitDataBaseTest():
print
(
temp_gl_h
.
reshape
(
self
.
GRID_COL
,
self
.
GRID_ROW
))
print
(
temp_gl_h
.
reshape
(
self
.
GRID_COL
,
self
.
GRID_ROW
))
print
(
temp_os_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
(
"GL H Congestion: "
,
self
.
plc
.
get_horizontal_routing_congestion
()
)
print
(
"OS H Congestion: "
,
temp_os_h
)
print
(
"OS H Congestion: "
,
self
.
plc_os
.
get_horizontal_routing_congestion
()
)
temp_gl_v
=
np
.
array
(
self
.
plc
.
get_vertical_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
())
temp_os_v
=
np
.
array
(
self
.
plc_os
.
get_vertical_routing_congestion
())
...
@@ -144,7 +158,19 @@ class CircuitDataBaseTest():
...
@@ -144,7 +158,19 @@ class CircuitDataBaseTest():
# print("gl, os:", temp_gl_h[idx], temp_os_h[idx], temp_gl_v[idx], temp_os_v[idx])
# print("gl, os:", temp_gl_h[idx], temp_os_h[idx], temp_gl_v[idx], temp_os_v[idx])
# print("congestion summation gl os", sum(temp_gl_h), sum(temp_os_h), sum(temp_gl_v), sum(temp_os_v))
# 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
):
def
test_proxy_cost
(
self
):
# Google's Binary Executable
# Google's Binary Executable
self
.
plc
=
plc_client
.
PlacementCost
(
self
.
NETLIST_PATH
)
self
.
plc
=
plc_client
.
PlacementCost
(
self
.
NETLIST_PATH
)
...
@@ -154,12 +180,11 @@ class CircuitDataBaseTest():
...
@@ -154,12 +180,11 @@ class CircuitDataBaseTest():
macro_macro_x_spacing
=
50
,
macro_macro_x_spacing
=
50
,
macro_macro_y_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_canvas_size
(
self
.
CANVAS_WIDTH
,
self
.
CANVAS_HEIGHT
)
self
.
plc
.
set_placement_grid
(
self
.
GRID_COL
,
self
.
GRID_ROW
)
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_canvas_size
(
self
.
CANVAS_WIDTH
,
self
.
CANVAS_HEIGHT
)
self
.
plc_os
.
set_placement_grid
(
self
.
GRID_COL
,
self
.
GRID_ROW
)
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
())
print
(
self
.
plc_os
.
get_wirelength
(),
self
.
plc
.
get_wirelength
())
...
@@ -262,11 +287,19 @@ class CircuitDataBaseTest():
...
@@ -262,11 +287,19 @@ class CircuitDataBaseTest():
def
main
(
argv
):
def
main
(
argv
):
args
=
sys
.
argv
[
1
:]
args
=
sys
.
argv
[
1
:]
temp
=
CircuitDataBaseTest
(
args
[
0
])
temp
.
test_proxy_congestion
()
if
len
(
args
)
>
1
:
# temp.test_proxy_cost()
# netlist+plc file
# temp.test_metadata()
PCT
=
PlacementCostTest
(
args
[
0
],
args
[
1
])
# temp.test_miscellaneous()
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__"
:
if
__name__
==
"__main__"
:
app
.
run
(
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