#include #include #include "../include/neuroflow/model.hpp" #include "../include/neuroflow/backprop.hpp" using namespace neuroflow; void test_forward_cache() { std::cout << "\n=== Forward Cache Test ===\n"; NeuroFlowModel::Config cfg; cfg.input_dim = 64; cfg.hidden_dim = 32; cfg.output_dim = 5; cfg.memory_dim = 32; cfg.num_layers = 1; cfg.num_associations = 2; NeuroFlowModel model(cfg); FullBackpropEngine bp(model); Tensor input({2, 64}); float* data = input.as_fp32(); for (size_t i = 0; i < input.numel(); ++i) { data[i] = 0.1f * i; } auto output = bp.forward_with_cache(input); std::cout << " Forward cache stored:\n"; std::cout << " input: [" << bp.cache.input.shape_[0] << ", " << bp.cache.input.shape_[1] << "]\n"; std::cout << " h: [" << bp.cache.h.shape_[0] << ", " << bp.cache.h.shape_[1] << "]\n"; std::cout << " ecn_hidden: " << bp.cache.ecn_hidden.size() << " layers\n"; std::cout << " combined: [" << bp.cache.combined.shape_[0] << ", " << bp.cache.combined.shape_[1] << "]\n"; std::cout << " Output shape: [" << output.output.shape_[0] << ", " << output.output.shape_[1] << "]\n"; std::cout << " [PASS] Forward cache works\n"; } void test_backward_pass() { std::cout << "\n=== Backward Pass Test ===\n"; NeuroFlowModel::Config cfg; cfg.input_dim = 64; cfg.hidden_dim = 32; cfg.output_dim = 5; cfg.memory_dim = 32; cfg.num_layers = 1; cfg.num_associations = 2; NeuroFlowModel model(cfg); FullBackpropEngine bp(model); Tensor input({2, 64}); for (size_t i = 0; i < input.numel(); ++i) { input.as_fp32()[i] = 0.1f * i; } auto output = bp.forward_with_cache(input); Tensor output_grad({2, 5}); for (size_t i = 0; i < output_grad.numel(); ++i) { output_grad.as_fp32()[i] = 0.01f; } auto grads = bp.backward(output_grad); std::cout << " Backward gradients computed:\n"; std::cout << " output_fusion_down_weight_grad: [" << grads.output_fusion_down_weight_grad.shape_[0] << ", " << grads.output_fusion_down_weight_grad.shape_[1] << "]\n"; std::cout << " output_fusion_up_weight_grad: [" << grads.output_fusion_up_weight_grad.shape_[0] << ", " << grads.output_fusion_up_weight_grad.shape_[1] << "]\n"; std::cout << " input_grad: [" << grads.input_grad.shape_[0] << ", " << grads.input_grad.shape_[1] << "]\n"; float grad_sum = 0; const float* wg = grads.output_fusion_down_weight_grad.as_fp32(); for (size_t i = 0; i < grads.output_fusion_down_weight_grad.numel(); ++i) { grad_sum += std::abs(wg[i]); } std::cout << " Total weight gradient magnitude: " << grad_sum << "\n"; std::cout << " [PASS] Backward pass works\n"; } void test_trainer() { std::cout << "\n=== FullTrainer Test ===\n"; NeuroFlowModel::Config cfg; cfg.input_dim = 64; cfg.hidden_dim = 32; cfg.output_dim = 5; cfg.memory_dim = 32; cfg.num_layers = 1; cfg.num_associations = 2; NeuroFlowModel model(cfg); FullTrainer trainer(model, 0.01f); Tensor input({2, 64}); Tensor target({2, 5}); std::mt19937 rng(42); std::uniform_real_distribution dist(-0.05f, 0.05f); for (size_t i = 0; i < input.numel(); ++i) { input.as_fp32()[i] = dist(rng); } for (size_t i = 0; i < target.numel(); ++i) { target.as_fp32()[i] = (i % 5 == 2) ? 1.0f : 0.0f; } auto output1 = model.forward(input); float loss1 = LossFunctions::mse(output1.output, target); std::cout << " Training for 10 steps...\n"; for (int i = 0; i < 10; ++i) { auto step = trainer.train_step(input, target); std::cout << " Step " << i << ": loss=" << step.loss << ", grad_norm=" << step.grad_norm << "\n"; } auto output2 = model.forward(input); float loss2 = LossFunctions::mse(output2.output, target); std::cout << " Initial loss: " << loss1 << "\n"; std::cout << " Final loss: " << loss2 << "\n"; std::cout << " Loss reduction: " << (loss1 - loss2) << "\n"; if (loss2 <= loss1) { std::cout << " [PASS] Training reduces loss\n"; } else { std::cout << " [WARN] Loss increased\n"; } } void test_memory_consolidation_training() { std::cout << "\n=== Memory Consolidation Training Test ===\n"; NeuroFlowModel::Config cfg; cfg.input_dim = 64; cfg.hidden_dim = 32; cfg.output_dim = 5; cfg.memory_slots = 16; cfg.memory_dim = 16; NeuroFlowModel model(cfg); FullTrainer trainer(model, 0.01f); std::cout << " Initial memory bank sample: " << model.memory->memory_bank.as_fp32()[0] << "\n"; std::mt19937 rng(123); std::uniform_real_distribution dist(-0.05f, 0.05f); std::uniform_real_distribution dist01(0.0f, 1.0f); for (int batch = 0; batch < 5; ++batch) { Tensor input({4, 64}); Tensor target({4, 5}); for (size_t i = 0; i < input.numel(); ++i) { input.as_fp32()[i] = dist(rng); } for (size_t i = 0; i < target.numel(); ++i) { target.as_fp32()[i] = dist01(rng); } auto step = trainer.train_step(input, target); std::cout << " Batch " << batch << ": loss=" << step.loss << "\n"; } float mem_after = model.memory->memory_bank.as_fp32()[0]; std::cout << " Memory bank after training: " << mem_after << "\n"; std::cout << " Memory slots: " << model.memory->memory_slots << "\n"; std::cout << " [PASS] Memory consolidation during training\n"; } void test_gradient_flow() { std::cout << "\n=== Gradient Flow Test ===\n"; NeuroFlowModel::Config cfg; cfg.input_dim = 32; cfg.hidden_dim = 16; cfg.output_dim = 3; cfg.num_layers = 2; NeuroFlowModel model(cfg); FullBackpropEngine bp(model); Tensor input({1, 32}); for (size_t i = 0; i < 32; ++i) input.as_fp32()[i] = 0.1f; auto output = bp.forward_with_cache(input); Tensor output_grad({1, 3}); output_grad.as_fp32()[0] = 1.0f; output_grad.as_fp32()[1] = 0.0f; output_grad.as_fp32()[2] = -1.0f; auto grads = bp.backward(output_grad); std::cout << " Input gradient samples:\n"; const float* ig = grads.input_grad.as_fp32(); for (size_t i = 0; i < 5; ++i) { std::cout << " grad[" << i << "] = " << ig[i] << "\n"; } std::cout << " [PASS] Gradient flows to input\n"; } int main() { std::cout << "========================================\n"; std::cout << "NeuroFlow Backpropagation Tests\n"; std::cout << "========================================\n"; test_forward_cache(); test_backward_pass(); test_trainer(); test_memory_consolidation_training(); test_gradient_flow(); std::cout << "\n========================================\n"; std::cout << "All Tests Complete!\n"; std::cout << "========================================\n"; return 0; }