qualia_core_db/wgsl_forge/ir/
capabilities.rs1use serde::{Deserialize, Serialize};
2
3use super::intrinsics::{Intrinsic, IntrinsicClass};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
6pub struct HardwareCapabilityMatrix {
7 pub supports_f64: bool,
14 pub subgroup_size: Option<u32>,
15 pub supports_coopmat: bool,
17 pub supports_rt_cores: bool,
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum IntrinsicSupport {
24 Native,
26 LowerToSharedMemory,
29 Exclude,
32}
33
34impl HardwareCapabilityMatrix {
35 pub const fn intrinsic_support(&self, intrinsic: &Intrinsic) -> IntrinsicSupport {
37 match intrinsic.class() {
38 IntrinsicClass::Subgroup => {
39 if self.subgroup_size.is_some() {
40 IntrinsicSupport::Native
41 } else {
42 IntrinsicSupport::LowerToSharedMemory
44 }
45 }
46 IntrinsicClass::CooperativeMatrix => {
47 if self.supports_coopmat {
48 IntrinsicSupport::Native
49 } else {
50 IntrinsicSupport::Exclude
51 }
52 }
53 IntrinsicClass::RayTracing => {
54 if self.supports_rt_cores {
55 IntrinsicSupport::Native
56 } else {
57 IntrinsicSupport::Exclude
58 }
59 }
60 }
61 }
62}
63
64#[derive(Debug, Clone, PartialEq, Eq, Hash)]
71pub enum LoweringPolicy64Bit {
72 Native,
73 PairedU32Emulation,
74}
75
76use crate::wgsl_forge::Schedule;
77
78#[derive(Debug, Clone)]
79pub struct LoweringContext {
80 pub capabilities: HardwareCapabilityMatrix,
81 pub schedule: Schedule,
82}
83
84impl LoweringContext {
85 pub fn new(capabilities: HardwareCapabilityMatrix, schedule: Schedule) -> Self {
86 Self {
87 capabilities,
88 schedule,
89 }
90 }
91
92 pub fn policy_64bit(&self) -> LoweringPolicy64Bit {
99 if self.capabilities.supports_f64 {
100 LoweringPolicy64Bit::Native
101 } else {
102 LoweringPolicy64Bit::PairedU32Emulation
103 }
104 }
105
106 pub const fn intrinsic_support(&self, intrinsic: &Intrinsic) -> IntrinsicSupport {
108 self.capabilities.intrinsic_support(intrinsic)
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115 use crate::wgsl_forge::ir::intrinsics::SubgroupReduceOp;
116
117 fn ray_query() -> Intrinsic {
118 Intrinsic::RayQuery {
119 acceleration_structure: "tlas".to_string(),
120 origin: "o".to_string(),
121 direction: "d".to_string(),
122 t_min: "tmin".to_string(),
123 t_max: "tmax".to_string(),
124 destination: "hit".to_string(),
125 }
126 }
127
128 #[test]
129 fn rt_intrinsic_excluded_without_rt_cores() {
130 let absent = HardwareCapabilityMatrix::default();
131 assert_eq!(
132 absent.intrinsic_support(&ray_query()),
133 IntrinsicSupport::Exclude
134 );
135
136 let present = HardwareCapabilityMatrix {
137 supports_rt_cores: true,
138 ..Default::default()
139 };
140 assert_eq!(
141 present.intrinsic_support(&ray_query()),
142 IntrinsicSupport::Native
143 );
144 }
145
146 #[test]
147 fn coopmat_excluded_but_subgroup_lowers() {
148 let caps = HardwareCapabilityMatrix::default();
149 assert_eq!(
150 caps.intrinsic_support(&Intrinsic::CoopMatMul {
151 m: 16,
152 n: 16,
153 k: 16
154 }),
155 IntrinsicSupport::Exclude
156 );
157 assert_eq!(
159 caps.intrinsic_support(&Intrinsic::SubgroupReduce {
160 op: SubgroupReduceOp::Add
161 }),
162 IntrinsicSupport::LowerToSharedMemory
163 );
164 }
165}