1use crate::{verification::*, GpuCliffordAlgebra};
8use std::time::{Duration, Instant};
9use thiserror::Error;
10
11#[derive(Error, Debug)]
12pub enum AdaptiveVerificationError {
13 #[error("Platform detection failed: {0}")]
14 PlatformDetection(String),
15
16 #[error("GPU verification failed: {0}")]
17 GpuVerification(#[from] GpuVerificationError),
18
19 #[error("No suitable verification strategy available")]
20 NoSuitableStrategy,
21
22 #[error("Performance constraint violation: {constraint}")]
23 PerformanceConstraint { constraint: String },
24}
25
26#[derive(Debug, Clone, PartialEq)]
28pub enum VerificationPlatform {
29 NativeCpu { features: CpuFeatures },
31 Gpu {
33 backend: GpuBackend,
34 memory_mb: u64,
35 compute_units: u32,
36 },
37 Wasm { env: WasmEnvironment },
39}
40
41#[derive(Debug, Clone, PartialEq)]
42pub struct CpuFeatures {
43 pub supports_simd: bool,
44 pub core_count: usize,
45 pub cache_size_kb: u64,
46}
47
48#[derive(Debug, Clone, PartialEq)]
49pub enum GpuBackend {
50 Vulkan,
51 Metal,
52 Dx12,
53 OpenGL,
54 WebGpu,
55}
56
57#[derive(Debug, Clone, PartialEq)]
58pub enum WasmEnvironment {
59 Browser { engine: String },
60 NodeJs { version: String },
61 Standalone,
62}
63
64#[derive(Debug, Clone, PartialEq)]
66pub enum AdaptiveVerificationLevel {
67 Maximum,
69 High,
71 Balanced,
73 Minimal,
75 Debug,
77}
78
79pub struct AdaptiveVerifier {
81 platform: VerificationPlatform,
82 verification_level: AdaptiveVerificationLevel,
83 performance_budget: Duration,
84 boundary_verifier: Option<GpuBoundaryVerifier>,
85 gpu_instance: Option<GpuCliffordAlgebra>,
86}
87
88impl AdaptiveVerifier {
89 pub async fn new() -> Result<Self, AdaptiveVerificationError> {
91 let platform = Self::detect_platform().await?;
92 let verification_level = Self::determine_verification_level(&platform);
93 let performance_budget = Self::determine_performance_budget(&platform);
94
95 let (boundary_verifier, gpu_instance) = match &platform {
96 VerificationPlatform::Gpu { .. } => {
97 let config = Self::create_gpu_verification_config(&platform, &verification_level);
98 let verifier = GpuBoundaryVerifier::new(config);
99 let gpu = GpuCliffordAlgebra::new::<3, 0, 0>().await.ok();
100 (Some(verifier), gpu)
101 }
102 _ => (None, None),
103 };
104
105 Ok(Self {
106 platform,
107 verification_level,
108 performance_budget,
109 boundary_verifier,
110 gpu_instance,
111 })
112 }
113
114 pub async fn with_config(
116 level: AdaptiveVerificationLevel,
117 budget: Duration,
118 ) -> Result<Self, AdaptiveVerificationError> {
119 let platform = Self::detect_platform().await?;
120
121 let (boundary_verifier, gpu_instance) = match &platform {
122 VerificationPlatform::Gpu { .. } => {
123 let config = Self::create_gpu_verification_config(&platform, &level);
124 let verifier = GpuBoundaryVerifier::new(config);
125 let gpu = GpuCliffordAlgebra::new::<3, 0, 0>().await.ok();
126 (Some(verifier), gpu)
127 }
128 _ => (None, None),
129 };
130
131 Ok(Self {
132 platform,
133 verification_level: level,
134 performance_budget: budget,
135 boundary_verifier,
136 gpu_instance,
137 })
138 }
139
140 pub async fn verified_geometric_product<const P: usize, const Q: usize, const R: usize>(
142 &mut self,
143 a: &VerifiedMultivector<P, Q, R>,
144 b: &VerifiedMultivector<P, Q, R>,
145 ) -> Result<VerifiedMultivector<P, Q, R>, AdaptiveVerificationError> {
146 let start_time = Instant::now();
147
148 let result = match &self.platform {
149 VerificationPlatform::NativeCpu { .. } => {
150 self.cpu_verification(a, b).await?
152 }
153 VerificationPlatform::Gpu { .. } => {
154 self.cpu_verification(a, b).await?
156 }
157 VerificationPlatform::Wasm { .. } => {
158 self.wasm_runtime_verification(a, b).await?
160 }
161 };
162
163 let elapsed = start_time.elapsed();
164 if elapsed > self.performance_budget {
165 return Err(AdaptiveVerificationError::PerformanceConstraint {
166 constraint: format!(
167 "Operation exceeded budget: {:?} > {:?}",
168 elapsed, self.performance_budget
169 ),
170 });
171 }
172
173 Ok(result)
174 }
175
176 pub async fn verified_batch_geometric_product<
178 const P: usize,
179 const Q: usize,
180 const R: usize,
181 >(
182 &mut self,
183 a_batch: &[VerifiedMultivector<P, Q, R>],
184 b_batch: &[VerifiedMultivector<P, Q, R>],
185 ) -> Result<Vec<VerifiedMultivector<P, Q, R>>, AdaptiveVerificationError> {
186 if a_batch.len() != b_batch.len() {
187 return Err(AdaptiveVerificationError::NoSuitableStrategy);
188 }
189 if a_batch.is_empty() {
190 return Ok(Vec::new());
191 }
192
193 match &self.platform {
194 VerificationPlatform::NativeCpu { .. } => {
195 self.cpu_batch_verification(a_batch, b_batch).await
197 }
198 VerificationPlatform::Gpu { .. } => {
199 self.gpu_batch_verification(a_batch, b_batch).await
201 }
202 VerificationPlatform::Wasm { .. } => {
203 self.wasm_batch_verification(a_batch, b_batch).await
205 }
206 }
207 }
208
209 pub fn platform(&self) -> &VerificationPlatform {
211 &self.platform
212 }
213
214 pub fn verification_level(&self) -> &AdaptiveVerificationLevel {
216 &self.verification_level
217 }
218
219 pub fn performance_budget(&self) -> Duration {
221 self.performance_budget
222 }
223
224 pub fn should_use_gpu(&self, batch_size: usize) -> bool {
226 match &self.platform {
227 VerificationPlatform::Gpu {
228 compute_units,
229 memory_mb,
230 ..
231 } => {
232 let min_batch_size = match &self.verification_level {
234 AdaptiveVerificationLevel::Maximum => 500,
235 AdaptiveVerificationLevel::High => 200,
236 AdaptiveVerificationLevel::Balanced => 100,
237 AdaptiveVerificationLevel::Minimal => 50,
238 AdaptiveVerificationLevel::Debug => 1000, };
240
241 let capability_factor = (*compute_units as f64 / 16.0).clamp(0.5, 4.0);
243 let memory_factor = (*memory_mb as f64 / 1024.0).clamp(0.5, 2.0);
244 let adjusted_threshold =
245 (min_batch_size as f64 / (capability_factor * memory_factor)) as usize;
246
247 batch_size >= adjusted_threshold
248 }
249 _ => false,
250 }
251 }
252
253 pub fn set_verification_level(&mut self, level: AdaptiveVerificationLevel) {
255 if let Some(ref mut verifier) = self.boundary_verifier {
257 let new_config = Self::create_gpu_verification_config(&self.platform, &level);
258 *verifier = GpuBoundaryVerifier::new(new_config);
259 }
260
261 self.verification_level = level;
262 }
263
264 async fn detect_platform() -> Result<VerificationPlatform, AdaptiveVerificationError> {
268 if std::env::var_os("AMARI_GPU_FORCE_CPU").is_some() {
269 let features = Self::detect_cpu_features();
270 return Ok(VerificationPlatform::NativeCpu { features });
271 }
272
273 let gpu_platform = {
275 let panic_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
277 pollster::block_on(async {
279 if GpuCliffordAlgebra::new::<3, 0, 0>().await.is_ok() {
281 let backend = Self::detect_gpu_backend();
282 let (memory_mb, compute_units) = Self::estimate_gpu_capabilities().await;
283 Some(VerificationPlatform::Gpu {
284 backend,
285 memory_mb,
286 compute_units,
287 })
288 } else {
289 None
290 }
291 })
292 }));
293
294 panic_result.unwrap_or(None)
296 };
297
298 if let Some(platform) = gpu_platform {
299 return Ok(platform);
300 }
301
302 if cfg!(target_arch = "wasm32") {
304 let env = Self::detect_wasm_environment();
305 return Ok(VerificationPlatform::Wasm { env });
306 }
307
308 let features = Self::detect_cpu_features();
310 Ok(VerificationPlatform::NativeCpu { features })
311 }
312
313 fn detect_gpu_backend() -> GpuBackend {
315 if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
317 GpuBackend::Metal
318 } else if cfg!(target_os = "windows") {
319 GpuBackend::Dx12
320 } else if cfg!(target_arch = "wasm32") {
321 GpuBackend::WebGpu
322 } else {
323 GpuBackend::Vulkan
324 }
325 }
326
327 async fn estimate_gpu_capabilities() -> (u64, u32) {
329 (1024, 16) }
333
334 fn detect_wasm_environment() -> WasmEnvironment {
336 WasmEnvironment::Browser {
338 engine: "Unknown".to_string(),
339 }
340 }
341
342 fn detect_cpu_features() -> CpuFeatures {
344 CpuFeatures {
345 supports_simd: true, core_count: std::thread::available_parallelism()
347 .map(|n| n.get())
348 .unwrap_or(4),
349 cache_size_kb: 8192, }
351 }
352
353 fn determine_verification_level(platform: &VerificationPlatform) -> AdaptiveVerificationLevel {
355 match platform {
356 VerificationPlatform::NativeCpu { features } => {
357 if features.core_count >= 8 {
358 AdaptiveVerificationLevel::High
359 } else {
360 AdaptiveVerificationLevel::Balanced
361 }
362 }
363 VerificationPlatform::Gpu { compute_units, .. } => {
364 if *compute_units >= 32 {
365 AdaptiveVerificationLevel::Balanced
366 } else {
367 AdaptiveVerificationLevel::Minimal
368 }
369 }
370 VerificationPlatform::Wasm { .. } => {
371 AdaptiveVerificationLevel::Minimal
373 }
374 }
375 }
376
377 fn determine_performance_budget(platform: &VerificationPlatform) -> Duration {
379 match platform {
380 VerificationPlatform::NativeCpu { .. } => Duration::from_millis(50),
381 VerificationPlatform::Gpu { .. } => Duration::from_millis(20),
382 VerificationPlatform::Wasm { .. } => Duration::from_millis(100),
383 }
384 }
385
386 fn create_gpu_verification_config(
388 platform: &VerificationPlatform,
389 level: &AdaptiveVerificationLevel,
390 ) -> VerificationConfig {
391 let strategy = match level {
392 AdaptiveVerificationLevel::Maximum => VerificationStrategy::Strict,
393 AdaptiveVerificationLevel::High => {
394 VerificationStrategy::Statistical { sample_rate: 0.2 }
395 }
396 AdaptiveVerificationLevel::Balanced => {
397 VerificationStrategy::Statistical { sample_rate: 0.1 }
398 }
399 AdaptiveVerificationLevel::Minimal => VerificationStrategy::Boundary,
400 AdaptiveVerificationLevel::Debug => VerificationStrategy::Strict,
401 };
402
403 let budget = Self::determine_performance_budget(platform);
404
405 VerificationConfig {
406 strategy,
407 performance_budget: budget,
408 tolerance: 1e-12,
409 enable_invariant_checking: !matches!(level, AdaptiveVerificationLevel::Minimal),
410 }
411 }
412
413 async fn cpu_verification<const P: usize, const Q: usize, const R: usize>(
415 &self,
416 a: &VerifiedMultivector<P, Q, R>,
417 b: &VerifiedMultivector<P, Q, R>,
418 ) -> Result<VerifiedMultivector<P, Q, R>, AdaptiveVerificationError> {
419 let result = a.inner().geometric_product(b.inner());
421 let verified_result = VerifiedMultivector::new(result);
422
423 match self.verification_level {
425 AdaptiveVerificationLevel::Maximum | AdaptiveVerificationLevel::Debug => {
426 verified_result.verify_invariants()?;
427 self.verify_geometric_product_properties(a, b, &verified_result)?;
429 }
430 AdaptiveVerificationLevel::High => {
431 verified_result.verify_invariants()?;
432 }
433 _ => {
434 }
436 }
437
438 Ok(verified_result)
439 }
440
441 async fn cpu_batch_verification<const P: usize, const Q: usize, const R: usize>(
443 &self,
444 a_batch: &[VerifiedMultivector<P, Q, R>],
445 b_batch: &[VerifiedMultivector<P, Q, R>],
446 ) -> Result<Vec<VerifiedMultivector<P, Q, R>>, AdaptiveVerificationError> {
447 let mut results = Vec::with_capacity(a_batch.len());
448
449 for (a, b) in a_batch.iter().zip(b_batch.iter()) {
450 let result = self.cpu_verification(a, b).await?;
451 results.push(result);
452 }
453
454 Ok(results)
455 }
456
457 async fn gpu_batch_verification<const P: usize, const Q: usize, const R: usize>(
459 &mut self,
460 a_batch: &[VerifiedMultivector<P, Q, R>],
461 b_batch: &[VerifiedMultivector<P, Q, R>],
462 ) -> Result<Vec<VerifiedMultivector<P, Q, R>>, AdaptiveVerificationError> {
463 if !self.should_use_gpu(a_batch.len()) {
464 return self.cpu_batch_verification(a_batch, b_batch).await;
465 }
466
467 if let (Some(ref mut verifier), Some(ref gpu)) =
468 (&mut self.boundary_verifier, &self.gpu_instance)
469 {
470 verifier
471 .verified_batch_geometric_product(gpu, a_batch, b_batch)
472 .await
473 .map_err(AdaptiveVerificationError::GpuVerification)
474 } else {
475 self.cpu_batch_verification(a_batch, b_batch).await
477 }
478 }
479
480 async fn wasm_runtime_verification<const P: usize, const Q: usize, const R: usize>(
482 &self,
483 a: &VerifiedMultivector<P, Q, R>,
484 b: &VerifiedMultivector<P, Q, R>,
485 ) -> Result<VerifiedMultivector<P, Q, R>, AdaptiveVerificationError> {
486 if VerifiedMultivector::<P, Q, R>::signature() != (P, Q, R) {
488 return Err(AdaptiveVerificationError::GpuVerification(
489 GpuVerificationError::SignatureMismatch {
490 expected: (P, Q, R),
491 actual: VerifiedMultivector::<P, Q, R>::signature(),
492 },
493 ));
494 }
495
496 let result = a.inner().geometric_product(b.inner());
498 let verified_result = VerifiedMultivector::new(result);
499
500 if !verified_result.inner().magnitude().is_finite() {
502 return Err(AdaptiveVerificationError::GpuVerification(
503 GpuVerificationError::InvariantViolation {
504 invariant: "Result magnitude must be finite".to_string(),
505 },
506 ));
507 }
508
509 Ok(verified_result)
510 }
511
512 async fn wasm_batch_verification<const P: usize, const Q: usize, const R: usize>(
514 &self,
515 a_batch: &[VerifiedMultivector<P, Q, R>],
516 b_batch: &[VerifiedMultivector<P, Q, R>],
517 ) -> Result<Vec<VerifiedMultivector<P, Q, R>>, AdaptiveVerificationError> {
518 let mut results = Vec::with_capacity(a_batch.len());
519
520 for (a, b) in a_batch.iter().zip(b_batch.iter()) {
521 let result = self.wasm_runtime_verification(a, b).await?;
522 results.push(result);
523 }
524
525 Ok(results)
526 }
527
528 fn verify_geometric_product_properties<const P: usize, const Q: usize, const R: usize>(
530 &self,
531 a: &VerifiedMultivector<P, Q, R>,
532 b: &VerifiedMultivector<P, Q, R>,
533 result: &VerifiedMultivector<P, Q, R>,
534 ) -> Result<(), AdaptiveVerificationError> {
535 let result_mag = result.inner().magnitude();
537 let a_mag = a.inner().magnitude();
538 let b_mag = b.inner().magnitude();
539
540 if result_mag > a_mag * b_mag + 1e-12 {
541 return Err(AdaptiveVerificationError::GpuVerification(
542 GpuVerificationError::InvariantViolation {
543 invariant: format!(
544 "Magnitude inequality violated: {} > {} * {}",
545 result_mag, a_mag, b_mag
546 ),
547 },
548 ));
549 }
550
551 Ok(())
552 }
553}
554
555pub trait PlatformCapabilities {
557 fn max_batch_size(&self) -> usize;
559
560 fn optimal_strategy(&self, workload_size: usize) -> VerificationStrategy;
562
563 fn supports_concurrent_verification(&self) -> bool;
565
566 fn performance_characteristics(&self) -> PlatformPerformanceProfile;
568}
569
570#[derive(Debug, Clone)]
571pub struct PlatformPerformanceProfile {
572 pub verification_overhead_percent: f64,
573 pub memory_bandwidth_gbps: f64,
574 pub compute_throughput_gflops: f64,
575 pub latency_microseconds: f64,
576}
577
578impl PlatformCapabilities for VerificationPlatform {
579 fn max_batch_size(&self) -> usize {
580 match self {
581 VerificationPlatform::NativeCpu { features } => features.core_count * 1000,
582 VerificationPlatform::Gpu { memory_mb, .. } => {
583 (*memory_mb as usize * 1024 * 1024) / (8 * 64) }
585 VerificationPlatform::Wasm { .. } => {
586 10000 }
588 }
589 }
590
591 fn optimal_strategy(&self, workload_size: usize) -> VerificationStrategy {
592 match self {
593 VerificationPlatform::NativeCpu { .. } => {
594 if workload_size < 100 {
595 VerificationStrategy::Strict
596 } else {
597 VerificationStrategy::Statistical { sample_rate: 0.1 }
598 }
599 }
600 VerificationPlatform::Gpu { .. } => {
601 if workload_size < 50 {
602 VerificationStrategy::Boundary
603 } else {
604 VerificationStrategy::Statistical { sample_rate: 0.05 }
605 }
606 }
607 VerificationPlatform::Wasm { .. } => {
608 VerificationStrategy::Statistical { sample_rate: 0.02 }
609 }
610 }
611 }
612
613 fn supports_concurrent_verification(&self) -> bool {
614 match self {
615 VerificationPlatform::NativeCpu { features } => features.core_count > 1,
616 VerificationPlatform::Gpu { .. } => true,
617 VerificationPlatform::Wasm { .. } => false, }
619 }
620
621 fn performance_characteristics(&self) -> PlatformPerformanceProfile {
622 match self {
623 VerificationPlatform::NativeCpu { features } => PlatformPerformanceProfile {
624 verification_overhead_percent: 5.0,
625 memory_bandwidth_gbps: 50.0,
626 compute_throughput_gflops: features.core_count as f64 * 100.0,
627 latency_microseconds: 1.0,
628 },
629 VerificationPlatform::Gpu { compute_units, .. } => PlatformPerformanceProfile {
630 verification_overhead_percent: 15.0,
631 memory_bandwidth_gbps: 200.0,
632 compute_throughput_gflops: *compute_units as f64 * 50.0,
633 latency_microseconds: 100.0,
634 },
635 VerificationPlatform::Wasm { .. } => PlatformPerformanceProfile {
636 verification_overhead_percent: 25.0,
637 memory_bandwidth_gbps: 10.0,
638 compute_throughput_gflops: 10.0,
639 latency_microseconds: 1000.0,
640 },
641 }
642 }
643}
644
645#[cfg(test)]
646mod tests {
647 use super::*;
648
649 #[test]
650 fn test_cpu_features_detection() {
651 let features = AdaptiveVerifier::detect_cpu_features();
652 assert!(features.core_count > 0);
653 assert!(features.cache_size_kb > 0);
654 }
655
656 #[test]
657 fn test_verification_level_determination() {
658 let cpu_platform = VerificationPlatform::NativeCpu {
659 features: CpuFeatures {
660 supports_simd: true,
661 core_count: 8,
662 cache_size_kb: 8192,
663 },
664 };
665
666 let level = AdaptiveVerifier::determine_verification_level(&cpu_platform);
667 assert_eq!(level, AdaptiveVerificationLevel::High);
668
669 let gpu_platform = VerificationPlatform::Gpu {
670 backend: GpuBackend::Vulkan,
671 memory_mb: 2048,
672 compute_units: 16,
673 };
674
675 let level = AdaptiveVerifier::determine_verification_level(&gpu_platform);
676 assert_eq!(level, AdaptiveVerificationLevel::Minimal);
677 }
678
679 #[test]
680 fn test_platform_capabilities() {
681 let platform = VerificationPlatform::NativeCpu {
682 features: CpuFeatures {
683 supports_simd: true,
684 core_count: 4,
685 cache_size_kb: 8192,
686 },
687 };
688
689 assert_eq!(platform.max_batch_size(), 4000);
690 assert!(platform.supports_concurrent_verification());
691
692 let profile = platform.performance_characteristics();
693 assert_eq!(profile.verification_overhead_percent, 5.0);
694 assert_eq!(profile.compute_throughput_gflops, 400.0);
695 }
696
697 #[tokio::test]
698 #[ignore = "GPU hardware required, may fail in CI/CD environments"]
699 async fn test_adaptive_verifier_creation() {
700 match AdaptiveVerifier::new().await {
702 Ok(verifier) => {
703 assert!(verifier.performance_budget() > Duration::ZERO);
704 }
705 Err(AdaptiveVerificationError::PlatformDetection(_)) => {
706 }
708 Err(e) => panic!("Unexpected error: {:?}", e),
709 }
710 }
711
712 #[tokio::test]
713 async fn test_verification_with_config() {
714 std::env::set_var("AMARI_GPU_FORCE_CPU", "1");
718 match AdaptiveVerifier::with_config(
719 AdaptiveVerificationLevel::Minimal,
720 Duration::from_millis(5),
721 )
722 .await
723 {
724 Ok(verifier) => {
725 assert_eq!(
727 *verifier.verification_level(),
728 AdaptiveVerificationLevel::Minimal
729 );
730 assert_eq!(verifier.performance_budget(), Duration::from_millis(5));
731
732 assert!(matches!(
733 verifier.platform(),
734 VerificationPlatform::NativeCpu { .. }
735 ));
736 println!("✅ CPU verification platform detected via forced fallback");
737 }
738 Err(e) => {
739 std::env::remove_var("AMARI_GPU_FORCE_CPU");
740 panic!("Adaptive verifier should not fail, but got: {:?}", e);
742 }
743 }
744
745 std::env::remove_var("AMARI_GPU_FORCE_CPU");
746 }
747}