# Layout subgraph into a grid

**URL:** <https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831>\
**Category:** Help\
**Created:** [March 18, 2025, 10:36am UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831 "2025-03-18T10:36:10Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![KelvinChung](https://avatars.discourse-cdn.com/v4/letter/k/e79b87/32.png) [@KelvinChung](https://forum.graphviz.org/u/KelvinChung)\
**Post date:** [March 18, 2025, 10:36am UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/1 "2025-03-18T10:36:10Z")

</div>

I am trying to layout the top-level subgraph into a grid. I have tried putting an anchor node in each of the subgraphs and using a high weight to pull the location, but it is still not working. Do you have any suggestions on what could be done?

[dot fit=true verbose=true height=238 width=800]

```auto
digraph G {

packmode="array_c4i";

rankdir=TB;

layout=dot;

subgraph cluster_0_0 {

label="tile_0_0_NULL";

margin=15;

style=rounded;

rank=source;

anchor_X0Y0 [style=invis];

}

subgraph cluster_0_1 {

label="tile_0_1_W_IO";

margin=15;

style=rounded;

rank=source;

subgraph "cluster_0_1_c0.W_IO" {

label="c0.W_IO";

"X0Y1.bel_c0.W_IO" [label="bel_c0.W_IO(z=0x0000)", shape=box];

"X0Y1.c0.W_IO.from_fabric" [label="from_fabric", shape=hexagon];

"X0Y1.c0.W_from_fabric";

"X0Y1.c0.W_from_fabric" -> "X0Y1.c0.W_IO.from_fabric";

"X0Y1.c0.W_IO.from_fabric" -> "X0Y1.bel_c0.W_IO";

"X0Y1.c0.W_IO.in" [label=in, shape=hexagon];

"X0Y1.c0.W_in";

"X0Y1.c0.W_in" -> "X0Y1.c0.W_IO.in";

"X0Y1.c0.W_IO.in" -> "X0Y1.bel_c0.W_IO";

"X0Y1.c0.W_IO.to_fabric" [label="to_fabric", shape=hexagon];

"X0Y1.bel_c0.W_IO" -> "X0Y1.c0.W_IO.to_fabric";

"X0Y1.c0.W_to_fabric";

"X0Y1.c0.W_IO.to_fabric" -> "X0Y1.c0.W_to_fabric";

"X0Y1.c0.W_IO.out" [label=out, shape=hexagon];

"X0Y1.bel_c0.W_IO" -> "X0Y1.c0.W_IO.out";

"X0Y1.c0.W_out";

"X0Y1.c0.W_IO.out" -> "X0Y1.c0.W_out";

}

"X0Y1.c0.out1_internal";

"X0Y1.c0.out1";

"X0Y1.c0.out1_internal" -> "X0Y1.c0.out1";

"X0Y1.c0.W_to_fabric" -> "X0Y1.c0.out1_internal";

"X0Y1.c0.in1";

"X0Y1.c0.in1" -> "X0Y1.c0.W_from_fabric";

anchor_X0Y1 [style=invis];

}

"X1Y1.c0.in3";

"X0Y1.c0.out1" -> "X1Y1.c0.in3" [dir=none, color=blue, weight=10000];

subgraph cluster_0_2 {

label="tile_0_2_NULL";

margin=15;

style=rounded;

rank=source;

anchor_X0Y2 [style=invis];

}

subgraph cluster_1_0 {

label="tile_1_0_S_IO";

margin=15;

style=rounded;

rank=source;

subgraph "cluster_1_0_c0.S_IO" {

label="c0.S_IO";

"X1Y0.bel_c0.S_IO" [label="bel_c0.S_IO(z=0x0000)", shape=box];

"X1Y0.c0.S_IO.from_fabric" [label="from_fabric", shape=hexagon];

"X1Y0.c0.S_from_fabric";

"X1Y0.c0.S_from_fabric" -> "X1Y0.c0.S_IO.from_fabric";

"X1Y0.c0.S_IO.from_fabric" -> "X1Y0.bel_c0.S_IO";

"X1Y0.c0.S_IO.in" [label=in, shape=hexagon];

"X1Y0.c0.S_in";

"X1Y0.c0.S_in" -> "X1Y0.c0.S_IO.in";

"X1Y0.c0.S_IO.in" -> "X1Y0.bel_c0.S_IO";

"X1Y0.c0.S_IO.to_fabric" [label="to_fabric", shape=hexagon];

"X1Y0.bel_c0.S_IO" -> "X1Y0.c0.S_IO.to_fabric";

"X1Y0.c0.S_to_fabric";

"X1Y0.c0.S_IO.to_fabric" -> "X1Y0.c0.S_to_fabric";

"X1Y0.c0.S_IO.out" [label=out, shape=hexagon];

"X1Y0.bel_c0.S_IO" -> "X1Y0.c0.S_IO.out";

"X1Y0.c0.S_out";

"X1Y0.c0.S_IO.out" -> "X1Y0.c0.S_out";

}

"X1Y0.c0.out0_internal";

"X1Y0.c0.out0";

"X1Y0.c0.out0_internal" -> "X1Y0.c0.out0";

"X1Y0.c0.S_to_fabric" -> "X1Y0.c0.out0_internal";

"X1Y0.c0.in0";

"X1Y0.c0.in0" -> "X1Y0.c0.S_from_fabric";

anchor_X1Y0 [style=invis];

}

"X1Y1.c0.in2";

"X1Y0.c0.out0" -> "X1Y1.c0.in2" [dir=none, color=blue, weight=10000];

subgraph cluster_1_1 {

label="tile_1_1_PE";

margin=15;

style=rounded;

rank=source;

subgraph cluster_1_1_CLK_DRV {

label="CLK_DRV";

"X1Y1.bel_CLK_DRV" [label="bel_CLK_DRV(z=0xffff)", shape=box];

"X1Y1.CLK_DRV.CLK_O" [label="CLK_O", shape=hexagon];

"X1Y1.bel_CLK_DRV" -> "X1Y1.CLK_DRV.CLK_O";

"X1Y1.user_clk_o";

"X1Y1.CLK_DRV.CLK_O" -> "X1Y1.user_clk_o";

}

subgraph "cluster_1_1_c0.ALU" {

label="c0.ALU";

"X1Y1.bel_c0.ALU" [label="bel_c0.ALU(z=0x0000)", shape=box];

"X1Y1.c0.ALU.data_in1" [label="data_in1", shape=hexagon];

"X1Y1.c0.data_in1";

"X1Y1.c0.data_in1" -> "X1Y1.c0.ALU.data_in1";

"X1Y1.c0.ALU.data_in1" -> "X1Y1.bel_c0.ALU";

"X1Y1.c0.ALU.data_in2" [label="data_in2", shape=hexagon];

"X1Y1.c0.data_in2";

"X1Y1.c0.data_in2" -> "X1Y1.c0.ALU.data_in2";

"X1Y1.c0.ALU.data_in2" -> "X1Y1.bel_c0.ALU";

"X1Y1.c0.ALU.data_in3" [label="data_in3", shape=hexagon];

"X1Y1.c0.data_in3";

"X1Y1.c0.data_in3" -> "X1Y1.c0.ALU.data_in3";

"X1Y1.c0.ALU.data_in3" -> "X1Y1.bel_c0.ALU";

"X1Y1.c0.ALU.data_out" [label="data_out", shape=hexagon];

"X1Y1.bel_c0.ALU" -> "X1Y1.c0.ALU.data_out";

"X1Y1.c0.data_out";

"X1Y1.c0.ALU.data_out" -> "X1Y1.c0.data_out";

}

subgraph "cluster_1_1_c0.const_unit" {

label="c0.const_unit";

"X1Y1.bel_c0.const_unit" [label="bel_c0.const_unit(z=0x0001)", shape=box];

"X1Y1.c0.const_unit.const_out" [label="const_out", shape=hexagon];

"X1Y1.bel_c0.const_unit" -> "X1Y1.c0.const_unit.const_out";

"X1Y1.c0.const_out";

"X1Y1.c0.const_unit.const_out" -> "X1Y1.c0.const_out";

}

subgraph "cluster_1_1_c0.RES_reg_unit" {

label="c0.RES_reg_unit";

"X1Y1.bel_c0.RES_reg_unit" [label="bel_c0.RES_reg_unit(z=0x0002)", shape=box];

"X1Y1.c0.RES_reg_unit.en" [label=en, shape=hexagon];

"X1Y1.c0.RES_en";

"X1Y1.c0.RES_en" -> "X1Y1.c0.RES_reg_unit.en";

"X1Y1.c0.RES_reg_unit.en" -> "X1Y1.bel_c0.RES_reg_unit";

"X1Y1.c0.RES_reg_unit.reg_in" [label="reg_in", shape=hexagon];

"X1Y1.c0.RES_reg_in";

"X1Y1.c0.RES_reg_in" -> "X1Y1.c0.RES_reg_unit.reg_in";

"X1Y1.c0.RES_reg_unit.reg_in" -> "X1Y1.bel_c0.RES_reg_unit";

"X1Y1.c0.RES_reg_unit.rst" [label=rst, shape=hexagon];

"X1Y1.c0.RES_rst";

"X1Y1.c0.RES_rst" -> "X1Y1.c0.RES_reg_unit.rst";

"X1Y1.c0.RES_reg_unit.rst" -> "X1Y1.bel_c0.RES_reg_unit";

"X1Y1.c0.RES_reg_unit.reg_out" [label="reg_out", shape=hexagon];

"X1Y1.bel_c0.RES_reg_unit" -> "X1Y1.c0.RES_reg_unit.reg_out";

"X1Y1.c0.RES_reg_out";

"X1Y1.c0.RES_reg_unit.reg_out" -> "X1Y1.c0.RES_reg_out";

"X1Y1.c0.RES_reg_unit.clk" [label=clk, shape=hexagon];

"X1Y1.c0.RES_reg_unit_clk_i";

"X1Y1.c0.RES_reg_unit_clk_i" -> "X1Y1.c0.RES_reg_unit.clk";

"X1Y1.c0.RES_reg_unit.clk" -> "X1Y1.bel_c0.RES_reg_unit";

}

subgraph "cluster_1_1_c0.N_reg_unit" {

label="c0.N_reg_unit";

"X1Y1.bel_c0.N_reg_unit" [label="bel_c0.N_reg_unit(z=0x0003)", shape=box];

"X1Y1.c0.N_reg_unit.en" [label=en, shape=hexagon];

"X1Y1.c0.N_en";

"X1Y1.c0.N_en" -> "X1Y1.c0.N_reg_unit.en";

"X1Y1.c0.N_reg_unit.en" -> "X1Y1.bel_c0.N_reg_unit";

"X1Y1.c0.N_reg_unit.reg_in" [label="reg_in", shape=hexagon];

"X1Y1.c0.N_reg_in";

"X1Y1.c0.N_reg_in" -> "X1Y1.c0.N_reg_unit.reg_in";

"X1Y1.c0.N_reg_unit.reg_in" -> "X1Y1.bel_c0.N_reg_unit";

"X1Y1.c0.N_reg_unit.rst" [label=rst, shape=hexagon];

"X1Y1.c0.N_rst";

"X1Y1.c0.N_rst" -> "X1Y1.c0.N_reg_unit.rst";

"X1Y1.c0.N_reg_unit.rst" -> "X1Y1.bel_c0.N_reg_unit";

"X1Y1.c0.N_reg_unit.reg_out" [label="reg_out", shape=hexagon];

"X1Y1.bel_c0.N_reg_unit" -> "X1Y1.c0.N_reg_unit.reg_out";

"X1Y1.c0.N_reg_out";

"X1Y1.c0.N_reg_unit.reg_out" -> "X1Y1.c0.N_reg_out";

"X1Y1.c0.N_reg_unit.clk" [label=clk, shape=hexagon];

"X1Y1.c0.N_reg_unit_clk_i";

"X1Y1.c0.N_reg_unit_clk_i" -> "X1Y1.c0.N_reg_unit.clk";

"X1Y1.c0.N_reg_unit.clk" -> "X1Y1.bel_c0.N_reg_unit";

}

subgraph "cluster_1_1_c0.E_reg_unit" {

label="c0.E_reg_unit";

"X1Y1.bel_c0.E_reg_unit" [label="bel_c0.E_reg_unit(z=0x0004)", shape=box];

"X1Y1.c0.E_reg_unit.en" [label=en, shape=hexagon];

"X1Y1.c0.E_en";

"X1Y1.c0.E_en" -> "X1Y1.c0.E_reg_unit.en";

"X1Y1.c0.E_reg_unit.en" -> "X1Y1.bel_c0.E_reg_unit";

"X1Y1.c0.E_reg_unit.reg_in" [label="reg_in", shape=hexagon];

"X1Y1.c0.E_reg_in";

"X1Y1.c0.E_reg_in" -> "X1Y1.c0.E_reg_unit.reg_in";

"X1Y1.c0.E_reg_unit.reg_in" -> "X1Y1.bel_c0.E_reg_unit";

"X1Y1.c0.E_reg_unit.rst" [label=rst, shape=hexagon];

"X1Y1.c0.E_rst";

"X1Y1.c0.E_rst" -> "X1Y1.c0.E_reg_unit.rst";

"X1Y1.c0.E_reg_unit.rst" -> "X1Y1.bel_c0.E_reg_unit";

"X1Y1.c0.E_reg_unit.reg_out" [label="reg_out", shape=hexagon];

"X1Y1.bel_c0.E_reg_unit" -> "X1Y1.c0.E_reg_unit.reg_out";

"X1Y1.c0.E_reg_out";

"X1Y1.c0.E_reg_unit.reg_out" -> "X1Y1.c0.E_reg_out";

"X1Y1.c0.E_reg_unit.clk" [label=clk, shape=hexagon];

"X1Y1.c0.E_reg_unit_clk_i";

"X1Y1.c0.E_reg_unit_clk_i" -> "X1Y1.c0.E_reg_unit.clk";

"X1Y1.c0.E_reg_unit.clk" -> "X1Y1.bel_c0.E_reg_unit";

}

subgraph "cluster_1_1_c0.S_reg_unit" {

label="c0.S_reg_unit";

"X1Y1.bel_c0.S_reg_unit" [label="bel_c0.S_reg_unit(z=0x0005)", shape=box];

"X1Y1.c0.S_reg_unit.en" [label=en, shape=hexagon];

"X1Y1.c0.S_en";

"X1Y1.c0.S_en" -> "X1Y1.c0.S_reg_unit.en";

"X1Y1.c0.S_reg_unit.en" -> "X1Y1.bel_c0.S_reg_unit";

"X1Y1.c0.S_reg_unit.reg_in" [label="reg_in", shape=hexagon];

"X1Y1.c0.S_reg_in";

"X1Y1.c0.S_reg_in" -> "X1Y1.c0.S_reg_unit.reg_in";

"X1Y1.c0.S_reg_unit.reg_in" -> "X1Y1.bel_c0.S_reg_unit";

"X1Y1.c0.S_reg_unit.rst" [label=rst, shape=hexagon];

"X1Y1.c0.S_rst";

"X1Y1.c0.S_rst" -> "X1Y1.c0.S_reg_unit.rst";

"X1Y1.c0.S_reg_unit.rst" -> "X1Y1.bel_c0.S_reg_unit";

"X1Y1.c0.S_reg_unit.reg_out" [label="reg_out", shape=hexagon];

"X1Y1.bel_c0.S_reg_unit" -> "X1Y1.c0.S_reg_unit.reg_out";

"X1Y1.c0.S_reg_out";

"X1Y1.c0.S_reg_unit.reg_out" -> "X1Y1.c0.S_reg_out";

"X1Y1.c0.S_reg_unit.clk" [label=clk, shape=hexagon];

"X1Y1.c0.S_reg_unit_clk_i";

"X1Y1.c0.S_reg_unit_clk_i" -> "X1Y1.c0.S_reg_unit.clk";

"X1Y1.c0.S_reg_unit.clk" -> "X1Y1.bel_c0.S_reg_unit";

}

subgraph "cluster_1_1_c0.W_reg_unit" {

label="c0.W_reg_unit";

"X1Y1.bel_c0.W_reg_unit" [label="bel_c0.W_reg_unit(z=0x0006)", shape=box];

"X1Y1.c0.W_reg_unit.en" [label=en, shape=hexagon];

"X1Y1.c0.W_en";

"X1Y1.c0.W_en" -> "X1Y1.c0.W_reg_unit.en";

"X1Y1.c0.W_reg_unit.en" -> "X1Y1.bel_c0.W_reg_unit";

"X1Y1.c0.W_reg_unit.reg_in" [label="reg_in", shape=hexagon];

"X1Y1.c0.W_reg_in";

"X1Y1.c0.W_reg_in" -> "X1Y1.c0.W_reg_unit.reg_in";

"X1Y1.c0.W_reg_unit.reg_in" -> "X1Y1.bel_c0.W_reg_unit";

"X1Y1.c0.W_reg_unit.rst" [label=rst, shape=hexagon];

"X1Y1.c0.W_rst";

"X1Y1.c0.W_rst" -> "X1Y1.c0.W_reg_unit.rst";

"X1Y1.c0.W_reg_unit.rst" -> "X1Y1.bel_c0.W_reg_unit";

"X1Y1.c0.W_reg_unit.reg_out" [label="reg_out", shape=hexagon];

"X1Y1.bel_c0.W_reg_unit" -> "X1Y1.c0.W_reg_unit.reg_out";

"X1Y1.c0.W_reg_out";

"X1Y1.c0.W_reg_unit.reg_out" -> "X1Y1.c0.W_reg_out";

"X1Y1.c0.W_reg_unit.clk" [label=clk, shape=hexagon];

"X1Y1.c0.W_reg_unit_clk_i";

"X1Y1.c0.W_reg_unit_clk_i" -> "X1Y1.c0.W_reg_unit.clk";

"X1Y1.c0.W_reg_unit.clk" -> "X1Y1.bel_c0.W_reg_unit";

}

"X1Y1.user_clk_o" -> "X1Y1.c0.RES_reg_unit_clk_i";

"X1Y1.user_clk_o" -> "X1Y1.c0.N_reg_unit_clk_i";

"X1Y1.user_clk_o" -> "X1Y1.c0.E_reg_unit_clk_i";

"X1Y1.user_clk_o" -> "X1Y1.c0.S_reg_unit_clk_i";

"X1Y1.user_clk_o" -> "X1Y1.c0.W_reg_unit_clk_i";

"X1Y1.c0.out0_internal";

"X1Y1.c0.out0";

"X1Y1.c0.out0_internal" -> "X1Y1.c0.out0";

"X1Y1.c0.out1_internal";

"X1Y1.c0.out1";

"X1Y1.c0.out1_internal" -> "X1Y1.c0.out1";

"X1Y1.c0.out2_internal";

"X1Y1.c0.out2";

"X1Y1.c0.out2_internal" -> "X1Y1.c0.out2";

"X1Y1.c0.out3_internal";

"X1Y1.c0.out3";

"X1Y1.c0.out3_internal" -> "X1Y1.c0.out3";

"X1Y1.c0.data_out" -> "X1Y1.c0.out0_internal";

"X1Y1.c0.RES_reg_out" -> "X1Y1.c0.out0_internal";

"X1Y1.c0.in2";

"X1Y1.c0.in2" -> "X1Y1.c0.out0_internal";

"X1Y1.c0.data_out" -> "X1Y1.c0.out1_internal";

"X1Y1.c0.RES_reg_out" -> "X1Y1.c0.out1_internal";

"X1Y1.c0.in3";

"X1Y1.c0.in3" -> "X1Y1.c0.out1_internal";

"X1Y1.c0.data_out" -> "X1Y1.c0.out2_internal";

"X1Y1.c0.RES_reg_out" -> "X1Y1.c0.out2_internal";

"X1Y1.c0.in0";

"X1Y1.c0.in0" -> "X1Y1.c0.out2_internal";

"X1Y1.c0.data_out" -> "X1Y1.c0.out3_internal";

"X1Y1.c0.RES_reg_out" -> "X1Y1.c0.out3_internal";

"X1Y1.c0.in1";

"X1Y1.c0.in1" -> "X1Y1.c0.out3_internal";

"X1Y1.c0.in0" -> "X1Y1.c0.data_in1";

"X1Y1.c0.in1" -> "X1Y1.c0.data_in1";

"X1Y1.c0.in2" -> "X1Y1.c0.data_in1";

"X1Y1.c0.in3" -> "X1Y1.c0.data_in1";

"X1Y1.c0.RES_reg_out" -> "X1Y1.c0.data_in1";

"X1Y1.c0.N_reg_out" -> "X1Y1.c0.data_in1";

"X1Y1.c0.E_reg_out" -> "X1Y1.c0.data_in1";

"X1Y1.c0.S_reg_out" -> "X1Y1.c0.data_in1";

"X1Y1.c0.W_reg_out" -> "X1Y1.c0.data_in1";

"X1Y1.c0.in0" -> "X1Y1.c0.data_in2";

"X1Y1.c0.in1" -> "X1Y1.c0.data_in2";

"X1Y1.c0.in2" -> "X1Y1.c0.data_in2";

"X1Y1.c0.in3" -> "X1Y1.c0.data_in2";

"X1Y1.c0.const_out" -> "X1Y1.c0.data_in2";

"X1Y1.c0.RES_reg_out" -> "X1Y1.c0.data_in2";

"X1Y1.c0.N_reg_out" -> "X1Y1.c0.data_in2";

"X1Y1.c0.E_reg_out" -> "X1Y1.c0.data_in2";

"X1Y1.c0.S_reg_out" -> "X1Y1.c0.data_in2";

"X1Y1.c0.W_reg_out" -> "X1Y1.c0.data_in2";

"X1Y1.c0.in0" -> "X1Y1.c0.data_in3";

"X1Y1.c0.in1" -> "X1Y1.c0.data_in3";

"X1Y1.c0.in2" -> "X1Y1.c0.data_in3";

"X1Y1.c0.in3" -> "X1Y1.c0.data_in3";

"X1Y1.c0.const_out" -> "X1Y1.c0.data_in3";

"X1Y1.c0.data_out" -> "X1Y1.c0.RES_reg_in";

"X1Y1.c0.in0" -> "X1Y1.c0.N_reg_in";

"X1Y1.c0.N_reg_out" -> "X1Y1.c0.N_reg_in";

"X1Y1.c0.in1" -> "X1Y1.c0.E_reg_in";

"X1Y1.c0.E_reg_out" -> "X1Y1.c0.E_reg_in";

"X1Y1.c0.in2" -> "X1Y1.c0.S_reg_in";

"X1Y1.c0.S_reg_out" -> "X1Y1.c0.S_reg_in";

"X1Y1.c0.in3" -> "X1Y1.c0.W_reg_in";

"X1Y1.c0.W_reg_out" -> "X1Y1.c0.W_reg_in";

anchor_X1Y1 [style=invis];

}

"X1Y2.c0.in2";

"X1Y1.c0.out0" -> "X1Y2.c0.in2" [dir=none, color=blue, weight=10000];

"X2Y1.c0.in3";

"X1Y1.c0.out1" -> "X2Y1.c0.in3" [dir=none, color=blue, weight=10000];

"X1Y1.c0.out2" -> "X1Y0.c0.in0" [dir=none, color=blue, weight=10000];

"X1Y1.c0.out3" -> "X0Y1.c0.in1" [dir=none, color=blue, weight=10000];

subgraph cluster_1_2 {

label="tile_1_2_N_IO";

margin=15;

style=rounded;

rank=source;

subgraph "cluster_1_2_c0.N_IO" {

label="c0.N_IO";

"X1Y2.bel_c0.N_IO" [label="bel_c0.N_IO(z=0x0000)", shape=box];

"X1Y2.c0.N_IO.from_fabric" [label="from_fabric", shape=hexagon];

"X1Y2.c0.N_from_fabric";

"X1Y2.c0.N_from_fabric" -> "X1Y2.c0.N_IO.from_fabric";

"X1Y2.c0.N_IO.from_fabric" -> "X1Y2.bel_c0.N_IO";

"X1Y2.c0.N_IO.in" [label=in, shape=hexagon];

"X1Y2.c0.N_in";

"X1Y2.c0.N_in" -> "X1Y2.c0.N_IO.in";

"X1Y2.c0.N_IO.in" -> "X1Y2.bel_c0.N_IO";

"X1Y2.c0.N_IO.to_fabric" [label="to_fabric", shape=hexagon];

"X1Y2.bel_c0.N_IO" -> "X1Y2.c0.N_IO.to_fabric";

"X1Y2.c0.N_to_fabric";

"X1Y2.c0.N_IO.to_fabric" -> "X1Y2.c0.N_to_fabric";

"X1Y2.c0.N_IO.out" [label=out, shape=hexagon];

"X1Y2.bel_c0.N_IO" -> "X1Y2.c0.N_IO.out";

"X1Y2.c0.N_out";

"X1Y2.c0.N_IO.out" -> "X1Y2.c0.N_out";

}

"X1Y2.c0.out2_internal";

"X1Y2.c0.out2";

"X1Y2.c0.out2_internal" -> "X1Y2.c0.out2";

"X1Y2.c0.N_to_fabric" -> "X1Y2.c0.out2_internal";

"X1Y2.c0.in2";

"X1Y2.c0.in2" -> "X1Y2.c0.N_from_fabric";

anchor_X1Y2 [style=invis];

}

"X1Y2.c0.out2" -> "X1Y1.c0.in0" [dir=none, color=blue, weight=10000];

subgraph cluster_2_0 {

label="tile_2_0_NULL";

margin=15;

style=rounded;

rank=source;

anchor_X2Y0 [style=invis];

}

subgraph cluster_2_1 {

label="tile_2_1_E_IO";

margin=15;

style=rounded;

rank=source;

subgraph "cluster_2_1_c0.E_IO" {

label="c0.E_IO";

"X2Y1.bel_c0.E_IO" [label="bel_c0.E_IO(z=0x0000)", shape=box];

"X2Y1.c0.E_IO.from_fabric" [label="from_fabric", shape=hexagon];

"X2Y1.c0.E_from_fabric";

"X2Y1.c0.E_from_fabric" -> "X2Y1.c0.E_IO.from_fabric";

"X2Y1.c0.E_IO.from_fabric" -> "X2Y1.bel_c0.E_IO";

"X2Y1.c0.E_IO.in" [label=in, shape=hexagon];

"X2Y1.c0.E_in";

"X2Y1.c0.E_in" -> "X2Y1.c0.E_IO.in";

"X2Y1.c0.E_IO.in" -> "X2Y1.bel_c0.E_IO";

"X2Y1.c0.E_IO.to_fabric" [label="to_fabric", shape=hexagon];

"X2Y1.bel_c0.E_IO" -> "X2Y1.c0.E_IO.to_fabric";

"X2Y1.c0.E_to_fabric";

"X2Y1.c0.E_IO.to_fabric" -> "X2Y1.c0.E_to_fabric";

"X2Y1.c0.E_IO.out" [label=out, shape=hexagon];

"X2Y1.bel_c0.E_IO" -> "X2Y1.c0.E_IO.out";

"X2Y1.c0.E_out";

"X2Y1.c0.E_IO.out" -> "X2Y1.c0.E_out";

}

"X2Y1.c0.out3_internal";

"X2Y1.c0.out3";

"X2Y1.c0.out3_internal" -> "X2Y1.c0.out3";

"X2Y1.c0.E_to_fabric" -> "X2Y1.c0.out3_internal";

"X2Y1.c0.in3";

"X2Y1.c0.in3" -> "X2Y1.c0.E_from_fabric";

anchor_X2Y1 [style=invis];

}

"X2Y1.c0.out3" -> "X1Y1.c0.in1" [dir=none, color=blue, weight=10000];

subgraph cluster_2_2 {

label="tile_2_2_NULL";

margin=15;

style=rounded;

rank=source;

anchor_X2Y2 [style=invis];

}

anchor_X0Y0 -> anchor_X1Y0 [style=invis, weight=10000];

anchor_X0Y1 -> anchor_X1Y1 [style=invis, weight=10000];

anchor_X0Y2 -> anchor_X1Y2 [style=invis, weight=10000];

anchor_X1Y0 -> anchor_X2Y0 [style=invis, weight=10000];

anchor_X1Y1 -> anchor_X2Y1 [style=invis, weight=10000];

anchor_X1Y2 -> anchor_X2Y2 [style=invis, weight=10000];

anchor_X0Y0 -> anchor_X0Y1 [style=invis, rank=same, weight=10000];

anchor_X1Y0 -> anchor_X1Y1 [style=invis, rank=same, weight=10000];

anchor_X2Y0 -> anchor_X2Y1 [style=invis, rank=same, weight=10000];

anchor_X0Y1 -> anchor_X0Y2 [style=invis, rank=same, weight=10000];

anchor_X1Y1 -> anchor_X1Y2 [style=invis, rank=same, weight=10000];

anchor_X2Y1 -> anchor_X2Y2 [style=invis, rank=same, weight=10000];

}

```

[/dot]

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [March 18, 2025, 4:10pm UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/2 "2025-03-18T16:10:39Z")

</div>

I apologize. I have messed up the formatting of this post and can’t seem to figure out how to undo my mess.

While waiting for someone to correct my blunder,  
I’ll look at your graph

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [March 18, 2025, 4:51pm UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/3 "2025-03-18T16:51:17Z")

</div>

The graph has 4 modest-sized clusters and one large cluster. How do you want them arranged? (the input seems to say columns of four, based on input sequence)

---

<div class="post-metadata">

**Author:** ![magjac](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/magjac/32/16_2.png) [@magjac](https://forum.graphviz.org/u/magjac)\
**Post date:** [March 18, 2025, 5:25pm UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/4 "2025-03-18T17:25:07Z")

</div>

I’ve reverted the post to the original and added `fit=true verbose=true height=238 width=800` to show the DOT source and adjust the rendered graph a bit.

---

<div class="post-metadata">

**Author:** ![KelvinChung](https://avatars.discourse-cdn.com/v4/letter/k/e79b87/32.png) [@KelvinChung](https://forum.graphviz.org/u/KelvinChung)\
**Post date:** [March 18, 2025, 6:18pm UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/5 "2025-03-18T18:18:39Z")

</div>

I am trying to lay it out as a 3x3 grid. Towards the bottom, there is the section:

```auto
anchor_X0Y0 -> anchor_X1Y0 [style=invis, weight=10000];

anchor_X0Y1 -> anchor_X1Y1 [style=invis, weight=10000];

anchor_X0Y2 -> anchor_X1Y2 [style=invis, weight=10000];

anchor_X1Y0 -> anchor_X2Y0 [style=invis, weight=10000];

anchor_X1Y1 -> anchor_X2Y1 [style=invis, weight=10000];

anchor_X1Y2 -> anchor_X2Y2 [style=invis, weight=10000];

anchor_X0Y0 -> anchor_X0Y1 [style=invis, rank=same, weight=10000];

anchor_X1Y0 -> anchor_X1Y1 [style=invis, rank=same, weight=10000];

anchor_X2Y0 -> anchor_X2Y1 [style=invis, rank=same, weight=10000];

anchor_X0Y1 -> anchor_X0Y2 [style=invis, rank=same, weight=10000];

anchor_X1Y1 -> anchor_X1Y2 [style=invis, rank=same, weight=10000];

anchor_X2Y1 -> anchor_X2Y2 [style=invis, rank=same, weight=10000];

```

Which is trying to do that. I have put an anchor as an invisible node within each cluster. You should find `anchor_X0Y0` in `cluster_0_0`. But seems like is not enough.

I have also tried to put each row into a cluster, but do not seem to be working.

Ideally, I would like to have each cluster positioned relative to the cluster coordinate.

---

<div class="post-metadata">

**Author:** ![KelvinChung](https://avatars.discourse-cdn.com/v4/letter/k/e79b87/32.png) [@KelvinChung](https://forum.graphviz.org/u/KelvinChung)\
**Post date:** [March 18, 2025, 6:32pm UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/6 "2025-03-18T18:32:37Z")

</div>

I have a smaller example that might work better for discussion. That graph is generated, and I can fit the principle later.

[dot fit=true verbose=true height=238 width=800]

```auto
digraph G {

  subgraph cluster_0 {
    style=filled;
    color=lightgrey;
    node [style=filled,color=white];
    a0 -> a1 -> a2 -> a3;
    label = "process #0";
    anchor0[style=invis]
  }

  subgraph cluster_1 {
    node [style=filled];
    b0 -> b1 -> b2;
    label = "process #1";
    color=blue
    anchor1[style=invis]
  }
  
    subgraph cluster_2 {
    node [style=filled];
    c0 -> c1;
    label = "process #2";
    color=blue
    anchor2[style=invis]
  }
  
    subgraph cluster_3 {
    node [style=filled];
    d0 -> d1 -> d2 -> d3;
    label = "process #3";
    color=blue
    anchor3[style=invis]
  }
anchor0 -> anchor1[weight=1000, style=invis]
anchor0 -> anchor2[weight=1000, style=invis]
anchor1 -> anchor3[weight=1000, style=invis]
anchor2 -> anchor3[weight=1000, style=invis]
}

```

[/dot]

And format to

```auto
process 0 | process 1
process 2 | process 3

```

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [March 19, 2025, 2:18am UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/7 "2025-03-19T02:18:44Z")

</div>

- the first graph tries to use two conflicting techniques to build the grid:
  - “anchors” - dicey at best and probably doomed with wildly varying cluster sizes
    - no easy way to place the “anchors”
    - can’t use **rank=same** across clusters
    - hard to align columns, though **group** might help

  - **packmode** (packing) - a good idea, but seems to fail if there are edges between the clusters (as found in the first graph)

- the second graph is probably over-simplified
  - all the clusters are about the same size
  - there are no edges between the clusters

This needs more thought

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [March 19, 2025, 4:46am UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/8 "2025-03-19T04:46:09Z")

</div>

Here is work-in-progress - using **packmode** only

- removed all inter-cluster edges (going forward they would be replaced later)
- removed all anchor-\>anchor edges
- tweaked the **packmode** statement (packmode=“array\_ri3”; )
- colored the clusters for my eyes

Is this in any way close to what is desired?  
If not, what needs to be changed?

 ![forum2831_5](https://global.discourse-cdn.com/graphviz/original/2X/1/1e1ecdf253c70ff9c442ecfa1eb8691501bcc275.png)

---

<div class="post-metadata">

**Author:** ![KelvinChung](https://avatars.discourse-cdn.com/v4/letter/k/e79b87/32.png) [@KelvinChung](https://forum.graphviz.org/u/KelvinChung)\
**Post date:** [March 19, 2025, 10:23am UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/9 "2025-03-19T10:23:17Z")

</div>

That placement will be good enough for me.

A side question: Is the pack feature only available for a more recent version of Graphviz? TxDOT is leading to a double free, and the VSCode extension for viewing dot graphs is not rendering it correctly.

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [March 19, 2025, 2:06pm UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/10 "2025-03-19T14:06:36Z")

</div>

Yes, **packmode** was fixed about 8 months ago ([setting pack attributes can cause dot to crash (#2555) · Issues · graphviz / graphviz · GitLab](https://gitlab.com/graphviz/graphviz/-/issues/2555))  
As an alternative, you can:

- split your graph into 9 separate/independent graphs
- run each through dot to establish positioning
- feed all 9 to [gvpack](https://www.graphviz.org/pdf/gvpack.1.pdf) (another Graphviz program)
- finally, feed the **gvpack** output to **neato -n**

It is not as bad as it sounds.  
I have a program that will split one graph into multiple, based on top-level clusters and will publish if you need it.

---

<div class="post-metadata">

**Author:** ![KelvinChung](https://avatars.discourse-cdn.com/v4/letter/k/e79b87/32.png) [@KelvinChung](https://forum.graphviz.org/u/KelvinChung)\
**Post date:** [March 19, 2025, 3:06pm UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/11 "2025-03-19T15:06:26Z")

</div>

I can split the graph myself, I just need to make some changes in how I create the graph.

However, if I use this method, do I add the inter-cluster edge after **neato**?

---

<div class="post-metadata">

**Author:** ![BartB](https://avatars.discourse-cdn.com/v4/letter/b/848f3c/32.png) [@BartB](https://forum.graphviz.org/u/BartB)\
**Post date:** [March 19, 2025, 6:22pm UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/12 "2025-03-19T18:22:15Z")

</div>

I suggest to take a look at the osage layout, where you have much more control over how clusters are positioned.  
full explanation can be found here, comment from @jjlong: [Top Rank Node is not center aligned over some subgraphs - #5 by jjlong](https://forum.graphviz.org/t/top-rank-node-is-not-center-aligned-over-some-subgraphs/2338/5)

other example:[Is there a way to draw "desks" (2 boxes side by side and 2 below them) without using arrows on graphviz?](https://forum.graphviz.org/t/is-there-a-way-to-draw-desks-2-boxes-side-by-side-and-2-below-them-without-using-arrows-on-graphviz/1987)

---

<div class="post-metadata">

**Author:** ![KelvinChung](https://avatars.discourse-cdn.com/v4/letter/k/e79b87/32.png) [@KelvinChung](https://forum.graphviz.org/u/KelvinChung)\
**Post date:** [March 19, 2025, 7:18pm UTC](https://forum.graphviz.org/t/layout-subgraph-into-a-grid/2831/13 "2025-03-19T19:18:02Z")

</div>

Thanks. Maybe osage is the tool I want. Can I mix layout engine? Since the middle layer cluster might work better with dot…
