0) 큰그림: 파일 → 컴파일 → 링크 → .pyd → wheel → 설치
- 소스: *.cpp, *.cu (+ 헤더들)
- 컴파일
- C++ 소스(.cpp) → MSVC(cl.exe) 가 .obj 생성
- CUDA 소스(.cu) → NVCC가 호스트컴파일러(MSVC)를 호출해서 .obj 생성
- .cu가 여러 개면 Device Linking(Relocatable Device Code) 단계가 들어감
- 링크: 모든 .obj + 외부 라이브러리(cudart, cublas 등) → 하나의 DLL 생성
- 파이썬 확장 모듈이면 윈도우 확장자 = .pyd (사실상 DLL)
- 패키징: .pyd를 wheel 안에 넣어 .whl 생성
- 설치/import: pip install .whl → site-packages에 복사 → import 모듈명 동작
포인트: 모듈명(=import 이름)은 C++의 PYBIND11_MODULE(<이름>, m) 으로 결정. wheel의 패키지명(name=)과는 별개!
1) 각 파일의 “역할”
pyproject.toml (Python 빌드의 “메타+드라이버”)
- “내 프로젝트는 CMake + scikit-build-core로 빌드할 거야”를 pip에게 알려줌.
- python -m build나 pip install . 할 때 빌드 백엔드로 CMake를 실행해 wheel을 만들어 줌.
[build-system]
requires = ["scikit-build-core>=0.9", "pybind11>=2.12"]
build-backend = "scikit_build_core.build"
[project]
name = "graph-executor-v2" # pip에서 보이는 배포명 (하이픈 가능)
version = "0.0.1"
requires-python = ">=3.12"
CMakeLists.txt (C++/CUDA 빌드 “설정서”)
- 무슨 소스를 어떤 옵션으로 컴파일/링크할지 기술.
- NVCC/CL 세부 옵션, 아키텍처, 링크 라이브러리, 출력물 이름 등을 정의.
- install(TARGETS ...)로 wheel에 담을 결과물을 지정.
주요 포인트:
- project(... LANGUAGES CXX CUDA) : CUDA 사용 선언
- pybind11_add_module(<모듈명> MODULE srcs...) : pybind11 파이썬 모듈 타깃 생성
- CMAKE_CUDA_ARCHITECTURES : GPU 아키텍처 지정(예: 86 = Ampere)
- CUDA_SEPARABLE_COMPILATION ON : 여러 .cu의 device linking 자동 처리
- target_link_libraries(... CUDA::cudart CUDA::cublas ...) : CUDA 런타임/라이브러리 연결
- install(TARGETS ...) : wheel에 포함 지시
cmake_minimum_required(VERSION 3.26)
project(graph_executor_v2 LANGUAGES CXX CUDA)
find_package(Python 3.12 COMPONENTS Interpreter Development.Module REQUIRED)
find_package(pybind11 CONFIG REQUIRED)
find_package(CUDAToolkit REQUIRED)
# GPU 아키텍처(여러개면 세미콜론 구분: 75;86;89;90)
set(CMAKE_CUDA_ARCHITECTURES 86)
set(SRC
src/bindings_min_api.cpp # PYBIND11_MODULE(graph_executor_v2, m) 있어야 함
src/launch_table.cpp
src/my_kernels.cu
)
# 파이썬 모듈 타깃 생성 (.pyd 결과)
pybind11_add_module(graph_executor_v2 MODULE ${SRC})
# C++/CUDA 표준 및 분리컴파일
target_compile_features(graph_executor_v2 PRIVATE cxx_std_17)
set_target_properties(graph_executor_v2 PROPERTIES
CUDA_STANDARD 17
CUDA_SEPARABLE_COMPILATION ON
POSITION_INDEPENDENT_CODE ON
OUTPUT_NAME "graph_executor_v2" # 최종 모듈 이름 고정
)
# 컴파일 옵션 (MSVC/Windows)
if (MSVC)
target_compile_options(graph_executor_v2 PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:/bigobj;/W3;/EHsc;/O2;/MD>
)
endif()
# CUDA 전용으로 호스트컴파일러 옵션 넘길 때는 -Xcompiler 사용
target_compile_options(graph_executor_v2 PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=/EHsc;-Xcompiler=/O2;-Xcompiler=/MD>
)
# 링크할 CUDA 라이브러리
# cudart는 정적으로 링크하고 싶다면 아래 주석 해제:
# set_target_properties(graph_executor_v2 PROPERTIES CUDA_RUNTIME_LIBRARY Static)
target_link_libraries(graph_executor_v2 PRIVATE
CUDA::cudart
CUDA::cublas
# CUDA::cublasLt # 필요 시
)
target_include_directories(graph_executor_v2 PRIVATE
${CUDAToolkit_INCLUDE_DIRS}
include
)
# wheel에 담으려면 install이 매우 중요!
install(TARGETS graph_executor_v2
LIBRARY DESTINATION .
RUNTIME DESTINATION .
ARCHIVE DESTINATION .)
2) 빌드/설치 “실행 흐름”
A. 개발/빌드 전제
- Windows: Python 3.12, Visual Studio Build Tools 2022 (C++ 툴셋), CUDA Toolkit 12.x
- 환경변수: CUDA_PATH 설정되어 있고, PATH에 %CUDA_PATH%\bin 포함 권장
# 프로젝트 폴더: dev/backend/graph_executor_v2
python -m pip install -U pip scikit-build-core pybind11
# 과거 캐시가 섞여 있으면 정리
Remove-Item -Recurse -Force _skbuild, build, dist -ErrorAction SilentlyContinue
# wheel/sdist 생성
python -m build
# 설치(개발 반복 용이라면 -e . 도 가능)
python -m pip install --force-reinstall dist\graph_executor_v2-0.0.1-cp312-cp312-win_amd64.whl
3) NVCC/링킹에 대한 핵심 개념 (윈도우 기준 요약)
- NVCC는 메타 드라이버: .cu를 컴파일할 때 내부적으로 MSVC를 호출.
- Device Linking: .cu가 여러 개고 서로 __device__ 심볼을 참조하면 분리 컴파일 + 장치 링킹이 필요.
- CMake에선 CUDA_SEPARABLE_COMPILATION ON이면 자동 처리.
- 런타임 DLL: 보통 cudart64_12.dll, cublas64_12.dll 등이 실행 시 PATH에 있어야 import 성공.
- Python 3.8+에선 os.add_dll_directory(os.path.join(os.environ["CUDA_PATH"], "bin")) 권장.
- cudart를 정적 링크하면 그 DLL의존 하나 줄일 수 있지만, cuBLAS는 여전히 DLL 필요.
- /MD vs /MT: 파이썬/pybind11은 기본적으로 /MD 런타임을 가정(권장).
- 모듈명 일치:
- PYBIND11_MODULE(graph_executor_v2, m)
- pybind11_add_module(graph_executor_v2 ...)
- 최종 .pyd가 graph_executor_v2.cp312-win_amd64.pyd 로 나와야 import graph_executor_v2가 됨.
- wheel의 name="graph-executor-v2"는 pip 패키지명일 뿐, import 이름과 무관.
4) 체크리스트 (실무용)
- VS Build Tools 2022 + CUDA Toolkit 설치/버전 확인
- pyproject.toml에 scikit-build-core, pybind11 지정
- CMakeLists.txt에
- pybind11_add_module(graph_executor_v2 ...)
- set(CMAKE_CUDA_ARCHITECTURES 86) (GPU 맞게)
- CUDA_SEPARABLE_COMPILATION ON
- target_link_libraries(... CUDA::cudart CUDA::cublas)
- install(TARGETS graph_executor_v2 DESTINATION .)
- PYBIND11_MODULE(graph_executor_v2, m) 이름 일치
- python -m build 로 wheel 생성
- pip install dist\...whl
- import graph_executor_v2; print(__file__)로 경로 확인
- 실행 스크립트에서 ensure_cuda_dlls() 1회 호출
'dev_AI_framework' 카테고리의 다른 글
| 커널 ABI, 런타임 컨트랙트에 대해 (0) | 2025.09.02 |
|---|---|
| AI Compiler 구현 - python -> graph_executor_v2 -> launch_kernel() 까지의 완료된 상황 (0) | 2025.09.02 |
| AI 컴파일러의 구현 - graph_executor_v2 를 통해 (0) | 2025.09.01 |
| operator mapping 전략 짜기 - string or int ?? 메모리 효율, 빠른 비교를 위해 int 위주 매핑 전략 사용하기 (0) | 2025.09.01 |
| 폴더 및 파일 구조 변경 - Python 내 통제 방법으로 변경 예정 (2) | 2025.09.01 |