diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..340c2ff --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,4 @@ +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8" +MetagraphOptimization = "3e869610-d48d-4942-ba70-c1b702a33ca4" diff --git a/docs/make.jl b/docs/make.jl new file mode 100644 index 0000000..6bb4851 --- /dev/null +++ b/docs/make.jl @@ -0,0 +1,29 @@ +using Documenter +using MetagraphOptimization + +makedocs( + #format = Documenter.LaTeX(platform=""), + + root = ".", + source = "src", + build = "build", + clean = true, + doctest = true, + modules = Module[MetagraphOptimization], + repo = "https://code.woubery.com/Rubydragon/MetagraphOptimization.jl/src/branch/{commit}{path}#L{line}", + sitename = "MetagraphOptimization.jl", + pages = [ + "index.md", + "Manual" => "manual.md", + "Library" => [ + "Graph" => "lib/internals/graph.md", + "Node" => "lib/internals/node.md", + "Task" => "lib/internals/task.md", + "Operation" => "lib/internals/operation.md", + "Models" => "lib/internals/models.md", + "Diff" => "lib/internals/diff.md", + "Utility" => "lib/internals/utility.md", + ], + "Contribution" => "contribution.md", + ], +) diff --git a/docs/src/contribution.md b/docs/src/contribution.md new file mode 100644 index 0000000..474e324 --- /dev/null +++ b/docs/src/contribution.md @@ -0,0 +1,3 @@ +# Contribution + +This is currently in development for a diploma thesis and is therefore private and impossible to contribute to. diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 0000000..544a2e5 --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,26 @@ +# MetagraphOptimization.jl + +*A domain-specific DAG-optimizer* + +## Package Features +- Read a DAG from a file +- Analyze its properties +- Mute the graph using the operations NodeFusion, NodeReduction and NodeSplit + +## Coming Soon: +- Add Code Generation from finished DAG +- Add optimization algorithms and strategies + +## Library Outline + +```@contents +Pages = [ + "lib/public.md", + "lib/internals.md" +] +``` + +### [Index](@id main-index) +```@index +Pages = ["lib/public.md"] +``` diff --git a/docs/src/lib/internals/diff.md b/docs/src/lib/internals/diff.md new file mode 100644 index 0000000..aedf082 --- /dev/null +++ b/docs/src/lib/internals/diff.md @@ -0,0 +1,22 @@ +# Diff + +## Type +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["diff/type.jl"] +Order = [:type] +``` + +## Properties +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["diff/properties.jl"] +Order = [:function] +``` + +## Printing +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["diff/print.jl"] +Order = [:function] +``` diff --git a/docs/src/lib/internals/graph.md b/docs/src/lib/internals/graph.md new file mode 100644 index 0000000..f3c1807 --- /dev/null +++ b/docs/src/lib/internals/graph.md @@ -0,0 +1,50 @@ +# Graph + +## Type +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["graph/type.jl"] +Order = [:type] +``` + +## Interface +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["graph/interface.jl"] +Order = [:function] +``` + +## Compare +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["graph/compare.jl"] +Order = [:function] +``` + +## Mute +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["graph/mute.jl"] +Order = [:function] +``` + +## Print +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["graph/print.jl"] +Order = [:function] +``` + +## Properties +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["graph/properties.jl"] +Order = [:function] +``` + +## Validate +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["graph/validate.jl"] +Order = [:function] +``` diff --git a/docs/src/lib/internals/models.md b/docs/src/lib/internals/models.md new file mode 100644 index 0000000..6921e78 --- /dev/null +++ b/docs/src/lib/internals/models.md @@ -0,0 +1,28 @@ +# Models + +## ABC-Model + +### Types +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["model/abc/types.jl"] +Order = [:type] +``` + +### Parse +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["models/abc/parse.jl"] +Order = [:function] +``` + +### Properties +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["models/abc/properties.jl"] +Order = [:function] +``` + +## QED-Model + +*To be added* diff --git a/docs/src/lib/internals/node.md b/docs/src/lib/internals/node.md new file mode 100644 index 0000000..1ffcde7 --- /dev/null +++ b/docs/src/lib/internals/node.md @@ -0,0 +1,43 @@ +# Node + +## Type +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["node/type.jl"] +Order = [:type] +``` + +## Create +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["node/create.jl"] +Order = [:function] +``` + +## Compare +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["node/compare.jl"] +Order = [:function] +``` + +## Properties +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["node/properties.jl"] +Order = [:function] +``` + +## Print +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["node/print.jl"] +Order = [:function] +``` + +## Validate +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["node/validate.jl"] +Order = [:function] +``` diff --git a/docs/src/lib/internals/operation.md b/docs/src/lib/internals/operation.md new file mode 100644 index 0000000..9e56bb2 --- /dev/null +++ b/docs/src/lib/internals/operation.md @@ -0,0 +1,57 @@ +# Operation + +## Types +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["operation/type.jl"] +Order = [:type] +``` + +## Find +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["operation/find.jl"] +Order = [:function] +``` + +## Apply +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["operation/apply.jl"] +Order = [:function] +``` + +## Get +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["operation/get.jl"] +Order = [:function] +``` + +## Clean +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["operation/clean.jl"] +Order = [:function] +``` + +## Utility +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["operation/utility.jl"] +Order = [:function] +``` + +## Print +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["operation/print.jl"] +Order = [:function] +``` + +## Validate +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["operation/validate.jl"] +Order = [:function] +``` diff --git a/docs/src/lib/internals/task.md b/docs/src/lib/internals/task.md new file mode 100644 index 0000000..512eb88 --- /dev/null +++ b/docs/src/lib/internals/task.md @@ -0,0 +1,29 @@ +# Task + +## Type +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["task/type.jl"] +Order = [:type] +``` + +## Compare +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["task/compare.jl"] +Order = [:function] +``` + +## Properties +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["task/properties.jl"] +Order = [:function] +``` + +## Print +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["task/print.jl"] +Order = [:function] +``` diff --git a/docs/src/lib/internals/utility.md b/docs/src/lib/internals/utility.md new file mode 100644 index 0000000..ca034d8 --- /dev/null +++ b/docs/src/lib/internals/utility.md @@ -0,0 +1,17 @@ +# Utility + +## Helper Functions +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["utility.jl"] +Order = [:type, :function] +``` + +## Trie Helper +This is a simple implementation of a [Trie Data Structure](https://en.wikipedia.org/wiki/Trie) to greatly improve the performance of the Node Reduction search. + +```@autodocs +Modules = [MetagraphOptimization] +Pages = ["trie.jl"] +Order = [:type, :function] +``` diff --git a/docs/src/lib/public.md b/docs/src/lib/public.md new file mode 100644 index 0000000..b73c320 --- /dev/null +++ b/docs/src/lib/public.md @@ -0,0 +1,18 @@ +# Public Documentation + +Documentation for `MetagraphOptimization.jl`'s public interface. + +See the Internals section of the manual for documentation of everything else. + +## Contents + +```@contents +Pages = ["public.md"] +Depth = 2 +``` + +## Index + +```@index +Pages = ["public.md"] +``` diff --git a/docs/src/manual.md b/docs/src/manual.md new file mode 100644 index 0000000..827c6b2 --- /dev/null +++ b/docs/src/manual.md @@ -0,0 +1,3 @@ +# Manual + +This will become a manual. diff --git a/src/MetagraphOptimization.jl b/src/MetagraphOptimization.jl index c75c14c..9afb586 100644 --- a/src/MetagraphOptimization.jl +++ b/src/MetagraphOptimization.jl @@ -1,35 +1,52 @@ +""" + MetagraphOptimization + +A module containing tools to work on DAGs. +""" module MetagraphOptimization -export Node, Edge, ComputeTaskNode, DataTaskNode, DAG -export AbstractTask, - AbstractComputeTask, AbstractDataTask, DataTask, FusedComputeTask -export make_node, - make_edge, - insert_node, - insert_edge, - is_entry_node, - is_exit_node, - parents, - children, - compute, - graph_properties, - get_exit_node, - is_valid -export NodeFusion, - NodeReduction, - NodeSplit, - push_operation!, - pop_operation!, - can_pop, - reset_graph!, - get_operations -export parse_abc, - ComputeTaskP, - ComputeTaskS1, - ComputeTaskS2, - ComputeTaskV, - ComputeTaskU, - ComputeTaskSum +export DAG +export Node +export Edge +export ComputeTaskNode +export DataTaskNode +export AbstractTask +export AbstractComputeTask +export AbstractDataTask +export DataTask +export FusedComputeTask + +export make_node +export make_edge +export insert_node +export insert_edge +export is_entry_node +export is_exit_node +export parents +export children +export compute +export graph_properties +export get_exit_node +export is_valid + +export Operation +export AppliedOperation +export NodeFusion +export NodeReduction +export NodeSplit +export push_operation! +export pop_operation! +export can_pop +export reset_graph! +export get_operations + +export parse_abc +export ComputeTaskP +export ComputeTaskS1 +export ComputeTaskS2 +export ComputeTaskV +export ComputeTaskU +export ComputeTaskSum export ==, in, show, isempty, delete!, length diff --git a/src/diff/print.jl b/src/diff/print.jl index d949341..5f6c5ff 100644 --- a/src/diff/print.jl +++ b/src/diff/print.jl @@ -1,3 +1,8 @@ +""" + show(io::IO, diff::Diff) + +Pretty-print a [`Diff`](@ref). Called via print, println and co. +""" function show(io::IO, diff::Diff) print(io, "Nodes: ") print(io, length(diff.addedNodes) + length(diff.removedNodes)) diff --git a/src/diff/properties.jl b/src/diff/properties.jl index 63dfe67..86411ac 100644 --- a/src/diff/properties.jl +++ b/src/diff/properties.jl @@ -1,4 +1,9 @@ -# return a namedtuple of the lengths of the added/removed nodes/edges +""" + length(diff::Diff) + +Return a named tuple of the lengths of the added/removed nodes/edges. +The fields are `.addedNodes`, `.addedEdges`, `.removedNodes` and `.removedEdges`. +""" function length(diff::Diff) return ( addedNodes = length(diff.addedNodes), diff --git a/src/diff/type.jl b/src/diff/type.jl index e7e7471..b3b7de3 100644 --- a/src/diff/type.jl +++ b/src/diff/type.jl @@ -1,3 +1,8 @@ +""" + Diff + +A named tuple representing a difference of added and removed nodes and edges on a [`DAG`](@ref). +""" const Diff = NamedTuple{ (:addedNodes, :removedNodes, :addedEdges, :removedEdges), Tuple{Vector{Node}, Vector{Node}, Vector{Edge}, Vector{Edge}}, diff --git a/src/graph/compare.jl b/src/graph/compare.jl index 8a67523..0845de3 100644 --- a/src/graph/compare.jl +++ b/src/graph/compare.jl @@ -1,7 +1,30 @@ +""" + in(node::Node, graph::DAG) +Check whether the node is part of the graph. +""" in(node::Node, graph::DAG) = node in graph.nodes -in(edge::Edge, graph::DAG) = edge in graph.edges +""" + in(edge::Edge, graph::DAG) + +Check whether the edge is part of the graph. +""" +function in(edge::Edge, graph::DAG) + n1 = edge.edge[1] + n2 = edge.edge[2] + if !(n1 in graph) || !(n2 in graph) + return false + end + + return n1 in n2.children +end + +""" + ==(n1::Node, n2::Node, g::DAG) + +Check equality of two nodes in a graph. +""" function ==(n1::Node, n2::Node, g::DAG) if typeof(n1) != typeof(n2) return false diff --git a/src/graph/interface.jl b/src/graph/interface.jl index 20df42a..450419c 100644 --- a/src/graph/interface.jl +++ b/src/graph/interface.jl @@ -1,6 +1,10 @@ -# user interface on the DAG +""" + push_operation!(graph::DAG, operation::Operation) -# applies a new operation to the end of the graph +Apply a new operation to the graph. + +See also: [`DAG`](@ref), [`pop_operation!`](@ref) +""" function push_operation!(graph::DAG, operation::Operation) # 1.: Add the operation to the DAG push!(graph.operationsToApply, operation) @@ -8,7 +12,13 @@ function push_operation!(graph::DAG, operation::Operation) return nothing end -# reverts the latest applied operation, essentially like a ctrl+z for +""" + pop_operation!(graph::DAG) + +Revert the latest applied operation on the graph. + +See also: [`DAG`](@ref), [`push_operation!`](@ref) +""" function pop_operation!(graph::DAG) # 1.: Remove the operation from the appliedChain of the DAG if !isempty(graph.operationsToApply) @@ -23,10 +33,19 @@ function pop_operation!(graph::DAG) return nothing end +""" + can_pop(graph::DAG) + +Return `true` if [`pop_operation!`](@ref) is possible, `false` otherwise. +""" can_pop(graph::DAG) = !isempty(graph.operationsToApply) || !isempty(graph.appliedOperations) -# reset the graph to its initial state with no operations applied +""" + reset_graph!(graph::DAG) + +Reset the graph to its initial state with no operations applied. +""" function reset_graph!(graph::DAG) while (can_pop(graph)) pop_operation!(graph) diff --git a/src/graph/mute.jl b/src/graph/mute.jl index 94e68c8..e572d6b 100644 --- a/src/graph/mute.jl +++ b/src/graph/mute.jl @@ -3,6 +3,18 @@ # 2: keep track of what was changed for the diff (if track == true) # 3: invalidate operation caches +""" + insert_node!(graph::DAG, node::Node; track = true, invalidate_cache = true) + +Insert the node into the graph. + +## Keyword Arguments +`track::Bool`: Whether to add the changes to the [`DAG`](@ref)'s [`Diff`](@ref). Should be set `false` in parsing or graph creation functions for performance. + +`invalidate_cache::Bool`: Whether to invalidate caches associated with the changes. Should also be turned off for graph creation or parsing. + +See also: [`remove_node!`](@ref), [`insert_edge!`](@ref), [`remove_edge!`](@ref) +""" function insert_node!( graph::DAG, node::Node, @@ -26,6 +38,18 @@ function insert_node!( return node end +""" + insert_edge!(graph::DAG, node1::Node, node2::Node; track = true, invalidate_cache = true) + +Insert the edge between node1 (child) and node2 (parent) into the graph. + +## Keyword Arguments +`track::Bool`: Whether to add the changes to the [`DAG`](@ref)'s [`Diff`](@ref). Should be set `false` in parsing or graph creation functions for performance. + +`invalidate_cache::Bool`: Whether to invalidate caches associated with the changes. Should also be turned off for graph creation or parsing. + +See also: [`insert_node!`](@ref), [`remove_node!`](@ref), [`remove_edge!`](@ref) +""" function insert_edge!( graph::DAG, node1::Node, @@ -59,6 +83,18 @@ function insert_edge!( return nothing end +""" + remove_node!(graph::DAG, node::Node; track = true, invalidate_cache = true) + +Remove the node from the graph. + +## Keyword Arguments +`track::Bool`: Whether to add the changes to the [`DAG`](@ref)'s [`Diff`](@ref). Should be set `false` in parsing or graph creation functions for performance. + +`invalidate_cache::Bool`: Whether to invalidate caches associated with the changes. Should also be turned off for graph creation or parsing. + +See also: [`insert_node!`](@ref), [`insert_edge!`](@ref), [`remove_edge!`](@ref) +""" function remove_node!( graph::DAG, node::Node, @@ -86,6 +122,18 @@ function remove_node!( return nothing end +""" + remove_edge!(graph::DAG, node1::Node, node2::Node; track = true, invalidate_cache = true) + +Remove the edge between node1 (child) and node2 (parent) into the graph. + +## Keyword Arguments +`track::Bool`: Whether to add the changes to the [`DAG`](@ref)'s [`Diff`](@ref). Should be set `false` in parsing or graph creation functions for performance. + +`invalidate_cache::Bool`: Whether to invalidate caches associated with the changes. Should also be turned off for graph creation or parsing. + +See also: [`insert_node!`](@ref), [`remove_node!`](@ref), [`insert_edge!`](@ref) +""" function remove_edge!( graph::DAG, node1::Node, diff --git a/src/graph/type.jl b/src/graph/type.jl index 06cc115..11ad5dc 100644 --- a/src/graph/type.jl +++ b/src/graph/type.jl @@ -1,21 +1,27 @@ using DataStructures +""" + PossibleOperations + +A struct storing all possible operations on a [`DAG`](@ref). +To get the [`PossibleOperations`](@ref) on a [`DAG`](@ref), use [`get_operations`](@ref). +""" mutable struct PossibleOperations nodeFusions::Set{NodeFusion} nodeReductions::Set{NodeReduction} nodeSplits::Set{NodeSplit} end -function PossibleOperations() - return PossibleOperations( - Set{NodeFusion}(), - Set{NodeReduction}(), - Set{NodeSplit}(), - ) -end +""" + DAG -# The actual state of the DAG is the initial state given by the set of nodes -# but with all the operations in appliedChain applied in order +The DAG is the representation of the graph as a set of nodes. + +A DAG can be loaded using the appropriate parse function, e.g. [`parse_abc`](@ref). +[`Operation`](@ref)s can be applied on it using [`push_operation!`](@ref) and reverted using [`pop_operation!`](@ref) like a stack. +To get the set of possible operations, use [`get_operations`](@ref). +The members of the object should not be manually accessed, instead always use the provided interface functions. +""" mutable struct DAG nodes::Set{Node} @@ -36,6 +42,14 @@ mutable struct DAG diff::Diff end +function PossibleOperations() + return PossibleOperations( + Set{NodeFusion}(), + Set{NodeReduction}(), + Set{NodeSplit}(), + ) +end + function DAG() return DAG( Set{Node}(), diff --git a/src/utility.jl b/src/utility.jl index 96ad4a3..b0d9354 100644 --- a/src/utility.jl +++ b/src/utility.jl @@ -1,3 +1,15 @@ +""" + bytes_to_human_readable(bytes) + +Return a human readable string representation of the given number. + +```jldoctest +julia> using MetagraphOptimization + +julia> bytes_to_human_readable(4096) +"4.0 KiB" +``` +""" function bytes_to_human_readable(bytes) units = ["B", "KiB", "MiB", "GiB", "TiB"] unit_index = 1