๐ง ํ์ ์์ฌ: ์ฒซ ๋ฒ์งธ ์ฌ๋ก
๊ฐ์
์ด๋ฒ ํผ์ฆ์์๋ ํฌ๋์๊ฐ ๋ฐ์ํ๋ GPU ํ๋ก๊ทธ๋จ์ด ์ฃผ์ด์ง๋๋ค. ์์ค ์ฝ๋๋ฅผ ๋ณด์ง ์๊ณ (cuda-gdb) ๋๋ฒ๊น
๋๊ตฌ๋ง์ผ๋ก ๋ฌธ์ ๋ฅผ ์ฐพ์๋ด์ผ ํฉ๋๋ค. ๋๋ฒ๊น
์คํฌ์ ๋ฐํํด ๋ฏธ์คํฐ๋ฆฌ๋ฅผ ํ์ด๋ณด์ธ์!
์ฌ์ ์ค๋น: Mojo GPU ๋๋ฒ๊น ์ ํต์ฌ์ ๋จผ์ ์๋ฃํด์ CUDA-GDB ์ค์ ๊ณผ ๊ธฐ๋ณธ ๋๋ฒ๊น ๋ช ๋ น์ด๋ฅผ ์ตํ๋์ธ์. ์๋ ๋ช ๋ น์ ์คํํ๋์ง ํ์ธํ์ธ์:
pixi run -e nvidia setup-cuda-gdb
์ด ๋ช ๋ น์ ์์คํ ์ CUDA ์ค์น๋ฅผ ์๋์ผ๋ก ๊ฐ์งํ๊ณ GPU ๋๋ฒ๊น ์ ํ์ํ ๋งํฌ๋ฅผ ์ค์ ํฉ๋๋ค.
ํต์ฌ ๊ฐ๋
์ด๋ฒ ๋๋ฒ๊น ์ฑ๋ฆฐ์ง์์ ๋ฐฐ์ธ ๋ด์ฉ:
- ์ฒด๊ณ์ ์ธ ๋๋ฒ๊น : ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋จ์ ์ผ์ ๊ทผ๋ณธ ์์ธ ์ฐพ๊ธฐ
- ์ค๋ฅ ๋ถ์: ํฌ๋์ ๋ฉ์์ง์ ์คํ ์ถ์ (stack trace) ํด์ํ๊ธฐ
- ๊ฐ์ค ์๋ฆฝ: ๋ฌธ์ ์ ๋ํ ํฉ๋ฆฌ์ ์ธ ์ถ์ธก ์ธ์ฐ๊ธฐ
- ๋๋ฒ๊น ์ํฌํ๋ก์ฐ: ๋จ๊ณ๋ณ ์กฐ์ฌ ๊ณผ์ ์ตํ๊ธฐ
์ฝ๋ ์คํ
๋จผ์ ์ ์ฒด ์ฝ๋๋ฅผ ๋ณด์ง ์๊ณ ์ปค๋๋ง ์ดํด๋ด ์๋ค:
fn add_10(
output: UnsafePointer[Scalar[dtype], MutAnyOrigin],
a: UnsafePointer[Scalar[dtype], MutAnyOrigin],
):
i = thread_idx.x
output[i] = a[i] + 10.0
๋ฒ๊ทธ๋ฅผ ์ง์ ๊ฒฝํํ๋ ค๋ฉด ํฐ๋ฏธ๋์์ ๋ค์ ๋ช
๋ น์ ์คํํ์ธ์ (pixi ์ ์ฉ):
pixi run -e nvidia p09 --first-case
ํ๋ก๊ทธ๋จ์ด ํฌ๋์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ถ๋ ฅ์ด ๋ํ๋ฉ๋๋ค:
First Case: Try to identify what's wrong without looking at the code!
stack trace was not collected. Enable stack trace collection with environment variable `MOJO_ENABLE_STACK_TRACE_ON_ERROR`
Unhandled exception caught during execution: At open-source/max/mojo/stdlib/stdlib/gpu/host/device_context.mojo:2082:17: CUDA call failed: CUDA_ERROR_INVALID_IMAGE (device kernel image is invalid)
To get more accurate error information, set MODULAR_DEVICE_CONTEXT_SYNC_MODE=true.
/home/ubuntu/workspace/mojo-gpu-puzzles/.pixi/envs/nvidia/bin/mojo: error: execution exited with a non-zero result: 1
๊ณผ์ : ํ์ ์์ฌ
๋์ : ์ฝ๋๋ฅผ ๋ณด์ง ์์ ์ํ์์, ์ด ํฌ๋์๋ฅผ ์กฐ์ฌํ๊ธฐ ์ํ ๋๋ฒ๊น ์ ๋ต์ ๋ฌด์์ผ๊น์?
๋ค์ ๋ช ๋ น์ผ๋ก ์์ํด ๋ณด์ธ์:
pixi run -e nvidia mojo debug --cuda-gdb --break-on-launch problems/p09/p09.mojo --first-case
ํ
- ํฌ๋์ ๋ฉ์์ง๋ฅผ ๊ผผ๊ผผํ ์ฝ๊ธฐ -
CUDA_ERROR_ILLEGAL_ADDRESS๋ GPU๊ฐ ์๋ชป๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ๋ ค ํ๋ค๋ ๋ป์ ๋๋ค - ๋ธ๋ ์ดํฌํฌ์ธํธ ์ ๋ณด ํ์ธ - CUDA-GDB๊ฐ ๋ฉ์ถ ๋ ํ์๋๋ ํจ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ดํด๋ณด์ธ์
- ๋ชจ๋ ํฌ์ธํฐ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๊ฒ์ฌ -
print๋ก ๊ฐ ํฌ์ธํฐ ํ๋ผ๋ฏธํฐ๋ฅผ ํ์ธํ์ธ์ - ์์ํ ์ฃผ์ ์ฐพ๊ธฐ - ์ ํจํ GPU ์ฃผ์๋ ๋ณดํต ํฐ 16์ง์์
๋๋ค (
0x0์ ๋ฌด์์ ์๋ฏธํ ๊น์?) - ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํ ์คํธ - ๊ฐ ํฌ์ธํฐ๋ก ๋ฐ์ดํฐ์ ์ ๊ทผํด์ ์ด๋ ๊ฒ์ด ์คํจํ๋์ง ํ์ธํ์ธ์
- ์ฒด๊ณ์ ์ผ๋ก ์ ๊ทผ - ํ์ ์ฒ๋ผ ์ฆ๊ฑฐ๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉฐ ์ฆ์์์ ๊ทผ๋ณธ ์์ธ๊น์ง ์ถ์ ํ์ธ์
- ์ ํจํ ํจํด๊ณผ ๊ทธ๋ ์ง ์์ ํจํด ๋น๊ต - ํ ํฌ์ธํฐ๊ฐ ์๋ํ๊ณ ๋ค๋ฅธ ๊ฑด ์ ๋๋ค๋ฉด, ๋ฌธ์ ๊ฐ ์๋ ์ชฝ์ ์ง์คํ์ธ์
๐ก ์กฐ์ฌ ๊ณผ์ ๊ณผ ํด๊ฒฐ์ฑ
CUDA-GDB๋ก ๋จ๊ณ๋ณ ์กฐ์ฌ
๋๋ฒ๊ฑฐ ์คํ
pixi run -e nvidia mojo debug --cuda-gdb --break-on-launch problems/p09/p09.mojo --first-case
๋ธ๋ ์ดํฌํฌ์ธํธ ์ ๋ณด ํ์ธ
CUDA-GDB๊ฐ ๋ฉ์ถ๋ฉด ๋ฐ๋ก ์ ์ฉํ ๋จ์๊ฐ ๋ํ๋ฉ๋๋ค:
(cuda-gdb) run
CUDA thread hit breakpoint, p09_add_10_... (output=0x302000000, a=0x0)
at /home/ubuntu/workspace/mojo-gpu-puzzles/problems/p09/p09.mojo:31
31 i = thread_idx.x
๐ ์ฒซ ๋ฒ์งธ ๋จ์: ํจ์ ์๊ทธ๋์ฒ์ (output=0x302000000, a=0x0)์ด ๋ณด์
๋๋ค
output์ ์ ํจํ GPU ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋คa๋0x0- null ํฌ์ธํฐ์ ๋๋ค!
์ฒด๊ณ์ ์ธ ๋ณ์ ๊ฒ์ฌ
(cuda-gdb) next
32 output[i] = a[i] + 10.0
(cuda-gdb) print i
$1 = 0
(cuda-gdb) print output
$2 = (!pop.scalar<f32> * @register) 0x302000000
(cuda-gdb) print a
$3 = (!pop.scalar<f32> * @register) 0x0
์ฆ๊ฑฐ ์์ง:
- โ
์ค๋ ๋ ์ธ๋ฑ์ค
i=0์ ์ ํจํฉ๋๋ค - โ
๊ฒฐ๊ณผ ํฌ์ธํฐ
0x302000000์ ์ฌ๋ฐ๋ฅธ GPU ์ฃผ์์ ๋๋ค - โ ์
๋ ฅ ํฌ์ธํฐ
0x0์ null์ ๋๋ค
๋ฌธ์ ํ์ธ
(cuda-gdb) print a[i]
Cannot access memory at address 0x0
๊ฒฐ์ ์ ์ฆ๊ฑฐ: null ์ฃผ์์ ๋ฉ๋ชจ๋ฆฌ์ ์ ๊ทผํ ์ ์์ต๋๋ค - ๋ฐ๋ก ์ด๊ฒ์ด ํฌ๋์์ ์์ธ์ ๋๋ค!
๊ทผ๋ณธ ์์ธ ๋ถ์
๋ฌธ์ ์ : ์ด์ --first-crash์ ์ฝ๋๋ฅผ ๋ณด๋ฉด, ํธ์คํธ ์ฝ๋๊ฐ GPU ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๋๋ก ํ ๋นํ์ง ์๊ณ null ํฌ์ธํฐ๋ฅผ ๋ง๋ค๊ณ ์์ต๋๋ค:
input_buf = ctx.enqueue_create_buffer[dtype](0) # 0๊ฐ์ ์์๋ฅผ ๊ฐ์ง `DeviceBuffer`๋ฅผ ์์ฑํฉ๋๋ค. ์์๊ฐ 0๊ฐ์ด๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ ๋น๋์ง ์์ NULL ํฌ์ธํฐ๊ฐ ๋ฉ๋๋ค!
์ ํฌ๋์๊ฐ ๋ฐ์ํ๋๊ฐ:
ctx.enqueue_create_buffer[dtype](0)์ 0๊ฐ ์์๋ฅผ ๊ฐ์งDeviceBuffer๋ฅผ ์์ฑํฉ๋๋ค.- ํ ๋นํ ์์๊ฐ ์์ผ๋ null ํฌ์ธํฐ๋ฅผ ๋ฐํํฉ๋๋ค.
- ์ด null ํฌ์ธํฐ๊ฐ GPU ์ปค๋๋ก ์ ๋ฌ๋ฉ๋๋ค.
- ์ปค๋์ด
a[i]์ ์ ๊ทผํ๋ ค ํ ๋ null์ ์ญ์ฐธ์กฐ โCUDA_ERROR_ILLEGAL_ADDRESS
์์ ๋ฐฉ๋ฒ
Null ํฌ์ธํฐ ์์ฑ์ ์ ์ ํ ๋ฒํผ ํ ๋น์ผ๋ก ๊ต์ฒดํฉ๋๋ค:
# ์๋ชป๋ ๋ฐฉ๋ฒ: Null ํฌ์ธํฐ ์์ฑ
input_buf = ctx.enqueue_create_buffer[dtype](0)
# ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ: ์์ ํ ์ฒ๋ฆฌ๋ฅผ ์ํด ์ค์ GPU ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๊ณ ์ด๊ธฐํ
input_buf = ctx.enqueue_create_buffer[dtype](SIZE)
input_buf.enqueue_fill(0)
ํต์ฌ ๋๋ฒ๊น ๊ตํ
ํจํด ์ธ์:
0x0์ฃผ์๋ ํญ์ null ํฌ์ธํฐ์ ๋๋ค- ์ ํจํ GPU ์ฃผ์๋ ํฐ 16์ง์์
๋๋ค (์:
0x302000000)
๋๋ฒ๊น ์ ๋ต:
- ํฌ๋์ ๋ฉ์์ง ์ฝ๊ธฐ - ๋์ฒด๋ก ๋ฌธ์ ์ ํ์ ๋ํ ํํธ๋ฅผ ์ค๋๋ค
- ํจ์ ํ๋ผ๋ฏธํฐ ํ์ธ - CUDA-GDB๊ฐ ๋ธ๋ ์ดํฌํฌ์ธํธ ์ง์ ์ ๋ณด์ฌ์ค๋๋ค
- ๋ชจ๋ ํฌ์ธํฐ ๊ฒ์ฌ - ์ฃผ์๋ฅผ ๋น๊ตํด์ null์ด๋ ์๋ชป๋ ๊ฒ์ ์ฐพ์ต๋๋ค
- ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ํ ์คํธ - ์์ํ ํฌ์ธํฐ๋ฅผ ์ญ์ฐธ์กฐํด ๋ด ๋๋ค
- ํ ๋น ์ง์ ๊น์ง ์ถ์ - ๋ฌธ์ ์ ํฌ์ธํฐ๊ฐ ์ด๋์ ์์ฑ๋์๋์ง ์ฐพ์ต๋๋ค
๐ก ํต์ฌ ํต์ฐฐ: ์ด๋ฐ ์ ํ์ null ํฌ์ธํฐ ๋ฒ๊ทธ๋ GPU ํ๋ก๊ทธ๋๋ฐ์์ ๋งค์ฐ ํํฉ๋๋ค. ์ฌ๊ธฐ์ ๋ฐฐ์ด ์ฒด๊ณ์ ์ธ CUDA-GDB ์กฐ์ฌ ๋ฐฉ๋ฒ์ ๋ค๋ฅธ ๋ง์ GPU ๋ฉ๋ชจ๋ฆฌ ๋ฌธ์ , ๊ฒฝ์ ์ํ, ์ปค๋ ํฌ๋์๋ฅผ ๋๋ฒ๊น ํ ๋๋ ๊ทธ๋๋ก ์ ์ฉ๋ฉ๋๋ค.
๋ค์ ๋จ๊ณ: ํฌ๋์์์ ์กฐ์ฉํ ๋ฒ๊ทธ๋ก
ํฌ๋์ ๋๋ฒ๊น ์ ์ตํ์ต๋๋ค! ์ด์ ํ ์ ์์ต๋๋ค:
- ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋จ์๋ก GPU ํฌ๋์๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ์กฐ์ฌ
- ํฌ์ธํฐ ์ฃผ์ ๊ฒ์ฌ๋ฅผ ํตํด null ํฌ์ธํฐ ๋ฒ๊ทธ ์๋ณ
- ๋ฉ๋ชจ๋ฆฌ ๊ด๋ จ ๋๋ฒ๊น ์ CUDA-GDB๋ฅผ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉ
๋ค์ ๋์ : ํ์ ์์ฌ: ๋ ๋ฒ์งธ ์ฌ๋ก
๊ทธ๋ฐ๋ฐ ํ๋ก๊ทธ๋จ์ด ํฌ๋์ํ์ง ์๋๋ค๋ฉด์? ์๋ฒฝํ๊ฒ ์คํ๋์ง๋ง ์๋ชป๋ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค๋ฉด?
๋ ๋ฒ์งธ ์ฌ๋ก๋ ์ ํ ๋ค๋ฅธ ์ ํ์ ๋๋ฒ๊น ๋์ ์ ๋๋ค:
- ๊ธธ์ก์ด๊ฐ ๋์ด์ค ํฌ๋์ ๋ฉ์์ง๊ฐ ์์ต๋๋ค
- ์กฐ์ฌํ ๋๋ ทํ ํฌ์ธํฐ ๋ฌธ์ ๋ ์์ต๋๋ค
- ๋ฌธ์ ๋ฅผ ๊ฐ๋ฆฌํค๋ ์คํ ์ถ์ ๋ ์์ต๋๋ค
- ์ฒด๊ณ์ ์ธ ์กฐ์ฌ๊ฐ ํ์ํ ์๋ชป๋ ๊ฒฐ๊ณผ๋ง ์์ต๋๋ค
์๋กญ๊ฒ ์ตํ๊ฒ ๋ ์คํฌ:
- ๋ก์ง ๋ฒ๊ทธ ํ์ง - ํฌ๋์ ์์ด ์๊ณ ๋ฆฌ์ฆ ์ค๋ฅ ์ฐพ๊ธฐ
- ํจํด ๋ถ์ - ์๋ชป๋ ์ถ๋ ฅ์์ ๊ทผ๋ณธ ์์ธ๊น์ง ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ๊ธฐ
- ์คํ ํ๋ฆ ๋๋ฒ๊น - ์ต์ ํ ๋๋ฌธ์ ๋ณ์ ๊ฒ์ฌ๊ฐ ์ ๋ ๋ ๋์ฒํ๊ธฐ
์ฌ๊ธฐ์ ๋ฐฐ์ด ์ฒด๊ณ์ ์ธ ์กฐ์ฌ ๋ฐฉ๋ฒ - ๋จ์ ์ฝ๊ธฐ, ๊ฐ์ค ์ธ์ฐ๊ธฐ, ์ฒด๊ณ์ ์ผ๋ก ํ ์คํธํ๊ธฐ - ์ ์์ผ๋ก ๋ง์ฃผํ ๋ ๋ฏธ๋ฌํ ๋ก์ง ์ค๋ฅ๋ฅผ ๋๋ฒ๊น ํ๋ ๊ธฐ์ด๊ฐ ๋ฉ๋๋ค.