amari 0.12.3

Advanced mathematical computing library with geometric algebra, tropical algebra, and automatic differentiation
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
//! Phase 4B: GPU-Compatible Verification Contracts
//!
//! This module implements verification contracts specifically designed for GPU environments
//! where traditional phantom types face significant constraints. The design focuses on
//! boundary verification, performance-aware checking, and platform-adaptive strategies.

use std::marker::PhantomData;
use std::time::{Duration, Instant};
use amari_core::Multivector;

/// GPU-specific verification constraints and limitations
#[derive(Debug, Clone, Copy)]
pub struct GpuConstraints {
    /// Maximum memory overhead for verification data (in bytes)
    pub max_memory_overhead: u64,
    /// Maximum compute overhead per operation (in microseconds)
    pub max_compute_overhead_us: u64,
    /// SIMT execution compatibility requirement
    pub simt_compatible: bool,
    /// GPU memory hierarchy considerations
    pub memory_tier: GpuMemoryTier,
}

/// GPU memory hierarchy tiers with different verification strategies
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum GpuMemoryTier {
    /// Registers - no verification overhead allowed
    Register,
    /// Shared memory - minimal verification
    Shared,
    /// Global memory - bounded verification
    Global,
    /// Host memory - full verification available
    Host,
}

/// Verification error types specific to GPU environments
#[derive(Debug, Clone)]
pub enum GpuVerificationError {
    /// Memory tier constraint violation
    MemoryTierViolation { tier: GpuMemoryTier, operation: String },
    /// SIMT execution divergence detected
    SimtDivergence { warp_id: u32, thread_mask: u32 },
    /// GPU resource exhaustion
    ResourceExhaustion { resource: String, limit: u64 },
    /// Kernel execution failure
    KernelFailure { kernel: String, error: String },
    /// Mathematical invariant violation detected at GPU boundary
    BoundaryInvariantViolation { operation: String, details: String },
}

/// GPU-aware verification level that adapts to hardware constraints
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum GpuVerificationLevel {
    /// No verification - maximum performance
    None,
    /// Boundary-only verification at kernel launch/completion
    Boundary,
    /// Statistical verification using warp-level sampling
    WarpSampling { sample_rate: f32 },
    /// Thread-block level verification
    BlockLevel,
    /// Full verification (host-side only)
    HostSide,
}

/// GPU verification context that manages verification across device/host boundary
pub struct GpuVerificationContext<const P: usize, const Q: usize, const R: usize> {
    constraints: GpuConstraints,
    level: GpuVerificationLevel,
    device_verification_enabled: bool,
    host_verification_enabled: bool,
    operation_count: u64,
    total_overhead: Duration,
    _phantom: PhantomData<(P, Q, R)>,
}

impl<const P: usize, const Q: usize, const R: usize> GpuVerificationContext<P, Q, R> {
    /// Create GPU verification context with hardware detection
    pub fn new(constraints: GpuConstraints) -> Self {
        let level = Self::determine_optimal_gpu_level(constraints);

        Self {
            constraints,
            level,
            device_verification_enabled: Self::can_verify_on_device(constraints),
            host_verification_enabled: true,
            operation_count: 0,
            total_overhead: Duration::ZERO,
            _phantom: PhantomData,
        }
    }

    /// Determine optimal verification level based on GPU constraints
    fn determine_optimal_gpu_level(constraints: GpuConstraints) -> GpuVerificationLevel {
        match constraints.memory_tier {
            GpuMemoryTier::Register => GpuVerificationLevel::None,
            GpuMemoryTier::Shared => {
                if constraints.max_compute_overhead_us < 10 {
                    GpuVerificationLevel::None
                } else {
                    GpuVerificationLevel::Boundary
                }
            }
            GpuMemoryTier::Global => {
                if constraints.simt_compatible {
                    GpuVerificationLevel::WarpSampling { sample_rate: 0.1 }
                } else {
                    GpuVerificationLevel::BlockLevel
                }
            }
            GpuMemoryTier::Host => GpuVerificationLevel::HostSide,
        }
    }

    /// Check if verification can be performed on device
    fn can_verify_on_device(constraints: GpuConstraints) -> bool {
        constraints.max_memory_overhead > 1024 && // At least 1KB overhead allowed
        constraints.max_compute_overhead_us > 50   // At least 50 microseconds allowed
    }

    /// Verify GPU kernel launch with pre-conditions
    pub async fn verify_kernel_launch(
        &mut self,
        kernel_name: &str,
        input_data: &[Multivector<P, Q, R>],
    ) -> Result<(), GpuVerificationError> {
        let start = Instant::now();
        self.operation_count += 1;

        match self.level {
            GpuVerificationLevel::None => Ok(()),
            GpuVerificationLevel::Boundary |
            GpuVerificationLevel::WarpSampling { .. } |
            GpuVerificationLevel::BlockLevel => {
                self.verify_kernel_preconditions(kernel_name, input_data).await
            }
            GpuVerificationLevel::HostSide => {
                self.verify_host_preconditions(kernel_name, input_data).await
            }
        }?;

        self.total_overhead += start.elapsed();
        Ok(())
    }

    /// Verify GPU kernel completion with post-conditions
    pub async fn verify_kernel_completion(
        &mut self,
        kernel_name: &str,
        output_data: &[Multivector<P, Q, R>],
    ) -> Result<(), GpuVerificationError> {
        let start = Instant::now();

        match self.level {
            GpuVerificationLevel::None => Ok(()),
            GpuVerificationLevel::Boundary |
            GpuVerificationLevel::WarpSampling { .. } |
            GpuVerificationLevel::BlockLevel => {
                self.verify_kernel_postconditions(kernel_name, output_data).await
            }
            GpuVerificationLevel::HostSide => {
                self.verify_host_postconditions(kernel_name, output_data).await
            }
        }?;

        self.total_overhead += start.elapsed();
        Ok(())
    }

    /// Verify memory transfer from host to device
    pub async fn verify_host_to_device_transfer(
        &mut self,
        data: &[Multivector<P, Q, R>],
    ) -> Result<(), GpuVerificationError> {
        // Verify data integrity before GPU transfer
        for (i, mv) in data.iter().enumerate() {
            if !mv.magnitude().is_finite() {
                return Err(GpuVerificationError::BoundaryInvariantViolation {
                    operation: "host_to_device_transfer".to_string(),
                    details: format!("Non-finite magnitude at index {}", i),
                });
            }

            // Check for NaN or infinity in coefficients
            for j in 0..8 {
                let coeff = mv.get(j);
                if !coeff.is_finite() {
                    return Err(GpuVerificationError::BoundaryInvariantViolation {
                        operation: "host_to_device_transfer".to_string(),
                        details: format!("Non-finite coefficient at index {} basis {}", i, j),
                    });
                }
            }
        }

        // Check memory constraints
        let transfer_size = data.len() * std::mem::size_of::<Multivector<P, Q, R>>();
        if transfer_size as u64 > self.constraints.max_memory_overhead {
            return Err(GpuVerificationError::ResourceExhaustion {
                resource: "transfer_memory".to_string(),
                limit: self.constraints.max_memory_overhead,
            });
        }

        Ok(())
    }

    /// Verify memory transfer from device to host
    pub async fn verify_device_to_host_transfer(
        &mut self,
        data: &[Multivector<P, Q, R>],
    ) -> Result<(), GpuVerificationError> {
        // Verify computational integrity after GPU processing
        for (i, mv) in data.iter().enumerate() {
            // Verify magnitude is reasonable (not too large from numerical errors)
            let magnitude = mv.magnitude();
            if magnitude > 1e10 {
                return Err(GpuVerificationError::BoundaryInvariantViolation {
                    operation: "device_to_host_transfer".to_string(),
                    details: format!("Magnitude too large at index {}: {}", i, magnitude),
                });
            }

            // Verify no GPU computation artifacts
            if !magnitude.is_finite() {
                return Err(GpuVerificationError::BoundaryInvariantViolation {
                    operation: "device_to_host_transfer".to_string(),
                    details: format!("GPU computation produced non-finite result at index {}", i),
                });
            }
        }

        Ok(())
    }

    /// Verify batch geometric product operation on GPU
    pub async fn verify_batch_geometric_product(
        &mut self,
        a_batch: &[Multivector<P, Q, R>],
        b_batch: &[Multivector<P, Q, R>],
        result_batch: &[Multivector<P, Q, R>],
    ) -> Result<(), GpuVerificationError> {
        if a_batch.len() != b_batch.len() || b_batch.len() != result_batch.len() {
            return Err(GpuVerificationError::BoundaryInvariantViolation {
                operation: "batch_geometric_product".to_string(),
                details: "Batch size mismatch".to_string(),
            });
        }

        match self.level {
            GpuVerificationLevel::None => Ok(()),
            GpuVerificationLevel::Boundary => {
                // Verify only first and last elements
                self.verify_single_geometric_product(&a_batch[0], &b_batch[0], &result_batch[0]).await?;
                if a_batch.len() > 1 {
                    let last = a_batch.len() - 1;
                    self.verify_single_geometric_product(&a_batch[last], &b_batch[last], &result_batch[last]).await?;
                }
                Ok(())
            }
            GpuVerificationLevel::WarpSampling { sample_rate } => {
                // Verify sampled elements based on sample rate
                let sample_count = ((a_batch.len() as f32) * sample_rate).ceil() as usize;
                let step = a_batch.len() / sample_count.max(1);

                for i in (0..a_batch.len()).step_by(step) {
                    self.verify_single_geometric_product(&a_batch[i], &b_batch[i], &result_batch[i]).await?;
                }
                Ok(())
            }
            GpuVerificationLevel::BlockLevel => {
                // Verify block-aligned elements (64 elements per block)
                for i in (0..a_batch.len()).step_by(64) {
                    self.verify_single_geometric_product(&a_batch[i], &b_batch[i], &result_batch[i]).await?;
                }
                Ok(())
            }
            GpuVerificationLevel::HostSide => {
                // Verify all elements on host
                for i in 0..a_batch.len() {
                    self.verify_single_geometric_product(&a_batch[i], &b_batch[i], &result_batch[i]).await?;
                }
                Ok(())
            }
        }
    }

    /// Verify single geometric product with mathematical properties
    async fn verify_single_geometric_product(
        &self,
        a: &Multivector<P, Q, R>,
        b: &Multivector<P, Q, R>,
        result: &Multivector<P, Q, R>,
    ) -> Result<(), GpuVerificationError> {
        // Compute expected result on host for verification
        let expected = a.geometric_product(b);

        // Check numerical equivalence within GPU precision tolerance
        let tolerance = 1e-6; // GPU single precision tolerance
        for i in 0..8 {
            let diff = (result.get(i) - expected.get(i)).abs();
            if diff > tolerance {
                return Err(GpuVerificationError::BoundaryInvariantViolation {
                    operation: "geometric_product_verification".to_string(),
                    details: format!("Coefficient {} differs by {} (tolerance: {})", i, diff, tolerance),
                });
            }
        }

        Ok(())
    }

    /// Kernel precondition verification
    async fn verify_kernel_preconditions(
        &self,
        kernel_name: &str,
        input_data: &[Multivector<P, Q, R>],
    ) -> Result<(), GpuVerificationError> {
        // Check data size constraints for GPU kernels
        if input_data.len() > 1_000_000 {
            return Err(GpuVerificationError::ResourceExhaustion {
                resource: "input_batch_size".to_string(),
                limit: 1_000_000,
            });
        }

        // Verify SIMT compatibility if required
        if self.constraints.simt_compatible && input_data.len() % 32 != 0 {
            return Err(GpuVerificationError::SimtDivergence {
                warp_id: 0,
                thread_mask: 0xFFFFFFFF,
            });
        }

        // Check for values that might cause GPU numerical issues
        for (i, mv) in input_data.iter().enumerate() {
            let magnitude = mv.magnitude();
            if magnitude > 1e20 || magnitude < 1e-20 {
                return Err(GpuVerificationError::BoundaryInvariantViolation {
                    operation: kernel_name.to_string(),
                    details: format!("Input magnitude {} at index {} may cause GPU precision issues", magnitude, i),
                });
            }
        }

        Ok(())
    }

    /// Kernel postcondition verification
    async fn verify_kernel_postconditions(
        &self,
        kernel_name: &str,
        output_data: &[Multivector<P, Q, R>],
    ) -> Result<(), GpuVerificationError> {
        // Verify output data integrity
        for (i, mv) in output_data.iter().enumerate() {
            if !mv.magnitude().is_finite() {
                return Err(GpuVerificationError::KernelFailure {
                    kernel: kernel_name.to_string(),
                    error: format!("Non-finite output at index {}", i),
                });
            }

            // Check for GPU computation artifacts
            for j in 0..8 {
                let coeff = mv.get(j);
                if coeff.is_nan() {
                    return Err(GpuVerificationError::KernelFailure {
                        kernel: kernel_name.to_string(),
                        error: format!("NaN coefficient at index {} basis {}", i, j),
                    });
                }
            }
        }

        Ok(())
    }

    /// Host-side precondition verification (full phantom type support)
    async fn verify_host_preconditions(
        &self,
        _kernel_name: &str,
        input_data: &[Multivector<P, Q, R>],
    ) -> Result<(), GpuVerificationError> {
        // Full mathematical property verification on host
        for mv in input_data {
            if !Self::verify_clifford_properties(mv) {
                return Err(GpuVerificationError::BoundaryInvariantViolation {
                    operation: "host_precondition_check".to_string(),
                    details: "Clifford algebra properties violated".to_string(),
                });
            }
        }
        Ok(())
    }

    /// Host-side postcondition verification
    async fn verify_host_postconditions(
        &self,
        _kernel_name: &str,
        output_data: &[Multivector<P, Q, R>],
    ) -> Result<(), GpuVerificationError> {
        // Full mathematical property verification on host
        for mv in output_data {
            if !Self::verify_clifford_properties(mv) {
                return Err(GpuVerificationError::BoundaryInvariantViolation {
                    operation: "host_postcondition_check".to_string(),
                    details: "Output violates Clifford algebra properties".to_string(),
                });
            }
        }
        Ok(())
    }

    /// Verify Clifford algebra mathematical properties
    fn verify_clifford_properties(mv: &Multivector<P, Q, R>) -> bool {
        // Check magnitude is non-negative and finite
        let magnitude = mv.magnitude();
        if !magnitude.is_finite() || magnitude < 0.0 {
            return false;
        }

        // Check all coefficients are finite
        for i in 0..8 {
            if !mv.get(i).is_finite() {
                return false;
            }
        }

        // Check signature constraints for specific algebras
        match (P, Q, R) {
            (3, 0, 0) => {
                // Euclidean 3D - additional checks could be added
                true
            }
            (1, 3, 0) => {
                // Minkowski spacetime - check signature constraints
                true
            }
            _ => true,
        }
    }

    /// Get GPU verification statistics
    pub fn get_gpu_stats(&self) -> GpuVerificationStats {
        GpuVerificationStats {
            level: self.level,
            operation_count: self.operation_count,
            total_overhead: self.total_overhead,
            device_verification_enabled: self.device_verification_enabled,
            host_verification_enabled: self.host_verification_enabled,
            constraints: self.constraints,
        }
    }

    /// Adapt verification level based on runtime performance
    pub fn adapt_verification_level(&mut self, target_overhead_ratio: f64) {
        let current_overhead_ms = self.total_overhead.as_millis() as f64;
        let operation_time_estimate = current_overhead_ms / self.operation_count as f64;

        if operation_time_estimate > target_overhead_ratio * 1000.0 {
            // Reduce verification level if overhead too high
            self.level = match self.level {
                GpuVerificationLevel::HostSide => GpuVerificationLevel::BlockLevel,
                GpuVerificationLevel::BlockLevel => GpuVerificationLevel::WarpSampling { sample_rate: 0.1 },
                GpuVerificationLevel::WarpSampling { sample_rate } if sample_rate > 0.01 => {
                    GpuVerificationLevel::WarpSampling { sample_rate: sample_rate * 0.5 }
                }
                _ => GpuVerificationLevel::Boundary,
            };
        }
    }
}

/// GPU verification statistics for performance monitoring
#[derive(Debug)]
pub struct GpuVerificationStats {
    pub level: GpuVerificationLevel,
    pub operation_count: u64,
    pub total_overhead: Duration,
    pub device_verification_enabled: bool,
    pub host_verification_enabled: bool,
    pub constraints: GpuConstraints,
}

/// GPU-verified multivector wrapper with boundary checking
pub struct GpuVerifiedMultivector<const P: usize, const Q: usize, const R: usize> {
    inner: Multivector<P, Q, R>,
    gpu_verified: bool,
    host_verified: bool,
    verification_level: GpuVerificationLevel,
    _phantom: PhantomData<(P, Q, R)>,
}

impl<const P: usize, const Q: usize, const R: usize> GpuVerifiedMultivector<P, Q, R> {
    /// Create GPU-verified multivector with boundary validation
    pub fn new_gpu_verified(
        multivector: Multivector<P, Q, R>,
        context: &GpuVerificationContext<P, Q, R>,
    ) -> Result<Self, GpuVerificationError> {
        // Always verify on host side
        if !GpuVerificationContext::<P, Q, R>::verify_clifford_properties(&multivector) {
            return Err(GpuVerificationError::BoundaryInvariantViolation {
                operation: "gpu_verified_creation".to_string(),
                details: "Input violates Clifford algebra properties".to_string(),
            });
        }

        Ok(Self {
            inner: multivector,
            gpu_verified: context.device_verification_enabled,
            host_verified: true,
            verification_level: context.level,
            _phantom: PhantomData,
        })
    }

    /// Perform verified batch geometric product on GPU
    pub async fn batch_geometric_product_gpu_verified(
        a_batch: &[Self],
        b_batch: &[Self],
        context: &mut GpuVerificationContext<P, Q, R>,
    ) -> Result<Vec<Self>, GpuVerificationError> {
        // Extract inner multivectors
        let a_mvs: Vec<Multivector<P, Q, R>> = a_batch.iter().map(|v| v.inner).collect();
        let b_mvs: Vec<Multivector<P, Q, R>> = b_batch.iter().map(|v| v.inner).collect();

        // Verify kernel launch
        context.verify_kernel_launch("batch_geometric_product", &a_mvs).await?;

        // Simulate GPU computation (in real implementation, this would call GPU kernel)
        let mut result_mvs = Vec::with_capacity(a_mvs.len());
        for (a, b) in a_mvs.iter().zip(b_mvs.iter()) {
            result_mvs.push(a.geometric_product(b));
        }

        // Verify kernel completion
        context.verify_kernel_completion("batch_geometric_product", &result_mvs).await?;

        // Verify batch operation
        context.verify_batch_geometric_product(&a_mvs, &b_mvs, &result_mvs).await?;

        // Wrap results in verified containers
        let verified_results: Result<Vec<Self>, _> = result_mvs
            .into_iter()
            .map(|mv| Self::new_gpu_verified(mv, context))
            .collect();

        verified_results
    }

    /// Get underlying multivector (verified)
    pub fn inner(&self) -> &Multivector<P, Q, R> {
        &self.inner
    }

    /// Check if GPU verification was performed
    pub fn is_gpu_verified(&self) -> bool {
        self.gpu_verified
    }

    /// Check if host verification was performed
    pub fn is_host_verified(&self) -> bool {
        self.host_verified
    }

    /// Get verification level used
    pub fn verification_level(&self) -> GpuVerificationLevel {
        self.verification_level
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_gpu_verification_context_creation() {
        let constraints = GpuConstraints {
            max_memory_overhead: 1024 * 1024, // 1MB
            max_compute_overhead_us: 1000,     // 1ms
            simt_compatible: true,
            memory_tier: GpuMemoryTier::Global,
        };

        let context = GpuVerificationContext::<3, 0, 0>::new(constraints);
        assert_eq!(context.level, GpuVerificationLevel::WarpSampling { sample_rate: 0.1 });
        assert!(context.device_verification_enabled);
    }

    #[tokio::test]
    async fn test_boundary_verification() {
        let constraints = GpuConstraints {
            max_memory_overhead: 512, // Low memory
            max_compute_overhead_us: 10, // Low overhead
            simt_compatible: false,
            memory_tier: GpuMemoryTier::Shared,
        };

        let mut context = GpuVerificationContext::<3, 0, 0>::new(constraints);

        let test_data = vec![
            Multivector::<3, 0, 0>::basis_vector(0),
            Multivector::<3, 0, 0>::basis_vector(1),
        ];

        let result = context.verify_kernel_launch("test_kernel", &test_data).await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    async fn test_gpu_verified_multivector() {
        let constraints = GpuConstraints {
            max_memory_overhead: 1024 * 1024,
            max_compute_overhead_us: 1000,
            simt_compatible: true,
            memory_tier: GpuMemoryTier::Global,
        };

        let context = GpuVerificationContext::<3, 0, 0>::new(constraints);
        let mv = Multivector::<3, 0, 0>::basis_vector(0);

        let verified_mv = GpuVerifiedMultivector::new_gpu_verified(mv, &context);
        assert!(verified_mv.is_ok());

        let verified = verified_mv.unwrap();
        assert!(verified.is_host_verified());
        assert_eq!(verified.verification_level(), GpuVerificationLevel::WarpSampling { sample_rate: 0.1 });
    }

    #[tokio::test]
    async fn test_invalid_gpu_data_rejection() {
        let constraints = GpuConstraints {
            max_memory_overhead: 1024,
            max_compute_overhead_us: 100,
            simt_compatible: true,
            memory_tier: GpuMemoryTier::Global,
        };

        let context = GpuVerificationContext::<3, 0, 0>::new(constraints);

        // Create invalid multivector with NaN
        let mut invalid_mv = Multivector::<3, 0, 0>::zero();
        invalid_mv.set_scalar(f64::NAN);

        let result = GpuVerifiedMultivector::new_gpu_verified(invalid_mv, &context);
        assert!(result.is_err());

        if let Err(GpuVerificationError::BoundaryInvariantViolation { operation, .. }) = result {
            assert_eq!(operation, "gpu_verified_creation");
        } else {
            panic!("Expected BoundaryInvariantViolation error");
        }
    }

    #[test]
    fn test_verification_level_adaptation() {
        let constraints = GpuConstraints {
            max_memory_overhead: 1024 * 1024,
            max_compute_overhead_us: 1000,
            simt_compatible: true,
            memory_tier: GpuMemoryTier::Host,
        };

        let mut context = GpuVerificationContext::<3, 0, 0>::new(constraints);
        assert_eq!(context.level, GpuVerificationLevel::HostSide);

        // Simulate high overhead
        context.operation_count = 1;
        context.total_overhead = Duration::from_millis(2000);

        context.adapt_verification_level(0.1); // 10% overhead target

        // Should have reduced verification level
        assert_ne!(context.level, GpuVerificationLevel::HostSide);
    }
}