Add Node Documentation
This commit is contained in:
parent
e07ade47ad
commit
cf19856118
@ -181,6 +181,7 @@ jobs:
|
||||
|
||||
- name: Webhook Trigger
|
||||
uses: https://github.com/zzzze/webhook-trigger@master
|
||||
continue-on-error: true
|
||||
with:
|
||||
data: "{\"event\":\"action_completed\", \"download_url\":\"deckardcain.local:8099/something\"}"
|
||||
webhook_url: ${{ secrets.WEBHOOK_URL }}
|
||||
|
@ -1,15 +1,35 @@
|
||||
"""
|
||||
==(e1::Edge, e2::Edge)
|
||||
|
||||
Equality comparison between two edges.
|
||||
"""
|
||||
function ==(e1::Edge, e2::Edge)
|
||||
return e1.edge[1] == e2.edge[1] && e1.edge[2] == e2.edge[2]
|
||||
end
|
||||
|
||||
"""
|
||||
==(n1::Node, n2::Node)
|
||||
|
||||
Fallback equality comparison between two nodes. For equal node types, the more specific versions of this function will be called.
|
||||
"""
|
||||
function ==(n1::Node, n2::Node)
|
||||
return false
|
||||
end
|
||||
|
||||
"""
|
||||
==(n1::ComputeTaskNode, n2::ComputeTaskNode)
|
||||
|
||||
Equality comparison between two [`ComputeTaskNode`](@ref)s.
|
||||
"""
|
||||
function ==(n1::ComputeTaskNode, n2::ComputeTaskNode)
|
||||
return n1.id == n2.id
|
||||
end
|
||||
|
||||
"""
|
||||
==(n1::DataTaskNode, n2::DataTaskNode)
|
||||
|
||||
Equality comparison between two [`DataTaskNode`](@ref)s.
|
||||
"""
|
||||
function ==(n1::DataTaskNode, n2::DataTaskNode)
|
||||
return n1.id == n2.id
|
||||
end
|
||||
|
@ -1,23 +1,53 @@
|
||||
"""
|
||||
make_node(t::AbstractTask)
|
||||
|
||||
Fallback implementation of `make_node` for an [`AbstractTask`](@ref), throwing an error.
|
||||
"""
|
||||
function make_node(t::AbstractTask)
|
||||
return error("Cannot make a node from this task type")
|
||||
end
|
||||
|
||||
"""
|
||||
make_node(t::AbstractDataTask)
|
||||
|
||||
Construct and return a new [`DataTaskNode`](@ref) with the given task.
|
||||
"""
|
||||
function make_node(t::AbstractDataTask)
|
||||
return DataTaskNode(t)
|
||||
end
|
||||
|
||||
"""
|
||||
make_node(t::AbstractComputeTask)
|
||||
|
||||
Construct and return a new [`ComputeTaskNode`](@ref) with the given task.
|
||||
"""
|
||||
function make_node(t::AbstractComputeTask)
|
||||
return ComputeTaskNode(t)
|
||||
end
|
||||
|
||||
"""
|
||||
make_edge(n1::Node, n2::Node)
|
||||
|
||||
Fallback implementation of `make_edge` throwing an error. If you got this error it likely means you tried to construct an edge between two nodes of the same type.
|
||||
"""
|
||||
function make_edge(n1::Node, n2::Node)
|
||||
return error("Can only create edges from compute to data node or reverse")
|
||||
end
|
||||
|
||||
"""
|
||||
make_edge(n1::ComputeTaskNode, n2::DataTaskNode)
|
||||
|
||||
Construct and return a new [`Edge`](@ref) pointing from `n1` (child) to `n2` (parent).
|
||||
"""
|
||||
function make_edge(n1::ComputeTaskNode, n2::DataTaskNode)
|
||||
return Edge((n1, n2))
|
||||
end
|
||||
|
||||
"""
|
||||
make_edge(n1::DataTaskNode, n2::ComputeTaskNode)
|
||||
|
||||
Construct and return a new [`Edge`](@ref) pointing from `n1` (child) to `n2` (parent).
|
||||
"""
|
||||
function make_edge(n1::DataTaskNode, n2::ComputeTaskNode)
|
||||
return Edge((n1, n2))
|
||||
end
|
||||
|
@ -1,7 +1,17 @@
|
||||
"""
|
||||
show(io::IO, n::Node)
|
||||
|
||||
Print a short string representation of the node to io.
|
||||
"""
|
||||
function show(io::IO, n::Node)
|
||||
return print(io, "Node(", n.task, ")")
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, e::Edge)
|
||||
|
||||
Print a short string representation of the edge to io.
|
||||
"""
|
||||
function show(io::IO, e::Edge)
|
||||
return print(io, "Edge(", e.edge[1], ", ", e.edge[2], ")")
|
||||
end
|
||||
|
@ -1,17 +1,46 @@
|
||||
"""
|
||||
is_entry_node(node::Node)
|
||||
|
||||
Return whether this node is an entry node in its graph, i.e., it has no children.
|
||||
"""
|
||||
is_entry_node(node::Node) = length(node.children) == 0
|
||||
|
||||
"""
|
||||
is_exit_node(node::Node)
|
||||
|
||||
Return whether this node is an exit node of its graph, i.e., it has no parents.
|
||||
"""
|
||||
is_exit_node(node::Node) = length(node.parents) == 0
|
||||
|
||||
# children = prerequisite nodes, nodes that need to execute before the task, edges point into this task
|
||||
"""
|
||||
children(node::Node)
|
||||
|
||||
Return a copy of the node's children so it can safely be muted without changing the node in the graph.
|
||||
|
||||
A node's children are its prerequisite nodes, nodes that need to execute before the task of this node.
|
||||
"""
|
||||
function children(node::Node)
|
||||
return copy(node.children)
|
||||
end
|
||||
|
||||
# parents = subsequent nodes, nodes that need this node to execute, edges point from this task
|
||||
"""
|
||||
parents(node::Node)
|
||||
|
||||
Return a copy of the node's parents so it can safely be muted without changing the node in the graph.
|
||||
|
||||
A node's parents are its subsequent nodes, nodes that need this node to execute.
|
||||
"""
|
||||
function parents(node::Node)
|
||||
return copy(node.parents)
|
||||
end
|
||||
|
||||
# siblings = all children of any parents, no duplicates, includes the node itself
|
||||
"""
|
||||
siblings(node::Node)
|
||||
|
||||
Return a vector of all siblings of this node.
|
||||
|
||||
A node's siblings are all children of any of its parents. The result contains no duplicates and includes the node itself.
|
||||
"""
|
||||
function siblings(node::Node)
|
||||
result = Set{Node}()
|
||||
push!(result, node)
|
||||
@ -22,7 +51,16 @@ function siblings(node::Node)
|
||||
return result
|
||||
end
|
||||
|
||||
# partners = all parents of any children, no duplicates, includes the node itself
|
||||
"""
|
||||
partners(node::Node)
|
||||
|
||||
Return a vector of all partners of this node.
|
||||
|
||||
A node's partners are all parents of any of its children. The result contains no duplicates and includes the node itself.
|
||||
|
||||
Note: This is very slow when there are multiple children with many parents.
|
||||
This is less of a problem in [`siblings(node::Node)`](@ref) because (depending on the model) there are no nodes with a large number of children, or only a single one.
|
||||
"""
|
||||
function partners(node::Node)
|
||||
result = Set{Node}()
|
||||
push!(result, node)
|
||||
@ -33,8 +71,11 @@ function partners(node::Node)
|
||||
return result
|
||||
end
|
||||
|
||||
# alternative version to partners(Node), avoiding allocation of a new set
|
||||
# works on the given set and returns nothing
|
||||
"""
|
||||
partners(node::Node, set::Set{Node})
|
||||
|
||||
Alternative version to [`partners(node::Node)`](@ref), avoiding allocation of a new set. Works on the given set and returns `nothing`.
|
||||
"""
|
||||
function partners(node::Node, set::Set{Node})
|
||||
push!(set, node)
|
||||
for child in node.children
|
||||
@ -43,10 +84,20 @@ function partners(node::Node, set::Set{Node})
|
||||
return nothing
|
||||
end
|
||||
|
||||
function is_parent(potential_parent, node)
|
||||
"""
|
||||
is_parent(potential_parent::Node, node::Node)
|
||||
|
||||
Return whether the `potential_parent` is a parent of `node`.
|
||||
"""
|
||||
function is_parent(potential_parent::Node, node::Node)
|
||||
return potential_parent in node.parents
|
||||
end
|
||||
|
||||
function is_child(potential_child, node)
|
||||
"""
|
||||
is_child(potential_child::Node, node::Node)
|
||||
|
||||
Return whether the `potential_child` is a child of `node`.
|
||||
"""
|
||||
function is_child(potential_child::Node, node::Node)
|
||||
return potential_child in node.children
|
||||
end
|
||||
|
@ -5,12 +5,33 @@ using Base.Threads
|
||||
# TODO: reliably find out how many threads we're running with (nthreads() returns 1 when precompiling :/)
|
||||
rng = [Random.MersenneTwister(0) for _ in 1:32]
|
||||
|
||||
"""
|
||||
Node
|
||||
|
||||
The abstract base type of every node.
|
||||
|
||||
See [`DataTaskNode`](@ref), [`ComputeTaskNode`](@ref) and [`make_node`](@ref).
|
||||
"""
|
||||
abstract type Node end
|
||||
|
||||
# declare this type here because it's needed
|
||||
# the specific operations are declared in graph.jl
|
||||
abstract type Operation end
|
||||
|
||||
"""
|
||||
DataTaskNode <: Node
|
||||
|
||||
Any node that transfers data and does no computation.
|
||||
|
||||
# Fields
|
||||
`.task`: The node's data task type. Usually [`DataTask`](@ref).\\
|
||||
`.parents`: A vector of the node's parents (i.e. nodes that depend on this one).\\
|
||||
`.children`: A vector of the node's children (i.e. nodes that this one depends on).\\
|
||||
`.id`: The node's id. Improves the speed of comparisons.\\
|
||||
`.nodeReduction`: Either this node's [`NodeReduction`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeSplit`: Either this node's [`NodeSplit`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeFusion`: Either this node's [`NodeFusion`](@ref) or `missing`, if none. There can only be at most one for DataTaskNodes.
|
||||
"""
|
||||
mutable struct DataTaskNode <: Node
|
||||
task::AbstractDataTask
|
||||
|
||||
@ -33,7 +54,20 @@ mutable struct DataTaskNode <: Node
|
||||
nodeFusion::Union{Operation, Missing}
|
||||
end
|
||||
|
||||
# same as DataTaskNode
|
||||
"""
|
||||
ComputeTaskNode <: Node
|
||||
|
||||
Any node that transfers data and does no computation.
|
||||
|
||||
# Fields
|
||||
`.task`: The node's data task type. Usually [`DataTask`](@ref).\\
|
||||
`.parents`: A vector of the node's parents (i.e. nodes that depend on this one).\\
|
||||
`.children`: A vector of the node's children (i.e. nodes that this one depends on).\\
|
||||
`.id`: The node's id. Improves the speed of comparisons.\\
|
||||
`.nodeReduction`: Either this node's [`NodeReduction`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeSplit`: Either this node's [`NodeSplit`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeFusion`: A vector of this node's [`NodeFusion`](@ref)s. For a ComputeTaskNode there can be any number of these, unlike the DataTaskNodes.
|
||||
"""
|
||||
mutable struct ComputeTaskNode <: Node
|
||||
task::AbstractComputeTask
|
||||
parents::Vector{Node}
|
||||
@ -66,6 +100,15 @@ ComputeTaskNode(t::AbstractComputeTask) = ComputeTaskNode(
|
||||
Vector{NodeFusion}(),
|
||||
)
|
||||
|
||||
"""
|
||||
Edge
|
||||
|
||||
Type of an edge in the graph. Edges can only exist between a [`DataTaskNode`](@ref) and a [`ComputeTaskNode`](@ref) or vice versa, not between two of the same type of node.
|
||||
|
||||
An edge always points from child to parent: `child = e.edge[1]` and `parent = e.edge[2]`.
|
||||
|
||||
The child is the prerequisite node of the parent.
|
||||
"""
|
||||
struct Edge
|
||||
# edge points from child to parent
|
||||
edge::Union{
|
||||
|
@ -1,3 +1,12 @@
|
||||
"""
|
||||
is_valid_node(graph::DAG, node::Node)
|
||||
|
||||
Verify that a given node is valid in the graph. Call like `@test is_valid_node(g, n)`. Uses `@assert` to fail if something is invalid but also provide an error message.
|
||||
|
||||
This function is very performance intensive and should only be used when testing or debugging.
|
||||
|
||||
See also this function's specific versions for the concrete Node types [`is_valid(graph::DAG, node::ComputeTaskNode)`](@ref) and [`is_valid(graph::DAG, node::DataTaskNode)`](@ref).
|
||||
"""
|
||||
function is_valid_node(graph::DAG, node::Node)
|
||||
@assert node in graph "Node is not part of the given graph!"
|
||||
|
||||
@ -22,7 +31,13 @@ function is_valid_node(graph::DAG, node::Node)
|
||||
return true
|
||||
end
|
||||
|
||||
# call with @assert
|
||||
"""
|
||||
is_valid(graph::DAG, node::ComputeTaskNode)
|
||||
|
||||
Verify that the given compute node is valid in the graph. Call with `@assert` or `@test` when testing or debugging.
|
||||
|
||||
This also calls [`is_valid_node(graph::DAG, node::Node)`](@ref).
|
||||
"""
|
||||
function is_valid(graph::DAG, node::ComputeTaskNode)
|
||||
@assert is_valid_node(graph, node)
|
||||
|
||||
@ -32,7 +47,13 @@ function is_valid(graph::DAG, node::ComputeTaskNode)
|
||||
return true
|
||||
end
|
||||
|
||||
# call with @assert
|
||||
"""
|
||||
is_valid(graph::DAG, node::DataTaskNode)
|
||||
|
||||
Verify that the given compute node is valid in the graph. Call with `@assert` or `@test` when testing or debugging.
|
||||
|
||||
This also calls [`is_valid_node(graph::DAG, node::Node)`](@ref).
|
||||
"""
|
||||
function is_valid(graph::DAG, node::DataTaskNode)
|
||||
@assert is_valid_node(graph, node)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user