PTX programming labs

Extract all files into one directory. Open x64 Developer PowerShell for Visual Studio
with the NVIDIA CUDA Toolkit on PATH, and switch to that directory.

The hand-written modules use PTX 7.0 and target sm_80. The commands below choose
compute_120 and sm_120 for an RTX 5060 Laptop GPU. On a different GPU, use the
matching target supported by your toolkit. The async-copy and matrix labs need
compute capability 8.0 or newer.

1. Emit PTX from a CUDA C++ kernel, build the host runner, and run both versions.
   nvcc -ptx -arch=compute_120 increment.cu -o generated.ptx
   nvcc -std=c++17 run.cpp -lcuda -o run.exe
   .\run.exe generated.ptx increment
   .\run.exe increment.ptx increment

2. Assemble the handwritten kernel, run the binary, and inspect native code.
   ptxas -arch=sm_120 -v increment.ptx -o increment.cubin
   .\run.exe increment.cubin increment
   cuobjdump -sass increment.cubin

3. Compare register exchange within a warp and shared memory across two warps.
   .\run.exe pair.ptx pair
   .\run.exe mirror.ptx mirror
   compute-sanitizer --tool memcheck .\run.exe mirror.ptx mirror
   compute-sanitizer --tool racecheck .\run.exe mirror.ptx mirror
   compute-sanitizer --tool synccheck .\run.exe mirror.ptx mirror

4. Run a warp-level matrix multiply with FP16 inputs and FP32 accumulators.
   nvcc -arch=sm_120 mma.cu -o mma.exe
   .\mma.exe

For each of the first three kernels the runner compares all results and an output
guard region with a CPU reference for nine sizes, including zero and a partial
block. The matrix lab checks all 128 results. The runner is for correctness;
allocations and copies occur in each test case.
