experiments (#1)
All checks were successful
MetagraphOptimization_CI / docs (push) Successful in 10m41s
MetagraphOptimization_CI / test (push) Successful in 30m40s

Co-authored-by: Anton Reinhard <anton.reinhard@proton.me>
Reviewed-on: #1
This commit is contained in:
2024-05-08 12:03:27 +02:00
parent 82ed774b7e
commit 87dbaf2c32
155 changed files with 5372 additions and 1029 deletions

View File

@@ -84,9 +84,17 @@ Compute a sum over the vector. Use an algorithm that accounts for accumulated er
Linearly many FLOP with growing data.
"""
function compute(::ComputeTaskABC_Sum, data...)::Float64
return sum(data)
s = 0.0im
for d in data
s += d
end
return s
end
function compute(::ComputeTaskABC_Sum, data::AbstractArray)::Float64
return sum(data)
s = 0.0im
for d in data
s += d
end
return s
end

View File

@@ -72,9 +72,9 @@ function compute(
# inner edge is just a "scalar", data1 and data2 are bispinor/adjointbispinnor, need to keep correct order
if typeof(data1.v) <: BiSpinor
return data2.v * inner * data1.v
return (data2.v)::AdjointBiSpinor * inner * (data1.v)::BiSpinor
else
return data1.v * inner * data2.v
return (data1.v)::AdjointBiSpinor * inner * (data2.v)::BiSpinor
end
end
@@ -115,10 +115,18 @@ Linearly many FLOP with growing data.
"""
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)
s = 0.0im
for d in data
s += d
end
return s
end
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)
s = 0.0im
for d in data
s += d
end
return s
end

View File

@@ -114,12 +114,8 @@ function gen_graph(process_description::QEDProcessDescription)
dataOutNodes[String(particle)] = data_out
end
#dataOutBackup = copy(dataOutNodes)
# TODO: this should be parallelizable somewhat easily
for diagram in diagrams
# the intermediate (virtual) particles change across
#dataOutNodes = copy(dataOutBackup)
tie = diagram.tie[]
# handle the vertices

View File

@@ -1,3 +1,4 @@
using Combinatorics
import Base.copy
import Base.hash
@@ -265,11 +266,12 @@ function add_vertex!(fd::FeynmanDiagram, vertex::FeynmanVertex)
end
if !can_apply_vertex(get_particles(fd), vertex)
#@assert false "Can't add vertex $vertex to diagram"
@assert false "Can't add vertex $vertex to diagram $(get_particles(fd))"
end
push!(fd.vertices, Set{FeynmanVertex}())
push!(fd.vertices[end], vertex)
fd.type_ids[vertex.out.particle] += 1
return nothing
@@ -437,12 +439,196 @@ function remove_duplicates(compare_set::Set{FeynmanDiagram})
return result
end
"""
is_compton(fd::FeynmanDiagram)
Returns true iff the given feynman diagram is an (empty) diagram of a compton process like ke->k^ne
"""
function is_compton(fd::FeynmanDiagram)
return fd.type_ids[FermionStateful{Incoming, SpinUp}] == 1 &&
fd.type_ids[FermionStateful{Outgoing, SpinUp}] == 1 &&
fd.type_ids[AntiFermionStateful{Incoming, SpinUp}] == 0 &&
fd.type_ids[AntiFermionStateful{Outgoing, SpinUp}] == 0 &&
fd.type_ids[PhotonStateful{Incoming, PolX}] >= 1 &&
fd.type_ids[PhotonStateful{Outgoing, PolX}] >= 1
end
"""
gen_compton_diagram_from_order(order::Vector{Int}, inFerm, outFerm, n::Int, m::Int)
Helper function for [`gen_compton_diagrams`](@Ref). Generates a single diagram for the given order and n input and m output photons.
"""
function gen_compton_diagram_from_order(order::Vector{Int}, inFerm, outFerm, n::Int, m::Int)
photons = vcat(
[FeynmanParticle(PhotonStateful{Incoming, PolX}, i) for i in 1:n],
[FeynmanParticle(PhotonStateful{Outgoing, PolX}, i) for i in 1:m],
)
new_diagram = FeynmanDiagram(
[],
missing,
[inFerm, outFerm, photons...],
Dict{Type, Int64}(
FermionStateful{Incoming, SpinUp} => 1,
FermionStateful{Outgoing, SpinUp} => 1,
PhotonStateful{Incoming, PolX} => n,
PhotonStateful{Outgoing, PolX} => m,
),
)
left_index = 1
right_index = length(order)
iterations = 1
while left_index <= right_index
# left side
v_left = FeynmanVertex(
FeynmanParticle(FermionStateful{Incoming, SpinUp}, iterations),
photons[order[left_index]],
FeynmanParticle(FermionStateful{Incoming, SpinUp}, iterations + 1),
)
left_index += 1
add_vertex!(new_diagram, v_left)
if (left_index > right_index)
break
end
# right side
v_right = FeynmanVertex(
FeynmanParticle(FermionStateful{Outgoing, SpinUp}, iterations),
photons[order[right_index]],
FeynmanParticle(FermionStateful{Outgoing, SpinUp}, iterations + 1),
)
right_index -= 1
add_vertex!(new_diagram, v_right)
iterations += 1
end
@assert possible_tie(new_diagram) !== missing
add_tie!(new_diagram, possible_tie(new_diagram))
return new_diagram
end
"""
gen_compton_diagram_from_order_one_side(order::Vector{Int}, inFerm, outFerm, n::Int, m::Int)
Helper function for [`gen_compton_diagrams`](@Ref). Generates a single diagram for the given order and n input and m output photons.
"""
function gen_compton_diagram_from_order_one_side(order::Vector{Int}, inFerm, outFerm, n::Int, m::Int)
photons = vcat(
[FeynmanParticle(PhotonStateful{Incoming, PolX}, i) for i in 1:n],
[FeynmanParticle(PhotonStateful{Outgoing, PolX}, i) for i in 1:m],
)
new_diagram = FeynmanDiagram(
[],
missing,
[inFerm, outFerm, photons...],
Dict{Type, Int64}(
FermionStateful{Incoming, SpinUp} => 1,
FermionStateful{Outgoing, SpinUp} => 1,
PhotonStateful{Incoming, PolX} => n,
PhotonStateful{Outgoing, PolX} => m,
),
)
left_index = 1
right_index = length(order)
iterations = 1
while left_index <= right_index
# left side
v_left = FeynmanVertex(
FeynmanParticle(FermionStateful{Incoming, SpinUp}, iterations),
photons[order[left_index]],
FeynmanParticle(FermionStateful{Incoming, SpinUp}, iterations + 1),
)
left_index += 1
add_vertex!(new_diagram, v_left)
if (left_index > right_index)
break
end
# only once on the right side
if (iterations == 1)
# right side
v_right = FeynmanVertex(
FeynmanParticle(FermionStateful{Outgoing, SpinUp}, iterations),
photons[order[right_index]],
FeynmanParticle(FermionStateful{Outgoing, SpinUp}, iterations + 1),
)
right_index -= 1
add_vertex!(new_diagram, v_right)
end
iterations += 1
end
ps = get_particles(new_diagram)
@assert length(ps) == 2
add_tie!(new_diagram, FeynmanTie(ps[1], ps[2]))
return new_diagram
end
"""
gen_compton_diagrams(n::Int, m::Int)
Special case diagram generation for Compton processes, i.e., processes of the form k^ne->k^me
"""
function gen_compton_diagrams(n::Int, m::Int)
inFerm = FeynmanParticle(FermionStateful{Incoming, SpinUp}, 1)
outFerm = FeynmanParticle(FermionStateful{Outgoing, SpinUp}, 1)
perms = [permutations([i for i in 1:(n + m)])...]
diagrams = [Vector{FeynmanDiagram}() for i in 1:nthreads()]
@threads for order in perms
push!(diagrams[threadid()], gen_compton_diagram_from_order(order, inFerm, outFerm, n, m))
end
return vcat(diagrams...)
end
"""
gen_compton_diagrams_one_side(n::Int, m::Int)
Special case diagram generation for Compton processes, i.e., processes of the form k^ne->k^me, but generating from one end, yielding larger diagrams
"""
function gen_compton_diagrams_one_side(n::Int, m::Int)
inFerm = FeynmanParticle(FermionStateful{Incoming, SpinUp}, 1)
outFerm = FeynmanParticle(FermionStateful{Outgoing, SpinUp}, 1)
perms = [permutations([i for i in 1:(n + m)])...]
diagrams = [Vector{FeynmanDiagram}() for i in 1:nthreads()]
@threads for order in perms
push!(diagrams[threadid()], gen_compton_diagram_from_order_one_side(order, inFerm, outFerm, n, m))
end
return vcat(diagrams...)
end
"""
gen_diagrams(fd::FeynmanDiagram)
From a given feynman diagram in its initial state, e.g. when created through the [`FeynmanDiagram(pd::ProcessDescription)`](@ref) constructor, generate and return all possible [`FeynmanDiagram`](@ref)s that describe that process.
"""
function gen_diagrams(fd::FeynmanDiagram)
if is_compton(fd)
return gen_compton_diagrams_one_side(
fd.type_ids[PhotonStateful{Incoming, PolX}],
fd.type_ids[PhotonStateful{Outgoing, PolX}],
)
end
working = Set{FeynmanDiagram}()
results = Set{FeynmanDiagram}()

View File

@@ -313,7 +313,7 @@ Return the factor of a vertex in a QED feynman diagram.
return -1im * e * gamma()
end
@inline function QED_inner_edge(p::QEDParticle)
@inline function QED_inner_edge(p::QEDParticle)::DiracMatrix
return propagator(particle(p), p.momentum)
end

View File

@@ -42,10 +42,10 @@ Create a short string suitable as a filename or similar, describing the given pr
julia> using MetagraphOptimization
julia> String(parse_process("ke->ke", QEDModel()))
qed_ke-ke
"qed_ke-ke"
julia> print(parse_process("kk->ep", QEDModel()))
qed_kk-ep
QED Process: 'kk->ep'
```
"""
function String(process::QEDProcessDescription)

View File

@@ -1,32 +1,32 @@
# TODO use correct numbers
# compute effort numbers were measured on a home pc system using likwid
"""
compute_effort(t::ComputeTaskQED_S1)
Return the compute effort of an S1 task.
"""
compute_effort(t::ComputeTaskQED_S1)::Float64 = 11.0
compute_effort(t::ComputeTaskQED_S1)::Float64 = 475.0
"""
compute_effort(t::ComputeTaskQED_S2)
Return the compute effort of an S2 task.
"""
compute_effort(t::ComputeTaskQED_S2)::Float64 = 12.0
compute_effort(t::ComputeTaskQED_S2)::Float64 = 505.0
"""
compute_effort(t::ComputeTaskQED_U)
Return the compute effort of a U task.
"""
compute_effort(t::ComputeTaskQED_U)::Float64 = 1.0
compute_effort(t::ComputeTaskQED_U)::Float64 = (291.0 + 467.0 + 16.0 + 17.0) / 4.0 # The exact FLOPS count depends heavily on the type of particle, take an average value here
"""
compute_effort(t::ComputeTaskQED_V)
Return the compute effort of a V task.
"""
compute_effort(t::ComputeTaskQED_V)::Float64 = 6.0
compute_effort(t::ComputeTaskQED_V)::Float64 = (1150.0 + 764.0 + 828.0) / 3.0
"""
compute_effort(t::ComputeTaskQED_P)