https://github.com/xlite-dev/LeetCUDA/blob/main/kernels/elementwise/elementwise.py
위의 python 코드에 대한 설명 (from GPT)
이 파이썬 스크립트는 CUDA 커널을 PyTorch 확장으로 빌드/로딩하고, 여러 텐서 크기(S, K)에서 커스텀 커널 vs PyTorch 연산의 성능을 반복 벤치마크하는 코드.
from torch.utils.cpp_extension import load
lib = load(
name="elementwise_lib",
sources=["elementwise.cu"],
extra_cuda_cflags=[
"-O3",
"-U__CUDA_NO_HALF_OPERATORS__",
"-U__CUDA_NO_HALF_CONVERSIONS__",
"-U__CUDA_NO_HALF2_OPERATORS__",
"-U__CUDA_NO_BFLOAT16_CONVERSIONS__",
"--expt-relaxed-constexpr",
"--expt-extended-lambda",
"--use_fast_math",
],
extra_cflags=["-std=c++17"],
)
load(...)가 elementwise.cu를 컴파일 → .so 생성 → 파이썬 모듈로 로드까지 한 번에 해줘.
첫 실행은 컴파일 때문에 시간이 길어질 수 있음(이후 캐시된 .so 재사용). (맞아. 꽤 오래 기다려야 했음. 이 코드를 돌리실 분들이라면 조급해하지 말고 기다려보길)
extra_cuda_cflags: (이 부분은 잘 모르지만 그냥 넘어갔다)
-O3, --use_fast_math: 최적화/빠른 수학 함수.-U__CUDA_NO_HALF_*: half/half2/bfloat16 연산 intrinsics 활성화.--expt-relaxed-constexpr, --expt-extended-lambda: CUDA C++ 확장 기능 허용.로드되면 lib.elementwise_add_f32, lib.elementwise_add_f16x8_pack 같은 바인딩된 파이썬 함수로 커널을 호출할 수 있어.
torch.set_grad_enabled(False)
def run_benchmark(perf_func, a, b, tag, out=None, warmup=10, iters=1000, ...):
입력
perf_func: 실행할 함수(커스텀 커널 또는 torch.add).a, b: 입력 텐서.out: 출력 버퍼(있으면 in-place 스타일, 없으면 함수가 반환값 생성).warmup: 워밍업 반복 횟수(캐시/클럭 워밍업).iters: 실제 측정 반복 횟수(평균 시간 산출).동작
out.fill_(0)로 출력 초기화(있을 때).torch.cuda.synchronize()로 GPU 작업 동기화 후 타이머 시작.iters만큼 호출(동기화 후 종료 시각 측정).중요 포인트
torch.cuda.synchronize()가 필수.iters=1000이라 꽤 오래 걸릴 수 있음(정밀 측정 목적).Ss = [1024, 2048, 4096]
Ks = [1024, 2048, 4096]
for S, K in SKs:
a = torch.randn((S, K)).cuda().float().contiguous()
b = torch.randn((S, K)).cuda().float().contiguous()
c = torch.zeros_like(a).cuda().float().contiguous()
9개 크기 조합(S,K) 각각에 대해 텐서 생성(GPU, FP32, contiguous).
FP32 벤치마크
lib.elementwise_add_f32(a,b,c) : 스칼라형 FP32 커널lib.elementwise_add_f32x4(a,b,c) : float4 벡터화 버전partial(torch.add, out=c) : PyTorch 기본 연산(비교군)FP16 벤치마크
a_f16 = a.half().contiguous(); b_f16 = b.half().contiguous(); c_f16 = c.half().contiguous()
lib.elementwise_add_f16 : half 스칼라lib.elementwise_add_f16x2 : half2 벡터화lib.elementwise_add_f16x8 : half2×4로 8개 처리lib.elementwise_add_f16x8_pack : 128비트 일괄 로드/스토어 + half2 연산(가장 공격적 최적화)partial(torch.add, out=c_f16) : PyTorch FP16 비교군각 호출은 run_benchmark(...)으로 감싸서 평균 시간과 샘플 출력값을 찍어 줘.
-------------------------------------
S=1024, K=1024
out_f32: [v1, v2], time:0.00xxms
out_f32x4: [v1, v2], time:0.00xxms
out_f32_th: [v1, v2], time:0.00xxms
-------------------------------------
out_f16: [...]
out_f16x2: [...]
out_f16x8: [...]
out_f16x8pack: [...]
out_f16_th: [...]
-------------------------------------
out_*: 결과 텐서 앞 2개의 값(정확도 체크)time:: 1회 평균 소요 시간(ms)load(...) 컴파일 비용.synchronize()가 들어가 있어 CPU가 GPU 끝날 때까지 대기.빠르게 돌리고 싶다면: iters 줄이기(예: 100), S/K 조합 축소, show_all=False 유지.
.contiguous()로 메모리 연속 보장(벡터화/128비트 접근에 중요).__hadd/__hadd2 사용(half/half2 연산).GPT가 설명을 알잘딱깔센으로 잘해줘서 궁금한 부분만 조금 더 물어보고 python 코드는 더 파지 않았다.
왜냐... 진도 나가야 해.
쿠다 코드 보는 걸 우선으로 하고 있는데, 쿠다 library를 실행할 파이썬 코드도 궁금하면 다시 돌아오는 걸로..!