CoolFace
Modelpublic

cwenzi/neuroflow-cpp

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
1likes
test_edge_cases.cpp268 linesDownload Raw Back to tests
1/**2 * NeuroFlow 边界条件测试3 * 4 * 测试各种边界和异常情况:5 * 1. 空张量6 * 2. 极小尺寸7 * 3. 极大尺寸8 * 4. 无效reshape9 * 5. 维度不匹配10 * 6. 内存溢出检测11 */12 13#include <iostream>14#include <cassert>15#include <stdexcept>16#include "../include/neuroflow/model.hpp"17#include "../include/neuroflow/tensor.hpp"18#include "../include/neuroflow/memory.hpp"19 20using namespace neuroflow;21 22void test_empty_tensor() {23    std::cout << "\n=== Empty Tensor Test ===\n";24    25    // 测试空张量26    try {27        Tensor empty({}, QuantType::FP32);28        std::cout << "  Empty tensor numel: " << empty.numel() << "\n";29        std::cout << "  Empty tensor data_size: " << empty.data_size_ << "\n";30        assert(empty.numel() == 1);  // {} shape means 1 element31        std::cout << "  [PASS] Empty tensor handled\n";32    } catch (const std::exception& e) {33        std::cout << "  Exception: " << e.what() << "\n";34        std::cout << "  [PASS] Empty tensor rejected\n";35    }36}37 38void test_minimal_sizes() {39    std::cout << "\n=== Minimal Size Test ===\n";40    41    // 1x1张量42    Tensor t1({1, 1}, QuantType::FP32);43    t1.as_fp32()[0] = 1.0f;44    std::cout << "  1x1 tensor: " << t1.as_fp32()[0] << "\n";45    46    // 单元素张量47    Tensor t2({1}, QuantType::FP32);48    std::cout << "  1D tensor numel: " << t2.numel() << "\n";49    50    // 极小模型51    NeuroFlowModel::Config cfg;52    cfg.input_dim = 1;53    cfg.hidden_dim = 1;54    cfg.output_dim = 1;55    cfg.memory_slots = 1;56    cfg.memory_dim = 1;57    cfg.num_layers = 1;58    cfg.num_associations = 1;59    60    NeuroFlowModel model(cfg);61    Tensor input({1, 1});62    input.as_fp32()[0] = 0.5f;63    64    auto output = model.forward(input);65    std::cout << "  Minimal model output shape: [" << output.output.shape_[0] 66              << ", " << output.output.shape_[1] << "]\n";67    68    std::cout << "  [PASS] Minimal sizes work\n";69}70 71void test_large_sizes() {72    std::cout << "\n=== Large Size Test ===\n";73    74    // 大张量 (但不至于溢出)75    size_t large_size = 1024 * 1024;  // 1M elements = 4MB76    77    try {78        Tensor large({large_size}, QuantType::FP32);79        std::cout << "  Large tensor size: " << large.data_size_ / 1024 / 1024 << " MB\n";80        81        // 填充数据测试82        float* data = large.as_fp32();83        data[0] = 1.0f;84        data[large_size - 1] = 2.0f;85        86        std::cout << "  First element: " << data[0] << "\n";87        std::cout << "  Last element: " << data[large_size - 1] << "\n";88        89        std::cout << "  [PASS] Large tensor works\n";90    } catch (const std::exception& e) {91        std::cout << "  Exception: " << e.what() << "\n";92        std::cout << "  [INFO] Large tensor allocation failed (expected on limited memory)\n";93    }94}95 96void test_invalid_reshape() {97    std::cout << "\n=== Invalid Reshape Test ===\n";98    99    Tensor t({2, 3}, QuantType::FP32);100    float* data = t.as_fp32();101    for (size_t i = 0; i < 6; ++i) data[i] = i;102    103    // 有效reshape104    try {105        Tensor valid = t.reshape({3, 2});106        std::cout << "  Valid reshape {2,3} -> {3,2}: OK\n";107        std::cout << "  [PASS] Valid reshape works\n";108    } catch (const std::exception& e) {109        std::cout << "  Exception: " << e.what() << "\n";110        std::cout << "  [FAIL] Valid reshape failed!\n";111    }112    113    // 无效reshape (元素数不匹配)114    try {115        Tensor invalid = t.reshape({4, 2});  // 8 != 6116        std::cout << "  Invalid reshape accepted - BUG!\n";117        std::cout << "  [FAIL] Invalid reshape should throw!\n";118    } catch (const std::runtime_error& e) {119        std::cout << "  Exception: " << e.what() << "\n";120        std::cout << "  [PASS] Invalid reshape rejected\n";121    }122}123 124void test_dimension_mismatch() {125    std::cout << "\n=== Dimension Mismatch Test ===\n";126    127    // GEMM维度不匹配128    Tensor A({2, 3}, QuantType::FP32);129    Tensor B({4, 5}, QuantType::FP32);  // 不匹配!130    Tensor C({2, 5}, QuantType::FP32);131    132    try {133        TensorOps::gemm(A, B, C);134        std::cout << "  [WARN] Dimension mismatch accepted - may crash\n";135    } catch (const std::exception& e) {136        std::cout << "  Exception: " << e.what() << "\n";137        std::cout << "  [PASS] Dimension mismatch detected\n";138    }139    140    // 正确维度141    Tensor B2({3, 5}, QuantType::FP32);142    TensorOps::gemm(A, B2, C);143    std::cout << "  Correct GEMM: OK\n";144    145    std::cout << "  [PASS] Dimension check works\n";146}147 148void test_quantization_edge_cases() {149    std::cout << "\n=== Quantization Edge Cases Test ===\n";150    151    // 全零张量量化152    Tensor zeros({4, 8}, QuantType::FP32);153    memset(zeros.as_fp32(), 0, zeros.data_size_);154    155    Tensor quant({4, 8}, QuantType::INT8);156    Tensor scale({4}, QuantType::FP32);157    158    TensorOps::quantize_int8(zeros, quant, scale);159    std::cout << "  Zero quantization scale[0]: " << scale.as_fp32()[0] << "\n";160    161    // 极大值量化162    Tensor large_vals({2, 4}, QuantType::FP32);163    float* lv = large_vals.as_fp32();164    lv[0] = 1e10f;  // 极大值165    lv[1] = -1e10f;166    lv[2] = 1e-10f;  // 极小值167    lv[3] = 0.0f;168    169    Tensor quant_large({2, 4}, QuantType::INT8);170    Tensor scale_large({2}, QuantType::FP32);171    172    TensorOps::quantize_int8(large_vals, quant_large, scale_large);173    std::cout << "  Large value quant scale[0]: " << scale_large.as_fp32()[0] << "\n";174    175    std::cout << "  [PASS] Quantization edge cases handled\n";176}177 178void test_mla_cache_limits() {179    std::cout << "\n=== MLA Cache Limit Test ===\n";180    181    // 测试cache达到上限182    LatentKVCache mla(64, 4, 16, 10);  // max_len=10183    184    for (int i = 0; i < 20; ++i) {  // 超过max_len185        Tensor input({1, 64});186        float* data = input.as_fp32();187        for (size_t j = 0; j < 64; ++j) data[j] = 0.1f * i;188        189        mla.forward(input, true);190    }191    192    std::cout << "  Cache len after 20 inputs: " << mla.cache_len << "\n";193    std::cout << "  Expected max: 10\n";194    195    assert(mla.cache_len <= 10);196    std::cout << "  [PASS] MLA cache limit enforced\n";197}198 199void test_memory_slots_limit() {200    std::cout << "\n=== Memory Slots Limit Test ===\n";201    202    MemoryConsolidationModule memory(64, 8, 32);  // 8 slots203    204    // 多次巩固205    for (int i = 0; i < 100; ++i) {206        Tensor input({1, 64});207        memory.consolidate(input);208    }209    210    std::cout << "  Memory slots: " << memory.memory_slots << "\n";211    std::cout << "  Memory still works after 100 consolidations\n";212    213    // 测试检索214    Tensor query({1, 64});215    auto result = memory.retrieve(query);216    std::cout << "  Retrieved shape: [" << result.retrieved.shape_[0] 217              << ", " << result.retrieved.shape_[1] << "]\n";218    219    std::cout << "  [PASS] Memory slots limit handled\n";220}221 222void test_batch_size_edge() {223    std::cout << "\n=== Batch Size Edge Test ===\n";224    225    NeuroFlowModel::Config cfg;226    cfg.input_dim = 16;227    cfg.hidden_dim = 8;228    cfg.output_dim = 2;229    230    NeuroFlowModel model(cfg);231    232    // batch=0 (应该失败或返回空)233    // batch=1234    Tensor single({1, 16});235    auto out1 = model.forward(single);236    std::cout << "  Batch=1 output: [" << out1.output.shape_[0] 237              << ", " << out1.output.shape_[1] << "]\n";238    239    // batch=100 (大batch)240    Tensor large_batch({100, 16});241    auto out100 = model.forward(large_batch);242    std::cout << "  Batch=100 output: [" << out100.output.shape_[0] 243              << ", " << out100.output.shape_[1] << "]\n";244    245    std::cout << "  [PASS] Batch size edge cases work\n";246}247 248int main() {249    std::cout << "========================================\n";250    std::cout << "NeuroFlow Edge Case Tests\n";251    std::cout << "========================================\n";252    253    test_empty_tensor();254    test_minimal_sizes();255    test_large_sizes();256    test_invalid_reshape();257    test_dimension_mismatch();258    test_quantization_edge_cases();259    test_mla_cache_limits();260    test_memory_slots_limit();261    test_batch_size_edge();262    263    std::cout << "\n========================================\n";264    std::cout << "All Edge Case Tests Complete!\n";265    std::cout << "========================================\n";266    267    return 0;268}