## Coverage Report

#### Created: 2026-01-25 15:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /home/noah/src/trueno/src/lib.rs

    Line
    Count
    Source
    1
    // ============================================================================
    2
    // Development-phase lint allows - to be addressed incrementally
    3
    // ============================================================================
    4
    // Allow manual_div_ceil - clearer for block calculations
    5
    #![allow(clippy::manual_div_ceil)]
    6
    // Allow manual_is_multiple_of - clearer alignment checks
    7
    #![allow(clippy::manual_is_multiple_of)]
    8
    // Allow needless_range_loop - index access is clearer in some SIMD algorithms
    9
    #![allow(clippy::needless_range_loop)]
    10
    // Allow empty line after doc comments - formatting preference
    11
    #![allow(clippy::empty_line_after_doc_comments)]
    12
    // Allow similar names - semantic distinction is clear
    13
    #![allow(clippy::similar_names)]
    14
    // Allow many single char names - standard math/matrix notation
    15
    #![allow(clippy::many_single_char_names)]
    16
    // Allow too many arguments - SIMD/compute APIs require many parameters
    17
    #![allow(clippy::too_many_arguments)]
    18
    // Allow type complexity - complex SIMD types
    19
    #![allow(clippy::type_complexity)]
    20
    // Allow macro metavars in unsafe - necessary for SIMD dispatch macros
    21
    #![allow(clippy::macro_metavars_in_unsafe)]
    22
    // Allow missing panics doc - will be added incrementally
    23
    #![allow(clippy::missing_panics_doc)]
    24
    // Allow missing errors doc - will be added incrementally
    25
    #![allow(clippy::missing_errors_doc)]
    26
    // Allow missing safety doc - will be added incrementally
    27
    #![allow(clippy::missing_safety_doc)]
    28
    // Allow excessive precision - SIMD math constants need specific precision
    29
    #![allow(clippy::excessive_precision)]
    30
    // Allow unnecessary cast - clearer type annotations in some cases
    31
    #![allow(clippy::unnecessary_cast)]
    32
    // Allow cast_possible_truncation - handled in SIMD code
    33
    #![allow(clippy::cast_possible_truncation)]
    34
    // Allow cast_sign_loss - handled in SIMD code
    35
    #![allow(clippy::cast_sign_loss)]
    36
    // Allow cast_precision_loss - handled in SIMD code
    37
    #![allow(clippy::cast_precision_loss)]
    38
    39
    //! Trueno: Multi-Target High-Performance Compute Library
    40
    //!
    41
    //! **Trueno** (Spanish: "thunder") provides unified, high-performance compute primitives
    42
    //! across three execution targets:
    43
    //!
    44
    //! 1. **CPU SIMD** - x86 (SSE2/AVX/AVX2/AVX-512), ARM (NEON), WASM (SIMD128)
    45
    //! 2. **GPU** - Vulkan/Metal/DX12/WebGPU via `wgpu`
    46
    //! 3. **WebAssembly** - Portable SIMD128 for browser/edge deployment
    47
    //!
    48
    //! # Design Principles
    49
    //!
    50
    //! - **Write once, optimize everywhere**: Single algorithm, multiple backends
    51
    //! - **Runtime dispatch**: Auto-select best implementation based on CPU features
    52
    //! - **Zero unsafe in public API**: Safety via type system, `unsafe` isolated in backends
    53
    //! - **Benchmarked performance**: Every optimization must prove ≥10% speedup
    54
    //! - **Extreme TDD**: >90% test coverage, mutation testing, property-based tests
    55
    //!
    56
    //! # Quick Start
    57
    //!
    58
    //! ```rust
    59
    //! use trueno::Vector;
    60
    //!
    61
    //! let a = Vector::from_slice(&[1.0, 2.0, 3.0, 4.0]);
    62
    //! let b = Vector::from_slice(&[5.0, 6.0, 7.0, 8.0]);
    63
    //!
    64
    //! // Auto-selects best backend (AVX2/GPU/WASM)
    65
    //! let result = a.add(&b).unwrap();
    66
    //! assert_eq!(result.as_slice(), &[6.0, 8.0, 10.0, 12.0]);
    67
    //! ```
    68
    69
    pub mod backends;
    70
    pub mod blis;
    71
    pub mod brick;
    72
    pub mod chaos;
    73
    pub mod eigen;
    74
    pub mod error;
    75
    pub mod hardware;
    76
    pub mod hash;
    77
    pub mod matrix;
    78
    pub mod monitor;
    79
    pub mod simulation;
    80
    pub mod tiling;
    81
    pub mod tuner;
    82
    pub mod vector;
    83
    84
    pub use eigen::SymmetricEigen;
    85
    pub use error::{Result, TruenoError};
    86
    pub use hash::{hash_bytes, hash_key, hash_keys_batch, hash_keys_batch_with_backend};
    87
    pub use matrix::Matrix;
    88
    pub use monitor::{
    89
        cuda_monitor_available, GpuBackend, GpuClockMetrics, GpuDeviceInfo, GpuMemoryMetrics,
    90
        GpuMetrics, GpuMonitor, GpuPcieMetrics, GpuPowerMetrics, GpuThermalMetrics, GpuUtilization,
    91
        GpuVendor, MonitorConfig, MonitorError,
    92
    };
    93
    #[cfg(feature = "cuda-monitor")]
    94
    pub use monitor::{enumerate_cuda_devices, query_cuda_device_info, query_cuda_memory};
    95
    pub use vector::Vector;
    96
    97
    // ComputeBrick exports
    98
    pub use brick::{
    99
        AddOp, AssertionResult, AttentionOp, BrickError, BrickLayer, BrickProfiler, BrickSample,
    100
        BrickStats, BrickTimer, BrickVerification, ByteBudget, ComputeAssertion, ComputeBackend,
    101
        ComputeBrick, ComputeOp, DotOp, FusedGateUpOp, FusedGateUpWeights, FusedQKVOp,
    102
        FusedQKVWeights, MatmulOp, SoftmaxOp, TokenBudget, TokenResult,
    103
        // QUANT-Q5K: Q5_K and Q6_K quantization formats (llama.cpp compatible)
    104
        BlockQ5K, BlockQ6K, DotQ5KOp, DotQ6KOp,
    105
        // CORRECTNESS-011: Divergence detection types
    106
        KernelChecksum, DivergenceInfo, fnv1a_f32_checksum,
    107
        // PAR-200: BrickProfiler v2 types
    108
        BrickId, BrickIdTimer, BrickCategory, BrickBottleneck, CategoryStats, SyncMode,
    109
        // PAR-201: Execution path graph types
    110
        ExecutionNodeId, ExecutionNode, EdgeType, ExecutionEdge, ExecutionGraph, PtxRegistry,
    111
        // TILING-SPEC-001: Tile-level profiling types
    112
        TileLevel, TileStats, TileTimer,
    113
    };
    114
    115
    // Hardware capability exports (PMAT-447)
    116
    pub use hardware::{
    117
        Bottleneck, CpuCapability, GpuCapability, HardwareCapability, RooflineParams, SimdWidth,
    118
        GpuBackend as HardwareGpuBackend, default_hardware_path,
    119
    };
    120
    121
    // ML Tuner exports (T-TUNER-003 through T-TUNER-007, GH#80-84)
    122
    pub use tuner::{
    123
        BottleneckClass, BottleneckPrediction, BrickTuner, ConceptDriftStatus, ExperimentSuggestion,
    124
        FeatureExtractor, KernelClassifier, KernelRecommendation, KernelType, QuantType, RunConfig,
    125
        ThroughputPrediction, ThroughputRegressor, TrainingSample, TrainingStats, TunerDataCollector,
    126
        TunerError, TunerFeatures, TunerRecommendation, UserFeedback,
    127
    };
    128
    129
    // Tiling Compute Blocks exports (TILING-SPEC-001)
    130
    pub use tiling::{
    131
        PackingLayout, PrefetchLocality, TcbGeometry, TcbIndexCalculator, TcbLevel, TilingBackend,
    132
        TilingConfig, TilingError, TilingStats, TiledQ4KMatvec,
    133
        Q4K_SUPERBLOCK_SIZE, Q4K_SUPERBLOCK_BYTES,
    134
        optimal_prefetch_distance, pack_a_index, pack_b_index, swizzle_index,
    135
    };
    136
    137
    /// Backend execution target
    138
    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    139
    pub enum Backend {
    140
        /// Scalar fallback (no SIMD)
    141
        Scalar,
    142
        /// SSE2 (x86_64 baseline)
    143
        SSE2,
    144
        /// AVX (256-bit)
    145
        AVX,
    146
        /// AVX2 (256-bit with FMA)
    147
        AVX2,
    148
        /// AVX-512 (512-bit)
    149
        AVX512,
    150
        /// ARM NEON
    151
        NEON,
    152
        /// WebAssembly SIMD128
    153
        WasmSIMD,
    154
        /// GPU compute (wgpu)
    155
        GPU,
    156
        /// Auto-select best available
    157
        Auto,
    158
    }
    159
    160
    impl Backend {
    161
        /// Select the best available backend for the current platform
    162
        ///
    163
        /// This is a convenience wrapper around `select_best_available_backend()`
    164
    10
        pub fn select_best() -> Self {
    165
    10
            select_best_available_backend()
    166
    10
        }
    167
    }
    168
    169
    /// Operation complexity for GPU dispatch eligibility
    170
    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
    171
    pub enum OpComplexity {
    172
        /// Simple operations (add, mul) - prefer SIMD unless very large
    173
        Low = 0,
    174
        /// Moderate operations (dot, reduce) - GPU beneficial at 100K+
    175
        Medium = 1,
    176
        /// Complex operations (matmul, convolution) - GPU beneficial at 10K+
    177
        High = 2,
    178
    }
    179
    180
    /// Operation type for SIMD backend selection
    181
    ///
    182
    /// Based on AVX-512 performance analysis (see AVX512_ANALYSIS.md), operations are
    183
    /// categorized by their memory vs compute characteristics to guide optimal backend selection.
    184
    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    185
    pub enum OperationType {
    186
        /// Memory-bound operations (add, sub, mul, scale, div)
    187
        ///
    188
        /// These operations perform minimal computation per memory access (arithmetic intensity < 1 op/byte).
    189
        /// Prefer AVX2 over AVX-512 due to memory bandwidth bottleneck.
    190
        ///
    191
        /// AVX-512 performance: 0.67-1.20x scalar (often slower!)
    192
        /// AVX2 performance: 1.0-1.2x scalar
    193
        MemoryBound,
    194
    195
        /// Compute-bound operations (dot, max, min, argmax, argmin)
    196
        ///
    197
        /// These operations perform significant computation per memory access (arithmetic intensity > 1 op/byte).
    198
        /// AVX-512 excels due to wider SIMD parallelism.
    199
        ///
    200
        /// AVX-512 performance: 7-14x scalar (validated)
    201
        /// AVX2 performance: 4-12x scalar (validated)
    202
        ComputeBound,
    203
    204
        /// Mixed operations (fma, sqrt, exp, sigmoid, activations)
    205
        ///
    206
        /// Performance depends on data size and hardware.
    207
        /// Use size-based heuristics or default to AVX2 for safety.
    208
        Mixed,
    209
    }
    210
    211
    /// Detect best SIMD backend for x86/x86_64 platforms
    212
    ///
    213
    /// **IMPORTANT**: Prefers AVX2 over AVX-512 by default based on performance analysis.
    214
    ///
    215
    /// AVX-512 is **NOT** universally faster - it causes 10-33% slowdown for memory-bound
    216
    /// operations (add, mul, sub) due to memory bandwidth bottleneck and thermal throttling.
    217
    /// See AVX512_ANALYSIS.md for detailed benchmarking results.
    218
    ///
    219
    /// For operation-specific backend selection, use `select_backend_for_operation()`.
    220
    #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
    221
    1
    fn detect_x86_backend() -> Backend {
    222
        // Prefer AVX2 over AVX-512 for safety (AVX-512 causes regressions for memory-bound ops)
    223
    1
        if is_x86_feature_detected!("avx2") && is_x86_feature_detected!("fma") {
    224
    1
            return Backend::AVX2;
    225
    0
        }
    226
        // Note: AVX-512 is intentionally NOT checked here
    227
        // Use select_backend_for_operation(OperationType::ComputeBound) for AVX-512
    228
    0
        if is_x86_feature_detected!("avx") {
    229
    0
            return Backend::AVX;
    230
    0
        }
    231
    0
        if is_x86_feature_detected!("sse2") {
    232
    0
            return Backend::SSE2;
    233
    0
        }
    234
    0
        Backend::Scalar
    235
    1
    }
    236
    237
    /// Detect best SIMD backend for ARM platforms
    238
    #[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
    239
    fn detect_arm_backend() -> Backend {
    240
        #[cfg(target_feature = "neon")]
    241
        {
    242
            Backend::NEON
    243
        }
    244
        #[cfg(not(target_feature = "neon"))]
    245
        {
    246
            Backend::Scalar
    247
        }
    248
    }
    249
    250
    /// Detect best SIMD backend for WebAssembly
    251
    #[cfg(target_arch = "wasm32")]
    252
    fn detect_wasm_backend() -> Backend {
    253
        #[cfg(target_feature = "simd128")]
    254
        {
    255
            Backend::WasmSIMD
    256
        }
    257
        #[cfg(not(target_feature = "simd128"))]
    258
        {
    259
            Backend::Scalar
    260
        }
    261
    }
    262
    263
    /// Select the best available backend for the current platform
    264
    ///
    265
    /// This function performs runtime CPU feature detection and selects the most
    266
    /// optimized backend available. The selection follows this priority:
    267
    ///
    268
    /// **x86/x86_64**:
    269
    /// 1. AVX-512 (if `avx512f` feature detected)
    270
    /// 2. AVX2 (if `avx2` and `fma` features detected)
    271
    /// 3. AVX (if `avx` feature detected)
    272
    /// 4. SSE2 (baseline for x86_64)
    273
    /// 5. Scalar (fallback)
    274
    ///
    275
    /// **ARM**:
    276
    /// 1. NEON (if available)
    277
    /// 2. Scalar (fallback)
    278
    ///
    279
    /// **WASM**: SIMD128 (if available), else Scalar
    280
    ///
    281
    /// **Other platforms**: Scalar
    282
    ///
    283
    /// # Returns
    284
    ///
    285
    /// The most optimized backend available on this CPU/platform
    286
    ///
    287
    /// # Examples
    288
    ///
    289
    /// ```
    290
    /// use trueno::select_best_available_backend;
    291
    ///
    292
    /// let backend = select_best_available_backend();
    293
    /// println!("Using backend: {:?}", backend);
    294
    /// ```
    295
    257k
    pub fn select_best_available_backend() -> Backend {
    296
        // Cache backend selection using OnceLock to avoid repeated CPU feature detection
    297
        // This eliminates 3-5% overhead from calling is_x86_feature_detected!() repeatedly
    298
        static BEST_BACKEND: std::sync::OnceLock<Backend> = std::sync::OnceLock::new();
    299
    300
    257k
        *BEST_BACKEND.get_or_init(|| {1
    301
            #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
    302
            {
    303
    1
                detect_x86_backend()
    304
            }
    305
    306
            #[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
    307
            {
    308
                detect_arm_backend()
    309
            }
    310
    311
            #[cfg(target_arch = "wasm32")]
    312
            {
    313
                detect_wasm_backend()
    314
            }
    315
    316
            #[cfg(not(any(
    317
                target_arch = "x86_64",
    318
                target_arch = "x86",
    319
                target_arch = "aarch64",
    320
                target_arch = "arm",
    321
                target_arch = "wasm32"
    322
            )))]
    323
            {
    324
                Backend::Scalar
    325
            }
    326
    1
        })
    327
    257k
    }
    328
    329
    /// Select the optimal backend for a specific operation type
    330
    ///
    331
    /// This function considers the memory vs compute characteristics of operations
    332
    /// to select the backend that will provide the best performance. Based on
    333
    /// comprehensive benchmarking (see AVX512_ANALYSIS.md), AVX-512 is avoided
    334
    /// for memory-bound operations where it causes 10-33% performance degradation.
    335
    ///
    336
    /// # Operation Classification
    337
    ///
    338
    /// - **MemoryBound**: add, sub, mul, div, scale, abs, clamp, lerp, relu
    339
    ///   - Prefer AVX2 (1.0-1.2x scalar) over AVX-512 (0.67-1.20x scalar)
    340
    ///   - Memory bandwidth bottleneck limits wider SIMD benefit
    341
    ///
    342
    /// - **ComputeBound**: dot, max, min, argmax, argmin, norm_l1, norm_l2, norm_linf
    343
    ///   - Prefer AVX-512 (7-14x scalar) over AVX2 (4-12x scalar)
    344
    ///   - High arithmetic intensity benefits from wider SIMD
    345
    ///
    346
    /// - **Mixed**: fma, sqrt, exp, ln, sigmoid, tanh, gelu, swish
    347
    ///   - Default to AVX2 for safety (avoids AVX-512 thermal throttling)
    348
    ///   - Size-based heuristics could improve this in future
    349
    ///
    350
    /// # Backend Selection Priority
    351
    ///
    352
    /// **For MemoryBound operations**:
    353
    /// 1. AVX2 (if available) - BEST for memory-bound
    354
    /// 2. SSE2 (x86_64 baseline)
    355
    /// 3. AVX-512 (AVOIDED - causes slowdown)
    356
    /// 4. NEON (ARM)
    357
    /// 5. WASM SIMD128
    358
    /// 6. Scalar (fallback)
    359
    ///
    360
    /// **For ComputeBound operations**:
    361
    /// 1. AVX-512 (if available) - BEST for compute-bound
    362
    /// 2. AVX2
    363
    /// 3. SSE2
    364
    /// 4. NEON (ARM)
    365
    /// 5. WASM SIMD128
    366
    /// 6. Scalar (fallback)
    367
    ///
    368
    /// # Arguments
    369
    ///
    370
    /// * `op_type` - The type of operation being performed
    371
    ///
    372
    /// # Returns
    373
    ///
    374
    /// The optimal backend for the given operation type
    375
    ///
    376
    /// # Examples
    377
    ///
    378
    /// ```
    379
    /// use trueno::{select_backend_for_operation, OperationType};
    380
    ///
    381
    /// // Memory-bound operation - prefers AVX2 over AVX-512
    382
    /// let backend = select_backend_for_operation(OperationType::MemoryBound);
    383
    ///
    384
    /// // Compute-bound operation - uses AVX-512 if available
    385
    /// let backend = select_backend_for_operation(OperationType::ComputeBound);
    386
    /// ```
    387
    ///
    388
    /// # Performance Impact
    389
    ///
    390
    /// Using operation-aware backend selection fixes performance regressions:
    391
    /// - mul with AVX-512: 0.67x → 1.0x (use AVX2 instead)
    392
    /// - sub with AVX-512: 0.87x → 1.0x (use AVX2 instead)
    393
    /// - dot with AVX-512: 7.89x (keep AVX-512)
    394
    0
    pub fn select_backend_for_operation(op_type: OperationType) -> Backend {
    395
        // Allow unused on non-x86 architectures
    396
    0
        let _ = &op_type;
    397
    398
        #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
    399
        {
    400
    0
            select_x86_backend_for_operation(op_type)
    401
        }
    402
    403
        #[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
    404
        {
    405
            detect_arm_backend()
    406
        }
    407
    408
        #[cfg(target_arch = "wasm32")]
    409
        {
    410
            detect_wasm_backend()
    411
        }
    412
    413
        #[cfg(not(any(
    414
            target_arch = "x86_64",
    415
            target_arch = "x86",
    416
            target_arch = "aarch64",
    417
            target_arch = "arm",
    418
            target_arch = "wasm32"
    419
        )))]
    420
        {
    421
            Backend::Scalar
    422
        }
    423
    0
    }
    424
    425
    /// Select the best x86 backend based on operation type and available features.
    426
    ///
    427
    /// Separated from `select_backend_for_operation` to reduce cyclomatic complexity.
    428
    #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
    429
    0
    fn select_x86_backend_for_operation(op_type: OperationType) -> Backend {
    430
        use std::arch::is_x86_feature_detected;
    431
    432
        // Check for AVX-512 (only for compute-bound operations)
    433
    0
        let use_avx512 = op_type == OperationType::ComputeBound && is_x86_feature_detected!("avx512f");
    434
    0
        if use_avx512 {
    435
    0
            return Backend::AVX512;
    436
    0
        }
    437
    438
        // AVX2 with FMA is preferred for most operations
    439
    0
        if is_x86_feature_detected!("avx2") && is_x86_feature_detected!("fma") {
    440
    0
            return Backend::AVX2;
    441
    0
        }
    442
    443
        // Fallback chain: AVX -> SSE2 -> Scalar
    444
    0
        if is_x86_feature_detected!("avx") {
    445
    0
            return Backend::AVX;
    446
    0
        }
    447
    0
        if is_x86_feature_detected!("sse2") {
    448
    0
            return Backend::SSE2;
    449
    0
        }
    450
    451
    0
        Backend::Scalar
    452
    0
    }
    453
    454
    #[cfg(test)]
    455
    mod tests {
    456
        use super::*;
    457
    458
        #[test]
    459
        fn test_backend_enum() {
    460
            assert_eq!(Backend::Scalar, Backend::Scalar);
    461
            assert_ne!(Backend::Scalar, Backend::AVX2);
    462
        }
    463
    464
        #[test]
    465
        fn test_op_complexity_ordering() {
    466
            assert!(OpComplexity::Low < OpComplexity::Medium);
    467
            assert!(OpComplexity::Medium < OpComplexity::High);
    468
        }
    469
    470
        #[test]
    471
        fn test_select_best_available_backend() {
    472
            let backend = select_best_available_backend();
    473
    474
            // On x86_64, we should get at least SSE2 (baseline for x86_64)
    475
            // or a more advanced SIMD backend if available
    476
            #[cfg(target_arch = "x86_64")]
    477
            {
    478
                // x86_64 baseline is SSE2, so we should never get Scalar on x86_64
    479
                assert_ne!(backend, Backend::Scalar);
    480
                // Verify it's one of the x86 SIMD backends
    481
                assert!(matches!(
    482
                    backend,
    483
                    Backend::SSE2 | Backend::AVX | Backend::AVX2 | Backend::AVX512
    484
                ));
    485
            }
    486
    487
            // On other platforms, we might get Scalar or platform-specific SIMD
    488
            #[cfg(not(target_arch = "x86_64"))]
    489
            {
    490
                // Just verify we got a valid backend
    491
                assert!(matches!(
    492
                    backend,
    493
                    Backend::Scalar
    494
                        | Backend::SSE2
    495
                        | Backend::AVX
    496
                        | Backend::AVX2
    497
                        | Backend::AVX512
    498
                        | Backend::NEON
    499
                        | Backend::WasmSIMD
    500
                ));
    501
            }
    502
        }
    503
    504
        #[test]
    505
        fn test_backend_selection_is_deterministic() {
    506
            // Backend selection should be deterministic (same result on multiple calls)
    507
            let backend1 = select_best_available_backend();
    508
            let backend2 = select_best_available_backend();
    509
            assert_eq!(backend1, backend2);
    510
        }
    511
    512
        #[test]
    513
        fn test_backend_selection_is_cached() {
    514
            // Verify backend selection is cached (OnceLock)
    515
            // Multiple calls should return the same backend without re-detection
    516
            let backend1 = select_best_available_backend();
    517
    518
            // Call 1000 times to ensure caching is working
    519
            // If not cached, this would be significantly slower
    520
            for _ in 0..1000 {
    521
                let backend = select_best_available_backend();
    522
                assert_eq!(backend, backend1, "Backend selection must be consistent");
    523
            }
    524
        }
    525
    526
        #[test]
    527
        fn test_backend_select_best() {
    528
            // Test Backend::select_best() method
    529
            let backend = Backend::select_best();
    530
            assert_eq!(backend, select_best_available_backend());
    531
        }
    532
    533
        #[test]
    534
        fn test_backend_variants() {
    535
            // Test all backend variants
    536
            let backends = vec![
    537
                Backend::Scalar,
    538
                Backend::SSE2,
    539
                Backend::AVX,
    540
                Backend::AVX2,
    541
                Backend::AVX512,
    542
                Backend::NEON,
    543
                Backend::WasmSIMD,
    544
                Backend::GPU,
    545
                Backend::Auto,
    546
            ];
    547
    548
            // Verify all variants are distinct
    549
            for (i, backend1) in backends.iter().enumerate() {
    550
                for (j, backend2) in backends.iter().enumerate() {
    551
                    if i == j {
    552
                        assert_eq!(backend1, backend2);
    553
                    } else {
    554
                        assert_ne!(backend1, backend2);
    555
                    }
    556
                }
    557
            }
    558
        }
    559
    560
        #[test]
    561
        fn test_backend_debug() {
    562
            // Verify Debug trait works
    563
            let backend = Backend::AVX2;
    564
            let debug_str = format!("{:?}", backend);
    565
            assert!(debug_str.contains("AVX2"));
    566
    567
            let backend = Backend::Auto;
    568
            let debug_str = format!("{:?}", backend);
    569
            assert!(debug_str.contains("Auto"));
    570
        }
    571
    572
        #[test]
    573
        fn test_backend_clone() {
    574
            let backend = Backend::AVX2;
    575
            #[allow(clippy::clone_on_copy)]
    576
            let cloned = backend.clone();
    577
            assert_eq!(backend, cloned);
    578
        }
    579
    580
        #[test]
    581
        fn test_backend_copy() {
    582
            let backend = Backend::SSE2;
    583
            let copied = backend;
    584
            assert_eq!(backend, copied);
    585
        }
    586
    587
        #[test]
    588
        fn test_op_complexity_values() {
    589
            assert_eq!(OpComplexity::Low as i32, 0);
    590
            assert_eq!(OpComplexity::Medium as i32, 1);
    591
            assert_eq!(OpComplexity::High as i32, 2);
    592
        }
    593
    594
        #[test]
    595
        fn test_op_complexity_ord() {
    596
            // Test PartialOrd
    597
            assert!(OpComplexity::Low < OpComplexity::Medium);
    598
            assert!(OpComplexity::Medium < OpComplexity::High);
    599
            assert!(OpComplexity::Low < OpComplexity::High);
    600
    601
            // Test Ord
    602
            use std::cmp::Ordering;
    603
            assert_eq!(OpComplexity::Low.cmp(&OpComplexity::Medium), Ordering::Less);
    604
            assert_eq!(
    605
                OpComplexity::Medium.cmp(&OpComplexity::High),
    606
                Ordering::Less
    607
            );
    608
            assert_eq!(
    609
                OpComplexity::High.cmp(&OpComplexity::Medium),
    610
                Ordering::Greater
    611
            );
    612
            assert_eq!(OpComplexity::Low.cmp(&OpComplexity::Low), Ordering::Equal);
    613
        }
    614
    615
        #[test]
    616
        fn test_op_complexity_eq() {
    617
            assert_eq!(OpComplexity::Low, OpComplexity::Low);
    618
            assert_eq!(OpComplexity::Medium, OpComplexity::Medium);
    619
            assert_eq!(OpComplexity::High, OpComplexity::High);
    620
            assert_ne!(OpComplexity::Low, OpComplexity::High);
    621
        }
    622
    623
        #[test]
    624
        fn test_op_complexity_debug() {
    625
            let complexity = OpComplexity::Medium;
    626
            let debug_str = format!("{:?}", complexity);
    627
            assert!(debug_str.contains("Medium"));
    628
        }
    629
    630
        #[test]
    631
        fn test_op_complexity_clone() {
    632
            let complexity = OpComplexity::High;
    633
            #[allow(clippy::clone_on_copy)]
    634
            let cloned = complexity.clone();
    635
            assert_eq!(complexity, cloned);
    636
        }
    637
    638
        #[test]
    639
        fn test_op_complexity_copy() {
    640
            let complexity = OpComplexity::Low;
    641
            let copied = complexity;
    642
            assert_eq!(complexity, copied);
    643
        }
    644
    645
        #[test]
    646
        fn test_trueno_error_reexport() {
    647
            // Verify error types are re-exported correctly
    648
            let _: Result<()> = Ok(());
    649
            let err: Result<()> = Err(TruenoError::EmptyVector);
    650
            assert!(err.is_err());
    651
        }
    652
    653
        #[test]
    654
        fn test_vector_reexport() {
    655
            // Verify Vector is re-exported correctly
    656
            let v = Vector::from_slice(&[1.0, 2.0, 3.0]);
    657
            assert_eq!(v.len(), 3);
    658
        }
    659
    660
        #[test]
    661
        fn test_matrix_reexport() {
    662
            // Verify Matrix is re-exported correctly
    663
            let m = Matrix::zeros(2, 2);
    664
            assert_eq!(m.rows(), 2);
    665
            assert_eq!(m.cols(), 2);
    666
        }
    667
    668
        #[cfg(target_arch = "x86_64")]
    669
        #[test]
    670
        fn test_detect_x86_backend() {
    671
            let backend = detect_x86_backend();
    672
            // On x86_64, we should get at least SSE2
    673
            assert!(matches!(
    674
                backend,
    675
                Backend::SSE2 | Backend::AVX | Backend::AVX2
    676
            ));
    677
            // Should NOT return AVX-512 (intentionally avoided for safety)
    678
            assert_ne!(backend, Backend::AVX512);
    679
        }
    680
    681
        #[test]
    682
        fn test_operation_type_enum() {
    683
            // Verify OperationType variants are distinct
    684
            assert_ne!(OperationType::MemoryBound, OperationType::ComputeBound);
    685
            assert_ne!(OperationType::MemoryBound, OperationType::Mixed);
    686
            assert_ne!(OperationType::ComputeBound, OperationType::Mixed);
    687
        }
    688
    689
        #[cfg(target_arch = "x86_64")]
    690
        #[test]
    691
        fn test_select_backend_for_memory_bound_prefers_avx2() {
    692
            let backend = select_backend_for_operation(OperationType::MemoryBound);
    693
    694
            // Should prefer AVX2 over AVX-512 for memory-bound operations
    695
            // (Based on AVX-512 performance analysis showing 0.67-1.01x scalar)
    696
            if is_x86_feature_detected!("avx2") {
    697
                assert_eq!(backend, Backend::AVX2);
    698
            } else if is_x86_feature_detected!("avx") {
    699
                assert_eq!(backend, Backend::AVX);
    700
            } else if is_x86_feature_detected!("sse2") {
    701
                assert_eq!(backend, Backend::SSE2);
    702
            } else {
    703
                assert_eq!(backend, Backend::Scalar);
    704
            }
    705
    706
            // Critical: Should NEVER return AVX-512 for memory-bound
    707
            assert_ne!(backend, Backend::AVX512);
    708
        }
    709
    710
        #[cfg(target_arch = "x86_64")]
    711
        #[test]
    712
        fn test_select_backend_for_compute_bound_allows_avx512() {
    713
            let backend = select_backend_for_operation(OperationType::ComputeBound);
    714
    715
            // Should prefer AVX-512 for compute-bound operations where it excels (7-14x scalar)
    716
            if is_x86_feature_detected!("avx512f") {
    717
                assert_eq!(backend, Backend::AVX512);
    718
            } else if is_x86_feature_detected!("avx2") {
    719
                assert_eq!(backend, Backend::AVX2);
    720
            } else if is_x86_feature_detected!("avx") {
    721
                assert_eq!(backend, Backend::AVX);
    722
            } else if is_x86_feature_detected!("sse2") {
    723
                assert_eq!(backend, Backend::SSE2);
    724
            } else {
    725
                assert_eq!(backend, Backend::Scalar);
    726
            }
    727
        }
    728
    729
        #[cfg(target_arch = "x86_64")]
    730
        #[test]
    731
        fn test_select_backend_for_mixed_prefers_avx2() {
    732
            let backend = select_backend_for_operation(OperationType::Mixed);
    733
    734
            // Mixed operations should default to AVX2 for safety (avoid AVX-512 thermal throttling)
    735
            if is_x86_feature_detected!("avx2") {
    736
                assert_eq!(backend, Backend::AVX2);
    737
            } else if is_x86_feature_detected!("avx") {
    738
                assert_eq!(backend, Backend::AVX);
    739
            } else if is_x86_feature_detected!("sse2") {
    740
                assert_eq!(backend, Backend::SSE2);
    741
            } else {
    742
                assert_eq!(backend, Backend::Scalar);
    743
            }
    744
    745
            // Should NOT return AVX-512 for mixed operations (safety first)
    746
            assert_ne!(backend, Backend::AVX512);
    747
        }
    748
    749
        #[cfg(target_arch = "x86_64")]
    750
        #[test]
    751
        fn test_default_backend_selection_avoids_avx512() {
    752
            // The default backend selection (detect_x86_backend) should avoid AVX-512
    753
            let default_backend = select_best_available_backend();
    754
    755
            // Even on CPUs with AVX-512, default selection should prefer AVX2
    756
            if is_x86_feature_detected!("avx2") {
    757
                assert_eq!(default_backend, Backend::AVX2);
    758
            }
    759
    760
            // Verify AVX-512 is NOT returned by default
    761
            assert_ne!(default_backend, Backend::AVX512);
    762
        }
    763
    764
        #[cfg(target_arch = "x86_64")]
    765
        #[test]
    766
        fn test_backend_selection_consistency() {
    767
            // Memory-bound and Mixed should return same backend (AVX2-first)
    768
            let memory_backend = select_backend_for_operation(OperationType::MemoryBound);
    769
            let mixed_backend = select_backend_for_operation(OperationType::Mixed);
    770
    771
            assert_eq!(memory_backend, mixed_backend);
    772
    773
            // Compute-bound may differ (allows AVX-512)
    774
            let compute_backend = select_backend_for_operation(OperationType::ComputeBound);
    775
    776
            // If AVX-512 is available, compute backend should be different
    777
            if is_x86_feature_detected!("avx512f") {
    778
                assert_ne!(compute_backend, memory_backend);
    779
                assert_eq!(compute_backend, Backend::AVX512);
    780
            } else {
    781
                // Without AVX-512, all should be the same
    782
                assert_eq!(compute_backend, memory_backend);
    783
            }
    784
        }
    785
    786
        #[cfg(not(target_arch = "x86_64"))]
    787
        #[test]
    788
        fn test_select_backend_for_operation_non_x86() {
    789
            // On non-x86 platforms, all operation types should return platform-specific backend
    790
            let memory = select_backend_for_operation(OperationType::MemoryBound);
    791
            let compute = select_backend_for_operation(OperationType::ComputeBound);
    792
            let mixed = select_backend_for_operation(OperationType::Mixed);
    793
    794
            // All should return the same backend (ARM NEON, WASM SIMD, or Scalar)
    795
            assert_eq!(memory, compute);
    796
            assert_eq!(memory, mixed);
    797
    798
            #[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
    799
            {
    800
                #[cfg(target_feature = "neon")]
    801
                assert_eq!(memory, Backend::NEON);
    802
            }
    803
    804
            #[cfg(target_arch = "wasm32")]
    805
            {
    806
                #[cfg(target_feature = "simd128")]
    807
                assert_eq!(memory, Backend::WasmSIMD);
    808
            }
    809
        }
    810
    811
        // ========================================================================
    812
        // Additional Coverage Tests
    813
        // ========================================================================
    814
    815
        #[test]
    816
        fn test_operation_type_debug() {
    817
            let mem = OperationType::MemoryBound;
    818
            let debug_str = format!("{:?}", mem);
    819
            assert!(debug_str.contains("MemoryBound"));
    820
    821
            let compute = OperationType::ComputeBound;
    822
            let debug_str = format!("{:?}", compute);
    823
            assert!(debug_str.contains("ComputeBound"));
    824
    825
            let mixed = OperationType::Mixed;
    826
            let debug_str = format!("{:?}", mixed);
    827
            assert!(debug_str.contains("Mixed"));
    828
        }
    829
    830
        #[test]
    831
        fn test_operation_type_clone() {
    832
            let op_type = OperationType::ComputeBound;
    833
            #[allow(clippy::clone_on_copy)]
    834
            let cloned = op_type.clone();
    835
            assert_eq!(op_type, cloned);
    836
        }
    837
    838
        #[test]
    839
        fn test_operation_type_copy() {
    840
            let op_type = OperationType::Mixed;
    841
            let copied = op_type;
    842
            assert_eq!(op_type, copied);
    843
        }
    844
    845
        #[test]
    846
        fn test_operation_type_equality() {
    847
            assert_eq!(OperationType::MemoryBound, OperationType::MemoryBound);
    848
            assert_eq!(OperationType::ComputeBound, OperationType::ComputeBound);
    849
            assert_eq!(OperationType::Mixed, OperationType::Mixed);
    850
        }
    851
    852
        #[test]
    853
        fn test_backend_all_variants_debug() {
    854
            // Test Debug for all backend variants
    855
            assert!(format!("{:?}", Backend::Scalar).contains("Scalar"));
    856
            assert!(format!("{:?}", Backend::SSE2).contains("SSE2"));
    857
            assert!(format!("{:?}", Backend::AVX).contains("AVX"));
    858
            assert!(format!("{:?}", Backend::AVX512).contains("AVX512"));
    859
            assert!(format!("{:?}", Backend::NEON).contains("NEON"));
    860
            assert!(format!("{:?}", Backend::WasmSIMD).contains("WasmSIMD"));
    861
            assert!(format!("{:?}", Backend::GPU).contains("GPU"));
    862
        }
    863
    864
        #[test]
    865
        fn test_symmetric_eigen_reexport() {
    866
            // Verify SymmetricEigen is re-exported correctly
    867
            // Just verify it's accessible
    868
            let _ = std::mem::size_of::<SymmetricEigen>();
    869
        }
    870
    871
        #[test]
    872
        fn test_hash_reexport() {
    873
            // Verify hash functions are re-exported correctly
    874
            let result = hash_bytes(b"test");
    875
            assert_ne!(result, 0);
    876
    877
            let key_hash = hash_key("test_key");
    878
            assert_ne!(key_hash, 0);
    879
    880
            let keys = ["a", "b", "c", "d"];
    881
            let batch_result = hash_keys_batch(&keys);
    882
            assert_eq!(batch_result.len(), 4);
    883
        }
    884
    }