Skip to content

Commit a5cdff9

Browse files
committed
Add parallelism lecture
1 parent ee683d8 commit a5cdff9

8 files changed

Lines changed: 1314 additions & 4 deletions

File tree

.github/workflows/action.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ jobs:
1717
runs-on: ubuntu-latest
1818
steps:
1919
- uses: actions/checkout@v4
20+
- name: Install dependencies
21+
run: sudo apt-get update && sudo apt-get install -y libtbb-dev
2022
- name: Check that all snippets compile
2123
run: |
2224
pip install pipenv
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"version": 0,
3+
"shared": {
4+
"background": "rgb(10,20,30)",
5+
"range": [
6+
0,
7+
null
8+
],
9+
"size": {
10+
"x": 1920,
11+
"y": 1080
12+
},
13+
"audioOffset": 0
14+
},
15+
"preview": {
16+
"fps": 30,
17+
"resolutionScale": 1
18+
},
19+
"rendering": {
20+
"fps": 60,
21+
"resolutionScale": 1,
22+
"colorSpace": "srgb",
23+
"exporter": {
24+
"name": "@motion-canvas/core/image-sequence",
25+
"options": {
26+
"fileType": "image/png",
27+
"quality": 100,
28+
"groupByScene": false
29+
}
30+
}
31+
}
32+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { makeProject } from '@motion-canvas/core';
2+
3+
import '../../global.css';
4+
5+
import code from './scenes/code?scene';
6+
7+
export default makeProject({
8+
scenes: [code],
9+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"version": 0,
3+
"timeEvents": [],
4+
"seed": 3165236554
5+
}
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
/// <reference types="vite/client" />
2+
import { createRef } from '@motion-canvas/core/lib/utils';
3+
import { makeScene2D, Code, LezerHighlighter, lines } from '@motion-canvas/2d';
4+
import { all, waitFor, waitUntil } from '@motion-canvas/core/lib/flow';
5+
import { ThreadGenerator } from '@motion-canvas/core/lib/threading';
6+
import { DEFAULT } from '@motion-canvas/core/lib/signals';
7+
import { BBox, Vector2 } from '@motion-canvas/core/lib/types';
8+
import { tags } from '@lezer/highlight';
9+
import { HighlightStyle } from '@codemirror/language';
10+
11+
import { parser as parser_css } from '@lezer/css';
12+
import { parser as parser_cpp } from '@lezer/cpp';
13+
14+
import blockingCode from '@lectures/parallelism.md?snippet=parallelism_blocking/main.cpp';
15+
import asyncCode from '@lectures/parallelism.md?snippet=parallelism_async/main.cpp';
16+
import algorithmsSequentialCode from '@lectures/parallelism.md?snippet=parallelism_algorithms/main_sequential.cpp';
17+
import algorithmsParallelCode from '@lectures/parallelism.md?snippet=parallelism_algorithms/main_parallel.cpp';
18+
import tbbCode from '@lectures/parallelism.md?snippet=parallelism_algorithms/main_tbb.cpp';
19+
import jthreadCode from '@lectures/parallelism.md?snippet=parallelism_jthread/main.cpp';
20+
import threadpool17Code from '@lectures/parallelism.md?snippet=parallelism_threadpool_17/main.cpp';
21+
22+
import { MyStyle } from '../../styles';
23+
24+
const CppHighlighter = new LezerHighlighter(parser_cpp, MyStyle);
25+
26+
function* centerOn(
27+
codeRef: Code,
28+
selectionInput: any,
29+
duration: number,
30+
targetFontSize?: number,
31+
): ThreadGenerator {
32+
// We only care about the bounding box of the new selection
33+
let bboxes: BBox[] = [];
34+
if (selectionInput !== DEFAULT) {
35+
// getSelectionBBox computes the bounds for the given selection using the CURRENT layout state.
36+
// We do NOT need to set the selection signal to measure it!
37+
bboxes = codeRef.getSelectionBBox(selectionInput);
38+
}
39+
40+
if (bboxes.length === 0) {
41+
const fallbackAnimations: ThreadGenerator[] = [
42+
codeRef.selection(selectionInput, duration),
43+
codeRef.y(0, duration)
44+
];
45+
if (targetFontSize !== undefined) {
46+
fallbackAnimations.push(codeRef.fontSize(targetFontSize, duration));
47+
}
48+
yield* all(...fallbackAnimations);
49+
return;
50+
}
51+
52+
let minY = Infinity;
53+
let maxY = -Infinity;
54+
55+
for (const bbox of bboxes) {
56+
if (bbox.top !== undefined && !isNaN(bbox.top)) minY = Math.min(minY, bbox.top);
57+
if (bbox.bottom !== undefined && !isNaN(bbox.bottom)) maxY = Math.max(maxY, bbox.bottom);
58+
}
59+
60+
let centerY = (minY + maxY) / 2;
61+
if (!isFinite(centerY) || isNaN(centerY)) {
62+
centerY = 0;
63+
}
64+
65+
// Scale the calculated target offset based on how the font size will change.
66+
// This perfectly centers it without needing to pollute the animation timeline
67+
// with synchronous layout mutations.
68+
if (targetFontSize !== undefined) {
69+
const currentFontSize = codeRef.fontSize();
70+
if (currentFontSize > 0) {
71+
centerY = centerY * (targetFontSize / currentFontSize);
72+
}
73+
}
74+
75+
const animations: ThreadGenerator[] = [
76+
codeRef.selection(selectionInput, duration),
77+
codeRef.y(-centerY, duration)
78+
];
79+
80+
if (targetFontSize !== undefined) {
81+
animations.push(codeRef.fontSize(targetFontSize, duration));
82+
}
83+
84+
yield* all(...animations);
85+
}
86+
87+
export default makeScene2D(function* (view) {
88+
const codeRef = createRef<Code>();
89+
90+
yield view.add(<Code
91+
ref={codeRef}
92+
fontSize={20}
93+
fontFamily={'Fira Mono'}
94+
fontWeight={500}
95+
offsetX={-1}
96+
x={-800}
97+
y={0}
98+
highlighter={CppHighlighter}
99+
/>);
100+
101+
const duration = 1.0;
102+
103+
// 0. Blocking
104+
yield* codeRef().code(blockingCode, 0);
105+
yield* centerOn(codeRef(), DEFAULT, 0, 20);
106+
yield* waitFor(duration);
107+
108+
// Focus on loading an image
109+
yield* centerOn(codeRef(), [lines(8, 10)], duration, 30);
110+
yield* waitFor(duration);
111+
yield* centerOn(codeRef(), [lines(12, 16), lines(6, 11)], duration, 30);
112+
yield* waitFor(duration);
113+
yield* centerOn(codeRef(), lines(18, 28), duration, 30);
114+
yield* waitFor(duration);
115+
yield* centerOn(codeRef(), DEFAULT, duration, 20);
116+
yield* waitFor(duration);
117+
118+
// 1. std::async Background Task
119+
yield* all(
120+
codeRef().code(asyncCode, duration),
121+
centerOn(codeRef(), DEFAULT, duration, 14)
122+
);
123+
yield* waitFor(duration);
124+
125+
// Focus on loading an image
126+
yield* centerOn(codeRef(), lines(21, 38), duration, 30);
127+
yield* waitFor(duration);
128+
129+
// Focus on std::async
130+
yield* centerOn(codeRef(), lines(42, 45), duration, 30);
131+
yield* waitFor(duration);
132+
133+
// Focus on future polling
134+
yield* centerOn(codeRef(), lines(46, 54), duration, 30);
135+
yield* waitFor(duration);
136+
137+
// Focus on getting
138+
yield* centerOn(codeRef(), lines(55, 58), duration, 30);
139+
yield* waitFor(duration);
140+
141+
yield* centerOn(codeRef(), lines(44, 45), duration, 40);
142+
yield* waitFor(duration);
143+
144+
// 2. Parallel Algorithms
145+
yield* centerOn(codeRef(), DEFAULT, duration, 18);
146+
yield* codeRef().code(algorithmsSequentialCode, duration);
147+
yield* waitFor(duration);
148+
149+
yield* centerOn(codeRef(), lines(16, 22), duration, 30);
150+
yield* waitFor(duration);
151+
152+
yield* centerOn(codeRef(), lines(8, 10), duration, 30);
153+
yield* waitFor(duration);
154+
155+
yield* centerOn(codeRef(), lines(12, 14), duration, 30);
156+
yield* waitFor(duration);
157+
158+
yield* centerOn(codeRef(), lines(26, 28), duration, 30);
159+
yield* waitFor(duration);
160+
161+
yield* centerOn(codeRef(), lines(32, 35), duration, 30);
162+
yield* waitFor(duration);
163+
164+
yield* centerOn(codeRef(), lines(29, 39), duration, 30);
165+
yield* waitFor(duration);
166+
167+
// 2. Parallel Algorithms
168+
yield* centerOn(codeRef(), DEFAULT, duration, 18);
169+
yield* codeRef().code(algorithmsParallelCode, duration);
170+
yield* waitFor(duration);
171+
172+
yield* centerOn(codeRef(), lines(32, 37), duration, 30);
173+
yield* waitFor(duration);
174+
175+
yield* centerOn(codeRef(), lines(2, 2), duration, 30);
176+
yield* waitFor(duration);
177+
178+
yield* centerOn(codeRef(), lines(29, 41), duration, 30);
179+
yield* waitFor(duration);
180+
181+
yield* centerOn(codeRef(), DEFAULT, duration, 17);
182+
yield* waitFor(duration);
183+
184+
// 3. Raw TBB
185+
yield* codeRef().code(tbbCode, duration);
186+
yield* waitFor(duration);
187+
188+
yield* centerOn(codeRef(), lines(34, 41), duration, 30);
189+
yield* waitFor(duration);
190+
191+
yield* centerOn(codeRef(), DEFAULT, duration, 20);
192+
yield* waitFor(duration);
193+
194+
// 4. Thread Pool jthread
195+
yield* codeRef().code(jthreadCode, duration);
196+
yield* waitFor(duration);
197+
198+
// Focus constructor and submit
199+
yield* centerOn(codeRef(), lines(22, 42), duration, 22);
200+
yield* waitFor(duration);
201+
202+
yield* centerOn(codeRef(), DEFAULT, duration, 15);
203+
yield* waitFor(duration);
204+
205+
// Focus on the locking and cv in ProcessImages
206+
yield* centerOn(codeRef(), lines(55, 61), duration, 22);
207+
yield* waitFor(duration);
208+
209+
yield* centerOn(codeRef(), DEFAULT, duration, 15);
210+
yield* waitFor(duration);
211+
212+
// 5. Thread Pool C++17 Equivalent (Morphing from C++20)
213+
// Morph the C++20 thread pool cleanly into the C++17 one!
214+
yield* codeRef().code(threadpool17Code, duration);
215+
yield* waitFor(duration);
216+
217+
// Focus on shutdown logic
218+
yield* centerOn(codeRef(), lines(41, 61), duration, 22);
219+
yield* waitFor(duration);
220+
221+
yield* centerOn(codeRef(), DEFAULT, duration, 15);
222+
yield* waitFor(duration);
223+
224+
// Focus CV condition
225+
yield* centerOn(codeRef(), lines(71, 77), duration, 25);
226+
yield* waitFor(duration);
227+
228+
// Focus on the data members changing
229+
yield* centerOn(codeRef(), lines(100, 105), duration, 22);
230+
yield* waitFor(duration);
231+
232+
// Finally wrap it out
233+
yield* centerOn(codeRef(), DEFAULT, duration, 20);
234+
yield* waitFor(duration);
235+
236+
});

animation/projects/vite.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export default defineConfig({
1414
plugins: [
1515
motionCanvas({
1616
project: [
17+
'./src/parallelism/project.ts',
1718
'./src/dummy/project.ts',
1819
]
1920
}),

0 commit comments

Comments
 (0)