SPIR-?
⋯? ? 목표 ? ?변형? ?번역 ⋯?
스피르-? SPIR-V에서 파생된 셰이더 중심 IR 디자인을 탐색하고 기존 SPIR-V 도구가 허용하는 것 이상으로 고급 컴파일 파이프라인을 용이하게 하기 위해 그러한 IR을 중심으로 프레임워크를 생성하는 것을 목표로 하는 연구 프로젝트입니다.
이러한 필요성은 형식화되지 않은 메모리에서 작동하는 범용(Rust 1 ) 코드를 GPU 친화적인 직접 데이터 흐름으로 전환하기 위해 다양한 합법화 패스가 필요한 Rust-GPU 프로젝트에서 발생했습니다.
우리의 목표는 기존 Rust-GPU SPIR-V 합법화 패스를 SPIR-? 등가물 - 그러나 훨씬 더 중요한 것은 SPIR-? 훨씬 더 강력한 합법화/최적화 패스를 작성할 수 있어야 하며 이는 SPIR-V를 직접 조작하기에는 불가능 합니다.
1 Rust는 여기서 요구 사항이 독특하지 않으며 결국 더 많은 언어(또는 IR)가 이러한 프레임워크를 사용할 수 있지만 초기 설계 및 구현 작업은 Rust-GPU에 중점을 두었습니다.
2 완전히 불가능하지는 않지만 과도한 개발/유지 비용이 필요하고 정확성과 성능의 균형을 지속적으로 유지해야 합니다(보다 보수적인 패스가 신뢰하기 더 쉽습니다).
이 프로젝트는 Khronos Group Inc. 또는 그 자회사 또는 계열사와 제휴, 연관, 승인, 보증 또는 어떤 방식으로든 공식적으로 연결되어 있지 않습니다. 공식 Khronos Group Inc. 웹사이트는 https://www.khronos.org에서 확인할 수 있습니다.
SPIR, SPIR-V라는 이름과 관련 이름, 마크, 엠블럼, 이미지는 해당 소유자의 상표입니다.
추가 맥락: 이 프로젝트의 이름은 SPIR-V에 대한 말장난이며 SPIR(이전 IR 표준)과는 전혀 관련이 없습니다.
? 이 프로젝트는 적극적으로 설계 및 개발 중이므로 많은 세부 사항이 변경될 수 있고 변경될 것 입니다.
SPIR- 사용에 관심이 있으신가요? 먼저 관련 문제에 대한 문제 추적기를 살펴보고 사용 사례를 설명하는 새 항목을 열어볼 수도 있습니다.
Rust-GPU의 사용 사례에 대한 초기 초점으로 인해 다양한(그렇지 않으면 바람직한) 기능/API/문서가 부족하거나 빠르게 변화할 수 있습니다. 동시에 SPIR-? 의 범위와 유용성을 확대하는 것에 대한 논의가 진행되고 있습니다. 장기적으로는 여전히 환영합니다.
Kernel
방언 지원Kernel
SPIR-V는 Shader
SPIR-V보다 LLVM IR에 훨씬 더 가깝기 때문에 LLVM 중심의 도구가 더 적합할 가능성이 높습니다.IR 데이터 유형 :
| 프레임워크 유틸리티 :
패스(SPIR-?로/에서/으로) :
|
GLSL ( #version 450
out int output0;
void main() {
int o = 1 ;
for ( int i = 1 ; i < 10 ; i ++ )
o *= i;
output0 = o;
} WGSL ( @vertex
fn main() -> @location( 0 ) i32 {
var o : i32 = 1 ;
for (var i : i32 = 1 ; i < 10 ; i ++ ) {
o *= i;
}
return o;
} | 스피르-? #[spv.Decoration.Flat]
#[spv.Decoration.Location(Location: 0 )]
global_var GV0 in spv.StorageClass.Output: s32
func F0 () -> spv.OpTypeVoid {
loop (v0: s32 <- 1s32, v1: s32 <- 1s32) {
v2 = spv. OpSLessThan (v1, 10s32): bool
(v3: s32, v4: s32) = if v2 {
v5 = spv. OpIMul (v0, v1): s32
v6 = spv. OpIAdd (v1, 1s32): s32
(v5, v6)
} else {
(spv. OpUndef : s32, spv. OpUndef : s32)
}
(v3, v4) -> (v0, v1)
} while v2
spv. OpStore (Pointer: &GV0, Object: v0)
} | SPIR-V ( %typeof_output0 = OpTypePointer Output %i32
%output0 = OpVariable %typeof_output0 Output
%typeof_main = OpTypeFunction %void
%main = OpFunction %void None %typeof_main
%entry = OpLabel
OpBranch %bb0
%bb0 = OpLabel
OpBranch %bb1
%bb1 = OpLabel
%o = OpPhi %i32 %1 _i32 %bb0 %o_next %bb5
%i = OpPhi %i32 %0 _i32 %bb0 %i_next %bb5
OpLoopMerge %bb6 %bb5 None
OpBranch %bb2
%bb2 = OpLabel
%cond = OpSLessThan %bool %i %10 _i32
OpSelectionMerge %bb4 None
OpBranchConditional %cond %bb4 %bb3
%bb3 = OpLabel
OpBranch %bb6
%bb4 = OpLabel
%o_next = OpIMul %i32 %o %i
OpBranch %bb5
%bb5 = OpLabel
%i_next = OpIAdd %i32 %i %1 _i32
OpBranch %bb1
%bb6 = OpLabel
OpStore %output0 %o
OpReturn
OpFunctionEnd |
(그리고 SPIR-?가 어떻게 여기에 들어맞는지에 대한 비전)
여기서 구별되는 사항은 다음과 같습니다.
우리는 이 프로젝트에 대한 커뮤니티의 기여를 환영합니다.
시작하는 방법에 대한 자세한 내용은 기여자 가이드를 읽어보세요. 기여하기 전에 기여자 약관도 읽어보시기 바랍니다.
Embark Studios 프로젝트에 포함하기 위해 의도적으로 제출된 모든 기여는 Rust 표준 라이선스 모델(MIT 또는 Apache 2.0)을 준수해야 하므로 추가 약관 없이 아래 설명된 대로 이중 라이선스가 부여됩니다.
이 기여는 다음 중 하나에 따라 이중 라이선스가 부여됩니다.
귀하의 선택에 따라.
명확하게 말하면, "귀하의"는 Embark 또는 해당 기여의 기타 라이센스 수혜자/사용자를 의미합니다.