experiments (#1)
Co-authored-by: Anton Reinhard <anton.reinhard@proton.me> Reviewed-on: #1
This commit is contained in:
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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}()
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user