0) 개요
- 목적: Python 컴파일러(compiler/) → 네이티브 실행기(graph_executor_v2/) 로 이어지는 실행 파이프라인을 고정된 런타임 컨트랙트(ABI) 로 연결하고, 최소 스텁 커널로 end-to-end 스모크까지 확인.
- 현재 상태:
- query_kernels() / query_capability() 정상
- copy 스텁 커널 런치 성공 (OK: copy smoke passed)
1) 변경/추가된 파일 요약
C++/CUDA (네이티브 실행기)
- include/ge_v2_api.h (신규)
- Python ↔ C++ 경계의 ABI(런타임 컨트랙트) 고정
- 공통 타입: ge2_uintptr(device ptr), ge2_stream_t(opaque stream), ge2_kernel_fn(커널 시그니처)
- 네이티브 테이블 심볼:
- ge_v2_kernel_table_raw() : kernel_name → ge2_kernel_fn
- ge_v2_capability_table_raw() : "<OPTYPE>__<KERNEL_NAME>" → score(int)
- 버전: GE2_API_VERSION 1
- src/bindings_min_api.cpp (수정)
- pybind11 바인딩
- query_capability(op_type, in_descs, out_descs)
- launch_kernel(kernel_name, buffers, descs, stream=0)
- query_kernels() (디버그)
- #include "ge_v2_api.h" 추가 및 예외 메시지 정리
- src/launch_table.cpp (수정)
- 커널 이름→함수 포인터 테이블
- 캡 점수 테이블:
- GEMM_BIAS_ACT__gemm_bias_act_tc_f16 → 40
- GEMM_BIAS_ACT__gemm_bias_act_f32 → 80 (스모크에서 f32 우선)
- src/my_kernels.cu (수정)
- 스모크 전용 copy 커널 (입력→출력으로 1024개 복사)
- C-링크 진입점:
- ge2_launch_gemm_bias_act_f32
- ge2_launch_gemm_bias_act_tc_f16
- CMakeLists.txt (수정)
- pybind11 자동 fetch(FetchContent; find_package 실패 시)
- include/ 경로 포함
- 모듈 이름/출력 고정 (OUTPUT_NAME "graph_executor_v2")
- 설치 시 ABI 헤더 동반 설치: install(FILES include/ge_v2_api.h DESTINATION include)
Python (컴파일러/런타임)
- compiler/kernels/registry.py (정리)
- 커널 메타 레지스트리(파이썬 선언)
- 예시 등록: gemm_bias_act_tc_f16, gemm_bias_act_f32
- compiler/kernels/selector.py (정리)
- 파이썬 메타 + 네이티브 query_capability 합산 스코어링
- 간단 룰: tensor_core, min_mnk 가산점
- compiler/runtime/executor.py (보강)
- 네이티브 모듈 우선 로딩(GE_NATIVE 환경변수 허용)
- Tensor → device ptr 자동 어댑터(Torch/CuPy 우선)
- dry_run=False 실행 경로 준비 (스텁 기준)
- smoke_test_v2.py (테스트 스크립트)
- query_kernels() / query_capability() 출력
- CuPy(or Torch)로 copy 스텁 검증 → "OK: copy smoke passed"
2) 런타임 컨트랙트(ABI) 핵심 규약
- launch_kernel(kernel_name, buffers, descs, stream)
- buffers: 입력들 → 출력들 순서의 device pointer(uintptr_t) 리스트
- descs: { "buffers": [ { "shape": [...], "dtype": "f16|f32|...", "layout": "rowmajor", "device": "cuda" }, ... ] }
(현재 C++에서는 opaque; 후속 확장에서 shape/stride를 사용하면 좋음)
- stream: CUDA면 cudaStream_t를 정수로 넘겨 reinterpret_cast 사용
- 반환 규약: 0=성공, 음수=에러(-1 invalid args / -2 device error / -3 not implemented 등)
- query_capability(op_type, ...)
- 네이티브 테이블 key: "<OPTYPE>__<KERNEL_NAME>"
- 파이썬 selector는 이 점수 + 룰 기반 점수를 합산해 선택
3) 빌드 절차
# 루트가 dev/backend/graph_executor_v2 라고 가정
PS> cd C:\Users\owner\Desktop\AI_framework-dev\dev\backend\graph_executor_v2
# (처음만) build 디렉토리 생성
PS> mkdir build
PS> cd build
# Configure (pybind11 패키지 경로 자동 탐색 실패 시 FetchContent로 받아옴)
PS ...\build> cmake .. -DCMAKE_BUILD_TYPE=Release
# Build
PS ...\build> cmake --build . --config Release -j
4) 컴파일러 측 연동 체크
- compiler/kernels/registry.py
- km["name"]가 네이티브 launch_table 키와 정확히 동일해야 함.
- compiler/kernels/selector.py
- query_capability()를 사용 가능하면 합산 스코어링, 아니면 룰만으로 선택.
- compiler/runtime/executor.py
- GE_NATIVE=graph_executor_v2 환경변수로 바인딩 강제 가능
- _prepare_buffers: Torch/CuPy 텐서 → device ptr 자동 어댑터 포함
- dry_run=False로 실행 시 실제 launch_kernel 호출
5) 자주 만나는 이슈 & 해결
- identifier 'ge_v2_capability_table_raw' is undefined
- bindings_min_api.cpp에 #include "ge_v2_api.h" 누락/오타 여부 확인
- target_include_directories(... include) 확인
- launch_table.cpp 내 함수 정의 확인
- Could not find pybind11Config.cmake
- pip install -U pybind11 후
- CMake에 -Dpybind11_DIR=<…site-packages…/pybind11/share/cmake/pybind11> 전달
- 또는 CMakeLists의 FetchContent 경로 사용
- CMakeCache.txt directory is different
- 예전 경로 캐시 충돌 → build/ 제거 후 재구성 (rmdir -Recurse -Force .\build)
- rmdir: 파일은 다른 프로세스에서 사용 중
- 상위 디렉토리로 이동(cd ..), VS/VSCode/빌드툴 종료, 필요 시 작업관리자에서 cl.exe/link.exe/ninja.exe 종료
6) 다음 단계(추천)
- shape/stride 사용: descs에서 실제 텐서 크기를 읽어 grid/block 및 N 계산 (지금은 N=1024 고정)
- 진짜 GEMM(+Bias+Act):
- cublasLt 또는 cutlass 기반 커널로 스텁 교체
- dtype/layout 검증/변환 로직 추가
- 에러코드/로깅 규약 통일: -1/-2/-3 등 공통 테이블 문서화
- 버전 핸드셰이크: GE2_API_VERSION을 파이썬에서 확인하여 미스매치 경고
- 테스트 확장: pytest로 IR → 패스 → 선택 → 런치까지 e2e 케이스 추가