File size: 8,325 Bytes
26d5b81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
/**
 * NeuroFlow 边界条件测试
 * 
 * 测试各种边界和异常情况:
 * 1. 空张量
 * 2. 极小尺寸
 * 3. 极大尺寸
 * 4. 无效reshape
 * 5. 维度不匹配
 * 6. 内存溢出检测
 */

#include <iostream>
#include <cassert>
#include <stdexcept>
#include "../include/neuroflow/model.hpp"
#include "../include/neuroflow/tensor.hpp"
#include "../include/neuroflow/memory.hpp"

using namespace neuroflow;

void test_empty_tensor() {
    std::cout << "\n=== Empty Tensor Test ===\n";
    
    // 测试空张量
    try {
        Tensor empty({}, QuantType::FP32);
        std::cout << "  Empty tensor numel: " << empty.numel() << "\n";
        std::cout << "  Empty tensor data_size: " << empty.data_size_ << "\n";
        assert(empty.numel() == 1);  // {} shape means 1 element
        std::cout << "  [PASS] Empty tensor handled\n";
    } catch (const std::exception& e) {
        std::cout << "  Exception: " << e.what() << "\n";
        std::cout << "  [PASS] Empty tensor rejected\n";
    }
}

void test_minimal_sizes() {
    std::cout << "\n=== Minimal Size Test ===\n";
    
    // 1x1张量
    Tensor t1({1, 1}, QuantType::FP32);
    t1.as_fp32()[0] = 1.0f;
    std::cout << "  1x1 tensor: " << t1.as_fp32()[0] << "\n";
    
    // 单元素张量
    Tensor t2({1}, QuantType::FP32);
    std::cout << "  1D tensor numel: " << t2.numel() << "\n";
    
    // 极小模型
    NeuroFlowModel::Config cfg;
    cfg.input_dim = 1;
    cfg.hidden_dim = 1;
    cfg.output_dim = 1;
    cfg.memory_slots = 1;
    cfg.memory_dim = 1;
    cfg.num_layers = 1;
    cfg.num_associations = 1;
    
    NeuroFlowModel model(cfg);
    Tensor input({1, 1});
    input.as_fp32()[0] = 0.5f;
    
    auto output = model.forward(input);
    std::cout << "  Minimal model output shape: [" << output.output.shape_[0] 
              << ", " << output.output.shape_[1] << "]\n";
    
    std::cout << "  [PASS] Minimal sizes work\n";
}

void test_large_sizes() {
    std::cout << "\n=== Large Size Test ===\n";
    
    // 大张量 (但不至于溢出)
    size_t large_size = 1024 * 1024;  // 1M elements = 4MB
    
    try {
        Tensor large({large_size}, QuantType::FP32);
        std::cout << "  Large tensor size: " << large.data_size_ / 1024 / 1024 << " MB\n";
        
        // 填充数据测试
        float* data = large.as_fp32();
        data[0] = 1.0f;
        data[large_size - 1] = 2.0f;
        
        std::cout << "  First element: " << data[0] << "\n";
        std::cout << "  Last element: " << data[large_size - 1] << "\n";
        
        std::cout << "  [PASS] Large tensor works\n";
    } catch (const std::exception& e) {
        std::cout << "  Exception: " << e.what() << "\n";
        std::cout << "  [INFO] Large tensor allocation failed (expected on limited memory)\n";
    }
}

void test_invalid_reshape() {
    std::cout << "\n=== Invalid Reshape Test ===\n";
    
    Tensor t({2, 3}, QuantType::FP32);
    float* data = t.as_fp32();
    for (size_t i = 0; i < 6; ++i) data[i] = i;
    
    // 有效reshape
    try {
        Tensor valid = t.reshape({3, 2});
        std::cout << "  Valid reshape {2,3} -> {3,2}: OK\n";
        std::cout << "  [PASS] Valid reshape works\n";
    } catch (const std::exception& e) {
        std::cout << "  Exception: " << e.what() << "\n";
        std::cout << "  [FAIL] Valid reshape failed!\n";
    }
    
    // 无效reshape (元素数不匹配)
    try {
        Tensor invalid = t.reshape({4, 2});  // 8 != 6
        std::cout << "  Invalid reshape accepted - BUG!\n";
        std::cout << "  [FAIL] Invalid reshape should throw!\n";
    } catch (const std::runtime_error& e) {
        std::cout << "  Exception: " << e.what() << "\n";
        std::cout << "  [PASS] Invalid reshape rejected\n";
    }
}

void test_dimension_mismatch() {
    std::cout << "\n=== Dimension Mismatch Test ===\n";
    
    // GEMM维度不匹配
    Tensor A({2, 3}, QuantType::FP32);
    Tensor B({4, 5}, QuantType::FP32);  // 不匹配!
    Tensor C({2, 5}, QuantType::FP32);
    
    try {
        TensorOps::gemm(A, B, C);
        std::cout << "  [WARN] Dimension mismatch accepted - may crash\n";
    } catch (const std::exception& e) {
        std::cout << "  Exception: " << e.what() << "\n";
        std::cout << "  [PASS] Dimension mismatch detected\n";
    }
    
    // 正确维度
    Tensor B2({3, 5}, QuantType::FP32);
    TensorOps::gemm(A, B2, C);
    std::cout << "  Correct GEMM: OK\n";
    
    std::cout << "  [PASS] Dimension check works\n";
}

void test_quantization_edge_cases() {
    std::cout << "\n=== Quantization Edge Cases Test ===\n";
    
    // 全零张量量化
    Tensor zeros({4, 8}, QuantType::FP32);
    memset(zeros.as_fp32(), 0, zeros.data_size_);
    
    Tensor quant({4, 8}, QuantType::INT8);
    Tensor scale({4}, QuantType::FP32);
    
    TensorOps::quantize_int8(zeros, quant, scale);
    std::cout << "  Zero quantization scale[0]: " << scale.as_fp32()[0] << "\n";
    
    // 极大值量化
    Tensor large_vals({2, 4}, QuantType::FP32);
    float* lv = large_vals.as_fp32();
    lv[0] = 1e10f;  // 极大值
    lv[1] = -1e10f;
    lv[2] = 1e-10f;  // 极小值
    lv[3] = 0.0f;
    
    Tensor quant_large({2, 4}, QuantType::INT8);
    Tensor scale_large({2}, QuantType::FP32);
    
    TensorOps::quantize_int8(large_vals, quant_large, scale_large);
    std::cout << "  Large value quant scale[0]: " << scale_large.as_fp32()[0] << "\n";
    
    std::cout << "  [PASS] Quantization edge cases handled\n";
}

void test_mla_cache_limits() {
    std::cout << "\n=== MLA Cache Limit Test ===\n";
    
    // 测试cache达到上限
    LatentKVCache mla(64, 4, 16, 10);  // max_len=10
    
    for (int i = 0; i < 20; ++i) {  // 超过max_len
        Tensor input({1, 64});
        float* data = input.as_fp32();
        for (size_t j = 0; j < 64; ++j) data[j] = 0.1f * i;
        
        mla.forward(input, true);
    }
    
    std::cout << "  Cache len after 20 inputs: " << mla.cache_len << "\n";
    std::cout << "  Expected max: 10\n";
    
    assert(mla.cache_len <= 10);
    std::cout << "  [PASS] MLA cache limit enforced\n";
}

void test_memory_slots_limit() {
    std::cout << "\n=== Memory Slots Limit Test ===\n";
    
    MemoryConsolidationModule memory(64, 8, 32);  // 8 slots
    
    // 多次巩固
    for (int i = 0; i < 100; ++i) {
        Tensor input({1, 64});
        memory.consolidate(input);
    }
    
    std::cout << "  Memory slots: " << memory.memory_slots << "\n";
    std::cout << "  Memory still works after 100 consolidations\n";
    
    // 测试检索
    Tensor query({1, 64});
    auto result = memory.retrieve(query);
    std::cout << "  Retrieved shape: [" << result.retrieved.shape_[0] 
              << ", " << result.retrieved.shape_[1] << "]\n";
    
    std::cout << "  [PASS] Memory slots limit handled\n";
}

void test_batch_size_edge() {
    std::cout << "\n=== Batch Size Edge Test ===\n";
    
    NeuroFlowModel::Config cfg;
    cfg.input_dim = 16;
    cfg.hidden_dim = 8;
    cfg.output_dim = 2;
    
    NeuroFlowModel model(cfg);
    
    // batch=0 (应该失败或返回空)
    // batch=1
    Tensor single({1, 16});
    auto out1 = model.forward(single);
    std::cout << "  Batch=1 output: [" << out1.output.shape_[0] 
              << ", " << out1.output.shape_[1] << "]\n";
    
    // batch=100 (大batch)
    Tensor large_batch({100, 16});
    auto out100 = model.forward(large_batch);
    std::cout << "  Batch=100 output: [" << out100.output.shape_[0] 
              << ", " << out100.output.shape_[1] << "]\n";
    
    std::cout << "  [PASS] Batch size edge cases work\n";
}

int main() {
    std::cout << "========================================\n";
    std::cout << "NeuroFlow Edge Case Tests\n";
    std::cout << "========================================\n";
    
    test_empty_tensor();
    test_minimal_sizes();
    test_large_sizes();
    test_invalid_reshape();
    test_dimension_mismatch();
    test_quantization_edge_cases();
    test_mla_cache_limits();
    test_memory_slots_limit();
    test_batch_size_edge();
    
    std::cout << "\n========================================\n";
    std::cout << "All Edge Case Tests Complete!\n";
    std::cout << "========================================\n";
    
    return 0;
}