What CUDA asks of you
Writing a fused kernel in CUDA means reasoning at the level of individual threads, and the obligations are substantial.
You decide how many threads run and how they are grouped into blocks. You compute, for each thread, which elements of which tensor it is responsible for, from its indices. You allocate shared memory explicitly and copy data into it. You insert synchronisation barriers wherever threads must agree on state, and both missing and unnecessary barriers are bugs, one producing wrong answers and the other producing slow ones.
Then the performance work begins. Memory accesses must be coalesced so that adjacent threads read adjacent addresses, or bandwidth collapses. Shared memory accesses must avoid bank conflicts. Register usage must stay low enough that enough blocks fit on a multiprocessor to hide latency. Tensor cores must be fed through specific data layouts.
All of that is learnable and the catalogue's CUDA path covers it. The problem is not difficulty; it is that the cost is high enough that a team with a promising fusion idea usually does not try it.

