diff --git a/src/recipes/MatMulToFC.cpp b/src/recipes/MatMulToFC.cpp index 87cb48682d473822ee651260ad5a8a4f74a4b6f2..9b5addd3bb971b3f61980a582d4cce6435c57219 100644 --- a/src/recipes/MatMulToFC.cpp +++ b/src/recipes/MatMulToFC.cpp @@ -95,8 +95,14 @@ void Aidge::matMulToFC(std::shared_ptr<Aidge::Node> matmulNode, std::shared_ptr< // Case 1 : If all nodes are in a graph view : delete old nodes & branch input & output // Case 2 : If not all nodes are in a graph view : only delete the nodes from the graphview // Maybe create a central mechanism to update automatically all graph views rather than each node have graphview presence memory? - auto newNodes = std::set<std::shared_ptr<Node>>({fc, fc->getParent(1), fc->getParent(2)}); - GraphView::replace({matmulNode, addNode, bias, weight}, newNodes); + if (addNode) { + auto newNodes = std::set<std::shared_ptr<Node>>({fc, fc->getParent(1), fc->getParent(2)}); + GraphView::replace({matmulNode, addNode, bias, weight}, newNodes); + } + else { + auto newNodes = std::set<std::shared_ptr<Node>>({fc, fc->getParent(1)}); + GraphView::replace({matmulNode, weight}, newNodes); + } } diff --git a/unit_tests/recipes/Test_MatMulToFC.cpp b/unit_tests/recipes/Test_MatMulToFC.cpp index 358204da6cba4c2d047e4d4f4b8ca3f6a06ebb54..2adf882ca69e0d5ca5f050d1b89cfb09d81b536b 100644 --- a/unit_tests/recipes/Test_MatMulToFC.cpp +++ b/unit_tests/recipes/Test_MatMulToFC.cpp @@ -24,51 +24,95 @@ namespace Aidge { TEST_CASE("[cpu/recipes] MatMulToFC", "[MatMulToFC][recipes]") { - // generate the original GraphView - auto matmul0 = MatMul("matmul0"); - auto add0 = Add(2, "add0"); - auto matmul1 = MatMul("matmul1"); - auto add1 = Add(2, "add1"); - - auto b0 = Producer({5}, "B0"); - auto w0 = Producer({5, 5}, "W0"); - auto b1 = Producer({5}, "B1"); - auto w1 = Producer({5,5},"W1"); - auto input = Producer({2,5}, "input"); - - input->addChild(matmul0, 0, 0); - w0->addChild(matmul0, 0, 1); - - matmul0->addChild(add0, 0, 0); - b0->addChild(add0, 0, 1); - - add0->addChild(matmul1, 0, 1); - w1->addChild(matmul1, 0, 0); - - matmul1->addChild(add1, 0, 0); - b1->addChild(add1, 0, 1); - - auto g = std::make_shared<GraphView>(); - g->add({w0, matmul0, b0, add0, w1, matmul1, b1, add1}); - - // Check original graph - REQUIRE(g->getNodes() == - std::set<std::shared_ptr<Node>>({w0, matmul0, b0, add0, w1, matmul1, b1, add1})); - REQUIRE(((matmul0->getParent(0) == input) && (matmul0->getParent(1) == w0))); - REQUIRE(((add0->getParent(0) == matmul0) && (add0->getParent(1) == b0))); - REQUIRE(((matmul1->getParent(1) == add0) && (matmul1->getParent(0) == w1))); - REQUIRE(((add1->getParent(0) == matmul1) && (add1->getParent(1) == b1))); - - // Transform GraphView inplace - matMulToFC(g); - - // Check new GraphView - std::set<std::shared_ptr<Node>> newNodes = g->getNodes(); - REQUIRE(newNodes != std::set<std::shared_ptr<Node>>({w0, matmul0, b0, add0, w1, matmul1, b1, add1})); - REQUIRE(newNodes.size() == 6); - for (const auto& node : newNodes) { - REQUIRE(((node->type() == "Producer") || (node->type() == "FC"))); - } + SECTION("with Add") { + // generate the original GraphView + auto matmul0 = MatMul("matmul0"); + auto add0 = Add(2, "add0"); + auto matmul1 = MatMul("matmul1"); + auto add1 = Add(2, "add1"); + + auto b0 = Producer({5}, "B0"); + auto w0 = Producer({5, 5}, "W0"); + auto b1 = Producer({5}, "B1"); + auto w1 = Producer({5,5},"W1"); + auto input = Producer({2,5}, "input"); + + input->addChild(matmul0, 0, 0); + w0->addChild(matmul0, 0, 1); + + matmul0->addChild(add0, 0, 0); + b0->addChild(add0, 0, 1); + + add0->addChild(matmul1, 0, 1); + w1->addChild(matmul1, 0, 0); + + matmul1->addChild(add1, 0, 0); + b1->addChild(add1, 0, 1); + + auto g = std::make_shared<GraphView>(); + g->add({w0, matmul0, b0, add0, w1, matmul1, b1, add1}); + + // Check original graph + REQUIRE(g->getNodes() == + std::set<std::shared_ptr<Node>>({w0, matmul0, b0, add0, w1, matmul1, b1, add1})); + REQUIRE(((matmul0->getParent(0) == input) && (matmul0->getParent(1) == w0))); + REQUIRE(((add0->getParent(0) == matmul0) && (add0->getParent(1) == b0))); + REQUIRE(((matmul1->getParent(1) == add0) && (matmul1->getParent(0) == w1))); + REQUIRE(((add1->getParent(0) == matmul1) && (add1->getParent(1) == b1))); + + // Transform GraphView inplace + matMulToFC(g); + + // Check new GraphView + std::set<std::shared_ptr<Node>> newNodes = g->getNodes(); + REQUIRE(newNodes != std::set<std::shared_ptr<Node>>({w0, matmul0, b0, add0, w1, matmul1, b1, add1})); + REQUIRE(newNodes.size() == 6); + for (const auto& node : newNodes) { + REQUIRE(((node->type() == "Producer") || (node->type() == "FC"))); + } + } + + SECTION("without Add") { + // generate the original GraphView + auto matmul0 = MatMul("matmul0"); + auto matmul1 = MatMul("matmul1"); + auto add1 = Add(2, "add1"); + + auto w0 = Producer({5, 5}, "W0"); + auto b1 = Producer({5}, "B1"); + auto w1 = Producer({5,5},"W1"); + auto input = Producer({2,5}, "input"); + + input->addChild(matmul0, 0, 0); + w0->addChild(matmul0, 0, 1); + + matmul0->addChild(matmul1, 0, 1); + w1->addChild(matmul1, 0, 0); + + matmul1->addChild(add1, 0, 0); + b1->addChild(add1, 0, 1); + + auto g = std::make_shared<GraphView>(); + g->add({w0, matmul0, w1, matmul1, b1, add1}); + + // Check original graph + REQUIRE(g->getNodes() == + std::set<std::shared_ptr<Node>>({w0, matmul0, w1, matmul1, b1, add1})); + REQUIRE(((matmul0->getParent(0) == input) && (matmul0->getParent(1) == w0))); + REQUIRE(((matmul1->getParent(1) == matmul0) && (matmul1->getParent(0) == w1))); + REQUIRE(((add1->getParent(0) == matmul1) && (add1->getParent(1) == b1))); + + // Transform GraphView inplace + matMulToFC(g); + + // Check new GraphView + std::set<std::shared_ptr<Node>> newNodes = g->getNodes(); + REQUIRE(newNodes != std::set<std::shared_ptr<Node>>({w0, matmul0, w1, matmul1, b1, add1})); + REQUIRE(newNodes.size() == 5); + for (const auto& node : newNodes) { + REQUIRE(((node->type() == "Producer") || (node->type() == "FC"))); + } + } } } // namespace Aidge