The 'each thread writes its coordinates to a buffer' pattern
Metal doesn't have GPU printf. Instead, the convention is: each thread writes its identity into a device buffer, and after the command buffer completes, the CPU reads the buffer and prints. Verbose, but it forces the round-trip you'll need for every real workload anyway.
Two files: hello.metal (the kernel) and hello_host.swift (the launch driver + result printer). Build with metal + metallib + swiftc, run as a single binary.