From 9bfe76bad00a95553914ec11ba1efbae7a22ca40 Mon Sep 17 00:00:00 2001 From: NAUD Maxence <maxence.naud@cea.fr> Date: Sat, 19 Oct 2024 19:45:21 +0000 Subject: [PATCH] Remove the number-of-input option from Add operator as it complicates the code but is never used --- .../aidge_export_aidge/operator_export/add.py | 14 +++++++++++++ .../templates/graph_ctor/add.jinja | 9 +++++++++ aidge_core/unit_tests/test_recipes.py | 4 ++-- .../unit_tests/test_topological_order.py | 4 ++-- include/aidge/operator/Add.hpp | 4 ++-- python_binding/operator/pybind_Add.cpp | 4 ++-- src/data/Tensor.cpp | 2 +- src/operator/Add.cpp | 14 ++++++------- src/operator/MetaOperatorDefs/LSTM.cpp | 20 +++++++++---------- src/recipes/ConvToMatMul.cpp | 2 +- unit_tests/graph/Test_GraphView.cpp | 10 +++++----- unit_tests/graph/Test_Matching.cpp | 4 ++-- unit_tests/operator/Test_Operator.cpp | 2 +- unit_tests/recipes/Test_MatMulToFC.cpp | 6 +++--- 14 files changed, 61 insertions(+), 38 deletions(-) create mode 100644 aidge_core/aidge_export_aidge/operator_export/add.py create mode 100644 aidge_core/aidge_export_aidge/templates/graph_ctor/add.jinja diff --git a/aidge_core/aidge_export_aidge/operator_export/add.py b/aidge_core/aidge_export_aidge/operator_export/add.py new file mode 100644 index 000000000..4eb7c3e37 --- /dev/null +++ b/aidge_core/aidge_export_aidge/operator_export/add.py @@ -0,0 +1,14 @@ +from aidge_core.aidge_export_aidge.registry import ExportSerialize +from aidge_core.aidge_export_aidge import ROOT_EXPORT +from aidge_core.export_utils import ExportNodeCpp +from aidge_core import ImplSpec, IOSpec, dtype + +@ExportSerialize.register("Add", ImplSpec(IOSpec(dtype.any))) +class Add(ExportNodeCpp): + def __init__(self, node, mem_info): + super().__init__(node, mem_info) + self.config_template = "" + self.forward_template = str( + ROOT_EXPORT / "templates/graph_ctor/add.jinja") + self.include_list = ["aidge/operator/Add.hpp"] + self.kernels_to_copy = [] diff --git a/aidge_core/aidge_export_aidge/templates/graph_ctor/add.jinja b/aidge_core/aidge_export_aidge/templates/graph_ctor/add.jinja new file mode 100644 index 000000000..2bfaf9364 --- /dev/null +++ b/aidge_core/aidge_export_aidge/templates/graph_ctor/add.jinja @@ -0,0 +1,9 @@ +{% filter indent(width=4, first=False) %} +/*** {{name|upper}} ***/ +std::shared_ptr<Aidge::Node> {{name}} = + Aidge::Add( + "{{name}}" + ); +{% include "./_set_input.jinja" %} +graph->add({{name}}); +{% endfilter %} diff --git a/aidge_core/unit_tests/test_recipes.py b/aidge_core/unit_tests/test_recipes.py index c8dd4c727..f4dd0220e 100644 --- a/aidge_core/unit_tests/test_recipes.py +++ b/aidge_core/unit_tests/test_recipes.py @@ -46,9 +46,9 @@ class test_recipes(unittest.TestCase): def test_fuse_matmul_add(self): matmul0 = aidge_core.MatMul(name="MatMul0") - add0 = aidge_core.Add(2, name="Add0") + add0 = aidge_core.Add(name="Add0") matmul1 = aidge_core.MatMul(name="MatMul1") - add1 = aidge_core.Add(2, name="Add1") + add1 = aidge_core.Add(name="Add1") w0 = aidge_core.Producer([1, 1], name="W0") w0.add_child(matmul0, 0, 0) b0 = aidge_core.Producer([1], name="B0") diff --git a/aidge_core/unit_tests/test_topological_order.py b/aidge_core/unit_tests/test_topological_order.py index 8e7f2e2d9..01a69409e 100644 --- a/aidge_core/unit_tests/test_topological_order.py +++ b/aidge_core/unit_tests/test_topological_order.py @@ -29,7 +29,7 @@ class test_topological_order(unittest.TestCase): loop0.get_operator().set_back_edges({1}) assert not loop0.get_operator().is_back_edge(0) assert loop0.get_operator().is_back_edge(1) - add0 = aidge_core.Add(2, "add0") + add0 = aidge_core.Add("add0") loop0.add_child(add0, 0, 1) add0.add_child(loop0, 0, 1) @@ -50,7 +50,7 @@ class test_topological_order(unittest.TestCase): loop0.get_operator().set_back_edges({0}) assert not loop0.get_operator().is_back_edge(1) assert loop0.get_operator().is_back_edge(0) - add0 = aidge_core.Add(2, "add0") + add0 = aidge_core.Add("add0") loop0.add_child(add0, 0, 1) add0.add_child(loop0, 0, 0) diff --git a/include/aidge/operator/Add.hpp b/include/aidge/operator/Add.hpp index f96996079..827fc0c27 100644 --- a/include/aidge/operator/Add.hpp +++ b/include/aidge/operator/Add.hpp @@ -29,7 +29,7 @@ class Add_Op : public OperatorTensor, public: static const std::string Type; - Add_Op(const IOIndex_t nbIn); + Add_Op(); /** * @brief Copy-constructor. Copy the operator attributes and its output tensor(s), but not its input tensors (the new operator has no input associated). @@ -66,7 +66,7 @@ public: } }; -std::shared_ptr<Node> Add(const IOIndex_t nbIn, const std::string& name = ""); +std::shared_ptr<Node> Add(const std::string& name = ""); } #endif /* AIDGE_CORE_OPERATOR_ADD_H_ */ diff --git a/python_binding/operator/pybind_Add.cpp b/python_binding/operator/pybind_Add.cpp index 8a00a1cb4..f8adfd5f4 100644 --- a/python_binding/operator/pybind_Add.cpp +++ b/python_binding/operator/pybind_Add.cpp @@ -22,14 +22,14 @@ namespace Aidge { void declare_Add(py::module &m) { py::class_<Add_Op, std::shared_ptr<Add_Op>, OperatorTensor>(m, "AddOp", py::multiple_inheritance()) - .def(py::init<const IOIndex_t>(), py::arg("nb_inputs")) + .def(py::init<>()) .def_static("get_inputs_name", &Add_Op::getInputsName) .def_static("get_outputs_name", &Add_Op::getOutputsName) .def_readonly_static("Type", &Add_Op::Type); declare_registrable<Add_Op>(m, "AddOp"); - m.def("Add", &Add, py::arg("nb_inputs"), py::arg("name") = ""); + m.def("Add", &Add, py::arg("name") = ""); } void init_Add(py::module &m) { diff --git a/src/data/Tensor.cpp b/src/data/Tensor.cpp index abfc91c6c..6f60d2f15 100644 --- a/src/data/Tensor.cpp +++ b/src/data/Tensor.cpp @@ -35,7 +35,7 @@ Aidge::Tensor Aidge::Tensor::operator+(const Aidge::Tensor& other) const { AIDGE_ASSERT(mImpl->backend() == other.mImpl->backend(), "Tensors must have the same backend"); AIDGE_ASSERT(dataType() == other.dataType(), "Tensors must have the same data type"); AIDGE_ASSERT(dataFormat() == other.dataFormat(), "Tensors must have the same data format"); - auto add_ = Add_Op(2); + auto add_ = Add_Op(); add_.associateInput(0, std::make_shared<Tensor>(*this)); add_.associateInput(1, std::make_shared<Tensor>(other)); add_.setDataType(dataType()); diff --git a/src/operator/Add.cpp b/src/operator/Add.cpp index 033c476c8..f6fd0cd9f 100644 --- a/src/operator/Add.cpp +++ b/src/operator/Add.cpp @@ -22,12 +22,10 @@ const std::string Aidge::Add_Op::Type = "Add"; -Aidge::Add_Op::Add_Op(const IOIndex_t nbIn) - : OperatorTensor(Type, std::vector<InputCategory>(nbIn, InputCategory::Data), 1) +Aidge::Add_Op::Add_Op() + : OperatorTensor(Type, {InputCategory::Data, InputCategory::Data}, 1) { - if (nbIn == 0) { - AIDGE_THROW_OR_ABORT(std::runtime_error, "Add operator should have at least one input."); - } + // ctor } Aidge::Add_Op::Add_Op(const Add_Op& op) @@ -89,6 +87,8 @@ std::set<std::string> Aidge::Add_Op::getAvailableBackends() const { return Registrar<Add_Op>::getKeys(); } -std::shared_ptr<Aidge::Node> Aidge::Add(const IOIndex_t nbIn, const std::string& name) { - return std::make_shared<Node>(std::make_shared<Add_Op>(nbIn), name); +//////////////////////////////////////////////////////////////////////////////// + +std::shared_ptr<Aidge::Node> Aidge::Add(const std::string& name) { + return std::make_shared<Node>(std::make_shared<Add_Op>(), name); } \ No newline at end of file diff --git a/src/operator/MetaOperatorDefs/LSTM.cpp b/src/operator/MetaOperatorDefs/LSTM.cpp index 9620f0404..2ed548805 100644 --- a/src/operator/MetaOperatorDefs/LSTM.cpp +++ b/src/operator/MetaOperatorDefs/LSTM.cpp @@ -35,14 +35,14 @@ std::shared_ptr<Node> LSTM(const DimSize_t inChannel, auto input = Identity((!name.empty()) ? name + "_input" : ""); auto hiddenState = Memorize(seqLength, (!name.empty()) ? name + "_hidden_state" : ""); auto cellState = Memorize(seqLength, (!name.empty()) ? name + "_cell_state" : ""); - auto add = Add(2, (!name.empty()) ? name + "_add" : ""); + auto add = Add((!name.empty()) ? name + "_add" : ""); // Forget gate auto forgetGateX = std::make_shared<Node>(std::make_shared<FC_Op>(), (!name.empty()) ? name + "_forgetGateX" : ""); input->addChild(forgetGateX, 0, 0); auto forgetGateH = std::make_shared<Node>(std::make_shared<FC_Op>(), (!name.empty()) ? name + "_forgetGateH" : ""); hiddenState->addChild(forgetGateH, 1, 0); - auto forgetGate = Add(2, (!name.empty()) ? name + "_forgetGate" : ""); + auto forgetGate = Add((!name.empty()) ? name + "_forgetGate" : ""); forgetGateX->addChild(forgetGate, 0, 0); forgetGateH->addChild(forgetGate, 0, 1); auto forgetGateAct = Sigmoid((!name.empty()) ? name + "_forgetGateAct" : ""); @@ -57,7 +57,7 @@ std::shared_ptr<Node> LSTM(const DimSize_t inChannel, input->addChild(inputGateX, 0, 0); auto inputGateH = std::make_shared<Node>(std::make_shared<FC_Op>(), (!name.empty()) ? name + "_inputGateH" : ""); hiddenState->addChild(inputGateH, 1, 0); - auto inputGate = Add(2, (!name.empty()) ? name + "_inputGate" : ""); + auto inputGate = Add((!name.empty()) ? name + "_inputGate" : ""); inputGateX->addChild(inputGate, 0, 0); inputGateH->addChild(inputGate, 0, 1); auto inputGateAct = Sigmoid((!name.empty()) ? name + "_inputGateAct" : ""); @@ -71,7 +71,7 @@ std::shared_ptr<Node> LSTM(const DimSize_t inChannel, input->addChild(cellCandidateX, 0, 0); auto cellCandidateH = std::make_shared<Node>(std::make_shared<FC_Op>(), (!name.empty()) ? name + "_cellCandidateH" : ""); hiddenState->addChild(cellCandidateH, 1, 0); - auto cellCandidate = Add(2, (!name.empty()) ? name + "_cellCandidate" : ""); + auto cellCandidate = Add((!name.empty()) ? name + "_cellCandidate" : ""); cellCandidateX->addChild(cellCandidate, 0, 0); cellCandidateH->addChild(cellCandidate, 0, 1); auto cellCandidateAct = Tanh((!name.empty()) ? name + "_cellCandidateAct" : ""); @@ -83,7 +83,7 @@ std::shared_ptr<Node> LSTM(const DimSize_t inChannel, input->addChild(outputGateX, 0, 0); auto outputGateH = std::make_shared<Node>(std::make_shared<FC_Op>(), (!name.empty()) ? name + "_outputGateH" : ""); hiddenState->addChild(outputGateH, 1, 0); - auto outputGate = Add(2, (!name.empty()) ? name + "_outputGate" : ""); + auto outputGate = Add((!name.empty()) ? name + "_outputGate" : ""); outputGateX->addChild(outputGate, 0, 0); outputGateH->addChild(outputGate, 0, 1); auto outputGateAct = Sigmoid((!name.empty()) ? name + "_outputGateAct" : ""); @@ -143,14 +143,14 @@ std::shared_ptr<MetaOperator_Op> LSTM_Op(const DimSize_t seqLength) auto input = Identity(""); auto hiddenState = Memorize(seqLength, ""); auto cellState = Memorize(seqLength, ""); - auto add = Add(2, ""); + auto add = Add(""); // Forget gate auto forgetGateX = std::make_shared<Node>(std::make_shared<FC_Op>(), ""); input->addChild(forgetGateX, 0, 0); auto forgetGateH = std::make_shared<Node>(std::make_shared<FC_Op>(), ""); hiddenState->addChild(forgetGateH, 1, 0); - auto forgetGate = Add(2, ""); + auto forgetGate = Add(""); forgetGateX->addChild(forgetGate, 0, 0); forgetGateH->addChild(forgetGate, 0, 1); auto forgetGateAct = Sigmoid(""); @@ -165,7 +165,7 @@ std::shared_ptr<MetaOperator_Op> LSTM_Op(const DimSize_t seqLength) input->addChild(inputGateX, 0, 0); auto inputGateH = std::make_shared<Node>(std::make_shared<FC_Op>(), ""); hiddenState->addChild(inputGateH, 1, 0); - auto inputGate = Add(2, ""); + auto inputGate = Add(""); inputGateX->addChild(inputGate, 0, 0); inputGateH->addChild(inputGate, 0, 1); auto inputGateAct = Sigmoid(""); @@ -179,7 +179,7 @@ std::shared_ptr<MetaOperator_Op> LSTM_Op(const DimSize_t seqLength) input->addChild(cellCandidateX, 0, 0); auto cellCandidateH = std::make_shared<Node>(std::make_shared<FC_Op>(), ""); hiddenState->addChild(cellCandidateH, 1, 0); - auto cellCandidate = Add(2, ""); + auto cellCandidate = Add(""); cellCandidateX->addChild(cellCandidate, 0, 0); cellCandidateH->addChild(cellCandidate, 0, 1); auto cellCandidateAct = Tanh(""); @@ -191,7 +191,7 @@ std::shared_ptr<MetaOperator_Op> LSTM_Op(const DimSize_t seqLength) input->addChild(outputGateX, 0, 0); auto outputGateH = std::make_shared<Node>(std::make_shared<FC_Op>(), ""); hiddenState->addChild(outputGateH, 1, 0); - auto outputGate = Add(2,""); + auto outputGate = Add(""); outputGateX->addChild(outputGate, 0, 0); outputGateH->addChild(outputGate, 0, 1); auto outputGateAct = Sigmoid(""); diff --git a/src/recipes/ConvToMatMul.cpp b/src/recipes/ConvToMatMul.cpp index 31462861e..70be33932 100644 --- a/src/recipes/ConvToMatMul.cpp +++ b/src/recipes/ConvToMatMul.cpp @@ -75,7 +75,7 @@ size_t Aidge::convToMatMul(std::shared_ptr<GraphView> graphView) { // Handle bias if (convOp->getInput(2) && !convOp->getInput(2)->empty()) { - auto add = Add(2, (!convNode->name().empty()) ? convNode->name() + "_add" : ""); + auto add = Add((!convNode->name().empty()) ? convNode->name() + "_add" : ""); auto bReshapeProd = Producer(std::make_shared<Tensor>(Vector<int64_t>{{1, static_cast<int64_t>(convOp->getInput(2)->size()), 1, 1}}), (!convNode->name().empty()) ? convNode->name() + "_b_reshape_shape_prod" : "", true); diff --git a/unit_tests/graph/Test_GraphView.cpp b/unit_tests/graph/Test_GraphView.cpp index a08808ee5..2fa06cf23 100644 --- a/unit_tests/graph/Test_GraphView.cpp +++ b/unit_tests/graph/Test_GraphView.cpp @@ -447,10 +447,10 @@ TEST_CASE("[core/graph] GraphView(getOrderedNodes)", "[GraphView][getOrderedNode auto data1 = Producer({2}, "data1"); auto data2 = Producer({2}, "data2"); auto data3 = Producer({2}, "data3"); - auto add1 = Add(2, "add1"); - auto add2 = Add(2, "add2"); + auto add1 = Add("add1"); + auto add2 = Add("add2"); auto split1 = Split(2, 0, {1, 1}, "split1"); - auto add3 = Add(3, "add3"); + auto add3 = Add("add3"); auto g = std::make_shared<GraphView>("TestGraph"); data1->addChild(add1); data2->addChild(add1); @@ -508,9 +508,9 @@ TEST_CASE("[core/graph] GraphView(getOrderedNodes)", "[GraphView][getOrderedNode TEST_CASE("[core/graph] GraphView(getOrderedNodes) cyclic", "[GraphView][getOrderedNodes]") { auto data1 = Producer({2}, "data1"); auto data2 = Producer({2}, "data2"); - auto add1 = Add(2, "add1"); + auto add1 = Add("add1"); auto mem1 = Memorize(1, "mem1"); - auto add2 = Add(2, "add2"); + auto add2 = Add("add2"); auto g = std::make_shared<GraphView>("TestGraph"); data1->addChild(add1); data2->addChild(add1); diff --git a/unit_tests/graph/Test_Matching.cpp b/unit_tests/graph/Test_Matching.cpp index d63b1e754..d6d98d470 100644 --- a/unit_tests/graph/Test_Matching.cpp +++ b/unit_tests/graph/Test_Matching.cpp @@ -51,10 +51,10 @@ TEST_CASE("[core/graph] Matching") { PaddedConv(8, 16, {3, 3}, "conv3", {1, 1}, {2, 2, 2, 2}), ReLU("relu3"), PaddedConv(8, 16, {5, 5}, "conv4", {1, 1}, {2, 2, 2, 2}), - Add(2, "add"), + Add("add"), PaddedConv(8, 16, {5, 5}, "conv5", {1, 1}, {2, 2, 2, 2}), ReLU("relu5"), - Add(2, "add2") + Add("add2") }); g1->getNode("relu3")->addChild(g1->getNode("add"), 0, 1); diff --git a/unit_tests/operator/Test_Operator.cpp b/unit_tests/operator/Test_Operator.cpp index a050bbc40..6bd12c51e 100644 --- a/unit_tests/operator/Test_Operator.cpp +++ b/unit_tests/operator/Test_Operator.cpp @@ -26,7 +26,7 @@ namespace Aidge { // TEST_CASE("[core/operator] Operator(computeReceptiveField)", "[Operator][computeReceptiveFiled]") { // auto dataProvider1 = Producer({16, 3, 224, 224}, "dataProvider1"); // auto dataProvider2 = Producer({16, 3, 224, 224}, "dataProvider2"); -// auto gen1 = Add(2); +// auto gen1 = Add(); // auto gen2 = ReLU(); // auto g = std::make_shared<GraphView>("TestGraph"); diff --git a/unit_tests/recipes/Test_MatMulToFC.cpp b/unit_tests/recipes/Test_MatMulToFC.cpp index 2adf882ca..28eae0be1 100644 --- a/unit_tests/recipes/Test_MatMulToFC.cpp +++ b/unit_tests/recipes/Test_MatMulToFC.cpp @@ -27,9 +27,9 @@ TEST_CASE("[cpu/recipes] MatMulToFC", "[MatMulToFC][recipes]") { SECTION("with Add") { // generate the original GraphView auto matmul0 = MatMul("matmul0"); - auto add0 = Add(2, "add0"); + auto add0 = Add("add0"); auto matmul1 = MatMul("matmul1"); - auto add1 = Add(2, "add1"); + auto add1 = Add("add1"); auto b0 = Producer({5}, "B0"); auto w0 = Producer({5, 5}, "W0"); @@ -76,7 +76,7 @@ TEST_CASE("[cpu/recipes] MatMulToFC", "[MatMulToFC][recipes]") { // generate the original GraphView auto matmul0 = MatMul("matmul0"); auto matmul1 = MatMul("matmul1"); - auto add1 = Add(2, "add1"); + auto add1 = Add("add1"); auto w0 = Producer({5, 5}, "W0"); auto b1 = Producer({5}, "B1"); -- GitLab