Check out my first novel, midnight's simulacra!
Dot: Difference between revisions
From dankwiki
(Created page with '==SVG== * graphviz tools generate svg via -Tsvg * [http://github.com/vidarh/diagram-tools notugly] is some XSL to beautify dot's SVG output ==Examples== ===Packed Record=== <pre>...') |
No edit summary |
||
(10 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
If nothing else, remember that '''subgraphs must start with "cluster", yes in their identifier name, to be visually distinguishable i.e. apply label/color''' augh. | |||
==SVG== | ==SVG== | ||
* graphviz tools generate svg via -Tsvg | * graphviz tools generate svg via -Tsvg | ||
* [http://github.com/vidarh/diagram-tools notugly] is some XSL to beautify dot's SVG output | * [http://github.com/vidarh/diagram-tools notugly] is some XSL to beautify dot's SVG output | ||
==Examples== | ==Examples== | ||
Generated using Graphviz 2.20.2 and postprocessing via <tt>xsltproc</tt> and [http://github.com/vidarh/diagram-tools notugly]. I hand-wrote the dot sources. | |||
===Packed Record=== | ===Packed Record=== | ||
[[Image:Opteron.svg|thumb|right|alt="Dot SVG example (packed record)"|A packed record-type node (click to enlarge)]] | |||
<pre>digraph G { | <pre>digraph G { | ||
subgraph clusterOpteron { | subgraph clusterOpteron { | ||
label="Quad-Core Opteron" | label="Quad-Core Opteron" | ||
node [shape=record]; | node [shape=record]; | ||
struct3 [label="{ {C0|C1|C2|C3}|{L1/L2|L1/L2|L1/L2|L1/L2}|SRI (SysReq Interface)|<xbar>XBAR (Crossbar Switch)|{MCH|ncHT-HB|HT0|HT1}}"]; | struct3 [label="{ {C0|C1|C2|C3}|{L1/L2|L1/L2|L1/L2|L1/L2}|SRI\ | ||
(SysReq Interface)|<xbar>XBAR (Crossbar Switch)|{MCH|ncHT-HB|HT0|HT1}}"]; | |||
} | } | ||
} </pre> | } </pre> | ||
===Rectilinear arrangement A=== | ===Rectilinear arrangement A=== | ||
[[Image:Deneb.svg|thumb|right|alt="Dot SVG example (rectilinear)"|A rectilinear graph (click to enlarge)]] | |||
<pre>digraph G { | <pre>digraph G { | ||
subgraph clusterOpteronNUMA { | subgraph clusterOpteronNUMA { | ||
Line 29: | Line 36: | ||
} | } | ||
}</pre> | }</pre> | ||
===Rectilinear arrangement B=== | ===Rectilinear arrangement B=== | ||
[[Image:Nehalem.svg|thumb|right|alt="Dot SVG example (rectilinear)"|A rectilinear graph (click to enlarge)]] | |||
<pre>digraph G { | <pre>digraph G { | ||
nodesep="1" | nodesep="1" | ||
Line 68: | Line 77: | ||
DDR1 [style=filled fillcolor=grey shape=trapezium] | DDR1 [style=filled fillcolor=grey shape=trapezium] | ||
HostBus [style=filled fillcolor=green shape=Msquare] | HostBus [style=filled fillcolor=green shape=Msquare] | ||
} | |||
} </pre> | |||
===Large flow=== | |||
[[Image:libtorque.svg|thumb|right|alt="DOT SVG example (large flow)"|A large flow (click to enlarge)]] | |||
<pre>digraph G { | |||
nodesep="0.5" | |||
subgraph clusterPrime { | |||
labelloc="b"; | |||
compound="true" | |||
subgraph clusterKernel { | |||
label="Kernelspace (Linux epoll, FreeBSD kqueue, etc...)" | |||
style=filled; | |||
color=cadetblue; | |||
wqueue0 [style=filled fillcolor=steelblue shape=Mdiamond] | |||
wqueueN [style=filled fillcolor=steelblue shape=Mdiamond] | |||
wqueue0 -> nics [dir=both] | |||
nics [style="filled,diagonals" fillcolor=greenyellow label="Devices/IPC"] | |||
nics -> wqueueN [dir=both] | |||
{ rank=same; wqueue0 wqueueN nics } | |||
} | |||
subgraph clusterUser { | |||
label="Userspace (libtorque-enabled process)"; | |||
style=filled; | |||
color=gold; | |||
evqueueN [style="diagonals,filled" fillcolor=mediumpurple shape=invtrapezium group="evq"] | |||
evqueue0 [style="diagonals,filled" fillcolor=mediumpurple shape=invtrapezium group="evq"] | |||
wqueue0 -> evqueue0 [dir=both style=bold color="blue:purple"] | |||
wqueueN -> evqueueN [dir=both style=bold color="blue:purple"] | |||
evqueue0 -> evqueueN [label="About sqrt(cpus) evqueues, usually" dir=both style=dotted color=maroon] | |||
API -> evqueue0 [style=bold color=purple] | |||
API -> evqueueN [style=bold color=purple] | |||
API [style=filled fillcolor=green shape=box group="evq"]; | |||
{ rank=same; evqueue0 evqueueN } | |||
node [shape=record]; | |||
thr0 [label="<t0>T0|<t1>T1|<t2>T2|<tN>TN"]; | |||
thrN [label="<t0>T0|<t1>T1|<t2>T2|<tN>TN"]; | |||
color=red; | |||
evqueue0 -> thr0:t0 [color=blue] | |||
evqueue0 -> thr0:t1 [color=blue] | |||
evqueue0 -> thr0:t2 [color=blue] | |||
evqueue0 -> thr0:tN [color=blue] | |||
evqueueN -> thrN:t0 [color=blue] | |||
evqueueN -> thrN:t1 [color=blue] | |||
evqueueN -> thrN:t2 [color=blue] | |||
evqueueN -> thrN:tN [color=blue] | |||
{ rank=same; thr0 thrN } | |||
thr0 -> sigtable [color=lightblue style=bold] | |||
thr0 -> fdtable [color=lightblue style=bold] | |||
thr0 -> twheel [color=lightblue style=bold] | |||
thrN -> sigtable [color=lightblue style=bold] | |||
thrN -> fdtable [color=lightblue style=bold] | |||
thrN -> twheel [color=lightblue style=bold] | |||
fdtable [style=filled fillcolor=lightgreen shape=box label="fd monads\n(array)"] | |||
twheel [style=filled fillcolor=lightgreen shape=box label="timer monads\n(hwheel or array)"] | |||
sigtable [style=filled fillcolor=lightgreen shape=box label="sig monads\n(array)"] | |||
sigtable -> fdtable [color=lightblue label="AIO"] | |||
fdtable -> buf [color=lightblue] | |||
fdtable -> dnsssl [color=lightblue] | |||
twheel -> dnsssl [color=lightblue] | |||
buf -> API | |||
{ rank=same; sigtable fdtable twheel } | |||
dnsssl -> API | |||
dnsssl [style=filled fillcolor=lightgreen shape=box label="DNS, SSL/TLS\n(adns, OpenSSL)"] | |||
buf [style=filled fillcolor=lightgreen shape=box label="Buffering\n(arch-adaptive)"] | |||
node [shape=record]; | |||
appthr [label="<tmain>Main\nthread|<t1>T1|<t2>T2|<tN>TN"]; | |||
cbs [style=filled fillcolor=orange shape=box label="Registered callbacks"]; | |||
cbs -> appthr [dir=both color=darkgreen] | |||
sigtable -> cbs [color=green] | |||
fdtable -> cbs [color=green] | |||
twheel -> cbs [color=green] | |||
buf -> cbs [color=green] | |||
dnsssl -> cbs [color=green] | |||
cbs -> API; | |||
appthr -> API; | |||
/*API -> fdtable [color=blueviolet] | |||
API -> sigtable [color=blueviolet] | |||
API -> twheel [color=blueviolet]*/ | |||
} | |||
} | |||
} </pre> | |||
==PNG== | |||
Generated with <tt>dot -Tpng</tt>, no postprocessing. | |||
===Multiple records=== | |||
[[Image:CUDASHA1input.png|thumb|right|alt="DOT PNG example (multiple records)"|Multiple records (click to enlarge)]] | |||
<pre>digraph G { | |||
nodesep="0.1" | |||
rankdir=RL; | |||
subgraph clusterPrime { | |||
label="SHA-1 input layout\ (b\ hashes\ per\ thread)\nNx1x1 block geometry,\ Gx1x1\ grid\ geometry"; | |||
labelloc="b"; | |||
compound="true" | |||
subgraph clusterKernel { | |||
color=darkgoldenrod; | |||
style=filled; | |||
label="bl0"; | |||
b0 [style=filled,width=5,shape=record,label="{ {Hash\ set\ 1\n(512n\ bits)}\ | |||
|{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; | |||
b1 [style=filled,width=5,shape=record,label="{ {Hash\ set\ b\n(512n\ bits)}\ | |||
|{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; | |||
label="Input to block 1 (512*n*b bits)"; | |||
} | |||
subgraph clusterUser { | |||
color=darkkhaki; | |||
style=filled; | |||
label="bl0"; | |||
b2 [style=filled,width=5,shape=record,label="{ {Hash\ set\ 1\n(512n\ bits)}\ | |||
|{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; | |||
b3 [style=filled,width=5,shape=record,label="{ {Hash\ set\ b\n(512n\ bits)}\ | |||
|{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; | |||
label="Input to block G (512*n*b bits)"; | |||
} | |||
} | } | ||
} </pre> | } </pre> |
Latest revision as of 02:53, 15 March 2020
If nothing else, remember that subgraphs must start with "cluster", yes in their identifier name, to be visually distinguishable i.e. apply label/color augh.
SVG
- graphviz tools generate svg via -Tsvg
- notugly is some XSL to beautify dot's SVG output
Examples
Generated using Graphviz 2.20.2 and postprocessing via xsltproc and notugly. I hand-wrote the dot sources.
Packed Record
digraph G { subgraph clusterOpteron { label="Quad-Core Opteron" node [shape=record]; struct3 [label="{ {C0|C1|C2|C3}|{L1/L2|L1/L2|L1/L2|L1/L2}|SRI\ (SysReq Interface)|<xbar>XBAR (Crossbar Switch)|{MCH|ncHT-HB|HT0|HT1}}"]; } }
Rectilinear arrangement A
digraph G { subgraph clusterOpteronNUMA { label = "2x 'Deneb' Phenom II X4 910 (45nm, AM3). 8 threads." Deneb0->Deneb1 [dir="both" label="2GHz 16-bit bidir\n8GB/s HyperTransport 3.0" color="blue"] DDR0 -> Deneb0 [dir="both" color="lightblue"] DDR1 -> Deneb1 [dir="both" color="lightblue"] HostBus -> Deneb0 [dir="both" color="darkgreen"] HostBus -> Deneb1 [dir="both" color="darkgreen"] { rank=same; Deneb0 Deneb1 } { rank=same; DDR0 DDR1 } Deneb0 [style=filled fillcolor=steelblue shape=box] Deneb1 [style=filled fillcolor=steelblue shape=box] DDR0 [style=filled fillcolor=grey shape=invhouse] DDR1 [style=filled fillcolor=grey shape=invhouse] HostBus [style=filled fillcolor=green shape=Msquare] } }
Rectilinear arrangement B
digraph G { nodesep="1" subgraph clusterNehalemSMP { DDR0 -> Nehalem0 [dir="both" color="lightblue"] DDR0 -> Nehalem1 [dir="both" color="lightblue"] Nehalem0->Nehalem1 [dir="both" label="25.6GB/s QuickPath" color="blue"] subgraph clusterNehalemSMP0 { label="DRAM may or may not be shared."; style=filled; color=lightgrey; { rank=same; DDR0 } { rank=same; Nehalem0 Nehalem1 } } Nehalem2->Nehalem3 [dir="both" label="25.6GB/s QuickPath" color="blue"] Nehalem2 -> DDR1 [dir="both" color="lightblue"] Nehalem3 -> DDR1 [dir="both" color="lightblue"] subgraph clusterNehalemSMP1 { labelloc="b"; label="Each package gets its own MCH and L3 cache,\neach core its own (split) L1 and (unified) L2."; style=filled; color=lightgrey; { rank=same; Nehalem2 Nehalem3 } { rank=same; DDR1 } } label = "4x 'Nehalem-EP' E5520 HT Core i7 (45nm LGA1336). 32 threads." Nehalem1->Nehalem2 [dir="both" color="blue"] Nehalem3->Nehalem0 [dir="both" color="blue"] Nehalem0->HostBus [dir="both" color="darkgreen"] Nehalem1->HostBus [dir="both" color="darkgreen"] HostBus->Nehalem2 [dir="both" color="darkgreen"] HostBus->Nehalem3 [dir="both" color="darkgreen"] Nehalem0 [style=filled fillcolor=steelblue shape=box label="4x 2-way cores"] Nehalem1 [style=filled fillcolor=steelblue shape=box label="4x 2-way cores"] Nehalem2 [style=filled fillcolor=steelblue shape=box label="4x 2-way cores"] Nehalem3 [style=filled fillcolor=steelblue shape=box label="4x 2-way cores"] DDR0 [style=filled fillcolor=grey shape=invtrapezium] DDR1 [style=filled fillcolor=grey shape=trapezium] HostBus [style=filled fillcolor=green shape=Msquare] } }
Large flow
digraph G { nodesep="0.5" subgraph clusterPrime { labelloc="b"; compound="true" subgraph clusterKernel { label="Kernelspace (Linux epoll, FreeBSD kqueue, etc...)" style=filled; color=cadetblue; wqueue0 [style=filled fillcolor=steelblue shape=Mdiamond] wqueueN [style=filled fillcolor=steelblue shape=Mdiamond] wqueue0 -> nics [dir=both] nics [style="filled,diagonals" fillcolor=greenyellow label="Devices/IPC"] nics -> wqueueN [dir=both] { rank=same; wqueue0 wqueueN nics } } subgraph clusterUser { label="Userspace (libtorque-enabled process)"; style=filled; color=gold; evqueueN [style="diagonals,filled" fillcolor=mediumpurple shape=invtrapezium group="evq"] evqueue0 [style="diagonals,filled" fillcolor=mediumpurple shape=invtrapezium group="evq"] wqueue0 -> evqueue0 [dir=both style=bold color="blue:purple"] wqueueN -> evqueueN [dir=both style=bold color="blue:purple"] evqueue0 -> evqueueN [label="About sqrt(cpus) evqueues, usually" dir=both style=dotted color=maroon] API -> evqueue0 [style=bold color=purple] API -> evqueueN [style=bold color=purple] API [style=filled fillcolor=green shape=box group="evq"]; { rank=same; evqueue0 evqueueN } node [shape=record]; thr0 [label="<t0>T0|<t1>T1|<t2>T2|<tN>TN"]; thrN [label="<t0>T0|<t1>T1|<t2>T2|<tN>TN"]; color=red; evqueue0 -> thr0:t0 [color=blue] evqueue0 -> thr0:t1 [color=blue] evqueue0 -> thr0:t2 [color=blue] evqueue0 -> thr0:tN [color=blue] evqueueN -> thrN:t0 [color=blue] evqueueN -> thrN:t1 [color=blue] evqueueN -> thrN:t2 [color=blue] evqueueN -> thrN:tN [color=blue] { rank=same; thr0 thrN } thr0 -> sigtable [color=lightblue style=bold] thr0 -> fdtable [color=lightblue style=bold] thr0 -> twheel [color=lightblue style=bold] thrN -> sigtable [color=lightblue style=bold] thrN -> fdtable [color=lightblue style=bold] thrN -> twheel [color=lightblue style=bold] fdtable [style=filled fillcolor=lightgreen shape=box label="fd monads\n(array)"] twheel [style=filled fillcolor=lightgreen shape=box label="timer monads\n(hwheel or array)"] sigtable [style=filled fillcolor=lightgreen shape=box label="sig monads\n(array)"] sigtable -> fdtable [color=lightblue label="AIO"] fdtable -> buf [color=lightblue] fdtable -> dnsssl [color=lightblue] twheel -> dnsssl [color=lightblue] buf -> API { rank=same; sigtable fdtable twheel } dnsssl -> API dnsssl [style=filled fillcolor=lightgreen shape=box label="DNS, SSL/TLS\n(adns, OpenSSL)"] buf [style=filled fillcolor=lightgreen shape=box label="Buffering\n(arch-adaptive)"] node [shape=record]; appthr [label="<tmain>Main\nthread|<t1>T1|<t2>T2|<tN>TN"]; cbs [style=filled fillcolor=orange shape=box label="Registered callbacks"]; cbs -> appthr [dir=both color=darkgreen] sigtable -> cbs [color=green] fdtable -> cbs [color=green] twheel -> cbs [color=green] buf -> cbs [color=green] dnsssl -> cbs [color=green] cbs -> API; appthr -> API; /*API -> fdtable [color=blueviolet] API -> sigtable [color=blueviolet] API -> twheel [color=blueviolet]*/ } } }
PNG
Generated with dot -Tpng, no postprocessing.
Multiple records
digraph G { nodesep="0.1" rankdir=RL; subgraph clusterPrime { label="SHA-1 input layout\ (b\ hashes\ per\ thread)\nNx1x1 block geometry,\ Gx1x1\ grid\ geometry"; labelloc="b"; compound="true" subgraph clusterKernel { color=darkgoldenrod; style=filled; label="bl0"; b0 [style=filled,width=5,shape=record,label="{ {Hash\ set\ 1\n(512n\ bits)}\ |{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; b1 [style=filled,width=5,shape=record,label="{ {Hash\ set\ b\n(512n\ bits)}\ |{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; label="Input to block 1 (512*n*b bits)"; } subgraph clusterUser { color=darkkhaki; style=filled; label="bl0"; b2 [style=filled,width=5,shape=record,label="{ {Hash\ set\ 1\n(512n\ bits)}\ |{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; b3 [style=filled,width=5,shape=record,label="{ {Hash\ set\ b\n(512n\ bits)}\ |{T0[0x0]|T0[0x1]|T0[...]|T0[0xf]}|{T1[0x0]|T1[0x1]|T1[...]|T1[0xf]}|{...|...|...|...}|{Tn[0x0]|Tn[0x1]|Tn[...]|Tn[0xf]}}"]; label="Input to block G (512*n*b bits)"; } } }