Skip to content
Snippets Groups Projects
Commit 5fb05f6f authored by Octave Perrin's avatar Octave Perrin
Browse files

aidge#199: update user guide of Node

parent 9fd586b0
No related branches found
No related tags found
No related merge requests found
......@@ -41,6 +41,16 @@ class GraphView;
/**
* @brief Object carrying the topological information of the computational graph.
* A Node contains :
* - mName : Optional, the name of the Node. If present, it should be unique
* - mViews: a set of pointers to GraphView instances including this Node instance
* - mOperator: a pointer to the Operator associated to the node
* - mParents: a vector of parent nodes, which are its inputs
* - mIdOutParents: a vector of indexes, corresponding to the connected output index of the parent nodes.
* - mChildren: a vector of vector of children nodes, which lists , for each output of the Node, all its children.
* - mIdInChildren: a vector of vector of indexes, which gives for each children nodes, which of their input is linked to the current Node
* - mForward: queue of forward propagation function
* - mBackward: queue of backward propagation function
*/
class Node : public std::enable_shared_from_this<Node> {
private:
......@@ -71,8 +81,8 @@ public:
Node() = delete;
/**
* @brief Construct a new Node object associated with the input Operator.
* @param op Operator giving the Node its number of connections.
* @brief Construct a new Node object associated with the inputted Operator.
* @param op The Operator of the Node, it determines its number of connections.
* @param attrs Attributes for the Node.
*/
Node(std::shared_ptr<Operator> op, std::shared_ptr<DynamicAttributes> attrs);
......@@ -80,7 +90,7 @@ public:
/**
* @brief Construct a new Node object associated with the input Operator.
* @param op Operator giving the Node its number of connections.
* @param op The Operator of the Node, it determines its number of connections.
* @param name (optional) name for the Node.
*/
Node(std::shared_ptr<Operator> op, const std::string& name = "");
......@@ -115,6 +125,7 @@ public:
/**
* @brief Functional operator for user-friendly connection interface using an ordered set of Connectors.
* @param ctors Ordered Connectors linking their associated Node to the input of the current Node with the same index.
* @warning length of ctors must be lower than the number of input of the Node
* @return Connector
*/
Connector operator()(const std::vector<Connector> &ctors);
......@@ -134,8 +145,8 @@ public:
inline std::string name() const noexcept { return mAttrs->getAttr<std::string>("name"); }
/**
* @brief Set the Node name.
* @warning Undefined behavior when several Nodes have the same name.
* @brief Set the Node's Name.
* @warning Undefined behaviour when several Nodes have the same name, use createUniqueName to avoid complications.
* @param name New name for the node.
*/
void setName(const std::string &name);
......@@ -143,16 +154,16 @@ public:
/**
* @brief Given the parameter name generate a new name which is unique
* in all the GraphView which contains this node.
* To generate the new name the method is called recursively and append
* the character ``_``.
* If no duplicate return name, this is the exit condition.
* @details if the inputted name is not yet used, it will be used as is
* if it is used, the returned name will be "name_X"
* name being the inputted name and X the smaller integer allowing name uniqueness
* @param name Base name to make unique.
* @return A unique name in all the GraphView which contains this one.
*/
std::string createUniqueName(std::string name);
/**
* @brief Type of the node.
* @brief Type of the Node's operator.
* @return std::string
*/
inline std::string type() const { return mOperator->type(); }
......@@ -185,30 +196,30 @@ public:
/**
* @brief Whether or not every input of the Node is linked to a Parent.
* If true then the Node is ready to be executed.
* @return true
* @return false
* @return bool
*/
bool valid() const;
/**
* @brief List of pair <Parent, ID of the data input>. When an input is not
* linked to any Parent, the pair is <nullptr, gk_IODefaultIndex>.
* @brief List the pairs <Parent, ID of the data intput> of the Node's inputs.
* @details When an input is not linked to any Parent, the pair is <nullptr, gk_IODefaultIndex>.
* Data inputs exclude inputs expecting parameters (weights or bias).
* @return std::vector<std::pair<std::shared_ptr<Node>, IOIndex_t>>
*/
std::vector<std::pair<NodePtr, IOIndex_t>> dataInputs() const;
/**
* @brief List of pair <Parent, ID of the parent output>. When an input is not linked
* to any Parent, the pair is <nullptr, gk_IODefaultIndex>.
* @brief List the pairs <Parent, ID of the input> of the Node's inputs.
* @details When an input is not linked to any Parent, the pair is <nullptr, gk_IODefaultIndex>.
* as opposed to dataInputs, inputs includes parent nodes containing parameters (e.g. weights or biases)
* @return std::vector<std::pair<std::shared_ptr<Node>, IOIndex_t>>
*/
std::vector<std::pair<NodePtr, IOIndex_t>> inputs() const;
/**
* @brief Parent and its output Tensor ID linked to the inID-th input Tensor.
* @brief Accessor of <parent_node, parent_node_output> linked to the inID-th input input of this node.
* If the input is not linked to any Parent, the pair is <nullptr, gk_IODefaultIndex>.
* @param inID
* @param inID : the ID of the input that we want to know the parent of
* @return std::pair<std::shared_ptr<Node>, IOIndex_t>
*/
inline std::pair<NodePtr, IOIndex_t> input(const IOIndex_t inID) const {
......@@ -219,7 +230,7 @@ public:
/**
* @brief Get the lowest index in the InputData Parent list equal to the
* nullptr.
* nullptr (i.e. the ID of the first free data input).
* Data inputs exclude inputs expecting parameters (weights or bias).
* @return std::size_t
*/
......@@ -235,22 +246,25 @@ public:
return (i < nbInputs()) ? i : gk_IODefaultIndex;
}
/**
* @brief Returns the number of free data inputs of the Node
* (i.e. data inputs that are not linked to an other node)
* @warning Node cannot run until all of its mandatory inputs are filled
* @return IOIndex_t
*/
IOIndex_t getNbFreeDataInputs() const;
/**
* @brief List input ids of children linked to outputs of the node. The vector
* size is guaranteed to match the number of outputs of the node. If there is
* no connection to a given output, the corresponding sub-vector will be empty.
* @return std::vector<std::vector<std::pair<std::shared_ptr<Node>,
* IOIndex_t>>>
* @brief Lists children of the Node and the ID of the child's input linked to the current Node.
* @details The parent vector size matches the number of outputs of the node.
* Each sub-vector size will match the number of children connected to the n-th output (i.e. if 3 nodes are connected to the 3rd output parent_vec[3].size() == 3).
* @return std::vector<std::vector<std::pair<std::shared_ptr<Node>, IOIndex_t>>>
*/
std::vector<std::vector<std::pair<NodePtr, IOIndex_t>>> outputs() const;
/**
* @brief Children and their input Tensor ID linked to the outId-th output
* Tensor.
* @param outId
* @brief Lists Nodes and input ids of children linked to specified output of the Node
* @param outId ID of the output from which we want to know the children
* @return std::vector<std::pair<std::shared_ptr<Node>, IOIndex_t>>
*/
std::vector<std::pair<NodePtr, IOIndex_t>>
......@@ -258,14 +272,15 @@ public:
/**
* @brief Number of inputs, including both data and learnable parameters.
* @details [data, data, weight, bias] => 4
* @details ex: [data, data, weight, bias] => 4
* @return IOIndex_t
*/
inline IOIndex_t nbInputs() const noexcept { return getOperator()->nbInputs(); }
/**
* @brief Category of a specific input (Data or Param, optional or not).
* @brief Returns the category of a specific input (Data or Param, optional or not).
* Data inputs exclude inputs expecting parameters (weights or bias).
* @details ex: with [datatype1, datatype2, weight, bias], inputCategory(1) returns datatype2
* @return InputCategory
*/
inline InputCategory inputCategory(IOIndex_t idx) const {
......@@ -274,8 +289,8 @@ public:
/**
* @brief Returns whether the given node parent index is a back edge
* A back edge is defined by the operator and node parent index
* correspond to operator input index.
* A back edge is an edge from a Node to one of its ancestor.
* @param idx Index of the Node's connection we want to test
* @return true if the operator defines it as a back edge
*/
inline bool parentIsBackEdge(IOIndex_t idx) const {
......@@ -284,6 +299,7 @@ public:
/**
* @brief Number of inputs linked to a Parent's output.
* @warning Unconnected Inputs will throw errors when compiling graph.
* @return IOIndex_t
*/
IOIndex_t nbValidInputs() const;
......@@ -323,6 +339,12 @@ public:
mViews.insert(std::weak_ptr<GraphView>(graphPtr));
}
/**
* @brief Remove the reference of this Node to the GraphView passed as argument.
* @warning This function does not remove the reference of the GraphView to the Node.
* As such, this function is used in other function and should be not used as is by an user
* @param graphPtr Pointer to GraphView to remove from the list.
*/
inline void removeView(const std::shared_ptr<GraphView> &graphPtr) {
mViews.erase(graphPtr);
}
......@@ -356,8 +378,9 @@ public:
std::pair<NodePtr, IOIndex_t>(nullptr, gk_IODefaultIndex));
/**
* @brief Get the list of parent Nodes. As an input is linked to a unique Node,
* if none is linked then the parent is a nullptr.
* @brief Get the list of parent Nodes.
* Each input can only be linked to one Node.
* If an input has no linked node, the associated parent is nullptr
* @return std::vector<std::shared_ptr<Node>>
*/
std::vector<NodePtr> getParents() const;
......@@ -380,16 +403,28 @@ public:
*/
NodePtr popParent(const IOIndex_t inId);
/**
* @brief unlinks the parent from the Node and replaces it with nullptr (for coherence with remaining parents)
* @param inId Input index of the parent to be removed
* @return std::bool true if parent has been removed.
*/
bool removeParent(const IOIndex_t inId);
/**
* @brief Get the set of pointers to children Nodes linked to the current Node.object.
* @details The returned set does not include any nullptr as an output maybe linked to
* an undifined number of Nodes. It does not change the computation of its associated Operator.
* an undefined number of Nodes. It does not change the computation of its associated Operator.
* @return std::set<std::shared_ptr<Node>>>
*/
std::set<NodePtr> getChildren() const;
/**
* @brief Get all children of the node
* @details The parent vector size matches the number of outputs of the node.
* Each sub-vector size will match the number of children connected to the n-th output
* (i.e. if 3 nodes are connected to the 3rd output parent_vec[2].size() == 3).
* @returns std::vector<std::vector<std::shared_ptr<Node>>>
*/
std::vector<std::vector<NodePtr>> getOrderedChildren() const;
/**
......@@ -401,7 +436,7 @@ public:
/**
* @brief Remove registered child from children list of specified output if possible.
* If so, also remove current Node from child Node from parent.
* If so, also remove current Node from child's parent.
* @param std::shared_ptr<Node> Node to remove.
* @param outId Output index. Default 0.
* @return true Child found and removed for given output index.
......@@ -466,12 +501,13 @@ public:
/**
* @brief Get the set of pointers to connected node at a distance of a delta.
* @details the recution are cut
* Return a nullptr is nofing found.
* @param delta Input delta.
* @return std::shared_ptr<Node>
* @details positive value are toward children, negative toward parents (ex: -2 would give grandparents)
* Return a nullptr is nothing found.
* @param int delta Input delta.
* @param std::set<Aidge::NodePtr> nodeSee is used in the recursion to avoid looping on the same nodes,
* should be empty when calling the method
* @return std::set<Aidge::NodePtr> set of nodes within expected distance from the original node
*/
std::set<NodePtr> getNodeDelta(int delta,std::set<Aidge::NodePtr> nodeSee);
#ifdef PYBIND
......@@ -509,9 +545,9 @@ private:
///////////////////////////////////////////////////////
/**
* @brief Set the idInChildren parameter.
* @param inID
* @param newNodeOutID
* @brief Updates mIdOutParents by giving the value newNodeOutID to the inID-th member of the list
* @param IOIndex_t inID input of the Node that is being changed
* @param IOIndex_t newNodeOutID updated value, corresponds to the new output of the parent Node
*/
void setInputId(const IOIndex_t inID, const IOIndex_t newNodeOutID);
......
......@@ -28,7 +28,10 @@ void init_Node(py::module& m) {
R"mydelimiter(
Name of the Node.
)mydelimiter")
.def("clone", (NodePtr (Node::*)() const) &Node::clone)
.def("clone", (NodePtr (Node::*)() const) &Node::clone,
R"mydelimiter(
Clone the Node and its Operator. The new Node has no connection.
)mydelimiter")
.def("type", &Node::type,
R"mydelimiter(
Type of the node.
......@@ -72,7 +75,7 @@ void init_Node(py::module& m) {
R"mydelimiter(
Link another Node to an output of the current Node.
:param other_node: Pointer to the other Node.
:param other_node: Pointer to the other Node that will be given as a child to the current Node
:type other_node: :py:class: Node
:param out_id: ID of the output of the current Node to connect to the other Node. (If Node has 1 output max ID is 0). Default to 0.
:type out_id: int
......@@ -116,11 +119,11 @@ void init_Node(py::module& m) {
.def("input", &Node::input, py::arg("in_id"),
R"mydelimiter(
Get the parent Node and the associated output index connected to the i-th input of the current Node.
Get the parent Node and the associated output index connected to the specified input of the current Node.
:param in_id: input index of the current Node object.
:type in_id: int
:return: i-th connection. When an input is not linked to any parent, the default value is (None, default_index)
:return: The parent Node and the corresponding output index of the specified input of the current Node. When an input is not linked to any parent, the default value is (None, 65535)
:rtype: tuple[Node, int]
)mydelimiter")
......@@ -128,7 +131,7 @@ void init_Node(py::module& m) {
R"mydelimiter(
Get, for each output of the Node, a list of the children Node and the associated input index connected to it.
:return: List of a list of connections. When an output is not linked to any child, its list a empty.
:return: List of a list of connections. When an output is not linked to any child, its list a empty.
:rtype: list[list[tuple[Node, int]]]
)mydelimiter")
......@@ -138,13 +141,14 @@ void init_Node(py::module& m) {
:param out_id: input index of the current Node object.
:type out_id: int
:return: i-th connection. When an input is not linked to any parent, the default value is (None, default_index)
:return: List of Nodes and their inputs that are connected to the specified output.
When an input is not linked to any parent, the default value is (None, default_index)
:rtype: list[tuple[Node, int]]
)mydelimiter")
.def("get_nb_inputs", &Node::nbInputs,
R"mydelimiter(
Number of inputs.
Number of inputs of the Node.
:rtype: int
)mydelimiter")
......@@ -159,21 +163,26 @@ void init_Node(py::module& m) {
.def("get_nb_outputs", &Node::nbOutputs,
R"mydelimiter(
Number of outputs.
Number of outputs of the Node.
:rtype: int
)mydelimiter")
.def("get_parent", &Node::getParent, py::arg("in_id"))
.def("get_parents", &Node::getParents,
.def("get_parent", &Node::getParent, py::arg("in_id"),
R"mydelimiter(
Get parents.
Get the pointer to parent of the specified input index.
This pointer is nullptr if no parent is linked to that input.
)mydelimiter")
.def("get_parents", &Node::getParents,R"mydelimiter(
Get the list of parent Nodes.
Each input can only be linked to one Node.
If an input has no linked node, the associated parent is nullptr
)mydelimiter")
.def("get_children", (std::set<std::shared_ptr<Node>> (Node::*)() const) &Node::getChildren,
R"mydelimiter(
Get children.
Returns a set of all children of the Node
)mydelimiter")
.def("get_ordered_children", &Node::getOrderedChildren,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment