-
Rust로 작성한 하나의 코드베이스가 CUDA, SPIR-V, Metal, DirectX 12, WebGPU, CPU 등 모든 주요 GPU 및 CPU 플랫폼에서 동작함
- Rust 커뮤니티가 Rust GPU, Rust CUDA, Naga 프로젝트를 결합해, GPU 코드를 별도 셰이더 언어 없이 일반 Rust 코드로 작성 가능하게 만듦
- 비토닉 정렬 알고리듬을 예시로, 공통 로직을 모든 플랫폼에서 동일하게 실행할 수 있음을 시연함
-
조건부 컴파일, newtype, trait, derive macro 등 Rust의 고유 기능을 적극 활용하여 GPU 코드 품질과 유지보수성을 높임
- 아직 개발자 경험에 거친 부분이 많고, 빌드 및 디버깅 도구 통합, 표준화 등 발전 여지가 상존함
프로젝트 소개 및 의의
- Rust 언어로 작성한 단일 코드베이스가 NVIDIA CUDA, Vulkan(SPIR-V), Metal, DirectX 12, WebGPU, CPU까지 전 메이저 GPU 백엔드를 지원함
- 셰이더 또는 커널 전용 언어(GLSL, HLSL 등) 사용 없이, 순수 Rust 코드만으로 GPU 및 CPU에서 동일한 연산 처리 가능함
- 이는 GPU·CPU 간 코드 중복 및 복잡도를 대폭 줄이고, Rust 생태계의 도구 및 언어 장점(타입 안정성, 테스트, 문서화, 빌드 관리 등)을 GPU 프로그래밍에도 적용함
배경
- 전통적 GPU 프로그래밍은 각 플랫폼별로 특화된 셰이더 언어(예:GSL, HLSL, MSL, WGSL 등) 사용이 필수임
- 이에 따라 CPU와 GPU 코드가 분리되고 로직 중복 및 개발 복잡성 증가 문제를 낳음
- Rust 커뮤니티는 이에 대응해 일반 Rust를 GPU 대상으로 컴파일하는 접근을 추구 중임
-
Rust GPU: Rust 코드를 SPIR-V로 컴파일, Vulkan 및 SPIR-V 호환 GPU에서 동작
-
Rust CUDA: Rust 코드를 NVIDIA CUDA용 IR(NVVM IR, PTX)로 컴파일, CUDA에서 실행
-
Naga: 다양한 GPU 언어 간 번역·중간 표현 지원, 백엔드 이식성을 담당
- 각 프로젝트가 독립적으로 시작되어 API, 구조가 달랐으나, 최근 협력을 통해 공동 코드베이스의 GPU 실행이 실현됨
구현 방식
- 예제 데모에서는 비토닉 정렬 알고리듬을 단일 Rust 코드로 구현하고, GPU와 CPU의 모든 대상으로 동일 코드가 실행됨
- 주요 컴포넌트 용어
-
Host: CPU에서 실행되는 Rust 코드(작업 시작)
-
Device: 커널이 실제로 실행되는 GPU/CPU
-
Driver API: CUDA, Vulkan, Metal, DX12 등, 장치와 통신용 저수준 API
-
Backend: 러스트에서 드라이버 API 대상으로 추상화 제공(cust, ash, wgpu 등)
- 러스트의 feature 플래그와 타깃 조합을 통해 백엔드 선택 및 빌드 제어 가능
- 예: wgpu, ash, cuda 등 각 백엔드 별 독립 빌드 옵션 제공
- 여러 백엔드를 하나의 바이너리로 빌드해 런타임에서 동적으로 선택하는 구조 구현 가능
커널 컴파일 흐름
- 타깃 및 feature에 따라 GPU 실행 바이너리(SPIR-V, PTX 등)를 빌드 시 생성, 객체 파일에 임베드됨
- 런타임에서 임베드된 커널을 로드, Naga 등을 통해 플랫폼별 요구 포맷으로 변환 후 실행
- 예:
- macOS: SPIR-V를 MSL로 변환→Metal 실행
- Windows: SPIR-V를 HLSL로 변환→DX12 실행
- Linux/Android: SPIR-V→Vulkan 실행
- CUDA: PTX를 SASS로 컴파일, GPU 업로드 및 실행
Rust 친화적 GPU 코딩 기법
no_std 지원
- GPU에는 OS 지원이 없으므로 Rust의 no_std 사용이 필수임
- 기본 Rust 생태계가 내장적으로 임베디드, 펌웨어, 커널 등 OS 없는 환경을 가정함에 따라 GPU도 별도 "특수 모드" 없이 Rust 표준 방식으로 지원 가능함
조건부 컴파일
- cfg 속성과 feature 플래그 조합으로 플랫폼 구분 코드와 GPU/CPU 구분 코드를 명확하고 간결하게 작성 가능함
- IDE와 컴파일러가 모든 코드 경로를 이해하여, 높은 코드 신뢰성 및 생산성 확보
newtype 활용
- GPU에서 실수할 수 있는 암묵적 인덱스·구조체 매핑을 newtype 사용으로 타입 레벨에서 오류 방지
- #[repr(transparent)] 속성으로 실질적인 오버헤드 없이 타입 추상화 가능
Enum과 안전한 표현
- 매직 넘버 사용 대신 Rust Enum 사용, #[repr(u32)] 적용으로 네이티브 정수 매핑 확보
- 패턴 매칭과 exhaustiveness(모든 경우 분기 처리)로 안전한 코드 구성
- 단, CPU-GPU 간 공유 버퍼에 Enum 값을 주고받을 때는 모든 값이 올바른 Enum이어야 하므로 주의 필요
Trait 기반 제네릭 알고리듬
- Trait을 이용해 다양한 값 타입에 대해 공통된 비교, 변환, 연산 등 GPU 연산 추상화 제공
- 제네릭 알고리듬에 trait bound를 명확하게 지정하여 type safety와 최적성 양립
#[inline] 및 성능 최적화
- #[inline] 사용으로 추상화 계층이 실제 컴파일 결과에서 사라지도록 유도
- GPU 특성(성능, 스택 부족 등)상 추상화의 비용이 없도록 설계됨
Struct 조합 및 의미론적 그룹화
- 복잡한 GPU 파라미터를 의미 단위로 묶어 struct로 관리, 타입 안정성 확보 및 파라미터 폭증 방지
- Smart constructor 패턴으로 invalid 상태를 컴파일 단계에서 차단
메모리 레이아웃 및 #[repr(C)] 제어
- GPU와의 데이터 호환성을 위해 #[repr(C)]로 구조체 레이아웃을 명시적으로 지정
- 향후 GPU별 padding 자동화 등 추가 언어 지원 필요성 언급
패턴 매칭
- Switch/case의 확장된 개념으로, GPU 코드 내 모든 분기 및 상태를 명확하게 처리할 수 있음
- 컴파일러에 의한 코드 경로 체크 및 성능 최적화 가능
제네릭 함수
- 데이타 타입에 구애받지 않고 여러 타입에 대해 동일 로직 구현
- trait bound, 모노모피제이션 등으로 유지보수성·테스트 용이성 강화
Derive 매크로
- Copy, Clone, Debug, PartialEq, Pod 등 GPU-적합 트레잇 자동 구현
- 안전성 및 코드 보일러플레이트 최소화
모듈 시스템, 워크스페이스 관리
- Rust의 패키지/모듈 시스템으로 호스트 코드, 커널, 타입, 백엔드 별 소스 구조화
- Cargo workspace, workspace dependency로 크레이트 간 의존성 일관성, 유지보수 편의성 확보
포매팅, 린트, 문서화
- rustfmt, clippy 등 Rust 표준 도구와 완전히 동일한 방식으로 GPU 코드 관리, 일관된 품질 유지 가능
- Doc comment, cargo doc으로 GPU 코드도 문서화
빌드 스크립트
- Cargo의 build.rs를 통해 feature flag 기반 커널 빌드 및 바이너리 임베드 자동화
유닛 테스트 및 개발 생산성
- GPU 커널 코드를 CPU에서도 테스트할 수 있어 개발 및 버그 탐지 용이
- println 디버그, gdb/lldb 등 전통 도구 사용 가능
- Vulkan 커널도 소프트웨어 드라이버(SwiftShader, lavapipe)로 CI 테스트 가능
- 테스트 및 코드 커버리지 측정, property-based 테스트 등 서드파티 도구와 원활 연동
미완성된 개발자 경험 및 과제
- GPU 백엔드가 공식 Rust 컴파일러에 내장되지 않아 별도 코드젠 백엔드(spirv, nvvm) 사용 및 nightly 버전 고정 필요
- CUDA 타깃은 NVIDIA의 LLVM 7.1에 종속적이어서 최신 리눅스 배포판에서 별도 빌드 필요
- 커널 빌드·디버깅 경험 부족, 에러 트레이싱/디버그 정보 미흡 문제가 있음
- Rust GPU와 Rust CUDA의 API, 표준 라이브러리 명칭 등이 달라 혼란 야기
- 장기적으로 Rust 언어와 생태계 전반에 GPU 위주의 일관성, 통합성 강화 필요
커뮤니티 참여 및 미래
- Rust로 모든 주요 GPU 플랫폼에서 동일 코드 실행이 실현됨
- 앞으로는 빌드 및 디버깅 개선, Rust 언어 및 API 지원 확대, 성능 튜닝 등이 과제로 남아있음
- 참여 및 기여를 원하는 개발자는 rust-gpu, rust-cuda의 GitHub 레포지토리를 참조할 것