Buckets:
| /** | |
| * NeuroFlow 边界条件测试 | |
| * | |
| * 测试各种边界和异常情况: | |
| * 1. 空张量 | |
| * 2. 极小尺寸 | |
| * 3. 极大尺寸 | |
| * 4. 无效reshape | |
| * 5. 维度不匹配 | |
| * 6. 内存溢出检测 | |
| */ | |
| 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; | |
| } |
Xet Storage Details
- Size:
- 8.33 kB
- Xet hash:
- b23475bf9f4c367f69db05617c5dc8b7159716c42e2acdf82dce6dcc95090ecc
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.