Tape Machine (#30)

Adds a tape machine way of executing the code.
The tape machine is a series of FunctionCall objects, which can either be called one by one, or be used to generate expressions to make up a function.

Reviewed-on: Rubydragon/MetagraphOptimization.jl#30
Co-authored-by: Anton Reinhard <anton.reinhard@proton.me>
Co-committed-by: Anton Reinhard <anton.reinhard@proton.me>
This commit is contained in:
2024-01-03 16:38:32 +01:00
committed by Anton Reinhard
parent 92e0eeaaef
commit 82ed774b7e
21 changed files with 398 additions and 502 deletions

View File

@@ -76,91 +76,17 @@ function compute(::ComputeTaskABC_S1, data::ABCParticleValue{P})::ABCParticleVal
end
"""
compute(::ComputeTaskABC_Sum, data::StaticVector)
compute(::ComputeTaskABC_Sum, data...)
compute(::ComputeTaskABC_Sum, data::AbstractArray)
Compute a sum over the vector. Use an algorithm that accounts for accumulated errors in long sums with potentially large differences in magnitude of the summands.
Linearly many FLOP with growing data.
"""
function compute(::ComputeTaskABC_Sum, data::StaticVector)::Float64
function compute(::ComputeTaskABC_Sum, data...)::Float64
return sum(data)
end
"""
get_expression(::ComputeTaskABC_P, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate and return code evaluating [`ComputeTaskABC_P`](@ref) on `inSyms`, providing the output on `outSym`.
"""
function get_expression(::ComputeTaskABC_P, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskABC_P(), $(in[1]))")
end
"""
get_expression(::ComputeTaskABC_U, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskABC_U`](@ref) on `inSyms`, providing the output on `outSym`.
`inSyms` should be of type [`ABCParticleValue`](@ref), `outSym` will be of type [`ABCParticleValue`](@ref).
"""
function get_expression(::ComputeTaskABC_U, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskABC_U(), $(in[1]))")
end
"""
get_expression(::ComputeTaskABC_V, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskABC_V`](@ref) on `inSyms`, providing the output on `outSym`.
`inSym[1]` and `inSym[2]` should be of type [`ABCParticleValue`](@ref), `outSym` will be of type [`ABCParticleValue`](@ref).
"""
function get_expression(::ComputeTaskABC_V, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1]), eval(inExprs[2])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskABC_V(), $(in[1]), $(in[2]))")
end
"""
get_expression(::ComputeTaskABC_S2, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskABC_S2`](@ref) on `inSyms`, providing the output on `outSym`.
`inSyms[1]` and `inSyms[2]` should be of type [`ABCParticleValue`](@ref), `outSym` will be of type `Float64`.
"""
function get_expression(::ComputeTaskABC_S2, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1]), eval(inExprs[2])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskABC_S2(), $(in[1]), $(in[2]))")
end
"""
get_expression(::ComputeTaskABC_S1, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskABC_S1`](@ref) on `inSyms`, providing the output on `outSym`.
`inSyms` should be of type [`ABCParticleValue`](@ref), `outSym` will be of type [`ABCParticleValue`](@ref).
"""
function get_expression(::ComputeTaskABC_S1, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskABC_S1(), $(in[1]))")
end
"""
get_expression(::ComputeTaskABC_Sum, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskABC_Sum`](@ref) on `inSyms`, providing the output on `outSym`.
`inSyms` should be of type [`Float64`], `outSym` will be of type [`Float64`].
"""
function get_expression(::ComputeTaskABC_Sum, device::AbstractDevice, inExprs::Vector, outExpr)
in = eval.(inExprs)
out = eval(outExpr)
return Meta.parse(
"$out = compute(ComputeTaskABC_Sum(), SVector{$(length(inExprs)), Float64}($(unroll_symbol_vector(in))))",
)
function compute(::ComputeTaskABC_Sum, data::AbstractArray)::Float64
return sum(data)
end

View File

@@ -43,48 +43,6 @@ this doesn't matter.
"""
compute_effort(t::ComputeTaskABC_Sum)::Float64 = 1.0
"""
show(io::IO, t::ComputeTaskABC_S1)
Print the S1 task to io.
"""
show(io::IO, t::ComputeTaskABC_S1) = print(io, "ComputeS1")
"""
show(io::IO, t::ComputeTaskABC_S2)
Print the S2 task to io.
"""
show(io::IO, t::ComputeTaskABC_S2) = print(io, "ComputeS2")
"""
show(io::IO, t::ComputeTaskABC_P)
Print the P task to io.
"""
show(io::IO, t::ComputeTaskABC_P) = print(io, "ComputeP")
"""
show(io::IO, t::ComputeTaskABC_U)
Print the U task to io.
"""
show(io::IO, t::ComputeTaskABC_U) = print(io, "ComputeU")
"""
show(io::IO, t::ComputeTaskABC_V)
Print the V task to io.
"""
show(io::IO, t::ComputeTaskABC_V) = print(io, "ComputeV")
"""
show(io::IO, t::ComputeTaskABC_Sum)
Print the sum task to io.
"""
show(io::IO, t::ComputeTaskABC_Sum) = print(io, "ComputeSum")
"""
children(::ComputeTaskABC_S1)

View File

@@ -106,92 +106,19 @@ function compute(::ComputeTaskQED_S1, data::QEDParticleValue{P}) where {P <: QED
end
"""
compute(::ComputeTaskQED_Sum, data::StaticVector)
compute(::ComputeTaskQED_Sum, data...)
compute(::ComputeTaskQED_Sum, data::AbstractArray)
Compute a sum over the vector. Use an algorithm that accounts for accumulated errors in long sums with potentially large differences in magnitude of the summands.
Linearly many FLOP with growing data.
"""
function compute(::ComputeTaskQED_Sum, data::StaticVector)::ComplexF64
function compute(::ComputeTaskQED_Sum, data...)::ComplexF64
# TODO: want to use sum_kbn here but it doesn't seem to support ComplexF64, do it element-wise?
return sum(data)
end
"""
get_expression(::ComputeTaskQED_P, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate and return code evaluating [`ComputeTaskQED_P`](@ref) on `inSyms`, providing the output on `outSym`.
"""
function get_expression(::ComputeTaskQED_P, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskQED_P(), $(in[1]))")
end
"""
get_expression(::ComputeTaskQED_U, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskQED_U`](@ref) on `inSyms`, providing the output on `outSym`.
`inSyms` should be of type [`QEDParticleValue`](@ref), `outSym` will be of type [`QEDParticleValue`](@ref).
"""
function get_expression(::ComputeTaskQED_U, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskQED_U(), $(in[1]))")
end
"""
get_expression(::ComputeTaskQED_V, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskQED_V`](@ref) on `inSyms`, providing the output on `outSym`.
`inSym[1]` and `inSym[2]` should be of type [`QEDParticleValue`](@ref), `outSym` will be of type [`QEDParticleValue`](@ref).
"""
function get_expression(::ComputeTaskQED_V, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1]), eval(inExprs[2])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskQED_V(), $(in[1]), $(in[2]))")
end
"""
get_expression(::ComputeTaskQED_S2, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskQED_S2`](@ref) on `inSyms`, providing the output on `outSym`.
`inSyms[1]` and `inSyms[2]` should be of type [`QEDParticleValue`](@ref), `outSym` will be of type `Float64`.
"""
function get_expression(::ComputeTaskQED_S2, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1]), eval(inExprs[2])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskQED_S2(), $(in[1]), $(in[2]))")
end
"""
get_expression(::ComputeTaskQED_S1, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskQED_S1`](@ref) on `inSyms`, providing the output on `outSym`.
`inSyms` should be of type [`QEDParticleValue`](@ref), `outSym` will be of type [`QEDParticleValue`](@ref).
"""
function get_expression(::ComputeTaskQED_S1, device::AbstractDevice, inExprs::Vector, outExpr)
in = [eval(inExprs[1])]
out = eval(outExpr)
return Meta.parse("$out = compute(ComputeTaskQED_S1(), $(in[1]))")
end
"""
get_expression(::ComputeTaskQED_Sum, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
Generate code evaluating [`ComputeTaskQED_Sum`](@ref) on `inSyms`, providing the output on `outSym`.
`inSyms` should be of type [`Float64`], `outSym` will be of type [`Float64`].
"""
function get_expression(::ComputeTaskQED_Sum, device::AbstractDevice, inExprs::Vector, outExpr)
in = eval.(inExprs)
out = eval(outExpr)
return Meta.parse(
"$out = compute(ComputeTaskQED_Sum(), SVector{$(length(inExprs)), ComplexF64}($(unroll_symbol_vector(in))))",
)
function compute(::ComputeTaskQED_Sum, data::AbstractArray)::ComplexF64
# TODO: want to use sum_kbn here but it doesn't seem to support ComplexF64, do it element-wise?
return sum(data)
end

View File

@@ -170,6 +170,12 @@ end
String(::Type{Incoming}) = "Incoming"
String(::Type{Outgoing}) = "Outgoing"
String(::Type{PolX}) = "polx"
String(::Type{PolY}) = "poly"
String(::Type{SpinUp}) = "spinup"
String(::Type{SpinDown}) = "spindown"
String(::Incoming) = "i"
String(::Outgoing) = "o"
@@ -183,6 +189,16 @@ function String(::Type{<:AntiFermionStateful})
return "p"
end
function unique_name(::Type{PhotonStateful{Dir, Pol}}) where {Dir, Pol}
return String(PhotonStateful) * String(Dir) * String(Pol)
end
function unique_name(::Type{FermionStateful{Dir, Spin}}) where {Dir, Spin}
return String(FermionStateful) * String(Dir) * String(Spin)
end
function unique_name(::Type{AntiFermionStateful{Dir, Spin}}) where {Dir, Spin}
return String(AntiFermionStateful) * String(Dir) * String(Spin)
end
@inline particle(::PhotonStateful) = Photon()
@inline particle(::FermionStateful) = Electron()
@inline particle(::AntiFermionStateful) = Positron()

View File

@@ -45,48 +45,6 @@ this doesn't matter.
"""
compute_effort(t::ComputeTaskQED_Sum)::Float64 = 1.0
"""
show(io::IO, t::ComputeTaskQED_S1)
Print the S1 task to io.
"""
show(io::IO, t::ComputeTaskQED_S1) = print(io, "ComputeS1")
"""
show(io::IO, t::ComputeTaskQED_S2)
Print the S2 task to io.
"""
show(io::IO, t::ComputeTaskQED_S2) = print(io, "ComputeS2")
"""
show(io::IO, t::ComputeTaskQED_P)
Print the P task to io.
"""
show(io::IO, t::ComputeTaskQED_P) = print(io, "ComputeP")
"""
show(io::IO, t::ComputeTaskQED_U)
Print the U task to io.
"""
show(io::IO, t::ComputeTaskQED_U) = print(io, "ComputeU")
"""
show(io::IO, t::ComputeTaskQED_V)
Print the V task to io.
"""
show(io::IO, t::ComputeTaskQED_V) = print(io, "ComputeV")
"""
show(io::IO, t::ComputeTaskQED_Sum)
Print the sum task to io.
"""
show(io::IO, t::ComputeTaskQED_Sum) = print(io, "ComputeSum")
"""
children(::ComputeTaskQED_S1)