Every "kernel" this track has discussed so far (01/02) was reasoned about abstractly, as a black box that reads memory, computes, and writes memory. A real GPU kernel isn't one sequential black box at all — it's launched as a grid of many thousands of independent threads running (conceptually) all at once, and mapping "one operation per array element" onto "one thread per array element" is the very first thing any real CUDA or Triton kernel has to work out, correctly, before it computes anything.
Implement compute_grid_size(n_elements, threads_per_block), global_thread_index(block_idx, thread_idx, threads_per_block), and simulate_kernel_launch(n_elements, threads_per_block) — the exact indexing scheme real CUDA and Triton kernels use to map a grid of threads onto an array, including the bounds-checking a non-exact-multiple array size requires.
compute_grid_size rounds up (ceiling division) — a partially-full last block still needs to be launched in full.global_thread_index(block_idx, thread_idx, threads_per_block) returns block_idx * threads_per_block + thread_idx.simulate_kernel_launch marks a position covered only when its global_thread_index is strictly less than n_elements — some threads in the last block will compute an index past the real array and must be skipped, exactly as a real kernel's bounds check does.0 to n_elements - 1 ends up covered exactly once.Open one at a time. Each gives away a little more than the last.
-(-n_elements // threads_per_block) is a standard integer trick for ceiling division without importing math.ceil — negate, floor-divide, negate again.
When n_elements isn't an exact multiple of threads_per_block, the last block still launches with a full threads_per_block threads — some of them compute a global_thread_index >= n_elements and must do nothing, which is exactly what the if gid < n_elements check inside simulate_kernel_launch is for.
No results yet
Run your code to check it against the examples, or submit to run every test.