A kernel is a function that runs on the GPU. It is marked __global__, called from host code with the <<<>>> launch syntax, and executed once per thread by every thread in the grid you asked for.
__global__ void scale(float *a, float k) { int i = blockIdx.x * blockDim.x + threadIdx.x; a[i] *= k; } scale<<<64, 256>>>(d_a, 2.0f); // 64 blocks x 256 threads = 16384 threads
There is no loop in the kernel body. The loop is the launch itself, and each thread runs one iteration of it. This inversion is the main mental shift coming from OpenMP, where you keep the loop and annotate it.
Kernels have some hard restrictions:
void. Results come back through pointers to device memory.
A __device__ function is callable only from device code and is normally inlined. A __host__ __device__ function is compiled twice, once for each side, which is how small utility functions get shared between CPU and GPU code.