Warning, /eic-opticks/docs/assets/simg4ox-event-processing.typ is written in an unsupported language. File is not indexed.
0001 // Regenerate from the repository root with:
0002 // typst compile --format svg docs/assets/simg4ox-event-processing.typ \
0003 // docs/assets/simg4ox-event-processing.svg
0004
0005 #let ink = rgb("#17324d")
0006 #let muted = rgb("#5d6975")
0007 #let panel-fill = rgb("#f8fafc")
0008 #let panel-stroke = rgb("#cbd5df")
0009 #let cpu-fill = rgb("#dceeff")
0010 #let cpu-stroke = rgb("#3978a8")
0011 #let gpu-fill = rgb("#eee3ff")
0012 #let gpu-stroke = rgb("#7651a8")
0013 #let wait-fill = rgb("#f0f2f4")
0014 #let wait-stroke = rgb("#8a929b")
0015 #let output-fill = rgb("#e3f5e8")
0016 #let output-stroke = rgb("#3d8b59")
0017
0018 #set page(width: 1050pt, height: auto, margin: 22pt, fill: white)
0019 #set text(font: "DejaVu Sans", size: 10pt, fill: ink)
0020 #set par(leading: 0.7em)
0021
0022 #let timeline-columns = (
0023 90pt,
0024 1fr, 1fr, 1fr, 1fr, 1fr, 1fr,
0025 1fr, 1fr, 1fr, 1fr, 1fr, 1fr,
0026 )
0027
0028 #let lane-label(body) = align(
0029 right + horizon,
0030 text(size: 8.5pt, weight: "bold", fill: ink, body),
0031 )
0032
0033 #let segment(fill-color, border-color, body) = box(
0034 width: 100%,
0035 height: 29pt,
0036 fill: fill-color,
0037 stroke: 0.8pt + border-color,
0038 radius: 4pt,
0039 inset: (x: 3pt, y: 4pt),
0040 align(center + horizon, text(size: 8pt, weight: "bold", fill: ink, body)),
0041 )
0042
0043 #let panel(title, subtitle, body) = block(
0044 width: 100%,
0045 fill: panel-fill,
0046 stroke: 0.8pt + panel-stroke,
0047 radius: 7pt,
0048 inset: 12pt,
0049 )[
0050 #text(size: 12pt, weight: "bold")[#title]
0051 #h(8pt)
0052 #text(size: 8.5pt, fill: muted)[#subtitle]
0053 #v(8pt)
0054 #body
0055 ]
0056
0057 #align(center)[
0058 #text(size: 17pt, weight: "bold")[Current `simg4ox` event processing]
0059 #v(2pt)
0060 #text(size: 9pt, fill: muted)[E0–E2 denote complete Geant4 events, each potentially containing many G4 tracks. The GPU event context is process-wide in both modes.]
0061 ]
0062
0063 #v(12pt)
0064
0065 #panel(
0066 [Serial (`--threads 1`)],
0067 [Each Geant4 event and its GPU photon transport finish before the next event starts.],
0068 grid(
0069 columns: timeline-columns,
0070 column-gutter: 2pt,
0071 row-gutter: 5pt,
0072 align: horizon,
0073
0074 [],
0075 grid.cell(colspan: 12)[#align(right)[#text(size: 7.5pt, fill: muted)[time →]]],
0076
0077 [#lane-label[Geant4 CPU]],
0078 grid.cell(colspan: 2)[#segment(cpu-fill, cpu-stroke)[process event E0]],
0079 grid.cell(colspan: 2)[],
0080 grid.cell(colspan: 2)[#segment(cpu-fill, cpu-stroke)[process event E1]],
0081 grid.cell(colspan: 2)[],
0082 grid.cell(colspan: 2)[#segment(cpu-fill, cpu-stroke)[process event E2]],
0083 grid.cell(colspan: 2)[],
0084
0085 [#lane-label[Shared GPU]],
0086 grid.cell(colspan: 2)[],
0087 grid.cell(colspan: 2)[#segment(gpu-fill, gpu-stroke)[transport E0 photons]],
0088 grid.cell(colspan: 2)[],
0089 grid.cell(colspan: 2)[#segment(gpu-fill, gpu-stroke)[transport E1 photons]],
0090 grid.cell(colspan: 2)[],
0091 grid.cell(colspan: 2)[#segment(gpu-fill, gpu-stroke)[transport E2 photons]],
0092 ),
0093 )
0094
0095 #v(10pt)
0096
0097 #panel(
0098 [Multithreaded (`--threads 3`)],
0099 [Geant4 events are processed concurrently; their photons enter GPU transport strictly in event-ID order.],
0100 grid(
0101 columns: timeline-columns,
0102 column-gutter: 2pt,
0103 row-gutter: 5pt,
0104 align: horizon,
0105
0106 [],
0107 grid.cell(colspan: 12)[#align(right)[#text(size: 7.5pt, fill: muted)[time →]]],
0108
0109 [#lane-label[Worker 0]],
0110 grid.cell(colspan: 3)[#segment(cpu-fill, cpu-stroke)[process event E0]],
0111 grid.cell(colspan: 2)[#segment(gpu-fill, gpu-stroke)[transport E0 photons]],
0112 grid.cell(colspan: 7)[],
0113
0114 [#lane-label[Worker 1]],
0115 grid.cell(colspan: 2)[#segment(cpu-fill, cpu-stroke)[process event E1]],
0116 grid.cell(colspan: 3)[#segment(wait-fill, wait-stroke)[wait for E0]],
0117 grid.cell(colspan: 2)[#segment(gpu-fill, gpu-stroke)[transport E1 photons]],
0118 grid.cell(colspan: 5)[],
0119
0120 [#lane-label[Worker 2]],
0121 grid.cell(colspan: 4)[#segment(cpu-fill, cpu-stroke)[process event E2]],
0122 grid.cell(colspan: 3)[#segment(wait-fill, wait-stroke)[wait for E0–E1]],
0123 grid.cell(colspan: 2)[#segment(gpu-fill, gpu-stroke)[transport E2 photons]],
0124 grid.cell(colspan: 3)[],
0125
0126 [#lane-label[Shared GPU]],
0127 grid.cell(colspan: 3)[],
0128 grid.cell(colspan: 2)[#segment(gpu-fill, gpu-stroke)[transport E0 photons]],
0129 grid.cell(colspan: 2)[#segment(gpu-fill, gpu-stroke)[transport E1 photons]],
0130 grid.cell(colspan: 2)[#segment(gpu-fill, gpu-stroke)[transport E2 photons]],
0131 grid.cell(colspan: 3)[],
0132 ),
0133 )
0134
0135 #v(10pt)
0136
0137 #align(center)[
0138 #box(width: 11pt, height: 11pt, fill: cpu-fill, stroke: 0.8pt + cpu-stroke, radius: 2pt)
0139 #h(4pt) Geant4 event processing
0140 #h(18pt)
0141 #box(width: 11pt, height: 11pt, fill: wait-fill, stroke: 0.8pt + wait-stroke, radius: 2pt)
0142 #h(4pt) Waiting for event-ID turn
0143 #h(18pt)
0144 #box(width: 11pt, height: 11pt, fill: gpu-fill, stroke: 0.8pt + gpu-stroke, radius: 2pt)
0145 #h(4pt) Serialized GPU photon transport
0146 #h(18pt)
0147 #box(width: 11pt, height: 11pt, fill: output-fill, stroke: 0.8pt + output-stroke, radius: 2pt)
0148 #h(4pt) Run-end merge and save
0149 ]
0150
0151 #v(8pt)
0152
0153 #align(center)[
0154 #box(
0155 fill: output-fill,
0156 stroke: 0.8pt + output-stroke,
0157 radius: 4pt,
0158 inset: (x: 10pt, y: 5pt),
0159 )[
0160 After all events: merge hits by event ID → `s_hits.npy` + `g_hits.npy`
0161 ]
0162 ]