๐ ํ์ ์์ฌ: ๋ ๋ฒ์งธ ์ฌ๋ก
๊ฐ์
์ฒซ ๋ฒ์งธ ์ฌ๋ก์์ ์ตํ ํฌ๋์ ๋๋ฒ๊น ์คํฌ์ ๋ฐํ์ผ๋ก, ์ด๋ฒ์๋ ์ ํ ๋ค๋ฅธ ์ ํ์ ๋์ ์ ๋ง์ฃผํฉ๋๋ค: ํฌ๋์ ์์ด ์๋ชป๋ ๊ฒฐ๊ณผ๋ฅผ ๋ด๋ ๋ก์ง ๋ฒ๊ทธ์ ๋๋ค.
๋๋ฒ๊น ๊ด์ ์ ์ ํ:
- ์ฒซ ๋ฒ์งธ ์ฌ๋ก: ๋ช
ํํ ํฌ๋์ ์ ํธ(
CUDA_ERROR_ILLEGAL_ADDRESS)๊ฐ ์กฐ์ฌ๋ฅผ ์๋ดํจ - ๋ ๋ฒ์งธ ์ฌ๋ก: ํฌ๋์๋ ์๊ณ ์๋ฌ ๋ฉ์์ง๋ ์์ - ํ์ ์ฒ๋ผ ํํค์ณ์ผ ํ๋ ๋ฏธ๋ฌํ๊ฒ ์๋ชป๋ ๊ฒฐ๊ณผ๋ง ์์
์ด๋ฒ ์ค๊ธ ๋๋ฒ๊น
์ฑ๋ฆฐ์ง์์๋ LayoutTensor ์ฐ์ฐ์ ์ฌ์ฉํ๋ ์๊ณ ๋ฆฌ์ฆ ์ค๋ฅ๋ฅผ ์กฐ์ฌํฉ๋๋ค. ํ๋ก๊ทธ๋จ์ ์ฑ๊ณต์ ์ผ๋ก ์คํ๋์ง๋ง ์๋ชป๋ ์ถ๋ ฅ์ ๋ด๋๋ฐ, ์ค์ ๊ฐ๋ฐ์์ ํจ์ฌ ํํ๋ฉด์๋ ๊น๋ค๋ก์ด ๋๋ฒ๊น
์๋๋ฆฌ์ค์
๋๋ค.
์ฌ์ ์ค๋น: Mojo GPU ๋๋ฒ๊น ์ ํต์ฌ๊ณผ ํ์ ์์ฌ: ์ฒซ ๋ฒ์งธ ์ฌ๋ก๋ฅผ ๋จผ์ ์๋ฃํด์ CUDA-GDB ์ํฌํ๋ก์ฐ์ ์ฒด๊ณ์ ์ธ ๋๋ฒ๊น ๊ธฐ๋ฒ์ ์ตํ๋์ธ์. ์๋ ๋ช ๋ น์ ์คํํ๋์ง ํ์ธํ์ธ์:
pixi run -e nvidia setup-cuda-gdb
ํต์ฌ ๊ฐ๋
์ด๋ฒ ๋๋ฒ๊น ์ฑ๋ฆฐ์ง์์ ๋ฐฐ์ธ ๋ด์ฉ:
- LayoutTensor ๋๋ฒ๊น : ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ ์ ๊ทผ ํจํด ์กฐ์ฌํ๊ธฐ
- ๋ก์ง ๋ฒ๊ทธ ํ์ง: ํฌ๋์ํ์ง ์๋ ์๊ณ ๋ฆฌ์ฆ ์ค๋ฅ ์ฐพ๊ธฐ
- ๋ฐ๋ณต๋ฌธ ๊ฒฝ๊ณ ๋ถ์: ๋ฐ๋ณต ํ์ ๋ฌธ์ ์ดํดํ๊ธฐ
- ๊ฒฐ๊ณผ ํจํด ๋ถ์: ์ถ๋ ฅ ๋ฐ์ดํฐ๋ก ๊ทผ๋ณธ ์์ธ๊น์ง ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ๊ธฐ
์ฝ๋ ์คํ
๋จผ์ ์ ์ฒด ์ฝ๋๋ฅผ ๋ณด์ง ์๊ณ ์ปค๋๋ง ์ดํด๋ด ์๋ค:
fn process_sliding_window(
output: LayoutTensor[dtype, vector_layout, MutAnyOrigin],
a: LayoutTensor[dtype, vector_layout, ImmutAnyOrigin],
):
thread_id = thread_idx.x
# Each thread processes a sliding window of 3 elements
window_sum = Scalar[dtype](0.0)
# Sum elements in sliding window: [i-1, i, i+1]
for offset in range(ITER):
idx = Int(thread_id) + offset - 1
if 0 <= idx < SIZE:
value = rebind[Scalar[dtype]](a[idx])
window_sum += value
output[thread_id] = window_sum
๋ฒ๊ทธ๋ฅผ ์ง์ ๊ฒฝํํ๋ ค๋ฉด ํฐ๋ฏธ๋์์ ๋ค์ ๋ช
๋ น์ ์คํํ์ธ์ (pixi ์ ์ฉ):
pixi run -e nvidia p09 --second-case
๋ค์๊ณผ ๊ฐ์ ์ถ๋ ฅ์ด ๋ํ๋ฉ๋๋ค - ํฌ๋์ ์์ด ์๋ชป๋ ๊ฒฐ๊ณผ:
This program computes sliding window sums for each position...
Input array: [0, 1, 2, 3]
Computing sliding window sums (window size = 3)...
Each position should sum its neighbors: [left + center + right]
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 --second-case
GDB ๋ช ๋ น์ด ๋จ์ถํค (๋น ๋ฅธ ๋๋ฒ๊น )
์ด ๋จ์ถํค๋ค์ ์ฌ์ฉํ๋ฉด ๋๋ฒ๊น ์ธ์ ์๋๋ฅผ ๋์ผ ์ ์์ต๋๋ค:
| ๋จ์ถ | ์ ์ฒด | ์ฌ์ฉ ์์ |
|---|---|---|
r | run | (cuda-gdb) r |
n | next | (cuda-gdb) n |
c | continue | (cuda-gdb) c |
b | break | (cuda-gdb) b 39 |
p | print | (cuda-gdb) p thread_id |
q | quit | (cuda-gdb) q |
์๋ ๋ชจ๋ ๋๋ฒ๊น ๋ช ๋ น์ด๋ ํจ์จ์ ์ํด ์ด ๋จ์ถํค๋ฅผ ์ฌ์ฉํฉ๋๋ค!
ํ
- ํจํด ๋ถ์๋ถํฐ - ๊ธฐ๋๊ฐ๊ณผ ์ค์ ๊ฒฐ๊ณผ์ ๊ด๊ณ๋ฅผ ์ดํด๋ณด์ธ์ (์ฐจ์ด์ ์ด๋ค ์ํ์ ํจํด์ด ์๋์?)
- ์คํ ํ๋ฆ์ ์ง์ค - ๋ณ์์ ์ ๊ทผํ ์ ์์ผ๋ฉด ๋ฐ๋ณต ํ์๋ฅผ ์ธ์ด๋ณด์ธ์
- ๋จ์ํ ๋ธ๋ ์ดํฌํฌ์ธํธ ์ฌ์ฉ - ์ต์ ํ๋ ์ฝ๋์์๋ ๋ณต์กํ ๋๋ฒ๊น ๋ช ๋ น์ด ์คํจํ๊ธฐ ์ฝ์ต๋๋ค
- ์ํ์ ์ถ๋ก - ๊ฐ ์ค๋ ๋๊ฐ ์ ๊ทผํด์ผ ํ๋ ๊ฒ๊ณผ ์ค์ ๋ก ์ ๊ทผํ๋ ๊ฒ์ ๋ฐ์ ธ๋ณด์ธ์
- ๋๋ฝ๋ ๋ฐ์ดํฐ ์กฐ์ฌ - ๊ฒฐ๊ณผ๊ฐ ์ผ๊ด๋๊ฒ ๊ธฐ๋๋ณด๋ค ์๋ค๋ฉด, ๋ฌด์์ด ๋น ์ก์๊น์?
- ํธ์คํธ ์ถ๋ ฅ ๊ฒ์ฆ - ์ต์ข ๊ฒฐ๊ณผ์์ ๋ฒ๊ทธ์ ํจํด์ด ๋๋ฌ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค
- ์๊ณ ๋ฆฌ์ฆ ๊ฒฝ๊ณ ๋ถ์ - ๋ฐ๋ณต๋ฌธ์ด ์ฌ๋ฐ๋ฅธ ๊ฐ์์ ์์๋ฅผ ์ฒ๋ฆฌํ๋์ง ํ์ธํ์ธ์
- ์๋ํ๋ ์ผ์ด์ค์ ๊ต์ฐจ ๊ฒ์ฆ - ์ค๋ ๋ 3์ ์ ํํ๊ฒ ์๋ํ๋๋ฐ ๋ค๋ฅธ ๊ฒ๋ค์ ์ ์ ๋ ๊น์?
๐ก ์กฐ์ฌ ๊ณผ์ ๊ณผ ํด๊ฒฐ์ฑ
CUDA-GDB๋ก ๋จ๊ณ๋ณ ์กฐ์ฌ
1๋จ๊ณ: ์คํ๊ณผ ์ด๊ธฐ ๋ถ์
Step 1: ๋๋ฒ๊ฑฐ ์คํ
pixi run -e nvidia mojo debug --cuda-gdb --break-on-launch problems/p09/p09.mojo --second-case
Step 2: ์ฆ์๋ถํฐ ๋ถ์
๋๋ฒ๊ฑฐ๋ก ๋ค์ด๊ฐ๊ธฐ ์ ์, ์ด๋ฏธ ์๊ณ ์๋ ๊ฒ์ ์ ๋ฆฌํฉ๋๋ค:
์ค์ ๊ฒฐ๊ณผ: [0.0, 1.0, 3.0, 5.0]
๊ธฐ๋๊ฐ: [1.0, 3.0, 6.0, 5.0]
๐ ํจํด ์ธ์:
- ์ค๋ ๋ 0: 0.0 ์ป์, ๊ธฐ๋๊ฐ 1.0 โ 1.0 ๋๋ฝ
- ์ค๋ ๋ 1: 1.0 ์ป์, ๊ธฐ๋๊ฐ 3.0 โ 2.0 ๋๋ฝ
- ์ค๋ ๋ 2: 3.0 ์ป์, ๊ธฐ๋๊ฐ 6.0 โ 3.0 ๋๋ฝ
- ์ค๋ ๋ 3: 5.0 ์ป์, ๊ธฐ๋๊ฐ 5.0 โ โ ์ ํ
์ด๊ธฐ ๊ฐ์ค: ๊ฐ ์ค๋ ๋๊ฐ ์ผ๋ถ ๋ฐ์ดํฐ๋ฅผ ๋๋ฝํ๊ณ ์๋๋ฐ, ์ค๋ ๋ 3๋ง ์ ํํ๊ฒ ์๋ํฉ๋๋ค.
2๋จ๊ณ: ์ปค๋ ์ง์
Step 3: ๋ธ๋ ์ดํฌํฌ์ธํธ ์ง์ ํ์ธ
์ค์ ๋๋ฒ๊น ์ธ์ ์์๋ ๋ค์๊ณผ ๊ฐ์ด ์งํ๋ฉ๋๋ค:
(cuda-gdb) r
Starting program: .../mojo run problems/p09/p09.mojo --second-case
This program computes sliding window sums for each position...
Input array: [0, 1, 2, 3]
Computing sliding window sums (window size = 3)...
Each position should sum its neighbors: [left + center + right]
[Switching focus to CUDA kernel 0, grid 1, block (0,0,0), thread (0,0,0), device 0, sm 0, warp 0, lane 0]
CUDA thread hit application kernel entry function breakpoint, p09_process_sliding_window_...
<<<(1,1,1),(4,1,1)>>> (output=..., input=...)
at /home/ubuntu/workspace/mojo-gpu-puzzles/problems/p09/p09.mojo:30
30 input: LayoutTensor[mut=False, dtype, vector_layout],
Step 4: ๋ฉ์ธ ๋ก์ง์ผ๋ก ์ด๋
(cuda-gdb) n
29 output: LayoutTensor[mut=True, dtype, vector_layout],
(cuda-gdb) n
32 thread_id = thread_idx.x
(cuda-gdb) n
38 for offset in range(ITER):
Step 5: ๋ณ์ ์ ๊ทผ์ฑ ํ ์คํธ - ์ค์ํ ๋ฐ๊ฒฌ
(cuda-gdb) p thread_id
$1 = 0
โ ์ข์: Thread ID์ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค.
(cuda-gdb) p window_sum
Cannot access memory at address 0x0
โ ๋ฌธ์ : window_sum์ ์ ๊ทผํ ์ ์์ต๋๋ค.
(cuda-gdb) p a[0]
Attempt to take address of value not located in memory.
โ ๋ฌธ์ : LayoutTensor ์ง์ ์ธ๋ฑ์ฑ์ด ์๋ํ์ง ์์ต๋๋ค.
(cuda-gdb) p a.ptr[0]
$2 = {0}
(cuda-gdb) p a.ptr[0]@4
$3 = {{0}, {1}, {2}, {3}}
๐ฏ ๋ํ๊ตฌ: a.ptr[0]@4๋ก ์ ์ฒด ์
๋ ฅ ๋ฐฐ์ด์ ๋ณผ ์ ์์ต๋๋ค! ์ด๊ฒ์ด LayoutTensor ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฌํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
3๋จ๊ณ: ํต์ฌ ๋ฐ๋ณต๋ฌธ ์กฐ์ฌ
Step 6: ๋ฐ๋ณต๋ฌธ ๋ชจ๋ํฐ๋ง ์ค์
(cuda-gdb) b 42
Breakpoint 1 at 0x7fffd326ffd0: file problems/p09/p09.mojo, line 42.
(cuda-gdb) c
Continuing.
CUDA thread hit Breakpoint 1, p09_process_sliding_window_...
<<<(1,1,1),(4,1,1)>>> (output=..., input=...)
at /home/ubuntu/workspace/mojo-gpu-puzzles/problems/p09/p09.mojo:42
42 idx = thread_id + offset - 1
๐ ์ด์ ๋ฐ๋ณต๋ฌธ ๋ณธ๋ฌธ ์์ ์์ต๋๋ค. ์ง์ ๋ฐ๋ณต ํ์๋ฅผ ์ธ์ด๋ด ์๋ค.
Step 7: ์ฒซ ๋ฒ์งธ ๋ฐ๋ณต (offset = 0)
(cuda-gdb) n
43 if 0 <= idx < SIZE:
(cuda-gdb) n
41 for offset in range(ITER):
์ฒซ ๋ฒ์งธ ๋ฐ๋ณต ์๋ฃ: ๋ฐ๋ณต๋ฌธ์ด 42๋ฒ ์ค โ 43๋ฒ ์ค โ 41๋ฒ ์ค๋ก ๋์์์ต๋๋ค. ๋ฐ๋ณต๋ฌธ์ด ๊ณ์๋ฉ๋๋ค.
Step 8: ๋ ๋ฒ์งธ ๋ฐ๋ณต (offset = 1)
(cuda-gdb) n
CUDA thread hit Breakpoint 1, p09_process_sliding_window_...
42 idx = thread_id + offset - 1
(cuda-gdb) n
43 if 0 <= idx < SIZE:
(cuda-gdb) n
44 value = rebind[Scalar[dtype]](input[idx])
(cuda-gdb) n
45 window_sum += value
(cuda-gdb) n
43 if 0 <= idx < SIZE:
(cuda-gdb) n
41 for offset in range(ITER):
๋ ๋ฒ์งธ ๋ฐ๋ณต ์๋ฃ: ์ด๋ฒ์๋ if ๋ธ๋ก(44-45๋ฒ ์ค)์ ํต๊ณผํ์ต๋๋ค.
Step 9: ์ธ ๋ฒ์งธ ๋ฐ๋ณต ํ ์คํธ
(cuda-gdb) n
47 output[thread_id] = window_sum
๊ฒฐ์ ์ ๋ฐ๊ฒฌ: ๋ฐ๋ณต๋ฌธ์ด 2๋ฒ๋ง ๋๊ณ ์ข ๋ฃ๋์์ต๋๋ค! 42๋ฒ ์ค์ ๋ธ๋ ์ดํฌํฌ์ธํธ์ ๋ค์ ๊ฑธ๋ฆฌ์ง ์๊ณ 47๋ฒ ์ค๋ก ๋ฐ๋ก ๋์ด๊ฐ์ต๋๋ค.
๊ฒฐ๋ก : ๋ฐ๋ณต๋ฌธ์ด ์ ํํ 2๋ฒ ๋๊ณ ์ข ๋ฃ๋์์ต๋๋ค.
Step 10: ์ปค๋ ์คํ ์๋ฃ์ ์ปจํ ์คํธ ์์ค
(cuda-gdb) n
31 fn process_sliding_window(
(cuda-gdb) n
[Switching to Thread 0x7ffff7cc0e00 (LWP 110927)]
0x00007ffff064f84a in ?? () from /lib/x86_64-linux-gnu/libcuda.so.1
(cuda-gdb) p output.ptr[0]@4
No symbol "output" in current context.
(cuda-gdb) p offset
No symbol "offset" in current context.
๐ ์ปจํ ์คํธ ์์ค: ์ปค๋ ์คํ์ด ๋๋๋ฉด ์ปค๋ ๋ณ์์ ๋ ์ด์ ์ ๊ทผํ ์ ์์ต๋๋ค. ์ ์์ ์ธ ๋์์ ๋๋ค.
4๋จ๊ณ: ๊ทผ๋ณธ ์์ธ ๋ถ์
Step 11: ๊ด์ฐฐ๋ ์คํ์์ ์๊ณ ๋ฆฌ์ฆ ๋ถ์
๋๋ฒ๊น ์ธ์ ์์ ๊ด์ฐฐํ ๊ฒ:
- ๋ฐ๋ณต ํ์: 2๋ฒ๋ง ๋ฐ๋ณต (offset = 0, offset = 1)
- ๊ธฐ๋๊ฐ: ํฌ๊ธฐ 3์ ์ฌ๋ผ์ด๋ฉ ์๋์ฐ๋ 3๋ฒ ๋ฐ๋ณตํด์ผ ํจ (offset = 0, 1, 2)
- ๋๋ฝ: ์ธ ๋ฒ์งธ ๋ฐ๋ณต (offset = 2)
๊ฐ ์ค๋ ๋๊ฐ ๊ณ์ฐํด์ผ ํ ๊ฒ:
- ์ค๋ ๋ 0: window_sum = input[-1] + input[0] + input[1] = (๊ฒฝ๊ณ) + 0 + 1 = 1.0
- ์ค๋ ๋ 1: window_sum = input[0] + input[1] + input[2] = 0 + 1 + 2 = 3.0
- ์ค๋ ๋ 2: window_sum = input[1] + input[2] + input[3] = 1 + 2 + 3 = 6.0
- ์ค๋ ๋ 3: window_sum = input[2] + input[3] + input[4] = 2 + 3 + (๊ฒฝ๊ณ) = 5.0
Step 12: ์ค๋ ๋ 0์ ์ค์ ์คํ ์ถ์
2๋ฒ๋ง ๋ฐ๋ณตํ ๊ฒฝ์ฐ (offset = 0, 1):
๋ฐ๋ณต 1 (offset = 0):
idx = thread_id + offset - 1 = 0 + 0 - 1 = -1if 0 <= idx < SIZE:โif 0 <= -1 < 4:โ False- ํฉ์ฐ ์ฐ์ฐ ๊ฑด๋๋
๋ฐ๋ณต 2 (offset = 1):
idx = thread_id + offset - 1 = 0 + 1 - 1 = 0if 0 <= idx < SIZE:โif 0 <= 0 < 4:โ Truewindow_sum += input[0]โwindow_sum += 0
๋๋ฝ๋ ๋ฐ๋ณต 3 (offset = 2):
idx = thread_id + offset - 1 = 0 + 2 - 1 = 1if 0 <= idx < SIZE:โif 0 <= 1 < 4:โ Truewindow_sum += input[1]โwindow_sum += 1โ ์ด ์ฐ์ฐ์ด ์คํ๋์ง ์์
๊ฒฐ๊ณผ: ์ค๋ ๋ 0์ window_sum = 0 + 1 = 1 ๋์ window_sum = 0์ ์ป์ต๋๋ค
5๋จ๊ณ: ๋ฒ๊ทธ ํ์ธ
๋ฌธ์ ์ฝ๋๋ฅผ ๋ณด๋ฉด:
comptime ITER = 2 # โ ๋ฒ๊ทธ: 3์ด์ด์ผ ํจ!
for offset in range(ITER): # โ 2๋ฒ๋ง ๋ฐ๋ณต: [0, 1]
idx = Int(thread_id) + offset - 1 # โ offset = 2 ๋๋ฝ
if 0 <= idx < SIZE:
value = rebind[Scalar[dtype]](a[idx])
window_sum += value
๐ฏ ๊ทผ๋ณธ ์์ธ ํ์ธ: ํฌ๊ธฐ 3์ ์ฌ๋ผ์ด๋ฉ ์๋์ฐ๋ฅผ ์ํด ITER = 2๊ฐ ITER = 3์ด์ด์ผ ํฉ๋๋ค.
์์ ๋ฐฉ๋ฒ: ์์ค ์ฝ๋์์ comptime ITER = 2๋ฅผ comptime ITER = 3์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
ํต์ฌ ๋๋ฒ๊น ๊ตํ
๋ณ์์ ์ ๊ทผํ ์ ์์ ๋:
- ์คํ ํ๋ฆ์ ์ง์ค - ๋ธ๋ ์ดํฌํฌ์ธํธ๊ฐ ๋ช ๋ฒ ๊ฑธ๋ฆฌ๋์ง, ๋ฐ๋ณต์ด ๋ช ๋ฒ ๋๋์ง ์ธ์ด๋ณด์ธ์
- ์ํ์ ์ถ๋ก ์ฌ์ฉ - ์ผ์ด๋์ผ ํ ์ผ๊ณผ ์ค์ ๋ก ์ผ์ด๋๋ ์ผ์ ๋ฐ์ ธ๋ณด์ธ์
- ํจํด ๋ถ์ - ์๋ชป๋ ๊ฒฐ๊ณผ๊ฐ ์กฐ์ฌ๋ฅผ ์ด๋๋๋ก ํ์ธ์
- ๊ต์ฐจ ๊ฒ์ฆ - ์ฌ๋ฌ ๋ฐ์ดํฐ ํฌ์ธํธ์ ๋ํด ๊ฐ์ค์ ํ ์คํธํ์ธ์
์ ๋ฌธ์ ์ธ GPU ๋๋ฒ๊น ์ ํ์ค:
- ์ปดํ์ผ๋ฌ ์ต์ ํ ๋๋ฌธ์ ๋ณ์ ๊ฒ์ฌ๊ฐ ์คํจํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค
- ์คํ ํ๋ฆ ๋ถ์์ด ๋ฐ์ดํฐ ๊ฒ์ฌ๋ณด๋ค ๋ ์ ๋ขฐํ ์ ์์ต๋๋ค
- ํธ์คํธ ์ถ๋ ฅ ํจํด์ด ์ค์ํ ๋๋ฒ๊น ๋จ์๋ฅผ ์ ๊ณตํฉ๋๋ค
- ์์ค ์ฝ๋ ์ถ๋ก ์ด ์ ํ๋ ๋๋ฒ๊ฑฐ ๊ธฐ๋ฅ์ ๋ณด์ํฉ๋๋ค
LayoutTensor ๋๋ฒ๊น :
- LayoutTensor ์ถ์ํ๋ฅผ ์ฌ์ฉํด๋ ๊ทผ๋ณธ์ ์ธ ์๊ณ ๋ฆฌ์ฆ ๋ฒ๊ทธ๋ ๊ทธ๋๋ก ๋๋ฌ๋ฉ๋๋ค
- ํ ์ ๋ด์ฉ์ ๊ฒ์ฌํ๋ ค ํ๊ธฐ๋ณด๋ค ์๊ณ ๋ฆฌ์ฆ ๋ก์ง์ ์ง์คํ์ธ์
- ์ฒด๊ณ์ ์ธ ์ถ๋ก ์ผ๋ก ๊ฐ ์ค๋ ๋๊ฐ ์ ๊ทผํด์ผ ํ๋ ๊ฒ๊ณผ ์ค์ ๋ก ์ ๊ทผํ๋ ๊ฒ์ ์ถ์ ํ์ธ์
๐ก ํต์ฌ ํต์ฐฐ: ์ด๋ฐ ์ ํ์ off-by-one (์ญ์ฃผ: ๊ฒฝ๊ณ๊ฐ์ด 1๋งํผ ์ด๊ธ๋๋ ์ค๋ฅ) ๋ฐ๋ณต๋ฌธ ๋ฒ๊ทธ๋ GPU ํ๋ก๊ทธ๋๋ฐ์์ ๋งค์ฐ ํํฉ๋๋ค. ์ฌ๊ธฐ์ ๋ฐฐ์ด ์ฒด๊ณ์ ์ธ ์ ๊ทผ๋ฒ - ์ ํ๋ ๋๋ฒ๊ฑฐ ์ ๋ณด์ ์ํ์ ๋ถ์๊ณผ ํจํด ์ธ์์ ๊ฒฐํฉํ๋ ๊ฒ - ์ ๋๊ตฌ์ ํ๊ณ๊ฐ ์์ ๋ ์ ๋ฌธ GPU ๊ฐ๋ฐ์๋ค์ด ๋๋ฒ๊น ํ๋ ๋ฐฉ์ ๊ทธ๋๋ก์ ๋๋ค.
๋ค์ ๋จ๊ณ: ๋ก์ง ๋ฒ๊ทธ์์ ๊ต์ฐฉ ์ํ๋ก
๋ก์ง ๋ฒ๊ทธ ๋๋ฒ๊น ์ ์ตํ์ต๋๋ค! ์ด์ ํ ์ ์์ต๋๋ค:
- โ ํฌ๋์๋ ๋๋ ทํ ์ฆ์ ์์ด๋ ์๊ณ ๋ฆฌ์ฆ ์ค๋ฅ ์กฐ์ฌ
- โ ํจํด ๋ถ์์ผ๋ก ์๋ชป๋ ๊ฒฐ๊ณผ์์ ๊ทผ๋ณธ ์์ธ๊น์ง ์ถ์
- โ ์คํ ํ๋ฆ ๋ถ์์ผ๋ก ๋ณ์ ์ ๊ทผ์ด ์ ํ๋ ์ํฉ์์ ๋๋ฒ๊น
- โ ๋๋ฒ๊ฑฐ ๋๊ตฌ์ ํ๊ณ๊ฐ ์์ ๋ ์ํ์ ์ถ๋ก ์ ์ฉ
๋ง์ง๋ง ๋์ : ํ์ ์์ฌ: ์ธ ๋ฒ์งธ ์ฌ๋ก
๊ทธ๋ฐ๋ฐ ํ๋ก๊ทธ๋จ์ด ํฌ๋์ํ์ง๋ ์๊ณ ๋๋์ง๋ ์๋๋ค๋ฉด์? ๊ทธ๋ฅ ์์ํ ๋ฉ์ถฐ๋ฒ๋ฆฐ๋ค๋ฉด์?
์ธ ๋ฒ์งธ ์ฌ๋ก๋ ๊ถ๊ทน์ ๋๋ฒ๊น ๋์ ์ ์ ์ํฉ๋๋ค:
- โ ํฌ๋์ ๋ฉ์์ง ์์ (์ฒซ ๋ฒ์งธ ์ฌ๋ก์ฒ๋ผ)
- โ ์๋ชป๋ ๊ฒฐ๊ณผ ์์ (๋ ๋ฒ์งธ ์ฌ๋ก์ฒ๋ผ)
- โ ์๋ฃ ์์ฒด๊ฐ ์์ - ๊ทธ๋ฅ ๋ฌดํํ ๋ฉ์ถค
- โ ๊ณ ๊ธ ์ค๋ ๋ ์กฐ์จ ๋ถ์์ด ํ์ํ ์กฐ์ฉํ ๊ต์ฐฉ ์ํ
์๋กญ๊ฒ ์ตํ๊ฒ ๋ ์คํฌ:
- ๋ฐฐ๋ฆฌ์ด ๊ต์ฐฉ ์ํ ํ์ง - ๋ณ๋ ฌ ์ค๋ ๋์์ ์กฐ์จ ์คํจ ์ฐพ๊ธฐ
- ๋ฉํฐ ์ค๋ ๋ ์ํ ๋ถ์ - ๋ชจ๋ ์ค๋ ๋๋ฅผ ๋์์ ๊ฒ์ฌํ๊ธฐ
- ๋๊ธฐํ ๋๋ฒ๊น - ์ค๋ ๋ ํ๋ ฅ ์คํจ ์ดํดํ๊ธฐ
๋๋ฒ๊น ์งํ:
- ์ฒซ ๋ฒ์งธ ์ฌ๋ก: ํฌ๋์ ์ ํธ ๋ฐ๋ผ๊ฐ๊ธฐ โ ๋ฉ๋ชจ๋ฆฌ ๋ฒ๊ทธ ์ฐพ๊ธฐ
- ๋ ๋ฒ์งธ ์ฌ๋ก: ๊ฒฐ๊ณผ ํจํด ๋ถ์ํ๊ธฐ โ ๋ก์ง ๋ฒ๊ทธ ์ฐพ๊ธฐ
- ์ธ ๋ฒ์งธ ์ฌ๋ก: ์ค๋ ๋ ์ํ ์กฐ์ฌํ๊ธฐ โ ์กฐ์จ ๋ฒ๊ทธ ์ฐพ๊ธฐ
์ด์ ๋ ์ฌ๋ก์์ ๋ฐฐ์ด ์ฒด๊ณ์ ์ธ ์กฐ์ฌ ์คํฌ - ๊ฐ์ค ์๋ฆฝ, ์ฆ๊ฑฐ ์์ง, ํจํด ๋ถ์ - ์ ๊ฐ์ฅ ์ด๋ ค์ด GPU ๋ฌธ์ ๋ฅผ ๋๋ฒ๊น ํ ๋ ํต์ฌ์ด ๋ฉ๋๋ค: ์กฐ์จ์ด ์ด๊ธ๋ ์์ํ ์๋ก๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ์ค๋ ๋๋ค.