Check out my first novel, midnight's simulacra!
Dot
From dankwiki
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)"; } } }