Commit 9435cf9c by sakundu

Merge branch 'main' of github.com:TILOS-AI-Institute/MacroPlacement into flow_scripts

parents 35fccb6b 9d08572f
......@@ -27,8 +27,50 @@ $$
HPWL(netlist) = \sum_{i}^{N_{netlist}} W_{i\_{source}} \cdot [max_{b\in i}(x_b) - min_{b\in i}(x_b) + max_{b\in i}(y_b) - min_{b\in i}(y_b)]
$$
## Density Cost Computation
Density cost is computed from grid cells density.
By default, any given input will have grid col/row set to 10/10 until user later defines in the .plc file.
Grid cell density is represented as an 1D array where the length is set to be
$$
grid_\{col} \cdot grid_\{row}
$$
Each entry of this array represents the current occupied precentage within this cell.
Overlaps gets double counted, so it is possible for a cell density to exceed 1.0.
When a Placement Cost object is initialized, coordinate information and dimension information will be read from the netlist input and used to compute an initial grid cell density.
Once grid cell density is obtained, we take the top 10% of the largest grid cells and compute its average. The density cost will be half of the average value.
## Adjacency Matrix Computation
The adjacency matrix is represented as an array of $[N_{hardmacros} + N_{softmacros} + N_{ports}] \times [N_{hardmacros} + N_{softmacros} + N_{ports}]$ elements.
For each entry of the adjacency matrix, it represents the total number of connections between module $i$ and module $j$ subject to all corresponding pins.
The adjacency matrix is represented as an array of
$$
[N_{hardmacros} + N_{softmacros} + N_{ports}] \times [N_{hardmacros} + N_{softmacros} + N_{ports}]
$$
elements.
For each entry of the adjacency matrix, it represents the total number of connections between module $i$ and module $j$ subject to all corresponding pins. For soft macro pins, weight should be consider a factor to the number of connections.
## Congestion Cost Computation
Congestion cost is computed from the horizontal congestion grid cells array and the vertical congestion grid cells array. After concatenating these two arrays, Google takes the top 5% of the most congested grid cells and compute the average of them to get the final congestion cost.
To compute the congestion for each grid cell, a fast routing technique is applied which is detailed [here](https://docs.google.com/document/d/1hM7UbmANkhoGB3-UfFBp8TRDvvVjpmio7cyyjK4a5bI/edit?usp=sharing). After fast routing, we acquire the horizontal/vertical congestion due to net routing. This will be added with horiztonal/vertical congestion due to macro placement.
On a high level, for each grid cell, we compute the following:
$$
\text{Grid horizontal congestion = horizontal congestion due to macros + horizontal congestion due to net routing after smoothing.}
$$
$$
\text{Grid vertical congestion = vertical congestion due to macros + vertical congestion due to net routing after smoothing.}
$$
Notice a smoothing range can be set for congestion. This is only applied to congestion due to net routing which by counting adjacent cells and adding the averaged congestion to these adjacent cells. More details are provided in the document above.
# proto-file: tensorflow/core/framework/graph.proto
# proto-message: tensorflow.GraphDef
node {
name: "M0"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 350
}
}
attr {
key: "y"
value {
f: 350
}
}
attr {
key: "width"
value {
f: 50
}
}
}
node {
name: "M0/P1"
input: "Grp_2/Pinput"
attr {
key: "macro_name"
value {
placeholder: "M0"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 375
}
}
attr {
key: "y"
value {
f: 325
}
}
}
node {
name: "Grp_2"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "type"
value {
placeholder: "macro"
}
}
attr {
key: "width"
value {
f: 50
}
}
attr {
key: "x"
value {
f: 150
}
}
attr {
key: "y"
value {
f: 50
}
}
}
node {
name: "Grp_2/Pinput"
attr {
key: "macro_name"
value {
placeholder: "Grp_2"
}
}
attr {
key: "type"
value {
placeholder: "macro_pin"
}
}
attr {
key: "x"
value {
f: 150
}
}
attr {
key: "x_offset"
value {
f: 0
}
}
attr {
key: "y"
value {
f: 50
}
}
attr {
key: "y_offset"
value {
f: 0
}
}
}
\ No newline at end of file
# proto-file: tensorflow/core/framework/graph.proto
# proto-message: tensorflow.GraphDef
node {
name: "M0"
attr {
key: "height"
value {
f: 200
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 399
}
}
attr {
key: "y"
value {
f: 399
}
}
attr {
key: "width"
value {
f: 200
}
}
}
node {
name: "M1"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 50
}
}
attr {
key: "y"
value {
f: 50
}
}
attr {
key: "width"
value {
f: 50
}
}
}
node {
name: "M0/P1"
input: "M1/P1"
attr {
key: "macro_name"
value {
placeholder: "M0"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: -25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 374
}
}
attr {
key: "y"
value {
f: 374
}
}
attr {
key: "weight"
value {
f: 1000
}
}
}
node {
name: "M0/P2"
attr {
key: "macro_name"
value {
placeholder: "M0"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: -25
}
}
attr {
key: "y_offset"
value {
f: 25
}
}
attr {
key: "x"
value {
f: 374
}
}
attr {
key: "y"
value {
f: 424
}
}
attr {
key: "weight"
value {
f: 1000
}
}
}
node {
name: "M1/P1"
attr {
key: "macro_name"
value {
placeholder: "M1"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 75
}
}
attr {
key: "y"
value {
f: 25
}
}
}
node {
name: "M1/P2"
attr {
key: "macro_name"
value {
placeholder: "M1"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: 25
}
}
attr {
key: "x"
value {
f: 75
}
}
attr {
key: "y"
value {
f: 75
}
}
}
\ No newline at end of file
# proto-file: tensorflow/core/framework/graph.proto
# proto-message: tensorflow.GraphDef
node {
name: "M0"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 350
}
}
attr {
key: "y"
value {
f: 350
}
}
attr {
key: "width"
value {
f: 50
}
}
}
node {
name: "M1"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 50
}
}
attr {
key: "y"
value {
f: 50
}
}
attr {
key: "width"
value {
f: 50
}
}
}
node {
name: "M2"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 150
}
}
attr {
key: "y"
value {
f: 250
}
}
attr {
key: "width"
value {
f: 50
}
}
}
node {
name: "M0/P1"
input: "M1/P1"
input: "M2/P1"
attr {
key: "macro_name"
value {
placeholder: "M0"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: -25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 325
}
}
attr {
key: "y"
value {
f: 325
}
}
attr {
key: "weight"
value {
f: 1000
}
}
}
node {
name: "M0/P2"
attr {
key: "macro_name"
value {
placeholder: "M0"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: -25
}
}
attr {
key: "y_offset"
value {
f: 25
}
}
attr {
key: "x"
value {
f: 325
}
}
attr {
key: "y"
value {
f: 375
}
}
attr {
key: "weight"
value {
f: 1000
}
}
}
node {
name: "M1/P1"
attr {
key: "macro_name"
value {
placeholder: "M1"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 75
}
}
attr {
key: "y"
value {
f: 25
}
}
}
node {
name: "M1/P2"
attr {
key: "macro_name"
value {
placeholder: "M1"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: 25
}
}
attr {
key: "x"
value {
f: 75
}
}
attr {
key: "y"
value {
f: 75
}
}
}
node {
name: "M2/P1"
attr {
key: "macro_name"
value {
placeholder: "M2"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 175
}
}
attr {
key: "y"
value {
f: 225
}
}
}
\ No newline at end of file
# proto-file: tensorflow/core/framework/graph.proto
# proto-message: tensorflow.GraphDef
node {
name: "M0"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 350
}
}
attr {
key: "y"
value {
f: 350
}
}
attr {
key: "width"
value {
f: 50
}
}
}
node {
name: "M1"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 50
}
}
attr {
key: "y"
value {
f: 50
}
}
attr {
key: "width"
value {
f: 50
}
}
}
node {
name: "M2"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 150
}
}
attr {
key: "y"
value {
f: 250
}
}
attr {
key: "width"
value {
f: 50
}
}
}
node {
name: "M3"
attr {
key: "height"
value {
f: 50
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "x"
value {
f: 250
}
}
attr {
key: "y"
value {
f: 150
}
}
attr {
key: "width"
value {
f: 50
}
}
}
node {
name: "M0/P1"
input: "M1/P1"
input: "M2/P1"
input: "M3/P1"
attr {
key: "macro_name"
value {
placeholder: "M0"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: -25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 325
}
}
attr {
key: "y"
value {
f: 325
}
}
attr {
key: "weight"
value {
f: 1000
}
}
}
node {
name: "M0/P2"
attr {
key: "macro_name"
value {
placeholder: "M0"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: -25
}
}
attr {
key: "y_offset"
value {
f: 25
}
}
attr {
key: "x"
value {
f: 325
}
}
attr {
key: "y"
value {
f: 375
}
}
attr {
key: "weight"
value {
f: 1000
}
}
}
node {
name: "M1/P1"
attr {
key: "macro_name"
value {
placeholder: "M1"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 75
}
}
attr {
key: "y"
value {
f: 25
}
}
}
node {
name: "M1/P2"
attr {
key: "macro_name"
value {
placeholder: "M1"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: 25
}
}
attr {
key: "x"
value {
f: 75
}
}
attr {
key: "y"
value {
f: 75
}
}
}
node {
name: "M2/P1"
attr {
key: "macro_name"
value {
placeholder: "M2"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 175
}
}
attr {
key: "y"
value {
f: 225
}
}
}
node {
name: "M3/P1"
attr {
key: "macro_name"
value {
placeholder: "M3"
}
}
attr {
key: "type"
value {
placeholder: "MACRO_PIN"
}
}
attr {
key: "x_offset"
value {
f: 25
}
}
attr {
key: "y_offset"
value {
f: -25
}
}
attr {
key: "x"
value {
f: 275
}
}
attr {
key: "y"
value {
f: 125
}
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
# proto-file: tensorflow/core/framework/graph.proto
# proto-message: tensorflow.GraphDef
node {
name: "i_ariane/ex_stage_i/lsu_i/i_nbdcache/sram_block_4__data_sram/mem/mem_inst_mem_256x128_256x16_0x1"
attr {
key: "height"
value {
f: 19.26
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "width"
value {
f: 29.355
}
}
attr {
key: "x"
value {
f: 0
}
}
attr {
key: "y"
value {
f: 0
}
}
}
\ No newline at end of file
# proto-file: tensorflow/core/framework/graph.proto
# proto-message: tensorflow.GraphDef
node {
name: "i_ariane/i_frontend/i_icache/sram_block_1__tag_sram/mem/mem_inst_mem_256x45_256x16_0x0"
attr {
key: "height"
value {
f: 19.26
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "width"
value {
f: 29.355
}
}
attr {
key: "x"
value {
f: 341.9145
}
}
attr {
key: "y"
value {
f: 25.804
}
}
}
node {
name: "i_ariane/i_frontend/i_icache/sram_block_3__tag_sram/mem/mem_inst_mem_256x45_256x16_0x0"
attr {
key: "height"
value {
f: 19.26
}
}
attr {
key: "orientation"
value {
placeholder: "N"
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "width"
value {
f: 29.355
}
}
attr {
key: "x"
value {
f: 341.75
}
}
attr {
key: "y"
value {
f: 8.8835
}
}
}
\ No newline at end of file
......@@ -3,7 +3,6 @@
node {
name: "P0"
input: "Grp_2/Pinput"
input: "P1"
attr {
key: "side"
value {
......
# Placement file for Circuit Training
# Source input file(s) : circuit_training/environment/test_data/sample_clustered/netlist.pb.txt
# This file : circuit_training/environment/test_data/sample_clustered/initial.plc
# Date : 2022-03-13 09:30:00
# Columns : 2 Rows : 2
# Width : 600.000 Height : 600.000
# Area : 17603.53279986302
# Wirelength : 0.0
# Wirelength cost : 0.0
# Congestion cost : 0.0
# Density cost : 0.2305
# Project : circuit_training
# Block : sample_clustered
# Routes per micron, hor : 70.33 ver : 74.51
# Routes used by macros, hor : 51.79 ver : 51.79
# Smoothing factor : 2
# Overlap threshold : 0.004
#
#
#
# Counts of node types:
# HARD_MACROs : 2
# HARD_MACRO_PINs : 4
# MACROs : 3
# MACRO_PINs : 6
# PORTs : 2
# SOFT_MACROs : 1
# SOFT_MACRO_PINs : 2
# STDCELLs : 0
#
# node_index x y orientation fixed
0 0 100 - 1
1 499 499 - 1
2 125 375 N 0
3 375 375 N 0
8 170 310 N 0
# proto-file: tensorflow/core/framework/graph.proto
# proto-message: tensorflow.GraphDef
node {
name: "Grp_2"
attr {
key: "height"
value {
f: 10
}
}
attr {
key: "type"
value {
placeholder: "MACRO"
}
}
attr {
key: "width"
value {
f: 10
}
}
attr {
key: "x"
value {
f: 10
}
}
attr {
key: "y"
value {
f: 10
}
}
}
\ No newline at end of file
# Placement file for Circuit Training
# Source input file(s) : circuit_training/environment/test_data/sample_clustered/netlist.pb.txt
# This file : circuit_training/environment/test_data/sample_clustered/initial.plc
# Date : 2022-03-13 09:30:00
# Columns : 2 Rows : 2
# Width : 600.000 Height : 600.000
# Area : 17603.53279986302
# Wirelength : 0.0
# Wirelength cost : 0.0
# Congestion cost : 0.0
# Density cost : 0.2305
# Project : circuit_training
# Block : sample_clustered
# Routes per micron, hor : 70.33 ver : 74.51
# Routes used by macros, hor : 51.79 ver : 51.79
# Smoothing factor : 2
# Overlap threshold : 0.004
#
#
#
# Counts of node types:
# HARD_MACROs : 2
# HARD_MACRO_PINs : 4
# MACROs : 3
# MACRO_PINs : 6
# PORTs : 2
# SOFT_MACROs : 1
# SOFT_MACRO_PINs : 2
# STDCELLs : 0
#
# node_index x y orientation fixed
0 0 100 - 1
1 499 499 - 1
2 125 375 N 0
3 375 375 N 0
8 170 310 N 0
# proto-file: tensorflow/core/framework/graph.proto
# proto-message: tensorflow.GraphDef
node {
name: "Grp_2"
attr {
key: "height"
value {
f: 8
}
}
attr {
key: "type"
value {
placeholder: "macro"
}
}
attr {
key: "width"
value {
f: 8
}
}
attr {
key: "x"
value {
f: 0
}
}
attr {
key: "y"
value {
f: 0
}
}
}
node {
name: "Grp_2/Poutput_single_0"
attr {
key: "macro_name"
value {
placeholder: "Grp_2"
}
}
attr {
key: "type"
value {
placeholder: "macro_pin"
}
}
attr {
key: "x"
value {
f: 20
}
}
attr {
key: "x_offset"
value {
f: 0
}
}
attr {
key: "y"
value {
f: 45
}
}
attr {
key: "y_offset"
value {
f: 0
}
}
}
node {
name: "Grp_2/Pinput"
attr {
key: "macro_name"
value {
placeholder: "Grp_2"
}
}
attr {
key: "type"
value {
placeholder: "macro_pin"
}
}
attr {
key: "x"
value {
f: 20
}
}
attr {
key: "x_offset"
value {
f: 0
}
}
attr {
key: "y"
value {
f: 45
}
}
attr {
key: "y_offset"
value {
f: 0
}
}
}
# Placement file for Circuit Training
# Source input file(s) : circuit_training/environment/test_data/sample_clustered/netlist.pb.txt
# This file : circuit_training/environment/test_data/sample_clustered/initial.plc
# Date : 2022-03-13 09:30:00
# Columns : 2 Rows : 2
# Width : 600.000 Height : 600.000
# Area : 17603.53279986302
# Wirelength : 0.0
# Wirelength cost : 0.0
# Congestion cost : 0.0
# Density cost : 0.2305
# Project : circuit_training
# Block : sample_clustered
# Routes per micron, hor : 70.33 ver : 74.51
# Routes used by macros, hor : 51.79 ver : 51.79
# Smoothing factor : 2
# Overlap threshold : 0.004
#
#
#
# Counts of node types:
# HARD_MACROs : 2
# HARD_MACRO_PINs : 4
# MACROs : 3
# MACRO_PINs : 6
# PORTs : 2
# SOFT_MACROs : 1
# SOFT_MACRO_PINs : 2
# STDCELLs : 0
#
# node_index x y orientation fixed
0 0 100 - 1
1 499 499 - 1
2 125 375 N 0
3 375 375 N 0
8 170 310 N 0
# proto-file: tensorflow/core/framework/graph.proto
# proto-message: tensorflow.GraphDef
node {
name: "Grp_2"
attr {
key: "height"
value {
f: 8
}
}
attr {
key: "type"
value {
placeholder: "macro"
}
}
attr {
key: "width"
value {
f: 8
}
}
attr {
key: "x"
value {
f: 4
}
}
attr {
key: "y"
value {
f: 4
}
}
}
node {
name: "Grp_3"
attr {
key: "height"
value {
f: 8
}
}
attr {
key: "type"
value {
placeholder: "macro"
}
}
attr {
key: "width"
value {
f: 8
}
}
attr {
key: "x"
value {
f: 20
}
}
attr {
key: "y"
value {
f: 20
}
}
}
node {
name: "Grp_2/Poutput_single_0"
input: "Grp_3/Pinput"
attr {
key: "macro_name"
value {
placeholder: "Grp_2"
}
}
attr {
key: "type"
value {
placeholder: "macro_pin"
}
}
attr {
key: "x"
value {
f: 4
}
}
attr {
key: "x_offset"
value {
f: 0
}
}
attr {
key: "y"
value {
f: 4
}
}
attr {
key: "y_offset"
value {
f: 0
}
}
}
node {
name: "Grp_2/Pinput"
attr {
key: "macro_name"
value {
placeholder: "Grp_2"
}
}
attr {
key: "type"
value {
placeholder: "macro_pin"
}
}
attr {
key: "x"
value {
f: 4
}
}
attr {
key: "x_offset"
value {
f: 0
}
}
attr {
key: "y"
value {
f: 4
}
}
attr {
key: "y_offset"
value {
f: 0
}
}
}
node {
name: "Grp_3/Poutput_single_0"
input: "Grp_2/Pinput"
attr {
key: "macro_name"
value {
placeholder: "Grp_3"
}
}
attr {
key: "type"
value {
placeholder: "macro_pin"
}
}
attr {
key: "x"
value {
f: 20
}
}
attr {
key: "x_offset"
value {
f: 0
}
}
attr {
key: "y"
value {
f: 20
}
}
attr {
key: "y_offset"
value {
f: 0
}
}
}
node {
name: "Grp_3/Pinput"
attr {
key: "macro_name"
value {
placeholder: "Grp_3"
}
}
attr {
key: "type"
value {
placeholder: "macro_pin"
}
}
attr {
key: "x"
value {
f: 20
}
}
attr {
key: "x_offset"
value {
f: 0
}
}
attr {
key: "y"
value {
f: 20
}
}
attr {
key: "y_offset"
value {
f: 0
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment