Skip to content

Commit 3cb3e86

Browse files
Ch04-Ch09 storytelling rewrite: narrative openings, terminology, events
- Ch04: Merge SM86/SM90/multi-warpgroup into single 'scaling cooperation' narrative, weave MMA variants into prose instead of API-reference tables, concept-driven section titles - Ch05: General-concept opening (pipeline serialization, SPMD/MPMD), rename structural split -> static role partitioning, runtime branch -> guarded execution, add events intro, new comparison figure (uniform vs specialized) - Ch06: Producer-consumer sync general-concept opening, reference ch05 events - Ch07: Data-movement-as-hardware-concern opening - Ch08: FFI-as-universal-pattern opening - Ch09: Observability-in-opaque-systems opening - All changes translated to ZH - Fix ch07 anchor reference after ch04 restructure Made-with: Cursor
1 parent 1fb5901 commit 3cb3e86

16 files changed

Lines changed: 532 additions & 358 deletions
88.7 KB
Loading
90.4 KB
Loading
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
"""
2+
Figure 1 (ch05): Uniform vs Specialized execution timelines.
3+
Left: single warpgroup does DMA then MMA sequentially (no overlap).
4+
Right: two warpgroups — producer DMA and consumer MMA overlap in time.
5+
"""
6+
import sys
7+
import os
8+
9+
sys.path.insert(0, os.path.dirname(__file__))
10+
from theme import parse_theme
11+
from manim import *
12+
13+
C, THEME = parse_theme()
14+
15+
16+
class RoleComparison(Scene):
17+
def construct(self):
18+
self.camera.background_color = C["bg"]
19+
20+
title = Text(
21+
"Uniform vs Role-Specialized Execution",
22+
font_size=22,
23+
color=C["fg"],
24+
font="Monospace",
25+
)
26+
title.to_edge(UP, buff=0.3)
27+
self.add(title)
28+
29+
# --- LEFT: Uniform (one warpgroup, sequential) ---
30+
left_lbl = Text(
31+
"Uniform: one warpgroup",
32+
font_size=14,
33+
color=C["fg2"],
34+
font="Monospace",
35+
)
36+
left_lbl.move_to(LEFT * 3.5 + UP * 2.2)
37+
self.add(left_lbl)
38+
39+
left_sub = Text(
40+
"DMA and MMA take turns — no overlap",
41+
font_size=11,
42+
color=C["dim"],
43+
font="Monospace",
44+
)
45+
left_sub.next_to(left_lbl, DOWN, buff=0.1)
46+
self.add(left_sub)
47+
48+
wg_lbl = Text("WG0", font_size=12, color=C["fg3"], font="Monospace")
49+
wg_lbl.move_to(LEFT * 5.8 + UP * 1.1)
50+
self.add(wg_lbl)
51+
52+
dma_color = C["blue"]
53+
mma_color = C["purple_role"]
54+
55+
seq_blocks = [
56+
(-5.4, 1.1, dma_color, "DMA"),
57+
(-4.1, 1.2, mma_color, "MMA"),
58+
(-2.7, 1.1, dma_color, "DMA"),
59+
(-1.4, 1.2, mma_color, "MMA"),
60+
]
61+
for x0, w, col, lab in seq_blocks:
62+
r = Rectangle(
63+
width=w,
64+
height=0.42,
65+
fill_color=col,
66+
fill_opacity=0.35,
67+
stroke_color=col,
68+
stroke_width=1.5,
69+
)
70+
r.move_to(RIGHT * (x0 + w / 2) + UP * 0.85)
71+
self.add(r)
72+
t = Text(lab, font_size=11, color=C["fg"], font="Monospace")
73+
t.move_to(r)
74+
self.add(t)
75+
76+
left_axis = Line(
77+
LEFT * 5.5 + UP * 0.35,
78+
RIGHT * 0.2 + UP * 0.35,
79+
color=C["dim"],
80+
stroke_width=1.5,
81+
)
82+
left_time = Text("time →", font_size=10, color=C["dim"], font="Monospace")
83+
left_time.next_to(left_axis, RIGHT, buff=0.08)
84+
self.add(left_axis, left_time)
85+
86+
total_left = Text(
87+
"total ≈ 4 × (DMA + MMA)",
88+
font_size=11,
89+
color=C["red"],
90+
font="Monospace",
91+
)
92+
total_left.next_to(left_axis, DOWN, buff=0.15)
93+
self.add(total_left)
94+
95+
# --- Divider ---
96+
divider = DashedLine(
97+
UP * 2.5,
98+
DOWN * 2.5,
99+
color=C["dim"],
100+
stroke_width=1,
101+
dash_length=0.08,
102+
)
103+
self.add(divider)
104+
105+
# --- RIGHT: Specialized (two warpgroups, overlapping) ---
106+
right_lbl = Text(
107+
"Specialized: two warpgroups",
108+
font_size=14,
109+
color=C["fg2"],
110+
font="Monospace",
111+
)
112+
right_lbl.move_to(RIGHT * 3.5 + UP * 2.2)
113+
self.add(right_lbl)
114+
115+
right_sub = Text(
116+
"Producer DMA + Consumer MMA overlap",
117+
font_size=11,
118+
color=C["dim"],
119+
font="Monospace",
120+
)
121+
right_sub.next_to(right_lbl, DOWN, buff=0.1)
122+
self.add(right_sub)
123+
124+
prod_lbl = Text("Producer", font_size=12, color=C["blue"], font="Monospace")
125+
prod_lbl.move_to(RIGHT * 1.0 + UP * 1.35)
126+
self.add(prod_lbl)
127+
128+
cons_lbl = Text("Consumer", font_size=12, color=C["purple_role"], font="Monospace")
129+
cons_lbl.move_to(RIGHT * 1.0 + UP * 0.5)
130+
self.add(cons_lbl)
131+
132+
dma_spec = [
133+
(1.6, 1.1, "DMA"),
134+
(2.9, 1.1, "DMA"),
135+
(4.2, 1.1, "DMA"),
136+
]
137+
for x0, w, lab in dma_spec:
138+
r = Rectangle(
139+
width=w,
140+
height=0.42,
141+
fill_color=dma_color,
142+
fill_opacity=0.35,
143+
stroke_color=dma_color,
144+
stroke_width=1.5,
145+
)
146+
r.move_to(RIGHT * (x0 + w / 2) + UP * 1.1)
147+
self.add(r)
148+
t = Text(lab, font_size=11, color=C["fg"], font="Monospace")
149+
t.move_to(r)
150+
self.add(t)
151+
152+
mma_spec = [
153+
(2.2, 1.2, "MMA"),
154+
(3.5, 1.2, "MMA"),
155+
(4.8, 1.2, "MMA"),
156+
]
157+
for x0, w, lab in mma_spec:
158+
r = Rectangle(
159+
width=w,
160+
height=0.42,
161+
fill_color=mma_color,
162+
fill_opacity=0.35,
163+
stroke_color=mma_color,
164+
stroke_width=1.5,
165+
)
166+
r.move_to(RIGHT * (x0 + w / 2) + UP * 0.25)
167+
self.add(r)
168+
t = Text(lab, font_size=11, color=C["fg"], font="Monospace")
169+
t.move_to(r)
170+
self.add(t)
171+
172+
right_axis = Line(
173+
RIGHT * 0.8 + DOWN * 0.3,
174+
RIGHT * 6.5 + DOWN * 0.3,
175+
color=C["dim"],
176+
stroke_width=1.5,
177+
)
178+
right_time = Text("time →", font_size=10, color=C["dim"], font="Monospace")
179+
right_time.next_to(right_axis, RIGHT, buff=0.08)
180+
self.add(right_axis, right_time)
181+
182+
total_right = Text(
183+
"total ≈ max(DMA, MMA) × stages",
184+
font_size=11,
185+
color=C["green"],
186+
font="Monospace",
187+
)
188+
total_right.next_to(right_axis, DOWN, buff=0.15)
189+
self.add(total_right)
190+
191+
# --- Bottom annotations ---
192+
note = Text(
193+
"inthreads.async assigns static roles — overlap is real concurrency, not interleaving",
194+
font_size=11,
195+
color=C["fg3"],
196+
font="Monospace",
197+
)
198+
note.to_edge(DOWN, buff=0.5)
199+
self.add(note)

‎figures/render_all.sh‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ render_static ch04_fig2_sm86_vs_sm90.py SM86vsSM90 fig4_sm86_vs_sm90 "$DOCS/imag
6464

6565
echo "=== Ch05 static ==="
6666
mkdir -p "$DOCS/images/ch05"
67+
render_static ch05_fig1_role_comparison.py RoleComparison fig1_role_comparison "$DOCS/images/ch05"
6768
render_static ch05_fig1_role_split.py Ch05Fig1RoleSplit fig1_role_split "$DOCS/images/ch05"
6869
render_static ch05_fig2_persistent_kernel.py Ch05Fig2PersistentKernel fig2_persistent_kernel "$DOCS/images/ch05"
6970

0 commit comments

Comments
 (0)