6.2.15 · D3GPU Architecture

Worked examples — ROCm - OpenCL alternatives

3,477 words16 min readBack to topic

This page is a drill. The parent topic told you what the work-item model and HIP porting are. Here we run them through every case class — clean divisions, ragged leftovers, degenerate 1-element launches, 2D and 3D grids, and the exam-twist where the naive formula gives the wrong answer.

Before we start, one promise: every symbol is earned. If you have never seen get_global_id, a "work-group", or the index formula, read the first two callouts — they build the whole vocabulary from a single picture.


The scenario matrix

Every launch you will ever configure falls into one of these cells. The examples below hit each one at least once.

# Case class What is special Example
A Clean 1D divide is an exact multiple of Ex 1
B Ragged 1D divide does not divide — need padding + guard Ex 2
C Degenerate input (single element) or empty Ex 3
D 2D NDRange index math on rows × columns Ex 4
E 3D NDRange volume, full formula Ex 5
F Vendor mapping same code, AMD wavefront 64 vs NVIDIA warp 32 Ex 6
G Real-world word problem image blur, choose the launch config Ex 7
H Exam twist the naive G/L answer is wrong; ceiling division Ex 8

Worked examples

Throughout, we use two short names inside kernel code: i is that worker's global id (i.e. int i = get_global_id(0);) and n is the number of real data elements (i.e. n = G_data, the true array length, before any padding). The output array is C (defined above).


Recall drill

Recall Which formula converts (group_id, local_id) back to global_id?

global_id = group_id × local_size + local_id ::: skip past all full squads, then step in by your local seat.

Recall Why do you round UP when computing work-group count?

Because rounding down would leave the leftover partial squad of real elements uncomputed — silent data loss. ::: Use (G + L - 1) / L and guard with if (i < n).

Recall On AMD vs NVIDIA, why does the same source compile but you still change local_size?

HIP/OpenCL hides the ISA, but you match to the physical batch width (wavefront 64 / warp 32) so no lanes sit idle. ::: Same total lanes either way.

Ceiling-division bug in a launch config
launching G/L (floor) instead of ceil(G/L) drops the final partial group — always round up.
Padding workers must be silenced by
an if (get_global_id(0) < n) guard so out-of-bounds lanes do nothing.