Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • eclipse/aidge/aidge_core
  • hrouis/aidge_core
  • mszczep/aidge_core
  • oantoni/aidge_core
  • cguillon/aidge_core
  • jeromeh/aidge_core
  • axelfarr/aidge_core
  • cmoineau/aidge_core
  • noamzerah/aidge_core
  • lrakotoarivony/aidge_core
  • silvanosky/aidge_core
  • maab05/aidge_core
  • mick94/aidge_core
  • lucaslopez/aidge_core_ll
  • wboussella/aidge_core
  • farnez/aidge_core
  • mnewson/aidge_core
17 results
Show changes
Commits on Source (12)
......@@ -38,6 +38,13 @@ enum class DataType;
/**
* @brief Groupement of Nodes forming a computational graph on which properties and functions
* can easily and safely be applied or run.
* A GraphView countains:
* - mName: The name of the GraphView
* - mRootNode: The root of the GraphView, an arbitrary Node of the GraphView
* - mNodes: The set of Nodes included in the GraphView
* - : Set of nodes included in the graphview with names
* - mInputNodes: GraphView inputs IOIndex_t designates the input number
* - mOutputNodes: GraphView outputs IOIndex_t designates the input number
*/
class GraphView : public std::enable_shared_from_this<GraphView> {
private:
......@@ -56,27 +63,46 @@ private:
/// @brief GraphView inputs IOIndex_t designates the input number
std::vector<std::pair<NodePtr, IOIndex_t>> mInputNodes;
/// @brief GraphView outputs IOIndex_t designates the input number
/// @brief GraphView outputs IOIndex_t designates the output number
std::vector<std::pair<NodePtr, IOIndex_t>> mOutputNodes;
public:
/**
* @brief Constructs a GraphView object with a given name
* @params string name : name given to the GraphView
*/
GraphView(const std::string& name="")
: mName(name)
{
// ctor
}
/**
* @brief equality operator, tests if the current GraphView and the gv GraphView have the same Nodes
* @params GraphView &gv GraphView that shall be compared to the current one
* @returns bool True if both GraphView have the same set of Nodes
*/
bool operator==(const GraphView &gv) const
{
return mNodes == gv.mNodes;
}
/**
* @brief Allows to find a Node in the GraphView using the Node's name
* @params string The name of the Node we are looking for
* @returns NodePtr Pointer of the Node that is found
* @details Returns nullptr if the Node isn't found
*/
const NodePtr operator[](const std::string& nodeName) const;
///////////////////////////////////////////////////////
// FUNCTIONAL DESCRIPTION
///////////////////////////////////////////////////////
/**
* @brief Functional operator for user-friendly connection interface using an ordered set of Connectors.
* @param ctors
* @return Connector
*/
Connector operator()(const std::vector<Connector> ctors);
///////////////////////////////////////////////////////
......@@ -84,15 +110,14 @@ public:
///////////////////////////////////////////////////////
public:
/**
* @brief Name of the node.
* @brief Name of the GraphView.
* @return std::string
*/
inline std::string name() const noexcept { return mName; }
/**
* @brief Set the node name.
* @warning Undefined behaviour when several Nodes have the same name.
* @param name New name for the node.
* @brief Set the GraphView name.
* @param name New name for the GraphView.
*/
inline void setName(const std::string &name) { mName = name; }
......@@ -105,17 +130,25 @@ public:
/**
* @brief Save the GraphView as a Mermaid graph in a .md file at the
* specified location.
* @param path
* @param path: Path where the file should be put
* @param verbose If true give more informations in the console during the saving process
* @param showProducers if true, shows additional informations
*/
void save(const std::string& path, bool verbose = false, bool showProducers = true) const;
/**
* @brief Logs the output of all nodes of the graph in a directory
* @details in the specified directory, it will create a subdirectory for each Node of the GraphView
* In that sub-directory, each output of the Node will be saved in a different .log file
* @param string dirName Path of the directory where the logs shall be stocked
*/
void logOutputs(const std::string& dirName) const;
/**
* Check that a node is in the current GraphView.
* @brief Check that a node is in the current GraphView.
* @param nodePtr Node to check
* @return bool True is nodePtr belongs to the GraphView.
*/
* @return bool True if nodePtr belongs to the GraphView.
*/
bool inView(const NodePtr& nodePtr) const;
/**
......@@ -125,10 +158,18 @@ public:
*/
bool inView(const std::string& nodeName) const;
/**
* Returns the rootNode of the GraphView
* @return NodePtr of the rootNode
*/
inline NodePtr rootNode() const noexcept {
return mRootNode;
}
/**
* Changes the rootNode of the GraphView
* @param NodePtr of the new rootNode
*/
void setRootNode(NodePtr node);
///////////////////////////////////////////////////////
......@@ -147,12 +188,25 @@ public:
/** @brief Assess if the given Node is an output Node of the GraphView object. */
bool isOutputNode(const NodePtr& nodePtr) const;
/**
* @brief Orders the inputs of the GraphView
* @details The Inputs will be ordered in the same order as they come in the std::vector.
* Inputs missing from this vector will then be added as per their previous order.
* @param std::vector<std::pair<NodePtr, IOIndex_t>>& inputs set of inputs in the wanted order
*/
void setOrderedInputs(const std::vector<std::pair<NodePtr, IOIndex_t>>& inputs);
/**
* @brief Orders the outputs of the GraphView
* @details The outputs will be ordered in the same order as they come in the std::vector.
* Outputs missing from this vector will then be added as per their previous order.
* @param std::vector<std::pair<NodePtr, IOIndex_t>>& outputs set of outputs in the wanted order
*/
void setOrderedOutputs(const std::vector<std::pair<NodePtr, IOIndex_t>>& outputs);
/**
* @brief Get a topological node order for an acyclic walk of the graph
* Graph cycles are broken on operator back edges such that resolution on
* @brief Get a topological node order for an acyclic walk of the graph.
* @details Graph cycles are broken on operator back edges such that resolution on
* single level lattice can be done in a single pass as it is
* the case generally for static resolution of Tensor shapes/datatypes.
* When reversed is true, gets a topological order on the reversed graph
......@@ -184,7 +238,7 @@ public:
/**
* @brief List outside data input connections of the GraphView.
* Data inputs exclude inputs expecting parameters (weights or bias).
* The vector size is garanteed to match the number of outside data inputs of the GraphView. If there is
* The vector size is guaranteed to match the number of outside data inputs of the GraphView. If there is
* no external connection to a given input, a pair of nullptr and gk_IODefaultIndex is returned.
* @return std::vector<std::pair<NodePtr, IOIndex_t>>
*/
......@@ -207,14 +261,15 @@ public:
std::vector<std::pair<NodePtr, IOIndex_t>> inputs() const;
/**
* @TODO @warning what if the node isn't found? where is the try catch of the .at?
* @brief List all input connections (within and outside) of the specified GraphView node named "name".
* @return std::vector<std::pair<NodePtr, IOIndex_t>>
*/
std::vector<std::pair<NodePtr, IOIndex_t>> inputs(const std::string& name) const;
/**
/** @todo weird things happening here with this outsideoutputpos
* @brief List outside output connections of the GraphView. The vector
* size is garanteed to match the number of outputs of the GraphView. If there is
* size is guaranteed to match the number of outputs of the GraphView. If there is
* no connection to a given output, the corresponding sub-vector will be empty.
* @return std::vector<std::pair<NodePtr, IOIndex_t>>
*/
......@@ -227,7 +282,6 @@ public:
*/
std::vector<std::vector<std::pair<NodePtr, IOIndex_t>>> outputs(
const std::string& nodeName) const;
/**
* @brief Assert Datatype, Backend, data format and dimensions along the GraphView are coherent.
* If not, apply the required transformations.
......@@ -240,13 +294,16 @@ public:
* compatible with the selected kernel.
* If not, add a Transpose Operator.
* 4 - Propagate Tensor dimensions through the consecutive Operators.
@params string: backend Backend used, default is cpu
@params Aidge Datatype: datatype used, default is float32
@params vector of vector of DimSize_t: dims
*/
void compile(const std::string& backend = "cpu",
const Aidge::DataType datatype = DataType::Float32,
DeviceIdx_t device = 0,
const std::vector<std::vector<DimSize_t>> dims = {});
/**
/** @todo naming the input dims, while there exist currentTensorPtr->dims is a nice way to mess with reader's head maybe some proper variable name would be great
* @brief Compute dimensions of input/output Tensors for each Operator of the
* GraphView object's Nodes, by calling Node::forwardDims().
* This function verifies the following conditions:
......@@ -257,19 +314,27 @@ public:
*/
bool forwardDims(const std::vector<std::vector<DimSize_t>>& dims = {}, bool allowDataDependency = false);
/** @brief Set the same backend for each Operator of the GraphView object's Nodes. */
/** @brief Set the same backend for each Operator of the GraphView object's Nodes.
* @param string: backend Backend name to be set
* @param DeviceIdx_t: device Backend device to be set
*/
void setBackend(const std::string& backend, const DeviceIdx_t device = 0) const;
/** @brief Set the same data type for each Operator of the GraphView object's Nodes. */
/** @brief Set the same data type for each Operator of the GraphView object's Nodes.
* @param DataType: datatype DataType to be set
*/
void setDataType(const DataType& datatype) const;
/** @brief Set the same data format for each Operator of the GraphView object's Nodes. */
/** @brief Set the same data format for each Operator of the GraphView object's Nodes.
* @param DataFormat: dataformat DataFormat to be set
*/
void setDataFormat(const DataFormat& dataformat) const;
///////////////////////////////////////////////////////
// TOPOLOGY
///////////////////////////////////////////////////////
//@todo 50 shades of get
public:
/**
* @brief Get the parents Nodes of inputNodes.
* @brief Get the parents Nodes of inputNodes of the graph.
* @return std::set<NodePtr>
*/
std::set<NodePtr> getParents() const;
......@@ -302,8 +367,7 @@ public:
inline const std::set<NodePtr>& getNodes() const noexcept { return mNodes; }
/**
* @brief Get the operator with the corresponding name if it is in the
* GraphView.
* @brief Get the Node with the corresponding name if it is in the GraphView.
* @param nodeName Name of the node.
* @return NodePtr returns a nullptr if the one asked for
* was not found.
......@@ -329,9 +393,10 @@ public:
std::pair<std::vector<NodePtr>, size_t> getRankedNodes() const;
/**
// todo see comment in code
* Get the nodes name according to the GraphView nodes ranking.
* @param format The formatting string to be used with fmt::format().
* The usable positional arguments are the following:
* @details The usable positional arguments are the following:
* {0} node name, {1} node type, {2} rank, {3} type rank
* @param markNonUnicity If true, non unique ranking is prefixed with "?"
* @return std::map<NodePtr, std::string> A map with the corresponding names
......@@ -342,16 +407,21 @@ public:
* @brief Remove a Node from the current GraphView scope without affecting its connections.
* @param nodePtr Node to remove
* @param includeLearnableParam Whether learnable parameters should also be removed. Default true.
* learnable params are removed only if they aren't used by other Nodes
*/
void remove(NodePtr nodePtr, bool includeLearnableParam = true);
// Surrounding nodes management
// not implemented yet
void setInputId(IOIndex_t inID, IOIndex_t newNodeOutID);
/**
* @brief Include a Node to the current GraphView object.
* @param other_Nde Node to add.
* @brief Include a Node to the current GraphView's set of Nodes.
* If the Node is named, it is added in the registery as well
* @details If the GraphView has no root Node (most likely this GraphView is empty)
* the added Node becomes the GraphView's root Node
* @param otherNode Node to add.
* @param includeLearnableParam Include non-data inputs, like weights and biases
* in the GraphView automatically. Default: true.
*/
......@@ -359,8 +429,9 @@ public:
/**
* @brief Include a set of Nodes to the current GraphView object.
* @param otherNodes
* @param includeLearnableParam
* @param otherNodes Nodes to add to the GraphView
* @param includeLearnableParam Include non-data inputs, like weights and biases
* in the GraphView automatically. Default: true.
* @return true if graph ordering is unique (meaning inputs/outputs order is well defined).
*/
bool add(std::set<NodePtr> otherNodes,
......@@ -368,7 +439,7 @@ public:
/**
* @brief Include a set of Nodes to the current GraphView object.
* The first element of the otherNodes pair is the start node and
* The first element of the otherNodes pair is the new RootNode of the GraphView and
* the second is the remaining nodes to add.
* @param otherNodes
* @param includeLearnableParam
......@@ -378,8 +449,8 @@ public:
bool includeLearnableParam = true);
/**
* @brief Include every Node inside another GraphView to the current
* GraphView.
* @brief Include every Node inside another GraphView to the current GraphView.
* @details If the current GraphView has no RootNode it takes the RootNode of the new GraphView
* @param other_graph GraphView containing the Nodes to include.
* @return true if graph ordering is unique (meaning inputs/outputs order is well defined).
*/
......@@ -388,14 +459,13 @@ public:
/**
* @brief Include a Node in the current GraphView and link it to another
* already contained Node.
* already contained Node as its child.
*
* @param toOtherNode Pointer to the Node to add.
* @param fromOutNode Pointer to the already included Node the new Node will
* be linked to (it will become a parent of the new Node). If the GraphView
* only has one output Node, then default to this Node.
* @param fromTensor Ouput Tensor ID of the already included Node. Default to
* 0.
* @param fromTensor Ouput Tensor ID of the already included Node. Default to 0.
* @param toTensor Input Tensor ID of the new Node. Default to gk_IODefaultIndex, meaning
* first available data input for the Node.
*/
......@@ -405,15 +475,14 @@ public:
/**
* @brief Include a Node in the current GraphView and link it to another
* already contained Node.
* already contained Node as its child.
*
* @param toOtherNode Pointer to the Node to add.
* @param fromOutNodeName Name of the already included Node the new Node will
* be linked to (it will become a parent of the new Node). As a name is
* optional, ensure such Node is in the GraphView or it will send back an
* error message.
* @param fromTensor Ouput Tensor ID of the already included Node. Default to
* 0.
* @param fromTensor Ouput Tensor ID of the already included Node. Default to 0.
* @param toTensor Input Tensor ID of the new Node. Default to gk_IODefaultIndex, meaning
* first available data input for the Node.
*/
......@@ -424,6 +493,10 @@ public:
addChild(toOtherNode, mNodeRegistry.at(fromOutNodeName), fromTensor, toTensor);
}
/**
//todo only updates registery with pair (newName, node) but does not ensure node's name is indeed newName
* @brief
*/
inline void updateNodeName(const std::shared_ptr<Node>& node, const std::string& newName){
if (!newName.empty()) {
auto itNew = mNodeRegistry.insert(std::make_pair(newName, node));
......@@ -459,6 +532,7 @@ public:
std::pair<NodePtr, IOIndex_t>(nullptr, gk_IODefaultIndex));
/**
//@todo not implemented
* @brief Swap two Node instances if possible.
* @param node
* @param otherNode
......@@ -467,10 +541,13 @@ public:
*/
bool swap(Node &node, Node &otherNode);
//@todo not implemented
void link(const std::string& name1_inID, const std::string& name2_outID);
/**
* @brief Insert a node (newParentNode) as a parent of the passed node (childNode).
//@todo why some functions have separate inputs for Node and TensorID (such as here) while other put them in a pair (consistency would be nice)
* @brief Insert a node (newParentNode) as a parent of the passed node (childNode)
* and as a child of the current parent of the Node.
*
* @param childNode Node that gets a new parent.
* @param newParentNode Inserted Node.
......@@ -485,6 +562,7 @@ public:
IOIndex_t newParentOutputTensorIdx);
/**
//@todo seems messed up, imma skip it for now
* @brief Replace a set of Nodes in every available GraphView with a new set of Nodes if possible.
* Both sets should include all the necessary Producers.
* @details There are 3 cases of replacement:
......@@ -530,8 +608,12 @@ public:
return cloneCallback(&Node::clone);
}
/**
* @brief Clone the current GraphView using a callback function for the Node cloning, allowing to specify how each Node should be cloned or replaced by another Node type, or removed (i.e. replaced by identity). When a Node is removed, the clone() method automatically finds the next valid parent in line, going backward in the graph and connects it if that makes sense without ambiguity (effectively treating the removed Node as an identity operation).
/** TODO: understand and reformulate (and see above clones)
* @brief Clone the current GraphView using a callback function for the Node cloning, allowing to specify how each
* Node should be cloned or replaced by another Node type, or removed (i.e. replaced by identity).
* When a Node is removed, the clone() method automatically finds the next valid parent in line, going backward in
* the graph and connects it if that makes sense without ambiguity (effectively treating the removed Node as an
* identity operation).
* @param cloneNode Callback function to clone a node
* @return std::shared_ptr<GraphView>
*/
......@@ -546,8 +628,8 @@ public:
/**
* @brief Force update of GraphView inputs/outputs.
* It may be necessary to force the update of GraphView inputs/outputs when
* connections are added or removed inside the GraphView **after** the nodes
* It may be necessary to force the update of GraphView inputs/outputs when Nodes
* and connections are added or removed inside the GraphView **after** the nodes
* were added.
*/
void updateInputsOutputs();
......@@ -576,11 +658,13 @@ private:
* inputs/outputs after adding this node.
* @param nodePtr
*/
//@todo 100+ lines =(
void updateInputsOutputsNew(NodePtr newNode);
//@todo 100+ lines =(
/**
* @brief Automatically update GraphView inputs/outputs with a Node removed, checking if
* it this Node was an input/output for the graph and if this node childs become new inputs/outputs
* it this Node was an input/output for the graph and if this node's children become new inputs/outputs
* for the graph.
* @param nodePtr
*/
......@@ -593,7 +677,7 @@ private:
};
/**
* Create a GraphView containing all nodes with a path to given argument.
* Create a GraphView containing all nodes with a path to given Node.
* @param node Initial node to construct the graph.
* @return GraphView GraphView containing all nodes with a path to node.
*/
......
......@@ -375,7 +375,7 @@ Aidge::IOIndex_t Aidge::GraphView::getNbFreeDataInputs() const {
std::vector<std::pair<std::shared_ptr<Aidge::Node>, Aidge::IOIndex_t>>
Aidge::GraphView::dataInputs() const {
std::vector<std::pair<std::shared_ptr<Node>, IOIndex_t>> res;
std::vector<std::pair<std::shared_ptr<Node>, IOIndex_t>> res; //todo three letters or less variable names should be illegal
for (const std::shared_ptr<Node>& inputNode : inputNodes()) {
const std::vector<std::pair<std::shared_ptr<Node>, IOIndex_t>> inputNodeinputs =
......@@ -623,7 +623,7 @@ Aidge::GraphView::outputs(const std::string& nodeName) const {
void Aidge::GraphView::setInputId(Aidge::IOIndex_t /*inID*/,
Aidge::IOIndex_t /*newNodeOutID*/) {
AIDGE_THROW_OR_ABORT(std::runtime_error, "Not implemented yet.");
AIDGE_THROW_OR_ABORT(std::radduntime_error, "Not implemented yet.");
}
void Aidge::GraphView::add(std::shared_ptr<Node> node, bool includeLearnableParam) {
......@@ -762,9 +762,9 @@ std::map<Aidge::NodePtr, std::string> Aidge::GraphView::getRankedNodesName(const
std::map<std::string, size_t>::iterator it;
std::tie(it, std::ignore) = typeRank.insert(std::make_pair(rankedNode->type(), 0));
const auto name = (markNonUnicity && rank < rankedNodes.second)
? fmt::format(format, rankedNode->name(), rankedNode->type(), rank, it->second)
: fmt::format(format, rankedNode->name(), rankedNode->type(), fmt::format("?{}", rank), fmt::format("?{}", it->second));
const auto name = (markNonUnicity && rank < rankedNodes.second) //if todo logic doesn't match description, to be checked
? fmt::format(format, rankedNode->name(), rankedNode->type(), rank, it->second) //then
: fmt::format(format, rankedNode->name(), rankedNode->type(), fmt::format("?{}", rank), fmt::format("?{}", it->second)); //else
rankedNodesName.insert(std::make_pair(rankedNode, name));
++it->second;
++rank;
......@@ -1009,9 +1009,9 @@ void Aidge::GraphView::remove(std::shared_ptr<Node> nodePtr, bool includeLearnab
for (const auto& parentOutput : inputI.first->outputs()) {
for (const auto& childOfParentOutput : parentOutput) {
// only remove the learnable parameter if not related to any other Node in the GraphView
if (childOfParentOutput.first != nodePtr) {
removeNode = false;
break;
if (childOfParentOutput.first != nodePtr) { //todo isn't it possible that childOfParentOutput.first == nodePtr?
removeNode = false; // todo too deep
break; // todo only one for loop is broken, why not both?
}
}
}
......@@ -1479,7 +1479,7 @@ std::shared_ptr<Aidge::GraphView> Aidge::GraphView::cloneCallback(NodePtr(*clone
for (const std::shared_ptr<Node> &node_ptr : mNodes) {
auto clonedNode = cloneNode(node_ptr);
if (clonedNode == nullptr) {
if (clonedNode == nullptr) { //todo: don't understand those checks: why is one child OK for deleted nodes?
AIDGE_ASSERT(node_ptr->getChildren().size() <= 1, "deleted nodes in GraphView::clone() cannot have multiple children");
AIDGE_ASSERT(node_ptr->dataInputs().size() <= 1, "deleted nodes in GraphView::clone() cannot have multiple data input parents");
}
......