diff --git a/unit_tests/operator/Test_BatchNormImpl.cpp b/unit_tests/operator/Test_BatchNormImpl.cpp index a1a749d805a45361c671544f5c94aed3421e557d..8c8c1dff3d74c2fce97abd8c3d88bf9840706ee4 100644 --- a/unit_tests/operator/Test_BatchNormImpl.cpp +++ b/unit_tests/operator/Test_BatchNormImpl.cpp @@ -14,6 +14,7 @@ #include "aidge/data/Tensor.hpp" #include "aidge/operator/BatchNorm.hpp" +#include "aidge/scheduler/SequentialScheduler.hpp" #include "aidge/backend/cpu.hpp" diff --git a/unit_tests/operator/Test_MetaOperator.cpp b/unit_tests/operator/Test_MetaOperator.cpp index c0e9be1c6062eaf311d5eaf2515df2b4fd2b8a9e..5eea881d113d72ecdd7f1efd39e077b218736ef0 100644 --- a/unit_tests/operator/Test_MetaOperator.cpp +++ b/unit_tests/operator/Test_MetaOperator.cpp @@ -23,6 +23,8 @@ #include "aidge/operator/MetaOperatorDefs.hpp" #include "aidge/operator/Pad.hpp" #include "aidge/operator/Pop.hpp" +#include "aidge/scheduler/SequentialScheduler.hpp" +#include "aidge/scheduler/ParallelScheduler.hpp" using namespace Aidge; @@ -206,7 +208,7 @@ TEST_CASE("[cpu/operator] MetaOperator", "[MetaOperator][CPU]") { std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>( Array2D<float, 16, 32>{}); std::shared_ptr<Tensor> myInit = std::make_shared<Tensor>( - Array2D<float, 1, 64>{}); + Array2D<float, 32, 64>{}); std::shared_ptr<Tensor> myInitW = std::make_shared<Tensor>( Array2D<float, 64, 32>{}); std::shared_ptr<Tensor> myInitR = std::make_shared<Tensor>( @@ -233,7 +235,7 @@ TEST_CASE("[cpu/operator] MetaOperator", "[MetaOperator][CPU]") { g->setBackend("cpu"); auto scheduler = SequentialScheduler(g); - scheduler.forward(true, true); + scheduler.forward(true); g->save("lstm_outside_dims", true, true); @@ -245,8 +247,8 @@ TEST_CASE("[cpu/operator] MetaOperator", "[MetaOperator][CPU]") { REQUIRE(op->getNbConsumedData(0) == 512); REQUIRE(op->getNbConsumedData(1) == 32768); - REQUIRE(op->getNbProducedData(0) == 1088); - REQUIRE(op->getNbProducedData(1) == 1088); + REQUIRE(op->getNbProducedData(0) == 34816); + REQUIRE(op->getNbProducedData(1) == 34816); REQUIRE(microGraphScheduler->getStaticScheduling(0).size() == 26); REQUIRE(microGraphScheduler->getStaticScheduling(1).size() == 24); REQUIRE(microGraphScheduler->getStaticScheduling(15).size() == 24); @@ -350,7 +352,7 @@ TEST_CASE("[cpu/operator] MetaOperator", "[MetaOperator][CPU]") { g->save("lstm_seq", true, true); auto scheduler = SequentialScheduler(g); - scheduler.forward(true, true); + scheduler.forward(true); scheduler.saveSchedulingDiagram("lstm_seq_schedule"); std::shared_ptr<Tensor> myHiddenState = std::make_shared<Tensor>( @@ -365,7 +367,7 @@ TEST_CASE("[cpu/operator] MetaOperator", "[MetaOperator][CPU]") { REQUIRE(approxEq<float>(*(op->getOutput(0)), *myHiddenState)); } - SECTION("LSTM(forward_values_seq_flatten)") { + SECTION("LSTM(forward_values_seq_flatten)(sequential)") { auto pop = Pop(); auto myLSTM = LSTM(2, 3, 2, true, "ltsm"); auto op = std::static_pointer_cast<MetaOperator_Op>(myLSTM->getOperator()); @@ -418,8 +420,72 @@ TEST_CASE("[cpu/operator] MetaOperator", "[MetaOperator][CPU]") { {0.67162132, 0.67162132, 0.67162132}}}); auto scheduler = SequentialScheduler(myGraph); - scheduler.forward(true, true); - scheduler.saveSchedulingDiagram("lstm_seq_flatten_schedule"); + scheduler.generateScheduling(); + scheduler.saveStaticSchedulingDiagram("lstm_static_schedule"); + scheduler.forward(true); + scheduler.saveSchedulingDiagram("lstm_seq_flatten_schedule_seq"); + + op->getOutput(0)->print(); + myHiddenState->print(); + + REQUIRE(approxEq<float>(*(op->getOutput(0)), *myHiddenState)); + } + SECTION("LSTM(forward_values_seq_flatten)(parallel)") { + auto pop = Pop(); + auto myLSTM = LSTM(2, 3, 2, true, "ltsm"); + auto op = std::static_pointer_cast<MetaOperator_Op>(myLSTM->getOperator()); + + // Here we test LSTM as it is was flatten in the graph. + // We just borrow its micro-graph into our larger myGraph graph. + auto myGraph = std::make_shared<GraphView>(); + pop->addChild(op->getMicroGraph()->getOrderedInputs()[0].first, 0, 0); + myGraph->add(op->getMicroGraph()); + myGraph->add(pop); + + REQUIRE(myLSTM->nbInputs() == 3 + 8 + 8); + REQUIRE(myLSTM->nbData() == 1); + REQUIRE(myLSTM->nbOutputs() == 2); + + std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>( + Array3D<float, 2, 3, 2>{{{{1.0, 2.0}, {3.0, 4.0}, {5.0, 6.0}}, {{2.0, 3.0}, {4.0, 5.0}, {6.0, 7.0}}}}); + std::shared_ptr<Tensor> myInit = std::make_shared<Tensor>( + Array2D<float, 3, 3>{{{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}}); + std::shared_ptr<Tensor> myInitW = std::make_shared<Tensor>( + Array2D<float, 3, 2>{{{0.1, 0.1}, {0.1, 0.1}, {0.1, 0.1}}}); + std::shared_ptr<Tensor> myInitR = std::make_shared<Tensor>( + Array2D<float, 3, 3>{{{0.1, 0.1, 0.1}, {0.1, 0.1, 0.1}, {0.1, 0.1, 0.1}}}); + + pop->getOperator()->associateInput(0, myInput); + op->associateInput(17, myInit); + op->associateInput(18, myInit); + + // Weights X + auto prodX = Producer(myInitW); + prodX->addChild(op->getMicroGraph()->getOrderedInputs()[1].first, 0, 1); + prodX->addChild(op->getMicroGraph()->getOrderedInputs()[2].first, 0, 1); + prodX->addChild(op->getMicroGraph()->getOrderedInputs()[3].first, 0, 1); + prodX->addChild(op->getMicroGraph()->getOrderedInputs()[4].first, 0, 1); + // Weights H + auto prodH = Producer(myInitR); + prodH->addChild(op->getMicroGraph()->getOrderedInputs()[5].first, 0, 1); + prodH->addChild(op->getMicroGraph()->getOrderedInputs()[6].first, 0, 1); + prodH->addChild(op->getMicroGraph()->getOrderedInputs()[7].first, 0, 1); + prodH->addChild(op->getMicroGraph()->getOrderedInputs()[8].first, 0, 1); + myGraph->add({prodX, prodH}); + + myGraph->setDataType(DataType::Float32); + myGraph->setBackend("cpu"); + myGraph->save("lstm_seq_flatten", true, true); + + std::shared_ptr<Tensor> myHiddenState = std::make_shared<Tensor>( + Array2D<float, 3, 3>{{{0.24439372, 0.24439372, 0.24439372}, + {0.49801484, 0.49801484, 0.49801484}, + {0.67162132, 0.67162132, 0.67162132}}}); + + auto scheduler = ParallelScheduler(myGraph); + scheduler.generateScheduling(); + scheduler.forward(true); + scheduler.saveSchedulingDiagram("lstm_seq_flatten_schedule_par"); op->getOutput(0)->print(); myHiddenState->print(); diff --git a/unit_tests/operator/Test_PaddedConv.cpp b/unit_tests/operator/Test_PaddedConv.cpp index 03a592e52b7d057065353a7d99c088d9831c67c7..b7584ad069336a270ed07c32d4c07552888b6587 100644 --- a/unit_tests/operator/Test_PaddedConv.cpp +++ b/unit_tests/operator/Test_PaddedConv.cpp @@ -16,6 +16,7 @@ #include "aidge/data/Tensor.hpp" #include "aidge/operator/MetaOperator.hpp" #include "aidge/operator/MetaOperatorDefs.hpp" +#include "aidge/scheduler/SequentialScheduler.hpp" #include "aidge/backend/cpu.hpp" diff --git a/unit_tests/recipies/Test_FuseBatchNorm.cpp b/unit_tests/recipies/Test_FuseBatchNorm.cpp index 82eec7f0c248b51b8447706168675f19116dbdf8..68a01541894ba25a8841343d2b3943ccc08c7a9d 100644 --- a/unit_tests/recipies/Test_FuseBatchNorm.cpp +++ b/unit_tests/recipies/Test_FuseBatchNorm.cpp @@ -19,7 +19,7 @@ #include "aidge/operator/BatchNorm.hpp" #include "aidge/operator/Producer.hpp" #include "aidge/recipes/Recipes.hpp" -#include "aidge/scheduler/Scheduler.hpp" +#include "aidge/scheduler/SequentialScheduler.hpp" #include "aidge/data/Tensor.hpp" diff --git a/unit_tests/recipies/Test_HorizontalTiling.cpp b/unit_tests/recipies/Test_HorizontalTiling.cpp index 5141e4386d46c181a1adc6f65c4820a60fafed85..a8a384f611a8cf99a0aa94c58e9bcd5955f698c4 100644 --- a/unit_tests/recipies/Test_HorizontalTiling.cpp +++ b/unit_tests/recipies/Test_HorizontalTiling.cpp @@ -17,7 +17,7 @@ #include "aidge/operator/Conv.hpp" #include "aidge/operator/ReLU.hpp" #include "aidge/recipes/Recipes.hpp" -#include "aidge/scheduler/Scheduler.hpp" +#include "aidge/scheduler/SequentialScheduler.hpp" #include "aidge/operator/Concat.hpp" diff --git a/unit_tests/scheduler/Test_CastMove.cpp b/unit_tests/scheduler/Test_CastMove.cpp index 1c46ee3b760644b1aa71a75900a1c198660cfa43..5ca2cd9de4dcc9dab2c78f7ae1e1bf3090db8f2b 100644 --- a/unit_tests/scheduler/Test_CastMove.cpp +++ b/unit_tests/scheduler/Test_CastMove.cpp @@ -18,7 +18,7 @@ #include "aidge/graph/Node.hpp" #include "aidge/graph/GraphView.hpp" #include "aidge/graph/OpArgs.hpp" -#include "aidge/scheduler/Scheduler.hpp" +#include "aidge/scheduler/SequentialScheduler.hpp" #include "aidge/recipes/Recipes.hpp" #include "aidge/backend/cpu.hpp" diff --git a/unit_tests/scheduler/Test_Scheduler.cpp b/unit_tests/scheduler/Test_Scheduler.cpp index 025ca8ba067297ff3232e05ea9142899dca8ddef..d2306ad0127f19c06ac2b84f8ab83673a56c35b2 100644 --- a/unit_tests/scheduler/Test_Scheduler.cpp +++ b/unit_tests/scheduler/Test_Scheduler.cpp @@ -17,7 +17,8 @@ #include "aidge/graph/Node.hpp" #include "aidge/graph/GraphView.hpp" #include "aidge/graph/OpArgs.hpp" -#include "aidge/scheduler/Scheduler.hpp" +#include "aidge/scheduler/SequentialScheduler.hpp" +#include "aidge/scheduler/ParallelScheduler.hpp" #include "aidge/backend/cpu.hpp" @@ -205,7 +206,7 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") { SECTION("Test Residual graph") { } - SECTION("Test Recurrent graph") { + SECTION("Test Recurrent graph (sequential)") { std::shared_ptr<Tensor> in = std::make_shared<Tensor>( Array2D<int, 2, 3>{{{1, 2, 3}, {4, 5, 6}}}); std::shared_ptr<Tensor> initTensor = std::make_shared<Tensor>( @@ -232,9 +233,54 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") { g->setDataType(Aidge::DataType::Int32); g->save("graphRecurrent"); g->forwardDims(); + SequentialScheduler scheduler(g); - REQUIRE_NOTHROW(scheduler.forward(true, true)); - scheduler.saveSchedulingDiagram("schedulingRecurrent"); + REQUIRE_NOTHROW(scheduler.forward(true)); + scheduler.saveStaticSchedulingDiagram("static_schedule"); + scheduler.saveSchedulingDiagram("schedulingRecurrent_seq"); + + std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>( + Array2D<int, 2, 3>{{{5, 6, 9}, {14, 16, 19}}}); + std::shared_ptr<Tensor> result = + std::static_pointer_cast<Tensor>(g->getNode("add2")->getOperator()->getRawOutput(0)); + result->print(); + expectedOutput->print(); + bool equal = (*result == *expectedOutput); + REQUIRE(equal); + } + + + SECTION("Test Recurrent graph (parallel)") { + std::shared_ptr<Tensor> in = std::make_shared<Tensor>( + Array2D<int, 2, 3>{{{1, 2, 3}, {4, 5, 6}}}); + std::shared_ptr<Tensor> initTensor = std::make_shared<Tensor>( + Array2D<int, 2, 3>{{{0, 0, 0}, {1, 1, 1}}}); + std::shared_ptr<Tensor> biasTensor = std::make_shared<Tensor>( + Array2D<int, 2, 3>{{{2, 0, 0}, {1, 0, 0}}}); + + auto add1 = Add(2, "add1"); + auto mem = Memorize(3, "mem1"); + auto add2 = Add(2, "add2"); + auto bias = Producer(biasTensor, "bias"); + auto init = Producer(initTensor, "init"); + auto input = Producer(in, "input"); + + std::shared_ptr<GraphView> g = Sequential({add1, mem, add2}); + init->addChild(mem, 0, 1); + mem->addChild(add1, 1, 1); + bias->addChild(add2, 0, 1); + input->addChild(add1, 0, 0); + // Update GraphView inputs/outputs following previous connections: + g->add({mem, add1, add2, init, bias, input}); + + g->setBackend("cpu"); + g->setDataType(Aidge::DataType::Int32); + g->save("graphRecurrent"); + g->forwardDims(); + + ParallelScheduler scheduler(g); + REQUIRE_NOTHROW(scheduler.forward(true)); + scheduler.saveSchedulingDiagram("schedulingRecurrent_par"); std::shared_ptr<Tensor> expectedOutput = std::make_shared<Tensor>( Array2D<int, 2, 3>{{{5, 6, 9}, {14, 16, 19}}}); @@ -299,7 +345,7 @@ TEST_CASE("[cpu/scheduler] SequentialScheduler(forward)") { SequentialScheduler scheduler(g); std::vector<std::shared_ptr<Aidge::Tensor>> dataIn = {inputTensor}; - REQUIRE_NOTHROW(scheduler.forward(true, false, dataIn)); + REQUIRE_NOTHROW(scheduler.forward(true, dataIn)); scheduler.saveSchedulingDiagram("schedulingSequential");