facet을 활용한 WebGPU 데이터 구조체 레이아웃 자동 검증
Testing WebGPU data layouts with Facet
Hacker NewsWebGPU 컴퓨트 셰이더에서 호스트(Rust)와 GPU(WGSL) 간 데이터를 공유할 때, 메모리 패딩 및 구조체 레이아웃 차이로 인해 오프셋 불일치 문제가 발생합니다.
- 개발자는 이 문제를 해결하기 위해 런타임 리플렉션 기능을 제공하는 `facet` 라이브러리를 도입하여 구조체의 레이아웃을 자동으로 비교 검증할 수 있게 되었습니다.
- `facet`은 Rust의 타입 정보를 기반으로 WGSL 구조체와 오프셋 및 크기를 정밀하게 대조하며, 복잡한 데이터 로딩 오류를 사전에 발견합니다.
- 이를 통해 컴퓨트 셰이더 환경에서 CPU-GPU 간의 데이터 일관성을 보장하여 시스템 안정성과 개발 신뢰도를 크게 높일 수 있습니다.
WebGPU 컴퓨트 셰이더 환경에서 호스트(Rust)와 셰이더 언어(WGSL) 간에 설정 데이터를 공유할 때, 메모리 패딩 및 자료형 규칙의 차이로 인해 구조체 레이아웃 오프셋 불일치 문제가 발생합니다. 예를 들어, Rust에서 정의된 `[[f32; 3]; 3]` 형태의 행렬은 타이트하게 패킹되어 36바이트를 차지하는 반면, WGSL에서는 각 행마다 4바이트의 패딩이 적용되어 전체 크기가 48바이트로 계산되는 오프셋 불일치 문제가 발견되었습니다.
초기에는 `naga` 라이브러리를 사용하여 수동으로 구조체 멤버들을 순회하며 Rust의 `std::mem::offset_of!` 결과와 WGSL의 오프셋을 비교하는 단위 테스트를 작성했습니다. 이 방법은 문제를 찾아내는 데 효과적이었으나, 모든 구성 객체의 멤버를 하드코딩해야 했고, 여러 설정 객체를 관리할 때마다 수동으로 코드를 유지보수해야 하는 어려움이 있었습니다.
이러한 한계를 극복하기 위해 런타임 리플렉션 기능을 제공하는 `facet` 라이브러리를 도입했습니다. 이 라이브러리는 구조체에 `#[derive(facet::Facet)]` 어노테이션을 추가함으로써, WGSL 파싱 결과와 Rust의 타입 정보를 기반으로 전체 구조체의 크기 및 각 필드의 오프셋과 크기를 자동으로 비교 검증하는 범용적인 체크 함수를 구현할 수 있게 했습니다. 특히 마지막 멤버가 런타임 크기 배열인 경우에도 정확한 크기 계산이 가능합니다.
결과적으로, 이 자동화된 구조체 레이아웃 검사기는 여러 개의 컴퓨트 셰이더에 사용되는 다양한 설정 객체(Config)의 데이터 일관성을 쉽게 보장할 수 있게 했습니다. 개발자는 새로운 컴퓨트 셰이더를 추가할 때마다 복잡한 메모리 레이아웃을 수동으로 검증할 필요 없이, 이 유틸리티 함수를 통해 시스템 안정성과 데이터 로딩의 정확도를 높일 수 있습니다.