Contribution
Feel free to open issues or pull requests to the official repository. Ideas, tips, bug reports, or contributions are all welcome.
diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 84ccc3e..569e556 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.6","generation_timestamp":"2024-11-07T13:14:28","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.6","generation_timestamp":"2024-11-07T13:43:31","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/dev/contribution/index.html b/dev/contribution/index.html index 99024e7..2341004 100644 --- a/dev/contribution/index.html +++ b/dev/contribution/index.html @@ -1,2 +1,2 @@ -
Feel free to open issues or pull requests to the official repository. Ideas, tips, bug reports, or contributions are all welcome.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
Feel free to open issues or pull requests to the official repository. Ideas, tips, bug reports, or contributions are all welcome.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
A domain-specific DAG-optimizer
This packages provides a way to represent large computations in a graph representation. Once such a graph is created, it can
There are some hard requirements for this to be possible to a specific computation problem:
Some more soft requirements exist for the project to be useful:
The project consists of several parts that are designed to be mostly orthogonal interfaces, extendable with new implementations without having to change other parts of the code. For example implementations, refer to the manual, the tests, or other projects in the ComputableDAGs project.
The Graph is the central part. It consists of Nodes and Edges. Nodes represent a Task, which is either a computation or a data transfer. Edges purely represent the dependencies between the nodes.
A graph has to be generated first, which is done by defining a Model and providing some form of Generator for a specific problem instance of that model. This part is entirely up to the user. A generator might parse a file and generate a graph from that, or it may generate a basic graph by itself.
Estimators can be used to collect properties of the graph, for example the total compute effort defined by tasks.
From any state of the graph, possible Operations can be generated. These represent topological changes to the graph which do not change the total computation. Operations can be applied and popped similar to a stack.
The Optimizer interface then allows to use an estimator to push and pop operations to reduce the execution time.
Finally, the Scheduler can use Device information to generate the code.
For detailed information on all the interfaces und functionality provided, please refer to the public documentation or the respective internals, as linked above.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
A domain-specific DAG-optimizer
This packages provides a way to represent large computations in a graph representation. Once such a graph is created, it can
There are some hard requirements for this to be possible to a specific computation problem:
Some more soft requirements exist for the project to be useful:
The project consists of several parts that are designed to be mostly orthogonal interfaces, extendable with new implementations without having to change other parts of the code. For example implementations, refer to the manual, the tests, or other projects in the ComputableDAGs project.
The Graph is the central part. It consists of Nodes and Edges. Nodes represent a Task, which is either a computation or a data transfer. Edges purely represent the dependencies between the nodes.
A graph has to be generated first, which is done by defining a Model and providing some form of Generator for a specific problem instance of that model. This part is entirely up to the user. A generator might parse a file and generate a graph from that, or it may generate a basic graph by itself.
Estimators can be used to collect properties of the graph, for example the total compute effort defined by tasks.
From any state of the graph, possible Operations can be generated. These represent topological changes to the graph which do not change the total computation. Operations can be applied and popped similar to a stack.
The Optimizer interface then allows to use an estimator to push and pop operations to reduce the execution time.
Finally, the Scheduler can use Device information to generate the code.
For detailed information on all the interfaces und functionality provided, please refer to the public documentation or the respective internals, as linked above.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.Tape
— TypeTape{INPUT}
TODO: update docs
INPUT
the input type of the problem instance
code::Vector{Expr}
: The julia expression containing the code for the whole graph.
inputSymbols::Dict{String, Vector{Symbol}}
: A dictionary of symbols mapping the names of the input nodes of the graph to the symbols their inputs should be provided on.
outputSymbol::Symbol
: The symbol of the final calculated value
Implementations for generation of a callable function. A function generated this way cannot immediately be called. One Julia World Age has to pass before this is possible, which happens when the global Julia scope advances. If the DAG and therefore the generated function becomes too large, use the tape machine instead, since compiling large functions becomes infeasible.
ComputableDAGs.execute
— Methodexecute(
+Code Generation · ComputableDAGs.jl Code Generation
Types
ComputableDAGs.Tape
— TypeTape{INPUT}
TODO: update docs
INPUT
the input type of the problem instance
code::Vector{Expr}
: The julia expression containing the code for the whole graph.
inputSymbols::Dict{String, Vector{Symbol}}
: A dictionary of symbols mapping the names of the input nodes of the graph to the symbols their inputs should be provided on.
outputSymbol::Symbol
: The symbol of the final calculated value
sourceFunction Generation
Implementations for generation of a callable function. A function generated this way cannot immediately be called. One Julia World Age has to pass before this is possible, which happens when the global Julia scope advances. If the DAG and therefore the generated function becomes too large, use the tape machine instead, since compiling large functions becomes infeasible.
ComputableDAGs.execute
— Methodexecute(
graph::DAG,
instance,
machine::Machine,
input,
context_module::Module
)
Execute the code of the given graph
on the given input values.
This is essentially shorthand for
tape = gen_tape(graph, instance, machine, context_module)
-return execute_tape(tape, input)
sourceComputableDAGs.get_compute_function
— Methodget_compute_function(
+return execute_tape(tape, input)
sourceComputableDAGs.get_compute_function
— Methodget_compute_function(
graph::DAG,
instance,
machine::Machine,
context_module::Module
)
Return a function of signature compute_<id>(input::input_type(instance))
, which will return the result of the DAG computation on the given input. The final argument context_module
should always be @__MODULE__
to be able to use functions defined in the caller's environment. For this to work, you need
using RuntimeGeneratedFunctions
-RuntimeGeneratedFunctions.init(@__MODULE__)
in your top level.
Keyword Arguments
closures_size
(default=0 (off)): The size of closures to use in the main generated code. This specifies the size of code blocks across which the compiler cannot optimize. For sufficiently large functions, a larger value means longer compile times but potentially faster execution time.
sourceTape Machine
ComputableDAGs.call_fc
— Methodcall_fc(fc::FunctionCall, cache::Dict{Symbol, Any})
Execute the given FunctionCall
on the dictionary.
Several more specialized versions of this function exist to reduce vector unrolling work for common cases.
sourceComputableDAGs.execute_tape
— Methodexecute_tape(tape::Tape, input::Input) where {Input}
Execute the given tape with the given input.
Warning This is very slow and might not work. This is to be majorly revamped.
sourceComputableDAGs.expr_from_fc
— Methodexpr_from_fc(fc::FunctionCall)
For a given function call, return an expression evaluating it.
sourceComputableDAGs.gen_function_body
— Methodgen_function_body(tape::Tape; closures_size)
Generate the function body from the given Tape
.
Keyword Arguments
closures_size
: The size of closures to generate (in lines of code). Closures introduce function barriers in the function body, preventing some optimizations by the compiler and therefore greatly reducing compile time. A value of 1 or less will disable the use of closures entirely.
sourceComputableDAGs.gen_input_assignment_code
— Methodgen_input_assignment_code(
+RuntimeGeneratedFunctions.init(@__MODULE__)
in your top level.
Keyword Arguments
closures_size
(default=0 (off)): The size of closures to use in the main generated code. This specifies the size of code blocks across which the compiler cannot optimize. For sufficiently large functions, a larger value means longer compile times but potentially faster execution time.
sourceTape Machine
ComputableDAGs.call_fc
— Methodcall_fc(fc::FunctionCall, cache::Dict{Symbol, Any})
Execute the given FunctionCall
on the dictionary.
Several more specialized versions of this function exist to reduce vector unrolling work for common cases.
sourceComputableDAGs.execute_tape
— Methodexecute_tape(tape::Tape, input::Input) where {Input}
Execute the given tape with the given input.
Warning This is very slow and might not work. This is to be majorly revamped.
sourceComputableDAGs.expr_from_fc
— Methodexpr_from_fc(fc::FunctionCall)
For a given function call, return an expression evaluating it.
sourceComputableDAGs.gen_function_body
— Methodgen_function_body(tape::Tape; closures_size)
Generate the function body from the given Tape
.
Keyword Arguments
closures_size
: The size of closures to generate (in lines of code). Closures introduce function barriers in the function body, preventing some optimizations by the compiler and therefore greatly reducing compile time. A value of 1 or less will disable the use of closures entirely.
sourceComputableDAGs.gen_input_assignment_code
— Methodgen_input_assignment_code(
input_symbols::Dict{String, Vector{Symbol}},
instance::AbstractProblemInstance,
machine::Machine,
context_module::Module
-)
Return a Vector{Expr}
doing the input assignments from the given problem_input
onto the input_symbols
.
sourceComputableDAGs.gen_tape
— Functiongen_tape(
+)
Return a Vector{Expr}
doing the input assignments from the given problem_input
onto the input_symbols
.
sourceComputableDAGs.gen_tape
— Functiongen_tape(
graph::DAG,
instance::AbstractProblemInstance,
machine::Machine,
context_module::Module,
scheduler::AbstractScheduler = GreedyScheduler()
-)
Generate the code for a given graph. The return value is a Tape
.
See also: execute
, execute_tape
sourceSettings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
+)
Generate the code for a given graph. The return value is a Tape
.
See also: execute
, execute_tape
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.AbstractDevice
— TypeAbstractDevice
Abstract base type for every device, like GPUs, CPUs or any other compute devices. Every implementation needs to implement various functions.
ComputableDAGs.Machine
— TypeMachine
A representation of a machine to execute on. Contains information about its architecture (CPUs, GPUs, maybe more). This representation can be used to make a more accurate cost prediction of a DAG
state.
See also: Scheduler
ComputableDAGs.DEVICE_TYPES
— ConstantDEVICE_TYPES::Vector{Type}
Global vector of available and implemented device types. Each implementation of a AbstractDevice
should add its concrete type to this vector.
See also: device_types
, get_devices
ComputableDAGs._gen_access_expr
— Function_gen_access_expr(device::AbstractDevice, symbol::Symbol)
Interface function that must be implemented for every subtype of AbstractDevice
. Return an Expr
or QuoteNode
accessing the variable identified by [symbol
].
ComputableDAGs._gen_local_init
— Function_gen_local_init(fc::FunctionCall, device::AbstractDevice)
Interface function that must be implemented for every subtype of AbstractDevice
. Return an Expr
or QuoteNode
that initializes the access expression returned by _gen_access_expr
in the local scope. This expression may be empty. For local variables it should be local <variable_name>::<Type>
.
ComputableDAGs.get_devices
— Functionget_devices(t::Type{T}; verbose::Bool) where {T <: AbstractDevice}
Interface function that must be implemented for every subtype of AbstractDevice
. Returns a Vector{Type}
of the devices for the given AbstractDevice
Type available on the current machine.
ComputableDAGs.kernel
— Functionkernel(gpu_type::Type{<:AbstractGPU}, graph::DAG, instance)
For a GPU type, a DAG
, and a problem instance, return an Expr
containing a function of signature compute_<id>(input::<GPU>Vector, output::<GPU>Vector, n::Int64)
, which will return the result of the DAG computation of the input on the given output vector, intended for computation on GPUs. Currently, CUDAGPU
and ROCmGPU
are available if their respective package extensions are loaded.
The generated kernel function accepts its thread ID in only the x-dimension, and only as thread ID, not as block ID. The input and output should therefore be 1-dimensional vectors. For detailed information on GPU programming and the Julia packages, please refer to their respective documentations.
A simple example call for a CUDA kernel might look like the following:
@cuda threads = (32,) always_inline = true cuda_kernel!(cu_inputs, outputs, length(cu_inputs))
Unlike the standard get_compute_function
to generate a callable function which returns a RuntimeGeneratedFunction
, this returns an Expr
that needs to be eval
'd. This is a current limitation of RuntimeGeneratedFunctions.jl
which currently cannot wrap GPU kernels. This might change in the future.
Size limitation
The generated kernel does not use any internal parallelization, i.e., the DAG is compiled into a serialized function, processing each input in a single thread of the GPU. This means it can be heavily parallelized and use the GPU at 100% for sufficiently large input vectors (and assuming the function does not become IO limited etc.). However, it also means that there is a limit to how large the compiled function can be. If it gets too large, the compilation might fail, take too long to complete, the kernel might fail during execution if too much stack memory is required, or other similar problems. If this happens, your problem is likely too large to be compiled to a GPU kernel like this.
Compute Requirements
A GPU function has more restrictions on what can be computed than general functions running on the CPU. In Julia, there are mainly two important restrictions to consider:
isbits(x)
must be true
for arguments and local variables used in ComputeTasks
.always_inline = true
argument for @cuda
calls can help with this.This feature is currently experimental. There are still some unresolved issues with the generated kernels.
ComputableDAGs.measure_device!
— Functionmeasure_device!(device::AbstractDevice; verbose::Bool)
Interface function that must be implemented for every subtype of AbstractDevice
. Measures the compute speed of the given device and writes into it.
ComputableDAGs.get_machine_info
— Methodget_machine_info(verbose::Bool)
Return the Machine
currently running on. The parameter verbose
defaults to true when interactive.
ComputableDAGs.measure_devices!
— Methodmeasure_devices(machine::Machine; verbose::Bool)
Measure FLOPS, RAM, cache sizes and what other properties can be extracted for the devices in the given machine.
ComputableDAGs.measure_transfer_rates!
— Methodmeasure_transfer_rates(machine::Machine; verbose::Bool)
Measure the transfer rates between devices in the machine.
ComputableDAGs.cpu_st
— Methodcpu_st()
A function returning a Machine
that only has a single thread of one CPU. It is the simplest machine definition possible and produces a simple function when used with get_compute_function
.
ComputableDAGs.device_types
— MethodComputableDAGs.entry_device
— Methodentry_device(machine::Machine)
Return the "entry" device, i.e., the device that starts CPU threads and GPU kernels, and takes input values and returns the output value.
ComputableDAGs.gen_access_expr
— Methodgen_access_expr(fc::FunctionCall)
Dispatch from the given FunctionCall
to the interface function _gen_access_expr
(@ref).
ComputableDAGs.gen_local_init
— Methodgen_local_init(fc::FunctionCall)
Dispatch from the given FunctionCall
to the interface function _gen_local_init
(@ref).
ComputableDAGs.NumaNode
— TypeNumaNode <: AbstractCPU
Representation of a specific CPU that code can run on. Implements the AbstractDevice
interface.
ComputableDAGs._gen_access_expr
— Method_gen_access_expr(device::NumaNode, symbol::Symbol)
Interface implementation, dispatched to from gen_access_expr
.
ComputableDAGs._gen_local_init
— Method_gen_local_init(fc::FunctionCall, device::NumaNode)
Interface implementation, dispatched to from gen_local_init
.
ComputableDAGs.get_devices
— Methodget_devices(deviceType::Type{T}; verbose::Bool) where {T <: NumaNode}
Return a Vector of NumaNode
s available on the current machine. If verbose
is true, print some additional information.
ComputableDAGs.CUDAGPU
— TypeCUDAGPU <: AbstractGPU
Representation of a specific CUDA GPU that code can run on. Implements the AbstractDevice
interface.
This requires CUDA to be loaded to be useful.
ComputableDAGs.ROCmGPU
— TypeROCmGPU <: AbstractGPU
Representation of a specific AMD GPU that code can run on. Implements the AbstractDevice
interface.
This requires AMDGPU to be loaded to be useful.
ComputableDAGs.oneAPIGPU
— TypeoneAPIGPU <: AbstractGPU
Representation of a specific Intel GPU that code can run on. Implements the AbstractDevice
interface.
This requires oneAPI to be loaded to be useful.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.AbstractDevice
— TypeAbstractDevice
Abstract base type for every device, like GPUs, CPUs or any other compute devices. Every implementation needs to implement various functions.
ComputableDAGs.Machine
— TypeMachine
A representation of a machine to execute on. Contains information about its architecture (CPUs, GPUs, maybe more). This representation can be used to make a more accurate cost prediction of a DAG
state.
See also: Scheduler
ComputableDAGs.DEVICE_TYPES
— ConstantDEVICE_TYPES::Vector{Type}
Global vector of available and implemented device types. Each implementation of a AbstractDevice
should add its concrete type to this vector.
See also: device_types
, get_devices
ComputableDAGs._gen_access_expr
— Function_gen_access_expr(device::AbstractDevice, symbol::Symbol)
Interface function that must be implemented for every subtype of AbstractDevice
. Return an Expr
or QuoteNode
accessing the variable identified by [symbol
].
ComputableDAGs._gen_local_init
— Function_gen_local_init(fc::FunctionCall, device::AbstractDevice)
Interface function that must be implemented for every subtype of AbstractDevice
. Return an Expr
or QuoteNode
that initializes the access expression returned by _gen_access_expr
in the local scope. This expression may be empty. For local variables it should be local <variable_name>::<Type>
.
ComputableDAGs.get_devices
— Functionget_devices(t::Type{T}; verbose::Bool) where {T <: AbstractDevice}
Interface function that must be implemented for every subtype of AbstractDevice
. Returns a Vector{Type}
of the devices for the given AbstractDevice
Type available on the current machine.
ComputableDAGs.kernel
— Functionkernel(gpu_type::Type{<:AbstractGPU}, graph::DAG, instance)
For a GPU type, a DAG
, and a problem instance, return an Expr
containing a function of signature compute_<id>(input::<GPU>Vector, output::<GPU>Vector, n::Int64)
, which will return the result of the DAG computation of the input on the given output vector, intended for computation on GPUs. Currently, CUDAGPU
and ROCmGPU
are available if their respective package extensions are loaded.
The generated kernel function accepts its thread ID in only the x-dimension, and only as thread ID, not as block ID. The input and output should therefore be 1-dimensional vectors. For detailed information on GPU programming and the Julia packages, please refer to their respective documentations.
A simple example call for a CUDA kernel might look like the following:
@cuda threads = (32,) always_inline = true cuda_kernel!(cu_inputs, outputs, length(cu_inputs))
Unlike the standard get_compute_function
to generate a callable function which returns a RuntimeGeneratedFunction
, this returns an Expr
that needs to be eval
'd. This is a current limitation of RuntimeGeneratedFunctions.jl
which currently cannot wrap GPU kernels. This might change in the future.
Size limitation
The generated kernel does not use any internal parallelization, i.e., the DAG is compiled into a serialized function, processing each input in a single thread of the GPU. This means it can be heavily parallelized and use the GPU at 100% for sufficiently large input vectors (and assuming the function does not become IO limited etc.). However, it also means that there is a limit to how large the compiled function can be. If it gets too large, the compilation might fail, take too long to complete, the kernel might fail during execution if too much stack memory is required, or other similar problems. If this happens, your problem is likely too large to be compiled to a GPU kernel like this.
Compute Requirements
A GPU function has more restrictions on what can be computed than general functions running on the CPU. In Julia, there are mainly two important restrictions to consider:
isbits(x)
must be true
for arguments and local variables used in ComputeTasks
.always_inline = true
argument for @cuda
calls can help with this.This feature is currently experimental. There are still some unresolved issues with the generated kernels.
ComputableDAGs.measure_device!
— Functionmeasure_device!(device::AbstractDevice; verbose::Bool)
Interface function that must be implemented for every subtype of AbstractDevice
. Measures the compute speed of the given device and writes into it.
ComputableDAGs.get_machine_info
— Methodget_machine_info(verbose::Bool)
Return the Machine
currently running on. The parameter verbose
defaults to true when interactive.
ComputableDAGs.measure_devices!
— Methodmeasure_devices(machine::Machine; verbose::Bool)
Measure FLOPS, RAM, cache sizes and what other properties can be extracted for the devices in the given machine.
ComputableDAGs.measure_transfer_rates!
— Methodmeasure_transfer_rates(machine::Machine; verbose::Bool)
Measure the transfer rates between devices in the machine.
ComputableDAGs.cpu_st
— Methodcpu_st()
A function returning a Machine
that only has a single thread of one CPU. It is the simplest machine definition possible and produces a simple function when used with get_compute_function
.
ComputableDAGs.device_types
— MethodComputableDAGs.entry_device
— Methodentry_device(machine::Machine)
Return the "entry" device, i.e., the device that starts CPU threads and GPU kernels, and takes input values and returns the output value.
ComputableDAGs.gen_access_expr
— Methodgen_access_expr(fc::FunctionCall)
Dispatch from the given FunctionCall
to the interface function _gen_access_expr
(@ref).
ComputableDAGs.gen_local_init
— Methodgen_local_init(fc::FunctionCall)
Dispatch from the given FunctionCall
to the interface function _gen_local_init
(@ref).
ComputableDAGs.NumaNode
— TypeNumaNode <: AbstractCPU
Representation of a specific CPU that code can run on. Implements the AbstractDevice
interface.
ComputableDAGs._gen_access_expr
— Method_gen_access_expr(device::NumaNode, symbol::Symbol)
Interface implementation, dispatched to from gen_access_expr
.
ComputableDAGs._gen_local_init
— Method_gen_local_init(fc::FunctionCall, device::NumaNode)
Interface implementation, dispatched to from gen_local_init
.
ComputableDAGs.get_devices
— Methodget_devices(deviceType::Type{T}; verbose::Bool) where {T <: NumaNode}
Return a Vector of NumaNode
s available on the current machine. If verbose
is true, print some additional information.
ComputableDAGs.CUDAGPU
— TypeCUDAGPU <: AbstractGPU
Representation of a specific CUDA GPU that code can run on. Implements the AbstractDevice
interface.
This requires CUDA to be loaded to be useful.
ComputableDAGs.ROCmGPU
— TypeROCmGPU <: AbstractGPU
Representation of a specific AMD GPU that code can run on. Implements the AbstractDevice
interface.
This requires AMDGPU to be loaded to be useful.
ComputableDAGs.oneAPIGPU
— TypeoneAPIGPU <: AbstractGPU
Representation of a specific Intel GPU that code can run on. Implements the AbstractDevice
interface.
This requires oneAPI to be loaded to be useful.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.Diff
— TypeDiff
A named tuple representing a difference of added and removed nodes and edges on a DAG
.
Base.length
— Methodlength(diff::Diff)
Return a named tuple of the lengths of the added/removed nodes/edges. The fields are .addedNodes
, .addedEdges
, .removedNodes
and .removedEdges
.
Base.show
— Methodshow(io::IO, diff::Diff)
Pretty-print a Diff
. Called via print, println and co.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.Diff
— TypeDiff
A named tuple representing a difference of added and removed nodes and edges on a DAG
.
Base.length
— Methodlength(diff::Diff)
Return a named tuple of the lengths of the added/removed nodes/edges. The fields are .addedNodes
, .addedEdges
, .removedNodes
and .removedEdges
.
Base.show
— Methodshow(io::IO, diff::Diff)
Pretty-print a Diff
. Called via print, println and co.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
The interface that has to be implemented for an estimator.
ComputableDAGs.AbstractEstimator
— TypeAbstractEstimator
Abstract base type for an estimator. An estimator estimates the cost of a graph or the difference an operation applied to a graph will make to its cost.
Interface functions are
ComputableDAGs.cost_type
— Functioncost_type(estimator::AbstractEstimator)
Interface function returning a specific estimator's cost type, i.e., the type returned by its implementation of graph_cost
and operation_effect
.
ComputableDAGs.graph_cost
— Functiongraph_cost(estimator::AbstractEstimator, graph::DAG)
Get the total estimated cost of the graph. The cost's data type can be chosen by the implementation, but must have a usable lessthan comparison operator (<), basic math operators (+, -) and an implementation of zero()
and typemax()
.
ComputableDAGs.operation_effect
— Methodoperation_effect(estimator::AbstractEstimator, graph::DAG, operation::Operation)
Get the estimated effect on the cost of the graph, such that graph_cost(estimator, graph) + operation_effect(estimator, graph, operation) ~= graph_cost(estimator, graph_with_operation_applied)
. There is no hard requirement for this, but the better the estimate, the better an optimization algorithm will be.
There is a default implementation of this function, applying the operation, calling graph_cost
, then popping the operation again.
It can be much faster to overload this function for a specific estimator and directly compute the effects from the operation if possible.
Implementation of a global metric estimator. It uses the graph properties compute effort, data transfer, and compute intensity.
ComputableDAGs.CDCost
— TypeCDCost
Representation of a DAG
's cost as estimated by the GlobalMetricEstimator
.
Fields:
.data
: The total data transfer..computeEffort
: The total compute effort..computeIntensity
: The compute intensity, will always equal .computeEffort / .data
.
Note that the computeIntensity
doesn't necessarily make sense in the context of only operation costs. It will still work as intended when adding/subtracting to/from a graph_cost
estimate.
ComputableDAGs.GlobalMetricEstimator
— TypeGlobalMetricEstimator <: AbstractEstimator
A simple estimator that adds up each node's set compute_effort
and data
.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
The interface that has to be implemented for an estimator.
ComputableDAGs.AbstractEstimator
— TypeAbstractEstimator
Abstract base type for an estimator. An estimator estimates the cost of a graph or the difference an operation applied to a graph will make to its cost.
Interface functions are
ComputableDAGs.cost_type
— Functioncost_type(estimator::AbstractEstimator)
Interface function returning a specific estimator's cost type, i.e., the type returned by its implementation of graph_cost
and operation_effect
.
ComputableDAGs.graph_cost
— Functiongraph_cost(estimator::AbstractEstimator, graph::DAG)
Get the total estimated cost of the graph. The cost's data type can be chosen by the implementation, but must have a usable lessthan comparison operator (<), basic math operators (+, -) and an implementation of zero()
and typemax()
.
ComputableDAGs.operation_effect
— Methodoperation_effect(estimator::AbstractEstimator, graph::DAG, operation::Operation)
Get the estimated effect on the cost of the graph, such that graph_cost(estimator, graph) + operation_effect(estimator, graph, operation) ~= graph_cost(estimator, graph_with_operation_applied)
. There is no hard requirement for this, but the better the estimate, the better an optimization algorithm will be.
There is a default implementation of this function, applying the operation, calling graph_cost
, then popping the operation again.
It can be much faster to overload this function for a specific estimator and directly compute the effects from the operation if possible.
Implementation of a global metric estimator. It uses the graph properties compute effort, data transfer, and compute intensity.
ComputableDAGs.CDCost
— TypeCDCost
Representation of a DAG
's cost as estimated by the GlobalMetricEstimator
.
Fields:
.data
: The total data transfer..computeEffort
: The total compute effort..computeIntensity
: The compute intensity, will always equal .computeEffort / .data
.
Note that the computeIntensity
doesn't necessarily make sense in the context of only operation costs. It will still work as intended when adding/subtracting to/from a graph_cost
estimate.
ComputableDAGs.GlobalMetricEstimator
— TypeGlobalMetricEstimator <: AbstractEstimator
A simple estimator that adds up each node's set compute_effort
and data
.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.DAG
— TypeDAG
The representation of the graph as a set of Node
s.
Operation
s can be applied on it using push_operation!
and reverted using pop_operation!
like a stack. To get the set of possible operations, use get_operations
. The members of the object should not be manually accessed, instead always use the provided interface functions.
ComputableDAGs.DAG
— MethodDAG()
Construct and return an empty DAG
.
ComputableDAGs.PossibleOperations
— TypePossibleOperations
A struct storing all possible operations on a DAG
. To get the PossibleOperations
on a DAG
, use get_operations
.
ComputableDAGs.PossibleOperations
— MethodPossibleOperations()
Construct and return an empty PossibleOperations
object.
ComputableDAGs.can_pop
— Methodcan_pop(graph::DAG)
Return true
if pop_operation!
is possible, false
otherwise.
ComputableDAGs.pop_operation!
— Methodpop_operation!(graph::DAG)
Revert the latest applied operation on the graph.
See also: DAG
, push_operation!
ComputableDAGs.push_operation!
— Methodpush_operation!(graph::DAG, operation::Operation)
Apply a new operation to the graph.
See also: DAG
, pop_operation!
ComputableDAGs.reset_graph!
— Methodreset_graph!(graph::DAG)
Reset the graph to its initial state with no operations applied.
Base.in
— Methodin(edge::Edge, graph::DAG)
Check whether the edge is part of the graph.
Base.in
— Methodin(node::Node, graph::DAG)
Check whether the node is part of the graph.
ComputableDAGs._insert_edge!
— Function_insert_edge!(graph::DAG, node1::Node, node2::Node, index::Int=0; track = true, invalidate_cache = true)
Insert the edge between node1
(child) and node2
(parent) into the graph. An optional integer index can be given. The arguments of the function call that this node compiles to will then be ordered by these indices.
For creating new graphs, use the public version insert_edge!
instead which uses the defaults false for the keywords.
Keyword Arguments
track::Bool
: Whether to add the changes to the DAG
's Diff
. 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!
, _remove_node!
, _remove_edge!
ComputableDAGs._insert_node!
— Method_insert_node!(graph::DAG, node::Node; track = true, invalidate_cache = true)
Insert the node into the graph.
For creating new graphs, use the public version insert_node!
instead which uses the defaults false for the keywords.
Keyword Arguments
track::Bool
: Whether to add the changes to the DAG
's Diff
. 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!
, _insert_edge!
, _remove_edge!
ComputableDAGs._remove_edge!
— Method_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. Returns the integer index of the removed edge.
Keyword Arguments
track::Bool
: Whether to add the changes to the DAG
's Diff
. 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!
, _remove_node!
, _insert_edge!
ComputableDAGs._remove_node!
— Method_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
's Diff
. 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!
, _insert_edge!
, _remove_edge!
ComputableDAGs.get_snapshot_diff
— Methodget_snapshot_diff(graph::DAG)
Return the graph's Diff
since last time this function was called.
See also: revert_diff!
, AppliedOperation
and revert_operation!
ComputableDAGs.insert_edge!
— Functioninsert_edge!(graph::DAG, node1::Node, node2::Node)
Insert the edge between node1 (child) and node2 (parent) into the graph.
ComputableDAGs.insert_node!
— Methodinsert_node!(graph::DAG, node::Node)
-insert_node!(graph::DAG, task::AbstractTask, name::String="")
Insert the node into the graph or alternatively construct a node from the given task and insert it.
ComputableDAGs.invalidate_caches!
— Methodinvalidate_caches!(graph::DAG, operation::NodeReduction)
Invalidate the operation caches for a given NodeReduction
.
This deletes the operation from the graph's possible operations and from the involved nodes' own operation caches.
ComputableDAGs.invalidate_caches!
— Methodinvalidate_caches!(graph::DAG, operation::NodeSplit)
Invalidate the operation caches for a given NodeSplit
.
This deletes the operation from the graph's possible operations and from the involved nodes' own operation caches.
ComputableDAGs.invalidate_operation_caches!
— Methodinvalidate_operation_caches!(graph::DAG, node::ComputeTaskNode)
Invalidate the operation caches of the given node through calls to the respective invalidate_caches!
functions.
ComputableDAGs.invalidate_operation_caches!
— Methodinvalidate_operation_caches!(graph::DAG, node::DataTaskNode)
Invalidate the operation caches of the given node through calls to the respective invalidate_caches!
functions.
Base.show
— Methodshow(io::IO, graph::DAG)
Print the given graph to io. If there are too many nodes it will print only a summary of them.
ComputableDAGs.show_nodes
— Methodshow_nodes(io::IO, graph::DAG)
Print a graph's nodes. Should only be used for small graphs as it prints every node in a list.
ComputableDAGs.get_entry_nodes
— Methodget_entry_nodes(graph::DAG)
Return a vector of the graph's entry nodes.
ComputableDAGs.get_exit_node
— Methodget_exit_node(graph::DAG)
Return the graph's exit node. This assumes the graph only has a single exit node. If the graph has multiple exit nodes, the one encountered first will be returned.
ComputableDAGs.get_properties
— Methodget_properties(graph::DAG)
Return the graph's GraphProperties
.
ComputableDAGs.operation_stack_length
— Methodoperation_stack_length(graph::DAG)
Return the number of operations applied to the graph.
ComputableDAGs.is_connected
— Methodis_connected(graph::DAG)
Return whether the given graph is connected.
ComputableDAGs.is_scheduled
— Methodis_scheduled(graph::DAG)
Validate that the entire graph has been scheduled, i.e., every ComputeTaskNode
has its .device
set.
ComputableDAGs.is_valid
— Methodis_valid(graph::DAG)
Validate the entire graph using asserts. Intended for testing with @assert is_valid(graph)
.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.DAG
— TypeDAG
The representation of the graph as a set of Node
s.
Operation
s can be applied on it using push_operation!
and reverted using pop_operation!
like a stack. To get the set of possible operations, use get_operations
. The members of the object should not be manually accessed, instead always use the provided interface functions.
ComputableDAGs.DAG
— MethodDAG()
Construct and return an empty DAG
.
ComputableDAGs.PossibleOperations
— TypePossibleOperations
A struct storing all possible operations on a DAG
. To get the PossibleOperations
on a DAG
, use get_operations
.
ComputableDAGs.PossibleOperations
— MethodPossibleOperations()
Construct and return an empty PossibleOperations
object.
ComputableDAGs.can_pop
— Methodcan_pop(graph::DAG)
Return true
if pop_operation!
is possible, false
otherwise.
ComputableDAGs.pop_operation!
— Methodpop_operation!(graph::DAG)
Revert the latest applied operation on the graph.
See also: DAG
, push_operation!
ComputableDAGs.push_operation!
— Methodpush_operation!(graph::DAG, operation::Operation)
Apply a new operation to the graph.
See also: DAG
, pop_operation!
ComputableDAGs.reset_graph!
— Methodreset_graph!(graph::DAG)
Reset the graph to its initial state with no operations applied.
Base.in
— Methodin(edge::Edge, graph::DAG)
Check whether the edge is part of the graph.
Base.in
— Methodin(node::Node, graph::DAG)
Check whether the node is part of the graph.
ComputableDAGs._insert_edge!
— Function_insert_edge!(graph::DAG, node1::Node, node2::Node, index::Int=0; track = true, invalidate_cache = true)
Insert the edge between node1
(child) and node2
(parent) into the graph. An optional integer index can be given. The arguments of the function call that this node compiles to will then be ordered by these indices.
For creating new graphs, use the public version insert_edge!
instead which uses the defaults false for the keywords.
Keyword Arguments
track::Bool
: Whether to add the changes to the DAG
's Diff
. 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!
, _remove_node!
, _remove_edge!
ComputableDAGs._insert_node!
— Method_insert_node!(graph::DAG, node::Node; track = true, invalidate_cache = true)
Insert the node into the graph.
For creating new graphs, use the public version insert_node!
instead which uses the defaults false for the keywords.
Keyword Arguments
track::Bool
: Whether to add the changes to the DAG
's Diff
. 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!
, _insert_edge!
, _remove_edge!
ComputableDAGs._remove_edge!
— Method_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. Returns the integer index of the removed edge.
Keyword Arguments
track::Bool
: Whether to add the changes to the DAG
's Diff
. 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!
, _remove_node!
, _insert_edge!
ComputableDAGs._remove_node!
— Method_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
's Diff
. 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!
, _insert_edge!
, _remove_edge!
ComputableDAGs.get_snapshot_diff
— Methodget_snapshot_diff(graph::DAG)
Return the graph's Diff
since last time this function was called.
See also: revert_diff!
, AppliedOperation
and revert_operation!
ComputableDAGs.insert_edge!
— Functioninsert_edge!(graph::DAG, node1::Node, node2::Node)
Insert the edge between node1 (child) and node2 (parent) into the graph.
ComputableDAGs.insert_node!
— Methodinsert_node!(graph::DAG, node::Node)
+insert_node!(graph::DAG, task::AbstractTask, name::String="")
Insert the node into the graph or alternatively construct a node from the given task and insert it.
ComputableDAGs.invalidate_caches!
— Methodinvalidate_caches!(graph::DAG, operation::NodeReduction)
Invalidate the operation caches for a given NodeReduction
.
This deletes the operation from the graph's possible operations and from the involved nodes' own operation caches.
ComputableDAGs.invalidate_caches!
— Methodinvalidate_caches!(graph::DAG, operation::NodeSplit)
Invalidate the operation caches for a given NodeSplit
.
This deletes the operation from the graph's possible operations and from the involved nodes' own operation caches.
ComputableDAGs.invalidate_operation_caches!
— Methodinvalidate_operation_caches!(graph::DAG, node::ComputeTaskNode)
Invalidate the operation caches of the given node through calls to the respective invalidate_caches!
functions.
ComputableDAGs.invalidate_operation_caches!
— Methodinvalidate_operation_caches!(graph::DAG, node::DataTaskNode)
Invalidate the operation caches of the given node through calls to the respective invalidate_caches!
functions.
Base.show
— Methodshow(io::IO, graph::DAG)
Print the given graph to io. If there are too many nodes it will print only a summary of them.
ComputableDAGs.show_nodes
— Methodshow_nodes(io::IO, graph::DAG)
Print a graph's nodes. Should only be used for small graphs as it prints every node in a list.
ComputableDAGs.get_entry_nodes
— Methodget_entry_nodes(graph::DAG)
Return a vector of the graph's entry nodes.
ComputableDAGs.get_exit_node
— Methodget_exit_node(graph::DAG)
Return the graph's exit node. This assumes the graph only has a single exit node. If the graph has multiple exit nodes, the one encountered first will be returned.
ComputableDAGs.get_properties
— Methodget_properties(graph::DAG)
Return the graph's GraphProperties
.
ComputableDAGs.operation_stack_length
— Methodoperation_stack_length(graph::DAG)
Return the number of operations applied to the graph.
ComputableDAGs.is_connected
— Methodis_connected(graph::DAG)
Return whether the given graph is connected.
ComputableDAGs.is_scheduled
— Methodis_scheduled(graph::DAG)
Validate that the entire graph has been scheduled, i.e., every ComputeTaskNode
has its .device
set.
ComputableDAGs.is_valid
— Methodis_valid(graph::DAG)
Validate the entire graph using asserts. Intended for testing with @assert is_valid(graph)
.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
The interface that has to be implemented for a model to be usable is defined in src/models/interface.jl
.
ComputableDAGs.AbstractModel
— TypeAbstractModel
Base type for all models. From this, AbstractProblemInstance
s can be constructed.
See also: problem_instance
ComputableDAGs.AbstractProblemInstance
— TypeAbstractProblemInstance
Base type for problem instances. An object of this type of a corresponding AbstractModel
should uniquely identify a problem instance of that model.
ComputableDAGs.graph
— Functiongraph(::AbstractProblemInstance)
Generate the DAG
for the given AbstractProblemInstance
. Every entry node (see get_entry_nodes
) to the graph must have a name set. Implement input_expr
to return a valid expression for each of those names.
ComputableDAGs.input_expr
— Functioninput_expr(instance::AbstractProblemInstance, name::String, input_symbol::Symbol)
For the given AbstractProblemInstance
, the entry node name, and the symbol of the problem input (where a variable of type input_type(...)
will exist), return an Expr
that gets that specific input value from the input symbol.
ComputableDAGs.input_type
— Functioninput_type(problem::AbstractProblemInstance)
Return the input type for a specific AbstractProblemInstance
. This can be a specific type or a supertype for which all child types are expected to work.
ComputableDAGs.problem_instance
— Functionproblem_instance(::AbstractModel, ::Vararg)
Interface function that must be implemented for any implementation of AbstractModel
. This function should return a specific AbstractProblemInstance
given some parameters.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
The interface that has to be implemented for a model to be usable is defined in src/models/interface.jl
.
ComputableDAGs.AbstractModel
— TypeAbstractModel
Base type for all models. From this, AbstractProblemInstance
s can be constructed.
See also: problem_instance
ComputableDAGs.AbstractProblemInstance
— TypeAbstractProblemInstance
Base type for problem instances. An object of this type of a corresponding AbstractModel
should uniquely identify a problem instance of that model.
ComputableDAGs.graph
— Functiongraph(::AbstractProblemInstance)
Generate the DAG
for the given AbstractProblemInstance
. Every entry node (see get_entry_nodes
) to the graph must have a name set. Implement input_expr
to return a valid expression for each of those names.
ComputableDAGs.input_expr
— Functioninput_expr(instance::AbstractProblemInstance, name::String, input_symbol::Symbol)
For the given AbstractProblemInstance
, the entry node name, and the symbol of the problem input (where a variable of type input_type(...)
will exist), return an Expr
that gets that specific input value from the input symbol.
ComputableDAGs.input_type
— Functioninput_type(problem::AbstractProblemInstance)
Return the input type for a specific AbstractProblemInstance
. This can be a specific type or a supertype for which all child types are expected to work.
ComputableDAGs.problem_instance
— Functionproblem_instance(::AbstractModel, ::Vararg)
Interface function that must be implemented for any implementation of AbstractModel
. This function should return a specific AbstractProblemInstance
given some parameters.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.ComputeTaskNode
— TypeComputeTaskNode <: Node
Any node that computes a result from inputs using an AbstractComputeTask
.
Fields
.task
: The node's compute task type. A concrete subtype of AbstractComputeTask
..parents
: A vector of the node's parents (i.e. nodes that depend on this one)..children
: A vector of tuples with the node's children (i.e. nodes that this one depends on) and their index, used to order the arguments for the AbstractComputeTask
..id
: The node's id. Improves the speed of comparisons and is used as a unique identifier..nodeReduction
: Either this node's NodeReduction
or missing
, if none. There can only be at most one..nodeSplit
: Either this node's NodeSplit
or missing
, if none. There can only be at most one..device
: The Device this node has been scheduled on by a Scheduler
.
ComputableDAGs.DataTaskNode
— TypeDataTaskNode <: Node
Any node that transfers data and does no computation.
Fields
.task
: The node's data task type. Usually DataTask
..parents
: A vector of the node's parents (i.e. nodes that depend on this one)..children
: A vector of tuples of the node's children (i.e. nodes that this one depends on) and their indices, indicating their order in the resulting function call passed to the task..id
: The node's id. Improves the speed of comparisons and is used as a unique identifier..nodeReduction
: Either this node's NodeReduction
or missing
, if none. There can only be at most one..nodeSplit
: Either this node's NodeSplit
or missing
, if none. There can only be at most one..name
: The name of this node for entry nodes into the graph (is_entry_node
) to reliably assign the inputs to the correct nodes when executing.
ComputableDAGs.Edge
— TypeEdge
Type of an edge in the graph. Edges can only exist between a DataTaskNode
and a ComputeTaskNode
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]
. Additionally, the Edge
contains the
index` which is used as the child's index in the parent node.
The child is the prerequisite node of the parent.
ComputableDAGs.Node
— TypeComputableDAGs.make_edge
— Functionmake_edge(n1::Node, n2::Node, index::Int)
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.
ComputableDAGs.make_edge
— Functionmake_edge(n1::ComputeTaskNode, n2::DataTaskNode, index::Int)
Construct and return a new Edge
pointing from n1
(child) to n2
(parent).
The index parameter is 0 by default and is passed to the parent node as argument index for its child.
ComputableDAGs.make_edge
— Functionmake_edge(n1::DataTaskNode, n2::ComputeTaskNode)
Construct and return a new Edge
pointing from n1
(child) to n2
(parent).
The index parameter is 0 by default and is passed to the parent node as argument index for its child.
ComputableDAGs.make_node
— Functionmake_node(t::AbstractDataTask)
Construct and return a new DataTaskNode
with the given task.
ComputableDAGs.make_node
— Methodmake_node(t::AbstractComputeTask)
Construct and return a new ComputeTaskNode
with the given task.
ComputableDAGs.make_node
— Methodmake_node(t::AbstractTask)
Fallback implementation of make_node
for an AbstractTask
, throwing an error.
Base.:==
— Method==(e1::Edge, e2::Edge)
Equality comparison between two edges.
Base.:==
— Method==(n1::Node, n2::Node)
Fallback equality comparison between two nodes. For equal node types, the more specific versions of this function will be called.
Base.:==
— Method==(n1::ComputeTaskNode, n2::ComputeTaskNode)
Equality comparison between two ComputeTaskNode
s.
Base.:==
— Method==(n1::DataTaskNode, n2::DataTaskNode)
Equality comparison between two DataTaskNode
s.
ComputableDAGs.children
— Methodchildren(node::Node)
Return node's children.
A node's children are its prerequisite nodes, nodes that need to execute before the task of this node.
A node's children are the nodes that must run before it.
ComputableDAGs.is_child
— Methodis_child(potential_child::Node, node::Node)
Return whether the potential_child
is a child of node
.
ComputableDAGs.is_entry_node
— Methodis_entry_node(node::Node)
Return whether this node is an entry node in its graph, i.e., it has no children.
ComputableDAGs.is_exit_node
— Methodis_exit_node(node::Node)
Return whether this node is an exit node of its graph, i.e., it has no parents.
ComputableDAGs.is_parent
— Methodis_parent(potential_parent::Node, node::Node)
Return whether the potential_parent
is a parent of node
.
ComputableDAGs.parents
— Methodparents(node::Node)
Return the node's parents.
A node's parents are its subsequent nodes, nodes that need this node to execute.
ComputableDAGs.partners
— Methodpartners(node::Node, set::Set{Node})
Alternative version to partners(node::Node)
, avoiding allocation of a new set. Works on the given set and returns nothing
.
ComputableDAGs.partners
— Methodpartners(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.
This is very slow when there are multiple children with many parents. This is less of a problem in siblings(node::Node)
because (depending on the model) there are no nodes with a large number of children, or only a single one.
ComputableDAGs.siblings
— Methodsiblings(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.
ComputableDAGs.task
— Methodtask(node::Node)
Return the node's task.
Base.show
— Methodshow(io::IO, e::Edge)
Print a short string representation of the edge to io.
Base.show
— Methodshow(io::IO, n::Node)
Print a short string representation of the node to io.
ComputableDAGs.to_var_name
— Methodto_var_name(id::UUID)
Return the uuid as a string usable as a variable name in code generation.
ComputableDAGs.is_valid
— Methodis_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)
.
ComputableDAGs.is_valid
— Methodis_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)
.
ComputableDAGs.is_valid_node
— Methodis_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)
and is_valid(graph::DAG, node::DataTaskNode)
.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.ComputeTaskNode
— TypeComputeTaskNode <: Node
Any node that computes a result from inputs using an AbstractComputeTask
.
Fields
.task
: The node's compute task type. A concrete subtype of AbstractComputeTask
..parents
: A vector of the node's parents (i.e. nodes that depend on this one)..children
: A vector of tuples with the node's children (i.e. nodes that this one depends on) and their index, used to order the arguments for the AbstractComputeTask
..id
: The node's id. Improves the speed of comparisons and is used as a unique identifier..nodeReduction
: Either this node's NodeReduction
or missing
, if none. There can only be at most one..nodeSplit
: Either this node's NodeSplit
or missing
, if none. There can only be at most one..device
: The Device this node has been scheduled on by a Scheduler
.
ComputableDAGs.DataTaskNode
— TypeDataTaskNode <: Node
Any node that transfers data and does no computation.
Fields
.task
: The node's data task type. Usually DataTask
..parents
: A vector of the node's parents (i.e. nodes that depend on this one)..children
: A vector of tuples of the node's children (i.e. nodes that this one depends on) and their indices, indicating their order in the resulting function call passed to the task..id
: The node's id. Improves the speed of comparisons and is used as a unique identifier..nodeReduction
: Either this node's NodeReduction
or missing
, if none. There can only be at most one..nodeSplit
: Either this node's NodeSplit
or missing
, if none. There can only be at most one..name
: The name of this node for entry nodes into the graph (is_entry_node
) to reliably assign the inputs to the correct nodes when executing.
ComputableDAGs.Edge
— TypeEdge
Type of an edge in the graph. Edges can only exist between a DataTaskNode
and a ComputeTaskNode
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]
. Additionally, the Edge
contains the
index` which is used as the child's index in the parent node.
The child is the prerequisite node of the parent.
ComputableDAGs.Node
— TypeComputableDAGs.make_edge
— Functionmake_edge(n1::Node, n2::Node, index::Int)
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.
ComputableDAGs.make_edge
— Functionmake_edge(n1::DataTaskNode, n2::ComputeTaskNode)
Construct and return a new Edge
pointing from n1
(child) to n2
(parent).
The index parameter is 0 by default and is passed to the parent node as argument index for its child.
ComputableDAGs.make_edge
— Functionmake_edge(n1::ComputeTaskNode, n2::DataTaskNode, index::Int)
Construct and return a new Edge
pointing from n1
(child) to n2
(parent).
The index parameter is 0 by default and is passed to the parent node as argument index for its child.
ComputableDAGs.make_node
— Functionmake_node(t::AbstractDataTask)
Construct and return a new DataTaskNode
with the given task.
ComputableDAGs.make_node
— Methodmake_node(t::AbstractComputeTask)
Construct and return a new ComputeTaskNode
with the given task.
ComputableDAGs.make_node
— Methodmake_node(t::AbstractTask)
Fallback implementation of make_node
for an AbstractTask
, throwing an error.
Base.:==
— Method==(e1::Edge, e2::Edge)
Equality comparison between two edges.
Base.:==
— Method==(n1::Node, n2::Node)
Fallback equality comparison between two nodes. For equal node types, the more specific versions of this function will be called.
Base.:==
— Method==(n1::ComputeTaskNode, n2::ComputeTaskNode)
Equality comparison between two ComputeTaskNode
s.
Base.:==
— Method==(n1::DataTaskNode, n2::DataTaskNode)
Equality comparison between two DataTaskNode
s.
ComputableDAGs.children
— Methodchildren(node::Node)
Return node's children.
A node's children are its prerequisite nodes, nodes that need to execute before the task of this node.
A node's children are the nodes that must run before it.
ComputableDAGs.is_child
— Methodis_child(potential_child::Node, node::Node)
Return whether the potential_child
is a child of node
.
ComputableDAGs.is_entry_node
— Methodis_entry_node(node::Node)
Return whether this node is an entry node in its graph, i.e., it has no children.
ComputableDAGs.is_exit_node
— Methodis_exit_node(node::Node)
Return whether this node is an exit node of its graph, i.e., it has no parents.
ComputableDAGs.is_parent
— Methodis_parent(potential_parent::Node, node::Node)
Return whether the potential_parent
is a parent of node
.
ComputableDAGs.parents
— Methodparents(node::Node)
Return the node's parents.
A node's parents are its subsequent nodes, nodes that need this node to execute.
ComputableDAGs.partners
— Methodpartners(node::Node, set::Set{Node})
Alternative version to partners(node::Node)
, avoiding allocation of a new set. Works on the given set and returns nothing
.
ComputableDAGs.partners
— Methodpartners(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.
This is very slow when there are multiple children with many parents. This is less of a problem in siblings(node::Node)
because (depending on the model) there are no nodes with a large number of children, or only a single one.
ComputableDAGs.siblings
— Methodsiblings(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.
ComputableDAGs.task
— Methodtask(node::Node)
Return the node's task.
Base.show
— Methodshow(io::IO, e::Edge)
Print a short string representation of the edge to io.
Base.show
— Methodshow(io::IO, n::Node)
Print a short string representation of the node to io.
ComputableDAGs.to_var_name
— Methodto_var_name(id::UUID)
Return the uuid as a string usable as a variable name in code generation.
ComputableDAGs.is_valid
— Methodis_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)
.
ComputableDAGs.is_valid
— Methodis_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)
.
ComputableDAGs.is_valid_node
— Methodis_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)
and is_valid(graph::DAG, node::DataTaskNode)
.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.AppliedNodeReduction
— TypeAppliedNodeReduction <: AppliedOperation
The applied version of the NodeReduction
.
ComputableDAGs.AppliedNodeSplit
— TypeAppliedNodeSplit <: AppliedOperation
The applied version of the NodeSplit
.
ComputableDAGs.AppliedOperation
— TypeAppliedOperation
An abstract base class for already applied operations. An applied operation can be reversed iff it is the last applied operation on the DAG. Every applied operation stores a Diff
from when it was initially applied to be able to revert the operation.
See also: revert_operation!
.
ComputableDAGs.NodeReduction
— TypeNodeReduction <: Operation
The NodeReduction operation. Represents the reduction of two or more nodes with one another. Only one of the input nodes is kept, while all others are deleted and their parents are accumulated in the kept node's parents instead.
After the node reduction is applied, the graph has length(nr.input) - 1
fewer nodes.
Requirements for successful application
A vector of nodes can be reduced if:
is_valid_node_reduction_input
can be used to @assert
these requirements.
See also: can_reduce
ComputableDAGs.NodeSplit
— TypeNodeSplit <: Operation
The NodeSplit operation. Represents the split of its input node into one node for each of its parents. It is the reverse operation to the NodeReduction
.
Requirements for successful application
A node can be split if:
is_valid_node_split_input
can be used to @assert
these requirements.
See also: can_split
ComputableDAGs.Operation
— TypeOperation
An abstract base class for operations. An operation can be applied to a DAG
, changing its nodes and edges.
Possible operations on a DAG
can be retrieved using get_operations
.
See also: push_operation!
, pop_operation!
ComputableDAGs.generate_operations
— Methodgenerate_operations(graph::DAG)
Generate all possible operations on the graph. Used initially when the graph is freshly assembled or parsed. Uses multithreading for speedup.
Safely inserts all the found operations into the graph and its nodes.
ComputableDAGs.insert_operation!
— Methodinsert_operation!(nf::NodeReduction)
Insert the given node reduction into its input nodes' operation caches. This is thread-safe.
ComputableDAGs.insert_operation!
— Methodinsert_operation!(nf::NodeSplit)
Insert the given node split into its input node's operation cache. This is thread-safe.
ComputableDAGs.nr_insertion!
— Methodnr_insertion!(operations::PossibleOperations, nodeReductions::Vector{Vector{NodeReduction}})
Insert the node reductions into the graph and the nodes' caches. Employs multithreading for speedup.
ComputableDAGs.ns_insertion!
— Methodns_insertion!(operations::PossibleOperations, nodeSplits::Vector{Vector{NodeSplits}})
Insert the node splits into the graph and the nodes' caches. Employs multithreading for speedup.
ComputableDAGs.apply_all!
— Methodapply_all!(graph::DAG)
Apply all unapplied operations in the DAG. Is automatically called in all functions that require the latest state of the DAG
.
ComputableDAGs.apply_operation!
— Methodapply_operation!(graph::DAG, operation::NodeReduction)
Apply the given NodeReduction
to the graph. Generic wrapper around node_reduction!
.
Return an AppliedNodeReduction
object generated from the graph's Diff
.
ComputableDAGs.apply_operation!
— Methodapply_operation!(graph::DAG, operation::NodeSplit)
Apply the given NodeSplit
to the graph. Generic wrapper around node_split!
.
Return an AppliedNodeSplit
object generated from the graph's Diff
.
ComputableDAGs.apply_operation!
— Methodapply_operation!(graph::DAG, operation::Operation)
Fallback implementation of apply_operation! for unimplemented operation types, throwing an error.
ComputableDAGs.node_reduction!
— Methodnode_reduction!(graph::DAG, nodes::Vector{Node})
Reduce the given nodes together into one node, return the applied difference to the graph.
For details see NodeReduction
.
ComputableDAGs.node_split!
— Methodnode_split!(graph::DAG, n1::Node)
Split the given node into one node per parent, return the applied difference to the graph.
For details see NodeSplit
.
ComputableDAGs.revert_diff!
— Methodrevert_diff!(graph::DAG, diff::Diff)
Revert the given diff on the graph. Used to revert the individual AppliedOperation
s with revert_operation!
.
ComputableDAGs.revert_operation!
— Methodrevert_operation!(graph::DAG, operation::AppliedOperation)
Fallback implementation of operation reversion for unimplemented operation types, throwing an error.
ComputableDAGs.revert_operation!
— Methodrevert_operation!(graph::DAG, operation::AppliedNodeReduction)
Revert the applied node reduction on the graph. Return the original NodeReduction
operation.
ComputableDAGs.revert_operation!
— Methodrevert_operation!(graph::DAG, operation::AppliedNodeSplit)
Revert the applied node split on the graph. Return the original NodeSplit
operation.
ComputableDAGs.get_operations
— Methodget_operations(graph::DAG)
Return the PossibleOperations
of the graph at the current state.
ComputableDAGs.clean_node!
— Methodclean_node!(graph::DAG, node::Node)
Sort this node's parent and child sets, then find reductions and splits involving it. Needs to be called after the node was changed in some way.
ComputableDAGs.find_reductions!
— Methodfind_reductions!(graph::DAG, node::Node)
Find node reductions involving the given node. The function pushes the found NodeReduction
(if any) everywhere it needs to be and returns nothing.
ComputableDAGs.find_splits!
— Methodfind_splits!(graph::DAG, node::Node)
Find the node split of the given node. The function pushes the found NodeSplit
(if any) everywhere it needs to be and returns nothing.
Base.:==
— Method==(op1::NodeReduction, op2::NodeReduction)
Equality comparison between two node reductions. Two node reductions are considered equal when they have the same inputs.
Base.:==
— Method==(op1::NodeSplit, op2::NodeSplit)
Equality comparison between two node splits. Two node splits are considered equal if they have the same input node.
Base.:==
— Method==(op1::Operation, op2::Operation)
Fallback implementation of operation equality. Return false. Actual comparisons are done by the overloads of same type operation comparisons.
Base.delete!
— Methoddelete!(operations::PossibleOperations, op::NodeReduction)
Delete the given node reduction from the possible operations.
Base.delete!
— Methoddelete!(operations::PossibleOperations, op::NodeSplit)
Delete the given node split from the possible operations.
Base.isempty
— Methodisempty(operations::PossibleOperations)
Return whether operations
is empty, i.e. all of its fields are empty.
Base.length
— Methodlength(operations::PossibleOperations)
Return a named tuple with the number of each of the operation types as a named tuple. The fields are named the same as the PossibleOperations
'.
ComputableDAGs.can_reduce
— Methodcan_reduce(n1::Node, n2::Node)
Return whether the given two nodes can be reduced. See NodeReduction
for the requirements.
ComputableDAGs.can_split
— Methodcan_split(n1::Node)
Return whether the given node can be split. See NodeSplit
for the requirements.
Base.show
— Methodshow(io::IO, op::NodeReduction)
Print a string representation of the node reduction to io.
Base.show
— Methodshow(io::IO, op::NodeSplit)
Print a string representation of the node split to io.
Base.show
— Methodshow(io::IO, ops::PossibleOperations)
Print a string representation of the set of possible operations to io.
ComputableDAGs.is_valid
— Methodis_valid(graph::DAG, nr::NodeReduction)
Assert for a given NodeReduction
whether it is a valid operation in the graph.
Intended for use with @assert
or @test
.
ComputableDAGs.is_valid
— Methodis_valid(graph::DAG, nr::NodeSplit)
Assert for a given NodeSplit
whether it is a valid operation in the graph.
Intended for use with @assert
or @test
.
ComputableDAGs.is_valid_node_reduction_input
— Methodis_valid_node_reduction_input(graph::DAG, nodes::Vector{Node})
Assert for a gven node reduction input whether the nodes can be reduced. For the requirements of a node reduction see NodeReduction
.
Intended for use with @assert
or @test
.
ComputableDAGs.is_valid_node_split_input
— Methodis_valid_node_split_input(graph::DAG, n1::Node)
Assert for a gven node split input whether the node can be split. For the requirements of a node split see NodeSplit
.
Intended for use with @assert
or @test
.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.AppliedNodeReduction
— TypeAppliedNodeReduction <: AppliedOperation
The applied version of the NodeReduction
.
ComputableDAGs.AppliedNodeSplit
— TypeAppliedNodeSplit <: AppliedOperation
The applied version of the NodeSplit
.
ComputableDAGs.AppliedOperation
— TypeAppliedOperation
An abstract base class for already applied operations. An applied operation can be reversed iff it is the last applied operation on the DAG. Every applied operation stores a Diff
from when it was initially applied to be able to revert the operation.
See also: revert_operation!
.
ComputableDAGs.NodeReduction
— TypeNodeReduction <: Operation
The NodeReduction operation. Represents the reduction of two or more nodes with one another. Only one of the input nodes is kept, while all others are deleted and their parents are accumulated in the kept node's parents instead.
After the node reduction is applied, the graph has length(nr.input) - 1
fewer nodes.
Requirements for successful application
A vector of nodes can be reduced if:
is_valid_node_reduction_input
can be used to @assert
these requirements.
See also: can_reduce
ComputableDAGs.NodeSplit
— TypeNodeSplit <: Operation
The NodeSplit operation. Represents the split of its input node into one node for each of its parents. It is the reverse operation to the NodeReduction
.
Requirements for successful application
A node can be split if:
is_valid_node_split_input
can be used to @assert
these requirements.
See also: can_split
ComputableDAGs.Operation
— TypeOperation
An abstract base class for operations. An operation can be applied to a DAG
, changing its nodes and edges.
Possible operations on a DAG
can be retrieved using get_operations
.
See also: push_operation!
, pop_operation!
ComputableDAGs.generate_operations
— Methodgenerate_operations(graph::DAG)
Generate all possible operations on the graph. Used initially when the graph is freshly assembled or parsed. Uses multithreading for speedup.
Safely inserts all the found operations into the graph and its nodes.
ComputableDAGs.insert_operation!
— Methodinsert_operation!(nf::NodeReduction)
Insert the given node reduction into its input nodes' operation caches. This is thread-safe.
ComputableDAGs.insert_operation!
— Methodinsert_operation!(nf::NodeSplit)
Insert the given node split into its input node's operation cache. This is thread-safe.
ComputableDAGs.nr_insertion!
— Methodnr_insertion!(operations::PossibleOperations, nodeReductions::Vector{Vector{NodeReduction}})
Insert the node reductions into the graph and the nodes' caches. Employs multithreading for speedup.
ComputableDAGs.ns_insertion!
— Methodns_insertion!(operations::PossibleOperations, nodeSplits::Vector{Vector{NodeSplits}})
Insert the node splits into the graph and the nodes' caches. Employs multithreading for speedup.
ComputableDAGs.apply_all!
— Methodapply_all!(graph::DAG)
Apply all unapplied operations in the DAG. Is automatically called in all functions that require the latest state of the DAG
.
ComputableDAGs.apply_operation!
— Methodapply_operation!(graph::DAG, operation::NodeReduction)
Apply the given NodeReduction
to the graph. Generic wrapper around node_reduction!
.
Return an AppliedNodeReduction
object generated from the graph's Diff
.
ComputableDAGs.apply_operation!
— Methodapply_operation!(graph::DAG, operation::NodeSplit)
Apply the given NodeSplit
to the graph. Generic wrapper around node_split!
.
Return an AppliedNodeSplit
object generated from the graph's Diff
.
ComputableDAGs.apply_operation!
— Methodapply_operation!(graph::DAG, operation::Operation)
Fallback implementation of apply_operation! for unimplemented operation types, throwing an error.
ComputableDAGs.node_reduction!
— Methodnode_reduction!(graph::DAG, nodes::Vector{Node})
Reduce the given nodes together into one node, return the applied difference to the graph.
For details see NodeReduction
.
ComputableDAGs.node_split!
— Methodnode_split!(graph::DAG, n1::Node)
Split the given node into one node per parent, return the applied difference to the graph.
For details see NodeSplit
.
ComputableDAGs.revert_diff!
— Methodrevert_diff!(graph::DAG, diff::Diff)
Revert the given diff on the graph. Used to revert the individual AppliedOperation
s with revert_operation!
.
ComputableDAGs.revert_operation!
— Methodrevert_operation!(graph::DAG, operation::AppliedOperation)
Fallback implementation of operation reversion for unimplemented operation types, throwing an error.
ComputableDAGs.revert_operation!
— Methodrevert_operation!(graph::DAG, operation::AppliedNodeReduction)
Revert the applied node reduction on the graph. Return the original NodeReduction
operation.
ComputableDAGs.revert_operation!
— Methodrevert_operation!(graph::DAG, operation::AppliedNodeSplit)
Revert the applied node split on the graph. Return the original NodeSplit
operation.
ComputableDAGs.get_operations
— Methodget_operations(graph::DAG)
Return the PossibleOperations
of the graph at the current state.
ComputableDAGs.clean_node!
— Methodclean_node!(graph::DAG, node::Node)
Sort this node's parent and child sets, then find reductions and splits involving it. Needs to be called after the node was changed in some way.
ComputableDAGs.find_reductions!
— Methodfind_reductions!(graph::DAG, node::Node)
Find node reductions involving the given node. The function pushes the found NodeReduction
(if any) everywhere it needs to be and returns nothing.
ComputableDAGs.find_splits!
— Methodfind_splits!(graph::DAG, node::Node)
Find the node split of the given node. The function pushes the found NodeSplit
(if any) everywhere it needs to be and returns nothing.
Base.:==
— Method==(op1::NodeReduction, op2::NodeReduction)
Equality comparison between two node reductions. Two node reductions are considered equal when they have the same inputs.
Base.:==
— Method==(op1::NodeSplit, op2::NodeSplit)
Equality comparison between two node splits. Two node splits are considered equal if they have the same input node.
Base.:==
— Method==(op1::Operation, op2::Operation)
Fallback implementation of operation equality. Return false. Actual comparisons are done by the overloads of same type operation comparisons.
Base.delete!
— Methoddelete!(operations::PossibleOperations, op::NodeReduction)
Delete the given node reduction from the possible operations.
Base.delete!
— Methoddelete!(operations::PossibleOperations, op::NodeSplit)
Delete the given node split from the possible operations.
Base.isempty
— Methodisempty(operations::PossibleOperations)
Return whether operations
is empty, i.e. all of its fields are empty.
Base.length
— Methodlength(operations::PossibleOperations)
Return a named tuple with the number of each of the operation types as a named tuple. The fields are named the same as the PossibleOperations
'.
ComputableDAGs.can_reduce
— Methodcan_reduce(n1::Node, n2::Node)
Return whether the given two nodes can be reduced. See NodeReduction
for the requirements.
ComputableDAGs.can_split
— Methodcan_split(n1::Node)
Return whether the given node can be split. See NodeSplit
for the requirements.
Base.show
— Methodshow(io::IO, op::NodeReduction)
Print a string representation of the node reduction to io.
Base.show
— Methodshow(io::IO, op::NodeSplit)
Print a string representation of the node split to io.
Base.show
— Methodshow(io::IO, ops::PossibleOperations)
Print a string representation of the set of possible operations to io.
ComputableDAGs.is_valid
— Methodis_valid(graph::DAG, nr::NodeReduction)
Assert for a given NodeReduction
whether it is a valid operation in the graph.
Intended for use with @assert
or @test
.
ComputableDAGs.is_valid
— Methodis_valid(graph::DAG, nr::NodeSplit)
Assert for a given NodeSplit
whether it is a valid operation in the graph.
Intended for use with @assert
or @test
.
ComputableDAGs.is_valid_node_reduction_input
— Methodis_valid_node_reduction_input(graph::DAG, nodes::Vector{Node})
Assert for a gven node reduction input whether the nodes can be reduced. For the requirements of a node reduction see NodeReduction
.
Intended for use with @assert
or @test
.
ComputableDAGs.is_valid_node_split_input
— Methodis_valid_node_split_input(graph::DAG, n1::Node)
Assert for a gven node split input whether the node can be split. For the requirements of a node split see NodeSplit
.
Intended for use with @assert
or @test
.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
The interface that has to be implemented for an optimization algorithm.
ComputableDAGs.AbstractOptimizer
— TypeAbstractOptimizer
Abstract base type for optimizer implementations.
ComputableDAGs.fixpoint_reached
— Methodfixpoint_reached(optimizer::AbstractOptimizer, graph::DAG)
Interface function that can be implemented by optimization algorithms that can reach a fixpoint, returning as a Bool
whether it has been reached. The default implementation returns false
.
See also: optimize_to_fixpoint!
ComputableDAGs.optimize!
— Methodoptimize!(optimizer::AbstractOptimizer, graph::DAG, n::Int)
Function calling the given optimizer n
times, muting the graph. Returns true
if the requested number of operations has been applied, false
if not, usually when a fixpoint of the algorithm has been reached.
If a more efficient method exists, this can be overloaded for a specific optimizer.
ComputableDAGs.optimize_step!
— Functionoptimize_step!(optimizer::AbstractOptimizer, graph::DAG)
Interface function that must be implemented by implementations of AbstractOptimizer
. Returns true
if an operations has been applied, false
if not, usually when a fixpoint of the algorithm has been reached.
It should do one smallest logical step on the given DAG
, muting the graph and, if necessary, the optimizer's state.
ComputableDAGs.optimize_to_fixpoint!
— Functionoptimize_to_fixpoint!(optimizer::AbstractOptimizer, graph::DAG)
Interface function that can be implemented by optimization algorithms that can reach a fixpoint. The algorithm will be run until that fixpoint is reached, at which point fixpoint_reached
should return true.
A usual implementation might look like this:
function optimize_to_fixpoint!(optimizer::MyOptimizer, graph::DAG)
+Optimization · ComputableDAGs.jl Optimization
Interface
The interface that has to be implemented for an optimization algorithm.
ComputableDAGs.AbstractOptimizer
— TypeAbstractOptimizer
Abstract base type for optimizer implementations.
sourceComputableDAGs.fixpoint_reached
— Methodfixpoint_reached(optimizer::AbstractOptimizer, graph::DAG)
Interface function that can be implemented by optimization algorithms that can reach a fixpoint, returning as a Bool
whether it has been reached. The default implementation returns false
.
See also: optimize_to_fixpoint!
sourceComputableDAGs.optimize!
— Methodoptimize!(optimizer::AbstractOptimizer, graph::DAG, n::Int)
Function calling the given optimizer n
times, muting the graph. Returns true
if the requested number of operations has been applied, false
if not, usually when a fixpoint of the algorithm has been reached.
If a more efficient method exists, this can be overloaded for a specific optimizer.
sourceComputableDAGs.optimize_step!
— Functionoptimize_step!(optimizer::AbstractOptimizer, graph::DAG)
Interface function that must be implemented by implementations of AbstractOptimizer
. Returns true
if an operations has been applied, false
if not, usually when a fixpoint of the algorithm has been reached.
It should do one smallest logical step on the given DAG
, muting the graph and, if necessary, the optimizer's state.
sourceComputableDAGs.optimize_to_fixpoint!
— Functionoptimize_to_fixpoint!(optimizer::AbstractOptimizer, graph::DAG)
Interface function that can be implemented by optimization algorithms that can reach a fixpoint. The algorithm will be run until that fixpoint is reached, at which point fixpoint_reached
should return true.
A usual implementation might look like this:
function optimize_to_fixpoint!(optimizer::MyOptimizer, graph::DAG)
while !fixpoint_reached(optimizer, graph)
optimize_step!(optimizer, graph)
end
return nothing
- end
sourceRandom Walk Optimizer
Implementation of a random walk algorithm.
ComputableDAGs.RandomWalkOptimizer
— TypeRandomWalkOptimizer
An optimizer that randomly pushes or pops operations. It doesn't optimize in any direction and is useful mainly for testing purposes.
This algorithm never reaches a fixpoint, so it does not implement optimize_to_fixpoint!
.
sourceReduction Optimizer
Implementation of a an optimizer that reduces as far as possible.
ComputableDAGs.ReductionOptimizer
— TypeReductionOptimizer
An optimizer that simply applies an available NodeReduction
on each step. It implements optimize_to_fixpoint!
. The fixpoint is reached when there are no more possible NodeReduction
s in the graph.
See also: SplitOptimizer
sourceSplit Optimizer
Implementation of an optimizer that splits as far as possible.
ComputableDAGs.SplitOptimizer
— TypeSplitOptimizer
An optimizer that simply applies an available NodeSplit
on each step. It implements optimize_to_fixpoint!
. The fixpoint is reached when there are no more possible NodeSplit
s in the graph.
See also: ReductionOptimizer
sourceGreedy Optimizer
Implementation of a greedy optimization algorithm.
ComputableDAGs.GreedyOptimizer
— TypeGreedyOptimizer
An implementation of the greedy optimization algorithm, simply choosing the best next option evaluated with the given estimator.
The fixpoint is reached when any leftover operation would increase the graph's total cost according to the given estimator.
sourceSettings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
+ end
Implementation of a random walk algorithm.
ComputableDAGs.RandomWalkOptimizer
— TypeRandomWalkOptimizer
An optimizer that randomly pushes or pops operations. It doesn't optimize in any direction and is useful mainly for testing purposes.
This algorithm never reaches a fixpoint, so it does not implement optimize_to_fixpoint!
.
Implementation of a an optimizer that reduces as far as possible.
ComputableDAGs.ReductionOptimizer
— TypeReductionOptimizer
An optimizer that simply applies an available NodeReduction
on each step. It implements optimize_to_fixpoint!
. The fixpoint is reached when there are no more possible NodeReduction
s in the graph.
See also: SplitOptimizer
Implementation of an optimizer that splits as far as possible.
ComputableDAGs.SplitOptimizer
— TypeSplitOptimizer
An optimizer that simply applies an available NodeSplit
on each step. It implements optimize_to_fixpoint!
. The fixpoint is reached when there are no more possible NodeSplit
s in the graph.
See also: ReductionOptimizer
Implementation of a greedy optimization algorithm.
ComputableDAGs.GreedyOptimizer
— TypeGreedyOptimizer
An implementation of the greedy optimization algorithm, simply choosing the best next option evaluated with the given estimator.
The fixpoint is reached when any leftover operation would increase the graph's total cost according to the given estimator.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.GraphProperties
— TypeGraphProperties
Representation of a DAG
's properties.
Fields:
.data
: The total data transfer..computeEffort
: The total compute effort..computeIntensity
: The compute intensity, will always equal .computeEffort / .data
..noNodes
: Number of Node
s..noEdges
: Number of Edge
s.
Base.:+
— Method+(prop1::GraphProperties, prop2::GraphProperties)
Add prop1
and prop2
and return the result as a new GraphProperties
. Also take care to keep consistent compute intensity.
Base.:-
— Method-(prop1::GraphProperties, prop2::GraphProperties)
Subtract prop1
from prop2
and return the result as a new GraphProperties
. Also take care to keep consistent compute intensity.
Base.:-
— Method-(prop::GraphProperties)
Unary negation of the graph properties. .computeIntensity
will not be negated because .data
and .computeEffort
both are.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.GraphProperties
— TypeGraphProperties
Representation of a DAG
's properties.
Fields:
.data
: The total data transfer..computeEffort
: The total compute effort..computeIntensity
: The compute intensity, will always equal .computeEffort / .data
..noNodes
: Number of Node
s..noEdges
: Number of Edge
s.
Base.:+
— Method+(prop1::GraphProperties, prop2::GraphProperties)
Add prop1
and prop2
and return the result as a new GraphProperties
. Also take care to keep consistent compute intensity.
Base.:-
— Method-(prop1::GraphProperties, prop2::GraphProperties)
Subtract prop1
from prop2
and return the result as a new GraphProperties
. Also take care to keep consistent compute intensity.
Base.:-
— Method-(prop::GraphProperties)
Unary negation of the graph properties. .computeIntensity
will not be negated because .data
and .computeEffort
both are.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.AbstractScheduler
— TypeAbstractScheduler
Abstract base type for scheduler implementations. The scheduler is used to assign each node to a device and create a topological ordering of tasks.
ComputableDAGs.schedule_dag
— Functionschedule_dag(::Scheduler, ::DAG, ::Machine)
Interface functions that must be implemented for implementations of Scheduler
.
The function assigns each ComputeTaskNode
of the DAG
to one of the devices in the given Machine
and returns a Vector{Node}
representing a topological ordering.
DataTaskNode
s are not scheduled to devices since they do not compute. Instead, a data node transfers data from the AbstractDevice
of their child to all AbstractDevice
s of its parents.
The produced schedule can be converted to FunctionCall
s using lower
.
ComputableDAGs.FunctionCall
— TypeFunctionCall{N}
Type representing a function call with N
parameters. Contains the function to call, argument symbols, the return symbol and the device to execute on.
ComputableDAGs.GreedyScheduler
— TypeGreedyScheduler
A greedy implementation of a scheduler, creating a topological ordering of nodes and naively balancing them onto the different devices.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.AbstractScheduler
— TypeAbstractScheduler
Abstract base type for scheduler implementations. The scheduler is used to assign each node to a device and create a topological ordering of tasks.
ComputableDAGs.schedule_dag
— Functionschedule_dag(::Scheduler, ::DAG, ::Machine)
Interface functions that must be implemented for implementations of Scheduler
.
The function assigns each ComputeTaskNode
of the DAG
to one of the devices in the given Machine
and returns a Vector{Node}
representing a topological ordering.
DataTaskNode
s are not scheduled to devices since they do not compute. Instead, a data node transfers data from the AbstractDevice
of their child to all AbstractDevice
s of its parents.
The produced schedule can be converted to FunctionCall
s using lower
.
ComputableDAGs.FunctionCall
— TypeFunctionCall{N}
Type representing a function call with N
parameters. Contains the function to call, argument symbols, the return symbol and the device to execute on.
ComputableDAGs.GreedyScheduler
— TypeGreedyScheduler
A greedy implementation of a scheduler, creating a topological ordering of nodes and naively balancing them onto the different devices.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.AbstractComputeTask
— TypeAbstractComputeTask <: AbstractTask
The shared base type for any compute task.
ComputableDAGs.AbstractDataTask
— TypeAbstractDataTask <: AbstractTask
The shared base type for any data task.
ComputableDAGs.AbstractTask
— TypeAbstractTask
The shared base type for any task.
ComputableDAGs.DataTask
— TypeDataTask <: AbstractDataTask
Task representing a specific data transfer.
Base.copy
— Methodcopy(t::AbstractComputeTask)
Return a copy of the given compute task.
Base.copy
— Methodcopy(t::AbstractDataTask)
Fallback implementation of the copy of an abstract data task, throwing an error.
Base.:==
— Method==(t1::AbstractComputeTask, t2::AbstractComputeTask)
Equality comparison between two compute tasks.
Base.:==
— Method==(t1::AbstractDataTask, t2::AbstractDataTask)
Equality comparison between two data tasks.
Base.:==
— Method==(t1::AbstractTask, t2::AbstractTask)
Fallback implementation of equality comparison between two abstract tasks. Always returns false. For equal specific types of t1 and t2, a more specific comparison is called instead, doing an actual comparison.
ComputableDAGs.get_function_call
— Methodget_function_call(n::Node)
-get_function_call(t::AbstractTask, device::AbstractDevice, in_symbols::AbstractVector, out_symbol::Symbol)
For a node or a task together with necessary information, return a vector of FunctionCall
s for the computation of the node or task.
For ordinary compute or data tasks the vector will contain exactly one element.
Base.copy
— Methodcopy(t::DataTask)
Copy the data task and return it.
ComputableDAGs.children
— Methodchildren(::DataTask)
Return the number of children of a data task (always 1).
ComputableDAGs.compute
— Functioncompute(t::AbstractTask; data...)
Fallback implementation of the compute function of a compute task, throwing an error.
ComputableDAGs.compute_effort
— Functioncompute_effort(t::AbstractTask)
Fallback implementation of the compute effort of a task, throwing an error.
ComputableDAGs.compute_effort
— Methodcompute_effort(t::AbstractDataTask)
Return the compute effort of a data task, always zero, regardless of the specific task.
ComputableDAGs.data
— Functiondata(t::AbstractTask)
Fallback implementation of the data of a task, throwing an error.
ComputableDAGs.data
— Methoddata(t::AbstractComputeTask)
Return the data of a compute task, always zero, regardless of the specific task.
ComputableDAGs.data
— Methoddata(t::AbstractDataTask)
Return the data of a data task. Given by the task's .data
field.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs.AbstractComputeTask
— TypeAbstractComputeTask <: AbstractTask
The shared base type for any compute task.
ComputableDAGs.AbstractDataTask
— TypeAbstractDataTask <: AbstractTask
The shared base type for any data task.
ComputableDAGs.AbstractTask
— TypeAbstractTask
The shared base type for any task.
ComputableDAGs.DataTask
— TypeDataTask <: AbstractDataTask
Task representing a specific data transfer.
Base.copy
— Methodcopy(t::AbstractComputeTask)
Return a copy of the given compute task.
Base.copy
— Methodcopy(t::AbstractDataTask)
Fallback implementation of the copy of an abstract data task, throwing an error.
Base.:==
— Method==(t1::AbstractComputeTask, t2::AbstractComputeTask)
Equality comparison between two compute tasks.
Base.:==
— Method==(t1::AbstractDataTask, t2::AbstractDataTask)
Equality comparison between two data tasks.
Base.:==
— Method==(t1::AbstractTask, t2::AbstractTask)
Fallback implementation of equality comparison between two abstract tasks. Always returns false. For equal specific types of t1 and t2, a more specific comparison is called instead, doing an actual comparison.
ComputableDAGs.get_function_call
— Methodget_function_call(n::Node)
+get_function_call(t::AbstractTask, device::AbstractDevice, in_symbols::AbstractVector, out_symbol::Symbol)
For a node or a task together with necessary information, return a vector of FunctionCall
s for the computation of the node or task.
For ordinary compute or data tasks the vector will contain exactly one element.
Base.copy
— Methodcopy(t::DataTask)
Copy the data task and return it.
ComputableDAGs.children
— Methodchildren(::DataTask)
Return the number of children of a data task (always 1).
ComputableDAGs.compute
— Functioncompute(t::AbstractTask; data...)
Fallback implementation of the compute function of a compute task, throwing an error.
ComputableDAGs.compute_effort
— Functioncompute_effort(t::AbstractTask)
Fallback implementation of the compute effort of a task, throwing an error.
ComputableDAGs.compute_effort
— Methodcompute_effort(t::AbstractDataTask)
Return the compute effort of a data task, always zero, regardless of the specific task.
ComputableDAGs.data
— Functiondata(t::AbstractTask)
Fallback implementation of the data of a task, throwing an error.
ComputableDAGs.data
— Methoddata(t::AbstractComputeTask)
Return the data of a compute task, always zero, regardless of the specific task.
ComputableDAGs.data
— Methoddata(t::AbstractDataTask)
Return the data of a data task. Given by the task's .data
field.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
ComputableDAGs._lt_node_tuples
— Method_lt_node_tuples(n1::Tuple{Node, Int}, n2::Tuple{Node, Int})
Less-Than comparison between nodes with indices.
ComputableDAGs._lt_nodes
— Method_lt_nodes(n1::Node, n2::Node)
Less-Than comparison between nodes. Uses the nodes' ids to sort.
ComputableDAGs.bytes_to_human_readable
— Methodbytes_to_human_readable(bytes)
Return a human readable string representation of the given number.
julia> using ComputableDAGs
+Utility · ComputableDAGs.jl Utility
Helper Functions
ComputableDAGs._lt_node_tuples
— Method_lt_node_tuples(n1::Tuple{Node, Int}, n2::Tuple{Node, Int})
Less-Than comparison between nodes with indices.
sourceComputableDAGs._lt_nodes
— Method_lt_nodes(n1::Node, n2::Node)
Less-Than comparison between nodes. Uses the nodes' ids to sort.
sourceComputableDAGs.bytes_to_human_readable
— Methodbytes_to_human_readable(bytes)
Return a human readable string representation of the given number.
julia> using ComputableDAGs
julia> ComputableDAGs.bytes_to_human_readable(4096)
-"4.0 KiB"
sourceComputableDAGs.infer_types!
— Methodinfer_types!(schedule::Vector{FunctionCall})
Infer the result type of each function call in the given schedule. Returns a dictionary with the result type for each Node
. This assumes that each node has only one statically inferrable return type and will throw an exceptin otherwise. This also assumes that the given Vector
contains a topological ordering of its nodes, such as returned by a call to schedule_dag
.
sourceComputableDAGs.lower
— Methodlower(schedule::Vector{Node}, machine::Machine)
After schedule_dag
has made a schedule of nodes, this function lowers the vector of Node
s into a vector of FunctionCall
s.
sourceComputableDAGs.mem
— Methodmem(graph::DAG)
Return the memory footprint of the graph in Byte. Should be the same result as Base.summarysize(graph)
but a lot faster.
sourceComputableDAGs.mem
— Methodmem(op::Operation)
Return the memory footprint of the node in Byte. Used in mem(graph::DAG)
. Unlike Base.summarysize()
this doesn't follow all references which would yield (almost) the size of the entire graph.
sourceComputableDAGs.mem
— Methodmem(op::Operation)
Return the memory footprint of the operation in Byte. Used in mem(graph::DAG)
. Unlike Base.summarysize()
this doesn't follow all references which would yield (almost) the size of the entire graph.
sourceComputableDAGs.noop
— Methodnoop()
Function with no arguments, returns nothing, does nothing. Useful for noop FunctionCall
s.
sourceComputableDAGs.sort_node!
— Methodsort_node!(node::Node)
Sort the nodes' parents and children vectors. The vectors are mostly very short so sorting does not take a lot of time. Sorted nodes are required to make the finding of NodeReduction
s a lot faster using the NodeTrie
data structure.
sourceComputableDAGs.unpack_identity
— Methodunpack_identity(x::SVector)
Function taking an SVector
, returning it unpacked.
sourceComputableDAGs.unroll_symbol_vector
— Methodunroll_symbol_vector(vec::Vector{Symbol})
Return the given vector as single String without quotation marks or brackets.
sourceTrie Helper
This is a simple implementation of a Trie Data Structure to greatly improve the performance of the Node Reduction search.
ComputableDAGs.NodeIdTrie
— TypeNodeIdTrie
Helper struct for NodeTrie
. After the Trie's first level, every Trie level contains the vector of nodes that had children up to that level, and the TrieNode's children by UUID of the node's children.
sourceComputableDAGs.NodeIdTrie
— MethodNodeIdTrie()
Constructor for an empty NodeIdTrie
.
sourceComputableDAGs.NodeTrie
— TypeNodeTrie
Trie data structure for node reduction, inserts nodes by children. Assumes that given nodes have ordered vectors of children (see sort_node!
). First insertion level is the node's own task type and thus does not have a value (every node has a task type).
sourceComputableDAGs.NodeTrie
— MethodNodeTrie()
Constructor for an empty NodeTrie
.
sourceBase.collect
— Methodcollect(trie::NodeTrie)
Return all sets of at least 2 Node
s that have accumulated in leaves of the trie.
sourceBase.insert!
— Methodinsert!(trie::NodeTrie, node::Node)
Insert the given node into the trie. It's sorted by its type in the first layer, then by its children in the following layers.
sourceComputableDAGs.collect_helper
— Methodcollect_helper(trie::NodeIdTrie, acc::Set{Vector{Node}})
Collects the Vectors of this NodeIdTrie
node and all its children and puts them in the acc
argument.
sourceComputableDAGs.insert_helper!
— Methodinsert_helper!(trie::NodeIdTrie, node::Node, depth::Int)
Insert the given node into the trie. The depth is used to iterate through the trie layers, while the function calls itself recursively until it ran through all children of the node.
sourceSettings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
+"4.0 KiB"
ComputableDAGs.infer_types!
— Methodinfer_types!(schedule::Vector{FunctionCall})
Infer the result type of each function call in the given schedule. Returns a dictionary with the result type for each Node
. This assumes that each node has only one statically inferrable return type and will throw an exceptin otherwise. This also assumes that the given Vector
contains a topological ordering of its nodes, such as returned by a call to schedule_dag
.
ComputableDAGs.lower
— Methodlower(schedule::Vector{Node}, machine::Machine)
After schedule_dag
has made a schedule of nodes, this function lowers the vector of Node
s into a vector of FunctionCall
s.
ComputableDAGs.mem
— Methodmem(graph::DAG)
Return the memory footprint of the graph in Byte. Should be the same result as Base.summarysize(graph)
but a lot faster.
ComputableDAGs.mem
— Methodmem(op::Operation)
Return the memory footprint of the node in Byte. Used in mem(graph::DAG)
. Unlike Base.summarysize()
this doesn't follow all references which would yield (almost) the size of the entire graph.
ComputableDAGs.mem
— Methodmem(op::Operation)
Return the memory footprint of the operation in Byte. Used in mem(graph::DAG)
. Unlike Base.summarysize()
this doesn't follow all references which would yield (almost) the size of the entire graph.
ComputableDAGs.noop
— Methodnoop()
Function with no arguments, returns nothing, does nothing. Useful for noop FunctionCall
s.
ComputableDAGs.sort_node!
— Methodsort_node!(node::Node)
Sort the nodes' parents and children vectors. The vectors are mostly very short so sorting does not take a lot of time. Sorted nodes are required to make the finding of NodeReduction
s a lot faster using the NodeTrie
data structure.
ComputableDAGs.unpack_identity
— Methodunpack_identity(x::SVector)
Function taking an SVector
, returning it unpacked.
ComputableDAGs.unroll_symbol_vector
— Methodunroll_symbol_vector(vec::Vector{Symbol})
Return the given vector as single String without quotation marks or brackets.
This is a simple implementation of a Trie Data Structure to greatly improve the performance of the Node Reduction search.
ComputableDAGs.NodeIdTrie
— TypeNodeIdTrie
Helper struct for NodeTrie
. After the Trie's first level, every Trie level contains the vector of nodes that had children up to that level, and the TrieNode's children by UUID of the node's children.
ComputableDAGs.NodeIdTrie
— MethodNodeIdTrie()
Constructor for an empty NodeIdTrie
.
ComputableDAGs.NodeTrie
— TypeNodeTrie
Trie data structure for node reduction, inserts nodes by children. Assumes that given nodes have ordered vectors of children (see sort_node!
). First insertion level is the node's own task type and thus does not have a value (every node has a task type).
ComputableDAGs.NodeTrie
— MethodNodeTrie()
Constructor for an empty NodeTrie
.
Base.collect
— Methodcollect(trie::NodeTrie)
Return all sets of at least 2 Node
s that have accumulated in leaves of the trie.
Base.insert!
— Methodinsert!(trie::NodeTrie, node::Node)
Insert the given node into the trie. It's sorted by its type in the first layer, then by its children in the following layers.
ComputableDAGs.collect_helper
— Methodcollect_helper(trie::NodeIdTrie, acc::Set{Vector{Node}})
Collects the Vectors of this NodeIdTrie
node and all its children and puts them in the acc
argument.
ComputableDAGs.insert_helper!
— Methodinsert_helper!(trie::NodeIdTrie, node::Node, depth::Int)
Insert the given node into the trie. The depth is used to iterate through the trie layers, while the function calls itself recursively until it ran through all children of the node.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
Documentation for ComputableDAGs.jl
's public interface.
See the Internals section of the manual for documentation of everything else.
ComputableDAGs.ComputableDAGs
— ModuleComputableDAGs
A module containing tools to represent computations as DAGs.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
Documentation for ComputableDAGs.jl
's public interface.
See the Internals section of the manual for documentation of everything else.
ComputableDAGs.ComputableDAGs
— ModuleComputableDAGs
A module containing tools to represent computations as DAGs.
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
The following repositories use this package productively, which can be referred to as examples:
In the notebooks
directory are notebooks containing some examples of the usage of this repository.
TBW
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.
The following repositories use this package productively, which can be referred to as examples:
In the notebooks
directory are notebooks containing some examples of the usage of this repository.
TBW
Settings
This document was generated with Documenter.jl version 1.7.0 on Thursday 7 November 2024. Using Julia version 1.10.6.