Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
timing
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
timing
Commits
f81e4bdf
Commit
f81e4bdf
authored
Jan 22, 2024
by
lvzhengyang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
build graph, and model runs
parent
d689adc4
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
193 additions
and
47 deletions
+193
-47
.gitignore
+2
-0
build_graph/create_graph.py
+178
-12
build_graph/utils.py
+2
-1
build_model/load_graph.py
+10
-17
build_model/model.py
+1
-17
No files found.
.gitignore
View file @
f81e4bdf
place_parser
data/asap7
*/__pycache__
*.log
build_graph/create_graph.py
View file @
f81e4bdf
...
...
@@ -827,6 +827,7 @@ def create_graph6(data_dir, parsed_libs_dir, parsed_sdf_dir, save_dir, block_nam
# NOTE: this assume that the path has only buffers inserted,
# and each buffer has only one input and one output
delay
+=
path
.
value
# is it right??
arc
.
delay
=
delay
rebuild
=
False
if
rebuild
:
...
...
@@ -865,7 +866,7 @@ def create_graph6(data_dir, parsed_libs_dir, parsed_sdf_dir, save_dir, block_nam
faninfanout
[
pin_id
]
=
1
# find primary_io_pin
types
=
{
'inport2d'
,
'inport2clk'
,
'inport2
p
in'
,
'inport2outport'
}
types
=
{
'inport2d'
,
'inport2clk'
,
'inport2in'
,
'inport2outport'
}
if
arc
.
type
in
types
:
pin_id
=
place_pin2id_map
[
arc
.
src
]
is_primary_io_pin
[
pin_id
]
=
1
...
...
@@ -895,17 +896,30 @@ def create_graph6(data_dir, parsed_libs_dir, parsed_sdf_dir, save_dir, block_nam
'inport2d'
,
'inport2clk'
,
'inport2in'
,
'q2outport'
,
'out2outport'
,
'inport2outport'
,
'q2in'
,
'out2in'
,
'out2d'
,
'q2d'
]
# type net_in is a reverse of net_out's src and dst
# build DGL edge types
for
arc_type
,
types
in
dgl_edge_types
.
items
():
edges
[
arc_type
]
=
[]
for
merge_type
in
types
:
edges
[
arc_type
]
+=
edges
[
merge_type
]
# type net_in is a reverse of net_out's src and dst
edges
[
'net_in'
]
=
[]
for
edge
in
edges
[
'net_out'
]:
edges
[
'net_in'
]
.
append
((
edge
[
1
],
edge
[
0
]))
dgl_graph
=
{}
for
arc_type
in
edges
:
dgl_graph
[(
'node'
,
arc_type
,
'node'
)]
=
edges
[
arc_type
]
g
=
dgl
.
heterograph
(
dgl_graph
)
"""
g = dgl.heterograph({
# for training
('node', 'net_out', 'node'): edges['net_out'],
('node', 'net_in', 'node'): edges['net_in'],
('node', 'cell_out', 'node'): edges['cell_out'],
})
"""
# test
try
:
...
...
@@ -957,12 +971,171 @@ def create_graph6(data_dir, parsed_libs_dir, parsed_sdf_dir, save_dir, block_nam
######## End build DGL graph ########
######## fill data into graph ########
# node data
num_pins
=
pin_cnt
valid_pin_list
=
place_pins_list
src_pin2path_map_place
=
dict
()
for
arc
in
timing_graph
.
all_arcs
:
if
not
arc
.
src
in
src_pin2path_map_place
:
src_pin2path_map_place
[
arc
.
src
]
=
[]
src_pin2path_map_place
[
arc
.
src
]
.
append
(
arc
)
net_delays_at_fanin
=
np
.
zeros
((
num_pins
,
4
))
for
edge
in
edges
[
'net_out'
]:
src
=
edge
[
0
]
dst
=
edge
[
1
]
src_pin
=
place_pins_list
[
src
]
dst_pin
=
place_pins_list
[
dst
]
paths
=
src_pin2path_map_place
[
src_pin
]
flag
=
False
for
path
in
paths
:
if
path
.
dst
==
dst_pin
:
net_delays_at_fanin
[
dst
]
=
np
.
maximum
(
path
.
delay
,
net_delays_at_fanin
[
dst
])
flag
=
True
break
if
not
flag
:
pdb
.
set_trace
()
assert
(
False
)
pin_loc
=
np
.
zeros
((
num_pins
,
4
))
for
i
in
range
(
num_pins
):
pin_name
=
valid_pin_list
[
i
]
inst_name
=
pin_name
.
split
(
'/'
)[
0
]
place_node_id
=
node_name2id_map
[
inst_name
]
place_node_x
=
node_x
[
place_node_id
]
place_node_y
=
node_y
[
place_node_id
]
place_node_pins
=
node2pin_map
[
place_node_id
]
if
inst_name
==
pin_name
:
# port
assert
(
place_node_pins
.
size
==
1
)
place_node_pin_id
=
place_node_pins
[
0
]
else
:
num_node_pins
=
place_node_pins
.
size
for
pi
in
range
(
num_node_pins
):
place_node_pin_id
=
place_node_pins
[
pi
]
place_node_pin_name
=
pin_names_raw
[
place_node_pin_id
]
.
decode
()
if
pin_name
.
split
(
'/'
)[
1
]
==
place_node_pin_name
:
break
place_pin_x_off
=
pin_offset_x
[
place_node_pin_id
]
place_pin_y_off
=
pin_offset_y
[
place_node_pin_id
]
pin_x
=
place_node_x
+
place_pin_x_off
pin_y
=
place_node_y
+
place_pin_y_off
pin_loc
[
i
]
=
np
.
array
([
pin_x
-
xl
,
pin_y
-
yl
,
xh
-
pin_x
,
yh
-
pin_y
])
ndata
=
dict
()
ndata
[
"n_rats"
]
=
torch
.
zeros
(
num_pins
,
4
)
ndata
[
"n_ats"
]
=
torch
.
zeros
(
num_pins
,
4
)
ndata
[
"n_slews"
]
=
torch
.
zeros
(
num_pins
,
4
)
ndata
[
"n_net_delays"
]
=
torch
.
from_numpy
(
net_delays_at_fanin
)
.
float
()
ndata
[
"nf"
]
=
torch
.
zeros
(
num_pins
,
10
)
ndata
[
"n_is_timing_endpt"
]
=
torch
.
from_numpy
(
is_timing_endpoint
)
.
float
()
for
pi
in
range
(
num_pins
):
pin_name
=
valid_pin_list
[
pi
]
ndata
[
"n_rats"
][
pi
]
=
torch
.
from_numpy
(
pin_time
[
pin_name
]
.
rat
)
ndata
[
"n_ats"
][
pi
]
=
torch
.
from_numpy
(
pin_time
[
pin_name
]
.
at
)
ndata
[
"n_slews"
][
pi
]
=
torch
.
from_numpy
(
pin_time
[
pin_name
]
.
slew
)
ndata
[
'nf'
][
pi
][
0
]
=
is_primary_io_pin
[
pi
]
ndata
[
'nf'
][
pi
][
1
]
=
faninfanout
[
pi
]
ndata
[
'nf'
][
pi
][
2
:
6
]
=
torch
.
from_numpy
(
pin_loc
[
pi
])
# cap data
if
is_primary_io_pin
[
pi
]:
ndata
[
"nf"
][
pi
][
6
:
10
]
=
torch
.
zeros
(
4
)
else
:
inst
=
pin_name
.
split
(
'/'
)[
0
]
pin_name_str
=
pin_name
.
split
(
'/'
)[
1
]
celltype
=
inst2libcell_map
[
inst
]
cap_data
=
np
.
zeros
(
4
)
cap_data
[
0
]
=
pin_caps
[
'fast'
][
celltype
][
pin_name_str
][
'rise_capacitance'
]
cap_data
[
1
]
=
pin_caps
[
'fast'
][
celltype
][
pin_name_str
][
'fall_capacitance'
]
cap_data
[
2
]
=
pin_caps
[
'slow'
][
celltype
][
pin_name_str
][
'rise_capacitance'
]
cap_data
[
3
]
=
pin_caps
[
'slow'
][
celltype
][
pin_name_str
][
'fall_capacitance'
]
ndata
[
"nf"
][
pi
][
6
:
10
]
=
torch
.
from_numpy
(
cap_data
)
# edge data
edges_features
=
dict
()
edges_features
[
'net_out'
]
=
[]
edges_features
[
'net_in'
]
=
[]
edges_features
[
'cell_out'
]
=
[]
for
edge
in
edges
[
'net_out'
]:
src
=
edge
[
0
]
dst
=
edge
[
1
]
srcx
=
pin_loc
[
src
][
0
]
+
xl
srcy
=
pin_loc
[
src
][
1
]
+
yl
dstx
=
pin_loc
[
dst
][
0
]
+
xl
dsty
=
pin_loc
[
dst
][
1
]
+
yl
ef
=
np
.
array
([
dstx
-
srcx
,
dsty
-
srcy
])
edges_features
[
'net_out'
]
.
append
(
ef
)
edges_features
[
'net_in'
]
.
append
(
-
ef
)
for
edge
in
edges
[
'cell_out'
]:
src
=
edge
[
0
]
dst
=
edge
[
1
]
src_pin
=
valid_pin_list
[
src
]
dst_pin
=
valid_pin_list
[
dst
]
inst
=
src_pin
.
split
(
'/'
)[
0
]
assert
(
inst
==
dst_pin
.
split
(
'/'
)[
0
])
path_key
=
dst_pin
.
split
(
'/'
)[
1
]
+
'/'
+
src_pin
.
split
(
'/'
)[
1
]
celltype
=
inst2libcell_map
[
inst
]
ef
=
np
.
zeros
(
512
)
ef
[:
4
*
15
]
=
lib_data
[
'fast'
][
celltype
][
path_key
][:
4
*
15
]
ef
[
4
*
15
:
2
*
4
*
15
]
=
lib_data
[
'slow'
][
celltype
][
path_key
][:
4
*
15
]
ef
[
2
*
4
*
15
:
2
*
4
*
15
+
4
*
49
]
=
lib_data
[
'fast'
][
celltype
][
path_key
][
-
4
*
49
:]
ef
[
-
4
*
49
:]
=
lib_data
[
'slow'
][
celltype
][
path_key
][
-
4
*
49
:]
edges_features
[
'cell_out'
]
.
append
(
ef
)
edges_delay
=
dict
()
edges_delay
[
'net_out'
]
=
[]
edges_delay
[
'cell_out'
]
=
[]
for
edge
in
edges
[
'net_out'
]:
src
=
edge
[
0
]
dst
=
edge
[
1
]
src_pin
=
valid_pin_list
[
src
]
dst_pin
=
valid_pin_list
[
dst
]
paths
=
src_pin2path_map_place
[
src_pin
]
flag
=
False
for
path
in
paths
:
if
path
.
dst
==
dst_pin
:
flag
=
True
edges_delay
[
'net_out'
]
.
append
(
path
.
delay
)
break
if
not
flag
:
pdb
.
set_trace
()
assert
(
False
)
for
edge
in
edges
[
'cell_out'
]:
src
=
edge
[
0
]
dst
=
edge
[
1
]
src_pin
=
valid_pin_list
[
src
]
dst_pin
=
valid_pin_list
[
dst
]
paths
=
src_pin2path_map_place
[
src_pin
]
flag
=
False
for
path
in
paths
:
if
path
.
dst
==
dst_pin
:
flag
=
True
edges_delay
[
'cell_out'
]
.
append
(
path
.
delay
)
break
if
not
flag
:
pdb
.
set_trace
()
assert
(
False
)
g
=
g_hetero
g
.
ndata
[
'n_rats'
]
=
ndata
[
'n_rats'
]
.
float
()
g
.
ndata
[
'n_ats'
]
=
ndata
[
'n_ats'
]
.
float
()
g
.
ndata
[
'n_slews'
]
=
ndata
[
'n_slews'
]
.
float
()
g
.
ndata
[
'nf'
]
=
ndata
[
'nf'
]
.
float
()
g
.
ndata
[
'n_is_timing_endpt'
]
=
ndata
[
'n_is_timing_endpt'
]
.
float
()
g
.
edges
[
'cell_out'
]
.
data
[
'e_delay'
]
=
torch
.
tensor
(
edges_delay
[
'cell_out'
])
.
float
()
g
.
edges
[
'cell_out'
]
.
data
[
'ef'
]
=
torch
.
tensor
(
edges_features
[
'cell_out'
])
.
float
()
g
.
edges
[
'net_out'
]
.
data
[
'e_delay'
]
=
torch
.
tensor
(
edges_delay
[
'net_out'
])
.
float
()
g
.
edges
[
'net_out'
]
.
data
[
'ef'
]
=
torch
.
tensor
(
edges_features
[
'net_out'
])
.
float
()
g
.
edges
[
'net_in'
]
.
data
[
'ef'
]
=
torch
.
tensor
(
edges_features
[
'net_in'
])
.
float
()
######## End fill data into graph ########
######## save graph ########
dgl
.
save_graphs
(
os
.
path
.
join
(
save_dir
,
f
'{block_name}.graph.bin'
),
[
g
])
######## End save graph ########
if
__name__
==
'__main__'
:
pdk
=
"asap7"
...
...
@@ -979,7 +1152,7 @@ if __name__ == '__main__':
# blocks = "ethmac".split()
# blocks = "mock-alu".split()
raw_data_dir
=
f
"
/cyberpi/OpenROAD-flow-scripts/flow/parse
/{pdk}"
raw_data_dir
=
f
"
../data
/{pdk}"
techlib_dir
=
os
.
path
.
join
(
raw_data_dir
,
"techlib"
)
do_parse_libs
=
0
...
...
@@ -1027,13 +1200,6 @@ if __name__ == '__main__':
sdf_dir
=
os
.
path
.
join
(
block_dir
,
'parsed'
)
lib_dir
=
os
.
path
.
join
(
techlib_dir
,
'parsed_lib'
)
# NOTE: skip error blocks
# error_blocks = {'ethmac', 'ibex', 'jpeg', 'mock-alu'}
# if block in error_blocks:
# print('skip')
# continue
# check_legal(data_dir, lib_dir, sdf_dir, save_dir, block)
create_graph6
(
data_dir
,
lib_dir
,
sdf_dir
,
save_dir
,
block
)
build_graph/utils.py
View file @
f81e4bdf
...
...
@@ -400,6 +400,7 @@ def parse_libs(libs, save_dir):
print
(
f
'finish reading {liberty_file}'
)
# pickle and save libdata and pin_cap
os
.
makedirs
(
save_dir
,
exist_ok
=
True
)
with
open
(
os
.
path
.
join
(
save_dir
,
"lib_data.pkl"
),
'wb'
)
as
f
:
pickle
.
dump
(
libdata
,
f
)
f
.
close
()
...
...
@@ -465,7 +466,7 @@ class TimingArc:
self
.
type
=
None
self
.
buffers
=
[]
# an ordered sequence of buffer, src->dst, (buf_in, buf_out)
self
.
delay
s
=
None
# delays from src->dst
self
.
delay
=
None
# delays from src->dst
class
TimingGraph
:
def
__init__
(
self
,
inst2libcell_map
):
...
...
build_model/load_graph.py
View file @
f81e4bdf
...
...
@@ -14,7 +14,7 @@ from model import PredModel
pdk
=
"asap7"
tag
=
"no_timing_opt"
dir_prefix
=
f
"
/cyberpi/OpenROAD-flow-scripts/flow/parse
/{pdk}/{tag}"
dir_prefix
=
f
"
../data
/{pdk}/{tag}"
# blocks = "aes aes-mbff ethmac gcd ibex jpeg mock-alu uart".split()
blocks
=
"aes aes-mbff gcd ibex jpeg uart"
.
split
()
...
...
@@ -33,20 +33,10 @@ groundtruth = True
def
gen_topo
(
g_hetero
):
torch
.
cuda
.
synchronize
()
time_s
=
time
.
time
()
# na, nb = g_hetero.edges(etype='fanout2fanin', form='uv')
# ca, cb = g_hetero.edges(etype='in2out', form='uv')
# ffa, ffb = g_hetero.edges(etype='clk2q', form='uv')
# eda, edb = g_hetero.edges(etype='fanout2d', form='uv')
# g = dgl.graph((torch.cat([na, ca, ffa, eda]).cpu(), torch.cat([nb, cb, ffb, edb]).cpu()))
# na, nb = g_hetero.edges(etype='net_out', form='uv')
# ca, cb = g_hetero.edges(etype='cell_out', form='uv')
# g = dgl.graph((torch.cat([na, ca]).cpu(), torch.cat([nb, cb]).cpu()))
na
,
nb
=
g_hetero
.
edges
(
etype
=
'fanout2fanin'
,
form
=
'uv'
)
ca
,
cb
=
g_hetero
.
edges
(
etype
=
'in2out'
,
form
=
'uv'
)
pa
,
pb
=
g_hetero
.
edges
(
etype
=
'_2outport'
,
form
=
'uv'
)
g
=
dgl
.
graph
((
torch
.
cat
([
na
,
ca
,
pa
])
.
cpu
(),
torch
.
cat
([
nb
,
cb
,
pb
])
.
cpu
()))
na
,
nb
=
g_hetero
.
edges
(
etype
=
'net_out'
,
form
=
'uv'
)
ca
,
cb
=
g_hetero
.
edges
(
etype
=
'cell_out'
,
form
=
'uv'
)
g
=
dgl
.
graph
((
torch
.
cat
([
na
,
ca
])
.
cpu
(),
torch
.
cat
([
nb
,
cb
])
.
cpu
()))
topo
=
dgl
.
topological_nodes_generator
(
g
)
# this seems like topo-sort
ret
=
[
t
.
cuda
()
for
t
in
topo
]
...
...
@@ -57,14 +47,17 @@ def gen_topo(g_hetero):
def
load_data
():
data
=
{}
for
block
in
blocks
:
graph_path
=
os
.
path
.
join
(
dir_prefix
,
block
,
"parsed"
,
f
"{block}.
2.
graph.bin"
)
graph_path
=
os
.
path
.
join
(
dir_prefix
,
block
,
"parsed"
,
f
"{block}.graph.bin"
)
g
=
dgl
.
load_graphs
(
graph_path
)[
0
][
0
]
.
to
(
'cuda'
)
topo
,
topo_time
=
gen_topo
(
g
)
ts
=
{
# 'fanin_nodes': g.edges(etype='fanout2fanin')[1].long(),
# 'fanout_nodes': g.edges(etype='fanout2fanin')[0].long(),
'input_nodes'
:
(
g
.
ndata
[
'nf'
][:,
1
]
<
0.5
)
.
nonzero
()
.
flatten
()
.
type
(
torch
.
int64
),
'output_nodes'
:
(
g
.
ndata
[
'nf'
][:,
1
]
>
0.5
)
.
nonzero
()
.
flatten
()
.
type
(
torch
.
int64
),
'output_nodes_nonpi'
:
torch
.
logical_and
(
g
.
ndata
[
'nf'
][:,
1
]
>
0.5
,
g
.
ndata
[
'nf'
][:,
0
]
<
0.5
)
.
nonzero
()
.
flatten
()
.
type
(
torch
.
int64
),
# pi/po: primary input/output
'pi_nodes'
:
torch
.
logical_and
(
g
.
ndata
[
'nf'
][:,
1
]
>
0.5
,
g
.
ndata
[
'nf'
][:,
0
]
>
0.5
)
.
nonzero
()
.
flatten
()
.
type
(
torch
.
int64
),
'po_nodes'
:
torch
.
logical_and
(
g
.
ndata
[
'nf'
][:,
1
]
<
0.5
,
g
.
ndata
[
'nf'
][:,
0
]
>
0.5
)
.
nonzero
()
.
flatten
()
.
type
(
torch
.
int64
),
'endpoints'
:
(
g
.
ndata
[
'n_is_timing_endpt'
]
>
0.5
)
.
nonzero
()
.
flatten
()
.
type
(
torch
.
long
),
'topo'
:
topo
,
}
data
[
block
]
=
g
,
ts
...
...
build_model/model.py
View file @
f81e4bdf
...
...
@@ -54,14 +54,6 @@ class NetConv(torch.nn.Module):
with
g
.
local_scope
():
g
.
ndata
[
'nf'
]
=
nf
# # fanin nodes
# g.update_all(self.edge_msg_i, fn.sum('efi', 'new_nf'), etype='fanout2fanin')
# # fanout nodes
# g.apply_edges(self.edge_msg_o, etype='fanin2fanout')
# g.update_all(fn.copy_e('efo1', 'efo1'), fn.sum('efo1', 'nfo1'), etype='fanin2fanout')
# g.update_all(fn.copy_e('efo2', 'efo2'), fn.max('efo2', 'nfo2'), etype='fanin2fanout')
# g.apply_nodes(self.node_reduce_o, ts['fanout_nodes'])
# input nodes
g
.
update_all
(
self
.
edge_msg_i
,
fn
.
sum
(
'efi'
,
'new_nf'
),
etype
=
'net_out'
)
# output nodes
...
...
@@ -155,16 +147,9 @@ class SignalProp(torch.nn.Module):
# g.apply_nodes(self.node_skip_level_o, ts['pi_nodes'])
def
prop_net
(
nodes
,
groundtruth
):
g
.
pull
(
nodes
,
functools
.
partial
(
self
.
edge_msg_net
,
groundtruth
=
groundtruth
),
fn
.
sum
(
'efn'
,
'new_nf'
),
etype
=
'
fanout2fanin
'
)
g
.
pull
(
nodes
,
functools
.
partial
(
self
.
edge_msg_net
,
groundtruth
=
groundtruth
),
fn
.
sum
(
'efn'
,
'new_nf'
),
etype
=
'
net_out
'
)
def
prop_cell
(
nodes
,
groundtruth
):
# cell_edges = ['in2out', 'clk2q', 'fanout2d']
# for etype in cell_edges:
# es = g.in_edges(nodes, etype=etype)
# g.apply_edges(functools.partial(self.edge_msg_cell, groundtruth=groundtruth), es, etype=etype)
# g.send_and_recv(es, fn.copy_e('efc1', 'efc1'), fn.sum('efc1', 'nfc1'), etype=etype)
# g.send_and_recv(es, fn.copy_e('efc2', 'efc2'), fn.max('efc2', 'nfc2'), etype=etype)
etype
=
'cell_out'
es
=
g
.
in_edges
(
nodes
,
etype
=
etype
)
g
.
apply_edges
(
functools
.
partial
(
self
.
edge_msg_cell
,
groundtruth
=
groundtruth
),
es
,
etype
=
etype
)
...
...
@@ -204,4 +189,3 @@ class PredModel(torch.nn.Module):
nf1
=
torch
.
cat
([
nf0
,
x
],
dim
=
1
)
nf2
,
cell_delays
=
self
.
prop
(
g
,
ts
,
nf1
)
return
net_delays
,
cell_delays
,
nf2
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