Skip to content

Commit d08331b

Browse files
committed
changes to cuda notebooks
1 parent 39c45e2 commit d08331b

9 files changed

Lines changed: 634 additions & 612 deletions

cuda/03_The_Julia_Set.ipynb

Lines changed: 0 additions & 190 deletions
This file was deleted.

cuda/04_Thread-cooperation.ipynb

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"id": "b",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"#undef __noinline__"
11+
]
12+
},
13+
{
14+
"cell_type": "markdown",
15+
"id": "a",
16+
"metadata": {},
17+
"source": [
18+
"# Thread Cooperation - The Grid-Stride Loop\n",
19+
"\n",
20+
"In the previous notebooks each GPU thread handled exactly one array element.\n",
21+
"That only works when you launch exactly as many threads as you have data points.\n",
22+
"\n",
23+
"A more flexible pattern is the **grid-stride loop**: launch a fixed number of threads\n",
24+
"(typically chosen to saturate the GPU) and have each thread walk through the array\n",
25+
"in steps equal to the total number of threads in the grid.\n",
26+
"\n",
27+
"This means:\n",
28+
"- You never need to know N at launch time\n",
29+
"- You can reuse the same launch config for any array size\n",
30+
"- Each thread does a balanced share of the work"
31+
]
32+
},
33+
{
34+
"cell_type": "code",
35+
"execution_count": 2,
36+
"id": "ec24e43e",
37+
"metadata": {},
38+
"outputs": [],
39+
"source": [
40+
"#include <cstdio>\n",
41+
"#include <cmath>\n",
42+
"\n",
43+
"static const int N = 1 << 17; // 131 072 elements\n",
44+
"static const float ALPHA = 2.5f; // scalar for SAXPY\n",
45+
"\n",
46+
"__global__ void saxpy(float alpha, const float *x, float *y, int n) {\n",
47+
" int start = threadIdx.x + blockIdx.x * blockDim.x;\n",
48+
" int step = blockDim.x * gridDim.x; // total threads in the grid\n",
49+
"\n",
50+
" for (int i = start; i < n; i += step)\n",
51+
" y[i] = alpha * x[i] + y[i];\n",
52+
"}"
53+
]
54+
},
55+
{
56+
"cell_type": "markdown",
57+
"id": "9d46b9e7",
58+
"metadata": {},
59+
"source": [
60+
"We launch with 64 blocks × 256 threads = 16 384 threads, but the array has 131 072 elements.\n",
61+
"Each thread therefore handles roughly 8 elements via the loop. The result is verified\n",
62+
"element-by-element on the CPU."
63+
]
64+
},
65+
{
66+
"cell_type": "code",
67+
"execution_count": 3,
68+
"id": "d080db69",
69+
"metadata": {},
70+
"outputs": [
71+
{
72+
"name": "stdout",
73+
"output_type": "stream",
74+
"text": [
75+
"Verified - 131072 elements correct, max error = 0.00e+00\n"
76+
]
77+
}
78+
],
79+
"source": [
80+
"// Allocate, fill, launch, verifi\n",
81+
"float *h_x = (float*)malloc(N * sizeof(float));\n",
82+
"float *h_y = (float*)malloc(N * sizeof(float));\n",
83+
"float *h_ref = (float*)malloc(N * sizeof(float));\n",
84+
"\n",
85+
"for (int i = 0; i < N; i++) {\n",
86+
" h_x[i] = sinf((float)i);\n",
87+
" h_y[i] = cosf((float)i);\n",
88+
" h_ref[i] = ALPHA * h_x[i] + h_y[i]; // CPU reference\n",
89+
"}\n",
90+
"\n",
91+
"float *d_x, *d_y;\n",
92+
"cudaMalloc(&d_x, N * sizeof(float));\n",
93+
"cudaMalloc(&d_y, N * sizeof(float));\n",
94+
"cudaMemcpy(d_x, h_x, N * sizeof(float), cudaMemcpyHostToDevice);\n",
95+
"cudaMemcpy(d_y, h_y, N * sizeof(float), cudaMemcpyHostToDevice);\n",
96+
"\n",
97+
"// 256 threads/block, 64 blocks — 16 384 total threads for 131 072 elements\n",
98+
"saxpy<<<64, 256>>>(ALPHA, d_x, d_y, N);\n",
99+
"\n",
100+
"cudaMemcpy(h_y, d_y, N * sizeof(float), cudaMemcpyDeviceToHost);\n",
101+
"\n",
102+
"// Verify (allow small floating-point tolerance)\n",
103+
"int errors = 0;\n",
104+
"float max_err = 0.f;\n",
105+
"for (int i = 0; i < N; i++) {\n",
106+
" float err = fabsf(h_y[i] - h_ref[i]);\n",
107+
" if (err > 1e-4f) errors++;\n",
108+
" if (err > max_err) max_err = err;\n",
109+
"}\n",
110+
"\n",
111+
"if (errors == 0)\n",
112+
" printf(\"Verified - %d elements correct, max error = %.2e\\n\", N, max_err);\n",
113+
"else\n",
114+
" printf(\"FAIL - %d mismatches\\n\", errors);\n",
115+
"\n",
116+
"cudaFree(d_x); cudaFree(d_y);\n",
117+
"free(h_x); free(h_y); free(h_ref);"
118+
]
119+
}
120+
],
121+
"metadata": {
122+
"kernelspec": {
123+
"display_name": "C++23 CUDA",
124+
"language": "cpp",
125+
"name": "xcpp23-cuda"
126+
},
127+
"language_info": {
128+
"codemirror_mode": "text/x-c++src",
129+
"file_extension": ".cpp",
130+
"mimetype": "text/x-c++src",
131+
"name": "CUDA",
132+
"nbconvert_exporter": "",
133+
"pygments_lexer": "",
134+
"version": "cxx23"
135+
}
136+
},
137+
"nbformat": 4,
138+
"nbformat_minor": 5
139+
}

cuda/05_The_Julia_Set.ipynb

Lines changed: 192 additions & 0 deletions
Large diffs are not rendered by default.

cuda/05_Thread-cooperation.ipynb

Lines changed: 0 additions & 136 deletions
This file was deleted.

cuda/06_GPU-ripple.ipynb

Lines changed: 25 additions & 22 deletions
Large diffs are not rendered by default.

cuda/07_Dot-product.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@
7474
"source": [
7575
"__global__ void dot_product(float *a, float *b, float *partial) {\n",
7676
" __shared__ float tile[THREADS]; // one float per thread, on-chip\n",
77+
" float running = 0.0f;\n",
7778
"\n",
7879
" int tid = threadIdx.x + blockIdx.x * blockDim.x;\n",
7980
" int stride = blockDim.x * gridDim.x;\n",
8081
" int lane = threadIdx.x;\n",
8182
"\n",
8283
" // Phase 1: each thread accumulates its share of element-wise products\n",
83-
" float running = 0.0f;\n",
8484
" for (int i = tid; i < N; i += stride)\n",
8585
" running += a[i] * b[i];\n",
8686
" tile[lane] = running;\n",

0 commit comments

Comments
 (0)