diff --git a/aidge/_Core/python_binding/backend/pybind_OperatorImpl.cpp b/aidge/_Core/python_binding/backend/pybind_OperatorImpl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ca413a7a2e7bf8e873e416965109106d3a22c787 --- /dev/null +++ b/aidge/_Core/python_binding/backend/pybind_OperatorImpl.cpp @@ -0,0 +1,20 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include "backend/OperatorImpl.hpp" + +namespace py = pybind11; +namespace Aidge { +void init_OperatorImpl(py::module& m){ + py::class_<OperatorImpl, std::shared_ptr<OperatorImpl>>(m, "OperatorImpl"); +} +} diff --git a/aidge/_Core/python_binding/data/pybind_Data.cpp b/aidge/_Core/python_binding/data/pybind_Data.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dfa841bdbc70a75967d12ec3eb187b461366a122 --- /dev/null +++ b/aidge/_Core/python_binding/data/pybind_Data.cpp @@ -0,0 +1,37 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include "data/Data.hpp" + +namespace py = pybind11; +namespace Aidge { + +void init_Data(py::module& m){ + // TODO : extend with more values ! + py::enum_<DataType>(m, "DataType") + .value("Float64", DataType::Float64) + .value("Float32", DataType::Float32) + .value("Float16", DataType::Float16) + .value("Int8", DataType::Int8) + .value("Int32", DataType::Int32) + .value("Int64", DataType::Int64) + .value("UInt8", DataType::UInt8) + .value("UInt32", DataType::UInt32) + .value("UInt64", DataType::UInt64) + ; + + py::class_<Data, std::shared_ptr<Data>>(m,"Data") + .def(py::init<const char*>()); + + +} +} diff --git a/aidge/_Core/python_binding/data/pybind_Tensor.cpp b/aidge/_Core/python_binding/data/pybind_Tensor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7342b22536e4374807a0ab0ff5597292b2cee2f0 --- /dev/null +++ b/aidge/_Core/python_binding/data/pybind_Tensor.cpp @@ -0,0 +1,138 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#include <pybind11/operators.h> +#include <pybind11/numpy.h> + +#include "data/Tensor.hpp" +#include "data/Data.hpp" +#include "utils/Registrar.hpp" +#include "utils/Types.h" +#include "backend/TensorImpl.hpp" + +namespace py = pybind11; +namespace Aidge { + + +template<typename T> +void addCtor(py::class_<Tensor, + std::shared_ptr<Tensor>, + Data, + Registrable<std::tuple<std::string, DataType>, + std::unique_ptr<TensorImpl>(const Tensor&)>>& mTensor){ + mTensor.def(py::init([]( py::array_t<T, py::array::c_style | py::array::forcecast> b) { + /* Request a buffer descriptor from Python */ + py::buffer_info info = b.request(); + Tensor* newTensor = new Tensor(); + newTensor->setDatatype(NativeType<T>::type); + const std::vector<DimSize_t> dims(info.shape.begin(), info.shape.end()); + newTensor->resize(dims); + // TODO : Find a better way to choose backend + std::set<std::string> availableBackends = Tensor::getAvailableBackends(); + if (availableBackends.find("ref_cpp") != availableBackends.end()){ + newTensor->setBackend("ref_cpp"); + newTensor->getImpl()->setRawPtr(static_cast<T*>(info.ptr)); + }else{ + printf("Warning : Could not use aidge_ref_cpp backend, verify you have `import aidge_ref_cpp`\n"); + } + + return newTensor; + })); +} + + +void init_Tensor(py::module& m){ + py::class_<Registrable<std::tuple<std::string, DataType>, + std::unique_ptr<TensorImpl>(const Tensor&)>, + std::shared_ptr<Registrable<std::tuple<std::string, DataType>, + std::unique_ptr<TensorImpl>(const Tensor&)>>>(m,"TensorRegistrable"); + + py::class_<Tensor, std::shared_ptr<Tensor>, + Data, + Registrable<std::tuple<std::string, DataType>, + std::unique_ptr<TensorImpl>(const Tensor&)>> pyClassTensor + (m,"Tensor", py::multiple_inheritance(), py::buffer_protocol()); + + pyClassTensor.def(py::init<>()) + .def("set_backend", &Tensor::setBackend, py::arg("name")) + .def("dims", (const std::vector<DimSize_t>& (Tensor::*)()const) &Tensor::dims) + .def("dtype", &Tensor::dataType) + .def("size", &Tensor::size) + .def("resize", (void (Tensor::*)(const std::vector<DimSize_t>&)) &Tensor::resize) + .def("has_impl", &Tensor::hasImpl) + .def_static("get_available_backends", &Tensor::getAvailableBackends) + .def("__str__", [](Tensor& b) { + return b.toString(); + }) + .def("__len__", [](Tensor& b) -> size_t{ + return b.size(); + }) + .def("__getitem__", [](Tensor& b, size_t idx)-> py::object { + // TODO : Should return error if backend not compatible with get + if (idx >= b.size()) throw py::index_error(); + switch(b.dataType()){ + case DataType::Float32: + return py::cast(static_cast<float*>(b.getImpl()->rawPtr())[idx]); + case DataType::Int32: + return py::cast(static_cast<int*>(b.getImpl()->rawPtr())[idx]); + default: + return py::none(); + } + }) + .def_buffer([](Tensor& b) -> py::buffer_info { + const std::unique_ptr<TensorImpl>& tensorImpl = b.getImpl(); + + std::vector<ssize_t> dims; + std::vector<ssize_t> strides; + ssize_t stride = tensorImpl->scalarSize(); + + for (unsigned int dim = 0; dim < b.nbDims(); ++dim) { + dims.push_back(b.dims()[dim]); + strides.push_back(stride); + stride *= b.dims()[dim]; + } + std::reverse(dims.begin(), dims.end()); + std::reverse(strides.begin(), strides.end()); + + std::string dataFormatDescriptor; + switch(b.dataType()){ + case DataType::Float32: + dataFormatDescriptor = py::format_descriptor<float>::format(); + break; + case DataType::Int32: + dataFormatDescriptor = py::format_descriptor<int>::format(); + break; + default: + throw py::value_error("Unsupported data format"); + } + + return py::buffer_info( + tensorImpl->rawPtr(), /* Pointer to buffer */ + tensorImpl->scalarSize(), /* Size of one scalar */ + dataFormatDescriptor, /* Python struct-style format descriptor */ + b.nbDims(), /* Number of dimensions */ + dims, /* Buffer dimensions */ + strides /* Strides (in bytes) for each index */ + ); + }); + + // TODO : If the ctor with the right data type does not exist, pybind will always convert the data to INT ! + // Need to find a way to avoid this ! + addCtor<int>(pyClassTensor); + addCtor<float>(pyClassTensor); +// #if SIZE_MAX != 0xFFFFFFFF + addCtor<double>(pyClassTensor); +// #endif + +} +} diff --git a/aidge/_Core/python_binding/graph/pybind_Connector.cpp b/aidge/_Core/python_binding/graph/pybind_Connector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a937fb4f2afbc30f1d64217215e95ed907ead2cf --- /dev/null +++ b/aidge/_Core/python_binding/graph/pybind_Connector.cpp @@ -0,0 +1,29 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#include "graph/Connector.hpp" +#include "graph/Node.hpp" +#include "graph/GraphView.hpp" + +namespace py = pybind11; +namespace Aidge { +void init_Connector(py::module& m){ + py::class_<Connector, std::shared_ptr<Connector>>(m, "Connector") + .def(py::init<>()) + .def(py::init<std::shared_ptr<Node>>()) + .def("__getitem__", &Connector::operator[], py::arg("key")) + ; + m.def("generate_graph", &Aidge::generateGraph, py::arg("output_connectors")); + // m.def("generate_graph", (std::shared_ptr<GraphView>(*)(std::vector<Connector>)) &Aidge::generateGraph, py::arg("output_connectors")); +} +} diff --git a/aidge/_Core/python_binding/graph/pybind_GraphView.cpp b/aidge/_Core/python_binding/graph/pybind_GraphView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b7ef2e1661a08cfca4814be175fe4e5bb82712a4 --- /dev/null +++ b/aidge/_Core/python_binding/graph/pybind_GraphView.cpp @@ -0,0 +1,60 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#include <memory> +#include <string> +#include "graph/GraphView.hpp" +#include "graph/Node.hpp" +#include "utils/Types.h" +#include "data/Data.hpp" + +namespace py = pybind11; +namespace Aidge { +void init_GraphView(py::module& m) { + py::class_<GraphView, std::shared_ptr<GraphView>>(m, "GraphView") + .def(py::init<>()) + .def("save", &GraphView::save, py::arg("path"), py::arg("verbose") = false) + .def("get_output_nodes", &GraphView::outputNodes) + .def("get_input_nodes", &GraphView::inputNodes) + .def("add", (void (GraphView::*)(std::shared_ptr<Node>, bool)) & GraphView::add, + py::arg("other_node"), py::arg("include_learnable_parameters") = true) + .def("add_child", + (void (GraphView::*)(std::shared_ptr<Node>, + std::shared_ptr<Node>, + const IOIndex_t, + IOIndex_t)) & + GraphView::addChild, + py::arg("toOtherNode"), py::arg("fromOutNode") = nullptr, + py::arg("fromTensor") = 0U, py::arg("toTensor") = gk_IODefaultIndex) + .def("replace_with", &GraphView::replaceWith, py::arg("new_nodes")) + .def("get_nodes", &GraphView::getNodes) + .def("get_node", &GraphView::getNode, py::arg("node_name")) + .def("forward_dims", &GraphView::forwardDims) + .def("__call__", &GraphView::operator(), py::arg("connectors")) + .def("set_datatype", &GraphView::setDatatype, py::arg("datatype")) + .def("set_backend", &GraphView::setBackend, py::arg("backend")) + // .def("__getitem__", [](Tensor& b, size_t idx)-> py::object { + // // TODO : Should return error if backend not compatible with get + // if (idx >= b.size()) throw py::index_error(); + // switch(b.dataType()){ + // case DataType::Float32: + // return py::cast(static_cast<float*>(b.getImpl()->rawPtr())[idx]); + // case DataType::Int32: + // return py::cast(static_cast<int*>(b.getImpl()->rawPtr())[idx]); + // default: + // return py::none(); + // } + // }) + ; +} +} // namespace Aidge diff --git a/aidge/_Core/python_binding/graph/pybind_Node.cpp b/aidge/_Core/python_binding/graph/pybind_Node.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d957eb2ca5e32ca33642f2e66116caf302e7cc2 --- /dev/null +++ b/aidge/_Core/python_binding/graph/pybind_Node.cpp @@ -0,0 +1,49 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +#include <memory> + +#include "graph/GraphView.hpp" +#include "graph/Node.hpp" +#include "utils/Types.h" + +namespace py = pybind11; +namespace Aidge { +void init_Node(py::module& m) { + py::class_<Node, std::shared_ptr<Node>>(m, "Node") + .def("name", &Node::name) + .def("type", &Node::type) + .def("get_operator", &Node::getOperator) + .def("set_name", &Node::setName, py::arg("name")) + .def("add_child", + (void (Node::*)(std::shared_ptr<Node>, const IOIndex_t, IOIndex_t)) & + Node::addChild, + py::arg("other_node"), py::arg("out_id") = 0, py::arg("other_in_id") = -1) + .def("add_child", + (void (Node::*)(std::shared_ptr<GraphView>, const IOIndex_t, + std::pair<std::shared_ptr<Node>, IOIndex_t>)) & + Node::addChild, + py::arg("other_graph"), py::arg("out_id") = 0, + py::arg("other_in_id") = + std::pair<std::shared_ptr<Node>, IOIndex_t>(nullptr, gk_IODefaultIndex)) + .def("inputs", &Node::inputs) + .def("input", &Node::input, py::arg("inID")) + .def("outputs", &Node::outputs) + .def("output", &Node::output, py::arg("outID")) + .def("get_nb_inputs", &Node::nbInputs) + .def("get_nb_datainputs", &Node::nbDataInputs) + .def("get_nb_outputs", &Node::nbOutputs) + .def("__call__", &Node::operator(), py::arg("connectors")); +} +} // namespace Aidge diff --git a/aidge/_Core/python_binding/graph/pybind_OpArgs.cpp b/aidge/_Core/python_binding/graph/pybind_OpArgs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fa7a974312127ab75faa7864bb54f6c1388280fa --- /dev/null +++ b/aidge/_Core/python_binding/graph/pybind_OpArgs.cpp @@ -0,0 +1,38 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include "graph/OpArgs.hpp" +#include "graph/Node.hpp" +#include "graph/GraphView.hpp" +#include <pybind11/stl.h> +#include <pybind11/complex.h> +#include <pybind11/functional.h> +#include <pybind11/chrono.h> + + +namespace py = pybind11; +namespace Aidge { +void init_OpArgs(py::module& m){ + py::class_<OpArgs, std::shared_ptr<OpArgs>>(m, "OpArgs") + .def("node", &OpArgs::node) + .def("view", &OpArgs::view) + ; + + py::implicitly_convertible<Node, OpArgs>(); + py::implicitly_convertible<GraphView, OpArgs>(); + + m.def("sequential", &Sequential, py::arg("inputs")); + m.def("parallel", &Parallel, py::arg("inputs")); + m.def("residual", &Residual, py::arg("inputs")); + +} +} diff --git a/aidge/_Core/python_binding/graphmatching/pybind_GRegex.cpp b/aidge/_Core/python_binding/graphmatching/pybind_GRegex.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4eefccec172c284f2cacae83deb1144ccc304fa3 --- /dev/null +++ b/aidge/_Core/python_binding/graphmatching/pybind_GRegex.cpp @@ -0,0 +1,25 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#include "graph/GraphView.hpp" +#include "graphmatching/GRegex.hpp" + +namespace py = pybind11; +namespace Aidge { +void init_GRegex(py::module& m){ + py::class_<GRegex, std::shared_ptr<GRegex>>(m, "GRegex") + .def(py::init<const std::map<std::string,NodeRegex*>&, std::vector<std::string>&>(), py::arg("nodesRegex"), py::arg("seqRegexps")) + .def("match", &GRegex::match, py::arg("graphToMatch")) + ; +} +} diff --git a/aidge/_Core/python_binding/graphmatching/pybind_Match.cpp b/aidge/_Core/python_binding/graphmatching/pybind_Match.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8646ff91de47ece3e4c72a64dd142607c9d45b0f --- /dev/null +++ b/aidge/_Core/python_binding/graphmatching/pybind_Match.cpp @@ -0,0 +1,25 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#include "graphmatching/Match.hpp" + +namespace py = pybind11; +namespace Aidge { +void init_Match(py::module& m){ + py::class_<Match, std::shared_ptr<Match>>(m, "Match") + .def(py::init<>()) + .def("get_nb_match", &Match::getNbMatch) + .def("get_start_nodes", &Match::getStartNodes) + .def("get_match_nodes", &Match::getMatchNodes); +} +} diff --git a/aidge/_Core/python_binding/graphmatching/pybind_NodeRegex.cpp b/aidge/_Core/python_binding/graphmatching/pybind_NodeRegex.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ee4c93323998c1b1e9982b49c82a84b24bb3dcf --- /dev/null +++ b/aidge/_Core/python_binding/graphmatching/pybind_NodeRegex.cpp @@ -0,0 +1,22 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include "graphmatching/NodeRegex.hpp" + +namespace py = pybind11; +namespace Aidge { +void init_NodeRegex(py::module& m){ + py::class_<NodeRegex, std::shared_ptr<NodeRegex>>(m, "NodeRegex") + .def(py::init<const std::string>(), py::arg("condition")) + ; +} +} diff --git a/aidge/_Core/python_binding/operator/pybind_Add.cpp b/aidge/_Core/python_binding/operator/pybind_Add.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3585db040b9f12004bc8b7f47c7907dbbcc5f96a --- /dev/null +++ b/aidge/_Core/python_binding/operator/pybind_Add.cpp @@ -0,0 +1,32 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> + +#include "operator/Add.hpp" +#include "utils/Parameter.hpp" +#include "backend/OperatorImpl.hpp" +#include "operator/Operator.hpp" +#include "utils/Types.h" + +namespace py = pybind11; +namespace Aidge { + +template <std::size_t NUM> void declare_Add(py::module &m) { + py::class_<Add_Op<NUM>, std::shared_ptr<Add_Op<NUM>>, Operator>(m, "Add_Op", py::multiple_inheritance()); + + m.def("Add", &Add<NUM>, py::arg("name") = nullptr); +} + +void init_Add(py::module &m) { + declare_Add<2>(m); +} +} // namespace Aidge diff --git a/aidge/_Core/python_binding/operator/pybind_Conv.cpp b/aidge/_Core/python_binding/operator/pybind_Conv.cpp new file mode 100644 index 0000000000000000000000000000000000000000..16e86a7c9f76ee5ab351103d02909cad95f00392 --- /dev/null +++ b/aidge/_Core/python_binding/operator/pybind_Conv.cpp @@ -0,0 +1,61 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +#include <string> + +#include "utils/Parameter.hpp" +#include "backend/OperatorImpl.hpp" +#include "operator/Conv.hpp" +#include "operator/Operator.hpp" +#include "utils/Types.h" + +namespace py = pybind11; +namespace Aidge { + +template <DimIdx_t DIM> void declare_ConvOp(py::module &m) { + py::class_<Conv_Op<DIM>, std::shared_ptr<Conv_Op<DIM>>, Operator>( + m, ("ConvOp" + std::to_string(DIM) + "D").c_str(), + py::multiple_inheritance()) + .def(py::init<DimSize_t, DimSize_t, const std::array<DimSize_t, DIM> &>(), + py::arg("in_channels"), py::arg("out_channels"), + py::arg("kernel_dims")); + + m.def(("Conv" + std::to_string(DIM) + "D").c_str(), [](DimSize_t in_channels, DimSize_t out_channels, std::vector<DimSize_t>& kernel_dims, const char* name) { + // Lambda function wrapper because PyBind fails to convert const array. + // So we use a vector that we convert in this function to a const DimeSize_t [DIM] array. + if (kernel_dims.size() != DIM) { + throw std::runtime_error("kernel_dims size [" + std::to_string(kernel_dims.size()) + "] does not match DIM [" + std::to_string(DIM) +"]"); + } + DimSize_t tmp_kernel_dims_array[DIM]; + for (size_t i = 0; i < DIM; ++i) { + tmp_kernel_dims_array[i] = kernel_dims[i]; + } + const DimSize_t (&kernel_dims_array)[DIM] = tmp_kernel_dims_array; + return Conv<DIM>(in_channels, out_channels, kernel_dims_array, name); + }, py::arg("in_channels"), py::arg("out_channels"), + py::arg("kernel_dims"), py::arg("name") = nullptr); + +} + + +void init_Conv(py::module &m) { + declare_ConvOp<1>(m); + declare_ConvOp<2>(m); + declare_ConvOp<3>(m); + + // FIXME: + // m.def("Conv1D", static_cast<NodeAPI(*)(const char*, int, int, int const + // (&)[1])>(&Conv)); +} +} // namespace Aidge diff --git a/aidge/_Core/python_binding/operator/pybind_FC.cpp b/aidge/_Core/python_binding/operator/pybind_FC.cpp new file mode 100644 index 0000000000000000000000000000000000000000..293ae841818b979aa357dd54703834aba0264d45 --- /dev/null +++ b/aidge/_Core/python_binding/operator/pybind_FC.cpp @@ -0,0 +1,32 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> + +#include "operator/FC.hpp" +#include "utils/Parameter.hpp" +#include "backend/OperatorImpl.hpp" +#include "operator/Operator.hpp" +#include "utils/Types.h" + +namespace py = pybind11; +namespace Aidge { + +void declare_FC(py::module &m) { + py::class_<FC_Op, std::shared_ptr<FC_Op>, Operator>(m, "FC_Op", py::multiple_inheritance()); + + m.def("FC", &FC, py::arg("out_channels"), py::arg("nobias") = false, py::arg("name") = nullptr); +} + +void init_FC(py::module &m) { + declare_FC(m); +} +} // namespace Aidge diff --git a/aidge/_Core/python_binding/operator/pybind_GenericOperator.cpp b/aidge/_Core/python_binding/operator/pybind_GenericOperator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7aa5d42ba1085c36a61c8887d5f4520652fd34b5 --- /dev/null +++ b/aidge/_Core/python_binding/operator/pybind_GenericOperator.cpp @@ -0,0 +1,67 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> +#include <stdio.h> + +#include "backend/OperatorImpl.hpp" +#include "operator/GenericOperator.hpp" +#include "operator/Operator.hpp" +namespace py = pybind11; +namespace Aidge { + +void init_GenericOperator(py::module& m) { + py::class_<GenericOperator_Op, std::shared_ptr<GenericOperator_Op>, Operator>(m, "GenericOperatorOp", + py::multiple_inheritance()) + .def("get_parameter_type", &GenericOperator_Op::getParameterType) + .def("get_parameters_name", &GenericOperator_Op::getParametersName) + .def("add_parameter", &GenericOperator_Op::addParameter<bool>) + .def("add_parameter", &GenericOperator_Op::addParameter<int>) + .def("add_parameter", &GenericOperator_Op::addParameter<float>) + .def("add_parameter", &GenericOperator_Op::addParameter<std::string>) + .def("add_parameter", &GenericOperator_Op::addParameter<std::vector<bool>>) + .def("add_parameter", &GenericOperator_Op::addParameter<std::vector<int>>) + .def("add_parameter", &GenericOperator_Op::addParameter<std::vector<float>>) + .def("add_parameter", &GenericOperator_Op::addParameter<std::vector<std::string>>) + .def("get_parameter", [](GenericOperator_Op& self, std::string key) -> py::object { + /* + This getParameter method returns the good python type without having to have + prior knowledge of the parameter type. + */ + py::object res = py::none(); + std::string paramType = self.getParameterType(key); + if(paramType == typeid(int).name()) + res = py::cast(self.getParameter<int>(key)); + else if(paramType == typeid(float).name()) + res = py::cast(self.getParameter<float>(key)); + else if(paramType == typeid(bool).name()) + res = py::cast(self.getParameter<bool>(key)); + else if(paramType == typeid(std::string).name()) + res = py::cast(self.getParameter<std::string>(key)); + else if(paramType == typeid(std::vector<bool>).name()) + res = py::cast(self.getParameter<std::vector<bool>>(key)); + else if(paramType == typeid(std::vector<int>).name()) + res = py::cast(self.getParameter<std::vector<int>>(key)); + else if(paramType == typeid(std::vector<float>).name()) + res = py::cast(self.getParameter<std::vector<float>>(key)); + else if(paramType == typeid(std::vector<std::string>).name()) + res = py::cast(self.getParameter<std::vector<std::string>>(key)); + else { + throw py::key_error("Failed to convert parameter type " + key + ", this issue may come from typeid function which gave an unknown key : [" + paramType + "]. Please open an issue asking to add the support for this key."); + } + return res; + }); + + m.def("GenericOperator", &GenericOperator, py::arg("type"), py::arg("nbDataIn"), py::arg("nbIn"), py::arg("nbOut"), + py::arg("name") = nullptr); +} +} // namespace Aidge diff --git a/aidge/_Core/python_binding/operator/pybind_Matmul.cpp b/aidge/_Core/python_binding/operator/pybind_Matmul.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a2748fcd87b4e7d62c070b7fe2cc32762593ec0 --- /dev/null +++ b/aidge/_Core/python_binding/operator/pybind_Matmul.cpp @@ -0,0 +1,32 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> + +#include "operator/Matmul.hpp" +#include "utils/Parameter.hpp" +#include "backend/OperatorImpl.hpp" +#include "operator/Operator.hpp" +#include "utils/Types.h" + +namespace py = pybind11; +namespace Aidge { + +void declare_Matmul(py::module &m) { + py::class_<Matmul_Op, std::shared_ptr<Matmul_Op>, Operator>(m, "Matmul_Op", py::multiple_inheritance()); + + m.def("Matmul", &Matmul, py::arg("out_channels"), py::arg("name") = nullptr); +} + +void init_Matmul(py::module &m) { + declare_Matmul(m); +} +} // namespace Aidge diff --git a/aidge/_Core/python_binding/operator/pybind_Operator.cpp b/aidge/_Core/python_binding/operator/pybind_Operator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ea1ba636b0de1f16ce6efbee694fff006b7cb42 --- /dev/null +++ b/aidge/_Core/python_binding/operator/pybind_Operator.cpp @@ -0,0 +1,28 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include "backend/OperatorImpl.hpp" +#include "operator/Operator.hpp" +#include <pybind11/stl.h> + +namespace py = pybind11; +namespace Aidge { +void init_Operator(py::module& m){ + py::class_<Operator, std::shared_ptr<Operator>>(m, "Operator") + .def("get_output", &Operator::getOutput, py::arg("outputIdx")) + .def("get_input", &Operator::getInput, py::arg("inputIdx")) + .def("set_input", &Operator::setInput, py::arg("inputIdx"), py::arg("data")) + .def("set_datatype", &Operator::setDatatype, py::arg("datatype")) + .def("set_backend", &Operator::setBackend, py::arg("name")) + ; +} +} diff --git a/aidge/_Core/python_binding/operator/pybind_Producer.cpp b/aidge/_Core/python_binding/operator/pybind_Producer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a60b1cff5b1a06ad948b998c9b7bfa2f12bbefb --- /dev/null +++ b/aidge/_Core/python_binding/operator/pybind_Producer.cpp @@ -0,0 +1,46 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +#include "utils/Types.h" +#include "utils/Parameter.hpp" +// #include "backend/OperatorImpl.hpp> +#include "operator/Operator.hpp" +#include "operator/Producer.hpp" + +namespace py = pybind11; +namespace Aidge { + +template <DimIdx_t DIM> +void declare_Producer(py::module &m) { + py::class_<Producer_Op<DIM>, std::shared_ptr<Producer_Op<DIM>>, Operator>( + m, + ("ProducerOp" + std::to_string(DIM)+"D").c_str(), + py::multiple_inheritance()) + .def("set_output", &Producer_Op<DIM>::setOutput, py::arg("output_data")); + // m.def(("Producer_" + std::to_string(DIM)+"D").c_str(), py::overload_cast<shared_ptr<Node>&>(&Producer<DIM>), py::arg("dims"), py::arg("name")); + m.def("Producer", static_cast<std::shared_ptr<Node>(*)(const std::array<DimSize_t, DIM>&, const char*)>(&Producer), py::arg("dims"), py::arg("name")); + +} + + +void init_Producer(py::module &m) { + declare_Producer<1>(m); + declare_Producer<2>(m); + declare_Producer<3>(m); + declare_Producer<4>(m); + declare_Producer<5>(m); + declare_Producer<6>(m); + +} +} diff --git a/aidge/_Core/python_binding/operator/pybind_Relu.cpp b/aidge/_Core/python_binding/operator/pybind_Relu.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42d983fa9065627c93fd7e301200b0d805515ac4 --- /dev/null +++ b/aidge/_Core/python_binding/operator/pybind_Relu.cpp @@ -0,0 +1,24 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> + +#include "operator/ReLU.hpp" +#include "operator/Operator.hpp" +namespace py = pybind11; +namespace Aidge { + +void init_ReLU(py::module& m) { + py::class_<ReLU_Op, std::shared_ptr<ReLU_Op>, Operator>(m, "ReLU_Op", py::multiple_inheritance()); + + m.def("ReLU", &ReLU, py::arg("alpha") = 0.0f, py::arg("name") = nullptr); +} +} // namespace Aidge diff --git a/aidge/_Core/python_binding/pybind_core.cpp b/aidge/_Core/python_binding/pybind_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06d739c257af68f1f5e67f40c26278bbfce55177 --- /dev/null +++ b/aidge/_Core/python_binding/pybind_core.cpp @@ -0,0 +1,73 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> + +namespace py = pybind11; + +namespace Aidge { +void init_Data(py::module&); +void init_Tensor(py::module&); +void init_OperatorImpl(py::module&); +void init_Operator(py::module&); +void init_GraphView(py::module&); +void init_Conv(py::module&); +void init_ReLU(py::module&); +void init_Matmul(py::module&); +void init_Add(py::module&); +void init_FC(py::module&); +void init_GenericOperator(py::module&); +void init_Producer(py::module&); +void init_OpArgs(py::module&); +// void init_Structured(py::module&); +void init_Node(py::module&); +void init_Connector(py::module&); +void init_Match(py::module&); +void init_NodeRegex(py::module&); +void init_GRegex(py::module&); +void init_Recipies(py::module&); +void init_Scheduler(py::module&); + + +void set_python_flag(){ + // Set an env variable to know if we run with ypthon or cpp + py::module os_module = py::module::import("os"); + os_module.attr("environ")["AIDGE_CORE_WITH_PYBIND"] = "1"; +}; + +void init_Aidge(py::module& m){ + set_python_flag(); + init_Data(m); + init_Tensor(m); + init_Node(m); + init_OpArgs(m); + init_OperatorImpl(m); + init_Operator(m); + init_Conv(m); + init_ReLU(m); + init_Matmul(m); + init_Add(m); + init_FC(m); + init_GenericOperator(m); + init_Producer(m); + init_GraphView(m); + init_Connector(m); + init_Match(m); + init_NodeRegex(m); + init_GRegex(m); + init_Recipies(m); + init_Scheduler(m); +} + +PYBIND11_MODULE(aidge_core, m) { + init_Aidge(m); +} +} diff --git a/aidge/_Core/python_binding/recipies/pybind_Recipies.cpp b/aidge/_Core/python_binding/recipies/pybind_Recipies.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3ebffd95fdf40ccabe8fba0cbfc052c32c9045f0 --- /dev/null +++ b/aidge/_Core/python_binding/recipies/pybind_Recipies.cpp @@ -0,0 +1,26 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include <pybind11/stl.h> + +#include <string> + +#include "utils/Recipies.hpp" + +namespace py = pybind11; + +namespace Aidge { +void init_Recipies(py::module &m) { + m.def("fuse_mul_add", &fuseMulAdd, py::arg("nodes")); + +} +} // namespace Aidge diff --git a/aidge/_Core/python_binding/scheduler/pybind_Scheduler.cpp b/aidge/_Core/python_binding/scheduler/pybind_Scheduler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0f2598c750500b219a8de9c31c5c9d7e9eccae7c --- /dev/null +++ b/aidge/_Core/python_binding/scheduler/pybind_Scheduler.cpp @@ -0,0 +1,26 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +#include <pybind11/pybind11.h> +#include "scheduler/Scheduler.hpp" +#include "graph/GraphView.hpp" + +namespace py = pybind11; +namespace Aidge { +void init_Scheduler(py::module& m){ + py::class_<SequentialScheduler, std::shared_ptr<SequentialScheduler>>(m, "SequentialScheduler") + .def(py::init<std::shared_ptr<GraphView>&>(), py::arg("graph_view")) + .def("forward", &SequentialScheduler::forward, py::arg("forward_dims")=true, py::arg("verbose")=false) + .def("save_scheduling_diagram", &SequentialScheduler::saveSchedulingDiagram, py::arg("file_name")) + ; +} +} +