Compare commits
18 Commits
feature/pr
...
qed
Author | SHA1 | Date | |
---|---|---|---|
5e5e29dc69 | |||
86799644c4 | |||
f78cde613a | |||
3ca24f76e1 | |||
6314539f2c | |||
ba0c75c8dc | |||
aa18430d29 | |||
268841990e | |||
7ad5e78b3b | |||
afec3f6e70 | |||
62d572adbf | |||
c2687cdc01 | |||
fcb7c992da | |||
938bf216e5 | |||
04d5673b44 | |||
b7560685d4 | |||
16274919e4 | |||
2709eeb3dc |
@ -7,65 +7,8 @@ env:
|
||||
JULIA_DEPOT_PATH: './.julia'
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
runs-on: arch-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Julia environment
|
||||
uses: https://github.com/julia-actions/setup-julia@v1.9.2
|
||||
with:
|
||||
version: '1.9.2'
|
||||
|
||||
# needed for the file hashing, should be removed when ${{ hashFiles('**/Project.toml') }} is supported in gitea
|
||||
- name: Setup go environment
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.20'
|
||||
|
||||
- name: Hash files
|
||||
uses: https://gitea.com/actions/go-hashfiles@v0.0.1
|
||||
id: get-hash
|
||||
with:
|
||||
patterns: |-
|
||||
**/Project.toml
|
||||
|
||||
- name: Restore Cache
|
||||
uses: actions/cache/restore@v3
|
||||
id: cache-restore
|
||||
with:
|
||||
path: |
|
||||
.julia/artifacts
|
||||
.julia/packages
|
||||
.julia/registries
|
||||
key: julia-${{ steps.get-hash.outputs.hash }}
|
||||
|
||||
- name: Check cache hit
|
||||
if: steps.cache-restore.outputs.cache-hit == 'true'
|
||||
run: exit 0
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
julia --project=./ -e 'import Pkg; Pkg.instantiate(); Pkg.precompile()'
|
||||
julia --project=examples/ -e 'import Pkg; Pkg.develop(Pkg.PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'
|
||||
julia --project=docs/ -e 'import Pkg; Pkg.develop(Pkg.PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'
|
||||
|
||||
- name: Cache Julia packages
|
||||
uses: actions/cache/save@v3
|
||||
with:
|
||||
path: |
|
||||
.julia/artifacts
|
||||
.julia/packages
|
||||
.julia/registries
|
||||
key: julia-${{ steps.get-hash.outputs.hash }}
|
||||
|
||||
test:
|
||||
needs: prepare
|
||||
runs-on: arch-latest
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@ -78,33 +21,8 @@ jobs:
|
||||
with:
|
||||
version: '1.9.2'
|
||||
|
||||
# needed for the file hashing, should be removed when ${{ hashFiles('**/Project.toml') }} is supported in gitea
|
||||
- name: Setup go environment
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.20'
|
||||
|
||||
- name: Hash files
|
||||
uses: https://gitea.com/actions/go-hashfiles@v0.0.1
|
||||
id: get-hash
|
||||
with:
|
||||
patterns: |-
|
||||
**/Project.toml
|
||||
|
||||
- name: Restore cached Julia packages
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: |
|
||||
.julia/artifacts
|
||||
.julia/packages
|
||||
.julia/registries
|
||||
key: julia-${{ steps.get-hash.outputs.hash }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
julia --project=./ -e 'import Pkg; Pkg.instantiate(); Pkg.precompile()'
|
||||
julia --project=examples/ -e 'import Pkg; Pkg.develop(Pkg.PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'
|
||||
julia --project=docs/ -e 'import Pkg; Pkg.develop(Pkg.PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'
|
||||
- name: Instantiate
|
||||
run: julia --project=./ -e 'using Pkg; Pkg.instantiate()'
|
||||
|
||||
- name: Format check
|
||||
run: |
|
||||
@ -120,14 +38,15 @@ jobs:
|
||||
end'
|
||||
|
||||
- name: Run tests
|
||||
run: julia --project=./ -t 4 -e 'import Pkg; Pkg.test()' -O0
|
||||
run: julia --project=./ -t 4 -e 'using Pkg; Pkg.test()' -O0
|
||||
|
||||
- name: Run examples
|
||||
run: julia --project=examples/ -t 4 -e 'include("examples/import_bench.jl")' -O3
|
||||
run: |
|
||||
julia --project=examples/ -e 'using Pkg; Pkg.develop(Pkg.PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'
|
||||
julia --project=examples/ -t 4 -e 'include("examples/import_bench.jl")' -O3
|
||||
|
||||
docs:
|
||||
needs: prepare
|
||||
runs-on: arch-latest
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@ -140,36 +59,10 @@ jobs:
|
||||
with:
|
||||
version: '1.9.2'
|
||||
|
||||
# needed for the file hashing, should be removed when ${{ hashFiles('**/Project.toml') }} is supported in gitea
|
||||
- name: Setup go environment
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.20'
|
||||
|
||||
- name: Hash files
|
||||
uses: https://gitea.com/actions/go-hashfiles@v0.0.1
|
||||
id: get-hash
|
||||
with:
|
||||
patterns: |-
|
||||
**/Project.toml
|
||||
|
||||
- name: Restore cached Julia packages
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: |
|
||||
.julia/artifacts
|
||||
.julia/packages
|
||||
.julia/registries
|
||||
key: julia-${{ steps.get-hash.outputs.hash }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
julia --project=./ -e 'import Pkg; Pkg.instantiate(); Pkg.precompile()'
|
||||
julia --project=examples/ -e 'import Pkg; Pkg.develop(Pkg.PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'
|
||||
julia --project=docs/ -e 'import Pkg; Pkg.develop(Pkg.PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'
|
||||
|
||||
- name: Build docs
|
||||
run: julia --project=docs/ docs/make.jl
|
||||
run: |
|
||||
julia --project=docs/ -e 'using Pkg; Pkg.develop(Pkg.PackageSpec(path=pwd())); Pkg.instantiate(); Pkg.precompile()'
|
||||
julia --project=docs/ docs/make.jl
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,3 +28,4 @@ Manifest.toml
|
||||
.vscode
|
||||
.julia
|
||||
**/.ipynb_checkpoints/
|
||||
*.bkp
|
||||
|
@ -12,6 +12,7 @@ JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
|
||||
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
|
||||
NumaAllocators = "21436f30-1b4a-4f08-87af-e26101bb5379"
|
||||
QEDbase = "10e22c08-3ccb-4172-bfcf-7d7aa3d04d93"
|
||||
QEDprocesses = "46de9c38-1bb3-4547-a1ec-da24d767fdad"
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
|
||||
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
|
42
README.md
42
README.md
@ -50,8 +50,8 @@ Problems:
|
||||
|
||||
For graphs AB->AB^n:
|
||||
- Number of Sums should always be 1
|
||||
- Number of ComputeTaskS2 should always be (n+1)!
|
||||
- Number of ComputeTaskU should always be (n+3)
|
||||
- Number of ComputeTaskABC_S2 should always be (n+1)!
|
||||
- Number of ComputeTaskABC_U should always be (n+3)
|
||||
|
||||
Times are from my home machine: AMD Ryzen 7900X3D, 64GB DDR5 RAM @ 6000MHz (not necessarily up to date, check Jupyter Notebooks in `notebooks/` instead)
|
||||
|
||||
@ -59,9 +59,9 @@ Times are from my home machine: AMD Ryzen 7900X3D, 64GB DDR5 RAM @ 6000MHz (not
|
||||
$ julia --project examples/import_bench.jl
|
||||
AB->AB:
|
||||
Graph:
|
||||
Nodes: Total: 34, DataTask: 19, ComputeTaskP: 4,
|
||||
ComputeTaskS2: 2, ComputeTaskV: 4, ComputeTaskU: 4,
|
||||
ComputeTaskSum: 1
|
||||
Nodes: Total: 34, DataTask: 19, ComputeTaskABC_P: 4,
|
||||
ComputeTaskABC_S2: 2, ComputeTaskABC_V: 4, ComputeTaskABC_U: 4,
|
||||
ComputeTaskABC_Sum: 1
|
||||
Edges: 37
|
||||
Total Compute Effort: 185
|
||||
Total Data Transfer: 102
|
||||
@ -71,9 +71,9 @@ Graph:
|
||||
|
||||
AB->ABBB:
|
||||
Graph:
|
||||
Nodes: Total: 280, DataTask: 143, ComputeTaskP: 6,
|
||||
ComputeTaskS2: 24, ComputeTaskV: 64, ComputeTaskU: 6,
|
||||
ComputeTaskSum: 1, ComputeTaskS1: 36
|
||||
Nodes: Total: 280, DataTask: 143, ComputeTaskABC_P: 6,
|
||||
ComputeTaskABC_S2: 24, ComputeTaskABC_V: 64, ComputeTaskABC_U: 6,
|
||||
ComputeTaskABC_Sum: 1, ComputeTaskABC_S1: 36
|
||||
Edges: 385
|
||||
Total Compute Effort: 2007
|
||||
Total Data Transfer: 828
|
||||
@ -83,9 +83,9 @@ Graph:
|
||||
|
||||
AB->ABBBBB:
|
||||
Graph:
|
||||
Nodes: Total: 7854, DataTask: 3931, ComputeTaskP: 8,
|
||||
ComputeTaskS2: 720, ComputeTaskV: 1956, ComputeTaskU: 8,
|
||||
ComputeTaskSum: 1, ComputeTaskS1: 1230
|
||||
Nodes: Total: 7854, DataTask: 3931, ComputeTaskABC_P: 8,
|
||||
ComputeTaskABC_S2: 720, ComputeTaskABC_V: 1956, ComputeTaskABC_U: 8,
|
||||
ComputeTaskABC_Sum: 1, ComputeTaskABC_S1: 1230
|
||||
Edges: 11241
|
||||
Total Compute Effort: 58789
|
||||
Total Data Transfer: 23244
|
||||
@ -95,9 +95,9 @@ Graph:
|
||||
|
||||
AB->ABBBBBBB:
|
||||
Graph:
|
||||
Nodes: Total: 438436, DataTask: 219223, ComputeTaskP: 10,
|
||||
ComputeTaskS2: 40320, ComputeTaskV: 109600, ComputeTaskU: 10,
|
||||
ComputeTaskSum: 1, ComputeTaskS1: 69272
|
||||
Nodes: Total: 438436, DataTask: 219223, ComputeTaskABC_P: 10,
|
||||
ComputeTaskABC_S2: 40320, ComputeTaskABC_V: 109600, ComputeTaskABC_U: 10,
|
||||
ComputeTaskABC_Sum: 1, ComputeTaskABC_S1: 69272
|
||||
Edges: 628665
|
||||
Total Compute Effort: 3288131
|
||||
Total Data Transfer: 1297700
|
||||
@ -107,7 +107,7 @@ Graph:
|
||||
|
||||
AB->ABBBBBBBBB:
|
||||
Graph:
|
||||
Nodes: Total: 39456442, DataTask: 19728227, ComputeTaskS1: 6235290, ComputeTaskP: 12, ComputeTaskU: 12, ComputeTaskV: 9864100, ComputeTaskS2: 3628800, ComputeTaskSum: 1
|
||||
Nodes: Total: 39456442, DataTask: 19728227, ComputeTaskABC_S1: 6235290, ComputeTaskABC_P: 12, ComputeTaskABC_U: 12, ComputeTaskABC_V: 9864100, ComputeTaskABC_S2: 3628800, ComputeTaskABC_Sum: 1
|
||||
Edges: 56578129
|
||||
Total Compute Effort: 295923153
|
||||
Total Data Transfer: 175407750
|
||||
@ -116,9 +116,9 @@ Graph:
|
||||
|
||||
ABAB->ABAB:
|
||||
Graph:
|
||||
Nodes: Total: 3218, DataTask: 1613, ComputeTaskP: 8,
|
||||
ComputeTaskS2: 288, ComputeTaskV: 796, ComputeTaskU: 8,
|
||||
ComputeTaskSum: 1, ComputeTaskS1: 504
|
||||
Nodes: Total: 3218, DataTask: 1613, ComputeTaskABC_P: 8,
|
||||
ComputeTaskABC_S2: 288, ComputeTaskABC_V: 796, ComputeTaskABC_U: 8,
|
||||
ComputeTaskABC_Sum: 1, ComputeTaskABC_S1: 504
|
||||
Edges: 4581
|
||||
Total Compute Effort: 24009
|
||||
Total Data Transfer: 9494
|
||||
@ -128,9 +128,9 @@ Graph:
|
||||
|
||||
ABAB->ABC:
|
||||
Graph:
|
||||
Nodes: Total: 817, DataTask: 412, ComputeTaskP: 7,
|
||||
ComputeTaskS2: 72, ComputeTaskV: 198, ComputeTaskU: 7,
|
||||
ComputeTaskSum: 1, ComputeTaskS1: 120
|
||||
Nodes: Total: 817, DataTask: 412, ComputeTaskABC_P: 7,
|
||||
ComputeTaskABC_S2: 72, ComputeTaskABC_V: 198, ComputeTaskABC_U: 7,
|
||||
ComputeTaskABC_Sum: 1, ComputeTaskABC_S1: 120
|
||||
Edges: 1151
|
||||
Total Compute Effort: 6028
|
||||
Total Data Transfer: 2411
|
||||
|
259
docs/src/QED-Bhabha-DAG.drawio
Normal file
259
docs/src/QED-Bhabha-DAG.drawio
Normal file
@ -0,0 +1,259 @@
|
||||
<mxfile host="Electron" modified="2023-11-25T19:36:18.149Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.1 Chrome/114.0.5735.289 Electron/25.9.4 Safari/537.36" etag="hBUSDG3lmnElLEv2sh-Z" version="21.6.1" type="device">
|
||||
<diagram name="Page-1" id="pzz-rsbNjEFeZeQIA-38">
|
||||
<mxGraphModel dx="1430" dy="853" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="500" pageHeight="900" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-6" target="KG5lhhUBjoQ79gfvQvIC-18" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-6" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">AdjointBiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-7" target="KG5lhhUBjoQ79gfvQvIC-18" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-7" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">BiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="310" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-8" target="KG5lhhUBjoQ79gfvQvIC-26" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-8" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">AdjointBiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-9" target="KG5lhhUBjoQ79gfvQvIC-26" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-9" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">BiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="430" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-14" target="KG5lhhUBjoQ79gfvQvIC-6" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-14" value="U(p<sub>1</sub>)<br style="border-color: var(--border-color);"><font color="#0000ff"><b>IncomingAntiFermion</b></font><br>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-15" target="KG5lhhUBjoQ79gfvQvIC-7" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-15" value="U(e<sub style="border-color: var(--border-color);">1</sub>)<br style="border-color: var(--border-color);"><b><font color="#0000ff">IncomingFermion<br></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="310" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-16" target="KG5lhhUBjoQ79gfvQvIC-9" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-16" value="U(p<span style="font-size: 10px;"><sub>2</sub></span>)<br style="border-color: var(--border-color);"><b><font color="#0000ff">OutgoingAntiFermion<br></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="430" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-17" target="KG5lhhUBjoQ79gfvQvIC-8" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-17" value="U(e<sub style="border-color: var(--border-color);">2</sub>)<br style="border-color: var(--border-color);"><b><font color="#0000ff">OutgoingFermion<br></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-18" target="KG5lhhUBjoQ79gfvQvIC-25" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-18" value="V(e<sub>1</sub>, p<sub>1</sub>)<br>Result Particle:<br>q: <font color="#0000ff"><b>OutgoingPhoton<br></b></font>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="240" y="480" width="140" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-36" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-25" target="KG5lhhUBjoQ79gfvQvIC-35" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-25" value="<b><font color="#336600">vertex</font></b> -&gt;<br>AdjointBiSpinor * <br>DiracMatrix *<br>BiSpinor<br>=&nbsp;<b style="border-color: var(--border-color);"><font color="#cc00cc" style="border-color: var(--border-color);">Complex<br></font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="360" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-26" target="KG5lhhUBjoQ79gfvQvIC-27" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-26" value="V(e<sub>2</sub>, p<sub>2</sub>)<br>Result Particle:<br>q': <b><font color="#0000ff">IncomingPhoton</font></b>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="480" y="480" width="140" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-37" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-27" target="KG5lhhUBjoQ79gfvQvIC-35" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="550" y="340" />
|
||||
<mxPoint x="420" y="340" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-27" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">vertex</font></b>&nbsp;-&gt;<br>AdjointBiSpinor * <br>DiracMatrix *<br>BiSpinor<br>=&nbsp;<b style="border-color: var(--border-color);"><font color="#cc00cc" style="border-color: var(--border-color);">Complex</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="490" y="360" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-35" target="KG5lhhUBjoQ79gfvQvIC-38" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-35" value="S2(q, q')<br>q == -q'<br><b><font color="#0000ff">No Result Particle</font></b>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="240" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-71" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-38" target="KG5lhhUBjoQ79gfvQvIC-70" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="670" y="170" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-38" value="<b style=""><font color="#336600">inner_edge</font></b> -&gt;<br>Complex * propagator(q) * Complex&nbsp;<br>=&nbsp;<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">Complex<br></font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="350" y="140" width="140" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-40" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-41" target="KG5lhhUBjoQ79gfvQvIC-57" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-41" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">AdjointBiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="670" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-68" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-43" target="KG5lhhUBjoQ79gfvQvIC-61" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-43" value="<b style=""><font color="#336600">base_state</font></b> -&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">AdjointBiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="1030" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-67" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-45" target="KG5lhhUBjoQ79gfvQvIC-57" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-45" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">BiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="790" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-46" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-47" target="KG5lhhUBjoQ79gfvQvIC-61" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-47" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">BiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="910" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-48" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-49" target="KG5lhhUBjoQ79gfvQvIC-41" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-49" value="U(p<sub style="border-color: var(--border-color);">1</sub>)<br style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#0000ff"><b style="border-color: var(--border-color);">IncomingAntiFermion</b></font><br style="border-color: var(--border-color);">Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="670" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-69" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-51" target="KG5lhhUBjoQ79gfvQvIC-43" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-51" value="U(e<sub>2</sub>)<br style="border-color: var(--border-color);"><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#0000ff">OutgoingFermion<br style="border-color: var(--border-color);"></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="1030" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-52" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-53" target="KG5lhhUBjoQ79gfvQvIC-47" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-53" value="U(e<sub>1</sub>)<br style="border-color: var(--border-color);"><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#0000ff">IncomingFermion<br style="border-color: var(--border-color);"></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="910" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-54" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-55" target="KG5lhhUBjoQ79gfvQvIC-45" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-55" value="U(p<sub style="border-color: var(--border-color);">2</sub>)<br style="border-color: var(--border-color);"><font color="#0000ff"><b>OutgoingAntiFermion<br></b></font>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="790" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-56" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-57" target="KG5lhhUBjoQ79gfvQvIC-59" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-57" value="<font style="font-size: 12px;">V(p<sub>1</sub>, p<sub>2</sub>)</font><br>Result Particle:<br>q: <b><font color="#0000ff">IncomingPhoton</font></b>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="720" y="480" width="140" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-58" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-59" target="KG5lhhUBjoQ79gfvQvIC-65" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-59" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">vertex</font></b>&nbsp;-&gt;<br>AdjointBiSpinor * <br>DiracMatrix *<br>BiSpinor<br>=&nbsp;<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">Complex</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="730" y="360" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-60" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-61" target="KG5lhhUBjoQ79gfvQvIC-63" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-61" value="<font style="font-size: 12px;">V(e<sub>1</sub>, e<sub>2</sub>)</font><br>Result Particle:<br>q': <font color="#0000ff"><b>OutgoingPhoton</b></font>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="960" y="480" width="140" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-62" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-63" target="KG5lhhUBjoQ79gfvQvIC-65" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1030" y="340" />
|
||||
<mxPoint x="900" y="340" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-63" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">vertex</font></b>&nbsp;-&gt;<br>AdjointBiSpinor * <br>DiracMatrix * <br>BiSpinor <br>=&nbsp;<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">Complex<br></font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="970" y="360" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-64" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-65" target="KG5lhhUBjoQ79gfvQvIC-66" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-65" value="S2(q, q')<br>q == -q'<br><b><font color="#0000ff">No Result Particle</font></b>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="840" y="240" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-72" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-66" target="KG5lhhUBjoQ79gfvQvIC-70" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="670" y="170" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-66" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">inner_edge</font></b>&nbsp;-&gt;<br>Complex * propagator(q) * Complex<br>=&nbsp;<b style="border-color: var(--border-color);"><font color="#cc00cc">Complex</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="830" y="140" width="140" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-70" value="<span style="font-size: 32px;">diff()</span>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#ffcd28;strokeColor=#d79b00;gradientColor=#ffa500;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="20" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-73" value="<b><font style="font-size: 22px;">ValueAcc</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="155" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-74" value="<b><font style="font-size: 22px;">ValueAcc</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="385" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-75" value="<b><font style="font-size: 22px;">ValueAcc</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="615" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-76" value="<b><font style="font-size: 22px;">Particle Propagation</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="725" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-77" value="<b><font style="font-size: 22px;">Particle Propagation</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="505" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-78" value="<b><font style="font-size: 22px;">Particle Propagation</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="265" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-79" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="220" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="220" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-80" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="340" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="340" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-81" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="460" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="460" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-82" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="120" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="120" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-83" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="580" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="580" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-84" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="680" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="680" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-85" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="800" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="800" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
259
docs/src/QED-Compton-DAG.drawio
Normal file
259
docs/src/QED-Compton-DAG.drawio
Normal file
@ -0,0 +1,259 @@
|
||||
<mxfile host="Electron" modified="2023-11-25T19:38:46.724Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.1 Chrome/114.0.5735.289 Electron/25.9.4 Safari/537.36" etag="GgWoS9drZkpaqTCZiHI_" version="21.6.1" type="device">
|
||||
<diagram name="Page-1" id="pzz-rsbNjEFeZeQIA-38">
|
||||
<mxGraphModel dx="1430" dy="853" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="500" pageHeight="900" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-6" target="KG5lhhUBjoQ79gfvQvIC-18" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-6" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font color="#cc00cc">LorentzVector</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-7" target="KG5lhhUBjoQ79gfvQvIC-18" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-7" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">BiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="310" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-8" target="KG5lhhUBjoQ79gfvQvIC-26" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-8" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">AdjointBiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-9" target="KG5lhhUBjoQ79gfvQvIC-26" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-9" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">LorentzVector</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="430" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-14" target="KG5lhhUBjoQ79gfvQvIC-6" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-14" value="U(γ<sub style="border-color: var(--border-color);">1</sub>)<br style="border-color: var(--border-color);"><font color="#0000ff"><b>IncomingPhoton</b></font><br>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="190" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-15" target="KG5lhhUBjoQ79gfvQvIC-7" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-15" value="U(p<sub style="border-color: var(--border-color);">1</sub>)<br style="border-color: var(--border-color);"><b><font color="#0000ff">IncomingFermion<br></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="310" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-16" target="KG5lhhUBjoQ79gfvQvIC-9" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-16" value="U(γ<sub style="border-color: var(--border-color);">2</sub>)<br style="border-color: var(--border-color);"><b><font color="#0000ff">OutgoingPhoton<br></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="430" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-17" target="KG5lhhUBjoQ79gfvQvIC-8" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-17" value="U(p<sub style="border-color: var(--border-color);">2</sub>)<br style="border-color: var(--border-color);"><b><font color="#0000ff">OutgoingFermion<br></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-18" target="KG5lhhUBjoQ79gfvQvIC-25" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-18" value="V(γ<sub>1</sub>, p<sub>1</sub>)<br>Result Particle:<br>q: <font color="#0000ff"><b>OutgoingFermion</b></font>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="240" y="480" width="140" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-36" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-25" target="KG5lhhUBjoQ79gfvQvIC-35" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-25" value="<b><font color="#336600">vertex</font></b> -&gt;<br>LorentzVector * DiracMatrix * <br>BiSpinor<br>=&nbsp;<b style="border-color: var(--border-color);"><font color="#cc00cc" style="border-color: var(--border-color);">BiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="360" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-26" target="KG5lhhUBjoQ79gfvQvIC-27" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-26" value="V(γ<sub>2</sub>, p<sub>2</sub>)<br>Result Particle:<br>q': <b><font color="#0000ff">IncomingFermion</font></b>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="480" y="480" width="140" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-37" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-27" target="KG5lhhUBjoQ79gfvQvIC-35" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="550" y="340" />
|
||||
<mxPoint x="420" y="340" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-27" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">vertex</font></b>&nbsp;-&gt;<br>AdjointBiSpinor * LorentzVector * <br>DiracMatrix <br>=&nbsp;<b style="border-color: var(--border-color);"><font color="#cc00cc" style="border-color: var(--border-color);">AdjointBiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="490" y="360" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-35" target="KG5lhhUBjoQ79gfvQvIC-38" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-35" value="S2(q, q')<br>q == -q'<br><b><font color="#0000ff">No Result Particle</font></b>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="360" y="240" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-71" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-38" target="KG5lhhUBjoQ79gfvQvIC-70" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="670" y="170" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-38" value="<b style=""><font color="#336600">inner_edge</font></b> -&gt;<br>AdjointBiSpinor * propagator(q) * BiSpinor =&nbsp;<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">ComplexF64</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="350" y="140" width="140" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-40" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-41" target="KG5lhhUBjoQ79gfvQvIC-57" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-41" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">LorentzVector</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="670" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-68" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-43" target="KG5lhhUBjoQ79gfvQvIC-61" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-43" value="<b style=""><font color="#336600">base_state</font></b> -&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">BiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="1030" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-67" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-45" target="KG5lhhUBjoQ79gfvQvIC-57" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-45" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">AdjointBiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="790" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-46" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-47" target="KG5lhhUBjoQ79gfvQvIC-61" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-47" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">base_state</font></b>&nbsp;-&gt;<br><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">LorentzVector</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="910" y="600" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-48" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-49" target="KG5lhhUBjoQ79gfvQvIC-41" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-49" value="U(γ<sub style="border-color: var(--border-color);">1</sub>)<br style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#0000ff"><b style="border-color: var(--border-color);">IncomingPhoton</b></font><br style="border-color: var(--border-color);">Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="670" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-69" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-51" target="KG5lhhUBjoQ79gfvQvIC-43" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-51" value="U(p<sub style="border-color: var(--border-color);">1</sub>)<br style="border-color: var(--border-color);"><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#0000ff">IncomingFermion<br style="border-color: var(--border-color);"></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="1030" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-52" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-53" target="KG5lhhUBjoQ79gfvQvIC-47" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-53" value="U(γ<sub style="border-color: var(--border-color);">2</sub>)<br style="border-color: var(--border-color);"><b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#0000ff">OutgoingPhoton<br style="border-color: var(--border-color);"></font></b>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="910" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-54" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-55" target="KG5lhhUBjoQ79gfvQvIC-45" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-55" value="U(p<sub style="border-color: var(--border-color);">2</sub>)<br style="border-color: var(--border-color);"><font color="#0000ff"><b>OutgoingFermion<br></b></font>Outer Edge" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="790" y="700" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-56" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-57" target="KG5lhhUBjoQ79gfvQvIC-59" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-57" value="V(γ<sub>1</sub>, p<span style="font-size: 10px;"><sub>2</sub></span>)<br>Result Particle:<br>q: <b><font color="#0000ff">IncomingFermion</font></b>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="720" y="480" width="140" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-58" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-59" target="KG5lhhUBjoQ79gfvQvIC-65" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-59" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">vertex</font></b>&nbsp;-&gt;<br>AdjointBiSpinor * LorentzVector * <br>DiracMatrix&nbsp;<br>=&nbsp;<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">AdjointBiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="730" y="360" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-60" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-61" target="KG5lhhUBjoQ79gfvQvIC-63" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-61" value="V(γ<sub>2</sub>, p<span style="font-size: 10px;"><sub>1</sub></span>)<br>Result Particle:<br>q': <b><font color="#0000ff">OutgoingFermion</font></b>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="960" y="480" width="140" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-62" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-63" target="KG5lhhUBjoQ79gfvQvIC-65" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1030" y="340" />
|
||||
<mxPoint x="900" y="340" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-63" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">vertex</font></b>&nbsp;-&gt;<br>LorentzVector * <br>DiracMatrix * <br>BiSpinor <br>=&nbsp;<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#cc00cc">BiSpinor</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="970" y="360" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-64" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-65" target="KG5lhhUBjoQ79gfvQvIC-66" edge="1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-65" value="S2(q, q')<br>q == -q'<br><b><font color="#0000ff">No Result Particle</font></b>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#9AC7BF;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="840" y="240" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-72" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=2;" parent="1" source="KG5lhhUBjoQ79gfvQvIC-66" target="KG5lhhUBjoQ79gfvQvIC-70" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="670" y="170" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-66" value="<b style="border-color: var(--border-color);"><font style="border-color: var(--border-color);" color="#336600">inner_edge</font></b>&nbsp;-&gt;<br>AdjointBiSpinor * propagator(q) * BiSpinor =&nbsp;<b style="border-color: var(--border-color);"><font color="#cc00cc">ComplexF64</font></b>" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#f5f5f5;gradientColor=#b3b3b3;strokeColor=#666666;" parent="1" vertex="1">
|
||||
<mxGeometry x="830" y="140" width="140" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-70" value="<font style="font-size: 32px;">Σ</font>" style="ellipse;whiteSpace=wrap;html=1;strokeWidth=2;fillColor=#ffcd28;strokeColor=#d79b00;gradientColor=#ffa500;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="20" width="120" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-73" value="<b><font style="font-size: 22px;">ValueAcc</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="155" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-74" value="<b><font style="font-size: 22px;">ValueAcc</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="385" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-75" value="<b><font style="font-size: 22px;">ValueAcc</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="615" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-76" value="<b><font style="font-size: 22px;">Particle Propagation</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="725" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-77" value="<b><font style="font-size: 22px;">Particle Propagation</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="505" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-78" value="<b><font style="font-size: 22px;">Particle Propagation</font></b>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
|
||||
<mxGeometry x="10" y="265" width="120" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-79" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="220" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="220" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-80" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="340" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="340" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-81" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="460" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="460" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-82" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="120" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="120" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-83" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="580" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="580" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-84" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="680" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="680" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="KG5lhhUBjoQ79gfvQvIC-85" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint y="800" as="sourcePoint" />
|
||||
<mxPoint x="1160" y="800" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
21
docs/src/lib/internals/estimator.md
Normal file
21
docs/src/lib/internals/estimator.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Estimation
|
||||
|
||||
## Interface
|
||||
|
||||
The interface that has to be implemented for an estimator.
|
||||
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["estimator/interafce.jl"]
|
||||
Order = [:type, :constant, :function]
|
||||
```
|
||||
|
||||
## Global Metric Estimator
|
||||
|
||||
Implementation of a global metric estimator. It uses the graph properties compute effort, data transfer, and compute intensity.
|
||||
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["estimator/global_metric.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
@ -69,4 +69,58 @@ Order = [:function]
|
||||
|
||||
## QED-Model
|
||||
|
||||
*To be added*
|
||||
### Feynman Diagrams
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/qed/diagrams.jl"]
|
||||
Order = [:type, :function, :constant]
|
||||
```
|
||||
|
||||
### Types
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/qed/types.jl"]
|
||||
Order = [:type, :constant]
|
||||
```
|
||||
|
||||
### Particle
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/qed/particle.jl"]
|
||||
Order = [:type, :constant, :function]
|
||||
```
|
||||
|
||||
### Parse
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/qed/parse.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
### Properties
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/qed/properties.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
### Create
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/qed/create.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
### Compute
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/qed/compute.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
### Print
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/qed/print.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
41
docs/src/lib/internals/optimization.md
Normal file
41
docs/src/lib/internals/optimization.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Optimization
|
||||
|
||||
## Interface
|
||||
|
||||
The interface that has to be implemented for an optimization algorithm.
|
||||
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["optimization/interafce.jl"]
|
||||
Order = [:type, :constant, :function]
|
||||
```
|
||||
|
||||
## Random Walk Optimizer
|
||||
|
||||
Implementation of a random walk algorithm.
|
||||
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["estimator/random_walk.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
||||
|
||||
## Reduction Optimizer
|
||||
|
||||
Implementation of a an optimizer that reduces as far as possible.
|
||||
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["estimator/reduce.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
||||
|
||||
## Greedy Optimizer
|
||||
|
||||
Implementation of a greedy optimization algorithm.
|
||||
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["estimator/greedy.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
122
docs/src/structure_qed.drawio
Normal file
122
docs/src/structure_qed.drawio
Normal file
File diff suppressed because one or more lines are too long
33
examples/ab5.jl
Normal file
33
examples/ab5.jl
Normal file
@ -0,0 +1,33 @@
|
||||
using MetagraphOptimization
|
||||
using BenchmarkTools
|
||||
|
||||
println("Getting machine info")
|
||||
@time machine = get_machine_info()
|
||||
|
||||
println("Making model")
|
||||
@time model = ABCModel()
|
||||
|
||||
println("Making process")
|
||||
process_str = "AB->ABBBBB"
|
||||
@time process = parse_process(process_str, model)
|
||||
|
||||
println("Parsing DAG")
|
||||
@time graph = parse_dag("input/$process_str.txt", model)
|
||||
|
||||
println("Generating input data")
|
||||
@time input_data = [gen_process_input(process) for _ in 1:1000]
|
||||
|
||||
println("Reducing graph")
|
||||
@time optimize_to_fixpoint!(ReductionOptimizer(), graph)
|
||||
|
||||
println("Generating compute function")
|
||||
@time compute_func = get_compute_function(graph, process, machine)
|
||||
|
||||
println("First run, single argument")
|
||||
@time compute_func(input_data[1])
|
||||
|
||||
println("\nBenchmarking function, 1 input")
|
||||
display(@benchmark compute_func($(input_data[1])))
|
||||
|
||||
println("\nBenchmarking function, 1000 inputs")
|
||||
display(@benchmark compute_func.($input_data))
|
33
examples/ab7.jl
Normal file
33
examples/ab7.jl
Normal file
@ -0,0 +1,33 @@
|
||||
using MetagraphOptimization
|
||||
using BenchmarkTools
|
||||
|
||||
println("Getting machine info")
|
||||
@time machine = get_machine_info()
|
||||
|
||||
println("Making model")
|
||||
@time model = ABCModel()
|
||||
|
||||
println("Making process")
|
||||
process_str = "AB->ABBBBBBB"
|
||||
@time process = parse_process(process_str, model)
|
||||
|
||||
println("Parsing DAG")
|
||||
@time graph = parse_dag("input/$process_str.txt", model)
|
||||
|
||||
println("Generating input data")
|
||||
@time input_data = [gen_process_input(process) for _ in 1:1000]
|
||||
|
||||
println("Reducing graph")
|
||||
@time optimize_to_fixpoint!(ReductionOptimizer(), graph)
|
||||
|
||||
println("Generating compute function")
|
||||
@time compute_func = get_compute_function(graph, process, machine)
|
||||
|
||||
println("First run, single argument")
|
||||
@time compute_func(input_data[1])
|
||||
|
||||
println("\nBenchmarking function, 1 input")
|
||||
display(@benchmark compute_func($(input_data[1])))
|
||||
|
||||
println("\nBenchmarking function, 1000 inputs")
|
||||
display(@benchmark compute_func.($input_data))
|
@ -1,59 +0,0 @@
|
||||
|
||||
function random_walk!(g::DAG, n::Int64)
|
||||
# the purpose here is to do "random" operations on the graph to simulate an optimizer
|
||||
reset_graph!(g)
|
||||
|
||||
properties = get_properties(g)
|
||||
|
||||
for i in 1:n
|
||||
# choose push or pop
|
||||
if rand(Bool)
|
||||
# push
|
||||
opt = get_operations(g)
|
||||
|
||||
# choose one of fuse/split/reduce
|
||||
option = rand(1:3)
|
||||
if option == 1 && !isempty(opt.nodeFusions)
|
||||
push_operation!(g, rand(collect(opt.nodeFusions)))
|
||||
elseif option == 2 && !isempty(opt.nodeReductions)
|
||||
push_operation!(g, rand(collect(opt.nodeReductions)))
|
||||
elseif option == 3 && !isempty(opt.nodeSplits)
|
||||
push_operation!(g, rand(collect(opt.nodeSplits)))
|
||||
else
|
||||
i = i - 1
|
||||
end
|
||||
else
|
||||
# pop
|
||||
if (can_pop(g))
|
||||
pop_operation!(g)
|
||||
else
|
||||
i = i - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
function reduce_all!(g::DAG)
|
||||
reset_graph!(g)
|
||||
|
||||
opt = get_operations(g)
|
||||
while (!isempty(opt.nodeReductions))
|
||||
push_operation!(g, pop!(opt.nodeReductions))
|
||||
|
||||
if (isempty(opt.nodeReductions))
|
||||
opt = get_operations(g)
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function reduce_one!(g::DAG)
|
||||
opt = get_operations(g)
|
||||
if !isempty(opt.nodeReductions)
|
||||
push_operation!(g, pop!(opt.nodeReductions))
|
||||
end
|
||||
opt = get_operations(g)
|
||||
return nothing
|
||||
end
|
@ -11,7 +11,18 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Get machine and set dictionary caching strategy\n",
|
||||
"machine = get_machine_info()\n",
|
||||
"MetagraphOptimization.set_cache_strategy(machine.devices[1], MetagraphOptimization.LocalVariables())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
@ -19,19 +30,19 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Graph:\n",
|
||||
" Nodes: Total: 438436, ComputeTaskP: 10, ComputeTaskU: 10, \n",
|
||||
" ComputeTaskV: 109600, ComputeTaskSum: 1, ComputeTaskS2: 40320, \n",
|
||||
" ComputeTaskS1: 69272, DataTask: 219223\n",
|
||||
" Edges: 628665\n",
|
||||
" Total Compute Effort: 1.903443e6\n",
|
||||
" Total Data Transfer: 1.8040896e7\n",
|
||||
" Total Compute Intensity: 0.10550712115407128\n"
|
||||
" Nodes: Total: 7854, DataTask: 3931, ComputeTaskABC_S1: 1230, \n",
|
||||
" ComputeTaskABC_Sum: 1, ComputeTaskABC_U: 8, ComputeTaskABC_P: 8, \n",
|
||||
" ComputeTaskABC_V: 1956, ComputeTaskABC_S2: 720\n",
|
||||
" Edges: 11241\n",
|
||||
" Total Compute Effort: 33915.0\n",
|
||||
" Total Data Transfer: 322464.0\n",
|
||||
" Total Compute Intensity: 0.10517453111044954\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"model = ABCModel()\n",
|
||||
"process_str = \"AB->ABBBBBBB\"\n",
|
||||
"process_str = \"AB->ABBBBB\"\n",
|
||||
"process = parse_process(process_str, model)\n",
|
||||
"graph = parse_dag(\"../input/$process_str.txt\", model)\n",
|
||||
"print(graph)"
|
||||
@ -39,449 +50,323 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"compute__8bced4be_8f2e_11ee_37d9_3f851690d249 (generic function with 1 method)"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"compute_AB_AB5 = get_compute_function(graph, process, machine)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"351.606942 seconds (1.13 G allocations: 25.949 GiB, 1.33% gc time, 0.72% compilation time)\n",
|
||||
" 0.184484 seconds (2.75 M allocations: 153.561 MiB, 15.46% gc time)\n",
|
||||
"Graph:\n",
|
||||
" Nodes: Total: 277188, ComputeTaskP: 10, ComputeTaskU: 10, \n",
|
||||
" ComputeTaskV: 69288, ComputeTaskSum: 1, ComputeTaskS2: 40320, \n",
|
||||
" ComputeTaskS1: 28960, DataTask: 138599\n",
|
||||
" Edges: 427105\n",
|
||||
" Total Compute Effort: 1.218139e6\n",
|
||||
" Total Data Transfer: 1.2235968e7\n",
|
||||
" Total Compute Intensity: 0.0995539543745129\n"
|
||||
" Nodes: Total: 4998, DataTask: 2503, ComputeTaskABC_S1: 516, \n",
|
||||
" ComputeTaskABC_Sum: 1, ComputeTaskABC_U: 8, ComputeTaskABC_P: 8, \n",
|
||||
" ComputeTaskABC_V: 1242, ComputeTaskABC_S2: 720\n",
|
||||
" Edges: 7671\n",
|
||||
" Total Compute Effort: 21777.0\n",
|
||||
" Total Data Transfer: 253920.0\n",
|
||||
" Total Compute Intensity: 0.0857632325141777\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"include(\"../examples/profiling_utilities.jl\")\n",
|
||||
"@time reduce_all!(graph)\n",
|
||||
"@time optimize_to_fixpoint!(ReductionOptimizer(), graph)\n",
|
||||
"print(graph)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Found 1 NUMA nodes\n",
|
||||
"CUDA is non-functional\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Get machine and set dictionary caching strategy\n",
|
||||
"machine = get_machine_info()\n",
|
||||
"MetagraphOptimization.set_cache_strategy(machine.devices[1], MetagraphOptimization.Dictionary())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2315.896312 seconds (87.18 M allocations: 132.726 GiB, 0.11% gc time, 0.04% compilation time)\n"
|
||||
" 0.822702 seconds (574.85 k allocations: 48.098 MiB, 0.90% gc time)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"compute__8fd7c454_6214_11ee_3616_0f2435e477fe (generic function with 1 method)"
|
||||
"compute__8dffb17a_8f2e_11ee_2d70_13a063f6b2e1 (generic function with 1 method)"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"@time compute_AB_AB7 = get_compute_function(graph, process, machine)"
|
||||
"@time compute_AB_AB5_reduced = get_compute_function(graph, process, machine)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" 1.910169 seconds (4.34 M allocations: 278.284 MiB, 6.25% gc time, 99.23% compilation time)\n"
|
||||
" 0.054193 seconds (108.22 k allocations: 6.222 MiB, 92.26% compilation time)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1000-element Vector{ABCProcessInput}:\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [8.411745173347825, 0.0, 0.0, 8.352092962924948]\n",
|
||||
" B: [8.411745173347825, 0.0, 0.0, -8.352092962924948]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-2.003428483168789, 1.2386385417950023, -0.8321671195319228, 0.8871291535745444]\n",
|
||||
" B: [-2.444326994820653, 1.1775023368116424, -0.9536682034633904, 1.6366855721594777]\n",
|
||||
" B: [-4.289211829680359, -3.7216649121036443, 1.128125248220305, 1.50793959634144]\n",
|
||||
" B: [-1.2727607454602508, 0.07512513775641204, 0.6370236198332677, -0.45659285653208986]\n",
|
||||
" B: [-1.8777156401619268, -1.042329795325101, -0.5508846238377632, -1.0657817573524957]\n",
|
||||
" B: [-1.1322368113474306, 0.0498922458527246, -0.2963537951915457, -0.4377732162313449]\n",
|
||||
" B: [-1.4340705015357569, 0.7798902829682378, 0.144450581630926, -0.6538068364381232]\n",
|
||||
" B: [-2.369739340520482, 1.4429461622447262, 0.7234742923401235, -1.4177996555214083]\n",
|
||||
" A: [5.53824935935883, 0.0, 0.0, 5.447220021849539]\n",
|
||||
" B: [5.53824935935883, 0.0, 0.0, -5.447220021849539]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.3103925957044282, 0.7331872395687581, 0.24174619498761993, 0.34802873993327305]\n",
|
||||
" B: [-1.7235347423723115, -0.9221216475500805, -0.5368654338299067, 0.9121618174658171]\n",
|
||||
" B: [-3.2983236636246445, -1.4122494078132704, -0.264394674616116, -2.7954581120438933]\n",
|
||||
" B: [-1.4663199369248787, -0.21617929792622487, -0.41022326537895987, 0.9669940750145931]\n",
|
||||
" B: [-1.1596695896410607, 0.40971989086421784, 0.1871290088754596, -0.3767570864705371]\n",
|
||||
" B: [-2.118258190450336, 1.4076432228565998, 0.7826081699619032, 0.945030566100747]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [8.262146117199348, 0.0, 0.0, 8.201405883258813]\n",
|
||||
" B: [8.262146117199348, 0.0, 0.0, -8.201405883258813]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-2.022253637967156, 0.040616190652067494, 1.5789161216660899, -0.7712872241073523]\n",
|
||||
" B: [-1.085155894223277, -0.4013306445746292, 0.044561160964560184, -0.12046298778597243]\n",
|
||||
" B: [-2.3099664718736963, -0.6028883246226666, 0.7721426580907682, 1.8374619682515352]\n",
|
||||
" B: [-3.8528592267292674, -1.1057919702708323, -3.154341441424319, -1.6345881470237529]\n",
|
||||
" B: [-1.445065980497648, -0.3803292238069696, -0.9038074225417192, 0.3559459403736899]\n",
|
||||
" B: [-1.637993216461692, 0.18276067729419151, -0.6165325663294264, 1.1267244146927589]\n",
|
||||
" B: [-3.0791604558286254, 1.8666082398498536, 2.1149851082876507, -0.7237684597886623]\n",
|
||||
" B: [-1.091837350817336, 0.4003550554789843, 0.16407638128639515, -0.0700255046122441]\n",
|
||||
" A: [6.406766539805908, 0.0, 0.0, 6.328242844232241]\n",
|
||||
" B: [6.406766539805908, 0.0, 0.0, -6.328242844232241]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.6009185206411505, -0.5320720115654639, 1.09590848570997, -0.2807562558330809]\n",
|
||||
" B: [-3.146359037361951, -0.17028519968266745, 1.7773008494544373, -2.389933018577465]\n",
|
||||
" B: [-1.010135923448664, 0.06427364329577855, -0.1146419285663243, -0.05568402673627389]\n",
|
||||
" B: [-3.6289281421436512, 0.6465018878980286, -0.8216898266580996, 3.328059584585744]\n",
|
||||
" B: [-1.3592677632187082, 0.8038563415980269, -0.35192233894694247, -0.27852199472993183]\n",
|
||||
" B: [-2.06792369279769, -0.8122746615437029, -1.5849552409930403, -0.323164288708993]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [9.522164300929319, 0.0, 0.0, 9.4695096480173]\n",
|
||||
" B: [9.522164300929319, 0.0, 0.0, -9.4695096480173]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-2.2614545815907876, 0.09596466269330481, -1.680314037563078, -1.1320390202111377]\n",
|
||||
" B: [-2.5164555101345942, 2.0544568173259474, 0.7608284478099104, 0.7299969816600982]\n",
|
||||
" B: [-3.527555187469315, 3.1461533872404055, -0.4998113855480195, 1.1382236350884531]\n",
|
||||
" B: [-1.5843416170605953, -0.649775322646379, 0.6368565466386346, -0.8260412390634552]\n",
|
||||
" B: [-1.0715042390215452, 0.33101538188959895, -0.19275377509309963, -0.037364868271978664]\n",
|
||||
" B: [-1.8269658913133924, -1.2104472444295427, -0.7036857693244948, 0.6143681099517287]\n",
|
||||
" B: [-1.7510547915269752, 0.35168054121444203, 0.408535633181173, -1.3325210378384098]\n",
|
||||
" B: [-4.504996783741433, -4.119048223287777, 1.270344339898973, 0.8453774386847008]\n",
|
||||
" A: [4.592675400586894, 0.0, 0.0, 4.482484504731276]\n",
|
||||
" B: [4.592675400586894, 0.0, 0.0, -4.482484504731276]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.1473149674649585, -0.35076892712815855, -0.170139004859497, -0.4053955023873595]\n",
|
||||
" B: [-2.058220554606089, -0.8121547455466859, -1.4272449393744948, 0.7346076529133699]\n",
|
||||
" B: [-2.0024960896606476, 1.3172479417787402, 0.7582221815549833, -0.8366286944540325]\n",
|
||||
" B: [-1.0179814720237987, 0.162899519872391, -0.09860388948222289, -0.0052246328160273445]\n",
|
||||
" B: [-1.834456765054589, -0.0990687609983643, 1.3606293642672649, 0.7100033355854413]\n",
|
||||
" B: [-1.1248809523637056, -0.2181550279779225, -0.42286371210603335, -0.19736215884139197]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [7.225275339000687, 0.0, 0.0, 7.1557392157883655]\n",
|
||||
" B: [7.225275339000687, 0.0, 0.0, -7.1557392157883655]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.5721586195862234, -0.6346644373772993, 0.7957285133297657, -0.6600756851617959]\n",
|
||||
" B: [-1.0093393293662618, -0.11321130994303012, 0.07324286826550051, -0.024177745030521003]\n",
|
||||
" B: [-2.7355755394886443, 0.2329840388558535, -2.4939308642531, -0.4576033371958622]\n",
|
||||
" B: [-1.618399027736879, -0.47727357006920945, 1.0132042772011558, -0.6040218911217943]\n",
|
||||
" B: [-1.7201610947708947, 0.01110230391313025, 0.8839000043421623, -1.0851505486038107]\n",
|
||||
" B: [-1.792300907703241, 0.8101193095744785, -0.625916307414256, 1.0790171565463333]\n",
|
||||
" B: [-1.5563810656498285, -1.1865287585293671, 0.12019738267353275, -0.004910793671790455]\n",
|
||||
" B: [-2.4462350936994026, 1.3574724235754438, 0.2335741258552372, 1.7569228442392408]\n",
|
||||
" A: [4.037101162257922, 0.0, 0.0, 3.9112895308714055]\n",
|
||||
" B: [4.037101162257922, 0.0, 0.0, -3.9112895308714055]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.7053110482506162, -0.23947337333507246, -1.2744970749813946, 0.47581034101100217]\n",
|
||||
" B: [-1.3631569288619594, 0.7221467297219651, 0.42638713494656166, -0.3935669251960867]\n",
|
||||
" B: [-1.0326521624735496, -0.11131042747240362, 0.20341304874809626, 0.11226579619908084]\n",
|
||||
" B: [-1.195196392865049, -0.5445059949974184, -0.16637078706558947, 0.32299907142385453]\n",
|
||||
" B: [-1.1830550739590457, 0.24824882865433953, -0.423307203181585, -0.39850073880304915]\n",
|
||||
" B: [-1.5948307181056223, -0.07510576257141027, 1.2343748815339113, -0.11900754463480165]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [7.94532861335446, 0.0, 0.0, 7.882147345374172]\n",
|
||||
" B: [7.94532861335446, 0.0, 0.0, -7.882147345374172]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-2.118671714766621, -0.6322452591326608, -1.2236882164873555, -1.2615953852509143]\n",
|
||||
" B: [-2.560753710001491, -1.7412395645571277, -1.5891033163317627, 0.01717533495153369]\n",
|
||||
" B: [-1.5550581087132076, -0.639122838128628, -0.9624327134008909, 0.2888788525193626]\n",
|
||||
" B: [-2.181477133464949, 0.4918918998013713, 1.8559068969600523, -0.2692479016749415]\n",
|
||||
" B: [-1.2628370388798702, -0.4013500667990802, 0.24813196852393224, 0.6100049482124643]\n",
|
||||
" B: [-1.901139724448186, 1.3625293914322611, -0.8176066997802711, 0.2989401174693193]\n",
|
||||
" B: [-2.2302691928842697, -0.1867565668705846, 1.9609184768063308, 0.3066290670808993]\n",
|
||||
" B: [-2.0804506035503256, 1.7462930042544484, 0.5278736037099664, 0.009214966692276028]\n",
|
||||
" A: [7.636716907339512, 0.0, 0.0, 7.57096064729207]\n",
|
||||
" B: [7.636716907339512, 0.0, 0.0, -7.57096064729207]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.8228350224036067, -0.22313230508453247, 0.05829362440621317, -1.5064997001932685]\n",
|
||||
" B: [-2.467409891320565, 1.6506915327402656, -0.771321444516658, 1.3298091083892047]\n",
|
||||
" B: [-3.7191367050304223, 1.01401048234514, -0.8448690579747132, -3.3301586819963456]\n",
|
||||
" B: [-1.086062092991359, 0.018065163049532738, 0.4218324659828878, 0.035523096142663795]\n",
|
||||
" B: [-3.708627500490809, -3.0248517041401413, 1.3840072581447456, 1.2995052961646025]\n",
|
||||
" B: [-2.4693626024422626, 0.5652168310897357, -0.24794284604247502, 2.171820881493144]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [5.597768901835826, 0.0, 0.0, 5.507723366179557]\n",
|
||||
" B: [5.597768901835826, 0.0, 0.0, -5.507723366179557]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.0009073340208385, 0.03522831505376105, -0.010844681575969111, -0.021374049609080487]\n",
|
||||
" B: [-1.3943823799403026, -0.886019044587247, 0.21582726795187737, -0.3356948979730148]\n",
|
||||
" B: [-1.0593061926863385, 0.3261714964515558, -0.10930051701751846, -0.06160488410736567]\n",
|
||||
" B: [-1.0190344437384602, 0.02512063114228613, 0.04379726771854621, -0.18942531709556668]\n",
|
||||
" B: [-1.0919277601624486, -0.39612686480944176, 0.07078221355247243, -0.17429750036714983]\n",
|
||||
" B: [-1.8292258091360047, 1.1565638126055895, 0.329244535677723, 0.9486966026643375]\n",
|
||||
" B: [-1.7379569022732355, 0.6562121276078657, 0.7749535141539342, -0.9946491284065995]\n",
|
||||
" B: [-2.0627969817140217, -0.9171504734643696, -1.3144596004610647, 0.8283491748944392]\n",
|
||||
" A: [4.844757462595395, 0.0, 0.0, 4.740429819264681]\n",
|
||||
" B: [4.844757462595395, 0.0, 0.0, -4.740429819264681]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.3377157678137663, -0.44312783214029056, -0.34462836811169034, -0.6887325226333468]\n",
|
||||
" B: [-1.0287552354600262, 0.10884372468923921, -0.0798214909694111, 0.20029704855940197]\n",
|
||||
" B: [-1.237602042094568, -0.1707812371296387, -0.708500409075891, -0.02279811352743621]\n",
|
||||
" B: [-1.2285767946957649, -0.45314793159826366, 0.5376309116329622, -0.12251895938933055]\n",
|
||||
" B: [-2.3944375695065316, 0.5631279933752329, -1.4234056115727505, 1.5460060162511446]\n",
|
||||
" B: [-2.4624275156201336, 0.3950852828037212, 2.0187249680967807, -0.9122534692604332]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [6.860362769879496, 0.0, 0.0, 6.787089017712134]\n",
|
||||
" B: [6.860362769879496, 0.0, 0.0, -6.787089017712134]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-2.1483538194490985, 1.8204047500578164, 0.1342978924269131, -0.532461036694855]\n",
|
||||
" B: [-1.2136825716769264, 0.12932805245115084, -0.43609629710270903, -0.5158678699965871]\n",
|
||||
" B: [-3.3642987422516573, -1.7653207470663739, 0.533955101409256, 2.630026736893018]\n",
|
||||
" B: [-1.053677321951765, 0.11000921943972916, 0.04739423847128557, -0.30965732123337875]\n",
|
||||
" B: [-1.2932387925896982, -0.6843810329952256, 0.045636429012288295, -0.4494513240410521]\n",
|
||||
" B: [-1.1237194151971648, -0.45140047643622017, 0.19994785657222267, -0.13785422959193222]\n",
|
||||
" B: [-1.7619597212239484, 1.3299261857304887, 0.561749934748497, 0.1422512233127988]\n",
|
||||
" B: [-1.7617951554187332, -0.488565951181366, -1.0868851555377534, -0.8269861786480115]\n",
|
||||
" A: [6.914095647194839, 0.0, 0.0, 6.841397417089481]\n",
|
||||
" B: [6.914095647194839, 0.0, 0.0, -6.841397417089481]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.8747539146164607, -1.15195487912761, 1.0796978964166692, -0.14817101368775237]\n",
|
||||
" B: [-2.0219963752169967, -0.8963094934108238, -1.380862038576808, 0.6150761447412909]\n",
|
||||
" B: [-2.4839643051342004, -0.5463241040770312, 0.28470426735854887, -2.1887329948244236]\n",
|
||||
" B: [-1.0870998264481033, 0.03306160941873628, 0.20168848226668348, -0.3741854069403313]\n",
|
||||
" B: [-2.4584897964753116, 0.9082805780526032, -1.8726214974559325, -0.844089567623928]\n",
|
||||
" B: [-3.9018870764986056, 1.6532462891441266, 1.6873928899908393, 2.9401028383351444]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [9.57507915889135, 0.0, 0.0, 9.522717096450755]\n",
|
||||
" B: [9.57507915889135, 0.0, 0.0, -9.522717096450755]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-3.4305207411483516, 2.6682294806816835, -1.883054168339437, -0.3211401453721668]\n",
|
||||
" B: [-2.185574270107571, 1.4558232366821502, 1.2235951792097912, 0.40016050668089054]\n",
|
||||
" B: [-3.0259648593433583, -0.9184166853584697, -0.10930222461665634, -2.7020412923806107]\n",
|
||||
" B: [-3.246659025038245, -2.493839704051011, -1.0189869044243565, 1.5110340975546257]\n",
|
||||
" B: [-1.4247322676315595, 0.05954103854817788, 0.9940897925990366, -0.19519831815252583]\n",
|
||||
" B: [-1.4889906300188005, 0.5912092032645169, -0.19371449043911573, -0.9110650198822441]\n",
|
||||
" B: [-1.1268952499657272, 0.36236812621338876, -0.3636229828302436, 0.07975319340034331]\n",
|
||||
" B: [-3.220821274529085, -1.7249146959804351, 1.350995798840981, 2.1384969781516885]\n",
|
||||
" A: [4.882838018892802, 0.0, 0.0, 4.77934170349275]\n",
|
||||
" B: [4.882838018892802, 0.0, 0.0, -4.77934170349275]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.3368922715636002, -0.024254114235374817, -0.17993280734873465, 0.8685141729118435]\n",
|
||||
" B: [-1.336032053759296, 0.44580739433740213, 0.4009862518446777, -0.6522633223307408]\n",
|
||||
" B: [-1.1917158881102905, 0.11587748600254362, 0.21032579337862262, -0.6020981870524788]\n",
|
||||
" B: [-1.8590179700604674, -0.4659878149612763, 1.4629321849562218, 0.3140582613697155]\n",
|
||||
" B: [-1.2740128533657533, -0.3900331968801154, 0.6651639498517544, 0.16893719451393388]\n",
|
||||
" B: [-2.7680050009261956, 0.3185902457368207, -2.559475372682542, -0.09714811941227354]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [8.472852690841874, 0.0, 0.0, 8.413633740584764]\n",
|
||||
" B: [8.472852690841874, 0.0, 0.0, -8.413633740584764]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.1530011327357317, 0.34211475449117323, -0.45923141786607913, -0.03841369149190832]\n",
|
||||
" B: [-2.62915067223017, 1.042431210232047, 0.6288618003426715, -2.1048285595963105]\n",
|
||||
" B: [-1.1265473249385953, -0.4344882737979479, -0.1553035746380426, 0.2370856700921221]\n",
|
||||
" B: [-1.4826889242092416, -0.5889894099544346, -0.45026884678673923, -0.8054290077639529]\n",
|
||||
" B: [-4.118520088756618, -2.101194203160593, -3.0008966741533745, 1.5943054265577095]\n",
|
||||
" B: [-3.9992129109551517, 1.0607252636964415, 3.6847882851419875, 0.539352496783755]\n",
|
||||
" B: [-1.3172538577755006, 0.4084669000294691, -0.6351790575407871, 0.4060296568803221]\n",
|
||||
" B: [-1.1193304700827373, 0.2709337584638445, 0.3872294855003629, 0.17189800853826395]\n",
|
||||
" A: [4.215107110349817, 0.0, 0.0, 4.094768363622244]\n",
|
||||
" B: [4.215107110349817, 0.0, 0.0, -4.094768363622244]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.3241447475687065, 0.7510738166043768, -0.3909856211208319, 0.19072933335458914]\n",
|
||||
" B: [-1.7731907344857587, 0.036019000265901324, 1.4622797510086056, -0.06816114931690141]\n",
|
||||
" B: [-1.019387957593508, 0.014655316462798782, 0.19300767940790514, -0.04104954903058491]\n",
|
||||
" B: [-1.6169881803397028, 0.04956396056952302, -1.0323879934365006, -0.7391679242087841]\n",
|
||||
" B: [-1.6537900060652204, -1.1032956801849205, -0.08849835738509954, 0.7140924778952892]\n",
|
||||
" B: [-1.0427125946467377, 0.2519835862823207, -0.14341545847407883, -0.056443188693607704]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [5.913538688235051, 0.0, 0.0, 5.828373685450576]\n",
|
||||
" B: [5.913538688235051, 0.0, 0.0, -5.828373685450576]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.6813734506828508, -1.1942921586618185, -0.384476919421686, 0.5028522833318558]\n",
|
||||
" B: [-1.412586238014363, 0.010275442474480664, 0.8780055986304257, -0.4737092609218783]\n",
|
||||
" B: [-1.5338446207986793, 1.1234162145644635, 0.1670274754582306, -0.25043392751132176]\n",
|
||||
" B: [-1.4260274101869397, 0.9023875675844153, -0.4646063309051003, -0.058239245843783906]\n",
|
||||
" B: [-1.1055189977833793, -0.3699146930280028, 0.2809292901965394, -0.08008812803177658]\n",
|
||||
" B: [-1.1926016738662872, 0.4242726765633766, 0.34415633034138016, -0.3519202590308968]\n",
|
||||
" B: [-1.4188061371181722, 0.47356120240959365, 0.33662773751584696, 0.8218469496393668]\n",
|
||||
" B: [-2.0563188480194308, -1.3697062519065082, -1.1576631818156364, -0.1103084116315648]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [6.062750568659298, 0.0, 0.0, 5.979711068085032]\n",
|
||||
" B: [6.062750568659298, 0.0, 0.0, -5.979711068085032]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.1157392140073992, -0.0424317149721654, 0.4662958482482185, -0.16013033799016252]\n",
|
||||
" B: [-2.395340693850968, -1.171776361305547, -1.746409249879336, 0.5609384374776449]\n",
|
||||
" B: [-1.0289722654275464, 0.23139962589771268, 0.07055331234631396, 0.01613586906426155]\n",
|
||||
" B: [-1.212565238145815, -0.6377842504248107, 0.04163119753237706, 0.24862129848767983]\n",
|
||||
" B: [-1.8156755638105053, -0.3987185167288875, 1.2510245302740972, 0.7567290942527487]\n",
|
||||
" B: [-2.003891077687212, 1.2159250459117166, 0.38048599808923245, -1.1799729400359336]\n",
|
||||
" B: [-1.4663599649673638, 0.593985649692284, -0.7733488095969958, -0.44645740391848543]\n",
|
||||
" B: [-1.086957119421786, 0.20940052192969777, 0.3097671729860923, 0.20413598266224653]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [7.088363151833832, 0.0, 0.0, 7.017470496715726]\n",
|
||||
" B: [7.088363151833832, 0.0, 0.0, -7.017470496715726]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-3.1474601133746627, 0.14412280671945385, 2.7364508363525357, 1.1821889028802701]\n",
|
||||
" B: [-1.256451004773104, 0.1153142495225348, -0.7455659837621855, -0.09748392231091944]\n",
|
||||
" B: [-1.4964417911663928, -0.0996845872039782, -0.8492275192498467, 0.7128910421459969]\n",
|
||||
" B: [-3.2499484244824526, -0.8927423628721523, -1.0242747556675866, -2.777775559729678]\n",
|
||||
" B: [-1.0489067674373789, -0.31603136975662793, 0.016268502528308637, -0.008057042333727152]\n",
|
||||
" B: [-1.6957667777105587, 1.0857339287179024, 0.6252297389508089, 0.5530773670555896]\n",
|
||||
" B: [-1.243679438145053, 0.06348629097723194, -0.7145975145476898, 0.17904867473682565]\n",
|
||||
" B: [-1.0380719865780628, -0.10019895610436466, -0.044283304604344965, 0.2561105375556422]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [9.842517855137334, 0.0, 0.0, 9.791586068084028]\n",
|
||||
" B: [9.842517855137334, 0.0, 0.0, -9.791586068084028]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.0081083393933719, 0.09315850477843095, -0.05390640772287413, 0.06854207575149836]\n",
|
||||
" B: [-1.2533776879399583, -0.09567218890986252, -0.022562148977002077, -0.749195175056841]\n",
|
||||
" B: [-4.199102452438099, 3.1204551726062775, 2.23725963921713, 1.3747327844190023]\n",
|
||||
" B: [-5.1018332572388285, -4.999892707918183, 0.09407944148737099, -0.14465321518774693]\n",
|
||||
" B: [-3.7582268429742243, 2.1814891293707577, -1.5410280493623207, -2.4475715991095703]\n",
|
||||
" B: [-1.1792132348986593, 0.6125282131702711, -0.12369433042852651, -0.007263198361168502]\n",
|
||||
" B: [-1.3600169327450258, -0.07835376476887727, -0.6694537001487819, 0.6287594836317273]\n",
|
||||
" B: [-1.8251569626465018, -0.8337123583288142, 0.07930555593500455, 1.2766488439130985]\n",
|
||||
" A: [7.2720657357811564, 0.0, 0.0, 7.202981331748843]\n",
|
||||
" B: [7.2720657357811564, 0.0, 0.0, -7.202981331748843]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.110939233644008, -0.268184416567738, 0.24360224044987097, 0.3208131044822848]\n",
|
||||
" B: [-2.6388927199644003, 0.8314814079287018, -0.21777668284358856, 2.2858186218857472]\n",
|
||||
" B: [-3.473898607870094, 2.051862236379928, 2.4003392500206266, -1.046997796315806]\n",
|
||||
" B: [-3.152819934613197, -1.9424358511984305, -2.028267056813039, -1.0263280422556738]\n",
|
||||
" B: [-2.275152937944009, -1.7654922583464505, 0.7703768739716074, -0.6825521583027478]\n",
|
||||
" B: [-1.8924280375266047, 1.0927688818039885, -1.1682746247854774, 0.14924627050619674]\n",
|
||||
"\n",
|
||||
" ⋮\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [9.861596443743153, 0.0, 0.0, 9.810763702141012]\n",
|
||||
" B: [9.861596443743153, 0.0, 0.0, -9.810763702141012]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.8179384769334697, 0.9572508915748105, -0.9794338269553214, 0.6551949443563104]\n",
|
||||
" B: [-2.1028582035167607, -0.7676665378472812, 0.6218562087985972, -1.5639678917247444]\n",
|
||||
" B: [-3.1263866679666865, 2.3808322573838474, -1.6099851834448586, 0.7168535896041835]\n",
|
||||
" B: [-5.177179415841987, -1.3605325795287053, 4.805481256903438, -0.9270855911989424]\n",
|
||||
" B: [-1.2605754590213083, -0.023284320526100116, -0.14250915308265208, 0.7537900699744495]\n",
|
||||
" B: [-2.712925004518324, -1.4343063146086636, -1.452340398698398, 1.4810249296764189]\n",
|
||||
" B: [-2.3798188172675734, 0.6412170781802653, -1.487389994435021, -1.4283029321979925]\n",
|
||||
" B: [-1.1455108424201939, -0.39351047462817185, 0.24432109091421514, 0.3124928815103169]\n",
|
||||
" A: [6.22966038636724, 0.0, 0.0, 6.148875387375584]\n",
|
||||
" B: [6.22966038636724, 0.0, 0.0, -6.148875387375584]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.4304429070664482, -0.33884344128192095, 0.8653360836289696, -0.42725343187224885]\n",
|
||||
" B: [-1.9749814666096197, 1.3609392980219706, -0.9441991051819204, -0.39608593805462516]\n",
|
||||
" B: [-2.2715747343865793, 1.2408591011012648, 1.6172984936557957, 0.06830847338590983]\n",
|
||||
" B: [-1.661609068228756, -0.4012681871023404, -1.1964016761233542, 0.4105503221395213]\n",
|
||||
" B: [-1.746963024762814, 1.345279186098992, -0.06451410595930414, 0.48779263162695097]\n",
|
||||
" B: [-3.373749571680263, -3.2069659568379674, -0.2775196900201868, -0.1433120572255088]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [5.611571819338176, 0.0, 0.0, 5.521751378284825]\n",
|
||||
" B: [5.611571819338176, 0.0, 0.0, -5.521751378284825]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.0759150984150232, -0.3903007964405737, 0.045679777762273936, -0.05632002484775736]\n",
|
||||
" B: [-1.021003529021616, -0.07269336486556076, 0.11388411952175649, 0.15554513267817288]\n",
|
||||
" B: [-1.6939705353811365, -0.1440535362616654, -0.25084793375093056, -1.3363607550219565]\n",
|
||||
" B: [-1.185801144621379, -0.31618880274591826, 0.5459120200606805, -0.09016131075324207]\n",
|
||||
" B: [-1.197431131926246, 0.16472462054297168, -0.17198607315407527, -0.6141074056988615]\n",
|
||||
" B: [-1.0089442324730478, -0.12314856400749492, -0.027052115631495212, -0.04550910308256443]\n",
|
||||
" B: [-2.703474424566498, 0.16902217864171518, -0.14049660772763695, 2.502092358533033]\n",
|
||||
" B: [-1.3366035422714058, 0.7126382651365266, -0.11509318708057305, -0.5151788918068239]\n",
|
||||
" A: [4.358722688789774, 0.0, 0.0, 4.242459602373458]\n",
|
||||
" B: [4.358722688789774, 0.0, 0.0, -4.242459602373458]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.0452779390743625, -0.2727572224505045, -0.0754336299872278, 0.11188938726967125]\n",
|
||||
" B: [-1.7048247824379945, 0.4983084694471347, 0.872827621048126, 0.9467249611304639]\n",
|
||||
" B: [-1.2899467751023526, 0.29644307338358544, -0.46128198344041976, -0.602746313628815]\n",
|
||||
" B: [-2.1244189851466975, -1.8139000349895653, -0.4266469607437963, -0.20222526648433034]\n",
|
||||
" B: [-1.4709803178987078, 1.0687795622551313, -0.1466043527374882, 0.0007118353293400601]\n",
|
||||
" B: [-1.0819965779194327, 0.22312615235421782, 0.23713930586080637, -0.25435460361632983]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [8.775111706253933, 0.0, 0.0, 8.717946171962454]\n",
|
||||
" B: [8.775111706253933, 0.0, 0.0, -8.717946171962454]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-2.2750151423103953, 1.8467170131598, 0.8729070809034145, 0.05799482008261441]\n",
|
||||
" B: [-1.5756212156561644, 1.0377655822554295, 0.3001332912880399, 0.5617337616455574]\n",
|
||||
" B: [-1.6945981163898138, -0.5153714693329569, 0.050834292767083435, 1.2662823142365867]\n",
|
||||
" B: [-2.630307241578496, -0.5126707368632603, 1.3344949978186418, -1.9684532002212756]\n",
|
||||
" B: [-3.0848917600353407, -2.827901193400985, -0.46541663267058264, -0.5503811129833626]\n",
|
||||
" B: [-2.812675339815945, 2.346626876124383, -1.1757879806725677, 0.14834923648401968]\n",
|
||||
" B: [-1.695817659938434, -0.3817827622891304, -0.19598317768122073, 1.3006267920675472]\n",
|
||||
" B: [-1.7812969367832734, -0.9933833096532803, -0.7211818717528079, -0.8161526113116866]\n",
|
||||
" A: [4.946953336826144, 0.0, 0.0, 4.844826861378569]\n",
|
||||
" B: [4.946953336826144, 0.0, 0.0, -4.844826861378569]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.0798321354813016, -0.05701177676898147, 0.3748038410417432, -0.1493625751924078]\n",
|
||||
" B: [-2.535607459805834, 0.2786802518140389, -2.1413493157456154, 0.8753659894167939]\n",
|
||||
" B: [-1.1465622434125131, 0.048325266102822936, -0.30303094935893476, 0.46951239643469417]\n",
|
||||
" B: [-1.0565850692648957, -0.15422821749644713, -0.2946016814579471, -0.0761282786060691]\n",
|
||||
" B: [-1.3897397103611828, 0.8757386144485694, 0.40183039146109456, 0.054687093694094344]\n",
|
||||
" B: [-2.6855800553265587, -0.9915041381000028, 1.96234771405966, -1.1740746257471053]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [6.832501783927461, 0.0, 0.0, 6.758925996589395]\n",
|
||||
" B: [6.832501783927461, 0.0, 0.0, -6.758925996589395]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.0114752465345387, -0.11558780230223581, -0.03776248532804595, -0.09108034372406744]\n",
|
||||
" B: [-1.031154612454516, -0.04425244057817861, -0.0789748074180023, -0.23470095032271823]\n",
|
||||
" B: [-2.2555952063288855, 1.7491237654517413, -0.4233804231771479, -0.9214254203222908]\n",
|
||||
" B: [-2.089561973736715, 0.9235335217807571, 1.3477207222453012, -0.8348676128969853]\n",
|
||||
" B: [-1.3199981586264844, -0.6902187266500668, -0.06216816149242132, -0.5119847340063199]\n",
|
||||
" B: [-1.0105028642371863, -0.09317036739551621, -0.041275823376393385, -0.1035935696630954]\n",
|
||||
" B: [-1.2426376312622325, -0.48126859609618416, 0.05225488689293943, -0.5565952280036419]\n",
|
||||
" B: [-3.704077874674367, -1.2481593542103167, -0.7564139083462295, 3.254247858939119]\n",
|
||||
" A: [5.263219273050624, 0.0, 0.0, 5.1673472029864165]\n",
|
||||
" B: [5.263219273050624, 0.0, 0.0, -5.1673472029864165]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-2.399019535788919, -1.2110047848361276, -1.812263889139395, -0.06679625979229631]\n",
|
||||
" B: [-2.017935306086244, -0.3374680394916718, 1.6282821358219384, 0.5539634536990483]\n",
|
||||
" B: [-1.6695031594114513, 0.8270762338660977, -0.06260699981442713, 1.0484589005931164]\n",
|
||||
" B: [-2.2597097606741916, 0.7611180237287621, 0.18055687193684328, -1.869327893238054]\n",
|
||||
" B: [-1.073204850363539, -0.22248377596385552, 0.3188604064962904, -0.024447115284049005]\n",
|
||||
" B: [-1.1070659337769053, 0.18276234269679548, -0.25282852530124955, 0.3581489140222342]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [8.775903429741401, 0.0, 0.0, 8.718743086485969]\n",
|
||||
" B: [8.775903429741401, 0.0, 0.0, -8.718743086485969]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.7137666526922533, 1.1358800766324049, 0.08268488211087159, 0.7999598750311686]\n",
|
||||
" B: [-1.1669696745288112, -0.04351472671445914, 0.5992401461010018, 0.028912577361687116]\n",
|
||||
" B: [-3.5481649603318184, 0.4490928742123019, 1.0371640968528058, -3.21124287656006]\n",
|
||||
" B: [-1.276578701414564, -0.08287623449031867, -0.6317118623642547, -0.47299559576203803]\n",
|
||||
" B: [-4.955351547203613, -2.6459981607514886, 0.5026315754882429, 4.037519558961317]\n",
|
||||
" B: [-2.3130557250521284, 1.4242375193555785, -1.5228161303749386, 0.05296516521446809]\n",
|
||||
" B: [-1.4353464814836179, 0.25997106791735547, -0.029309860840599063, -0.9958792586507745]\n",
|
||||
" B: [-1.1425731167759967, -0.4967924161613736, -0.03788284697312998, -0.23923944559576807]\n",
|
||||
" A: [4.459941032222146, 0.0, 0.0, 4.346386316343583]\n",
|
||||
" B: [4.459941032222146, 0.0, 0.0, -4.346386316343583]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.9579957774892203, 0.01711251988645602, -0.9941971785148113, 1.3583175610150744]\n",
|
||||
" B: [-2.2086526478827153, 0.26811947256465357, -0.29730202477347406, -1.9281778894844153]\n",
|
||||
" B: [-1.1393295497986875, -0.09576318262839165, 0.3418914140864091, 0.4147426875441645]\n",
|
||||
" B: [-1.5437833884502452, -0.2526758526831343, 1.1436052762387854, 0.10765238541055888]\n",
|
||||
" B: [-1.029324601398587, -0.04086809209820055, -0.11666716588470447, -0.21030384327692128]\n",
|
||||
" B: [-1.040796099424839, 0.10407513495861721, -0.07733032115220424, 0.25776909879153836]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [8.907102929629284, 0.0, 0.0, 8.850789942090511]\n",
|
||||
" B: [8.907102929629284, 0.0, 0.0, -8.850789942090511]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-2.946046511363992, -0.9439001466724447, 2.1873638734369836, 1.4155146927582347]\n",
|
||||
" B: [-3.7848309582649415, -2.22832689875391, -0.18756115269295068, -2.885190709282662]\n",
|
||||
" B: [-1.0159875652570234, 0.04172671107403079, -0.15271016054388648, 0.08467125371989566]\n",
|
||||
" B: [-2.0867601165869685, -1.8155383548303043, -0.021995043965926685, -0.24063350631004576]\n",
|
||||
" B: [-4.34790862339958, 3.6266859724946396, -1.8990793068549607, 1.0700261868843775]\n",
|
||||
" B: [-1.1578951917200673, 0.35622580432348594, 0.23734793715600985, 0.3968506117802061]\n",
|
||||
" B: [-1.4421363377447174, 1.0156020669389267, -0.20020339434090184, -0.0907097523285523]\n",
|
||||
" B: [-1.0326405549212787, -0.052475154574424254, 0.03683724780563263, 0.24947122277854633]\n",
|
||||
" A: [5.6127229037846575, 0.0, 0.0, 5.522921183094041]\n",
|
||||
" B: [5.6127229037846575, 0.0, 0.0, -5.522921183094041]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.3401191006255044, 0.07455340773270878, 0.8329539127008466, 0.3107229836576332]\n",
|
||||
" B: [-2.2407608326391446, 1.9616328357565815, 0.2748188274329855, 0.3122184153114968]\n",
|
||||
" B: [-1.9353505325144305, 0.5041718248979296, 0.4986811623094062, -1.4975678792765024]\n",
|
||||
" B: [-1.1665291383852119, -0.5919830552573446, -0.0003589073718047799, 0.10171609595055851]\n",
|
||||
" B: [-1.3532183234755, -0.2764818233423043, 0.8493370095656062, 0.18271364627008788]\n",
|
||||
" B: [-3.1894678799295257, -1.671893189787572, -2.45543200463704, 0.5901967380867258]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [6.294285658794556, 0.0, 0.0, 6.214340830249562]\n",
|
||||
" B: [6.294285658794556, 0.0, 0.0, -6.214340830249562]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.06844272609547, -0.2848922847204133, 0.15179083391454987, -0.19330232226393051]\n",
|
||||
" B: [-2.114647837734541, -1.6956804594706658, -0.38950327120442063, 0.6668511518515798]\n",
|
||||
" B: [-1.494217345848325, 0.7529614584695401, -0.5432224448027106, -0.6088053006963738]\n",
|
||||
" B: [-1.3783311635115514, 0.9215501628423943, 0.0395584401371469, -0.2213079833313275]\n",
|
||||
" B: [-1.7816982863175768, 0.5393674002906785, 0.38766524831377364, 1.316528482874748]\n",
|
||||
" B: [-1.659172767477475, 0.17135237894801714, -1.2297516401309854, -0.45956886117628726]\n",
|
||||
" B: [-1.55277617510909, -0.23319042207457166, 1.041131562383322, 0.522284545863997]\n",
|
||||
" B: [-1.5392850154950812, -0.17146823428497893, 0.5423312713893238, -1.022679713122405]\n",
|
||||
" A: [4.8915558702989275, 0.0, 0.0, 4.788247991933574]\n",
|
||||
" B: [4.8915558702989275, 0.0, 0.0, -4.788247991933574]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.7166600698631052, -0.6792891539923208, 0.6748994636717233, 1.0148885429772172]\n",
|
||||
" B: [-2.5106233942424825, -0.7525848308448442, -1.9630692909736174, 0.9397897950798489]\n",
|
||||
" B: [-1.0591214238384126, 0.22224342472975844, 0.26723772059994233, -0.030496742226701214]\n",
|
||||
" B: [-2.107615205886531, 1.2019506202258687, 1.111787687227206, -0.8725163042331971]\n",
|
||||
" B: [-1.1276654384352531, 0.3419112314983172, -0.15371273194576066, -0.3620751950278375]\n",
|
||||
" B: [-1.2614262083320695, -0.33423129161677956, 0.06285715142050609, -0.689590096569332]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [6.965556009635571, 0.0, 0.0, 6.8934005050751415]\n",
|
||||
" B: [6.965556009635571, 0.0, 0.0, -6.8934005050751415]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.0775179795487104, -0.05690318568456522, -0.2919638065794134, 0.269377354945329]\n",
|
||||
" B: [-3.216279237662679, -2.600571207682032, 0.23217633942174215, 1.5898351096286563]\n",
|
||||
" B: [-1.9852997763312183, 1.2696870590322706, -0.6412445999499571, -0.9581833525279955]\n",
|
||||
" B: [-1.9885313318262752, 0.8019078287339996, 1.2060162608136897, 0.9255946577864792]\n",
|
||||
" B: [-1.4288503016026572, 0.2805632486843285, 0.07929023042776773, -0.9780646743628009]\n",
|
||||
" B: [-1.3652585458391595, -0.12810083240879516, 0.7809145290728301, -0.4875382774777694]\n",
|
||||
" B: [-1.8158888731893035, 0.7439741257624499, -1.2924797037897653, -0.2710186621991885]\n",
|
||||
" B: [-1.0534859732711408, -0.3105570364376559, -0.07270924941689365, -0.0900021557927108]\n",
|
||||
" A: [7.730105975946025, 0.0, 0.0, 7.665150905191394]\n",
|
||||
" B: [7.730105975946025, 0.0, 0.0, -7.665150905191394]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-1.5069861693238755, -0.14569717271308374, -1.0624243147247645, 0.3478997325070473]\n",
|
||||
" B: [-1.3943234172777221, -0.04432112759455558, 0.08353004942916775, 0.9670554071303941]\n",
|
||||
" B: [-2.959534510858716, -2.3414048211285614, 1.2349523309699664, 0.8669260203682391]\n",
|
||||
" B: [-3.9504084752062516, -1.3395798731389539, -0.8585843373250325, -3.4747785282176675]\n",
|
||||
" B: [-3.4956434330579116, 2.5236614743308494, -0.431975773525167, 2.1596418001942994]\n",
|
||||
" B: [-2.153315946167574, 1.3473415202443053, 1.0345020451758309, -0.8667444319823133]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" Input for ABC Process: 'AB->ABBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [6.43062328219917, 0.0, 0.0, 6.352394493225528]\n",
|
||||
" B: [6.43062328219917, 0.0, 0.0, -6.352394493225528]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-2.125364788369443, -1.214725294501684, 0.4075454777366224, 1.369497946736289]\n",
|
||||
" B: [-1.1032249572940587, -0.2977536437640783, 0.35819035202044425, 0.012155070594697458]\n",
|
||||
" B: [-2.225917349319406, 1.3039585629995813, -0.8668848261688078, 1.2259326287114942]\n",
|
||||
" B: [-2.717025897056506, -0.9721840017189309, 0.6274004665152297, -2.2457641565164295]\n",
|
||||
" B: [-1.000557419196324, 0.013685057618434337, 0.015873673340379625, 0.025997976872664537]\n",
|
||||
" B: [-1.1652637249339481, 0.20750251779397902, -0.05219673300317853, -0.5586212982154317]\n",
|
||||
" B: [-1.4667402310584912, 0.9160649085291783, -0.533306342231441, -0.16654228923208916]\n",
|
||||
" B: [-1.057152197170161, 0.043451893043520345, 0.0433779317907512, 0.3373441210488047]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [8.156196486154876, 0.0, 0.0, 8.094661272762755]\n",
|
||||
" B: [8.156196486154876, 0.0, 0.0, -8.094661272762755]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.4617318374080812, 0.10404421660552193, -0.19476289320497314, -1.0430254938944576]\n",
|
||||
" B: [-2.745518719911882, 2.0283487429720055, -0.01415841484271091, -1.556751090431481]\n",
|
||||
" B: [-1.193795120882441, -0.223211890483827, 0.20666745479885903, 0.5767250694363129]\n",
|
||||
" B: [-1.0771186742980503, 0.29121400254582763, -0.18584437613704033, 0.20209134345899718]\n",
|
||||
" B: [-2.9756813564276348, 0.7747616688600099, 0.31071107817153876, 2.6754219325851647]\n",
|
||||
" B: [-1.8605025819101852, -0.3441559100391822, 0.5570133470539003, 1.4257498722017754]\n",
|
||||
" B: [-3.3546424693401353, -1.4228183303706836, -0.7768040014609222, -2.7614832317390525]\n",
|
||||
" B: [-1.6434022121313414, -1.2081825000896715, 0.0971778056213486, 0.48127159838273986]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [9.631814348202784, 0.0, 0.0, 9.579762399884718]\n",
|
||||
" B: [9.631814348202784, 0.0, 0.0, -9.579762399884718]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-2.4271747113709625, -0.9216752449526319, 0.35006248470601437, 1.9796838331313595]\n",
|
||||
" B: [-1.926574191117535, -0.6155920425308834, -0.36855158619622796, 1.4821957628346814]\n",
|
||||
" B: [-2.809711053334662, 0.053095841327541846, -2.415282611989454, -1.0286238083410733]\n",
|
||||
" B: [-2.069340346061984, 0.0706218659128716, 1.6880494984307581, 0.6539655271821153]\n",
|
||||
" B: [-1.600891859223819, 0.522182956459051, 1.0136801062226364, -0.5124766796267364]\n",
|
||||
" B: [-2.3653602811566903, 0.7359929823506941, 2.003935313635875, 0.19361520696286152]\n",
|
||||
" B: [-4.134587420071929, 0.11270979705086029, -1.0448676862999513, -3.871738776569513]\n",
|
||||
" B: [-1.9299888340679847, 0.04266384438249662, -1.2270255185096508, 1.1033789344263045]\n",
|
||||
"\n",
|
||||
" Input for ABC Process: 'AB->ABBBBBBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [7.383091586636561, 0.0, 0.0, 7.31505580133628]\n",
|
||||
" B: [7.383091586636561, 0.0, 0.0, -7.31505580133628]\n",
|
||||
" 8 Outgoing Particles:\n",
|
||||
" A: [-1.0026822379766207, 0.02425303574920085, -0.0683120173174935, 0.010813366763733786]\n",
|
||||
" B: [-3.2851307251831745, -2.830568076855887, -0.9156122597784988, 0.9703723169846757]\n",
|
||||
" B: [-2.028220232462834, 1.6810294384373135, 0.4923274291375999, -0.21314558638988076]\n",
|
||||
" B: [-1.5191535227395792, -0.17123543395193966, -1.1293131485074372, -0.05619309939470401]\n",
|
||||
" B: [-1.1059696544762567, 0.2375361941082015, -0.40208228112542477, -0.07124094550113935]\n",
|
||||
" B: [-1.371740281577803, -0.2278482692103191, -0.6986437390927988, -0.5845113276468179]\n",
|
||||
" B: [-1.2867512190171768, 0.6015837296464805, -0.16735271525316733, -0.5155761675681034]\n",
|
||||
" B: [-3.166535299839676, 0.6852493820769491, 2.888988731937221, 0.4594814427522358]\n"
|
||||
" A: [5.140973354732315, 0.0, 0.0, 5.042777710158126]\n",
|
||||
" B: [5.140973354732315, 0.0, 0.0, -5.042777710158126]\n",
|
||||
" 6 Outgoing Particles:\n",
|
||||
" A: [-2.1212395395513415, 0.5721186152245487, -1.464674439391297, 1.013442776314144]\n",
|
||||
" B: [-1.4152359585953729, 0.6568206137784666, 0.5137348552056548, -0.5545773150462135]\n",
|
||||
" B: [-1.6621060291271548, -0.07490000906447869, -1.013680695206552, 0.8540713605247167]\n",
|
||||
" B: [-1.602034710373159, -1.201656230753467, -0.11487974312683813, 0.3306662379967043]\n",
|
||||
" B: [-1.6826459861655199, -0.324056691191041, 0.7444127790391002, -1.082651555236741]\n",
|
||||
" B: [-1.7986844856520843, 0.3716737020059716, 1.3350872434799315, -0.5609515045526104]\n"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
@ -490,171 +375,37 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Internal error: stack overflow in type inference of materialize(Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(MetagraphOptimization.compute__8fd7c454_6214_11ee_3616_0f2435e477fe), Tuple{Array{MetagraphOptimization.ABCProcessInput, 1}}}).\n",
|
||||
"This might be caused by recursion over very long tuples or argument lists.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "LoadError",
|
||||
"evalue": "StackOverflowError:",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"StackOverflowError:",
|
||||
"",
|
||||
"Stacktrace:",
|
||||
" [1] get",
|
||||
" @ ./iddict.jl:102 [inlined]",
|
||||
" [2] in",
|
||||
" @ ./iddict.jl:189 [inlined]",
|
||||
" [3] haskey",
|
||||
" @ ./abstractdict.jl:17 [inlined]",
|
||||
" [4] findall(sig::Type, table::Core.Compiler.CachedMethodTable{Core.Compiler.InternalMethodTable}; limit::Int64)",
|
||||
" @ Core.Compiler ./compiler/methodtable.jl:120",
|
||||
" [5] findall",
|
||||
" @ ./compiler/methodtable.jl:114 [inlined]",
|
||||
" [6] find_matching_methods(argtypes::Vector{Any}, atype::Any, method_table::Core.Compiler.CachedMethodTable{Core.Compiler.InternalMethodTable}, union_split::Int64, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:336",
|
||||
" [7] abstract_call_gf_by_type(interp::Core.Compiler.NativeInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, atype::Any, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:80",
|
||||
" [8] abstract_call_known(interp::Core.Compiler.NativeInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1949",
|
||||
" [9] abstract_call(interp::Core.Compiler.NativeInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2020",
|
||||
" [10] abstract_apply(interp::Core.Compiler.NativeInterpreter, argtypes::Vector{Any}, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1566",
|
||||
" [11] abstract_call_known(interp::Core.Compiler.NativeInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1855",
|
||||
" [12] abstract_call(interp::Core.Compiler.NativeInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Nothing)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2020",
|
||||
" [13] abstract_call(interp::Core.Compiler.NativeInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1999",
|
||||
" [14] abstract_eval_statement_expr(interp::Core.Compiler.NativeInterpreter, e::Expr, vtypes::Vector{Core.Compiler.VarState}, sv::Core.Compiler.InferenceState, mi::Nothing)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2183",
|
||||
" [15] abstract_eval_statement(interp::Core.Compiler.NativeInterpreter, e::Any, vtypes::Vector{Core.Compiler.VarState}, sv::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2396",
|
||||
" [16] abstract_eval_basic_statement(interp::Core.Compiler.NativeInterpreter, stmt::Any, pc_vartable::Vector{Core.Compiler.VarState}, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2682",
|
||||
" [17] typeinf_local(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2867",
|
||||
" [18] typeinf_nocycle(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2955",
|
||||
" [19] _typeinf(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:246",
|
||||
" [20] typeinf(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:216",
|
||||
" [21] typeinf_edge(interp::Core.Compiler.NativeInterpreter, method::Method, atype::Any, sparams::Core.SimpleVector, caller::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:932",
|
||||
" [22] abstract_call_method(interp::Core.Compiler.NativeInterpreter, method::Method, sig::Any, sparams::Core.SimpleVector, hardlimit::Bool, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:611",
|
||||
" [23] abstract_call_gf_by_type(interp::Core.Compiler.NativeInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, atype::Any, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:152",
|
||||
"--- the last 16 lines are repeated 413 more times ---",
|
||||
" [6632] abstract_call_known(interp::Core.Compiler.NativeInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1949",
|
||||
" [6633] abstract_call(interp::Core.Compiler.NativeInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2020",
|
||||
" [6634] abstract_apply(interp::Core.Compiler.NativeInterpreter, argtypes::Vector{Any}, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1566",
|
||||
" [6635] abstract_call_known(interp::Core.Compiler.NativeInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1855",
|
||||
" [6636] abstract_call(interp::Core.Compiler.NativeInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Nothing)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2020",
|
||||
" [6637] abstract_call(interp::Core.Compiler.NativeInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1999",
|
||||
" [6638] abstract_eval_statement_expr(interp::Core.Compiler.NativeInterpreter, e::Expr, vtypes::Vector{Core.Compiler.VarState}, sv::Core.Compiler.InferenceState, mi::Nothing)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2183",
|
||||
" [6639] abstract_eval_statement(interp::Core.Compiler.NativeInterpreter, e::Any, vtypes::Vector{Core.Compiler.VarState}, sv::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2396",
|
||||
" [6640] abstract_eval_basic_statement(interp::Core.Compiler.NativeInterpreter, stmt::Any, pc_vartable::Vector{Core.Compiler.VarState}, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2658",
|
||||
" [6641] typeinf_local(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2867",
|
||||
" [6642] typeinf_nocycle(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2955",
|
||||
" [6643] _typeinf(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:246",
|
||||
" [6644] typeinf(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:216",
|
||||
" [6645] typeinf_edge(interp::Core.Compiler.NativeInterpreter, method::Method, atype::Any, sparams::Core.SimpleVector, caller::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:932",
|
||||
" [6646] abstract_call_method(interp::Core.Compiler.NativeInterpreter, method::Method, sig::Any, sparams::Core.SimpleVector, hardlimit::Bool, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:611",
|
||||
" [6647] abstract_call_gf_by_type(interp::Core.Compiler.NativeInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, atype::Any, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:152",
|
||||
" [6648] abstract_call_known(interp::Core.Compiler.NativeInterpreter, f::Any, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Int64)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1949",
|
||||
" [6649] abstract_call(interp::Core.Compiler.NativeInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState, max_methods::Nothing)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2020",
|
||||
" [6650] abstract_call(interp::Core.Compiler.NativeInterpreter, arginfo::Core.Compiler.ArgInfo, si::Core.Compiler.StmtInfo, sv::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:1999",
|
||||
" [6651] abstract_eval_statement_expr(interp::Core.Compiler.NativeInterpreter, e::Expr, vtypes::Vector{Core.Compiler.VarState}, sv::Core.Compiler.InferenceState, mi::Nothing)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2183",
|
||||
" [6652] abstract_eval_statement(interp::Core.Compiler.NativeInterpreter, e::Any, vtypes::Vector{Core.Compiler.VarState}, sv::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2396",
|
||||
" [6653] abstract_eval_basic_statement(interp::Core.Compiler.NativeInterpreter, stmt::Any, pc_vartable::Vector{Core.Compiler.VarState}, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2682",
|
||||
" [6654] typeinf_local(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2867",
|
||||
" [6655] typeinf_nocycle(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/abstractinterpretation.jl:2955",
|
||||
" [6656] _typeinf(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:246",
|
||||
" [6657] typeinf(interp::Core.Compiler.NativeInterpreter, frame::Core.Compiler.InferenceState)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:216",
|
||||
" [6658] typeinf",
|
||||
" @ ./compiler/typeinfer.jl:12 [inlined]",
|
||||
" [6659] typeinf_type(interp::Core.Compiler.NativeInterpreter, method::Method, atype::Any, sparams::Core.SimpleVector)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:1079",
|
||||
" [6660] return_type(interp::Core.Compiler.NativeInterpreter, t::DataType)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:1140",
|
||||
" [6661] return_type(f::Any, t::DataType)",
|
||||
" @ Core.Compiler ./compiler/typeinfer.jl:1112",
|
||||
" [6662] combine_eltypes(f::Function, args::Tuple{Vector{ABCProcessInput}})",
|
||||
" @ Base.Broadcast ./broadcast.jl:730",
|
||||
" [6663] copy(bc::Base.Broadcast.Broadcasted{Style}) where Style",
|
||||
" @ Base.Broadcast ./broadcast.jl:895",
|
||||
" [6664] materialize(bc::Base.Broadcast.Broadcasted)",
|
||||
" @ Base.Broadcast ./broadcast.jl:873",
|
||||
" [6665] var\"##core#293\"()",
|
||||
" @ Main ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:489",
|
||||
" [6666] var\"##sample#294\"(::Tuple{}, __params::BenchmarkTools.Parameters)",
|
||||
" @ Main ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:495",
|
||||
" [6667] _run(b::BenchmarkTools.Benchmark, p::BenchmarkTools.Parameters; verbose::Bool, pad::String, kwargs::Base.Pairs{Symbol, Integer, NTuple{4, Symbol}, NamedTuple{(:samples, :evals, :gctrial, :gcsample), Tuple{Int64, Int64, Bool, Bool}}})",
|
||||
" @ BenchmarkTools ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:99",
|
||||
" [6668] #invokelatest#2",
|
||||
" @ ./essentials.jl:821 [inlined]",
|
||||
" [6669] invokelatest",
|
||||
" @ ./essentials.jl:816 [inlined]",
|
||||
" [6670] #run_result#45",
|
||||
" @ ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:34 [inlined]",
|
||||
" [6671] run_result",
|
||||
" @ ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:34 [inlined]",
|
||||
" [6672] run(b::BenchmarkTools.Benchmark, p::BenchmarkTools.Parameters; progressid::Nothing, nleaves::Float64, ndone::Float64, kwargs::Base.Pairs{Symbol, Integer, NTuple{5, Symbol}, NamedTuple{(:verbose, :samples, :evals, :gctrial, :gcsample), Tuple{Bool, Int64, Int64, Bool, Bool}}})",
|
||||
" @ BenchmarkTools ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:117",
|
||||
" [6673] run (repeats 2 times)",
|
||||
" @ ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:117 [inlined]",
|
||||
" [6674] #warmup#54",
|
||||
" @ ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:169 [inlined]",
|
||||
" [6675] warmup(item::BenchmarkTools.Benchmark)",
|
||||
" @ BenchmarkTools ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:168"
|
||||
]
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"BenchmarkTools.Trial: 231 samples with 1 evaluation.\n",
|
||||
" Range \u001b[90m(\u001b[39m\u001b[36m\u001b[1mmin\u001b[22m\u001b[39m … \u001b[35mmax\u001b[39m\u001b[90m): \u001b[39m\u001b[36m\u001b[1m18.197 ms\u001b[22m\u001b[39m … \u001b[35m27.498 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m0.00% … 8.36%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m21.868 ms \u001b[22m\u001b[39m\u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmedian\u001b[90m): \u001b[39m0.00%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[32m\u001b[1mmean\u001b[22m\u001b[39m ± \u001b[32mσ\u001b[39m\u001b[90m): \u001b[39m\u001b[32m\u001b[1m21.644 ms\u001b[22m\u001b[39m ± \u001b[32m 1.609 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m1.21% ± 2.71%\n",
|
||||
"\n",
|
||||
" \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[32m \u001b[39m\u001b[39m▃\u001b[34m█\u001b[39m\u001b[39m▁\u001b[39m \u001b[39m▅\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \n",
|
||||
" \u001b[39m▃\u001b[39m▃\u001b[39m▁\u001b[39m▅\u001b[39m▇\u001b[39m▃\u001b[39m▅\u001b[39m▅\u001b[39m▅\u001b[39m▃\u001b[39m▄\u001b[39m▃\u001b[39m▃\u001b[39m▅\u001b[39m▄\u001b[39m▅\u001b[39m▃\u001b[39m▅\u001b[39m▄\u001b[39m▃\u001b[39m▅\u001b[39m▄\u001b[39m▃\u001b[39m▅\u001b[39m▇\u001b[39m▅\u001b[39m▅\u001b[32m▆\u001b[39m\u001b[39m█\u001b[34m█\u001b[39m\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▇\u001b[39m▆\u001b[39m▇\u001b[39m▄\u001b[39m▅\u001b[39m▄\u001b[39m▅\u001b[39m▅\u001b[39m▄\u001b[39m▃\u001b[39m▅\u001b[39m▃\u001b[39m▁\u001b[39m▁\u001b[39m▃\u001b[39m▄\u001b[39m▁\u001b[39m▄\u001b[39m▁\u001b[39m▃\u001b[39m▃\u001b[39m▁\u001b[39m▃\u001b[39m▁\u001b[39m▁\u001b[39m▃\u001b[39m \u001b[39m▃\n",
|
||||
" 18.2 ms\u001b[90m Histogram: frequency by time\u001b[39m 25.6 ms \u001b[0m\u001b[1m<\u001b[22m\n",
|
||||
"\n",
|
||||
" Memory estimate\u001b[90m: \u001b[39m\u001b[33m6.78 MiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m17003\u001b[39m."
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"using BenchmarkTools\n",
|
||||
"@benchmark compute_AB_AB7.(inputs)"
|
||||
"#compute_bench = @benchmark compute_AB_AB5.(inputs)\n",
|
||||
"compute_bench_reduced = @benchmark compute_AB_AB5_reduced.(inputs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
@ -662,7 +413,7 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Julia 1.9.3",
|
||||
"display_name": "Julia 1.9.4",
|
||||
"language": "julia",
|
||||
"name": "julia-1.9"
|
||||
},
|
||||
@ -670,7 +421,7 @@
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "1.9.3"
|
||||
"version": "1.9.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
@ -97,7 +97,7 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Total: 280, ComputeTaskP"
|
||||
"Total: 280, ComputeTaskABC_P"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -119,9 +119,9 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
": 6, ComputeTaskU: 6, \n",
|
||||
" ComputeTaskV: 64, ComputeTaskSum: 1, ComputeTaskS2: 24, \n",
|
||||
" ComputeTaskS1: 36, DataTask: 143"
|
||||
": 6, ComputeTaskABC_U: 6, \n",
|
||||
" ComputeTaskABC_V: 64, ComputeTaskABC_Sum: 1, ComputeTaskABC_S2: 24, \n",
|
||||
" ComputeTaskABC_S1: 36, DataTask: 143"
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -211,10 +211,8 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"include(\"../examples/profiling_utilities.jl\")\n",
|
||||
"\n",
|
||||
"# We can also mute the graph by applying some operations to it\n",
|
||||
"reduce_all!(graph)"
|
||||
"optimize_to_fixpoint!(ReductionOptimizer(), graph)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
451
notebooks/diagram_gen.ipynb
Normal file
451
notebooks/diagram_gen.ipynb
Normal file
@ -0,0 +1,451 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 37,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"using Revise; using QEDbase; using QEDprocesses; using MetagraphOptimization; using BenchmarkTools; using DataStructures\n",
|
||||
"import MetagraphOptimization.gen_diagrams"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Diagram 1: Initial Particles: [k_i_1, e_i_1, k_o_1, e_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_i_1 -> e_i_2, k_o_1 + e_o_1 -> e_o_2]\n",
|
||||
" Tie: e_i_2 -- e_o_2\n",
|
||||
"\n",
|
||||
"Diagram 2: Initial Particles: [k_i_1, e_i_1, k_o_1, e_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_o_1 -> e_o_2, e_i_1 + k_o_1 -> e_i_2]\n",
|
||||
" Tie: e_o_2 -- e_i_2\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Compton Scattering\n",
|
||||
"fd = FeynmanDiagram(parse_process(\"ke->ke\", QEDModel()))\n",
|
||||
"\n",
|
||||
"diagrams = gen_diagrams(fd)\n",
|
||||
"\n",
|
||||
"c = 1\n",
|
||||
"for d in diagrams\n",
|
||||
" println(\"Diagram $c: $d\")\n",
|
||||
" c += 1\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 39,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"BenchmarkTools.Trial: 6044 samples with 1 evaluation.\n",
|
||||
" Range \u001b[90m(\u001b[39m\u001b[36m\u001b[1mmin\u001b[22m\u001b[39m … \u001b[35mmax\u001b[39m\u001b[90m): \u001b[39m\u001b[36m\u001b[1m490.857 μs\u001b[22m\u001b[39m … \u001b[35m 3.657 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m0.00% … 77.38%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m800.314 μs \u001b[22m\u001b[39m\u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmedian\u001b[90m): \u001b[39m0.00%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[32m\u001b[1mmean\u001b[22m\u001b[39m ± \u001b[32mσ\u001b[39m\u001b[90m): \u001b[39m\u001b[32m\u001b[1m825.263 μs\u001b[22m\u001b[39m ± \u001b[32m208.306 μs\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m1.62% ± 5.53%\n",
|
||||
"\n",
|
||||
" \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▃\u001b[39m█\u001b[39m▂\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▁\u001b[39m \u001b[39m▂\u001b[39m▃\u001b[39m▃\u001b[39m▂\u001b[39m▃\u001b[39m▃\u001b[39m▄\u001b[39m▅\u001b[34m▅\u001b[39m\u001b[39m▅\u001b[39m▃\u001b[32m▂\u001b[39m\u001b[39m▁\u001b[39m \u001b[39m▁\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▃\u001b[39m▆\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \n",
|
||||
" \u001b[39m▂\u001b[39m▂\u001b[39m▁\u001b[39m▂\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▂\u001b[39m▂\u001b[39m▁\u001b[39m▁\u001b[39m▃\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▇\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[34m█\u001b[39m\u001b[39m█\u001b[39m█\u001b[32m█\u001b[39m\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▇\u001b[39m▆\u001b[39m▆\u001b[39m▅\u001b[39m▅\u001b[39m▄\u001b[39m▄\u001b[39m▄\u001b[39m▅\u001b[39m▇\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▅\u001b[39m▄\u001b[39m▃\u001b[39m \u001b[39m▅\n",
|
||||
" 491 μs\u001b[90m Histogram: frequency by time\u001b[39m 1.04 ms \u001b[0m\u001b[1m<\u001b[22m\n",
|
||||
"\n",
|
||||
" Memory estimate\u001b[90m: \u001b[39m\u001b[33m280.03 KiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m2709\u001b[39m."
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Found 6 Diagrams for 2-Photon Compton\n",
|
||||
"Diagram 1: Initial Particles: [k_i_1, k_i_2, e_i_1, k_o_1, e_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_i_1 -> e_i_2, k_i_2 + e_o_1 -> e_o_2]\n",
|
||||
" Virtuality Level 2 Vertices: [k_o_1 + e_i_2 -> e_i_3]\n",
|
||||
" Tie: e_o_2 -- e_i_3\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 2-Photon Compton Scattering\n",
|
||||
"two_k_compton = FeynmanDiagram(parse_process(\"kke->ke\", QEDModel()))\n",
|
||||
"\n",
|
||||
"display(@benchmark gen_diagrams(two_k_compton))\n",
|
||||
"diagrams = gen_diagrams(two_k_compton)\n",
|
||||
"\n",
|
||||
"println(\"Found $(length(diagrams)) Diagrams for 2-Photon Compton\")\n",
|
||||
"println(\"Diagram 1: $(first(diagrams))\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 40,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"BenchmarkTools.Trial: 1167 samples with 1 evaluation.\n",
|
||||
" Range \u001b[90m(\u001b[39m\u001b[36m\u001b[1mmin\u001b[22m\u001b[39m … \u001b[35mmax\u001b[39m\u001b[90m): \u001b[39m\u001b[36m\u001b[1m2.581 ms\u001b[22m\u001b[39m … \u001b[35m 7.394 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m0.00% … 38.39%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m4.278 ms \u001b[22m\u001b[39m\u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmedian\u001b[90m): \u001b[39m0.00%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[32m\u001b[1mmean\u001b[22m\u001b[39m ± \u001b[32mσ\u001b[39m\u001b[90m): \u001b[39m\u001b[32m\u001b[1m4.284 ms\u001b[22m\u001b[39m ± \u001b[32m550.104 μs\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m1.84% ± 6.28%\n",
|
||||
"\n",
|
||||
" \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▃\u001b[39m▃\u001b[39m▅\u001b[39m▅\u001b[34m▃\u001b[39m\u001b[39m▃\u001b[39m▇\u001b[39m█\u001b[39m▄\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \n",
|
||||
" \u001b[39m▂\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▂\u001b[39m▂\u001b[39m▁\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▄\u001b[39m█\u001b[39m▄\u001b[39m▄\u001b[39m▄\u001b[39m▃\u001b[39m▃\u001b[39m▄\u001b[39m▆\u001b[39m▇\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[34m█\u001b[39m\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▆\u001b[39m▄\u001b[39m▃\u001b[39m▃\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▂\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▂\u001b[39m▃\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m \u001b[39m▃\n",
|
||||
" 2.58 ms\u001b[90m Histogram: frequency by time\u001b[39m 6.46 ms \u001b[0m\u001b[1m<\u001b[22m\n",
|
||||
"\n",
|
||||
" Memory estimate\u001b[90m: \u001b[39m\u001b[33m1.71 MiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m15410\u001b[39m."
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Found 24 Diagrams for 3-Photon Compton\n",
|
||||
"Diagram 1: Initial Particles: [k_i_1, k_i_2, k_i_3, e_i_1, k_o_1, e_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_2 + e_o_1 -> e_o_2, k_i_3 + e_i_1 -> e_i_2]\n",
|
||||
" Virtuality Level 2 Vertices: [k_i_1 + e_o_2 -> e_o_3, k_o_1 + e_i_2 -> e_i_3]\n",
|
||||
" Tie: e_o_3 -- e_i_3\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 3-Photon Compton Scattering\n",
|
||||
"three_k_compton = FeynmanDiagram(parse_process(\"kkke->ke\", QEDModel()))\n",
|
||||
"\n",
|
||||
"display(@benchmark gen_diagrams(three_k_compton))\n",
|
||||
"diagrams = gen_diagrams(three_k_compton)\n",
|
||||
"\n",
|
||||
"println(\"Found $(length(diagrams)) Diagrams for 3-Photon Compton\")\n",
|
||||
"println(\"Diagram 1: $(first(diagrams))\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 41,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"BenchmarkTools.Trial: 141 samples with 1 evaluation.\n",
|
||||
" Range \u001b[90m(\u001b[39m\u001b[36m\u001b[1mmin\u001b[22m\u001b[39m … \u001b[35mmax\u001b[39m\u001b[90m): \u001b[39m\u001b[36m\u001b[1m31.255 ms\u001b[22m\u001b[39m … \u001b[35m42.658 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m0.00% … 4.92%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m35.749 ms \u001b[22m\u001b[39m\u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmedian\u001b[90m): \u001b[39m4.34%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[32m\u001b[1mmean\u001b[22m\u001b[39m ± \u001b[32mσ\u001b[39m\u001b[90m): \u001b[39m\u001b[32m\u001b[1m35.690 ms\u001b[22m\u001b[39m ± \u001b[32m 2.009 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m3.04% ± 2.83%\n",
|
||||
"\n",
|
||||
" \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▆\u001b[39m▁\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▃\u001b[39m▁\u001b[39m▁\u001b[39m \u001b[39m \u001b[39m▁\u001b[39m \u001b[39m▃\u001b[39m▁\u001b[39m▃\u001b[39m▁\u001b[39m \u001b[39m█\u001b[34m▆\u001b[39m\u001b[39m▁\u001b[39m▁\u001b[39m▆\u001b[39m▁\u001b[39m▁\u001b[39m▃\u001b[39m \u001b[39m▁\u001b[39m \u001b[39m▃\u001b[39m▆\u001b[39m▁\u001b[39m▆\u001b[39m█\u001b[39m \u001b[39m \u001b[39m \u001b[39m▁\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▁\u001b[39m \u001b[39m \u001b[39m \u001b[39m \n",
|
||||
" \u001b[39m▇\u001b[39m▄\u001b[39m▄\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▄\u001b[39m▇\u001b[39m▇\u001b[39m▄\u001b[39m▄\u001b[39m▄\u001b[39m▇\u001b[39m▄\u001b[39m█\u001b[39m█\u001b[39m▇\u001b[39m▄\u001b[39m▇\u001b[39m▇\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▇\u001b[39m▁\u001b[39m█\u001b[39m▄\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▇\u001b[39m█\u001b[34m█\u001b[39m\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▄\u001b[39m█\u001b[39m▇\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▇\u001b[39m▇\u001b[39m▁\u001b[39m█\u001b[39m▄\u001b[39m▁\u001b[39m▄\u001b[39m▇\u001b[39m█\u001b[39m▇\u001b[39m▄\u001b[39m \u001b[39m▄\n",
|
||||
" 31.3 ms\u001b[90m Histogram: frequency by time\u001b[39m 39.2 ms \u001b[0m\u001b[1m<\u001b[22m\n",
|
||||
"\n",
|
||||
" Memory estimate\u001b[90m: \u001b[39m\u001b[33m23.29 MiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m171048\u001b[39m."
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Found 120 Diagrams for 4-Photon Compton\n",
|
||||
"Diagram 1: Initial Particles: [k_i_1, k_i_2, k_i_3, k_i_4, e_i_1, k_o_1, e_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_o_1 -> e_o_2, e_i_1 + k_o_1 -> e_i_2]\n",
|
||||
" Virtuality Level 2 Vertices: [k_i_3 + e_o_2 -> e_o_3, k_i_2 + e_i_2 -> e_i_3]\n",
|
||||
" Virtuality Level 3 Vertices: [k_i_4 + e_o_3 -> e_o_4]\n",
|
||||
" Tie: e_i_3 -- e_o_4\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 4-Photon Compton Scattering\n",
|
||||
"four_k_compton = FeynmanDiagram(parse_process(\"kkkke->ke\", QEDModel()))\n",
|
||||
"\n",
|
||||
"display(@benchmark gen_diagrams(four_k_compton))\n",
|
||||
"diagrams = gen_diagrams(four_k_compton)\n",
|
||||
"\n",
|
||||
"println(\"Found $(length(diagrams)) Diagrams for 4-Photon Compton\")\n",
|
||||
"println(\"Diagram 1: $(first(diagrams))\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 42,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"BenchmarkTools.Trial: 10 samples with 1 evaluation.\n",
|
||||
" Range \u001b[90m(\u001b[39m\u001b[36m\u001b[1mmin\u001b[22m\u001b[39m … \u001b[35mmax\u001b[39m\u001b[90m): \u001b[39m\u001b[36m\u001b[1m471.789 ms\u001b[22m\u001b[39m … \u001b[35m527.196 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m6.00% … 7.35%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m499.068 ms \u001b[22m\u001b[39m\u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmedian\u001b[90m): \u001b[39m6.98%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[32m\u001b[1mmean\u001b[22m\u001b[39m ± \u001b[32mσ\u001b[39m\u001b[90m): \u001b[39m\u001b[32m\u001b[1m502.132 ms\u001b[22m\u001b[39m ± \u001b[32m 17.383 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m6.79% ± 0.77%\n",
|
||||
"\n",
|
||||
" \u001b[39m▁\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m█\u001b[39m▁\u001b[39m \u001b[34m▁\u001b[39m\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[32m \u001b[39m\u001b[39m \u001b[39m▁\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▁\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▁\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▁\u001b[39m▁\u001b[39m \u001b[39m \n",
|
||||
" \u001b[39m█\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m█\u001b[39m█\u001b[39m▁\u001b[34m█\u001b[39m\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[32m▁\u001b[39m\u001b[39m▁\u001b[39m█\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m█\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m█\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m█\u001b[39m█\u001b[39m \u001b[39m▁\n",
|
||||
" 472 ms\u001b[90m Histogram: frequency by time\u001b[39m 527 ms \u001b[0m\u001b[1m<\u001b[22m\n",
|
||||
"\n",
|
||||
" Memory estimate\u001b[90m: \u001b[39m\u001b[33m627.12 MiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m3747679\u001b[39m."
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Found 720 Diagrams for 5-Photon Compton\n",
|
||||
"Diagram 1: Initial Particles: [k_i_1, k_i_2, k_i_3, k_i_4, k_i_5, e_i_1, k_o_1, e_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_i_1 -> e_i_2, k_i_4 + e_o_1 -> e_o_2]\n",
|
||||
" Virtuality Level 2 Vertices: [k_i_3 + e_i_2 -> e_i_3, k_i_5 + e_o_2 -> e_o_3]\n",
|
||||
" Virtuality Level 3 Vertices: [k_i_2 + e_i_3 -> e_i_4, k_o_1 + e_o_3 -> e_o_4]\n",
|
||||
" Tie: e_i_4 -- e_o_4\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 5-Photon Compton Scattering\n",
|
||||
"five_k_compton = FeynmanDiagram(parse_process(\"kkkkke->ke\", QEDModel()))\n",
|
||||
"\n",
|
||||
"display(@benchmark gen_diagrams(five_k_compton))\n",
|
||||
"diagrams = gen_diagrams(five_k_compton)\n",
|
||||
"\n",
|
||||
"println(\"Found $(length(diagrams)) Diagrams for 5-Photon Compton\")\n",
|
||||
"println(\"Diagram 1: $(first(diagrams))\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 43,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Diagram 1: Initial Particles: [p_i_1, e_i_1, e_o_1, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [p_i_1 + e_i_1 -> k_o_2, e_o_1 + p_o_1 -> k_o_1]\n",
|
||||
" Tie: k_o_2 -- k_o_1\n",
|
||||
"\n",
|
||||
"Diagram 2: Initial Particles: [p_i_1, e_i_1, e_o_1, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [p_i_1 + p_o_1 -> k_o_1, e_i_1 + e_o_1 -> k_o_2]\n",
|
||||
" Tie: k_o_1 -- k_o_2\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Bhabha Scattering\n",
|
||||
"fd = FeynmanDiagram(parse_process(\"ep->ep\", QEDModel()))\n",
|
||||
"\n",
|
||||
"diagrams = gen_diagrams(fd)\n",
|
||||
"\n",
|
||||
"c = 1\n",
|
||||
"for d in diagrams\n",
|
||||
" println(\"Diagram $c: $d\")\n",
|
||||
" c += 1\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 44,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Diagram 1: Initial Particles: [e_i_1, e_i_2, e_o_1, e_o_2]\n",
|
||||
" Virtuality Level 1 Vertices: [e_i_2 + e_o_2 -> k_o_2, e_i_1 + e_o_1 -> k_o_1]\n",
|
||||
" Tie: k_o_2 -- k_o_1\n",
|
||||
"\n",
|
||||
"Diagram 2: Initial Particles: [e_i_1, e_i_2, e_o_1, e_o_2]\n",
|
||||
" Virtuality Level 1 Vertices: [e_i_1 + e_o_2 -> k_o_1, e_i_2 + e_o_1 -> k_o_2]\n",
|
||||
" Tie: k_o_1 -- k_o_2\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Moller Scattering\n",
|
||||
"fd = FeynmanDiagram(parse_process(\"ee->ee\", QEDModel()))\n",
|
||||
"\n",
|
||||
"diagrams = gen_diagrams(fd)\n",
|
||||
"\n",
|
||||
"c = 1\n",
|
||||
"for d in diagrams\n",
|
||||
" println(\"Diagram $c: $d\")\n",
|
||||
" c += 1\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 45,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Diagram 1: Initial Particles: [p_i_1, e_i_1, k_o_1, k_o_2]\n",
|
||||
" Virtuality Level 1 Vertices: [e_i_1 + k_o_2 -> e_i_2, p_i_1 + k_o_1 -> e_o_1]\n",
|
||||
" Tie: e_i_2 -- e_o_1\n",
|
||||
"\n",
|
||||
"Diagram 2: Initial Particles: [p_i_1, e_i_1, k_o_1, k_o_2]\n",
|
||||
" Virtuality Level 1 Vertices: [e_i_1 + k_o_1 -> e_i_2, p_i_1 + k_o_2 -> e_o_1]\n",
|
||||
" Tie: e_i_2 -- e_o_1\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Pair annihilation\n",
|
||||
"fd = FeynmanDiagram(parse_process(\"ep->kk\", QEDModel()))\n",
|
||||
"\n",
|
||||
"diagrams = gen_diagrams(fd)\n",
|
||||
"\n",
|
||||
"c = 1\n",
|
||||
"for d in diagrams\n",
|
||||
" println(\"Diagram $c: $d\")\n",
|
||||
" c += 1\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 46,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Diagram 1: Initial Particles: [k_i_1, k_i_2, e_o_1, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + p_o_1 -> e_i_1, k_i_2 + e_o_1 -> e_o_2]\n",
|
||||
" Tie: e_i_1 -- e_o_2\n",
|
||||
"\n",
|
||||
"Diagram 2: Initial Particles: [k_i_1, k_i_2, e_o_1, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_o_1 -> e_o_2, k_i_2 + p_o_1 -> e_i_1]\n",
|
||||
" Tie: e_o_2 -- e_i_1\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Pair production\n",
|
||||
"fd = FeynmanDiagram(parse_process(\"kk->pe\", QEDModel()))\n",
|
||||
"\n",
|
||||
"diagrams = gen_diagrams(fd)\n",
|
||||
"\n",
|
||||
"c = 1\n",
|
||||
"for d in diagrams\n",
|
||||
" println(\"Diagram $c: $d\")\n",
|
||||
" c += 1\n",
|
||||
"end"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 47,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Found 8 diagrams:\n",
|
||||
"Diagram 1: Initial Particles: [k_i_1, e_i_1, e_o_1, e_o_2, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_o_1 -> e_o_3, e_i_1 + e_o_2 -> k_o_1]\n",
|
||||
" Virtuality Level 2 Vertices: [p_o_1 + k_o_1 -> e_i_2]\n",
|
||||
" Tie: e_o_3 -- e_i_2\n",
|
||||
"\n",
|
||||
"Diagram 2: Initial Particles: [k_i_1, e_i_1, e_o_1, e_o_2, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + p_o_1 -> e_i_2, e_i_1 + e_o_2 -> k_o_1]\n",
|
||||
" Virtuality Level 2 Vertices: [e_o_1 + e_i_2 -> k_o_2]\n",
|
||||
" Tie: k_o_1 -- k_o_2\n",
|
||||
"\n",
|
||||
"Diagram 3: Initial Particles: [k_i_1, e_i_1, e_o_1, e_o_2, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_o_2 -> e_o_3, e_i_1 + e_o_1 -> k_o_1]\n",
|
||||
" Virtuality Level 2 Vertices: [p_o_1 + e_o_3 -> k_o_2]\n",
|
||||
" Tie: k_o_1 -- k_o_2\n",
|
||||
"\n",
|
||||
"Diagram 4: Initial Particles: [k_i_1, e_i_1, e_o_1, e_o_2, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_i_1 -> e_i_2, e_o_2 + p_o_1 -> k_o_1]\n",
|
||||
" Virtuality Level 2 Vertices: [e_o_1 + e_i_2 -> k_o_2]\n",
|
||||
" Tie: k_o_1 -- k_o_2\n",
|
||||
"\n",
|
||||
"Diagram 5: Initial Particles: [k_i_1, e_i_1, e_o_1, e_o_2, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_o_1 -> e_o_3, e_o_2 + p_o_1 -> k_o_1]\n",
|
||||
" Virtuality Level 2 Vertices: [e_i_1 + k_o_1 -> e_i_2]\n",
|
||||
" Tie: e_o_3 -- e_i_2\n",
|
||||
"\n",
|
||||
"Diagram 6: Initial Particles: [k_i_1, e_i_1, e_o_1, e_o_2, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_o_2 -> e_o_3, e_o_1 + p_o_1 -> k_o_1]\n",
|
||||
" Virtuality Level 2 Vertices: [e_i_1 + e_o_3 -> k_o_2]\n",
|
||||
" Tie: k_o_1 -- k_o_2\n",
|
||||
"\n",
|
||||
"Diagram 7: Initial Particles: [k_i_1, e_i_1, e_o_1, e_o_2, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + p_o_1 -> e_i_2, e_i_1 + e_o_1 -> k_o_1]\n",
|
||||
" Virtuality Level 2 Vertices: [e_o_2 + k_o_1 -> e_o_3]\n",
|
||||
" Tie: e_i_2 -- e_o_3\n",
|
||||
"\n",
|
||||
"Diagram 8: Initial Particles: [k_i_1, e_i_1, e_o_1, e_o_2, p_o_1]\n",
|
||||
" Virtuality Level 1 Vertices: [k_i_1 + e_i_1 -> e_i_2, e_o_1 + p_o_1 -> k_o_1]\n",
|
||||
" Virtuality Level 2 Vertices: [e_o_2 + k_o_1 -> e_o_3]\n",
|
||||
" Tie: e_i_2 -- e_o_3\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Trident\n",
|
||||
"fd = FeynmanDiagram(parse_process(\"ke->epe\", QEDModel()))\n",
|
||||
"\n",
|
||||
"diagrams = gen_diagrams(fd)\n",
|
||||
"\n",
|
||||
"println(\"Found $(length(diagrams)) diagrams:\")\n",
|
||||
"c = 1\n",
|
||||
"for d in diagrams\n",
|
||||
" println(\"Diagram $c: $d\")\n",
|
||||
" c += 1\n",
|
||||
"end"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Julia 1.9.4",
|
||||
"language": "julia",
|
||||
"name": "julia-1.9"
|
||||
},
|
||||
"language_info": {
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "1.9.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
111
notebooks/diagram_gen_profiling.ipynb
Normal file
111
notebooks/diagram_gen_profiling.ipynb
Normal file
@ -0,0 +1,111 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "595a07c5-0ecc-4f3e-8cbe-63fc64b456da",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[36m\u001b[1m[ \u001b[22m\u001b[39m\u001b[36m\u001b[1mInfo: \u001b[22m\u001b[39mPrecompiling MetagraphOptimization [3e869610-d48d-4942-ba70-c1b702a33ca4]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1"
|
||||
]
|
||||
},
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"using BenchmarkTools; using Profile; using PProf; using Revise; using MetagraphOptimization;\n",
|
||||
"Threads.nthreads()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "163f84be-1e2e-480e-9944-1fa4e0eedf3b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Found 1 NUMA nodes\n",
|
||||
"CUDA is non-functional\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"QED Process: 'ke->kkkkke'"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"machine = get_machine_info()\n",
|
||||
"model = QEDModel()\n",
|
||||
"process = parse_process(\"ke->kkkkke\", model)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "6c2eef40-5df0-4396-8e62-5204c4de61f3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"\"profile.pb.gz\""
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Main binary filename not available.\n",
|
||||
"Serving web UI on http://localhost:57599\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"gen_graph(parse_process(\"ke->kke\", model))\n",
|
||||
"Profile.clear()\n",
|
||||
"@profile gen_graph(process)\n",
|
||||
"pprof()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Julia 1.9.4",
|
||||
"language": "julia",
|
||||
"name": "julia-1.9"
|
||||
},
|
||||
"language_info": {
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "1.9.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
129
notebooks/large_compton.ipynb
Normal file
129
notebooks/large_compton.ipynb
Normal file
@ -0,0 +1,129 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"12"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"using MetagraphOptimization\n",
|
||||
"using BenchmarkTools\n",
|
||||
"\n",
|
||||
"Threads.nthreads()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Graph:\n",
|
||||
" Nodes: Total: 131069, DataTask: 65539, ComputeTaskQED_Sum: 1, \n",
|
||||
" ComputeTaskQED_V: 35280, ComputeTaskQED_S2: 5040, ComputeTaskQED_U: 9, \n",
|
||||
" ComputeTaskQED_S1: 25200\n",
|
||||
" Edges: 176419\n",
|
||||
" Total Compute Effort: 549370.0\n",
|
||||
" Total Data Transfer: 1.0645344e7\n",
|
||||
" Total Compute Intensity: 0.05160659909158408\n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"machine = get_machine_info()\n",
|
||||
"model = QEDModel()\n",
|
||||
"process = parse_process(\"ke->kkkkkke\", model)\n",
|
||||
"\n",
|
||||
"inputs = [gen_process_input(process) for _ in 1:1e3];\n",
|
||||
"graph = gen_graph(process)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Graph:\n",
|
||||
" Nodes: Total: 14783, DataTask: 7396, ComputeTaskQED_Sum: 1, \n",
|
||||
" ComputeTaskQED_V: 1819, ComputeTaskQED_S2: 5040, ComputeTaskQED_U: 9, \n",
|
||||
" ComputeTaskQED_S1: 518\n",
|
||||
" Edges: 26672\n",
|
||||
" Total Compute Effort: 77102.0\n",
|
||||
" Total Data Transfer: 5.063616e6\n",
|
||||
" Total Compute Intensity: 0.015226668056977465\n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"optimizer = ReductionOptimizer()\n",
|
||||
"\n",
|
||||
"optimize_to_fixpoint!(optimizer, graph)\n",
|
||||
"graph"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Calculated 15537.0 results/s, 1295.0 results/s per thread for QED Process: 'ke->kkkkkke' (12 threads)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"compute_compton_reduced = get_compute_function(graph, process, machine)\n",
|
||||
"outputs = [zero(ComplexF64) for _ in 1:1e6]\n",
|
||||
"\n",
|
||||
"bench_result = @benchmark begin\n",
|
||||
" Threads.@threads :static for i in eachindex(inputs)\n",
|
||||
" outputs[i] = compute_compton_reduced(inputs[i])\n",
|
||||
" end\n",
|
||||
"end\n",
|
||||
"\n",
|
||||
"rate = length(inputs) / (mean(bench_result.times) / 1.0e9)\n",
|
||||
"rate_per_thread = rate / Threads.nthreads()\n",
|
||||
"println(\"Calculated $(round(rate)) results/s, $(round(rate_per_thread)) results/s per thread for $(process) ($(Threads.nthreads()) threads)\")"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Julia 1.9.4",
|
||||
"language": "julia",
|
||||
"name": "julia-1.9"
|
||||
},
|
||||
"language_info": {
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "1.9.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
@ -30,17 +30,16 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"include(\"../examples/profiling_utilities.jl\")\n",
|
||||
"@ProfileView.profview reduce_all!(graph)"
|
||||
"@ProfileView.profview optimize_to_fixpoint!(ReductionOptimizer(), graph)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@ProfileView.profview comp_func = get_compute_function(graph, process)"
|
||||
"@ProfileView.profview comp_func = get_compute_function(graph, process, get_machine_info())"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -53,7 +52,7 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Julia 1.9.3",
|
||||
"display_name": "Julia 1.9.4",
|
||||
"language": "julia",
|
||||
"name": "julia-1.9"
|
||||
},
|
||||
@ -61,7 +60,7 @@
|
||||
"file_extension": ".jl",
|
||||
"mimetype": "application/julia",
|
||||
"name": "julia",
|
||||
"version": "1.9.3"
|
||||
"version": "1.9.4"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
|
@ -4,8 +4,8 @@ Run with 32 Threads
|
||||
|
||||
AB->AB:
|
||||
Graph:
|
||||
Nodes: Total: 34, ComputeTaskS2: 2, ComputeTaskU: 4,
|
||||
ComputeTaskSum: 1, ComputeTaskV: 4, ComputeTaskP: 4,
|
||||
Nodes: Total: 34, ComputeTaskABC_S2: 2, ComputeTaskABC_U: 4,
|
||||
ComputeTaskABC_Sum: 1, ComputeTaskABC_V: 4, ComputeTaskABC_P: 4,
|
||||
DataTask: 19
|
||||
Edges: 37
|
||||
Total Compute Effort: 185
|
||||
@ -27,9 +27,9 @@ Waiting...
|
||||
|
||||
AB->ABBB:
|
||||
Graph:
|
||||
Nodes: Total: 280, ComputeTaskS2: 24, ComputeTaskU: 6,
|
||||
ComputeTaskV: 64, ComputeTaskSum: 1, ComputeTaskP: 6,
|
||||
ComputeTaskS1: 36, DataTask: 143
|
||||
Nodes: Total: 280, ComputeTaskABC_S2: 24, ComputeTaskABC_U: 6,
|
||||
ComputeTaskABC_V: 64, ComputeTaskABC_Sum: 1, ComputeTaskABC_P: 6,
|
||||
ComputeTaskABC_S1: 36, DataTask: 143
|
||||
Edges: 385
|
||||
Total Compute Effort: 2007
|
||||
Total Data Transfer: 1176
|
||||
@ -50,9 +50,9 @@ Waiting...
|
||||
|
||||
AB->ABBBBB:
|
||||
Graph:
|
||||
Nodes: Total: 7854, ComputeTaskS2: 720, ComputeTaskU: 8,
|
||||
ComputeTaskV: 1956, ComputeTaskSum: 1, ComputeTaskP: 8,
|
||||
ComputeTaskS1: 1230, DataTask: 3931
|
||||
Nodes: Total: 7854, ComputeTaskABC_S2: 720, ComputeTaskABC_U: 8,
|
||||
ComputeTaskABC_V: 1956, ComputeTaskABC_Sum: 1, ComputeTaskABC_P: 8,
|
||||
ComputeTaskABC_S1: 1230, DataTask: 3931
|
||||
Edges: 11241
|
||||
Total Compute Effort: 58789
|
||||
Total Data Transfer: 34826
|
||||
@ -73,9 +73,9 @@ Waiting...
|
||||
|
||||
AB->ABBBBBBB:
|
||||
Graph:
|
||||
Nodes: Total: 438436, ComputeTaskS2: 40320, ComputeTaskU: 10,
|
||||
ComputeTaskV: 109600, ComputeTaskSum: 1, ComputeTaskP: 10,
|
||||
ComputeTaskS1: 69272, DataTask: 219223
|
||||
Nodes: Total: 438436, ComputeTaskABC_S2: 40320, ComputeTaskABC_U: 10,
|
||||
ComputeTaskABC_V: 109600, ComputeTaskABC_Sum: 1, ComputeTaskABC_P: 10,
|
||||
ComputeTaskABC_S1: 69272, DataTask: 219223
|
||||
Edges: 628665
|
||||
Total Compute Effort: 3288131
|
||||
Total Data Transfer: 1949004
|
||||
@ -96,9 +96,9 @@ Waiting...
|
||||
|
||||
AB->ABBBBBBBBB:
|
||||
Graph:
|
||||
Nodes: Total: 39456442, ComputeTaskS2: 3628800, ComputeTaskU: 12,
|
||||
ComputeTaskV: 9864100, ComputeTaskSum: 1, ComputeTaskP: 12,
|
||||
ComputeTaskS1: 6235290, DataTask: 19728227
|
||||
Nodes: Total: 39456442, ComputeTaskABC_S2: 3628800, ComputeTaskABC_U: 12,
|
||||
ComputeTaskABC_V: 9864100, ComputeTaskABC_Sum: 1, ComputeTaskABC_P: 12,
|
||||
ComputeTaskABC_S1: 6235290, DataTask: 19728227
|
||||
Edges: 56578129
|
||||
Total Compute Effort: 295923153
|
||||
Total Data Transfer: 175407750
|
||||
@ -119,9 +119,9 @@ Waiting...
|
||||
|
||||
ABAB->ABAB:
|
||||
Graph:
|
||||
Nodes: Total: 3218, ComputeTaskS2: 288, ComputeTaskU: 8,
|
||||
ComputeTaskV: 796, ComputeTaskSum: 1, ComputeTaskP: 8,
|
||||
ComputeTaskS1: 504, DataTask: 1613
|
||||
Nodes: Total: 3218, ComputeTaskABC_S2: 288, ComputeTaskABC_U: 8,
|
||||
ComputeTaskABC_V: 796, ComputeTaskABC_Sum: 1, ComputeTaskABC_P: 8,
|
||||
ComputeTaskABC_S1: 504, DataTask: 1613
|
||||
Edges: 4581
|
||||
Total Compute Effort: 24009
|
||||
Total Data Transfer: 14144
|
||||
@ -142,9 +142,9 @@ Waiting...
|
||||
|
||||
ABAB->ABC:
|
||||
Graph:
|
||||
Nodes: Total: 817, ComputeTaskS2: 72, ComputeTaskU: 7,
|
||||
ComputeTaskV: 198, ComputeTaskSum: 1, ComputeTaskP: 7,
|
||||
ComputeTaskS1: 120, DataTask: 412
|
||||
Nodes: Total: 817, ComputeTaskABC_S2: 72, ComputeTaskABC_U: 7,
|
||||
ComputeTaskABC_V: 198, ComputeTaskABC_Sum: 1, ComputeTaskABC_P: 7,
|
||||
ComputeTaskABC_S1: 120, DataTask: 412
|
||||
Edges: 1151
|
||||
Total Compute Effort: 6028
|
||||
Total Data Transfer: 3538
|
||||
|
@ -5,6 +5,9 @@ A module containing tools to work on DAGs.
|
||||
"""
|
||||
module MetagraphOptimization
|
||||
|
||||
using QEDbase
|
||||
|
||||
# graph types
|
||||
export DAG
|
||||
export Node
|
||||
export Edge
|
||||
@ -18,6 +21,7 @@ export FusedComputeTask
|
||||
export PossibleOperations
|
||||
export GraphProperties
|
||||
|
||||
# graph functions
|
||||
export make_node
|
||||
export make_edge
|
||||
export insert_node
|
||||
@ -27,10 +31,15 @@ export is_exit_node
|
||||
export parents
|
||||
export children
|
||||
export compute
|
||||
export data
|
||||
export compute_effort
|
||||
export task
|
||||
export get_properties
|
||||
export get_exit_node
|
||||
export operation_stack_length
|
||||
export is_valid, is_scheduled
|
||||
|
||||
# graph operation related
|
||||
export Operation
|
||||
export AppliedOperation
|
||||
export NodeFusion
|
||||
@ -42,21 +51,45 @@ export can_pop
|
||||
export reset_graph!
|
||||
export get_operations
|
||||
|
||||
export ComputeTaskP
|
||||
export ComputeTaskS1
|
||||
export ComputeTaskS2
|
||||
export ComputeTaskV
|
||||
export ComputeTaskU
|
||||
export ComputeTaskSum
|
||||
# ABC model
|
||||
export ParticleValue
|
||||
export ParticleA, ParticleB, ParticleC
|
||||
export ABCParticle, ABCProcessDescription, ABCProcessInput, ABCModel
|
||||
export ComputeTaskABC_P
|
||||
export ComputeTaskABC_S1
|
||||
export ComputeTaskABC_S2
|
||||
export ComputeTaskABC_V
|
||||
export ComputeTaskABC_U
|
||||
export ComputeTaskABC_Sum
|
||||
|
||||
# QED model
|
||||
export FeynmanDiagram, FeynmanVertex, FeynmanTie, FeynmanParticle
|
||||
export PhotonStateful, FermionStateful, AntiFermionStateful
|
||||
export QEDParticle, QEDProcessDescription, QEDProcessInput, QEDModel
|
||||
export ComputeTaskQED_P
|
||||
export ComputeTaskQED_S1
|
||||
export ComputeTaskQED_S2
|
||||
export ComputeTaskQED_V
|
||||
export ComputeTaskQED_U
|
||||
export ComputeTaskQED_Sum
|
||||
export gen_graph
|
||||
|
||||
# code generation related
|
||||
export execute
|
||||
export parse_dag, parse_process
|
||||
export gen_process_input
|
||||
export get_compute_function
|
||||
export ParticleValue
|
||||
export ParticleA, ParticleB, ParticleC
|
||||
export ABCProcessDescription, ABCProcessInput, ABCModel
|
||||
|
||||
# estimator
|
||||
export cost_type, graph_cost, operation_effect
|
||||
export GlobalMetricEstimator, CDCost
|
||||
|
||||
# optimization
|
||||
export AbstractOptimizer, GreedyOptimizer, ReductionOptimizer, RandomWalkOptimizer
|
||||
export optimize_step!, optimize!
|
||||
export fixpoint_reached, optimize_to_fixpoint!
|
||||
|
||||
# machine info
|
||||
export Machine
|
||||
export get_machine_info
|
||||
|
||||
@ -64,6 +97,9 @@ export ==, in, show, isempty, delete!, length
|
||||
|
||||
export bytes_to_human_readable
|
||||
|
||||
# TODO: this is probably not good
|
||||
import QEDprocesses.compute
|
||||
|
||||
import Base.length
|
||||
import Base.show
|
||||
import Base.==
|
||||
@ -105,6 +141,7 @@ include("node/properties.jl")
|
||||
include("node/validate.jl")
|
||||
|
||||
include("operation/utility.jl")
|
||||
include("operation/iterate.jl")
|
||||
include("operation/apply.jl")
|
||||
include("operation/clean.jl")
|
||||
include("operation/find.jl")
|
||||
@ -121,6 +158,14 @@ include("task/compute.jl")
|
||||
include("task/print.jl")
|
||||
include("task/properties.jl")
|
||||
|
||||
include("estimator/interface.jl")
|
||||
include("estimator/global_metric.jl")
|
||||
|
||||
include("optimization/interface.jl")
|
||||
include("optimization/greedy.jl")
|
||||
include("optimization/random_walk.jl")
|
||||
include("optimization/reduce.jl")
|
||||
|
||||
include("models/interface.jl")
|
||||
include("models/print.jl")
|
||||
|
||||
@ -132,6 +177,15 @@ include("models/abc/properties.jl")
|
||||
include("models/abc/parse.jl")
|
||||
include("models/abc/print.jl")
|
||||
|
||||
include("models/qed/types.jl")
|
||||
include("models/qed/particle.jl")
|
||||
include("models/qed/diagrams.jl")
|
||||
include("models/qed/compute.jl")
|
||||
include("models/qed/create.jl")
|
||||
include("models/qed/properties.jl")
|
||||
include("models/qed/parse.jl")
|
||||
include("models/qed/print.jl")
|
||||
|
||||
include("devices/measure.jl")
|
||||
include("devices/detect.jl")
|
||||
include("devices/impl.jl")
|
||||
|
@ -61,13 +61,11 @@ function gen_input_assignment_code(
|
||||
|
||||
assignInputs = Vector{Expr}()
|
||||
for (name, symbols) in inputSymbols
|
||||
type = type_from_name(name)
|
||||
index = parse(Int, name[2:end])
|
||||
|
||||
(type, index) = type_index_from_name(model(processDescription), name)
|
||||
p = nothing
|
||||
|
||||
if (index > in_particles(processDescription)[type])
|
||||
index -= in_particles(processDescription)[type]
|
||||
if (index > get(in_particles(processDescription), type, 0))
|
||||
index -= get(in_particles(processDescription), type, 0)
|
||||
@assert index <= out_particles(processDescription)[type] "Too few particles of type $type in input particles for this process"
|
||||
|
||||
p = "filter(x -> typeof(x) <: $type, out_particles($(processInputSymbol)))[$(index)]"
|
||||
@ -76,10 +74,9 @@ function gen_input_assignment_code(
|
||||
end
|
||||
|
||||
for symbol in symbols
|
||||
# TODO: how to get the "default" cpu device?
|
||||
device = entry_device(machine)
|
||||
evalExpr = eval(gen_access_expr(device, symbol))
|
||||
push!(assignInputs, Meta.parse("$(evalExpr) = ParticleValue($p, 1.0)"))
|
||||
push!(assignInputs, Meta.parse("$(evalExpr)::ParticleValue{$type} = ParticleValue($p, one(ComplexF64))"))
|
||||
end
|
||||
end
|
||||
|
||||
@ -102,6 +99,7 @@ function get_compute_function(graph::DAG, process::AbstractProcessDescription, m
|
||||
expr = Meta.parse(
|
||||
"function compute_$(functionId)(input::AbstractProcessInput) $initCaches; $assignInputs; $code; return $resSym; end",
|
||||
)
|
||||
|
||||
func = eval(expr)
|
||||
|
||||
return func
|
||||
|
77
src/estimator/global_metric.jl
Normal file
77
src/estimator/global_metric.jl
Normal file
@ -0,0 +1,77 @@
|
||||
|
||||
"""
|
||||
CDCost
|
||||
|
||||
Representation of a [`DAG`](@ref)'s cost as estimated by the [`GlobalMetricEstimator`](@ref).
|
||||
|
||||
# Fields:
|
||||
`.data`: The total data transfer.\\
|
||||
`.computeEffort`: The total compute effort.\\
|
||||
`.computeIntensity`: The compute intensity, will always equal `.computeEffort / .data`.
|
||||
|
||||
|
||||
!!! note
|
||||
Note that the `computeIntensity` doesn't necessarily make sense in the context of only operation costs.
|
||||
For example, for node fusions this will always be 0, since the computeEffort is zero.
|
||||
It will still work as intended when adding/subtracting to/from a `graph_cost` estimate.
|
||||
"""
|
||||
const CDCost = NamedTuple{(:data, :computeEffort, :computeIntensity), Tuple{Float64, Float64, Float64}}
|
||||
|
||||
function +(cost1::CDCost, cost2::CDCost)::CDCost
|
||||
d = cost1.data + cost2.data
|
||||
ce = computeEffort = cost1.computeEffort + cost2.computeEffort
|
||||
return (data = d, computeEffort = ce, computeIntensity = ce / d)::CDCost
|
||||
end
|
||||
|
||||
function -(cost1::CDCost, cost2::CDCost)::CDCost
|
||||
d = cost1.data - cost2.data
|
||||
ce = computeEffort = cost1.computeEffort - cost2.computeEffort
|
||||
return (data = d, computeEffort = ce, computeIntensity = ce / d)::CDCost
|
||||
end
|
||||
|
||||
function isless(cost1::CDCost, cost2::CDCost)::Bool
|
||||
return cost1.data + cost1.computeEffort < cost2.data + cost2.computeEffort
|
||||
end
|
||||
|
||||
function zero(type::Type{CDCost})
|
||||
return (data = 0.0, computeEffort = 00.0, computeIntensity = 0.0)::CDCost
|
||||
end
|
||||
|
||||
function typemax(type::Type{CDCost})
|
||||
return (data = Inf, computeEffort = Inf, computeIntensity = 0.0)::CDCost
|
||||
end
|
||||
|
||||
struct GlobalMetricEstimator <: AbstractEstimator end
|
||||
|
||||
function cost_type(estimator::GlobalMetricEstimator)::Type{CDCost}
|
||||
return CDCost
|
||||
end
|
||||
|
||||
function graph_cost(estimator::GlobalMetricEstimator, graph::DAG)
|
||||
properties = get_properties(graph)
|
||||
return (
|
||||
data = properties.data,
|
||||
computeEffort = properties.computeEffort,
|
||||
computeIntensity = properties.computeIntensity,
|
||||
)::CDCost
|
||||
end
|
||||
|
||||
function operation_effect(estimator::GlobalMetricEstimator, graph::DAG, operation::NodeFusion)
|
||||
return (data = -data(operation.input[2].task), computeEffort = 0.0, computeIntensity = 0.0)::CDCost
|
||||
end
|
||||
|
||||
function operation_effect(estimator::GlobalMetricEstimator, graph::DAG, operation::NodeReduction)
|
||||
s = length(operation.input) - 1
|
||||
return (
|
||||
data = s * -data(task(operation.input[1])),
|
||||
computeEffort = s * -compute_effort(task(operation.input[1])),
|
||||
computeIntensity = typeof(operation.input) <: DataTaskNode ? 0.0 : Inf,
|
||||
)::CDCost
|
||||
end
|
||||
|
||||
function operation_effect(estimator::GlobalMetricEstimator, graph::DAG, operation::NodeSplit)
|
||||
s::Float64 = length(parents(operation.input)) - 1
|
||||
d::Float64 = s * data(task(operation.input))
|
||||
ce::Float64 = s * compute_effort(task(operation.input))
|
||||
return (data = d, computeEffort = ce, computeIntensity = ce / d)::CDCost
|
||||
end
|
44
src/estimator/interface.jl
Normal file
44
src/estimator/interface.jl
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
"""
|
||||
AbstractEstimator
|
||||
|
||||
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
|
||||
- [`graph_cost`](@ref)
|
||||
- [`operation_effect`](@ref)
|
||||
"""
|
||||
abstract type AbstractEstimator end
|
||||
|
||||
"""
|
||||
cost_type(estimator::AbstractEstimator)
|
||||
|
||||
Interface function returning a specific estimator's cost type, i.e., the type returned by its implementation of [`graph_cost`](@ref) and [`operation_effect`](@ref).
|
||||
"""
|
||||
function cost_type end
|
||||
|
||||
"""
|
||||
graph_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()`.
|
||||
"""
|
||||
function graph_cost end
|
||||
|
||||
"""
|
||||
operation_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.
|
||||
|
||||
!!! note
|
||||
There is a default implementation of this function, applying the operation, calling [`graph_cost`](@ref), 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.
|
||||
"""
|
||||
function operation_effect(estimator::AbstractEstimator, graph::DAG, operation::Operation)
|
||||
# This is currently not stably working, see issue #16
|
||||
cost = graph_cost(estimator, graph)
|
||||
push_operation!(graph, operation)
|
||||
cost_after = graph_cost(estimator, graph)
|
||||
pop_operation!(graph)
|
||||
return cost_after - cost
|
||||
end
|
@ -17,21 +17,5 @@ function in(edge::Edge, graph::DAG)
|
||||
return false
|
||||
end
|
||||
|
||||
return n1 in n2.children
|
||||
end
|
||||
|
||||
"""
|
||||
==(n1::Node, n2::Node, g::DAG)
|
||||
|
||||
Check equality of two nodes in a graph.
|
||||
"""
|
||||
function ==(n1::Node, n2::Node, g::DAG)
|
||||
if typeof(n1) != typeof(n2)
|
||||
return false
|
||||
end
|
||||
if !(n1 in g) || !(n2 in g)
|
||||
return false
|
||||
end
|
||||
|
||||
return n1.task == n2.task && children(n1) == children(n2)
|
||||
return n1 in children(n2)
|
||||
end
|
||||
|
@ -46,7 +46,7 @@ Insert the edge between node1 (child) and node2 (parent) into the graph.
|
||||
See also: [`insert_node!`](@ref), [`remove_node!`](@ref), [`remove_edge!`](@ref)
|
||||
"""
|
||||
function insert_edge!(graph::DAG, node1::Node, node2::Node; track = true, invalidate_cache = true)
|
||||
@assert (node2 ∉ node1.parents) && (node1 ∉ node2.children) "Edge to insert already exists"
|
||||
#@assert (node2 ∉ parents(node1)) && (node1 ∉ children(node2)) "Edge to insert already exists"
|
||||
|
||||
# 1: mute
|
||||
# edge points from child to parent
|
||||
@ -85,7 +85,7 @@ Remove the node from the graph.
|
||||
See also: [`insert_node!`](@ref), [`insert_edge!`](@ref), [`remove_edge!`](@ref)
|
||||
"""
|
||||
function remove_node!(graph::DAG, node::Node; track = true, invalidate_cache = true)
|
||||
@assert node in graph.nodes "Trying to remove a node that's not in the graph"
|
||||
#@assert node in graph.nodes "Trying to remove a node that's not in the graph"
|
||||
|
||||
# 1: mute
|
||||
delete!(graph.nodes, node)
|
||||
@ -123,19 +123,29 @@ function remove_edge!(graph::DAG, node1::Node, node2::Node; track = true, invali
|
||||
pre_length1 = length(node1.parents)
|
||||
pre_length2 = length(node2.children)
|
||||
|
||||
#TODO: filter is very slow
|
||||
filter!(x -> x != node2, node1.parents)
|
||||
filter!(x -> x != node1, node2.children)
|
||||
for i in eachindex(node1.parents)
|
||||
if (node1.parents[i] == node2)
|
||||
splice!(node1.parents, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
@assert begin
|
||||
for i in eachindex(node2.children)
|
||||
if (node2.children[i] == node1)
|
||||
splice!(node2.children, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
#=@assert begin
|
||||
removed = pre_length1 - length(node1.parents)
|
||||
removed <= 1
|
||||
end "removed more than one node from node1's parents"
|
||||
end "removed more than one node from node1's parents"=#
|
||||
|
||||
@assert begin
|
||||
removed = pre_length2 - length(node2.children)
|
||||
#=@assert begin
|
||||
removed = pre_length2 - length(children(node2))
|
||||
removed <= 1
|
||||
end "removed more than one node from node2's children"
|
||||
end "removed more than one node from node2's children"=#
|
||||
|
||||
# 2: keep track
|
||||
if (track)
|
||||
@ -163,7 +173,7 @@ function replace_children!(task::FusedComputeTask, before, after)
|
||||
replacedIn1 = length(findall(x -> x == before, task.t1_inputs))
|
||||
replacedIn2 = length(findall(x -> x == before, task.t2_inputs))
|
||||
|
||||
@assert replacedIn1 >= 1 || replacedIn2 >= 1 "Nothing to replace while replacing $before with $after in $(task.t1_inputs...) and $(task.t2_inputs...)"
|
||||
#@assert replacedIn1 >= 1 || replacedIn2 >= 1 "Nothing to replace while replacing $before with $after in $(task.t1_inputs...) and $(task.t2_inputs...)"
|
||||
|
||||
replace!(task.t1_inputs, before => after)
|
||||
replace!(task.t2_inputs, before => after)
|
||||
@ -185,33 +195,33 @@ end
|
||||
|
||||
function update_child!(graph::DAG, n::Node, child_before::Symbol, child_after::Symbol; track = true)
|
||||
# only need to update fused compute tasks
|
||||
if !(typeof(n.task) <: FusedComputeTask)
|
||||
if !(typeof(task(n)) <: FusedComputeTask)
|
||||
return nothing
|
||||
end
|
||||
|
||||
taskBefore = copy(n.task)
|
||||
taskBefore = copy(task(n))
|
||||
|
||||
if !((child_before in n.task.t1_inputs) || (child_before in n.task.t2_inputs))
|
||||
#=if !((child_before in task(n).t1_inputs) || (child_before in task(n).t2_inputs))
|
||||
println("------------------ Nothing to replace!! ------------------")
|
||||
child_ids = Vector{String}()
|
||||
for child in n.children
|
||||
for child in children(n)
|
||||
push!(child_ids, "$(child.id)")
|
||||
end
|
||||
println("From $(child_before) to $(child_after) in $n with children $(child_ids)")
|
||||
@assert false
|
||||
end
|
||||
end=#
|
||||
|
||||
replace_children!(n.task, child_before, child_after)
|
||||
replace_children!(task(n), child_before, child_after)
|
||||
|
||||
if !((child_after in n.task.t1_inputs) || (child_after in n.task.t2_inputs))
|
||||
#=if !((child_after in task(n).t1_inputs) || (child_after in task(n).t2_inputs))
|
||||
println("------------------ Did not replace anything!! ------------------")
|
||||
child_ids = Vector{String}()
|
||||
for child in n.children
|
||||
for child in children(n)
|
||||
push!(child_ids, "$(child.id)")
|
||||
end
|
||||
println("From $(child_before) to $(child_after) in $n with children $(child_ids)")
|
||||
@assert false
|
||||
end
|
||||
end=#
|
||||
|
||||
# keep track
|
||||
if (track)
|
||||
@ -241,9 +251,14 @@ function invalidate_caches!(graph::DAG, operation::NodeFusion)
|
||||
delete!(graph.possibleOperations, operation)
|
||||
|
||||
# delete the operation from all caches of nodes involved in the operation
|
||||
# TODO: filter is very slow
|
||||
filter!(!=(operation), operation.input[1].nodeFusions)
|
||||
filter!(!=(operation), operation.input[3].nodeFusions)
|
||||
for n in [1, 3]
|
||||
for i in eachindex(operation.input[n].nodeFusions)
|
||||
if operation == operation.input[n].nodeFusions[i]
|
||||
splice!(operation.input[n].nodeFusions, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
operation.input[2].nodeFusion = missing
|
||||
|
||||
|
@ -30,10 +30,10 @@ function show(io::IO, graph::DAG)
|
||||
nodeDict = Dict{Type, Int64}()
|
||||
noEdges = 0
|
||||
for node in graph.nodes
|
||||
if haskey(nodeDict, typeof(node.task))
|
||||
nodeDict[typeof(node.task)] = nodeDict[typeof(node.task)] + 1
|
||||
if haskey(nodeDict, typeof(task(node)))
|
||||
nodeDict[typeof(task(node))] = nodeDict[typeof(task(node))] + 1
|
||||
else
|
||||
nodeDict[typeof(node.task)] = 1
|
||||
nodeDict[typeof(task(node))] = 1
|
||||
end
|
||||
noEdges += length(parents(node))
|
||||
end
|
||||
@ -41,7 +41,7 @@ function show(io::IO, graph::DAG)
|
||||
if length(graph.nodes) <= 20
|
||||
show_nodes(io, graph)
|
||||
else
|
||||
print("Total: ", length(graph.nodes), ", ")
|
||||
print(io, "Total: ", length(graph.nodes), ", ")
|
||||
first = true
|
||||
i = 0
|
||||
for (type, number) in zip(keys(nodeDict), values(nodeDict))
|
||||
@ -49,12 +49,12 @@ function show(io::IO, graph::DAG)
|
||||
if first
|
||||
first = false
|
||||
else
|
||||
print(", ")
|
||||
print(io, ", ")
|
||||
end
|
||||
if (i % 3 == 0)
|
||||
print("\n ")
|
||||
print(io, "\n ")
|
||||
end
|
||||
print(type, ": ", number)
|
||||
print(io, type, ": ", number)
|
||||
end
|
||||
end
|
||||
println(io)
|
||||
|
@ -43,3 +43,12 @@ function get_entry_nodes(graph::DAG)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
"""
|
||||
operation_stack_length(graph::DAG)
|
||||
|
||||
Return the number of operations applied to the graph.
|
||||
"""
|
||||
function operation_stack_length(graph::DAG)
|
||||
return length(graph.appliedOperations) + length(graph.operationsToApply)
|
||||
end
|
||||
|
@ -24,7 +24,7 @@ To get the set of possible operations, use [`get_operations`](@ref).
|
||||
The members of the object should not be manually accessed, instead always use the provided interface functions.
|
||||
"""
|
||||
mutable struct DAG
|
||||
nodes::Set{Node}
|
||||
nodes::Set{Union{DataTaskNode, ComputeTaskNode}}
|
||||
|
||||
# The operations currently applied to the set of nodes
|
||||
appliedOperations::Stack{AppliedOperation}
|
||||
@ -36,7 +36,7 @@ mutable struct DAG
|
||||
possibleOperations::PossibleOperations
|
||||
|
||||
# The set of nodes whose possible operations need to be reevaluated
|
||||
dirtyNodes::Set{Node}
|
||||
dirtyNodes::Set{Union{DataTaskNode, ComputeTaskNode}}
|
||||
|
||||
# "snapshot" system: keep track of added/removed nodes/edges since last snapshot
|
||||
# these are muted in insert_node! etc.
|
||||
|
@ -1,42 +1,46 @@
|
||||
using AccurateArithmetic
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskP, data::ParticleValue)
|
||||
compute(::ComputeTaskABC_P, data::ABCParticleValue)
|
||||
|
||||
Return the particle and value as is.
|
||||
|
||||
0 FLOP.
|
||||
"""
|
||||
function compute(::ComputeTaskP, data::ParticleValue)
|
||||
function compute(::ComputeTaskABC_P, data::ABCParticleValue{P})::ABCParticleValue{P} where {P <: ABCParticle}
|
||||
return data
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskU, data::ParticleValue)
|
||||
compute(::ComputeTaskABC_U, data::ABCParticleValue)
|
||||
|
||||
Compute an outer edge. Return the particle value with the same particle and the value multiplied by an outer_edge factor.
|
||||
Compute an outer edge. Return the particle value with the same particle and the value multiplied by an ABC_outer_edge factor.
|
||||
|
||||
1 FLOP.
|
||||
"""
|
||||
function compute(::ComputeTaskU, data::ParticleValue)
|
||||
return ParticleValue(data.p, data.v * outer_edge(data.p))
|
||||
function compute(::ComputeTaskABC_U, data::ABCParticleValue{P})::ABCParticleValue{P} where {P <: ABCParticle}
|
||||
return ABCParticleValue{P}(data.p, data.v * ABC_outer_edge(data.p))
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskV, data1::ParticleValue, data2::ParticleValue)
|
||||
compute(::ComputeTaskABC_V, data1::ABCParticleValue, data2::ABCParticleValue)
|
||||
|
||||
Compute a vertex. Preserve momentum and particle types (AB->C etc.) to create resulting particle, multiply values together and times a vertex factor.
|
||||
|
||||
6 FLOP.
|
||||
"""
|
||||
function compute(::ComputeTaskV, data1::ParticleValue, data2::ParticleValue)
|
||||
p3 = preserve_momentum(data1.p, data2.p)
|
||||
dataOut = ParticleValue(p3, data1.v * vertex() * data2.v)
|
||||
function compute(
|
||||
::ComputeTaskABC_V,
|
||||
data1::ABCParticleValue{P1},
|
||||
data2::ABCParticleValue{P2},
|
||||
)::ABCParticleValue where {P1 <: ABCParticle, P2 <: ABCParticle}
|
||||
p3 = ABC_conserve_momentum(data1.p, data2.p)
|
||||
dataOut = ABCParticleValue{typeof(p3)}(p3, data1.v * ABC_vertex() * data2.v)
|
||||
return dataOut
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskS2, data1::ParticleValue, data2::ParticleValue)
|
||||
compute(::ComputeTaskABC_S2, data1::ABCParticleValue, data2::ABCParticleValue)
|
||||
|
||||
Compute a final inner edge (2 input particles, no output particle).
|
||||
|
||||
@ -44,111 +48,116 @@ For valid inputs, both input particles should have the same momenta at this poin
|
||||
|
||||
12 FLOP.
|
||||
"""
|
||||
function compute(::ComputeTaskS2, data1::ParticleValue, data2::ParticleValue)
|
||||
function compute(
|
||||
::ComputeTaskABC_S2,
|
||||
data1::ParticleValue{P},
|
||||
data2::ParticleValue{P},
|
||||
)::Float64 where {P <: ABCParticle}
|
||||
#=
|
||||
@assert isapprox(abs(data1.p.momentum.E), abs(data2.p.momentum.E), rtol = 0.001, atol = sqrt(eps())) "E: $(data1.p.momentum.E) vs. $(data2.p.momentum.E)"
|
||||
@assert isapprox(data1.p.momentum.px, -data2.p.momentum.px, rtol = 0.001, atol = sqrt(eps())) "px: $(data1.p.momentum.px) vs. $(data2.p.momentum.px)"
|
||||
@assert isapprox(data1.p.momentum.py, -data2.p.momentum.py, rtol = 0.001, atol = sqrt(eps())) "py: $(data1.p.momentum.py) vs. $(data2.p.momentum.py)"
|
||||
@assert isapprox(data1.p.momentum.pz, -data2.p.momentum.pz, rtol = 0.001, atol = sqrt(eps())) "pz: $(data1.p.momentum.pz) vs. $(data2.p.momentum.pz)"
|
||||
=#
|
||||
return data1.v * inner_edge(data1.p) * data2.v
|
||||
inner = ABC_inner_edge(data1.p)
|
||||
return data1.v * inner * data2.v
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskS1, data::ParticleValue)
|
||||
compute(::ComputeTaskABC_S1, data::ABCParticleValue)
|
||||
|
||||
Compute inner edge (1 input particle, 1 output particle).
|
||||
|
||||
11 FLOP.
|
||||
"""
|
||||
function compute(::ComputeTaskS1, data::ParticleValue)
|
||||
return ParticleValue(data.p, data.v * inner_edge(data.p))
|
||||
function compute(::ComputeTaskABC_S1, data::ABCParticleValue{P})::ABCParticleValue{P} where {P <: ABCParticle}
|
||||
return ABCParticleValue{P}(data.p, data.v * ABC_inner_edge(data.p))
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskSum, data::Vector{Float64})
|
||||
compute(::ComputeTaskABC_Sum, data::Vector{Float64})
|
||||
|
||||
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(::ComputeTaskSum, data::Vector{Float64})
|
||||
function compute(::ComputeTaskABC_Sum, data::Vector{Float64})::Float64
|
||||
return sum_kbn(data)
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskP, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
get_expression(::ComputeTaskABC_P, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
|
||||
Generate and return code evaluating [`ComputeTaskP`](@ref) on `inSyms`, providing the output on `outSym`.
|
||||
Generate and return code evaluating [`ComputeTaskABC_P`](@ref) on `inSyms`, providing the output on `outSym`.
|
||||
"""
|
||||
function get_expression(::ComputeTaskP, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
function get_expression(::ComputeTaskABC_P, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
in = [eval(inExprs[1])]
|
||||
out = eval(outExpr)
|
||||
|
||||
return Meta.parse("$out = compute(ComputeTaskP(), $(in[1]))")
|
||||
return Meta.parse("$out = compute(ComputeTaskABC_P(), $(in[1]))")
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskU, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
get_expression(::ComputeTaskABC_U, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
|
||||
Generate code evaluating [`ComputeTaskU`](@ref) on `inSyms`, providing the output on `outSym`.
|
||||
`inSyms` should be of type [`ParticleValue`](@ref), `outSym` will be of type [`ParticleValue`](@ref).
|
||||
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(::ComputeTaskU, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
function get_expression(::ComputeTaskABC_U, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
in = [eval(inExprs[1])]
|
||||
out = eval(outExpr)
|
||||
|
||||
return Meta.parse("$out = compute(ComputeTaskU(), $(in[1]))")
|
||||
return Meta.parse("$out = compute(ComputeTaskABC_U(), $(in[1]))")
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskV, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
get_expression(::ComputeTaskABC_V, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
|
||||
Generate code evaluating [`ComputeTaskV`](@ref) on `inSyms`, providing the output on `outSym`.
|
||||
`inSym[1]` and `inSym[2]` should be of type [`ParticleValue`](@ref), `outSym` will be of type [`ParticleValue`](@ref).
|
||||
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(::ComputeTaskV, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
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(ComputeTaskV(), $(in[1]), $(in[2]))")
|
||||
return Meta.parse("$out = compute(ComputeTaskABC_V(), $(in[1]), $(in[2]))")
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskS2, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
get_expression(::ComputeTaskABC_S2, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
|
||||
Generate code evaluating [`ComputeTaskS2`](@ref) on `inSyms`, providing the output on `outSym`.
|
||||
`inSyms[1]` and `inSyms[2]` should be of type [`ParticleValue`](@ref), `outSym` will be of type `Float64`.
|
||||
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(::ComputeTaskS2, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
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(ComputeTaskS2(), $(in[1]), $(in[2]))")
|
||||
return Meta.parse("$out = compute(ComputeTaskABC_S2(), $(in[1]), $(in[2]))")
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskS1, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
get_expression(::ComputeTaskABC_S1, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
|
||||
Generate code evaluating [`ComputeTaskS1`](@ref) on `inSyms`, providing the output on `outSym`.
|
||||
`inSyms` should be of type [`ParticleValue`](@ref), `outSym` will be of type [`ParticleValue`](@ref).
|
||||
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(::ComputeTaskS1, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
function get_expression(::ComputeTaskABC_S1, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
in = [eval(inExprs[1])]
|
||||
out = eval(outExpr)
|
||||
|
||||
return Meta.parse("$out = compute(ComputeTaskS1(), $(in[1]))")
|
||||
return Meta.parse("$out = compute(ComputeTaskABC_S1(), $(in[1]))")
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskSum, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
get_expression(::ComputeTaskABC_Sum, device::AbstractDevice, inExprs::Vector{Expr}, outExpr::Expr)
|
||||
|
||||
Generate code evaluating [`ComputeTaskSum`](@ref) on `inSyms`, providing the output on `outSym`.
|
||||
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(::ComputeTaskSum, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
function get_expression(::ComputeTaskABC_Sum, device::AbstractDevice, inExprs::Vector, outExpr)
|
||||
in = eval.(inExprs)
|
||||
out = eval(outExpr)
|
||||
|
||||
return Meta.parse("$out = compute(ComputeTaskSum(), [$(unroll_symbol_vector(in))])")
|
||||
return Meta.parse("$out = compute(ComputeTaskABC_Sum(), [$(unroll_symbol_vector(in))])")
|
||||
end
|
||||
|
@ -3,7 +3,7 @@ using Random
|
||||
using Roots
|
||||
using ForwardDiff
|
||||
|
||||
ComputeTaskSum() = ComputeTaskSum(0)
|
||||
ComputeTaskABC_Sum() = ComputeTaskABC_Sum(0)
|
||||
|
||||
"""
|
||||
gen_process_input(processDescription::ABCProcessDescription)
|
||||
@ -62,137 +62,3 @@ function gen_process_input(processDescription::ABCProcessDescription)
|
||||
|
||||
return return processInput
|
||||
end
|
||||
|
||||
####################
|
||||
# CODE FROM HERE BORROWED FROM SOURCE: https://codebase.helmholtz.cloud/qedsandbox/QEDphasespaces.jl/
|
||||
# use qedphasespaces directly once released
|
||||
#
|
||||
# quick and dirty implementation of the RAMBO algorithm
|
||||
#
|
||||
# reference:
|
||||
# * https://cds.cern.ch/record/164736/files/198601282.pdf
|
||||
# * https://www.sciencedirect.com/science/article/pii/0010465586901190
|
||||
####################
|
||||
|
||||
function generate_initial_moms(ss, masses)
|
||||
E1 = (ss^2 + masses[1]^2 - masses[2]^2) / (2 * ss)
|
||||
E2 = (ss^2 + masses[2]^2 - masses[1]^2) / (2 * ss)
|
||||
|
||||
rho1 = sqrt(E1^2 - masses[1]^2)
|
||||
rho2 = sqrt(E2^2 - masses[2]^2)
|
||||
|
||||
return [SFourMomentum(E1, 0, 0, rho1), SFourMomentum(E2, 0, 0, -rho2)]
|
||||
end
|
||||
|
||||
|
||||
Random.rand(rng::AbstractRNG, ::Random.SamplerType{SFourMomentum}) = SFourMomentum(rand(rng, 4))
|
||||
Random.rand(rng::AbstractRNG, ::Random.SamplerType{NTuple{N, Float64}}) where {N} = Tuple(rand(rng, N))
|
||||
|
||||
|
||||
function _transform_uni_to_mom(u1, u2, u3, u4)
|
||||
cth = 2 * u1 - 1
|
||||
sth = sqrt(1 - cth^2)
|
||||
phi = 2 * pi * u2
|
||||
q0 = -log(u3 * u4)
|
||||
qx = q0 * sth * cos(phi)
|
||||
qy = q0 * sth * sin(phi)
|
||||
qz = q0 * cth
|
||||
|
||||
return SFourMomentum(q0, qx, qy, qz)
|
||||
end
|
||||
|
||||
function _transform_uni_to_mom!(uni_mom, dest)
|
||||
u1, u2, u3, u4 = Tuple(uni_mom)
|
||||
cth = 2 * u1 - 1
|
||||
sth = sqrt(1 - cth^2)
|
||||
phi = 2 * pi * u2
|
||||
q0 = -log(u3 * u4)
|
||||
qx = q0 * sth * cos(phi)
|
||||
qy = q0 * sth * sin(phi)
|
||||
qz = q0 * cth
|
||||
|
||||
return dest = SFourMomentum(q0, qx, qy, qz)
|
||||
end
|
||||
|
||||
_transform_uni_to_mom(u1234::Tuple) = _transform_uni_to_mom(u1234...)
|
||||
_transform_uni_to_mom(u1234::SFourMomentum) = _transform_uni_to_mom(Tuple(u1234))
|
||||
|
||||
function generate_massless_moms(rng, n::Int)
|
||||
a = Vector{SFourMomentum}(undef, n)
|
||||
rand!(rng, a)
|
||||
return map(_transform_uni_to_mom, a)
|
||||
end
|
||||
|
||||
function generate_physical_massless_moms(rng, ss, n)
|
||||
r_moms = generate_massless_moms(rng, n)
|
||||
Q = sum(r_moms)
|
||||
M = sqrt(Q * Q)
|
||||
fac = -1 / M
|
||||
Qx = getX(Q)
|
||||
Qy = getY(Q)
|
||||
Qz = getZ(Q)
|
||||
bx = fac * Qx
|
||||
by = fac * Qy
|
||||
bz = fac * Qz
|
||||
gamma = getT(Q) / M
|
||||
a = 1 / (1 + gamma)
|
||||
x = ss / M
|
||||
|
||||
i = 1
|
||||
while i <= n
|
||||
mom = r_moms[i]
|
||||
mom0 = getT(mom)
|
||||
mom1 = getX(mom)
|
||||
mom2 = getY(mom)
|
||||
mom3 = getZ(mom)
|
||||
|
||||
bq = bx * mom1 + by * mom2 + bz * mom3
|
||||
|
||||
p0 = x * (gamma * mom0 + bq)
|
||||
px = x * (mom1 + bx * mom0 + a * bq * bx)
|
||||
py = x * (mom2 + by * mom0 + a * bq * by)
|
||||
pz = x * (mom3 + bz * mom0 + a * bq * bz)
|
||||
|
||||
r_moms[i] = SFourMomentum(p0, px, py, pz)
|
||||
i += 1
|
||||
end
|
||||
return r_moms
|
||||
end
|
||||
|
||||
function _to_be_solved(xi, masses, p0s, ss)
|
||||
sum = 0.0
|
||||
for (i, E) in enumerate(p0s)
|
||||
sum += sqrt(masses[i]^2 + xi^2 * E^2)
|
||||
end
|
||||
return sum - ss
|
||||
end
|
||||
|
||||
function _build_massive_momenta(xi, masses, massless_moms)
|
||||
vec = SFourMomentum[]
|
||||
i = 1
|
||||
while i <= length(massless_moms)
|
||||
massless_mom = massless_moms[i]
|
||||
k0 = sqrt(getT(massless_mom)^2 * xi^2 + masses[i]^2)
|
||||
|
||||
kx = xi * getX(massless_mom)
|
||||
ky = xi * getY(massless_mom)
|
||||
kz = xi * getZ(massless_mom)
|
||||
|
||||
push!(vec, SFourMomentum(k0, kx, ky, kz))
|
||||
|
||||
i += 1
|
||||
end
|
||||
return vec
|
||||
end
|
||||
|
||||
first_derivative(func) = x -> ForwardDiff.derivative(func, float(x))
|
||||
|
||||
|
||||
function generate_physical_massive_moms(rng, ss, masses; x0 = 0.1)
|
||||
n = length(masses)
|
||||
massless_moms = generate_physical_massless_moms(rng, ss, n)
|
||||
energies = getT.(massless_moms)
|
||||
f = x -> _to_be_solved(x, masses, energies, ss)
|
||||
xi = find_zero((f, first_derivative(f)), x0, Roots.Newton())
|
||||
return _build_massive_momenta(xi, masses, massless_moms)
|
||||
end
|
||||
|
@ -63,7 +63,7 @@ function parse_dag(filename::AbstractString, model::ABCModel, verbose::Bool = fa
|
||||
end
|
||||
sizehint!(graph.nodes, estimate_no_nodes)
|
||||
|
||||
sum_node = insert_node!(graph, make_node(ComputeTaskSum(0)), track = false, invalidate_cache = false)
|
||||
sum_node = insert_node!(graph, make_node(ComputeTaskABC_Sum(0)), track = false, invalidate_cache = false)
|
||||
global_data_out = insert_node!(graph, make_node(DataTask(FLOAT_SIZE)), track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, sum_node, global_data_out, track = false, invalidate_cache = false)
|
||||
|
||||
@ -92,12 +92,12 @@ function parse_dag(filename::AbstractString, model::ABCModel, verbose::Bool = fa
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
) # read particle data node
|
||||
compute_P = insert_node!(graph, make_node(ComputeTaskP()), track = false, invalidate_cache = false) # compute P node
|
||||
compute_P = insert_node!(graph, make_node(ComputeTaskABC_P()), track = false, invalidate_cache = false) # compute P node
|
||||
data_Pu =
|
||||
insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false) # transfer data from P to u (one ParticleValue object)
|
||||
compute_u = insert_node!(graph, make_node(ComputeTaskU()), track = false, invalidate_cache = false) # compute U node
|
||||
insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false) # transfer data from P to u (one ABCParticleValue object)
|
||||
compute_u = insert_node!(graph, make_node(ComputeTaskABC_U()), track = false, invalidate_cache = false) # compute U node
|
||||
data_out =
|
||||
insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false) # transfer data out from u (one ParticleValue object)
|
||||
insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false) # transfer data out from u (one ABCParticleValue object)
|
||||
|
||||
insert_edge!(graph, data_in, compute_P, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, compute_P, data_Pu, track = false, invalidate_cache = false)
|
||||
@ -112,13 +112,13 @@ function parse_dag(filename::AbstractString, model::ABCModel, verbose::Bool = fa
|
||||
in1 = capt.captures[1]
|
||||
in2 = capt.captures[2]
|
||||
|
||||
compute_v = insert_node!(graph, make_node(ComputeTaskV()), track = false, invalidate_cache = false)
|
||||
compute_v = insert_node!(graph, make_node(ComputeTaskABC_V()), track = false, invalidate_cache = false)
|
||||
data_out =
|
||||
insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false)
|
||||
|
||||
if (occursin(regex_c, in1))
|
||||
# put an S node after this input
|
||||
compute_S = insert_node!(graph, make_node(ComputeTaskS1()), track = false, invalidate_cache = false)
|
||||
compute_S = insert_node!(graph, make_node(ComputeTaskABC_S1()), track = false, invalidate_cache = false)
|
||||
data_S_v = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
@ -137,7 +137,7 @@ function parse_dag(filename::AbstractString, model::ABCModel, verbose::Bool = fa
|
||||
if (occursin(regex_c, in2))
|
||||
# i think the current generator only puts the combined particles in the first space, so this case might never be entered
|
||||
# put an S node after this input
|
||||
compute_S = insert_node!(graph, make_node(ComputeTaskS1()), track = false, invalidate_cache = false)
|
||||
compute_S = insert_node!(graph, make_node(ComputeTaskABC_S1()), track = false, invalidate_cache = false)
|
||||
data_S_v = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
@ -164,7 +164,7 @@ function parse_dag(filename::AbstractString, model::ABCModel, verbose::Bool = fa
|
||||
in3 = capt.captures[3]
|
||||
|
||||
# in2 + in3 with a v
|
||||
compute_v = insert_node!(graph, make_node(ComputeTaskV()), track = false, invalidate_cache = false)
|
||||
compute_v = insert_node!(graph, make_node(ComputeTaskABC_V()), track = false, invalidate_cache = false)
|
||||
data_v =
|
||||
insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false)
|
||||
|
||||
@ -173,7 +173,7 @@ function parse_dag(filename::AbstractString, model::ABCModel, verbose::Bool = fa
|
||||
insert_edge!(graph, compute_v, data_v, track = false, invalidate_cache = false)
|
||||
|
||||
# combine with the v of the combined other input
|
||||
compute_S2 = insert_node!(graph, make_node(ComputeTaskS2()), track = false, invalidate_cache = false)
|
||||
compute_S2 = insert_node!(graph, make_node(ComputeTaskABC_S2()), track = false, invalidate_cache = false)
|
||||
data_out = insert_node!(graph, make_node(DataTask(FLOAT_SIZE)), track = false, invalidate_cache = false) # output of a S2 task is only a float
|
||||
|
||||
insert_edge!(graph, data_v, compute_S2, track = false, invalidate_cache = false)
|
||||
@ -181,7 +181,7 @@ function parse_dag(filename::AbstractString, model::ABCModel, verbose::Bool = fa
|
||||
insert_edge!(graph, compute_S2, data_out, track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, data_out, sum_node, track = false, invalidate_cache = false)
|
||||
add_child!(sum_node.task)
|
||||
add_child!(task(sum_node))
|
||||
elseif occursin(regex_plus, node)
|
||||
if (verbose)
|
||||
println("\rReading Nodes Complete ")
|
||||
|
@ -1,4 +1,4 @@
|
||||
using QEDbase
|
||||
import QEDbase.mass
|
||||
|
||||
"""
|
||||
ABCModel <: AbstractPhysicsModel
|
||||
@ -66,6 +66,8 @@ struct ABCProcessInput <: AbstractProcessInput
|
||||
outParticles::Vector{ABCParticle}
|
||||
end
|
||||
|
||||
ABCParticleValue{ParticleType <: ABCParticle} = ParticleValue{ParticleType, ComplexF64}
|
||||
|
||||
"""
|
||||
PARTICLE_MASSES
|
||||
|
||||
@ -87,9 +89,9 @@ For 2 given (non-equal) particle types, return the third of ABC.
|
||||
"""
|
||||
function interaction_result(t1::Type{T1}, t2::Type{T2}) where {T1 <: ABCParticle, T2 <: ABCParticle}
|
||||
@assert t1 != t2
|
||||
if t1 != Type{ParticleA} && t2 != Type{ParticleA}
|
||||
if t1 != ParticleA && t2 != ParticleA
|
||||
return ParticleA
|
||||
elseif t1 != Type{ParticleB} && t2 != Type{ParticleB}
|
||||
elseif t1 != ParticleB && t2 != ParticleB
|
||||
return ParticleB
|
||||
else
|
||||
return ParticleC
|
||||
@ -117,66 +119,63 @@ function square(p::ABCParticle)
|
||||
end
|
||||
|
||||
"""
|
||||
inner_edge(p::ABCParticle)
|
||||
ABC_inner_edge(p::ABCParticle)
|
||||
|
||||
Return the factor of the inner edge with the given (virtual) particle.
|
||||
|
||||
Takes 10 effective FLOP. (3 here + 7 in square(p))
|
||||
"""
|
||||
function inner_edge(p::ABCParticle)
|
||||
function ABC_inner_edge(p::ABCParticle)
|
||||
return 1.0 / (square(p) - mass(typeof(p)) * mass(typeof(p)))
|
||||
end
|
||||
|
||||
"""
|
||||
outer_edge(p::ABCParticle)
|
||||
ABC_outer_edge(p::ABCParticle)
|
||||
|
||||
Return the factor of the outer edge with the given (real) particle.
|
||||
|
||||
Takes 0 effective FLOP.
|
||||
"""
|
||||
function outer_edge(p::ABCParticle)
|
||||
function ABC_outer_edge(p::ABCParticle)
|
||||
return 1.0
|
||||
end
|
||||
|
||||
"""
|
||||
vertex()
|
||||
ABC_vertex()
|
||||
|
||||
Return the factor of a vertex.
|
||||
|
||||
Takes 0 effective FLOP since it's constant.
|
||||
"""
|
||||
function vertex()
|
||||
function ABC_vertex()
|
||||
i = 1.0
|
||||
lambda = 1.0 / 137.0
|
||||
return i * lambda
|
||||
end
|
||||
|
||||
"""
|
||||
preserve_momentum(p1::ABCParticle, p2::ABCParticle)
|
||||
ABC_conserve_momentum(p1::ABCParticle, p2::ABCParticle)
|
||||
|
||||
Calculate and return a new particle from two given interacting ones at a vertex.
|
||||
|
||||
Takes 4 effective FLOP.
|
||||
"""
|
||||
function preserve_momentum(p1::ABCParticle, p2::ABCParticle)
|
||||
function ABC_conserve_momentum(p1::ABCParticle, p2::ABCParticle)
|
||||
t3 = interaction_result(typeof(p1), typeof(p2))
|
||||
p3 = t3(p1.momentum + p2.momentum)
|
||||
|
||||
return p3
|
||||
end
|
||||
|
||||
"""
|
||||
type_from_name(name::String)
|
||||
model(::ABCProcessDescription) = ABCModel()
|
||||
model(::ABCProcessInput) = ABCModel()
|
||||
|
||||
For a name of a particle, return the particle's [`Type`].
|
||||
"""
|
||||
function type_from_name(name::String)
|
||||
function type_index_from_name(::ABCModel, name::String)
|
||||
if startswith(name, "A")
|
||||
return ParticleA
|
||||
return (ParticleA, parse(Int, name[2:end]))
|
||||
elseif startswith(name, "B")
|
||||
return ParticleB
|
||||
return (ParticleB, parse(Int, name[2:end]))
|
||||
elseif startswith(name, "C")
|
||||
return ParticleC
|
||||
return (ParticleC, parse(Int, name[2:end]))
|
||||
else
|
||||
throw("Invalid name for a particle in the ABC model")
|
||||
end
|
||||
|
@ -1,166 +1,134 @@
|
||||
"""
|
||||
compute_effort(t::ComputeTaskS1)
|
||||
compute_effort(t::ComputeTaskABC_S1)
|
||||
|
||||
Return the compute effort of an S1 task.
|
||||
"""
|
||||
compute_effort(t::ComputeTaskS1) = 11
|
||||
compute_effort(t::ComputeTaskABC_S1)::Float64 = 11.0
|
||||
|
||||
"""
|
||||
compute_effort(t::ComputeTaskS2)
|
||||
compute_effort(t::ComputeTaskABC_S2)
|
||||
|
||||
Return the compute effort of an S2 task.
|
||||
"""
|
||||
compute_effort(t::ComputeTaskS2) = 12
|
||||
compute_effort(t::ComputeTaskABC_S2)::Float64 = 12.0
|
||||
|
||||
"""
|
||||
compute_effort(t::ComputeTaskU)
|
||||
compute_effort(t::ComputeTaskABC_U)
|
||||
|
||||
Return the compute effort of a U task.
|
||||
"""
|
||||
compute_effort(t::ComputeTaskU) = 1
|
||||
compute_effort(t::ComputeTaskABC_U)::Float64 = 1.0
|
||||
|
||||
"""
|
||||
compute_effort(t::ComputeTaskV)
|
||||
compute_effort(t::ComputeTaskABC_V)
|
||||
|
||||
Return the compute effort of a V task.
|
||||
"""
|
||||
compute_effort(t::ComputeTaskV) = 6
|
||||
compute_effort(t::ComputeTaskABC_V)::Float64 = 6.0
|
||||
|
||||
"""
|
||||
compute_effort(t::ComputeTaskP)
|
||||
compute_effort(t::ComputeTaskABC_P)
|
||||
|
||||
Return the compute effort of a P task.
|
||||
"""
|
||||
compute_effort(t::ComputeTaskP) = 0
|
||||
compute_effort(t::ComputeTaskABC_P)::Float64 = 0.0
|
||||
|
||||
"""
|
||||
compute_effort(t::ComputeTaskSum)
|
||||
compute_effort(t::ComputeTaskABC_Sum)
|
||||
|
||||
Return the compute effort of a Sum task.
|
||||
|
||||
Note: This is a constant compute effort, even though sum scales with the number of its inputs. Since there is only ever a single sum node in a graph generated from the ABC-Model,
|
||||
this doesn't matter.
|
||||
"""
|
||||
compute_effort(t::ComputeTaskSum) = 1
|
||||
compute_effort(t::ComputeTaskABC_Sum)::Float64 = 1.0
|
||||
|
||||
"""
|
||||
show(io::IO, t::DataTask)
|
||||
|
||||
Print the data task to io.
|
||||
"""
|
||||
function show(io::IO, t::DataTask)
|
||||
return print(io, "Data", t.data)
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskS1)
|
||||
show(io::IO, t::ComputeTaskABC_S1)
|
||||
|
||||
Print the S1 task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskS1) = print(io, "ComputeS1")
|
||||
show(io::IO, t::ComputeTaskABC_S1) = print(io, "ComputeS1")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskS2)
|
||||
show(io::IO, t::ComputeTaskABC_S2)
|
||||
|
||||
Print the S2 task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskS2) = print(io, "ComputeS2")
|
||||
show(io::IO, t::ComputeTaskABC_S2) = print(io, "ComputeS2")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskP)
|
||||
show(io::IO, t::ComputeTaskABC_P)
|
||||
|
||||
Print the P task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskP) = print(io, "ComputeP")
|
||||
show(io::IO, t::ComputeTaskABC_P) = print(io, "ComputeP")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskU)
|
||||
show(io::IO, t::ComputeTaskABC_U)
|
||||
|
||||
Print the U task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskU) = print(io, "ComputeU")
|
||||
show(io::IO, t::ComputeTaskABC_U) = print(io, "ComputeU")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskV)
|
||||
show(io::IO, t::ComputeTaskABC_V)
|
||||
|
||||
Print the V task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskV) = print(io, "ComputeV")
|
||||
show(io::IO, t::ComputeTaskABC_V) = print(io, "ComputeV")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskSum)
|
||||
show(io::IO, t::ComputeTaskABC_Sum)
|
||||
|
||||
Print the sum task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskSum) = print(io, "ComputeSum")
|
||||
show(io::IO, t::ComputeTaskABC_Sum) = print(io, "ComputeSum")
|
||||
|
||||
"""
|
||||
copy(t::DataTask)
|
||||
children(::ComputeTaskABC_S1)
|
||||
|
||||
Copy the data task and return it.
|
||||
Return the number of children of a ComputeTaskABC_S1 (always 1).
|
||||
"""
|
||||
copy(t::DataTask) = DataTask(t.data)
|
||||
children(::ComputeTaskABC_S1) = 1
|
||||
|
||||
"""
|
||||
children(::DataTask)
|
||||
children(::ComputeTaskABC_S2)
|
||||
|
||||
Return the number of children of a data task (always 1).
|
||||
Return the number of children of a ComputeTaskABC_S2 (always 2).
|
||||
"""
|
||||
children(::DataTask) = 1
|
||||
children(::ComputeTaskABC_S2) = 2
|
||||
|
||||
"""
|
||||
children(::ComputeTaskS1)
|
||||
children(::ComputeTaskABC_P)
|
||||
|
||||
Return the number of children of a ComputeTaskS1 (always 1).
|
||||
Return the number of children of a ComputeTaskABC_P (always 1).
|
||||
"""
|
||||
children(::ComputeTaskS1) = 1
|
||||
children(::ComputeTaskABC_P) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskS2)
|
||||
children(::ComputeTaskABC_U)
|
||||
|
||||
Return the number of children of a ComputeTaskS2 (always 2).
|
||||
Return the number of children of a ComputeTaskABC_U (always 1).
|
||||
"""
|
||||
children(::ComputeTaskS2) = 2
|
||||
children(::ComputeTaskABC_U) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskP)
|
||||
children(::ComputeTaskABC_V)
|
||||
|
||||
Return the number of children of a ComputeTaskP (always 1).
|
||||
Return the number of children of a ComputeTaskABC_V (always 2).
|
||||
"""
|
||||
children(::ComputeTaskP) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskU)
|
||||
|
||||
Return the number of children of a ComputeTaskU (always 1).
|
||||
"""
|
||||
children(::ComputeTaskU) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskV)
|
||||
|
||||
Return the number of children of a ComputeTaskV (always 2).
|
||||
"""
|
||||
children(::ComputeTaskV) = 2
|
||||
children(::ComputeTaskABC_V) = 2
|
||||
|
||||
|
||||
"""
|
||||
children(::ComputeTaskSum)
|
||||
children(::ComputeTaskABC_Sum)
|
||||
|
||||
Return the number of children of a ComputeTaskSum.
|
||||
Return the number of children of a ComputeTaskABC_Sum.
|
||||
"""
|
||||
children(t::ComputeTaskSum) = t.children_number
|
||||
children(t::ComputeTaskABC_Sum) = t.children_number
|
||||
|
||||
"""
|
||||
children(t::FusedComputeTask)
|
||||
|
||||
Return the number of children of a FusedComputeTask.
|
||||
"""
|
||||
function children(t::FusedComputeTask)
|
||||
return length(union(Set(t.t1_inputs), Set(t.t2_inputs)))
|
||||
end
|
||||
|
||||
function add_child!(t::ComputeTaskSum)
|
||||
function add_child!(t::ComputeTaskABC_Sum)
|
||||
t.children_number += 1
|
||||
return nothing
|
||||
end
|
||||
|
@ -1,53 +1,44 @@
|
||||
"""
|
||||
DataTask <: AbstractDataTask
|
||||
|
||||
Task representing a specific data transfer in the ABC Model.
|
||||
"""
|
||||
struct DataTask <: AbstractDataTask
|
||||
data::UInt64
|
||||
end
|
||||
|
||||
"""
|
||||
ComputeTaskS1 <: AbstractComputeTask
|
||||
ComputeTaskABC_S1 <: AbstractComputeTask
|
||||
|
||||
S task with a single child.
|
||||
"""
|
||||
struct ComputeTaskS1 <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_S1 <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskS2 <: AbstractComputeTask
|
||||
ComputeTaskABC_S2 <: AbstractComputeTask
|
||||
|
||||
S task with two children.
|
||||
"""
|
||||
struct ComputeTaskS2 <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_S2 <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskP <: AbstractComputeTask
|
||||
ComputeTaskABC_P <: AbstractComputeTask
|
||||
|
||||
P task with no children.
|
||||
"""
|
||||
struct ComputeTaskP <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_P <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskV <: AbstractComputeTask
|
||||
ComputeTaskABC_V <: AbstractComputeTask
|
||||
|
||||
v task with two children.
|
||||
"""
|
||||
struct ComputeTaskV <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_V <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskU <: AbstractComputeTask
|
||||
ComputeTaskABC_U <: AbstractComputeTask
|
||||
|
||||
u task with a single child.
|
||||
"""
|
||||
struct ComputeTaskU <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_U <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskSum <: AbstractComputeTask
|
||||
ComputeTaskABC_Sum <: AbstractComputeTask
|
||||
|
||||
Task that sums all its inputs, n children.
|
||||
"""
|
||||
mutable struct ComputeTaskSum <: AbstractComputeTask
|
||||
mutable struct ComputeTaskABC_Sum <: AbstractComputeTask
|
||||
children_number::Int
|
||||
end
|
||||
|
||||
@ -56,4 +47,5 @@ end
|
||||
|
||||
Constant vector of all tasks of the ABC-Model.
|
||||
"""
|
||||
ABC_TASKS = [DataTask, ComputeTaskS1, ComputeTaskS2, ComputeTaskP, ComputeTaskV, ComputeTaskU, ComputeTaskSum]
|
||||
ABC_TASKS =
|
||||
[ComputeTaskABC_S1, ComputeTaskABC_S2, ComputeTaskABC_P, ComputeTaskABC_V, ComputeTaskABC_U, ComputeTaskABC_Sum]
|
||||
|
@ -1,3 +1,5 @@
|
||||
import QEDbase.mass
|
||||
import QEDbase.AbstractParticle
|
||||
|
||||
"""
|
||||
AbstractPhysicsModel
|
||||
@ -6,23 +8,16 @@ Base type for a model, e.g. ABC-Model or QED. This is used to dispatch many func
|
||||
"""
|
||||
abstract type AbstractPhysicsModel end
|
||||
|
||||
"""
|
||||
AbstractParticle
|
||||
|
||||
Base type for particles belonging to a certain [`AbstractPhysicsModel`](@ref).
|
||||
"""
|
||||
abstract type AbstractParticle end
|
||||
|
||||
"""
|
||||
ParticleValue{ParticleType <: AbstractParticle}
|
||||
|
||||
A struct describing a particle during a calculation of a Feynman Diagram, together with the value that's being calculated.
|
||||
A struct describing a particle during a calculation of a Feynman Diagram, together with the value that's being calculated. `AbstractParticle` is the type from the QEDbase package.
|
||||
|
||||
`sizeof(ParticleValue())` = 48 Byte
|
||||
"""
|
||||
struct ParticleValue{ParticleType <: AbstractParticle}
|
||||
struct ParticleValue{ParticleType <: AbstractParticle, ValueType}
|
||||
p::ParticleType
|
||||
v::Float64
|
||||
v::ValueType
|
||||
end
|
||||
|
||||
"""
|
||||
@ -43,13 +38,6 @@ See also: [`gen_process_input`](@ref)
|
||||
"""
|
||||
abstract type AbstractProcessInput end
|
||||
|
||||
"""
|
||||
mass(t::Type{T}) where {T <: AbstractParticle}
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractParticle`](@ref), returning the particles mass at rest.
|
||||
"""
|
||||
function mass end
|
||||
|
||||
"""
|
||||
interaction_result(t1::Type{T1}, t2::Type{T2}) where {T1 <: AbstractParticle, T2 <: AbstractParticle}
|
||||
|
||||
@ -107,3 +95,18 @@ Interface function that must be implemented for every specific [`AbstractProcess
|
||||
Returns a randomly generated and valid corresponding `ProcessInput`.
|
||||
"""
|
||||
function gen_process_input end
|
||||
|
||||
"""
|
||||
model(::AbstractProcessDescription)
|
||||
model(::AbstarctProcessInput)
|
||||
|
||||
Return the model of this process description or input.
|
||||
"""
|
||||
function model end
|
||||
|
||||
"""
|
||||
type_from_name(model::AbstractModel, name::String)
|
||||
|
||||
For a name of a particle in the given [`AbstractModel`](@ref), return the particle's [`Type`] and index as a tuple. The input string can be expetced to be of the form \"<name><index>\".
|
||||
"""
|
||||
function type_index_from_name end
|
||||
|
198
src/models/qed/compute.jl
Normal file
198
src/models/qed/compute.jl
Normal file
@ -0,0 +1,198 @@
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskQED_P, data::QEDParticleValue)
|
||||
|
||||
Return the particle as is and initialize the Value.
|
||||
"""
|
||||
function compute(::ComputeTaskQED_P, data::QEDParticleValue{P})::QEDParticleValue{P} where {P <: QEDParticle}
|
||||
# TODO do we actually need this for anything?
|
||||
return QEDParticleValue{P}(data.p, one(DiracMatrix))
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskQED_U, data::QEDParticleValue)
|
||||
|
||||
Compute an outer edge. Return the particle value with the same particle and the value multiplied by an outer_edge factor.
|
||||
"""
|
||||
function compute(::ComputeTaskQED_U, data::PV) where {P <: QEDParticle, PV <: QEDParticleValue{P}}
|
||||
state = base_state(particle(data.p), direction(data.p), momentum(data.p), spin_or_pol(data.p))
|
||||
return ParticleValue{P, typeof(state)}(
|
||||
data.p,
|
||||
state, # will return a SLorentzVector{ComplexF64}, BiSpinor or AdjointBiSpinor
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskQED_V, data1::QEDParticleValue, data2::QEDParticleValue)
|
||||
|
||||
Compute a vertex. Preserve momentum and particle types (e + gamma->p etc.) to create resulting particle, multiply values together and times a vertex factor.
|
||||
"""
|
||||
function compute(
|
||||
::ComputeTaskQED_V,
|
||||
data1::PV1,
|
||||
data2::PV2,
|
||||
) where {P1 <: QEDParticle, P2 <: QEDParticle, PV1 <: QEDParticleValue{P1}, PV2 <: QEDParticleValue{P2}}
|
||||
p3 = QED_conserve_momentum(data1.p, data2.p)
|
||||
P3 = interaction_result(P1, P2)
|
||||
|
||||
state = QED_vertex()
|
||||
if (typeof(data1.v) <: AdjointBiSpinor)
|
||||
state = data1.v * state
|
||||
else
|
||||
state = state * data1.v
|
||||
end
|
||||
if (typeof(data2.v) <: AdjointBiSpinor)
|
||||
state = data2.v * state
|
||||
else
|
||||
state = state * data2.v
|
||||
end
|
||||
|
||||
dataOut = ParticleValue{P3, typeof(state)}(P3(p3), state)
|
||||
return dataOut
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskQED_S2, data1::QEDParticleValue, data2::QEDParticleValue)
|
||||
|
||||
Compute a final inner edge (2 input particles, no output particle).
|
||||
|
||||
For valid inputs, both input particles should have the same momenta at this point.
|
||||
|
||||
12 FLOP.
|
||||
"""
|
||||
function compute(
|
||||
::ComputeTaskQED_S2,
|
||||
data1::ParticleValue{P1},
|
||||
data2::ParticleValue{P2},
|
||||
)::ComplexF64 where {
|
||||
P1 <: Union{AntiFermionStateful, FermionStateful},
|
||||
P2 <: Union{AntiFermionStateful, FermionStateful},
|
||||
}
|
||||
@assert isapprox(data1.p.momentum, data2.p.momentum, rtol = sqrt(eps()), atol = sqrt(eps())) "$(data1.p.momentum) vs. $(data2.p.momentum)"
|
||||
|
||||
inner = QED_inner_edge(propagation_result(P1)(data1.p))
|
||||
|
||||
# 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
|
||||
else
|
||||
return data1.v * inner * data2.v
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: S2 when the particles are photons?
|
||||
function compute(
|
||||
::ComputeTaskQED_S2,
|
||||
data1::ParticleValue{P1},
|
||||
data2::ParticleValue{P2},
|
||||
)::ComplexF64 where {P1 <: PhotonStateful, P2 <: PhotonStateful}
|
||||
# TODO: assert that data1 and data2 are opposites
|
||||
inner = QED_inner_edge(data1.p)
|
||||
# inner edge is just a scalar, data1 and data2 are photon states that are just Complex numbers here
|
||||
return data1.v * inner * data2.v
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskQED_S1, data::QEDParticleValue)
|
||||
|
||||
Compute inner edge (1 input particle, 1 output particle).
|
||||
"""
|
||||
function compute(::ComputeTaskQED_S1, data::QEDParticleValue{P})::QEDParticleValue where {P <: QEDParticle}
|
||||
newP = propagation_result(P)
|
||||
new_p = newP(data.p)
|
||||
# inner edge is just a scalar, can multiply from either side
|
||||
if typeof(data.v) <: BiSpinor
|
||||
return ParticleValue(new_p, QED_inner_edge(new_p) * data.v)
|
||||
else
|
||||
return ParticleValue(new_p, data.v * QED_inner_edge(new_p))
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskQED_Sum, data::Vector{ComplexF64})
|
||||
|
||||
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::Vector{ComplexF64})::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(), [$(unroll_symbol_vector(in))])")
|
||||
end
|
172
src/models/qed/create.jl
Normal file
172
src/models/qed/create.jl
Normal file
@ -0,0 +1,172 @@
|
||||
|
||||
ComputeTaskQED_Sum() = ComputeTaskQED_Sum(0)
|
||||
|
||||
"""
|
||||
gen_process_input(processDescription::QEDProcessDescription)
|
||||
|
||||
Return a ProcessInput of randomly generated [`QEDParticle`](@ref)s from a [`QEDProcessDescription`](@ref). The process description can be created manually or parsed from a string using [`parse_process`](@ref).
|
||||
|
||||
Note: This uses RAMBO to create a valid process with conservation of momentum and energy.
|
||||
"""
|
||||
function gen_process_input(processDescription::QEDProcessDescription)
|
||||
massSum = 0
|
||||
inputMasses = Vector{Float64}()
|
||||
for (particle, n) in processDescription.inParticles
|
||||
for _ in 1:n
|
||||
massSum += mass(particle)
|
||||
push!(inputMasses, mass(particle))
|
||||
end
|
||||
end
|
||||
outputMasses = Vector{Float64}()
|
||||
for (particle, n) in processDescription.outParticles
|
||||
for _ in 1:n
|
||||
massSum += mass(particle)
|
||||
push!(outputMasses, mass(particle))
|
||||
end
|
||||
end
|
||||
|
||||
# add some extra random mass to allow for some momentum
|
||||
massSum += rand(rng[threadid()]) * (length(inputMasses) + length(outputMasses))
|
||||
|
||||
|
||||
inputParticles = Vector{QEDParticle}()
|
||||
initialMomenta = generate_initial_moms(massSum, inputMasses)
|
||||
index = 1
|
||||
for (particle, n) in processDescription.inParticles
|
||||
for _ in 1:n
|
||||
mom = initialMomenta[index]
|
||||
push!(inputParticles, particle(mom))
|
||||
index += 1
|
||||
end
|
||||
end
|
||||
|
||||
outputParticles = Vector{QEDParticle}()
|
||||
final_momenta = generate_physical_massive_moms(rng[threadid()], massSum, outputMasses)
|
||||
index = 1
|
||||
for (particle, n) in processDescription.outParticles
|
||||
for _ in 1:n
|
||||
push!(outputParticles, particle(final_momenta[index]))
|
||||
index += 1
|
||||
end
|
||||
end
|
||||
|
||||
processInput = QEDProcessInput(processDescription, inputParticles, outputParticles)
|
||||
|
||||
return return processInput
|
||||
end
|
||||
|
||||
"""
|
||||
gen_graph(process_description::QEDProcessDescription)
|
||||
|
||||
For a given [`QEDProcessDescription`](@ref), return the [`DAG`](@ref) that computes it.
|
||||
"""
|
||||
function gen_graph(process_description::QEDProcessDescription)
|
||||
initial_diagram = FeynmanDiagram(process_description)
|
||||
diagrams = gen_diagrams(initial_diagram)
|
||||
|
||||
graph = DAG()
|
||||
|
||||
COMPLEX_SIZE = sizeof(ComplexF64)
|
||||
PARTICLE_VALUE_SIZE = 96.0
|
||||
|
||||
# TODO: Not all diagram outputs should always be summed at the end, if they differ by fermion exchange they need to be diffed
|
||||
# Should not matter for n-Photon Compton processes though
|
||||
sum_node = insert_node!(graph, make_node(ComputeTaskQED_Sum(0)), track = false, invalidate_cache = false)
|
||||
global_data_out = insert_node!(graph, make_node(DataTask(COMPLEX_SIZE)), track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, sum_node, global_data_out, track = false, invalidate_cache = false)
|
||||
|
||||
# remember the data out nodes for connection
|
||||
dataOutNodes = Dict()
|
||||
|
||||
for particle in initial_diagram.particles
|
||||
# generate data in and U tasks
|
||||
data_in = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE), String(particle)),
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
) # read particle data node
|
||||
compute_u = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false, invalidate_cache = false) # compute U node
|
||||
data_out =
|
||||
insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false) # transfer data out from u (one ABCParticleValue object)
|
||||
|
||||
insert_edge!(graph, data_in, compute_u, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, compute_u, data_out, track = false, invalidate_cache = false)
|
||||
|
||||
# remember the data_out node for future edges
|
||||
dataOutNodes[String(particle)] = data_out
|
||||
end
|
||||
|
||||
#dataOutBackup = copy(dataOutNodes)
|
||||
|
||||
for diagram in diagrams
|
||||
# the intermediate (virtual) particles change across
|
||||
#dataOutNodes = copy(dataOutBackup)
|
||||
|
||||
tie = diagram.tie[]
|
||||
|
||||
# handle the vertices
|
||||
for vertices in diagram.vertices
|
||||
for vertex in vertices
|
||||
data_in1 = dataOutNodes[String(vertex.in1)]
|
||||
data_in2 = dataOutNodes[String(vertex.in2)]
|
||||
|
||||
compute_V = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false, invalidate_cache = false) # compute vertex
|
||||
|
||||
insert_edge!(graph, data_in1, compute_V, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, data_in2, compute_V, track = false, invalidate_cache = false)
|
||||
|
||||
data_V_out = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
)
|
||||
|
||||
insert_edge!(graph, compute_V, data_V_out, track = false, invalidate_cache = false)
|
||||
|
||||
if (vertex.out == tie.in1 || vertex.out == tie.in2)
|
||||
# out particle is part of the tie -> there will be an S2 task with it later, don't make S1 task
|
||||
dataOutNodes[String(vertex.out)] = data_V_out
|
||||
continue
|
||||
end
|
||||
|
||||
# otherwise, add S1 task
|
||||
compute_S1 =
|
||||
insert_node!(graph, make_node(ComputeTaskQED_S1()), track = false, invalidate_cache = false) # compute propagator
|
||||
|
||||
insert_edge!(graph, data_V_out, compute_S1, track = false, invalidate_cache = false)
|
||||
|
||||
data_S1_out = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
)
|
||||
|
||||
insert_edge!(graph, compute_S1, data_S1_out, track = false, invalidate_cache = false)
|
||||
|
||||
# overrides potentially different nodes from previous diagrams, which is intentional
|
||||
dataOutNodes[String(vertex.out)] = data_S1_out
|
||||
end
|
||||
end
|
||||
|
||||
# handle the tie
|
||||
data_in1 = dataOutNodes[String(tie.in1)]
|
||||
data_in2 = dataOutNodes[String(tie.in2)]
|
||||
|
||||
compute_S2 = insert_node!(graph, make_node(ComputeTaskQED_S2()), track = false, invalidate_cache = false)
|
||||
|
||||
data_S2 = insert_node!(graph, make_node(DataTask(PARTICLE_VALUE_SIZE)), track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, data_in1, compute_S2, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, data_in2, compute_S2, track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, compute_S2, data_S2, track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, data_S2, sum_node, track = false, invalidate_cache = false)
|
||||
add_child!(task(sum_node))
|
||||
end
|
||||
|
||||
return graph
|
||||
end
|
484
src/models/qed/diagrams.jl
Normal file
484
src/models/qed/diagrams.jl
Normal file
@ -0,0 +1,484 @@
|
||||
|
||||
import Base.copy
|
||||
import Base.hash
|
||||
import Base.==
|
||||
import Base.show
|
||||
|
||||
"""
|
||||
FeynmanParticle
|
||||
|
||||
Representation of a particle for use in [`FeynmanDiagram`](@ref)s. Consist of the [`QEDParticle`](@ref) type and an id.
|
||||
"""
|
||||
struct FeynmanParticle
|
||||
particle::Type{<:QEDParticle}
|
||||
id::Int
|
||||
end
|
||||
|
||||
"""
|
||||
FeynmanVertex
|
||||
|
||||
Representation of a vertex in a [`FeynmanDiagram`](@ref). Stores two input [`FeynmanParticle`](@ref)s and one output.
|
||||
"""
|
||||
struct FeynmanVertex
|
||||
in1::FeynmanParticle
|
||||
in2::FeynmanParticle
|
||||
out::FeynmanParticle
|
||||
end
|
||||
|
||||
"""
|
||||
FeynmanTie
|
||||
|
||||
Representation of a "tie" in a [`FeynmanDiagram`](@ref). A tie ties two virtual particles in a diagram together and thus represent an inner line of the diagram. Not all inner lines are [`FeynmanTie`](@ref)s, in fact, a connected diagram only ever has exactly one tie.
|
||||
"""
|
||||
struct FeynmanTie
|
||||
in1::FeynmanParticle
|
||||
in2::FeynmanParticle
|
||||
end
|
||||
|
||||
"""
|
||||
FeynmanDiagram
|
||||
|
||||
Representation of a feynman diagram. It consists of its initial input/output particles, and a vector of sets of [`FeynmanVertex`](@ref)s. The vertices are to be applied level by level.
|
||||
A [`FeynmanVertex`](@ref) will always be at the lowest level possible, i.e. the lowest level at which all input particles for it exist.
|
||||
The [`FeynmanTie`](@ref) represents the final inner edge of the diagram.
|
||||
"""
|
||||
struct FeynmanDiagram
|
||||
vertices::Vector{Set{FeynmanVertex}}
|
||||
tie::Ref{Union{FeynmanTie, Missing}}
|
||||
particles::Vector{FeynmanParticle}
|
||||
type_ids::Dict{Type, Int64} # lut for number of used ids for a particle type
|
||||
end
|
||||
|
||||
"""
|
||||
FeynmanDiagram(pd::QEDProcessDescription)
|
||||
|
||||
Create an initial [`FeynmanDiagram`](@ref) with only its initial particles set and no vertices or ties.
|
||||
|
||||
Use [`gen_diagrams`](@ref) to generate all possible diagrams from this one.
|
||||
"""
|
||||
function FeynmanDiagram(pd::QEDProcessDescription)
|
||||
parts = Vector{FeynmanParticle}()
|
||||
for (type, n) in pd.inParticles
|
||||
for i in 1:n
|
||||
push!(parts, FeynmanParticle(type, i))
|
||||
end
|
||||
end
|
||||
for (type, n) in pd.outParticles
|
||||
for i in 1:n
|
||||
push!(parts, FeynmanParticle(type, i))
|
||||
end
|
||||
end
|
||||
ids = Dict{Type, Int64}()
|
||||
for t in types(QEDModel())
|
||||
if (isincoming(t))
|
||||
ids[t] = get(pd.inParticles, t, 0)
|
||||
else
|
||||
ids[t] = get(pd.outParticles, t, 0)
|
||||
end
|
||||
end
|
||||
|
||||
return FeynmanDiagram([], missing, parts, ids)
|
||||
end
|
||||
|
||||
function particle_after_tie(p::FeynmanParticle, t::FeynmanTie)
|
||||
if p == t.in1 || p == t.in2
|
||||
return FeynmanParticle(FermionStateful{Incoming}, -1) # placeholder particle and id for tied particles
|
||||
end
|
||||
return p
|
||||
end
|
||||
|
||||
function vertex_after_tie(v::FeynmanVertex, t::FeynmanTie)
|
||||
return FeynmanVertex(particle_after_tie(v.in1, t), particle_after_tie(v.in2, t), particle_after_tie(v.out, t))
|
||||
end
|
||||
|
||||
function vertex_after_tie(v::FeynmanVertex, t::Missing)
|
||||
return v
|
||||
end
|
||||
|
||||
function vertex_set_after_tie(vs::Set{FeynmanVertex}, t::FeynmanTie)
|
||||
return Set{FeynmanVertex}(vertex_after_tie(v, t) for v in vs)
|
||||
end
|
||||
|
||||
function vertex_set_after_tie(vs::Set{FeynmanVertex}, t::Missing)
|
||||
return vs
|
||||
end
|
||||
|
||||
function vertex_set_after_tie(vs::Set{FeynmanVertex}, t1::Union{FeynmanTie, Missing}, t2::Union{FeynmanTie, Missing})
|
||||
return Set{FeynmanVertex}(vertex_after_tie(vertex_after_tie(v, t1), t2) for v in vs)
|
||||
end
|
||||
|
||||
"""
|
||||
String(p::FeynmanParticle)
|
||||
|
||||
Return a string representation of the [`FeynmanParticle`](@ref) in a format that is readable by [`type_index_from_name`](@ref).
|
||||
"""
|
||||
function String(p::FeynmanParticle)
|
||||
return "$(String(p.particle))$(String(direction(p.particle)))$(p.id)"
|
||||
end
|
||||
|
||||
function hash(v::FeynmanVertex)
|
||||
return hash(v.in1) * hash(v.in2)
|
||||
end
|
||||
|
||||
function hash(t::FeynmanTie)
|
||||
return hash(t.in1) * hash(t.in2)
|
||||
end
|
||||
|
||||
function hash(d::FeynmanDiagram)
|
||||
return hash((d.vertices, d.particles))
|
||||
end
|
||||
|
||||
function ==(v1::FeynmanVertex, v2::FeynmanVertex)
|
||||
return (v1.in1 == v2.in1 && v1.in2 == v2.in1) || (v1.in2 == v2.in1 && v1.in1 == v2.in2)
|
||||
end
|
||||
|
||||
function ==(t1::FeynmanTie, t2::FeynmanTie)
|
||||
return (t1.in1 == t2.in1 && t1.in2 == t2.in1) || (t1.in2 == t2.in1 && t1.in1 == t2.in2)
|
||||
end
|
||||
|
||||
function ==(d1::FeynmanDiagram, d2::FeynmanDiagram)
|
||||
if (!ismissing(d1.tie[]) && ismissing(d2.tie[])) || (ismissing(d1.tie[]) && !ismissing(d2.tie[]))
|
||||
return false
|
||||
end
|
||||
if d1.particles != d2.particles
|
||||
return false
|
||||
end
|
||||
if length(d1.vertices) != length(d2.vertices)
|
||||
return false
|
||||
end
|
||||
|
||||
# TODO can i prove that this works?
|
||||
for (v1, v2) in zip(d1.vertices, d2.vertices)
|
||||
if vertex_set_after_tie(v1, d1.tie[], d2.tie[]) != vertex_set_after_tie(v2, d1.tie[], d2.tie[])
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
|
||||
#=return isequal.(
|
||||
vertex_set_after_tie(d1.vertices, d1.tie, d2.tie),
|
||||
vertex_set_after_tie(d2.vertices, d1.tie, d2.tie),
|
||||
)=#
|
||||
end
|
||||
|
||||
copy(fd::FeynmanDiagram) =
|
||||
FeynmanDiagram(deepcopy(fd.vertices), copy(fd.tie[]), deepcopy(fd.particles), copy(fd.type_ids))
|
||||
|
||||
"""
|
||||
id_for_type(d::FeynmanDiagram, t::Type{<:QEDParticle})
|
||||
|
||||
Return the highest id of any particle of the given type in the diagram + 1.
|
||||
"""
|
||||
function id_for_type(d::FeynmanDiagram, t::Type{<:QEDParticle})
|
||||
return d.type_ids[t] + 1
|
||||
end
|
||||
|
||||
"""
|
||||
can_apply_vertex(particles::Vector{FeynmanParticle}, vertex::FeynmanVertex)
|
||||
|
||||
Return true if the given [`FeynmanVertex`](@ref) can be applied to the given particles, i.e. both input particles of the vertex are in the vector and the output particle is not.
|
||||
"""
|
||||
function can_apply_vertex(particles::Vector{FeynmanParticle}, vertex::FeynmanVertex)
|
||||
return vertex.in1 in particles && vertex.in2 in particles && !(vertex.out in particles)
|
||||
end
|
||||
|
||||
"""
|
||||
apply_vertex!(particles::Vector{FeynmanParticle}, vertex::FeynmanVertex)
|
||||
|
||||
Apply a [`FeynmanVertex`](@ref) to the given vector of [`FeynmanParticle`](@ref)s.
|
||||
"""
|
||||
function apply_vertex!(particles::Vector{FeynmanParticle}, vertex::FeynmanVertex)
|
||||
#@assert can_apply_vertex(particles, vertex)
|
||||
length_before = length(particles)
|
||||
filter!(x -> x != vertex.in1 && x != vertex.in2, particles)
|
||||
push!(particles, vertex.out)
|
||||
#@assert length(particles) == length_before - 1
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
can_apply_tie(particles::Vector{FeynmanParticle}, tie::FeynmanTie)
|
||||
|
||||
Return true if the given [`FeynmanTie`](@ref) can be applied to the given particles, i.e. both input particles of the tie are in the vector.
|
||||
"""
|
||||
function can_apply_tie(particles::Vector{FeynmanParticle}, tie::FeynmanTie)
|
||||
return tie.in1 in particles && tie.in2 in particles
|
||||
end
|
||||
|
||||
"""
|
||||
apply_tie!(particles::Vector{FeynmanParticle}, tie::FeynmanTie)
|
||||
|
||||
Apply a [`FeynmanTie`](@ref) to the given vector of [`FeynmanParticle`](@ref)s.
|
||||
"""
|
||||
function apply_tie!(particles::Vector{FeynmanParticle}, tie::FeynmanTie)
|
||||
@assert length(particles) == 2
|
||||
@assert can_apply_tie(particles, tie)
|
||||
@assert can_tie(tie.in1.particle, tie.in2.particle)
|
||||
empty!(particles)
|
||||
@assert length(particles) == 0
|
||||
return nothing
|
||||
end
|
||||
|
||||
function apply_tie!(::Vector{FeynmanParticle}, ::Missing)
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
get_particles(fd::FeynmanDiagram, level::Int)
|
||||
|
||||
Return a vector of the particles after applying the vertices and tie of the diagram up to the given level. If no level is given, apply all. The tie comes last and is its own "level".
|
||||
"""
|
||||
function get_particles(fd::FeynmanDiagram, level::Int = -1)
|
||||
if level == -1
|
||||
level = length(fd.vertices) + 1
|
||||
end
|
||||
|
||||
working_particles = copy(fd.particles)
|
||||
for l in 1:length(fd.vertices)
|
||||
if l > level
|
||||
break
|
||||
end
|
||||
for v in fd.vertices[l]
|
||||
apply_vertex!(working_particles, v)
|
||||
end
|
||||
end
|
||||
|
||||
if (level > length(fd.vertices))
|
||||
apply_tie!(working_particles, fd.tie[])
|
||||
end
|
||||
|
||||
return working_particles
|
||||
end
|
||||
|
||||
"""
|
||||
add_vertex!(fd::FeynmanDiagram, vertex::FeynmanVertex)
|
||||
|
||||
Add the given vertex to the diagram, at the earliest level possible.
|
||||
"""
|
||||
function add_vertex!(fd::FeynmanDiagram, vertex::FeynmanVertex)
|
||||
for i in eachindex(fd.vertices)
|
||||
if (can_apply_vertex(get_particles(fd, i - 1), vertex))
|
||||
push!(fd.vertices[i], vertex)
|
||||
fd.type_ids[vertex.out.particle] += 1
|
||||
return nothing
|
||||
end
|
||||
end
|
||||
|
||||
if !can_apply_vertex(get_particles(fd), vertex)
|
||||
#@assert false "Can't add vertex $vertex to diagram"
|
||||
end
|
||||
|
||||
push!(fd.vertices, Set{FeynmanVertex}())
|
||||
push!(fd.vertices[end], vertex)
|
||||
fd.type_ids[vertex.out.particle] += 1
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
add_vertex(fd::FeynmanDiagram, vertex::FeynmanVertex)
|
||||
|
||||
Add the given vertex to the diagram, at the earliest level possible. Return the new diagram without muting the given one.
|
||||
"""
|
||||
function add_vertex(fd::FeynmanDiagram, vertex::FeynmanVertex)
|
||||
newfd = copy(fd)
|
||||
add_vertex!(newfd, vertex)
|
||||
return newfd
|
||||
end
|
||||
|
||||
"""
|
||||
add_tie!(fd::FeynmanDiagram, tie::FeynmanTie)
|
||||
|
||||
Add the given tie to the diagram, always at the last level.
|
||||
"""
|
||||
function add_tie!(fd::FeynmanDiagram, tie::FeynmanTie)
|
||||
if !can_apply_tie(get_particles(fd), tie)
|
||||
@assert false "Can't add tie $tie to diagram"
|
||||
end
|
||||
|
||||
fd.tie[] = tie
|
||||
#=
|
||||
@assert length(fd.vertices) >= 2
|
||||
#if the last vertex is involved in the tie and alone, lower it one level down
|
||||
if (length(fd.vertices[end]) != 1)
|
||||
return nothing
|
||||
end
|
||||
|
||||
vert = fd.vertices[end][1]
|
||||
if (vert != vertex_after_tie(vert, tie))
|
||||
return nothing
|
||||
end
|
||||
|
||||
pop!(fd.vertices)
|
||||
push!(fd.vertices[end], vert)
|
||||
=#
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
add_tie(fd::FeynmanDiagram, tie::FeynmanTie)
|
||||
|
||||
Add the given tie to the diagram, at the earliest level possible. Return the new diagram without muting the given one.
|
||||
"""
|
||||
function add_tie(fd::FeynmanDiagram, tie::FeynmanTie)
|
||||
newfd = copy(fd)
|
||||
add_tie!(newfd, tie)
|
||||
return newfd
|
||||
end
|
||||
|
||||
"""
|
||||
isvalid(fd::FeynmanDiagram)
|
||||
|
||||
Return whether the given diagram is valid. A diagram is valid iff the following are true:
|
||||
- After applying all vertices and the tie, there are no more particles left
|
||||
- The diagram is connected
|
||||
"""
|
||||
function isvalid(fd::FeynmanDiagram)
|
||||
if ismissing(fd.tie[])
|
||||
# diagram is connected iff there is one tie
|
||||
return false
|
||||
end
|
||||
|
||||
if get_particles(fd) != []
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
"""
|
||||
possible_vertices(fd::FeynmanDiagram)
|
||||
|
||||
Return a vector of all possible vertices that can be applied to the diagram at its current state.
|
||||
"""
|
||||
function possible_vertices(fd::FeynmanDiagram)
|
||||
possibilities = Vector{FeynmanVertex}()
|
||||
fully_generated_particles = get_particles(fd)
|
||||
|
||||
min_level = max(0, length(fd.vertices) - 1)
|
||||
for l in min_level:length(fd.vertices)
|
||||
particles = get_particles(fd, l)
|
||||
for i in 1:length(particles)
|
||||
for j in (i + 1):length(particles)
|
||||
p1 = particles[i]
|
||||
p2 = particles[j]
|
||||
if (caninteract(p1.particle, p2.particle))
|
||||
interaction_res = propagation_result(interaction_result(p1.particle, p2.particle))
|
||||
v = FeynmanVertex(p1, p2, FeynmanParticle(interaction_res, id_for_type(fd, interaction_res)))
|
||||
#@assert !(v.out in particles) "$v is in $fd"
|
||||
if !can_apply_vertex(fully_generated_particles, v)
|
||||
continue
|
||||
end
|
||||
push!(possibilities, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
if (!isempty(possibilities))
|
||||
return possibilities
|
||||
end
|
||||
end
|
||||
return possibilities
|
||||
end
|
||||
|
||||
"""
|
||||
can_tie(p1::Type, p2::Type)
|
||||
|
||||
For two given [`QEDParitcle`](@ref) types, return whether they can be tied together.
|
||||
|
||||
They can be tied iff one is the [`propagation_result`](@ref) of the other, or if both are photons, in which case their direction does not matter.
|
||||
"""
|
||||
function can_tie(p1::Type, p2::Type)
|
||||
if p1 == propagation_result(p2)
|
||||
return true
|
||||
end
|
||||
if (p1 <: PhotonStateful && p2 <: PhotonStateful)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
"""
|
||||
possible_tie(fd::FeynmanDiagram)
|
||||
|
||||
Return a possible tie or `missing` for the diagram at its current state.
|
||||
"""
|
||||
function possible_tie(fd::FeynmanDiagram)
|
||||
particles = get_particles(fd)
|
||||
if (length(particles) != 2)
|
||||
return missing
|
||||
end
|
||||
|
||||
if (particles[1] in fd.particles || particles[2] in fd.particles)
|
||||
return missing
|
||||
end
|
||||
|
||||
tie = FeynmanTie(particles[1], particles[2])
|
||||
if (can_apply_tie(particles, tie))
|
||||
return tie
|
||||
end
|
||||
return missing
|
||||
end
|
||||
|
||||
function remove_duplicates(compare_set::Set{FeynmanDiagram})
|
||||
result = Set()
|
||||
|
||||
while !isempty(compare_set)
|
||||
x = pop!(compare_set)
|
||||
# we know there will only be one duplicate if any, so search for that and delete it
|
||||
for y in compare_set
|
||||
if x == y
|
||||
delete!(compare_set, y)
|
||||
break
|
||||
end
|
||||
end
|
||||
push!(result, x)
|
||||
end
|
||||
|
||||
return result
|
||||
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)
|
||||
working = Set{FeynmanDiagram}()
|
||||
results = Set{FeynmanDiagram}()
|
||||
|
||||
push!(working, fd)
|
||||
|
||||
# we know there will be particle_number - 2 vertices, followed by 1 tie
|
||||
n_particles = length(fd.particles)
|
||||
n_vertices = n_particles - 2
|
||||
|
||||
# doing this in iterations should reduce the intermediate number of diagrams by hash collisions
|
||||
for _ in 1:n_vertices
|
||||
next_iter_set = Set{FeynmanDiagram}()
|
||||
|
||||
while !isempty(working)
|
||||
d = pop!(working)
|
||||
|
||||
possibilities = possible_vertices(d)
|
||||
for v in possibilities
|
||||
push!(next_iter_set, add_vertex(d, v))
|
||||
end
|
||||
end
|
||||
|
||||
working = next_iter_set
|
||||
end
|
||||
|
||||
# add the tie
|
||||
for d in working
|
||||
tie = possible_tie(d)
|
||||
if ismissing(tie)
|
||||
continue
|
||||
end
|
||||
add_tie!(d, tie)
|
||||
if isvalid(d)
|
||||
push!(results, d)
|
||||
end
|
||||
end
|
||||
|
||||
return remove_duplicates(results)
|
||||
end
|
44
src/models/qed/parse.jl
Normal file
44
src/models/qed/parse.jl
Normal file
@ -0,0 +1,44 @@
|
||||
|
||||
"""
|
||||
parse_process(string::AbstractString, model::QEDModel)
|
||||
|
||||
Parse a string representation of a process, such as "ke->ke" into the corresponding [`QEDProcessDescription`](@ref).
|
||||
"""
|
||||
function parse_process(str::AbstractString, model::QEDModel)
|
||||
inParticles = Dict{Type, Int}()
|
||||
outParticles = Dict{Type, Int}()
|
||||
|
||||
if !(contains(str, "->"))
|
||||
throw("Did not find -> while parsing process \"$str\"")
|
||||
end
|
||||
|
||||
(inStr, outStr) = split(str, "->")
|
||||
|
||||
if (isempty(inStr) || isempty(outStr))
|
||||
throw("Process (\"$str\") input or output part is empty!")
|
||||
end
|
||||
|
||||
for t in types(model)
|
||||
if (isincoming(t))
|
||||
inCount = count(x -> x == String(t)[1], inStr)
|
||||
|
||||
if inCount != 0
|
||||
inParticles[t] = inCount
|
||||
end
|
||||
end
|
||||
if (isoutgoing(t))
|
||||
outCount = count(x -> x == String(t)[1], outStr)
|
||||
if outCount != 0
|
||||
outParticles[t] = outCount
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if length(inStr) != sum(values(inParticles))
|
||||
throw("Encountered unknown characters in the input part of process \"$str\"")
|
||||
elseif length(outStr) != sum(values(outParticles))
|
||||
throw("Encountered unknown characters in the output part of process \"$str\"")
|
||||
end
|
||||
|
||||
return QEDProcessDescription(inParticles, outParticles)
|
||||
end
|
348
src/models/qed/particle.jl
Normal file
348
src/models/qed/particle.jl
Normal file
@ -0,0 +1,348 @@
|
||||
using QEDprocesses
|
||||
import QEDbase.mass
|
||||
|
||||
# TODO check
|
||||
const e = sqrt(4π / 137)
|
||||
|
||||
"""
|
||||
QEDModel <: AbstractPhysicsModel
|
||||
|
||||
Singleton definition for identification of the QED-Model.
|
||||
"""
|
||||
struct QEDModel <: AbstractPhysicsModel end
|
||||
|
||||
"""
|
||||
QEDParticle
|
||||
|
||||
Base type for all particles in the [`QEDModel`](@ref).
|
||||
|
||||
Its template parameter specifies the particle's direction.
|
||||
|
||||
The concrete types contain singletons of the types that they are, like `Photon` and `Electron` from QEDbase, and their state descriptions.
|
||||
"""
|
||||
abstract type QEDParticle{Direction <: ParticleDirection} <: AbstractParticle end
|
||||
|
||||
"""
|
||||
QEDProcessDescription <: AbstractProcessDescription
|
||||
|
||||
A description of a process in the QED-Model. Contains the input and output particles.
|
||||
|
||||
See also: [`in_particles`](@ref), [`out_particles`](@ref), [`parse_process`](@ref)
|
||||
"""
|
||||
struct QEDProcessDescription <: AbstractProcessDescription
|
||||
inParticles::Dict{Type{<:QEDParticle{Incoming}}, Int}
|
||||
outParticles::Dict{Type{<:QEDParticle{Outgoing}}, Int}
|
||||
end
|
||||
|
||||
"""
|
||||
QEDProcessInput <: AbstractProcessInput
|
||||
|
||||
Input for a QED Process. Contains the [`QEDProcessDescription`](@ref) of the process it is an input for, and the values of the in and out particles.
|
||||
|
||||
See also: [`gen_process_input`](@ref)
|
||||
"""
|
||||
struct QEDProcessInput <: AbstractProcessInput
|
||||
process::QEDProcessDescription
|
||||
inParticles::Vector{QEDParticle}
|
||||
outParticles::Vector{QEDParticle}
|
||||
end
|
||||
|
||||
QEDParticleValue{ParticleType <: QEDParticle} = Union{
|
||||
ParticleValue{ParticleType, BiSpinor},
|
||||
ParticleValue{ParticleType, AdjointBiSpinor},
|
||||
ParticleValue{ParticleType, DiracMatrix},
|
||||
ParticleValue{ParticleType, SLorentzVector{Float64}},
|
||||
ParticleValue{ParticleType, ComplexF64},
|
||||
}
|
||||
|
||||
"""
|
||||
PhotonStateful <: QEDParticle
|
||||
|
||||
A photon of the [`QEDModel`](@ref) with its state.
|
||||
"""
|
||||
struct PhotonStateful{Direction <: ParticleDirection} <: QEDParticle{Direction}
|
||||
momentum::SFourMomentum
|
||||
# this will maybe change to the full polarization vector? or do i need both
|
||||
polarization::AbstractDefinitePolarization
|
||||
end
|
||||
|
||||
PhotonStateful{Direction}(mom::SFourMomentum) where {Direction <: ParticleDirection} =
|
||||
PhotonStateful{Direction}(mom, PolX()) # TODO: make allpol possible
|
||||
|
||||
PhotonStateful{Dir1}(ph::PhotonStateful{Dir2}) where {Dir1 <: ParticleDirection, Dir2 <: ParticleDirection} =
|
||||
PhotonStateful{Dir1}(ph.momentum, ph.polarization)
|
||||
|
||||
"""
|
||||
FermionStateful <: QEDParticle
|
||||
|
||||
A fermion of the [`QEDModel`](@ref) with its state.
|
||||
"""
|
||||
struct FermionStateful{Direction <: ParticleDirection} <: QEDParticle{Direction}
|
||||
momentum::SFourMomentum
|
||||
spin::AbstractDefiniteSpin
|
||||
# TODO: mass for electron/muon/tauon representation?
|
||||
end
|
||||
|
||||
FermionStateful{Direction}(mom::SFourMomentum) where {Direction <: ParticleDirection} =
|
||||
FermionStateful{Direction}(mom, SpinUp()) # TODO: make allspin possible
|
||||
|
||||
FermionStateful{Dir1}(f::FermionStateful{Dir2}) where {Dir1 <: ParticleDirection, Dir2 <: ParticleDirection} =
|
||||
FermionStateful{Dir1}(f.momentum, f.spin)
|
||||
|
||||
"""
|
||||
AntiFermionStateful <: QEDParticle
|
||||
|
||||
An anti-fermion of the [`QEDModel`](@ref) with its state.
|
||||
"""
|
||||
struct AntiFermionStateful{Direction <: ParticleDirection} <: QEDParticle{Direction}
|
||||
momentum::SFourMomentum
|
||||
spin::AbstractDefiniteSpin
|
||||
# TODO: mass for electron/muon/tauon representation?
|
||||
end
|
||||
|
||||
AntiFermionStateful{Direction}(mom::SFourMomentum) where {Direction <: ParticleDirection} =
|
||||
AntiFermionStateful{Direction}(mom, SpinUp()) # TODO: make allspin possible
|
||||
|
||||
AntiFermionStateful{Dir1}(f::AntiFermionStateful{Dir2}) where {Dir1 <: ParticleDirection, Dir2 <: ParticleDirection} =
|
||||
AntiFermionStateful{Dir1}(f.momentum, f.spin)
|
||||
|
||||
"""
|
||||
interaction_result(t1::Type{T1}, t2::Type{T2}) where {T1 <: QEDParticle, T2 <: QEDParticle}
|
||||
|
||||
For two given particle types that can interact, return the third.
|
||||
"""
|
||||
function interaction_result(t1::Type{T1}, t2::Type{T2}) where {T1 <: QEDParticle, T2 <: QEDParticle}
|
||||
@assert false "Invalid interaction between particles of types $t1 and $t2"
|
||||
end
|
||||
|
||||
interaction_result(::Type{FermionStateful{Incoming}}, ::Type{FermionStateful{Outgoing}}) = PhotonStateful{Incoming}
|
||||
interaction_result(::Type{FermionStateful{Incoming}}, ::Type{AntiFermionStateful{Incoming}}) = PhotonStateful{Incoming}
|
||||
interaction_result(::Type{FermionStateful{Incoming}}, ::Type{<:PhotonStateful}) = FermionStateful{Outgoing}
|
||||
|
||||
interaction_result(::Type{FermionStateful{Outgoing}}, ::Type{FermionStateful{Incoming}}) = PhotonStateful{Incoming}
|
||||
interaction_result(::Type{FermionStateful{Outgoing}}, ::Type{AntiFermionStateful{Outgoing}}) = PhotonStateful{Incoming}
|
||||
interaction_result(::Type{FermionStateful{Outgoing}}, ::Type{<:PhotonStateful}) = FermionStateful{Incoming}
|
||||
|
||||
# antifermion mirror
|
||||
interaction_result(::Type{AntiFermionStateful{Incoming}}, t2::Type{<:QEDParticle}) =
|
||||
interaction_result(FermionStateful{Outgoing}, t2)
|
||||
interaction_result(::Type{AntiFermionStateful{Outgoing}}, t2::Type{<:QEDParticle}) =
|
||||
interaction_result(FermionStateful{Incoming}, t2)
|
||||
|
||||
# photon commutativity
|
||||
interaction_result(t1::Type{<:PhotonStateful}, t2::Type{<:QEDParticle}) = interaction_result(t2, t1)
|
||||
|
||||
# but prevent stack overflow
|
||||
function interaction_result(t1::Type{<:PhotonStateful}, t2::Type{<:PhotonStateful})
|
||||
@assert false "Invalid interaction between particles of types $t1 and $t2"
|
||||
end
|
||||
|
||||
"""
|
||||
propagation_result(t1::Type{T}) where {T <: QEDParticle}
|
||||
|
||||
Return the type of the inverted direction. E.g.
|
||||
"""
|
||||
propagation_result(::Type{FermionStateful{Incoming}}) = FermionStateful{Outgoing}
|
||||
propagation_result(::Type{FermionStateful{Outgoing}}) = FermionStateful{Incoming}
|
||||
propagation_result(::Type{AntiFermionStateful{Incoming}}) = AntiFermionStateful{Outgoing}
|
||||
propagation_result(::Type{AntiFermionStateful{Outgoing}}) = AntiFermionStateful{Incoming}
|
||||
propagation_result(::Type{PhotonStateful{Incoming}}) = PhotonStateful{Outgoing}
|
||||
propagation_result(::Type{PhotonStateful{Outgoing}}) = PhotonStateful{Incoming}
|
||||
|
||||
"""
|
||||
types(::QEDModel)
|
||||
|
||||
Return a Vector of the possible types of particle in the [`QEDModel`](@ref).
|
||||
"""
|
||||
function types(::QEDModel)
|
||||
return [
|
||||
PhotonStateful{Incoming},
|
||||
PhotonStateful{Outgoing},
|
||||
FermionStateful{Incoming},
|
||||
FermionStateful{Outgoing},
|
||||
AntiFermionStateful{Incoming},
|
||||
AntiFermionStateful{Outgoing},
|
||||
]
|
||||
end
|
||||
|
||||
# type piracy?
|
||||
String(::Type{Incoming}) = "Incoming"
|
||||
String(::Type{Outgoing}) = "Outgoing"
|
||||
|
||||
String(::Incoming) = "i"
|
||||
String(::Outgoing) = "o"
|
||||
|
||||
function String(::Type{<:PhotonStateful})
|
||||
return "k"
|
||||
end
|
||||
function String(::Type{<:FermionStateful})
|
||||
return "e"
|
||||
end
|
||||
function String(::Type{<:AntiFermionStateful})
|
||||
return "p"
|
||||
end
|
||||
|
||||
@inline particle(::PhotonStateful) = Photon()
|
||||
@inline particle(::FermionStateful) = Electron()
|
||||
@inline particle(::AntiFermionStateful) = Positron()
|
||||
|
||||
@inline momentum(p::PhotonStateful)::SFourMomentum = p.momentum
|
||||
@inline momentum(p::FermionStateful)::SFourMomentum = p.momentum
|
||||
@inline momentum(p::AntiFermionStateful)::SFourMomentum = p.momentum
|
||||
|
||||
@inline spin_or_pol(p::PhotonStateful)::AbstractPolarization = p.polarization
|
||||
@inline spin_or_pol(p::FermionStateful)::AbstractSpin = p.spin
|
||||
@inline spin_or_pol(p::AntiFermionStateful)::AbstractSpin = p.spin
|
||||
|
||||
@inline direction(::PhotonStateful{Dir}) where {Dir <: ParticleDirection} = Dir()
|
||||
@inline direction(::FermionStateful{Dir}) where {Dir <: ParticleDirection} = Dir()
|
||||
@inline direction(::AntiFermionStateful{Dir}) where {Dir <: ParticleDirection} = Dir()
|
||||
|
||||
@inline direction(::Type{PhotonStateful{Dir}}) where {Dir <: ParticleDirection} = Dir()
|
||||
@inline direction(::Type{FermionStateful{Dir}}) where {Dir <: ParticleDirection} = Dir()
|
||||
@inline direction(::Type{AntiFermionStateful{Dir}}) where {Dir <: ParticleDirection} = Dir()
|
||||
|
||||
@inline isincoming(::QEDParticle{Incoming}) = true
|
||||
@inline isincoming(::QEDParticle{Outgoing}) = false
|
||||
@inline isoutgoing(::QEDParticle{Incoming}) = false
|
||||
@inline isoutgoing(::QEDParticle{Outgoing}) = true
|
||||
|
||||
@inline isincoming(::Type{<:QEDParticle{Incoming}}) = true
|
||||
@inline isincoming(::Type{<:QEDParticle{Outgoing}}) = false
|
||||
@inline isoutgoing(::Type{<:QEDParticle{Incoming}}) = false
|
||||
@inline isoutgoing(::Type{<:QEDParticle{Outgoing}}) = true
|
||||
|
||||
@inline mass(::Type{<:FermionStateful}) = 1.0
|
||||
@inline mass(::Type{<:AntiFermionStateful}) = 1.0
|
||||
@inline mass(::Type{<:PhotonStateful}) = 0.0
|
||||
|
||||
@inline invert_momentum(p::FermionStateful{Dir}) where {Dir <: ParticleDirection} =
|
||||
FermionStateful{Dir}(-p.momentum, p.spin)
|
||||
@inline invert_momentum(p::AntiFermionStateful{Dir}) where {Dir <: ParticleDirection} =
|
||||
AntiFermionStateful{Dir}(-p.momentum, p.spin)
|
||||
@inline invert_momentum(k::PhotonStateful{Dir}) where {Dir <: ParticleDirection} =
|
||||
PhotonStateful{Dir}(-k.momentum, k.polarization)
|
||||
|
||||
|
||||
"""
|
||||
caninteract(T1::Type{<:QEDParticle}, T2::Type{<:QEDParticle})
|
||||
|
||||
For two given [`QEDParticle`](@ref) types, return whether they can interact at a vertex. This is equivalent to `!issame(T1, T2)`.
|
||||
|
||||
See also: [`issame`](@ref) and [`interaction_result`](@ref)
|
||||
"""
|
||||
function caninteract(T1::Type{<:QEDParticle}, T2::Type{<:QEDParticle})
|
||||
if (T1 == T2)
|
||||
return false
|
||||
end
|
||||
if (T1 <: PhotonStateful && T2 <: PhotonStateful)
|
||||
return false
|
||||
end
|
||||
|
||||
for (P1, P2) in [(T1, T2), (T2, T1)]
|
||||
if (P1 == FermionStateful{Incoming} && P2 == AntiFermionStateful{Outgoing})
|
||||
return false
|
||||
end
|
||||
if (P1 == FermionStateful{Outgoing} && P2 == AntiFermionStateful{Incoming})
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function type_index_from_name(::QEDModel, name::String)
|
||||
if startswith(name, "ki")
|
||||
return (PhotonStateful{Incoming}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "ko")
|
||||
return (PhotonStateful{Outgoing}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "ei")
|
||||
return (FermionStateful{Incoming}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "eo")
|
||||
return (FermionStateful{Outgoing}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "pi")
|
||||
return (AntiFermionStateful{Incoming}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "po")
|
||||
return (AntiFermionStateful{Outgoing}, parse(Int, name[3:end]))
|
||||
else
|
||||
throw("Invalid name for a particle in the QED model")
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
issame(T1::Type{<:QEDParticle}, T2::Type{<:QEDParticle})
|
||||
|
||||
For two given [`QEDParticle`](@ref) types, return whether they are equivalent for the purpose of a Feynman Diagram. That means e.g. an `Incoming` `AntiFermion` is the same as an `Outgoing` `Fermion`. This is equivalent to `!caninteract(T1, T2)`.
|
||||
|
||||
See also: [`caninteract`](@ref) and [`interaction_result`](@ref)
|
||||
"""
|
||||
function issame(T1::Type{<:QEDParticle}, T2::Type{<:QEDParticle})
|
||||
return !caninteract(T1, T2)
|
||||
end
|
||||
|
||||
"""
|
||||
QED_vertex()
|
||||
|
||||
Return the factor of a vertex in a QED feynman diagram.
|
||||
"""
|
||||
@inline function QED_vertex()::SLorentzVector{DiracMatrix}
|
||||
# Peskin-Schroeder notation
|
||||
return -1im * e * gamma()
|
||||
end
|
||||
|
||||
@inline function QED_inner_edge(p::QEDParticle)
|
||||
pos_mom = p.momentum
|
||||
return propagator(particle(p), pos_mom)
|
||||
end
|
||||
|
||||
"""
|
||||
QED_conserve_momentum(p1::QEDParticle, p2::QEDParticle)
|
||||
|
||||
Calculate and return a new particle from two given interacting ones at a vertex.
|
||||
"""
|
||||
function QED_conserve_momentum(p1::QEDParticle, p2::QEDParticle)
|
||||
#println("Conserving momentum of \n$(direction(p1)) $(p1)\n and \n$(direction(p2)) $(p2)")
|
||||
T3 = interaction_result(typeof(p1), typeof(p2))
|
||||
# TODO: probably also need to do something about the spin/pol
|
||||
p1_mom = p1.momentum
|
||||
if (typeof(direction(p1)) <: Outgoing)
|
||||
p1_mom *= -1
|
||||
end
|
||||
p2_mom = p2.momentum
|
||||
if (typeof(direction(p2)) <: Outgoing)
|
||||
p2_mom *= -1
|
||||
end
|
||||
|
||||
p3_mom = p1_mom + p2_mom
|
||||
if (typeof(direction(T3)) <: Incoming)
|
||||
return T3(-p3_mom)
|
||||
end
|
||||
return T3(p3_mom)
|
||||
end
|
||||
|
||||
"""
|
||||
model(::AbstractProcessDescription)
|
||||
|
||||
Return the model of this process description.
|
||||
"""
|
||||
model(::QEDProcessDescription) = QEDModel()
|
||||
model(::QEDProcessInput) = QEDModel()
|
||||
|
||||
==(p1::QEDProcessDescription, p2::QEDProcessDescription) =
|
||||
p1.inParticles == p2.inParticles && p1.outParticles == p2.outParticles
|
||||
|
||||
function in_particles(process::QEDProcessDescription)
|
||||
return process.inParticles
|
||||
end
|
||||
|
||||
function in_particles(input::QEDProcessInput)
|
||||
return input.inParticles
|
||||
end
|
||||
|
||||
function out_particles(process::QEDProcessDescription)
|
||||
return process.outParticles
|
||||
end
|
||||
|
||||
function out_particles(input::QEDProcessInput)
|
||||
return input.outParticles
|
||||
end
|
115
src/models/qed/print.jl
Normal file
115
src/models/qed/print.jl
Normal file
@ -0,0 +1,115 @@
|
||||
|
||||
"""
|
||||
show(io::IO, process::QEDProcessDescription)
|
||||
|
||||
Pretty print an [`QEDProcessDescription`](@ref) (no newlines).
|
||||
|
||||
```jldoctest
|
||||
julia> using MetagraphOptimization
|
||||
|
||||
julia> print(parse_process("ke->ke", QEDModel()))
|
||||
QED Process: 'ke->ke'
|
||||
|
||||
julia> print(parse_process("kk->ep", QEDModel()))
|
||||
QED Process: 'kk->ep'
|
||||
```
|
||||
"""
|
||||
function show(io::IO, process::QEDProcessDescription)
|
||||
# types() gives the types in order (QED) instead of random like keys() would
|
||||
print(io, "QED Process: \'")
|
||||
for type in types(QEDModel())
|
||||
for _ in 1:get(process.inParticles, type, 0)
|
||||
print(io, String(type))
|
||||
end
|
||||
end
|
||||
print(io, "->")
|
||||
for type in types(QEDModel())
|
||||
for _ in 1:get(process.outParticles, type, 0)
|
||||
print(io, String(type))
|
||||
end
|
||||
end
|
||||
print(io, "'")
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, processInput::QEDProcessInput)
|
||||
|
||||
Pretty print an [`QEDProcessInput`](@ref) (with newlines).
|
||||
"""
|
||||
function show(io::IO, processInput::QEDProcessInput)
|
||||
println(io, "Input for $(processInput.process):")
|
||||
println(io, " $(length(processInput.inParticles)) Incoming particles:")
|
||||
for particle in processInput.inParticles
|
||||
println(io, " $particle")
|
||||
end
|
||||
println(io, " $(length(processInput.outParticles)) Outgoing Particles:")
|
||||
for particle in processInput.outParticles
|
||||
println(io, " $particle")
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, particle::T) where {T <: QEDParticle}
|
||||
|
||||
Pretty print an [`QEDParticle`](@ref) (no newlines).
|
||||
"""
|
||||
function show(io::IO, particle::T) where {T <: QEDParticle}
|
||||
print(io, "$(String(typeof(particle))): $(particle.momentum)")
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, particle::FeynmanParticle)
|
||||
|
||||
Pretty print a [`FeynmanParticle`](@ref) (no newlines).
|
||||
"""
|
||||
show(io::IO, p::FeynmanParticle) = print(io, "$(String(p.particle))_$(String(direction(p.particle)))_$(p.id)")
|
||||
|
||||
"""
|
||||
show(io::IO, particle::FeynmanVertex)
|
||||
|
||||
Pretty print a [`FeynmanVertex`](@ref) (no newlines).
|
||||
"""
|
||||
show(io::IO, v::FeynmanVertex) = print(io, "$(v.in1) + $(v.in2) -> $(v.out)")
|
||||
|
||||
"""
|
||||
show(io::IO, particle::FeynmanTie)
|
||||
|
||||
Pretty print a [`FeynmanTie`](@ref) (no newlines).
|
||||
"""
|
||||
show(io::IO, t::FeynmanTie) = print(io, "$(t.in1) -- $(t.in2)")
|
||||
|
||||
"""
|
||||
show(io::IO, particle::FeynmanDiagram)
|
||||
|
||||
Pretty print a [`FeynmanDiagram`](@ref) (with newlines).
|
||||
"""
|
||||
function show(io::IO, d::FeynmanDiagram)
|
||||
print(io, "Initial Particles: [")
|
||||
first = true
|
||||
for p in d.particles
|
||||
if first
|
||||
first = false
|
||||
print(io, "$p")
|
||||
else
|
||||
print(io, ", $p")
|
||||
end
|
||||
end
|
||||
print(io, "]\n")
|
||||
for l in eachindex(d.vertices)
|
||||
print(io, " Virtuality Level $l Vertices: [")
|
||||
first = true
|
||||
for v in d.vertices[l]
|
||||
if first
|
||||
first = false
|
||||
print(io, "$v")
|
||||
else
|
||||
print(io, ", $v")
|
||||
end
|
||||
end
|
||||
print(io, "]\n")
|
||||
end
|
||||
return print(io, " Tie: $(d.tie[])\n")
|
||||
end
|
135
src/models/qed/properties.jl
Normal file
135
src/models/qed/properties.jl
Normal file
@ -0,0 +1,135 @@
|
||||
# TODO use correct numbers
|
||||
|
||||
"""
|
||||
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_S2)
|
||||
|
||||
Return the compute effort of an S2 task.
|
||||
"""
|
||||
compute_effort(t::ComputeTaskQED_S2)::Float64 = 12.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_V)
|
||||
|
||||
Return the compute effort of a V task.
|
||||
"""
|
||||
compute_effort(t::ComputeTaskQED_V)::Float64 = 6.0
|
||||
|
||||
"""
|
||||
compute_effort(t::ComputeTaskQED_P)
|
||||
|
||||
Return the compute effort of a P task.
|
||||
"""
|
||||
compute_effort(t::ComputeTaskQED_P)::Float64 = 0.0
|
||||
|
||||
"""
|
||||
compute_effort(t::ComputeTaskQED_Sum)
|
||||
|
||||
Return the compute effort of a Sum task.
|
||||
|
||||
Note: This is a constant compute effort, even though sum scales with the number of its inputs. Since there is only ever a single sum node in a graph generated from the QED-Model,
|
||||
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)
|
||||
|
||||
Return the number of children of a ComputeTaskQED_S1 (always 1).
|
||||
"""
|
||||
children(::ComputeTaskQED_S1) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskQED_S2)
|
||||
|
||||
Return the number of children of a ComputeTaskQED_S2 (always 2).
|
||||
"""
|
||||
children(::ComputeTaskQED_S2) = 2
|
||||
|
||||
"""
|
||||
children(::ComputeTaskQED_P)
|
||||
|
||||
Return the number of children of a ComputeTaskQED_P (always 1).
|
||||
"""
|
||||
children(::ComputeTaskQED_P) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskQED_U)
|
||||
|
||||
Return the number of children of a ComputeTaskQED_U (always 1).
|
||||
"""
|
||||
children(::ComputeTaskQED_U) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskQED_V)
|
||||
|
||||
Return the number of children of a ComputeTaskQED_V (always 2).
|
||||
"""
|
||||
children(::ComputeTaskQED_V) = 2
|
||||
|
||||
"""
|
||||
children(::ComputeTaskQED_Sum)
|
||||
|
||||
Return the number of children of a ComputeTaskQED_Sum.
|
||||
"""
|
||||
children(t::ComputeTaskQED_Sum) = t.children_number
|
||||
|
||||
function add_child!(t::ComputeTaskQED_Sum)
|
||||
t.children_number += 1
|
||||
return nothing
|
||||
end
|
51
src/models/qed/types.jl
Normal file
51
src/models/qed/types.jl
Normal file
@ -0,0 +1,51 @@
|
||||
"""
|
||||
ComputeTaskQED_S1 <: AbstractComputeTask
|
||||
|
||||
S task with a single child.
|
||||
"""
|
||||
struct ComputeTaskQED_S1 <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_S2 <: AbstractComputeTask
|
||||
|
||||
S task with two children.
|
||||
"""
|
||||
struct ComputeTaskQED_S2 <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_P <: AbstractComputeTask
|
||||
|
||||
P task with no children.
|
||||
"""
|
||||
struct ComputeTaskQED_P <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_V <: AbstractComputeTask
|
||||
|
||||
v task with two children.
|
||||
"""
|
||||
struct ComputeTaskQED_V <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_U <: AbstractComputeTask
|
||||
|
||||
u task with a single child.
|
||||
"""
|
||||
struct ComputeTaskQED_U <: AbstractComputeTask end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_Sum <: AbstractComputeTask
|
||||
|
||||
Task that sums all its inputs, n children.
|
||||
"""
|
||||
mutable struct ComputeTaskQED_Sum <: AbstractComputeTask
|
||||
children_number::Int
|
||||
end
|
||||
|
||||
"""
|
||||
QED_TASKS
|
||||
|
||||
Constant vector of all tasks of the QED-Model.
|
||||
"""
|
||||
QED_TASKS =
|
||||
[ComputeTaskQED_S1, ComputeTaskQED_S2, ComputeTaskQED_P, ComputeTaskQED_V, ComputeTaskQED_U, ComputeTaskQED_Sum]
|
@ -21,7 +21,7 @@ end
|
||||
|
||||
Equality comparison between two [`ComputeTaskNode`](@ref)s.
|
||||
"""
|
||||
function ==(n1::ComputeTaskNode, n2::ComputeTaskNode)
|
||||
function ==(n1::ComputeTaskNode{TaskType}, n2::ComputeTaskNode{TaskType}) where {TaskType <: AbstractComputeTask}
|
||||
return n1.id == n2.id
|
||||
end
|
||||
|
||||
@ -30,6 +30,6 @@ end
|
||||
|
||||
Equality comparison between two [`DataTaskNode`](@ref)s.
|
||||
"""
|
||||
function ==(n1::DataTaskNode, n2::DataTaskNode)
|
||||
function ==(n1::DataTaskNode{TaskType}, n2::DataTaskNode{TaskType}) where {TaskType <: AbstractDataTask}
|
||||
return n1.id == n2.id
|
||||
end
|
||||
|
@ -13,8 +13,8 @@ ComputeTaskNode(t::AbstractComputeTask) = ComputeTaskNode(
|
||||
)
|
||||
|
||||
copy(m::Missing) = missing
|
||||
copy(n::ComputeTaskNode) = ComputeTaskNode(copy(n.task))
|
||||
copy(n::DataTaskNode) = DataTaskNode(copy(n.task), n.name)
|
||||
copy(n::ComputeTaskNode) = ComputeTaskNode(copy(task(n)))
|
||||
copy(n::DataTaskNode) = DataTaskNode(copy(task(n)), n.name)
|
||||
|
||||
"""
|
||||
make_node(t::AbstractTask)
|
||||
|
@ -4,7 +4,7 @@
|
||||
Print a short string representation of the node to io.
|
||||
"""
|
||||
function show(io::IO, n::Node)
|
||||
return print(io, "Node(", n.task, ")")
|
||||
return print(io, "Node(", task(n), ")")
|
||||
end
|
||||
|
||||
"""
|
||||
|
@ -3,25 +3,27 @@
|
||||
|
||||
Return whether this node is an entry node in its graph, i.e., it has no children.
|
||||
"""
|
||||
is_entry_node(node::Node) = length(node.children) == 0
|
||||
is_entry_node(node::Node) = length(children(node)) == 0
|
||||
|
||||
"""
|
||||
is_exit_node(node::Node)
|
||||
|
||||
Return whether this node is an exit node of its graph, i.e., it has no parents.
|
||||
"""
|
||||
is_exit_node(node::Node) = length(node.parents) == 0
|
||||
is_exit_node(node::Node)::Bool = length(parents(node)) == 0
|
||||
|
||||
"""
|
||||
data(edge::Edge)
|
||||
task(node::Node)
|
||||
|
||||
Return the data transfered by this edge, i.e., 0 if the child is a [`ComputeTaskNode`](@ref), otherwise the child's `data()`.
|
||||
Return the node's task.
|
||||
"""
|
||||
function data(edge::Edge)
|
||||
if typeof(edge.edge[1]) <: DataTaskNode
|
||||
return data(edge.edge[1].task)
|
||||
end
|
||||
return 0.0
|
||||
function task(node::DataTaskNode{TaskType})::TaskType where {TaskType <: Union{AbstractDataTask, AbstractComputeTask}}
|
||||
return node.task
|
||||
end
|
||||
function task(
|
||||
node::ComputeTaskNode{TaskType},
|
||||
)::TaskType where {TaskType <: Union{AbstractDataTask, AbstractComputeTask}}
|
||||
return node.task
|
||||
end
|
||||
|
||||
"""
|
||||
@ -31,8 +33,11 @@ Return a copy of the node's children so it can safely be muted without changing
|
||||
|
||||
A node's children are its prerequisite nodes, nodes that need to execute before the task of this node.
|
||||
"""
|
||||
function children(node::Node)
|
||||
return copy(node.children)
|
||||
function children(node::DataTaskNode)::Vector{ComputeTaskNode}
|
||||
return node.children
|
||||
end
|
||||
function children(node::ComputeTaskNode)::Vector{DataTaskNode}
|
||||
return node.children
|
||||
end
|
||||
|
||||
"""
|
||||
@ -42,8 +47,11 @@ Return a copy of the node's parents so it can safely be muted without changing t
|
||||
|
||||
A node's parents are its subsequent nodes, nodes that need this node to execute.
|
||||
"""
|
||||
function parents(node::Node)
|
||||
return copy(node.parents)
|
||||
function parents(node::DataTaskNode)::Vector{ComputeTaskNode}
|
||||
return node.parents
|
||||
end
|
||||
function parents(node::ComputeTaskNode)::Vector{DataTaskNode}
|
||||
return node.parents
|
||||
end
|
||||
|
||||
"""
|
||||
@ -53,11 +61,11 @@ 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.
|
||||
"""
|
||||
function siblings(node::Node)
|
||||
function siblings(node::Node)::Set{Node}
|
||||
result = Set{Node}()
|
||||
push!(result, node)
|
||||
for parent in node.parents
|
||||
union!(result, parent.children)
|
||||
for parent in parents(node)
|
||||
union!(result, children(parent))
|
||||
end
|
||||
|
||||
return result
|
||||
@ -73,11 +81,11 @@ A node's partners are all parents of any of its children. The result contains no
|
||||
Note: This is very slow when there are multiple children with many parents.
|
||||
This is less of a problem in [`siblings(node::Node)`](@ref) because (depending on the model) there are no nodes with a large number of children, or only a single one.
|
||||
"""
|
||||
function partners(node::Node)
|
||||
function partners(node::Node)::Set{Node}
|
||||
result = Set{Node}()
|
||||
push!(result, node)
|
||||
for child in node.children
|
||||
union!(result, child.parents)
|
||||
for child in children(node)
|
||||
union!(result, parents(child))
|
||||
end
|
||||
|
||||
return result
|
||||
@ -90,8 +98,8 @@ Alternative version to [`partners(node::Node)`](@ref), avoiding allocation of a
|
||||
"""
|
||||
function partners(node::Node, set::Set{Node})
|
||||
push!(set, node)
|
||||
for child in node.children
|
||||
union!(set, child.parents)
|
||||
for child in children(node)
|
||||
union!(set, parents(child))
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
@ -101,8 +109,8 @@ end
|
||||
|
||||
Return whether the `potential_parent` is a parent of `node`.
|
||||
"""
|
||||
function is_parent(potential_parent::Node, node::Node)
|
||||
return potential_parent in node.parents
|
||||
function is_parent(potential_parent::Node, node::Node)::Bool
|
||||
return potential_parent in parents(node)
|
||||
end
|
||||
|
||||
"""
|
||||
@ -110,6 +118,6 @@ end
|
||||
|
||||
Return whether the `potential_child` is a child of `node`.
|
||||
"""
|
||||
function is_child(potential_child::Node, node::Node)
|
||||
return potential_child in node.children
|
||||
function is_child(potential_child::Node, node::Node)::Bool
|
||||
return potential_child in children(node)
|
||||
end
|
||||
|
@ -33,8 +33,8 @@ Any node that transfers data and does no computation.
|
||||
`.nodeFusion`: Either this node's [`NodeFusion`](@ref) or `missing`, if none. There can only be at most one for DataTaskNodes.\\
|
||||
`.name`: The name of this node for entry nodes into the graph ([`is_entry_node`](@ref)) to reliably assign the inputs to the correct nodes when executing.\\
|
||||
"""
|
||||
mutable struct DataTaskNode <: Node
|
||||
task::AbstractDataTask
|
||||
mutable struct DataTaskNode{TaskType <: AbstractDataTask} <: Node
|
||||
task::TaskType
|
||||
|
||||
# use vectors as sets have way too much memory overhead
|
||||
parents::Vector{Node}
|
||||
@ -73,8 +73,8 @@ Any node that computes a result from inputs using an [`AbstractComputeTask`](@re
|
||||
`.nodeFusions`: A vector of this node's [`NodeFusion`](@ref)s. For a `ComputeTaskNode` there can be any number of these, unlike the [`DataTaskNode`](@ref)s.\\
|
||||
`.device`: The Device this node has been scheduled on by a [`Scheduler`](@ref).
|
||||
"""
|
||||
mutable struct ComputeTaskNode <: Node
|
||||
task::AbstractComputeTask
|
||||
mutable struct ComputeTaskNode{TaskType <: AbstractComputeTask} <: Node
|
||||
task::TaskType
|
||||
parents::Vector{Node}
|
||||
children::Vector{Node}
|
||||
id::Base.UUID
|
||||
@ -83,7 +83,7 @@ mutable struct ComputeTaskNode <: Node
|
||||
nodeSplit::Union{Operation, Missing}
|
||||
|
||||
# for ComputeTasks there can be multiple fusions, unlike the DataTasks
|
||||
nodeFusions::Vector{Operation}
|
||||
nodeFusions::Vector{<:Operation}
|
||||
|
||||
# the device this node is assigned to execute on
|
||||
device::Union{AbstractDevice, Missing}
|
||||
|
@ -29,7 +29,7 @@ function is_valid_node(graph::DAG, node::Node)
|
||||
@assert is_valid(graph, node.nodeSplit)
|
||||
end=#
|
||||
|
||||
if !(typeof(node.task) <: FusedComputeTask)
|
||||
if !(typeof(task(node)) <: FusedComputeTask)
|
||||
# the remaining checks are only necessary for fused compute tasks
|
||||
return true
|
||||
end
|
||||
@ -37,7 +37,7 @@ function is_valid_node(graph::DAG, node::Node)
|
||||
# every child must be in some input of the task
|
||||
for child in node.children
|
||||
str = Symbol(to_var_name(child.id))
|
||||
@assert (str in node.task.t1_inputs) || (str in node.task.t2_inputs) "$str was not in any of the tasks' inputs\nt1_inputs: $(node.task.t1_inputs)\nt2_inputs: $(node.task.t2_inputs)"
|
||||
@assert (str in task(node).t1_inputs) || (str in task(node).t2_inputs) "$str was not in any of the tasks' inputs\nt1_inputs: $(task(node).t1_inputs)\nt2_inputs: $(task(node).t2_inputs)"
|
||||
end
|
||||
|
||||
return true
|
||||
|
@ -132,11 +132,11 @@ function revert_diff!(graph::DAG, diff::Diff)
|
||||
insert_edge!(graph, edge.edge[1], edge.edge[2], track = false)
|
||||
end
|
||||
|
||||
for (node, task) in diff.updatedChildren
|
||||
for (node, t) in diff.updatedChildren
|
||||
# node must be fused compute task at this point
|
||||
@assert typeof(node.task) <: FusedComputeTask
|
||||
@assert typeof(task(node)) <: FusedComputeTask
|
||||
|
||||
node.task = task
|
||||
node.task = t
|
||||
end
|
||||
|
||||
graph.properties -= GraphProperties(diff)
|
||||
@ -158,11 +158,11 @@ function node_fusion!(graph::DAG, n1::ComputeTaskNode, n2::DataTaskNode, n3::Com
|
||||
get_snapshot_diff(graph)
|
||||
|
||||
# save children and parents
|
||||
n1Children = children(n1)
|
||||
n3Parents = parents(n3)
|
||||
n1Children = copy(children(n1))
|
||||
n3Parents = copy(parents(n3))
|
||||
|
||||
n1Task = copy(n1.task)
|
||||
n3Task = copy(n3.task)
|
||||
n1Task = copy(task(n1))
|
||||
n3Task = copy(task(n3))
|
||||
|
||||
# assemble the input node vectors of n1 and n3 to save into the FusedComputeTask
|
||||
n1Inputs = Vector{Symbol}()
|
||||
@ -177,7 +177,7 @@ function node_fusion!(graph::DAG, n1::ComputeTaskNode, n2::DataTaskNode, n3::Com
|
||||
remove_node!(graph, n2)
|
||||
|
||||
# get n3's children now so it automatically excludes n2
|
||||
n3Children = children(n3)
|
||||
n3Children = copy(children(n3))
|
||||
|
||||
n3Inputs = Vector{Symbol}()
|
||||
for child in n3Children
|
||||
@ -228,7 +228,7 @@ function node_reduction!(graph::DAG, nodes::Vector{Node})
|
||||
get_snapshot_diff(graph)
|
||||
|
||||
n1 = nodes[1]
|
||||
n1Children = children(n1)
|
||||
n1Children = copy(children(n1))
|
||||
|
||||
n1Parents = Set(n1.parents)
|
||||
|
||||
@ -245,7 +245,7 @@ function node_reduction!(graph::DAG, nodes::Vector{Node})
|
||||
remove_edge!(graph, child, n)
|
||||
end
|
||||
|
||||
for parent in parents(n)
|
||||
for parent in copy(parents(n))
|
||||
remove_edge!(graph, n, parent)
|
||||
|
||||
# collect all parents
|
||||
@ -278,14 +278,17 @@ Split the given node into one node per parent, return the applied difference to
|
||||
|
||||
For details see [`NodeSplit`](@ref).
|
||||
"""
|
||||
function node_split!(graph::DAG, n1::Node)
|
||||
function node_split!(
|
||||
graph::DAG,
|
||||
n1::Union{DataTaskNode{TaskType}, ComputeTaskNode{TaskType}},
|
||||
) where {TaskType <: AbstractTask}
|
||||
@assert is_valid_node_split_input(graph, n1)
|
||||
|
||||
# clear snapshot
|
||||
get_snapshot_diff(graph)
|
||||
|
||||
n1Parents = parents(n1)
|
||||
n1Children = children(n1)
|
||||
n1Parents = copy(parents(n1))
|
||||
n1Children = copy(children(n1))
|
||||
|
||||
for parent in n1Parents
|
||||
remove_edge!(graph, n1, parent)
|
||||
|
@ -13,18 +13,18 @@ function find_fusions!(graph::DAG, node::DataTaskNode)
|
||||
return nothing
|
||||
end
|
||||
|
||||
if length(node.parents) != 1 || length(node.children) != 1
|
||||
if length(parents(node)) != 1 || length(children(node)) != 1
|
||||
return nothing
|
||||
end
|
||||
|
||||
child_node = first(node.children)
|
||||
parent_node = first(node.parents)
|
||||
child_node = first(children(node))
|
||||
parent_node = first(parents(node))
|
||||
|
||||
if !(child_node in graph) || !(parent_node in graph)
|
||||
error("Parents/Children that are not in the graph!!!")
|
||||
end
|
||||
|
||||
if length(child_node.parents) != 1
|
||||
if length(parents(child_node)) != 1
|
||||
return nothing
|
||||
end
|
||||
|
||||
@ -44,11 +44,11 @@ Find node fusions involving the given compute node. The function pushes the foun
|
||||
"""
|
||||
function find_fusions!(graph::DAG, node::ComputeTaskNode)
|
||||
# just find fusions in neighbouring DataTaskNodes
|
||||
for child in node.children
|
||||
for child in children(node)
|
||||
find_fusions!(graph, child)
|
||||
end
|
||||
|
||||
for parent in node.parents
|
||||
for parent in parents(node)
|
||||
find_fusions!(graph, parent)
|
||||
end
|
||||
|
||||
@ -123,7 +123,10 @@ end
|
||||
|
||||
Sort this node's parent and child sets, then find fusions, reductions and splits involving it. Needs to be called after the node was changed in some way.
|
||||
"""
|
||||
function clean_node!(graph::DAG, node::Node)
|
||||
function clean_node!(
|
||||
graph::DAG,
|
||||
node::Union{DataTaskNode{TaskType}, ComputeTaskNode{TaskType}},
|
||||
) where {TaskType <: AbstractTask}
|
||||
sort_node!(node)
|
||||
|
||||
find_fusions!(graph, node)
|
||||
|
@ -203,18 +203,18 @@ function generate_operations(graph::DAG)
|
||||
# --- find possible node fusions ---
|
||||
@threads for node in nodeArray
|
||||
if (typeof(node) <: DataTaskNode)
|
||||
if length(node.parents) != 1
|
||||
if length(parents(node)) != 1
|
||||
# data node can only have a single parent
|
||||
continue
|
||||
end
|
||||
parent_node = first(node.parents)
|
||||
parent_node = first(parents(node))
|
||||
|
||||
if length(node.children) != 1
|
||||
if length(children(node)) != 1
|
||||
# this node is an entry node or has multiple children which should not be possible
|
||||
continue
|
||||
end
|
||||
child_node = first(node.children)
|
||||
if (length(child_node.parents) != 1)
|
||||
child_node = first(children(node))
|
||||
if (length(parents(child_node)) != 1)
|
||||
continue
|
||||
end
|
||||
|
||||
|
@ -14,9 +14,7 @@ function get_operations(graph::DAG)
|
||||
generate_operations(graph)
|
||||
end
|
||||
|
||||
for node in graph.dirtyNodes
|
||||
clean_node!(graph, node)
|
||||
end
|
||||
clean_node!.(Ref(graph), graph.dirtyNodes)
|
||||
empty!(graph.dirtyNodes)
|
||||
|
||||
return graph.possibleOperations
|
||||
|
39
src/operation/iterate.jl
Normal file
39
src/operation/iterate.jl
Normal file
@ -0,0 +1,39 @@
|
||||
import Base.iterate
|
||||
|
||||
const _POSSIBLE_OPERATIONS_FIELDS = fieldnames(PossibleOperations)
|
||||
|
||||
_POIteratorStateType =
|
||||
NamedTuple{(:result, :state), Tuple{Union{NodeFusion, NodeReduction, NodeSplit}, Tuple{Symbol, Int64}}}
|
||||
|
||||
@inline function iterate(possibleOperations::PossibleOperations)::Union{Nothing, _POIteratorStateType}
|
||||
for fieldname in _POSSIBLE_OPERATIONS_FIELDS
|
||||
iterator = iterate(getfield(possibleOperations, fieldname))
|
||||
if (!isnothing(iterator))
|
||||
return (result = iterator[1], state = (fieldname, iterator[2]))
|
||||
end
|
||||
end
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
@inline function iterate(possibleOperations::PossibleOperations, state)::Union{Nothing, _POIteratorStateType}
|
||||
newStateSym = state[1]
|
||||
newStateIt = iterate(getfield(possibleOperations, newStateSym), state[2])
|
||||
if !isnothing(newStateIt)
|
||||
return (result = newStateIt[1], state = (newStateSym, newStateIt[2]))
|
||||
end
|
||||
|
||||
# cycle to next field
|
||||
index = findfirst(x -> x == newStateSym, _POSSIBLE_OPERATIONS_FIELDS) + 1
|
||||
|
||||
while index <= length(_POSSIBLE_OPERATIONS_FIELDS)
|
||||
newStateSym = _POSSIBLE_OPERATIONS_FIELDS[index]
|
||||
newStateIt = iterate(getfield(possibleOperations, newStateSym))
|
||||
if !isnothing(newStateIt)
|
||||
return (result = newStateIt[1], state = (newStateSym, newStateIt[2]))
|
||||
end
|
||||
index += 1
|
||||
end
|
||||
|
||||
return nothing
|
||||
end
|
@ -30,7 +30,7 @@ function show(io::IO, op::NodeReduction)
|
||||
print(io, "NR: ")
|
||||
print(io, length(op.input))
|
||||
print(io, "x")
|
||||
return print(io, op.input[1].task)
|
||||
return print(io, task(op.input[1]))
|
||||
end
|
||||
|
||||
"""
|
||||
@ -40,7 +40,7 @@ Print a string representation of the node split to io.
|
||||
"""
|
||||
function show(io::IO, op::NodeSplit)
|
||||
print(io, "NS: ")
|
||||
return print(io, op.input.task)
|
||||
return print(io, task(op.input))
|
||||
end
|
||||
|
||||
"""
|
||||
@ -50,9 +50,9 @@ Print a string representation of the node fusion to io.
|
||||
"""
|
||||
function show(io::IO, op::NodeFusion)
|
||||
print(io, "NF: ")
|
||||
print(io, op.input[1].task)
|
||||
print(io, task(op.input[1]))
|
||||
print(io, "->")
|
||||
print(io, op.input[2].task)
|
||||
print(io, task(op.input[2]))
|
||||
print(io, "->")
|
||||
return print(io, op.input[3].task)
|
||||
return print(io, task(op.input[3]))
|
||||
end
|
||||
|
@ -40,8 +40,9 @@ A chain of (n1, n2, n3) can be fused if:
|
||||
|
||||
See also: [`can_fuse`](@ref)
|
||||
"""
|
||||
struct NodeFusion <: Operation
|
||||
input::Tuple{ComputeTaskNode, DataTaskNode, ComputeTaskNode}
|
||||
struct NodeFusion{TaskType1 <: AbstractComputeTask, TaskType2 <: AbstractDataTask, TaskType3 <: AbstractComputeTask} <:
|
||||
Operation
|
||||
input::Tuple{ComputeTaskNode{TaskType1}, DataTaskNode{TaskType2}, ComputeTaskNode{TaskType3}}
|
||||
end
|
||||
|
||||
"""
|
||||
@ -49,8 +50,12 @@ end
|
||||
|
||||
The applied version of the [`NodeFusion`](@ref).
|
||||
"""
|
||||
struct AppliedNodeFusion <: AppliedOperation
|
||||
operation::NodeFusion
|
||||
struct AppliedNodeFusion{
|
||||
TaskType1 <: AbstractComputeTask,
|
||||
TaskType2 <: AbstractDataTask,
|
||||
TaskType3 <: AbstractComputeTask,
|
||||
} <: AppliedOperation
|
||||
operation::NodeFusion{TaskType1, TaskType2, TaskType3}
|
||||
diff::Diff
|
||||
end
|
||||
|
||||
@ -73,8 +78,8 @@ A vector of nodes can be reduced if:
|
||||
|
||||
See also: [`can_reduce`](@ref)
|
||||
"""
|
||||
struct NodeReduction <: Operation
|
||||
input::Vector{Node}
|
||||
struct NodeReduction{NodeType <: Node} <: Operation
|
||||
input::Vector{NodeType}
|
||||
end
|
||||
|
||||
"""
|
||||
@ -82,8 +87,8 @@ end
|
||||
|
||||
The applied version of the [`NodeReduction`](@ref).
|
||||
"""
|
||||
struct AppliedNodeReduction <: AppliedOperation
|
||||
operation::NodeReduction
|
||||
struct AppliedNodeReduction{NodeType <: Node} <: AppliedOperation
|
||||
operation::NodeReduction{NodeType}
|
||||
diff::Diff
|
||||
end
|
||||
|
||||
@ -102,8 +107,8 @@ A node can be split if:
|
||||
|
||||
See also: [`can_split`](@ref)
|
||||
"""
|
||||
struct NodeSplit <: Operation
|
||||
input::Node
|
||||
struct NodeSplit{NodeType <: Node} <: Operation
|
||||
input::NodeType
|
||||
end
|
||||
|
||||
"""
|
||||
@ -111,7 +116,7 @@ end
|
||||
|
||||
The applied version of the [`NodeSplit`](@ref).
|
||||
"""
|
||||
struct AppliedNodeSplit <: AppliedOperation
|
||||
operation::NodeSplit
|
||||
struct AppliedNodeSplit{NodeType <: Node} <: AppliedOperation
|
||||
operation::NodeSplit{NodeType}
|
||||
diff::Diff
|
||||
end
|
||||
|
@ -61,7 +61,7 @@ function can_fuse(n1::ComputeTaskNode, n2::DataTaskNode, n3::ComputeTaskNode)
|
||||
return false
|
||||
end
|
||||
|
||||
if length(n2.parents) != 1 || length(n2.children) != 1 || length(n1.parents) != 1
|
||||
if length(parents(n2)) != 1 || length(children(n2)) != 1 || length(parents(n1)) != 1
|
||||
return false
|
||||
end
|
||||
|
||||
@ -74,12 +74,15 @@ end
|
||||
Return whether the given two nodes can be reduced. See [`NodeReduction`](@ref) for the requirements.
|
||||
"""
|
||||
function can_reduce(n1::Node, n2::Node)
|
||||
if (n1.task != n2.task)
|
||||
return false
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
n1_length = length(n1.children)
|
||||
n2_length = length(n2.children)
|
||||
function can_reduce(
|
||||
n1::NodeType,
|
||||
n2::NodeType,
|
||||
) where {TaskType <: AbstractTask, NodeType <: Union{DataTaskNode{TaskType}, ComputeTaskNode{TaskType}}}
|
||||
n1_length = length(children(n1))
|
||||
n2_length = length(children(n2))
|
||||
|
||||
if (n1_length != n2_length)
|
||||
return false
|
||||
@ -88,19 +91,19 @@ function can_reduce(n1::Node, n2::Node)
|
||||
# this seems to be the most common case so do this first
|
||||
# doing it manually is a lot faster than using the sets for a general solution
|
||||
if (n1_length == 2)
|
||||
if (n1.children[1] != n2.children[1])
|
||||
if (n1.children[1] != n2.children[2])
|
||||
if (children(n1)[1] != children(n2)[1])
|
||||
if (children(n1)[1] != children(n2)[2])
|
||||
return false
|
||||
end
|
||||
# 1_1 == 2_2
|
||||
if (n1.children[2] != n2.children[1])
|
||||
if (children(n1)[2] != children(n2)[1])
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
# 1_1 == 2_1
|
||||
if (n1.children[2] != n2.children[2])
|
||||
if (children(n1)[2] != children(n2)[2])
|
||||
return false
|
||||
end
|
||||
return true
|
||||
@ -108,11 +111,11 @@ function can_reduce(n1::Node, n2::Node)
|
||||
|
||||
# this is simple
|
||||
if (n1_length == 1)
|
||||
return n1.children[1] == n2.children[1]
|
||||
return children(n1)[1] == children(n2)[1]
|
||||
end
|
||||
|
||||
# this takes a long time
|
||||
return Set(n1.children) == Set(n2.children)
|
||||
return Set(children(n1)) == Set(children(n2))
|
||||
end
|
||||
|
||||
"""
|
||||
@ -138,7 +141,14 @@ end
|
||||
|
||||
Equality comparison between two node fusions. Two node fusions are considered equal if they have the same inputs.
|
||||
"""
|
||||
function ==(op1::NodeFusion, op2::NodeFusion)
|
||||
function ==(
|
||||
op1::NodeFusion{ComputeTaskType1, DataTaskType, ComputeTaskType2},
|
||||
op2::NodeFusion{ComputeTaskType1, DataTaskType, ComputeTaskType2},
|
||||
) where {
|
||||
ComputeTaskType1 <: AbstractComputeTask,
|
||||
DataTaskType <: AbstractDataTask,
|
||||
ComputeTaskType2 <: AbstractComputeTask,
|
||||
}
|
||||
# there can only be one node fusion on a given data task, so if the data task is the same, the fusion is the same
|
||||
return op1.input[2] == op2.input[2]
|
||||
end
|
||||
|
@ -54,9 +54,9 @@ function is_valid_node_reduction_input(graph::DAG, nodes::Vector{Node})
|
||||
@assert is_valid(graph, n)
|
||||
end
|
||||
|
||||
t = typeof(nodes[1].task)
|
||||
t = typeof(task(nodes[1]))
|
||||
for n in nodes
|
||||
if typeof(n.task) != t
|
||||
if typeof(task(n)) != t
|
||||
throw(AssertionError("[Node Reduction] The given nodes are not of the same type"))
|
||||
end
|
||||
|
||||
@ -115,7 +115,7 @@ Intended for use with `@assert` or `@test`.
|
||||
"""
|
||||
function is_valid(graph::DAG, nr::NodeReduction)
|
||||
@assert is_valid_node_reduction_input(graph, nr.input)
|
||||
@assert nr in graph.possibleOperations.nodeReductions "NodeReduction is not part of the graph's possible operations!"
|
||||
#@assert nr in graph.possibleOperations.nodeReductions "NodeReduction is not part of the graph's possible operations!"
|
||||
return true
|
||||
end
|
||||
|
||||
@ -128,7 +128,7 @@ Intended for use with `@assert` or `@test`.
|
||||
"""
|
||||
function is_valid(graph::DAG, ns::NodeSplit)
|
||||
@assert is_valid_node_split_input(graph, ns.input)
|
||||
@assert ns in graph.possibleOperations.nodeSplits "NodeSplit is not part of the graph's possible operations!"
|
||||
#@assert ns in graph.possibleOperations.nodeSplits "NodeSplit is not part of the graph's possible operations!"
|
||||
return true
|
||||
end
|
||||
|
||||
@ -141,6 +141,6 @@ Intended for use with `@assert` or `@test`.
|
||||
"""
|
||||
function is_valid(graph::DAG, nf::NodeFusion)
|
||||
@assert is_valid_node_fusion_input(graph, nf.input[1], nf.input[2], nf.input[3])
|
||||
@assert nf in graph.possibleOperations.nodeFusions "NodeFusion is not part of the graph's possible operations!"
|
||||
#@assert nf in graph.possibleOperations.nodeFusions "NodeFusion is not part of the graph's possible operations!"
|
||||
return true
|
||||
end
|
||||
|
73
src/optimization/greedy.jl
Normal file
73
src/optimization/greedy.jl
Normal file
@ -0,0 +1,73 @@
|
||||
"""
|
||||
GreedyOptimizer
|
||||
|
||||
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.
|
||||
"""
|
||||
struct GreedyOptimizer{EstimatorType <: AbstractEstimator} <: AbstractOptimizer
|
||||
estimator::EstimatorType
|
||||
end
|
||||
|
||||
function optimize_step!(optimizer::GreedyOptimizer, graph::DAG)
|
||||
# generate all options
|
||||
operations = get_operations(graph)
|
||||
if isempty(operations)
|
||||
return false
|
||||
end
|
||||
|
||||
result = nothing
|
||||
|
||||
lowestCost = reduce(
|
||||
(acc, op) -> begin
|
||||
op_cost = operation_effect(optimizer.estimator, graph, op)
|
||||
if op_cost < acc
|
||||
result = op
|
||||
return op_cost
|
||||
end
|
||||
return acc
|
||||
end,
|
||||
operations;
|
||||
init = typemax(cost_type(optimizer.estimator)),
|
||||
)
|
||||
|
||||
if lowestCost > zero(cost_type(optimizer.estimator))
|
||||
return false
|
||||
end
|
||||
|
||||
push_operation!(graph, result)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function fixpoint_reached(optimizer::GreedyOptimizer, graph::DAG)
|
||||
# generate all options
|
||||
operations = get_operations(graph)
|
||||
if isempty(operations)
|
||||
return true
|
||||
end
|
||||
|
||||
lowestCost = reduce(
|
||||
(acc, op) -> begin
|
||||
op_cost = operation_effect(optimizer.estimator, graph, op)
|
||||
if op_cost < acc
|
||||
return op_cost
|
||||
end
|
||||
return acc
|
||||
end,
|
||||
operations;
|
||||
init = typemax(cost_type(optimizer.estimator)),
|
||||
)
|
||||
|
||||
if lowestCost > zero(cost_type(optimizer.estimator))
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function optimize_to_fixpoint!(optimizer::GreedyOptimizer, graph::DAG)
|
||||
while optimize_step!(optimizer, graph)
|
||||
end
|
||||
return nothing
|
||||
end
|
60
src/optimization/interface.jl
Normal file
60
src/optimization/interface.jl
Normal file
@ -0,0 +1,60 @@
|
||||
|
||||
"""
|
||||
AbstractOptimizer
|
||||
|
||||
Abstract base type for optimizer implementations.
|
||||
"""
|
||||
abstract type AbstractOptimizer end
|
||||
|
||||
"""
|
||||
optimize_step!(optimizer::AbstractOptimizer, graph::DAG)
|
||||
|
||||
Interface function that must be implemented by implementations of [`AbstractOptimizer`](@ref). 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`](@ref), muting the graph and, if necessary, the optimizer's state.
|
||||
"""
|
||||
function optimize_step! end
|
||||
|
||||
"""
|
||||
optimize!(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.
|
||||
"""
|
||||
function optimize!(optimizer::AbstractOptimizer, graph::DAG, n::Int)
|
||||
for i in 1:n
|
||||
if !optimize_step!(optimizer, graph)
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
"""
|
||||
fixpoint_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!`](@ref)
|
||||
"""
|
||||
function fixpoint_reached(optimizer::AbstractOptimizer, graph::DAG)
|
||||
return false
|
||||
end
|
||||
|
||||
"""
|
||||
optimize_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`](@ref) should return true.
|
||||
|
||||
A usual implementation might look like this:
|
||||
```julia
|
||||
function optimize_to_fixpoint!(optimizer::MyOptimizer, graph::DAG)
|
||||
while !fixpoint_reached(optimizer, graph)
|
||||
optimize_step!(optimizer, graph)
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
```
|
||||
"""
|
||||
function optimize_to_fixpoint! end
|
49
src/optimization/random_walk.jl
Normal file
49
src/optimization/random_walk.jl
Normal file
@ -0,0 +1,49 @@
|
||||
using Random
|
||||
|
||||
"""
|
||||
RandomWalkOptimizer
|
||||
|
||||
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`](@ref).
|
||||
"""
|
||||
struct RandomWalkOptimizer <: AbstractOptimizer
|
||||
rng::AbstractRNG
|
||||
end
|
||||
|
||||
function optimize_step!(optimizer::RandomWalkOptimizer, graph::DAG)
|
||||
operations = get_operations(graph)
|
||||
|
||||
if sum(length(operations)) == 0 && length(graph.appliedOperations) + length(graph.operationsToApply) == 0
|
||||
# in case there are zero operations possible at all on the graph
|
||||
return false
|
||||
end
|
||||
|
||||
r = optimizer.rng
|
||||
# try until something was applied or popped
|
||||
while true
|
||||
# choose push or pop
|
||||
if rand(r, Bool)
|
||||
# push
|
||||
|
||||
# choose one of fuse/split/reduce
|
||||
option = rand(r, 1:3)
|
||||
if option == 1 && !isempty(operations.nodeFusions)
|
||||
push_operation!(graph, rand(r, collect(operations.nodeFusions)))
|
||||
return true
|
||||
elseif option == 2 && !isempty(operations.nodeReductions)
|
||||
push_operation!(graph, rand(r, collect(operations.nodeReductions)))
|
||||
return true
|
||||
elseif option == 3 && !isempty(operations.nodeSplits)
|
||||
push_operation!(graph, rand(r, collect(operations.nodeSplits)))
|
||||
return true
|
||||
end
|
||||
else
|
||||
# pop
|
||||
if (can_pop(graph))
|
||||
pop_operation!(graph)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
src/optimization/reduce.jl
Normal file
30
src/optimization/reduce.jl
Normal file
@ -0,0 +1,30 @@
|
||||
"""
|
||||
ReductionOptimizer
|
||||
|
||||
An optimizer that simply applies an available [`NodeReduction`](@ref) on each step. It implements [`optimize_to_fixpoint`](@ref). The fixpoint is reached when there are no more possible [`NodeReduction`](@ref)s in the graph.
|
||||
"""
|
||||
struct ReductionOptimizer <: AbstractOptimizer end
|
||||
|
||||
function optimize_step!(optimizer::ReductionOptimizer, graph::DAG)
|
||||
# generate all options
|
||||
operations = get_operations(graph)
|
||||
if fixpoint_reached(optimizer, graph)
|
||||
return false
|
||||
end
|
||||
|
||||
push_operation!(graph, first(operations.nodeReductions))
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function fixpoint_reached(optimizer::ReductionOptimizer, graph::DAG)
|
||||
operations = get_operations(graph)
|
||||
return isempty(operations.nodeReductions)
|
||||
end
|
||||
|
||||
function optimize_to_fixpoint!(optimizer::ReductionOptimizer, graph::DAG)
|
||||
while !fixpoint_reached(optimizer, graph)
|
||||
optimize_step!(optimizer, graph)
|
||||
end
|
||||
return nothing
|
||||
end
|
@ -4,14 +4,18 @@
|
||||
Create an empty [`GraphProperties`](@ref) object.
|
||||
"""
|
||||
function GraphProperties()
|
||||
return (
|
||||
data = 0.0,
|
||||
computeEffort = 0.0,
|
||||
computeIntensity = 0.0,
|
||||
cost = 0.0,
|
||||
noNodes = 0,
|
||||
noEdges = 0,
|
||||
)::GraphProperties
|
||||
return (data = 0.0, computeEffort = 0.0, computeIntensity = 0.0, noNodes = 0, noEdges = 0)::GraphProperties
|
||||
end
|
||||
|
||||
@inline function _props(
|
||||
node::DataTaskNode{TaskType},
|
||||
)::Tuple{Float64, Float64, Int64} where {TaskType <: AbstractDataTask}
|
||||
return (data(task(node)) * length(parents(node)), 0.0, length(parents(node)))
|
||||
end
|
||||
@inline function _props(
|
||||
node::ComputeTaskNode{TaskType},
|
||||
)::Tuple{Float64, Float64, Int64} where {TaskType <: AbstractComputeTask}
|
||||
return (0.0, compute_effort(task(node)), length(parents(node)))
|
||||
end
|
||||
|
||||
"""
|
||||
@ -27,16 +31,16 @@ function GraphProperties(graph::DAG)
|
||||
ce = 0.0
|
||||
ed = 0
|
||||
for node in graph.nodes
|
||||
d += data(node.task) * length(node.parents)
|
||||
ce += compute_effort(node.task)
|
||||
ed += length(node.parents)
|
||||
props = _props(node)
|
||||
d += props[1]
|
||||
ce += props[2]
|
||||
ed += props[3]
|
||||
end
|
||||
|
||||
return (
|
||||
data = d,
|
||||
computeEffort = ce,
|
||||
computeIntensity = (d == 0) ? 0.0 : ce / d,
|
||||
cost = 0.0, # TODO
|
||||
noNodes = length(graph.nodes),
|
||||
noEdges = ed,
|
||||
)::GraphProperties
|
||||
@ -50,23 +54,18 @@ The graph's properties after applying the [`Diff`](@ref) will be `get_properties
|
||||
For reverting a diff, it's `get_properties(graph) - GraphProperties(diff)`.
|
||||
"""
|
||||
function GraphProperties(diff::Diff)
|
||||
d = 0.0
|
||||
ce = 0.0
|
||||
c = 0.0 # TODO
|
||||
|
||||
ce =
|
||||
reduce(+, compute_effort(n.task) for n in diff.addedNodes; init = 0.0) -
|
||||
reduce(+, compute_effort(n.task) for n in diff.removedNodes; init = 0.0)
|
||||
reduce(+, compute_effort(task(n)) for n in diff.addedNodes; init = 0.0) -
|
||||
reduce(+, compute_effort(task(n)) for n in diff.removedNodes; init = 0.0)
|
||||
|
||||
d =
|
||||
reduce(+, data(e) for e in diff.addedEdges; init = 0.0) -
|
||||
reduce(+, data(e) for e in diff.removedEdges; init = 0.0)
|
||||
reduce(+, data(task(n)) for n in diff.addedNodes; init = 0.0) -
|
||||
reduce(+, data(task(n)) for n in diff.removedNodes; init = 0.0)
|
||||
|
||||
return (
|
||||
data = d,
|
||||
computeEffort = ce,
|
||||
computeIntensity = (d == 0) ? 0.0 : ce / d,
|
||||
cost = c,
|
||||
noNodes = length(diff.addedNodes) - length(diff.removedNodes),
|
||||
noEdges = length(diff.addedEdges) - length(diff.removedEdges),
|
||||
)::GraphProperties
|
||||
|
@ -7,11 +7,10 @@ Representation of a [`DAG`](@ref)'s properties.
|
||||
`.data`: The total data transfer.\\
|
||||
`.computeEffort`: The total compute effort.\\
|
||||
`.computeIntensity`: The compute intensity, will always equal `.computeEffort / .data`.\\
|
||||
`.cost`: The estimated cost.\\
|
||||
`.noNodes`: Number of [`Node`](@ref)s.\\
|
||||
`.noEdges`: Number of [`Edge`](@ref)s.
|
||||
"""
|
||||
const GraphProperties = NamedTuple{
|
||||
(:data, :computeEffort, :computeIntensity, :cost, :noNodes, :noEdges),
|
||||
Tuple{Float64, Float64, Float64, Float64, Int, Int},
|
||||
(:data, :computeEffort, :computeIntensity, :noNodes, :noEdges),
|
||||
Tuple{Float64, Float64, Float64, Int, Int},
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ function -(prop1::GraphProperties, prop2::GraphProperties)
|
||||
else
|
||||
(prop1.computeEffort - prop2.computeEffort) / (prop1.data - prop2.data)
|
||||
end,
|
||||
cost = prop1.cost - prop2.cost,
|
||||
noNodes = prop1.noNodes - prop2.noNodes,
|
||||
noEdges = prop1.noEdges - prop2.noEdges,
|
||||
)::GraphProperties
|
||||
@ -34,7 +33,6 @@ function +(prop1::GraphProperties, prop2::GraphProperties)
|
||||
else
|
||||
(prop1.computeEffort + prop2.computeEffort) / (prop1.data + prop2.data)
|
||||
end,
|
||||
cost = prop1.cost + prop2.cost,
|
||||
noNodes = prop1.noNodes + prop2.noNodes,
|
||||
noEdges = prop1.noEdges + prop2.noEdges,
|
||||
)::GraphProperties
|
||||
@ -50,7 +48,6 @@ function -(prop::GraphProperties)
|
||||
data = -prop.data,
|
||||
computeEffort = -prop.computeEffort,
|
||||
computeIntensity = prop.computeIntensity, # no negation here!
|
||||
cost = -prop.cost,
|
||||
noNodes = -prop.noNodes,
|
||||
noEdges = -prop.noEdges,
|
||||
)::GraphProperties
|
||||
|
@ -32,14 +32,14 @@ function schedule_dag(::GreedyScheduler, graph::DAG, machine::Machine)
|
||||
if (isa(node, ComputeTaskNode))
|
||||
lowestDevice = peek(deviceAccCost)[1]
|
||||
node.device = lowestDevice
|
||||
deviceAccCost[lowestDevice] = compute_effort(node.task)
|
||||
deviceAccCost[lowestDevice] = compute_effort(task(node))
|
||||
end
|
||||
|
||||
push!(schedule, node)
|
||||
for parent in node.parents
|
||||
for parent in parents(node)
|
||||
# reduce the priority of all parents by one
|
||||
if (!haskey(nodeQueue, parent))
|
||||
enqueue!(nodeQueue, parent => length(parent.children) - 1)
|
||||
enqueue!(nodeQueue, parent => length(children(parent)) - 1)
|
||||
else
|
||||
nodeQueue[parent] = nodeQueue[parent] - 1
|
||||
end
|
||||
|
@ -41,16 +41,16 @@ end
|
||||
Generate and return code for a given [`ComputeTaskNode`](@ref).
|
||||
"""
|
||||
function get_expression(node::ComputeTaskNode)
|
||||
@assert length(node.children) <= children(node.task) "Node $(node) has too many children for its task: node has $(length(node.children)) versus task has $(children(node.task))\nNode's children: $(getfield.(node.children, :children))"
|
||||
@assert length(children(node)) <= children(task(node)) "Node $(node) has too many children for its task: node has $(length(node.children)) versus task has $(children(task(node)))\nNode's children: $(getfield.(node.children, :children))"
|
||||
@assert !ismissing(node.device) "Trying to get expression for an unscheduled ComputeTaskNode\nNode: $(node)"
|
||||
|
||||
inExprs = Vector()
|
||||
for id in getfield.(node.children, :id)
|
||||
for id in getfield.(children(node), :id)
|
||||
push!(inExprs, gen_access_expr(node.device, Symbol(to_var_name(id))))
|
||||
end
|
||||
outExpr = gen_access_expr(node.device, Symbol(to_var_name(node.id)))
|
||||
|
||||
return get_expression(node.task, node.device, inExprs, outExpr)
|
||||
return get_expression(task(node), node.device, inExprs, outExpr)
|
||||
end
|
||||
|
||||
"""
|
||||
@ -59,11 +59,11 @@ end
|
||||
Generate and return code for a given [`DataTaskNode`](@ref).
|
||||
"""
|
||||
function get_expression(node::DataTaskNode)
|
||||
@assert length(node.children) == 1 "Trying to call get_expression on a data task node that has $(length(node.children)) children instead of 1"
|
||||
@assert length(children(node)) == 1 "Trying to call get_expression on a data task node that has $(length(node.children)) children instead of 1"
|
||||
|
||||
# TODO: dispatch to device implementations generating the copy commands
|
||||
|
||||
child = node.children[1]
|
||||
child = children(node)[1]
|
||||
inExpr = eval(gen_access_expr(child.device, Symbol(to_var_name(child.id))))
|
||||
outExpr = eval(gen_access_expr(child.device, Symbol(to_var_name(node.id))))
|
||||
dataTransportExp = Meta.parse("$outExpr = $inExpr")
|
||||
@ -79,7 +79,7 @@ Generate and return code for the initial input reading expression for [`DataTask
|
||||
See also: [`get_entry_nodes`](@ref)
|
||||
"""
|
||||
function get_init_expression(node::DataTaskNode, device::AbstractDevice)
|
||||
@assert isempty(node.children) "Trying to call get_init_expression on a data task node that is not an entry node."
|
||||
@assert isempty(children(node)) "Trying to call get_init_expression on a data task node that is not an entry node."
|
||||
|
||||
inExpr = eval(gen_access_expr(device, Symbol("$(to_var_name(node.id))_in")))
|
||||
outExpr = eval(gen_access_expr(device, Symbol(to_var_name(node.id))))
|
||||
|
@ -17,15 +17,16 @@ copy(t::AbstractComputeTask) = typeof(t)()
|
||||
|
||||
Return a copy of th egiven [`FusedComputeTask`](@ref).
|
||||
"""
|
||||
function copy(t::FusedComputeTask{T1, T2}) where {T1, T2}
|
||||
return FusedComputeTask{T1, T2}(
|
||||
copy(t.first_task),
|
||||
copy(t.second_task),
|
||||
copy(t.t1_inputs),
|
||||
t.t1_output,
|
||||
copy(t.t2_inputs),
|
||||
)
|
||||
function copy(t::FusedComputeTask)
|
||||
return FusedComputeTask(copy(t.first_task), copy(t.second_task), copy(t.t1_inputs), t.t1_output, copy(t.t2_inputs))
|
||||
end
|
||||
|
||||
FusedComputeTask{T1, T2}(t1_inputs::Vector{String}, t1_output::String, t2_inputs::Vector{String}) where {T1, T2} =
|
||||
FusedComputeTask{T1, T2}(T1(), T2(), t1_inputs, t1_output, t2_inputs)
|
||||
function FusedComputeTask(
|
||||
T1::Type{<:AbstractComputeTask},
|
||||
T2::Type{<:AbstractComputeTask},
|
||||
t1_inputs::Vector{String},
|
||||
t1_output::String,
|
||||
t2_inputs::Vector{String},
|
||||
)
|
||||
return FusedComputeTask(T1(), T2(), t1_inputs, t1_output, t2_inputs)
|
||||
end
|
||||
|
@ -6,3 +6,12 @@ Print a string representation of the fused compute task to io.
|
||||
function show(io::IO, t::FusedComputeTask)
|
||||
return print(io, "ComputeFuse($(t.first_task), $(t.second_task))")
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, t::DataTask)
|
||||
|
||||
Print the data task to io.
|
||||
"""
|
||||
function show(io::IO, t::DataTask)
|
||||
return print(io, "Data", t.data)
|
||||
end
|
||||
|
@ -30,7 +30,7 @@ compute(t::AbstractDataTask; data...) = data
|
||||
|
||||
Fallback implementation of the compute effort of a task, throwing an error.
|
||||
"""
|
||||
function compute_effort(t::AbstractTask)
|
||||
function compute_effort(t::AbstractTask)::Float64
|
||||
# default implementation using compute
|
||||
return error("Need to implement compute_effort()")
|
||||
end
|
||||
@ -40,7 +40,7 @@ end
|
||||
|
||||
Fallback implementation of the data of a task, throwing an error.
|
||||
"""
|
||||
function data(t::AbstractTask)
|
||||
function data(t::AbstractTask)::Float64
|
||||
return error("Need to implement data()")
|
||||
end
|
||||
|
||||
@ -49,28 +49,51 @@ end
|
||||
|
||||
Return the compute effort of a data task, always zero, regardless of the specific task.
|
||||
"""
|
||||
compute_effort(t::AbstractDataTask) = 0
|
||||
compute_effort(t::AbstractDataTask)::Float64 = 0.0
|
||||
|
||||
"""
|
||||
data(t::AbstractDataTask)
|
||||
|
||||
Return the data of a data task. Given by the task's `.data` field.
|
||||
"""
|
||||
data(t::AbstractDataTask) = getfield(t, :data)
|
||||
data(t::AbstractDataTask)::Float64 = getfield(t, :data)
|
||||
|
||||
"""
|
||||
copy(t::DataTask)
|
||||
|
||||
Copy the data task and return it.
|
||||
"""
|
||||
copy(t::DataTask) = DataTask(t.data)
|
||||
|
||||
"""
|
||||
children(::DataTask)
|
||||
|
||||
Return the number of children of a data task (always 1).
|
||||
"""
|
||||
children(::DataTask) = 1
|
||||
|
||||
"""
|
||||
children(t::FusedComputeTask)
|
||||
|
||||
Return the number of children of a FusedComputeTask.
|
||||
"""
|
||||
function children(t::FusedComputeTask)
|
||||
return length(union(Set(t.t1_inputs), Set(t.t2_inputs)))
|
||||
end
|
||||
|
||||
"""
|
||||
data(t::AbstractComputeTask)
|
||||
|
||||
Return the data of a compute task, always zero, regardless of the specific task.
|
||||
"""
|
||||
data(t::AbstractComputeTask) = 0
|
||||
data(t::AbstractComputeTask)::Float64 = 0.0
|
||||
|
||||
"""
|
||||
compute_effort(t::FusedComputeTask)
|
||||
|
||||
Return the compute effort of a fused compute task.
|
||||
"""
|
||||
function compute_effort(t::FusedComputeTask)
|
||||
function compute_effort(t::FusedComputeTask)::Float64
|
||||
return compute_effort(t.first_task) + compute_effort(t.second_task)
|
||||
end
|
||||
|
||||
@ -79,4 +102,4 @@ end
|
||||
|
||||
Return a tuple of a the fused compute task's components' types.
|
||||
"""
|
||||
get_types(::FusedComputeTask{T1, T2}) where {T1, T2} = (T1, T2)
|
||||
get_types(t::FusedComputeTask) = (typeof(t.first_task), typeof(t.second_task))
|
||||
|
@ -19,6 +19,15 @@ The shared base type for any data task.
|
||||
"""
|
||||
abstract type AbstractDataTask <: AbstractTask end
|
||||
|
||||
"""
|
||||
DataTask <: AbstractDataTask
|
||||
|
||||
Task representing a specific data transfer.
|
||||
"""
|
||||
struct DataTask <: AbstractDataTask
|
||||
data::Float64
|
||||
end
|
||||
|
||||
"""
|
||||
FusedComputeTask{T1 <: AbstractComputeTask, T2 <: AbstractComputeTask} <: AbstractComputeTask
|
||||
|
||||
@ -26,9 +35,9 @@ A fused compute task made up of the computation of first `T1` and then `T2`.
|
||||
|
||||
Also see: [`get_types`](@ref).
|
||||
"""
|
||||
struct FusedComputeTask{T1 <: AbstractComputeTask, T2 <: AbstractComputeTask} <: AbstractComputeTask
|
||||
first_task::T1
|
||||
second_task::T2
|
||||
struct FusedComputeTask <: AbstractComputeTask
|
||||
first_task::AbstractComputeTask
|
||||
second_task::AbstractComputeTask
|
||||
# the names of the inputs for T1
|
||||
t1_inputs::Vector{Symbol}
|
||||
# output name of T1
|
||||
|
32
src/trie.jl
32
src/trie.jl
@ -3,9 +3,9 @@
|
||||
|
||||
Helper struct for [`NodeTrie`](@ref). 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.
|
||||
"""
|
||||
mutable struct NodeIdTrie
|
||||
value::Vector{Node}
|
||||
children::Dict{UUID, NodeIdTrie}
|
||||
mutable struct NodeIdTrie{NodeType <: Node}
|
||||
value::Vector{NodeType}
|
||||
children::Dict{UUID, NodeIdTrie{NodeType}}
|
||||
end
|
||||
|
||||
"""
|
||||
@ -35,8 +35,8 @@ end
|
||||
|
||||
Constructor for an empty [`NodeIdTrie`](@ref).
|
||||
"""
|
||||
function NodeIdTrie()
|
||||
return NodeIdTrie(Vector{Node}(), Dict{UUID, NodeIdTrie}())
|
||||
function NodeIdTrie{NodeType}() where {NodeType <: Node}
|
||||
return NodeIdTrie(Vector{NodeType}(), Dict{UUID, NodeIdTrie{NodeType}}())
|
||||
end
|
||||
|
||||
"""
|
||||
@ -44,8 +44,12 @@ end
|
||||
|
||||
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.
|
||||
"""
|
||||
function insert_helper!(trie::NodeIdTrie, node::Node, depth::Int)
|
||||
if (length(node.children) == depth)
|
||||
function insert_helper!(
|
||||
trie::NodeIdTrie{NodeType},
|
||||
node::NodeType,
|
||||
depth::Int,
|
||||
) where {TaskType <: AbstractTask, NodeType <: Union{DataTaskNode{TaskType}, ComputeTaskNode{TaskType}}}
|
||||
if (length(children(node)) == depth)
|
||||
push!(trie.value, node)
|
||||
return nothing
|
||||
end
|
||||
@ -54,7 +58,7 @@ function insert_helper!(trie::NodeIdTrie, node::Node, depth::Int)
|
||||
id = node.children[depth].id
|
||||
|
||||
if (!haskey(trie.children, id))
|
||||
trie.children[id] = NodeIdTrie()
|
||||
trie.children[id] = NodeIdTrie{NodeType}()
|
||||
end
|
||||
return insert_helper!(trie.children[id], node, depth)
|
||||
end
|
||||
@ -64,12 +68,14 @@ end
|
||||
|
||||
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.
|
||||
"""
|
||||
function insert!(trie::NodeTrie, node::Node)
|
||||
t = typeof(node.task)
|
||||
if (!haskey(trie.children, t))
|
||||
trie.children[t] = NodeIdTrie()
|
||||
function insert!(
|
||||
trie::NodeTrie,
|
||||
node::NodeType,
|
||||
) where {TaskType <: AbstractTask, NodeType <: Union{DataTaskNode{TaskType}, ComputeTaskNode{TaskType}}}
|
||||
if (!haskey(trie.children, NodeType))
|
||||
trie.children[NodeType] = NodeIdTrie{NodeType}()
|
||||
end
|
||||
return insert_helper!(trie.children[typeof(node.task)], node, 0)
|
||||
return insert_helper!(trie.children[NodeType], node, 0)
|
||||
end
|
||||
|
||||
"""
|
||||
|
140
src/utility.jl
140
src/utility.jl
@ -36,8 +36,8 @@ Sort the nodes' parents and children vectors. The vectors are mostly very short
|
||||
Sorted nodes are required to make the finding of [`NodeReduction`](@ref)s a lot faster using the [`NodeTrie`](@ref) data structure.
|
||||
"""
|
||||
function sort_node!(node::Node)
|
||||
sort!(node.children, lt = lt_nodes)
|
||||
return sort!(node.parents, lt = lt_nodes)
|
||||
sort!(children(node), lt = lt_nodes)
|
||||
return sort!(parents(node), lt = lt_nodes)
|
||||
end
|
||||
|
||||
"""
|
||||
@ -103,3 +103,139 @@ function unroll_symbol_vector(vec::Vector)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
|
||||
####################
|
||||
# CODE FROM HERE BORROWED FROM SOURCE: https://codebase.helmholtz.cloud/qedsandbox/QEDphasespaces.jl/
|
||||
# use qedphasespaces directly once released
|
||||
#
|
||||
# quick and dirty implementation of the RAMBO algorithm
|
||||
#
|
||||
# reference:
|
||||
# * https://cds.cern.ch/record/164736/files/198601282.pdf
|
||||
# * https://www.sciencedirect.com/science/article/pii/0010465586901190
|
||||
####################
|
||||
|
||||
function generate_initial_moms(ss, masses)
|
||||
E1 = (ss^2 + masses[1]^2 - masses[2]^2) / (2 * ss)
|
||||
E2 = (ss^2 + masses[2]^2 - masses[1]^2) / (2 * ss)
|
||||
|
||||
rho1 = sqrt(E1^2 - masses[1]^2)
|
||||
rho2 = sqrt(E2^2 - masses[2]^2)
|
||||
|
||||
return [SFourMomentum(E1, 0, 0, rho1), SFourMomentum(E2, 0, 0, -rho2)]
|
||||
end
|
||||
|
||||
|
||||
Random.rand(rng::AbstractRNG, ::Random.SamplerType{SFourMomentum}) = SFourMomentum(rand(rng, 4))
|
||||
Random.rand(rng::AbstractRNG, ::Random.SamplerType{NTuple{N, Float64}}) where {N} = Tuple(rand(rng, N))
|
||||
|
||||
|
||||
function _transform_uni_to_mom(u1, u2, u3, u4)
|
||||
cth = 2 * u1 - 1
|
||||
sth = sqrt(1 - cth^2)
|
||||
phi = 2 * pi * u2
|
||||
q0 = -log(u3 * u4)
|
||||
qx = q0 * sth * cos(phi)
|
||||
qy = q0 * sth * sin(phi)
|
||||
qz = q0 * cth
|
||||
|
||||
return SFourMomentum(q0, qx, qy, qz)
|
||||
end
|
||||
|
||||
function _transform_uni_to_mom!(uni_mom, dest)
|
||||
u1, u2, u3, u4 = Tuple(uni_mom)
|
||||
cth = 2 * u1 - 1
|
||||
sth = sqrt(1 - cth^2)
|
||||
phi = 2 * pi * u2
|
||||
q0 = -log(u3 * u4)
|
||||
qx = q0 * sth * cos(phi)
|
||||
qy = q0 * sth * sin(phi)
|
||||
qz = q0 * cth
|
||||
|
||||
return dest = SFourMomentum(q0, qx, qy, qz)
|
||||
end
|
||||
|
||||
_transform_uni_to_mom(u1234::Tuple) = _transform_uni_to_mom(u1234...)
|
||||
_transform_uni_to_mom(u1234::SFourMomentum) = _transform_uni_to_mom(Tuple(u1234))
|
||||
|
||||
function generate_massless_moms(rng, n::Int)
|
||||
a = Vector{SFourMomentum}(undef, n)
|
||||
rand!(rng, a)
|
||||
return map(_transform_uni_to_mom, a)
|
||||
end
|
||||
|
||||
function generate_physical_massless_moms(rng, ss, n)
|
||||
r_moms = generate_massless_moms(rng, n)
|
||||
Q = sum(r_moms)
|
||||
M = sqrt(Q * Q)
|
||||
fac = -1 / M
|
||||
Qx = getX(Q)
|
||||
Qy = getY(Q)
|
||||
Qz = getZ(Q)
|
||||
bx = fac * Qx
|
||||
by = fac * Qy
|
||||
bz = fac * Qz
|
||||
gamma = getT(Q) / M
|
||||
a = 1 / (1 + gamma)
|
||||
x = ss / M
|
||||
|
||||
i = 1
|
||||
while i <= n
|
||||
mom = r_moms[i]
|
||||
mom0 = getT(mom)
|
||||
mom1 = getX(mom)
|
||||
mom2 = getY(mom)
|
||||
mom3 = getZ(mom)
|
||||
|
||||
bq = bx * mom1 + by * mom2 + bz * mom3
|
||||
|
||||
p0 = x * (gamma * mom0 + bq)
|
||||
px = x * (mom1 + bx * mom0 + a * bq * bx)
|
||||
py = x * (mom2 + by * mom0 + a * bq * by)
|
||||
pz = x * (mom3 + bz * mom0 + a * bq * bz)
|
||||
|
||||
r_moms[i] = SFourMomentum(p0, px, py, pz)
|
||||
i += 1
|
||||
end
|
||||
return r_moms
|
||||
end
|
||||
|
||||
function _to_be_solved(xi, masses, p0s, ss)
|
||||
sum = 0.0
|
||||
for (i, E) in enumerate(p0s)
|
||||
sum += sqrt(masses[i]^2 + xi^2 * E^2)
|
||||
end
|
||||
return sum - ss
|
||||
end
|
||||
|
||||
function _build_massive_momenta(xi, masses, massless_moms)
|
||||
vec = SFourMomentum[]
|
||||
i = 1
|
||||
while i <= length(massless_moms)
|
||||
massless_mom = massless_moms[i]
|
||||
k0 = sqrt(getT(massless_mom)^2 * xi^2 + masses[i]^2)
|
||||
|
||||
kx = xi * getX(massless_mom)
|
||||
ky = xi * getY(massless_mom)
|
||||
kz = xi * getZ(massless_mom)
|
||||
|
||||
push!(vec, SFourMomentum(k0, kx, ky, kz))
|
||||
|
||||
i += 1
|
||||
end
|
||||
return vec
|
||||
end
|
||||
|
||||
first_derivative(func) = x -> ForwardDiff.derivative(func, float(x))
|
||||
|
||||
|
||||
function generate_physical_massive_moms(rng, ss, masses; x0 = 0.1)
|
||||
n = length(masses)
|
||||
massless_moms = generate_physical_massless_moms(rng, ss, n)
|
||||
energies = getT.(massless_moms)
|
||||
f = x -> _to_be_solved(x, masses, energies, ss)
|
||||
xi = find_zero((f, first_derivative(f)), x0, Roots.Newton())
|
||||
return _build_massive_momenta(xi, masses, massless_moms)
|
||||
end
|
||||
|
@ -1,4 +1,8 @@
|
||||
[deps]
|
||||
AccurateArithmetic = "22286c92-06ac-501d-9306-4abd417d9753"
|
||||
QEDbase = "10e22c08-3ccb-4172-bfcf-7d7aa3d04d93"
|
||||
QEDprocesses = "46de9c38-1bb3-4547-a1ec-da24d767fdad"
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
|
||||
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
|
||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||
|
@ -1,3 +1,4 @@
|
||||
using MetagraphOptimization
|
||||
using Random
|
||||
|
||||
function test_known_graph(name::String, n, fusion_test = true)
|
||||
@ -88,9 +89,6 @@ end
|
||||
|
||||
Random.seed!(0)
|
||||
|
||||
@testset "Test Known ABC-Graphs" begin
|
||||
test_known_graph("AB->AB", 10000)
|
||||
test_known_graph("AB->ABBB", 10000)
|
||||
test_known_graph("AB->ABBBBB", 1000, false)
|
||||
end
|
||||
println("Known Graph Testing Complete!")
|
||||
test_known_graph("AB->AB", 10000)
|
||||
test_known_graph("AB->ABBB", 10000)
|
||||
test_known_graph("AB->ABBBBB", 1000, false)
|
||||
|
@ -1,99 +1,98 @@
|
||||
using MetagraphOptimization
|
||||
|
||||
import MetagraphOptimization.insert_node!
|
||||
import MetagraphOptimization.insert_edge!
|
||||
import MetagraphOptimization.make_node
|
||||
|
||||
@testset "Unit Tests Node Reduction" begin
|
||||
graph = MetagraphOptimization.DAG()
|
||||
graph = MetagraphOptimization.DAG()
|
||||
|
||||
d_exit = insert_node!(graph, make_node(DataTask(10)), track = false)
|
||||
d_exit = insert_node!(graph, make_node(DataTask(10)), track = false)
|
||||
|
||||
s0 = insert_node!(graph, make_node(ComputeTaskS2()), track = false)
|
||||
s0 = insert_node!(graph, make_node(ComputeTaskABC_S2()), track = false)
|
||||
|
||||
ED = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
FD = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
ED = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
FD = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
|
||||
EC = insert_node!(graph, make_node(ComputeTaskV()), track = false)
|
||||
FC = insert_node!(graph, make_node(ComputeTaskV()), track = false)
|
||||
EC = insert_node!(graph, make_node(ComputeTaskABC_V()), track = false)
|
||||
FC = insert_node!(graph, make_node(ComputeTaskABC_V()), track = false)
|
||||
|
||||
A1D = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
B1D_1 = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
B1D_2 = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
C1D = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
A1D = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
B1D_1 = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
B1D_2 = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
C1D = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
|
||||
A1C = insert_node!(graph, make_node(ComputeTaskU()), track = false)
|
||||
B1C_1 = insert_node!(graph, make_node(ComputeTaskU()), track = false)
|
||||
B1C_2 = insert_node!(graph, make_node(ComputeTaskU()), track = false)
|
||||
C1C = insert_node!(graph, make_node(ComputeTaskU()), track = false)
|
||||
A1C = insert_node!(graph, make_node(ComputeTaskABC_U()), track = false)
|
||||
B1C_1 = insert_node!(graph, make_node(ComputeTaskABC_U()), track = false)
|
||||
B1C_2 = insert_node!(graph, make_node(ComputeTaskABC_U()), track = false)
|
||||
C1C = insert_node!(graph, make_node(ComputeTaskABC_U()), track = false)
|
||||
|
||||
AD = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
BD = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
CD = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
AD = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
BD = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
CD = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
|
||||
insert_edge!(graph, s0, d_exit, track = false)
|
||||
insert_edge!(graph, ED, s0, track = false)
|
||||
insert_edge!(graph, FD, s0, track = false)
|
||||
insert_edge!(graph, EC, ED, track = false)
|
||||
insert_edge!(graph, FC, FD, track = false)
|
||||
insert_edge!(graph, s0, d_exit, track = false)
|
||||
insert_edge!(graph, ED, s0, track = false)
|
||||
insert_edge!(graph, FD, s0, track = false)
|
||||
insert_edge!(graph, EC, ED, track = false)
|
||||
insert_edge!(graph, FC, FD, track = false)
|
||||
|
||||
insert_edge!(graph, A1D, EC, track = false)
|
||||
insert_edge!(graph, B1D_1, EC, track = false)
|
||||
insert_edge!(graph, A1D, EC, track = false)
|
||||
insert_edge!(graph, B1D_1, EC, track = false)
|
||||
|
||||
insert_edge!(graph, B1D_2, FC, track = false)
|
||||
insert_edge!(graph, C1D, FC, track = false)
|
||||
insert_edge!(graph, B1D_2, FC, track = false)
|
||||
insert_edge!(graph, C1D, FC, track = false)
|
||||
|
||||
insert_edge!(graph, A1C, A1D, track = false)
|
||||
insert_edge!(graph, B1C_1, B1D_1, track = false)
|
||||
insert_edge!(graph, B1C_2, B1D_2, track = false)
|
||||
insert_edge!(graph, C1C, C1D, track = false)
|
||||
insert_edge!(graph, A1C, A1D, track = false)
|
||||
insert_edge!(graph, B1C_1, B1D_1, track = false)
|
||||
insert_edge!(graph, B1C_2, B1D_2, track = false)
|
||||
insert_edge!(graph, C1C, C1D, track = false)
|
||||
|
||||
insert_edge!(graph, AD, A1C, track = false)
|
||||
insert_edge!(graph, BD, B1C_1, track = false)
|
||||
insert_edge!(graph, BD, B1C_2, track = false)
|
||||
insert_edge!(graph, CD, C1C, track = false)
|
||||
insert_edge!(graph, AD, A1C, track = false)
|
||||
insert_edge!(graph, BD, B1C_1, track = false)
|
||||
insert_edge!(graph, BD, B1C_2, track = false)
|
||||
insert_edge!(graph, CD, C1C, track = false)
|
||||
|
||||
@test is_valid(graph)
|
||||
@test is_valid(graph)
|
||||
|
||||
@test is_exit_node(d_exit)
|
||||
@test is_entry_node(AD)
|
||||
@test is_entry_node(BD)
|
||||
@test is_entry_node(CD)
|
||||
@test is_exit_node(d_exit)
|
||||
@test is_entry_node(AD)
|
||||
@test is_entry_node(BD)
|
||||
@test is_entry_node(CD)
|
||||
|
||||
opt = get_operations(graph)
|
||||
opt = get_operations(graph)
|
||||
|
||||
@test length(opt) == (nodeFusions = 6, nodeReductions = 1, nodeSplits = 1)
|
||||
@test length(opt) == (nodeFusions = 6, nodeReductions = 1, nodeSplits = 1)
|
||||
|
||||
#println("Initial State:\n", opt)
|
||||
#println("Initial State:\n", opt)
|
||||
|
||||
nr = first(opt.nodeReductions)
|
||||
@test Set(nr.input) == Set([B1C_1, B1C_2])
|
||||
push_operation!(graph, nr)
|
||||
opt = get_operations(graph)
|
||||
nr = first(opt.nodeReductions)
|
||||
@test Set(nr.input) == Set([B1C_1, B1C_2])
|
||||
push_operation!(graph, nr)
|
||||
opt = get_operations(graph)
|
||||
|
||||
@test length(opt) == (nodeFusions = 4, nodeReductions = 1, nodeSplits = 1)
|
||||
#println("After 1 Node Reduction:\n", opt)
|
||||
@test length(opt) == (nodeFusions = 4, nodeReductions = 1, nodeSplits = 1)
|
||||
#println("After 1 Node Reduction:\n", opt)
|
||||
|
||||
nr = first(opt.nodeReductions)
|
||||
@test Set(nr.input) == Set([B1D_1, B1D_2])
|
||||
push_operation!(graph, nr)
|
||||
opt = get_operations(graph)
|
||||
nr = first(opt.nodeReductions)
|
||||
@test Set(nr.input) == Set([B1D_1, B1D_2])
|
||||
push_operation!(graph, nr)
|
||||
opt = get_operations(graph)
|
||||
|
||||
@test is_valid(graph)
|
||||
@test is_valid(graph)
|
||||
|
||||
@test length(opt) == (nodeFusions = 4, nodeReductions = 0, nodeSplits = 1)
|
||||
#println("After 2 Node Reductions:\n", opt)
|
||||
@test length(opt) == (nodeFusions = 4, nodeReductions = 0, nodeSplits = 1)
|
||||
#println("After 2 Node Reductions:\n", opt)
|
||||
|
||||
pop_operation!(graph)
|
||||
pop_operation!(graph)
|
||||
|
||||
opt = get_operations(graph)
|
||||
@test length(opt) == (nodeFusions = 4, nodeReductions = 1, nodeSplits = 1)
|
||||
#println("After reverting the second Node Reduction:\n", opt)
|
||||
opt = get_operations(graph)
|
||||
@test length(opt) == (nodeFusions = 4, nodeReductions = 1, nodeSplits = 1)
|
||||
#println("After reverting the second Node Reduction:\n", opt)
|
||||
|
||||
reset_graph!(graph)
|
||||
reset_graph!(graph)
|
||||
|
||||
opt = get_operations(graph)
|
||||
@test length(opt) == (nodeFusions = 6, nodeReductions = 1, nodeSplits = 1)
|
||||
#println("After reverting to the initial state:\n", opt)
|
||||
opt = get_operations(graph)
|
||||
@test length(opt) == (nodeFusions = 6, nodeReductions = 1, nodeSplits = 1)
|
||||
#println("After reverting to the initial state:\n", opt)
|
||||
|
||||
@test is_valid(graph)
|
||||
end
|
||||
println("Node Reduction Unit Tests Complete!")
|
||||
@test is_valid(graph)
|
||||
|
@ -1,14 +1,41 @@
|
||||
using MetagraphOptimization
|
||||
using Test
|
||||
using SafeTestsets
|
||||
|
||||
@testset "MetagraphOptimization Tests" begin
|
||||
@safetestset "Utility Unit Tests " begin
|
||||
include("unit_tests_utility.jl")
|
||||
end
|
||||
@safetestset "Task Unit Tests " begin
|
||||
include("unit_tests_tasks.jl")
|
||||
end
|
||||
@safetestset "Node Unit Tests " begin
|
||||
include("unit_tests_nodes.jl")
|
||||
end
|
||||
@safetestset "Properties Unit Tests " begin
|
||||
include("unit_tests_properties.jl")
|
||||
end
|
||||
@safetestset "Estimation Unit Tests " begin
|
||||
include("unit_tests_estimator.jl")
|
||||
end
|
||||
@safetestset "ABC-Model Unit Tests " begin
|
||||
include("unit_tests_abcmodel.jl")
|
||||
end
|
||||
@safetestset "QED Feynman Diagram Generation Tests" begin
|
||||
include("unit_tests_qed_diagrams.jl")
|
||||
end
|
||||
@safetestset "QED-Model Unit Tests " begin
|
||||
include("unit_tests_qedmodel.jl")
|
||||
end
|
||||
@safetestset "Node Reduction Unit Tests " begin
|
||||
include("node_reduction.jl")
|
||||
end
|
||||
@safetestset "Graph Unit Tests " begin
|
||||
include("unit_tests_graph.jl")
|
||||
end
|
||||
@safetestset "Execution Unit Tests " begin
|
||||
include("unit_tests_execution.jl")
|
||||
|
||||
end
|
||||
@safetestset "Optimization Unit Tests " begin
|
||||
include("unit_tests_optimization.jl")
|
||||
end
|
||||
@safetestset "Known Graph Tests " begin
|
||||
include("known_graphs.jl")
|
||||
end
|
||||
|
23
test/unit_tests_abcmodel.jl
Normal file
23
test/unit_tests_abcmodel.jl
Normal file
@ -0,0 +1,23 @@
|
||||
using MetagraphOptimization
|
||||
using QEDbase
|
||||
|
||||
import MetagraphOptimization.interaction_result
|
||||
|
||||
def_momentum = SFourMomentum(1.0, 0.0, 0.0, 0.0)
|
||||
|
||||
testparticleTypes = [ParticleA, ParticleB, ParticleC]
|
||||
testparticles = [ParticleA(def_momentum), ParticleB(def_momentum), ParticleC(def_momentum)]
|
||||
|
||||
@testset "Interaction Result" begin
|
||||
for p1 in testparticleTypes, p2 in testparticleTypes
|
||||
if (p1 == p2)
|
||||
@test_throws AssertionError interaction_result(p1, p2)
|
||||
else
|
||||
@test interaction_result(p1, p2) == setdiff(testparticleTypes, [p1, p2])[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Vertex" begin
|
||||
@test isapprox(MetagraphOptimization.ABC_vertex(), 1 / 137.0)
|
||||
end
|
91
test/unit_tests_estimator.jl
Normal file
91
test/unit_tests_estimator.jl
Normal file
@ -0,0 +1,91 @@
|
||||
using MetagraphOptimization
|
||||
|
||||
function test_op_specific(estimator, graph, nf::NodeFusion)
|
||||
estimate = operation_effect(estimator, graph, nf)
|
||||
data_reduce = data(nf.input[2].task)
|
||||
|
||||
@test isapprox(estimate.data, -data_reduce)
|
||||
@test isapprox(estimate.computeEffort, 0; atol = eps(Float64))
|
||||
@test isapprox(estimate.computeIntensity, 0; atol = eps(Float64))
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
function test_op_specific(estimator, graph, nr::NodeReduction)
|
||||
estimate = operation_effect(estimator, graph, nr)
|
||||
|
||||
data_reduce = data(nr.input[1].task) * (length(nr.input) - 1)
|
||||
compute_effort_reduce = compute_effort(nr.input[1].task) * (length(nr.input) - 1)
|
||||
|
||||
@test isapprox(estimate.data, -data_reduce; atol = eps(Float64))
|
||||
@test isapprox(estimate.computeEffort, -compute_effort_reduce)
|
||||
@test isapprox(estimate.computeIntensity, compute_effort_reduce / data_reduce)
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
function test_op_specific(estimator, graph, ns::NodeSplit)
|
||||
estimate = operation_effect(estimator, graph, ns)
|
||||
|
||||
copies = length(ns.input.parents) - 1
|
||||
|
||||
data_increase = data(ns.input.task) * copies
|
||||
compute_effort_increase = compute_effort(ns.input.task) * copies
|
||||
|
||||
@test isapprox(estimate.data, data_increase; atol = eps(Float64))
|
||||
@test isapprox(estimate.computeEffort, compute_effort_increase)
|
||||
@test isapprox(estimate.computeIntensity, compute_effort_increase / data_increase)
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
function test_op(estimator, graph, op)
|
||||
estimate_before = graph_cost(estimator, graph)
|
||||
|
||||
estimate = operation_effect(estimator, graph, op)
|
||||
|
||||
push_operation!(graph, op)
|
||||
estimate_after_apply = graph_cost(estimator, graph)
|
||||
reset_graph!(graph)
|
||||
|
||||
@test isapprox((estimate_before + estimate).data, estimate_after_apply.data)
|
||||
@test isapprox((estimate_before + estimate).computeEffort, estimate_after_apply.computeEffort)
|
||||
@test isapprox((estimate_before + estimate).computeIntensity, estimate_after_apply.computeIntensity)
|
||||
|
||||
test_op_specific(estimator, graph, op)
|
||||
return nothing
|
||||
end
|
||||
|
||||
@testset "Global Metric Estimator" for (graph_string, exp_data, exp_computeEffort) in
|
||||
zip(["AB->AB", "AB->ABBB"], [976, 10944], [53, 1075])
|
||||
estimator = GlobalMetricEstimator()
|
||||
|
||||
@test cost_type(estimator) == CDCost
|
||||
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "$(graph_string).txt"), ABCModel())
|
||||
|
||||
@testset "Graph Cost" begin
|
||||
estimate = graph_cost(estimator, graph)
|
||||
|
||||
@test estimate.data == exp_data
|
||||
@test estimate.computeEffort == exp_computeEffort
|
||||
@test isapprox(estimate.computeIntensity, exp_computeEffort / exp_data)
|
||||
end
|
||||
|
||||
@testset "Operation Cost" begin
|
||||
ops = get_operations(graph)
|
||||
nfs = copy(ops.nodeFusions)
|
||||
nrs = copy(ops.nodeReductions)
|
||||
nss = copy(ops.nodeSplits)
|
||||
|
||||
for nf in nfs
|
||||
test_op(estimator, graph, nf)
|
||||
end
|
||||
for nr in nrs
|
||||
test_op(estimator, graph, nr)
|
||||
end
|
||||
for ns in nss
|
||||
test_op(estimator, graph, ns)
|
||||
end
|
||||
end
|
||||
end
|
@ -1,92 +1,135 @@
|
||||
import MetagraphOptimization.ABCParticle
|
||||
|
||||
using MetagraphOptimization
|
||||
using QEDbase
|
||||
using AccurateArithmetic
|
||||
using Random
|
||||
|
||||
include("../examples/profiling_utilities.jl")
|
||||
import MetagraphOptimization.ABCParticle
|
||||
import MetagraphOptimization.interaction_result
|
||||
|
||||
@testset "Unit Tests Execution" begin
|
||||
machine = get_machine_info()
|
||||
const RTOL = sqrt(eps(Float64))
|
||||
RNG = Random.default_rng()
|
||||
|
||||
process_2_2 = ABCProcessDescription(
|
||||
Dict{Type, Int64}(ParticleA => 1, ParticleB => 1),
|
||||
Dict{Type, Int64}(ParticleA => 1, ParticleB => 1),
|
||||
)
|
||||
function check_particle_reverse_moment(p1::SFourMomentum, p2::SFourMomentum)
|
||||
@test isapprox(abs(p1.E), abs(p2.E))
|
||||
@test isapprox(p1.px, -p2.px)
|
||||
@test isapprox(p1.py, -p2.py)
|
||||
@test isapprox(p1.pz, -p2.pz)
|
||||
return nothing
|
||||
end
|
||||
|
||||
particles_2_2 = ABCProcessInput(
|
||||
process_2_2,
|
||||
ABCParticle[
|
||||
ParticleA(SFourMomentum(0.823648, 0.0, 0.0, 0.823648)),
|
||||
ParticleB(SFourMomentum(0.823648, 0.0, 0.0, -0.823648)),
|
||||
],
|
||||
ABCParticle[
|
||||
ParticleA(SFourMomentum(0.823648, -0.835061, -0.474802, 0.277915)),
|
||||
ParticleB(SFourMomentum(0.823648, 0.835061, 0.474802, -0.277915)),
|
||||
],
|
||||
)
|
||||
expected_result = 0.00013916495566048735
|
||||
function ground_truth_graph_result(input::ABCProcessInput)
|
||||
# formula for one diagram:
|
||||
# u_Bp * iλ * u_Ap * S_C * u_B * iλ * u_A
|
||||
# for the second diagram:
|
||||
# u_B * iλ * u_Ap * S_C * u_Bp * iλ * u_Ap
|
||||
# the "u"s are all 1, we ignore the i, λ is 1/137.
|
||||
|
||||
@testset "AB->AB no optimization" begin
|
||||
for _ in 1:10 # test in a loop because graph layout should not change the result
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->AB.txt"), ABCModel())
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = 0.001)
|
||||
constant = (1 / 137.0)^2
|
||||
|
||||
# graph should be fully scheduled after being executed
|
||||
@test is_scheduled(graph)
|
||||
# calculate particle C in diagram 1
|
||||
diagram1_C = ParticleC(input.inParticles[1].momentum + input.inParticles[2].momentum)
|
||||
diagram2_C = ParticleC(input.inParticles[1].momentum + input.outParticles[2].momentum)
|
||||
|
||||
func = get_compute_function(graph, process_2_2, machine)
|
||||
@test isapprox(func(particles_2_2), expected_result; rtol = 0.001)
|
||||
end
|
||||
diagram1_Cp = ParticleC(input.outParticles[1].momentum + input.outParticles[2].momentum)
|
||||
diagram2_Cp = ParticleC(input.outParticles[1].momentum + input.inParticles[2].momentum)
|
||||
|
||||
check_particle_reverse_moment(diagram1_Cp.momentum, diagram1_C.momentum)
|
||||
check_particle_reverse_moment(diagram2_Cp.momentum, diagram2_C.momentum)
|
||||
@test isapprox(getMass2(diagram1_C.momentum), getMass2(diagram1_Cp.momentum))
|
||||
@test isapprox(getMass2(diagram2_C.momentum), getMass2(diagram2_Cp.momentum))
|
||||
|
||||
inner1 = MetagraphOptimization.ABC_inner_edge(diagram1_C)
|
||||
inner2 = MetagraphOptimization.ABC_inner_edge(diagram2_C)
|
||||
|
||||
diagram1_result = inner1 * constant
|
||||
diagram2_result = inner2 * constant
|
||||
|
||||
return sum_kbn([diagram1_result, diagram2_result])
|
||||
end
|
||||
|
||||
machine = get_machine_info()
|
||||
|
||||
process_2_2 = ABCProcessDescription(
|
||||
Dict{Type, Int64}(ParticleA => 1, ParticleB => 1),
|
||||
Dict{Type, Int64}(ParticleA => 1, ParticleB => 1),
|
||||
)
|
||||
|
||||
particles_2_2 = ABCProcessInput(
|
||||
process_2_2,
|
||||
ABCParticle[
|
||||
ParticleA(SFourMomentum(0.823648, 0.0, 0.0, 0.823648)),
|
||||
ParticleB(SFourMomentum(0.823648, 0.0, 0.0, -0.823648)),
|
||||
],
|
||||
ABCParticle[
|
||||
ParticleA(SFourMomentum(0.823648, -0.835061, -0.474802, 0.277915)),
|
||||
ParticleB(SFourMomentum(0.823648, 0.835061, 0.474802, -0.277915)),
|
||||
],
|
||||
)
|
||||
expected_result = ground_truth_graph_result(particles_2_2)
|
||||
|
||||
@testset "AB->AB no optimization" begin
|
||||
for _ in 1:10 # test in a loop because graph layout should not change the result
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->AB.txt"), ABCModel())
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = RTOL)
|
||||
|
||||
# graph should be fully scheduled after being executed
|
||||
@test is_scheduled(graph)
|
||||
|
||||
func = get_compute_function(graph, process_2_2, machine)
|
||||
@test isapprox(func(particles_2_2), expected_result; rtol = RTOL)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "AB->AB after random walk" begin
|
||||
for i in 1:1000
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->AB.txt"), ABCModel())
|
||||
random_walk!(graph, 50)
|
||||
@testset "AB->AB after random walk" begin
|
||||
for i in 1:200
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->AB.txt"), ABCModel())
|
||||
optimize!(RandomWalkOptimizer(RNG), graph, 50)
|
||||
|
||||
@test is_valid(graph)
|
||||
@test is_valid(graph)
|
||||
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = 0.001)
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = RTOL)
|
||||
|
||||
# graph should be fully scheduled after being executed
|
||||
@test is_scheduled(graph)
|
||||
end
|
||||
# graph should be fully scheduled after being executed
|
||||
@test is_scheduled(graph)
|
||||
end
|
||||
end
|
||||
|
||||
process_2_4 = ABCProcessDescription(
|
||||
Dict{Type, Int64}(ParticleA => 1, ParticleB => 1),
|
||||
Dict{Type, Int64}(ParticleA => 1, ParticleB => 3),
|
||||
)
|
||||
particles_2_4 = gen_process_input(process_2_4)
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
|
||||
expected_result = execute(graph, process_2_4, machine, particles_2_4)
|
||||
process_2_4 = ABCProcessDescription(
|
||||
Dict{Type, Int64}(ParticleA => 1, ParticleB => 1),
|
||||
Dict{Type, Int64}(ParticleA => 1, ParticleB => 3),
|
||||
)
|
||||
particles_2_4 = gen_process_input(process_2_4)
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
|
||||
expected_result = execute(graph, process_2_4, machine, particles_2_4)
|
||||
|
||||
@testset "AB->ABBB no optimization" begin
|
||||
for _ in 1:5 # test in a loop because graph layout should not change the result
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
|
||||
@test isapprox(execute(graph, process_2_4, machine, particles_2_4), expected_result; rtol = 0.001)
|
||||
@testset "AB->ABBB no optimization" begin
|
||||
for _ in 1:5 # test in a loop because graph layout should not change the result
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
|
||||
@test isapprox(execute(graph, process_2_4, machine, particles_2_4), expected_result; rtol = RTOL)
|
||||
|
||||
func = get_compute_function(graph, process_2_4, machine)
|
||||
@test isapprox(func(particles_2_4), expected_result; rtol = 0.001)
|
||||
end
|
||||
func = get_compute_function(graph, process_2_4, machine)
|
||||
@test isapprox(func(particles_2_4), expected_result; rtol = RTOL)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "AB->ABBB after random walk" begin
|
||||
for i in 1:200
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
|
||||
random_walk!(graph, 100)
|
||||
@test is_valid(graph)
|
||||
@testset "AB->ABBB after random walk" begin
|
||||
for i in 1:50
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
|
||||
optimize!(RandomWalkOptimizer(RNG), graph, 100)
|
||||
@test is_valid(graph)
|
||||
|
||||
@test isapprox(execute(graph, process_2_4, machine, particles_2_4), expected_result; rtol = 0.001)
|
||||
end
|
||||
@test isapprox(execute(graph, process_2_4, machine, particles_2_4), expected_result; rtol = RTOL)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "AB->AB large sum fusion" for _ in 1:20
|
||||
@testset "AB->AB large sum fusion" begin
|
||||
for _ in 1:20
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->AB.txt"), ABCModel())
|
||||
|
||||
# push a fusion with the sum node
|
||||
ops = get_operations(graph)
|
||||
for fusion in ops.nodeFusions
|
||||
if isa(fusion.input[3].task, ComputeTaskSum)
|
||||
if isa(fusion.input[3].task, ComputeTaskABC_Sum)
|
||||
push_operation!(graph, fusion)
|
||||
break
|
||||
end
|
||||
@ -105,18 +148,20 @@ include("../examples/profiling_utilities.jl")
|
||||
|
||||
# try execute
|
||||
@test is_valid(graph)
|
||||
expected_result = 0.00013916495566048735
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = 0.001)
|
||||
expected_result = ground_truth_graph_result(particles_2_2)
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = RTOL)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@testset "AB->AB large sum fusion" for _ in 1:20
|
||||
@testset "AB->AB large sum fusion" begin
|
||||
for _ in 1:20
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->AB.txt"), ABCModel())
|
||||
|
||||
# push a fusion with the sum node
|
||||
ops = get_operations(graph)
|
||||
for fusion in ops.nodeFusions
|
||||
if isa(fusion.input[3].task, ComputeTaskSum)
|
||||
if isa(fusion.input[3].task, ComputeTaskABC_Sum)
|
||||
push_operation!(graph, fusion)
|
||||
break
|
||||
end
|
||||
@ -135,18 +180,20 @@ include("../examples/profiling_utilities.jl")
|
||||
|
||||
# try execute
|
||||
@test is_valid(graph)
|
||||
expected_result = 0.00013916495566048735
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = 0.001)
|
||||
expected_result = ground_truth_graph_result(particles_2_2)
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = RTOL)
|
||||
end
|
||||
end
|
||||
|
||||
@testset "AB->AB fusion edge case" for _ in 1:20
|
||||
@testset "AB->AB fusion edge case" begin
|
||||
for _ in 1:20
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->AB.txt"), ABCModel())
|
||||
|
||||
# push two fusions with ComputeTaskV
|
||||
# push two fusions with ComputeTaskABC_V
|
||||
for _ in 1:2
|
||||
ops = get_operations(graph)
|
||||
for fusion in ops.nodeFusions
|
||||
if isa(fusion.input[1].task, ComputeTaskV)
|
||||
if isa(fusion.input[1].task, ComputeTaskABC_V)
|
||||
push_operation!(graph, fusion)
|
||||
break
|
||||
end
|
||||
@ -169,9 +216,7 @@ include("../examples/profiling_utilities.jl")
|
||||
|
||||
# try execute
|
||||
@test is_valid(graph)
|
||||
expected_result = 0.00013916495566048735
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = 0.001)
|
||||
expected_result = ground_truth_graph_result(particles_2_2)
|
||||
@test isapprox(execute(graph, process_2_2, machine, particles_2_2), expected_result; rtol = RTOL)
|
||||
end
|
||||
|
||||
end
|
||||
println("Execution Unit Tests Complete!")
|
||||
|
@ -1,212 +1,213 @@
|
||||
using MetagraphOptimization
|
||||
|
||||
import MetagraphOptimization.insert_node!
|
||||
import MetagraphOptimization.insert_edge!
|
||||
import MetagraphOptimization.make_node
|
||||
import MetagraphOptimization.siblings
|
||||
import MetagraphOptimization.partners
|
||||
|
||||
@testset "Unit Tests Graph" begin
|
||||
graph = MetagraphOptimization.DAG()
|
||||
graph = MetagraphOptimization.DAG()
|
||||
|
||||
@test length(graph.nodes) == 0
|
||||
@test length(graph.appliedOperations) == 0
|
||||
@test length(graph.operationsToApply) == 0
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
@test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0)
|
||||
@test length(get_operations(graph)) == (nodeFusions = 0, nodeReductions = 0, nodeSplits = 0)
|
||||
@test length(graph.nodes) == 0
|
||||
@test length(graph.appliedOperations) == 0
|
||||
@test length(graph.operationsToApply) == 0
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
@test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0)
|
||||
@test length(get_operations(graph)) == (nodeFusions = 0, nodeReductions = 0, nodeSplits = 0)
|
||||
|
||||
# s to output (exit node)
|
||||
d_exit = insert_node!(graph, make_node(DataTask(10)), track = false)
|
||||
# s to output (exit node)
|
||||
d_exit = insert_node!(graph, make_node(DataTask(10)), track = false)
|
||||
|
||||
@test length(graph.nodes) == 1
|
||||
@test length(graph.dirtyNodes) == 1
|
||||
@test length(graph.nodes) == 1
|
||||
@test length(graph.dirtyNodes) == 1
|
||||
|
||||
# final s compute
|
||||
s0 = insert_node!(graph, make_node(ComputeTaskS2()), track = false)
|
||||
# final s compute
|
||||
s0 = insert_node!(graph, make_node(ComputeTaskABC_S2()), track = false)
|
||||
|
||||
@test length(graph.nodes) == 2
|
||||
@test length(graph.dirtyNodes) == 2
|
||||
@test length(graph.nodes) == 2
|
||||
@test length(graph.dirtyNodes) == 2
|
||||
|
||||
# data from v0 and v1 to s0
|
||||
d_v0_s0 = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
d_v1_s0 = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
# data from v0 and v1 to s0
|
||||
d_v0_s0 = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
d_v1_s0 = insert_node!(graph, make_node(DataTask(5)), track = false)
|
||||
|
||||
# v0 and v1 compute
|
||||
v0 = insert_node!(graph, make_node(ComputeTaskV()), track = false)
|
||||
v1 = insert_node!(graph, make_node(ComputeTaskV()), track = false)
|
||||
# v0 and v1 compute
|
||||
v0 = insert_node!(graph, make_node(ComputeTaskABC_V()), track = false)
|
||||
v1 = insert_node!(graph, make_node(ComputeTaskABC_V()), track = false)
|
||||
|
||||
# data from uB, uA, uBp and uAp to v0 and v1
|
||||
d_uB_v0 = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
d_uA_v0 = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
d_uBp_v1 = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
d_uAp_v1 = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
# data from uB, uA, uBp and uAp to v0 and v1
|
||||
d_uB_v0 = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
d_uA_v0 = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
d_uBp_v1 = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
d_uAp_v1 = insert_node!(graph, make_node(DataTask(3)), track = false)
|
||||
|
||||
# uB, uA, uBp and uAp computes
|
||||
uB = insert_node!(graph, make_node(ComputeTaskU()), track = false)
|
||||
uA = insert_node!(graph, make_node(ComputeTaskU()), track = false)
|
||||
uBp = insert_node!(graph, make_node(ComputeTaskU()), track = false)
|
||||
uAp = insert_node!(graph, make_node(ComputeTaskU()), track = false)
|
||||
# uB, uA, uBp and uAp computes
|
||||
uB = insert_node!(graph, make_node(ComputeTaskABC_U()), track = false)
|
||||
uA = insert_node!(graph, make_node(ComputeTaskABC_U()), track = false)
|
||||
uBp = insert_node!(graph, make_node(ComputeTaskABC_U()), track = false)
|
||||
uAp = insert_node!(graph, make_node(ComputeTaskABC_U()), track = false)
|
||||
|
||||
# data from PB, PA, PBp and PAp to uB, uA, uBp and uAp
|
||||
d_PB_uB = insert_node!(graph, make_node(DataTask(6)), track = false)
|
||||
d_PA_uA = insert_node!(graph, make_node(DataTask(6)), track = false)
|
||||
d_PBp_uBp = insert_node!(graph, make_node(DataTask(6)), track = false)
|
||||
d_PAp_uAp = insert_node!(graph, make_node(DataTask(6)), track = false)
|
||||
# data from PB, PA, PBp and PAp to uB, uA, uBp and uAp
|
||||
d_PB_uB = insert_node!(graph, make_node(DataTask(6)), track = false)
|
||||
d_PA_uA = insert_node!(graph, make_node(DataTask(6)), track = false)
|
||||
d_PBp_uBp = insert_node!(graph, make_node(DataTask(6)), track = false)
|
||||
d_PAp_uAp = insert_node!(graph, make_node(DataTask(6)), track = false)
|
||||
|
||||
# P computes PB, PA, PBp and PAp
|
||||
PB = insert_node!(graph, make_node(ComputeTaskP()), track = false)
|
||||
PA = insert_node!(graph, make_node(ComputeTaskP()), track = false)
|
||||
PBp = insert_node!(graph, make_node(ComputeTaskP()), track = false)
|
||||
PAp = insert_node!(graph, make_node(ComputeTaskP()), track = false)
|
||||
# P computes PB, PA, PBp and PAp
|
||||
PB = insert_node!(graph, make_node(ComputeTaskABC_P()), track = false)
|
||||
PA = insert_node!(graph, make_node(ComputeTaskABC_P()), track = false)
|
||||
PBp = insert_node!(graph, make_node(ComputeTaskABC_P()), track = false)
|
||||
PAp = insert_node!(graph, make_node(ComputeTaskABC_P()), track = false)
|
||||
|
||||
# entry nodes getting data for P computes
|
||||
d_PB = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
d_PA = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
d_PBp = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
d_PAp = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
# entry nodes getting data for P computes
|
||||
d_PB = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
d_PA = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
d_PBp = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
d_PAp = insert_node!(graph, make_node(DataTask(4)), track = false)
|
||||
|
||||
@test length(graph.nodes) == 26
|
||||
@test length(graph.dirtyNodes) == 26
|
||||
@test length(graph.nodes) == 26
|
||||
@test length(graph.dirtyNodes) == 26
|
||||
|
||||
# now for all the edges
|
||||
insert_edge!(graph, d_PB, PB, track = false)
|
||||
insert_edge!(graph, d_PA, PA, track = false)
|
||||
insert_edge!(graph, d_PBp, PBp, track = false)
|
||||
insert_edge!(graph, d_PAp, PAp, track = false)
|
||||
# now for all the edges
|
||||
insert_edge!(graph, d_PB, PB, track = false)
|
||||
insert_edge!(graph, d_PA, PA, track = false)
|
||||
insert_edge!(graph, d_PBp, PBp, track = false)
|
||||
insert_edge!(graph, d_PAp, PAp, track = false)
|
||||
|
||||
insert_edge!(graph, PB, d_PB_uB, track = false)
|
||||
insert_edge!(graph, PA, d_PA_uA, track = false)
|
||||
insert_edge!(graph, PBp, d_PBp_uBp, track = false)
|
||||
insert_edge!(graph, PAp, d_PAp_uAp, track = false)
|
||||
insert_edge!(graph, PB, d_PB_uB, track = false)
|
||||
insert_edge!(graph, PA, d_PA_uA, track = false)
|
||||
insert_edge!(graph, PBp, d_PBp_uBp, track = false)
|
||||
insert_edge!(graph, PAp, d_PAp_uAp, track = false)
|
||||
|
||||
insert_edge!(graph, d_PB_uB, uB, track = false)
|
||||
insert_edge!(graph, d_PA_uA, uA, track = false)
|
||||
insert_edge!(graph, d_PBp_uBp, uBp, track = false)
|
||||
insert_edge!(graph, d_PAp_uAp, uAp, track = false)
|
||||
insert_edge!(graph, d_PB_uB, uB, track = false)
|
||||
insert_edge!(graph, d_PA_uA, uA, track = false)
|
||||
insert_edge!(graph, d_PBp_uBp, uBp, track = false)
|
||||
insert_edge!(graph, d_PAp_uAp, uAp, track = false)
|
||||
|
||||
insert_edge!(graph, uB, d_uB_v0, track = false)
|
||||
insert_edge!(graph, uA, d_uA_v0, track = false)
|
||||
insert_edge!(graph, uBp, d_uBp_v1, track = false)
|
||||
insert_edge!(graph, uAp, d_uAp_v1, track = false)
|
||||
insert_edge!(graph, uB, d_uB_v0, track = false)
|
||||
insert_edge!(graph, uA, d_uA_v0, track = false)
|
||||
insert_edge!(graph, uBp, d_uBp_v1, track = false)
|
||||
insert_edge!(graph, uAp, d_uAp_v1, track = false)
|
||||
|
||||
insert_edge!(graph, d_uB_v0, v0, track = false)
|
||||
insert_edge!(graph, d_uA_v0, v0, track = false)
|
||||
insert_edge!(graph, d_uBp_v1, v1, track = false)
|
||||
insert_edge!(graph, d_uAp_v1, v1, track = false)
|
||||
insert_edge!(graph, d_uB_v0, v0, track = false)
|
||||
insert_edge!(graph, d_uA_v0, v0, track = false)
|
||||
insert_edge!(graph, d_uBp_v1, v1, track = false)
|
||||
insert_edge!(graph, d_uAp_v1, v1, track = false)
|
||||
|
||||
insert_edge!(graph, v0, d_v0_s0, track = false)
|
||||
insert_edge!(graph, v1, d_v1_s0, track = false)
|
||||
insert_edge!(graph, v0, d_v0_s0, track = false)
|
||||
insert_edge!(graph, v1, d_v1_s0, track = false)
|
||||
|
||||
insert_edge!(graph, d_v0_s0, s0, track = false)
|
||||
insert_edge!(graph, d_v1_s0, s0, track = false)
|
||||
insert_edge!(graph, d_v0_s0, s0, track = false)
|
||||
insert_edge!(graph, d_v1_s0, s0, track = false)
|
||||
|
||||
insert_edge!(graph, s0, d_exit, track = false)
|
||||
insert_edge!(graph, s0, d_exit, track = false)
|
||||
|
||||
@test length(graph.nodes) == 26
|
||||
@test length(graph.appliedOperations) == 0
|
||||
@test length(graph.operationsToApply) == 0
|
||||
@test length(graph.dirtyNodes) == 26
|
||||
@test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0)
|
||||
@test length(graph.nodes) == 26
|
||||
@test length(graph.appliedOperations) == 0
|
||||
@test length(graph.operationsToApply) == 0
|
||||
@test length(graph.dirtyNodes) == 26
|
||||
@test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0)
|
||||
|
||||
@test is_valid(graph)
|
||||
@test is_valid(graph)
|
||||
|
||||
@test is_entry_node(d_PB)
|
||||
@test is_entry_node(d_PA)
|
||||
@test is_entry_node(d_PBp)
|
||||
@test is_entry_node(d_PBp)
|
||||
@test !is_entry_node(PB)
|
||||
@test !is_entry_node(v0)
|
||||
@test !is_entry_node(d_exit)
|
||||
@test is_entry_node(d_PB)
|
||||
@test is_entry_node(d_PA)
|
||||
@test is_entry_node(d_PBp)
|
||||
@test is_entry_node(d_PBp)
|
||||
@test !is_entry_node(PB)
|
||||
@test !is_entry_node(v0)
|
||||
@test !is_entry_node(d_exit)
|
||||
|
||||
@test is_exit_node(d_exit)
|
||||
@test !is_exit_node(d_uB_v0)
|
||||
@test !is_exit_node(v0)
|
||||
@test is_exit_node(d_exit)
|
||||
@test !is_exit_node(d_uB_v0)
|
||||
@test !is_exit_node(v0)
|
||||
|
||||
@test length(children(v0)) == 2
|
||||
@test length(children(v1)) == 2
|
||||
@test length(parents(v0)) == 1
|
||||
@test length(parents(v1)) == 1
|
||||
@test length(children(v0)) == 2
|
||||
@test length(children(v1)) == 2
|
||||
@test length(parents(v0)) == 1
|
||||
@test length(parents(v1)) == 1
|
||||
|
||||
@test MetagraphOptimization.get_exit_node(graph) == d_exit
|
||||
@test MetagraphOptimization.get_exit_node(graph) == d_exit
|
||||
|
||||
@test length(partners(s0)) == 1
|
||||
@test length(siblings(s0)) == 1
|
||||
@test length(partners(s0)) == 1
|
||||
@test length(siblings(s0)) == 1
|
||||
|
||||
operations = get_operations(graph)
|
||||
@test length(operations) == (nodeFusions = 10, nodeReductions = 0, nodeSplits = 0)
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
operations = get_operations(graph)
|
||||
@test length(operations) == (nodeFusions = 10, nodeReductions = 0, nodeSplits = 0)
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
|
||||
@test operations == get_operations(graph)
|
||||
nf = first(operations.nodeFusions)
|
||||
@test sum(length(operations)) == 10
|
||||
|
||||
properties = get_properties(graph)
|
||||
@test properties.computeEffort == 28
|
||||
@test properties.data == 62
|
||||
@test properties.computeIntensity ≈ 28 / 62
|
||||
@test properties.noNodes == 26
|
||||
@test properties.noEdges == 25
|
||||
@test operations == get_operations(graph)
|
||||
nf = first(operations.nodeFusions)
|
||||
|
||||
push_operation!(graph, nf)
|
||||
# **does not immediately apply the operation**
|
||||
properties = get_properties(graph)
|
||||
@test properties.computeEffort == 28
|
||||
@test properties.data == 62
|
||||
@test properties.computeIntensity ≈ 28 / 62
|
||||
@test properties.noNodes == 26
|
||||
@test properties.noEdges == 25
|
||||
|
||||
@test length(graph.nodes) == 26
|
||||
@test length(graph.appliedOperations) == 0
|
||||
@test length(graph.operationsToApply) == 1
|
||||
@test first(graph.operationsToApply) == nf
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
@test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0)
|
||||
push_operation!(graph, nf)
|
||||
# **does not immediately apply the operation**
|
||||
|
||||
# this applies pending operations
|
||||
properties = get_properties(graph)
|
||||
@test length(graph.nodes) == 26
|
||||
@test length(graph.appliedOperations) == 0
|
||||
@test length(graph.operationsToApply) == 1
|
||||
@test first(graph.operationsToApply) == nf
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
@test length(graph.diff) == (addedNodes = 0, removedNodes = 0, addedEdges = 0, removedEdges = 0)
|
||||
|
||||
@test length(graph.nodes) == 24
|
||||
@test length(graph.appliedOperations) == 1
|
||||
@test length(graph.operationsToApply) == 0
|
||||
@test length(graph.dirtyNodes) != 0
|
||||
@test properties.noNodes == 24
|
||||
@test properties.noEdges == 23
|
||||
@test properties.computeEffort == 28
|
||||
@test properties.data < 62
|
||||
@test properties.computeIntensity > 28 / 62
|
||||
# this applies pending operations
|
||||
properties = get_properties(graph)
|
||||
|
||||
operations = get_operations(graph)
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
@test length(graph.nodes) == 24
|
||||
@test length(graph.appliedOperations) == 1
|
||||
@test length(graph.operationsToApply) == 0
|
||||
@test length(graph.dirtyNodes) != 0
|
||||
@test properties.noNodes == 24
|
||||
@test properties.noEdges == 23
|
||||
@test properties.computeEffort == 28
|
||||
@test properties.data < 62
|
||||
@test properties.computeIntensity > 28 / 62
|
||||
|
||||
@test length(operations) == (nodeFusions = 9, nodeReductions = 0, nodeSplits = 0)
|
||||
@test !isempty(operations)
|
||||
operations = get_operations(graph)
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
|
||||
possibleNF = 9
|
||||
while !isempty(operations.nodeFusions)
|
||||
push_operation!(graph, first(operations.nodeFusions))
|
||||
operations = get_operations(graph)
|
||||
possibleNF = possibleNF - 1
|
||||
@test length(operations) == (nodeFusions = possibleNF, nodeReductions = 0, nodeSplits = 0)
|
||||
end
|
||||
@test length(operations) == (nodeFusions = 9, nodeReductions = 0, nodeSplits = 0)
|
||||
@test !isempty(operations)
|
||||
|
||||
@test isempty(operations)
|
||||
|
||||
@test length(operations) == (nodeFusions = 0, nodeReductions = 0, nodeSplits = 0)
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
@test length(graph.nodes) == 6
|
||||
@test length(graph.appliedOperations) == 10
|
||||
@test length(graph.operationsToApply) == 0
|
||||
|
||||
reset_graph!(graph)
|
||||
|
||||
@test length(graph.dirtyNodes) == 26
|
||||
@test length(graph.nodes) == 26
|
||||
@test length(graph.appliedOperations) == 0
|
||||
@test length(graph.operationsToApply) == 0
|
||||
|
||||
properties = get_properties(graph)
|
||||
@test properties.noNodes == 26
|
||||
@test properties.noEdges == 25
|
||||
@test properties.computeEffort == 28
|
||||
@test properties.data == 62
|
||||
@test properties.computeIntensity ≈ 28 / 62
|
||||
|
||||
operations = get_operations(graph)
|
||||
@test length(operations) == (nodeFusions = 10, nodeReductions = 0, nodeSplits = 0)
|
||||
|
||||
@test is_valid(graph)
|
||||
possibleNF = 9
|
||||
while !isempty(operations.nodeFusions)
|
||||
push_operation!(graph, first(operations.nodeFusions))
|
||||
global operations = get_operations(graph)
|
||||
global possibleNF = possibleNF - 1
|
||||
@test length(operations) == (nodeFusions = possibleNF, nodeReductions = 0, nodeSplits = 0)
|
||||
end
|
||||
println("Graph Unit Tests Complete!")
|
||||
|
||||
@test isempty(operations)
|
||||
|
||||
@test length(operations) == (nodeFusions = 0, nodeReductions = 0, nodeSplits = 0)
|
||||
@test length(graph.dirtyNodes) == 0
|
||||
@test length(graph.nodes) == 6
|
||||
@test length(graph.appliedOperations) == 10
|
||||
@test length(graph.operationsToApply) == 0
|
||||
|
||||
reset_graph!(graph)
|
||||
|
||||
@test length(graph.dirtyNodes) == 26
|
||||
@test length(graph.nodes) == 26
|
||||
@test length(graph.appliedOperations) == 0
|
||||
@test length(graph.operationsToApply) == 0
|
||||
|
||||
properties = get_properties(graph)
|
||||
@test properties.noNodes == 26
|
||||
@test properties.noEdges == 25
|
||||
@test properties.computeEffort == 28
|
||||
@test properties.data == 62
|
||||
@test properties.computeIntensity ≈ 28 / 62
|
||||
|
||||
operations = get_operations(graph)
|
||||
@test length(operations) == (nodeFusions = 10, nodeReductions = 0, nodeSplits = 0)
|
||||
|
||||
@test is_valid(graph)
|
||||
|
@ -1,36 +1,34 @@
|
||||
using MetagraphOptimization
|
||||
|
||||
@testset "Unit Tests Nodes" begin
|
||||
nC1 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskU())
|
||||
nC2 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskV())
|
||||
nC3 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskP())
|
||||
nC4 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskSum())
|
||||
nC1 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskABC_U())
|
||||
nC2 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskABC_V())
|
||||
nC3 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskABC_P())
|
||||
nC4 = MetagraphOptimization.make_node(MetagraphOptimization.ComputeTaskABC_Sum())
|
||||
|
||||
nD1 = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(10))
|
||||
nD2 = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(20))
|
||||
nD1 = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(10))
|
||||
nD2 = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(20))
|
||||
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nC1, nC2)
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nC1, nC1)
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nC3, nC4)
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nD1, nD2)
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nD1, nD1)
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nC1, nC2)
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nC1, nC1)
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nC3, nC4)
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nD1, nD2)
|
||||
@test_throws ErrorException MetagraphOptimization.make_edge(nD1, nD1)
|
||||
|
||||
ed1 = MetagraphOptimization.make_edge(nC1, nD1)
|
||||
ed2 = MetagraphOptimization.make_edge(nD1, nC2)
|
||||
ed3 = MetagraphOptimization.make_edge(nC2, nD2)
|
||||
ed4 = MetagraphOptimization.make_edge(nD2, nC3)
|
||||
ed1 = MetagraphOptimization.make_edge(nC1, nD1)
|
||||
ed2 = MetagraphOptimization.make_edge(nD1, nC2)
|
||||
ed3 = MetagraphOptimization.make_edge(nC2, nD2)
|
||||
ed4 = MetagraphOptimization.make_edge(nD2, nC3)
|
||||
|
||||
@test nC1 != nC2
|
||||
@test nD1 != nD2
|
||||
@test nC1 != nD1
|
||||
@test nC3 != nC4
|
||||
@test nC1 != nC2
|
||||
@test nD1 != nD2
|
||||
@test nC1 != nD1
|
||||
@test nC3 != nC4
|
||||
|
||||
nC1_2 = copy(nC1)
|
||||
@test nC1_2 != nC1
|
||||
nC1_2 = copy(nC1)
|
||||
@test nC1_2 != nC1
|
||||
|
||||
nD1_2 = copy(nD1)
|
||||
@test nD1_2 != nD1
|
||||
nD1_2 = copy(nD1)
|
||||
@test nD1_2 != nD1
|
||||
|
||||
nD1_c = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(10))
|
||||
@test nD1_c != nD1
|
||||
end
|
||||
println("Node Unit Tests Complete!")
|
||||
nD1_c = MetagraphOptimization.make_node(MetagraphOptimization.DataTask(10))
|
||||
@test nD1_c != nD1
|
||||
|
40
test/unit_tests_optimization.jl
Normal file
40
test/unit_tests_optimization.jl
Normal file
@ -0,0 +1,40 @@
|
||||
using MetagraphOptimization
|
||||
using Random
|
||||
|
||||
RNG = Random.default_rng()
|
||||
|
||||
graph = parse_dag(joinpath(@__DIR__, "..", "input", "AB->ABBB.txt"), ABCModel())
|
||||
|
||||
# create the optimizers
|
||||
FIXPOINT_OPTIMIZERS = [GreedyOptimizer(GlobalMetricEstimator()), ReductionOptimizer()]
|
||||
NO_FIXPOINT_OPTIMIZERS = [RandomWalkOptimizer(RNG)]
|
||||
|
||||
@testset "Optimizer $optimizer" for optimizer in vcat(NO_FIXPOINT_OPTIMIZERS, FIXPOINT_OPTIMIZERS)
|
||||
@test operation_stack_length(graph) == 0
|
||||
@test optimize_step!(optimizer, graph)
|
||||
|
||||
@test !fixpoint_reached(optimizer, graph)
|
||||
@test operation_stack_length(graph) == 1
|
||||
|
||||
@test optimize!(optimizer, graph, 10)
|
||||
|
||||
@test !fixpoint_reached(optimizer, graph)
|
||||
|
||||
reset_graph!(graph)
|
||||
end
|
||||
|
||||
@testset "Fixpoint optimizer $optimizer" for optimizer in FIXPOINT_OPTIMIZERS
|
||||
@test operation_stack_length(graph) == 0
|
||||
|
||||
optimize_to_fixpoint!(optimizer, graph)
|
||||
|
||||
@test fixpoint_reached(optimizer, graph)
|
||||
@test !optimize_step!(optimizer, graph)
|
||||
@test !optimize!(optimizer, graph, 10)
|
||||
|
||||
reset_graph!(graph)
|
||||
end
|
||||
|
||||
@testset "No fixpoint optimizer $optimizer" for optimizer in NO_FIXPOINT_OPTIMIZERS
|
||||
@test_throws MethodError optimize_to_fixpoint!(optimizer, graph)
|
||||
end
|
@ -1,52 +1,33 @@
|
||||
using MetagraphOptimization
|
||||
|
||||
@testset "GraphProperties Unit Tests" begin
|
||||
prop = GraphProperties()
|
||||
prop = GraphProperties()
|
||||
|
||||
@test prop.data == 0.0
|
||||
@test prop.computeEffort == 0.0
|
||||
@test prop.computeIntensity == 0.0
|
||||
@test prop.cost == 0.0
|
||||
@test prop.noNodes == 0.0
|
||||
@test prop.noEdges == 0.0
|
||||
@test prop.data == 0.0
|
||||
@test prop.computeEffort == 0.0
|
||||
@test prop.computeIntensity == 0.0
|
||||
@test prop.noNodes == 0.0
|
||||
@test prop.noEdges == 0.0
|
||||
|
||||
prop2 = (
|
||||
data = 5.0,
|
||||
computeEffort = 6.0,
|
||||
computeIntensity = 6.0 / 5.0,
|
||||
cost = 0.0,
|
||||
noNodes = 2,
|
||||
noEdges = 3,
|
||||
)::GraphProperties
|
||||
prop2 = (data = 5.0, computeEffort = 6.0, computeIntensity = 6.0 / 5.0, noNodes = 2, noEdges = 3)::GraphProperties
|
||||
|
||||
@test prop + prop2 == prop2
|
||||
@test prop2 - prop == prop2
|
||||
@test prop + prop2 == prop2
|
||||
@test prop2 - prop == prop2
|
||||
|
||||
negProp = -prop2
|
||||
@test negProp.data == -5.0
|
||||
@test negProp.computeEffort == -6.0
|
||||
@test negProp.computeIntensity == 6.0 / 5.0
|
||||
@test negProp.cost == 0.0
|
||||
@test negProp.noNodes == -2
|
||||
@test negProp.noEdges == -3
|
||||
negProp = -prop2
|
||||
@test negProp.data == -5.0
|
||||
@test negProp.computeEffort == -6.0
|
||||
@test negProp.computeIntensity == 6.0 / 5.0
|
||||
@test negProp.noNodes == -2
|
||||
@test negProp.noEdges == -3
|
||||
|
||||
@test negProp + prop2 == GraphProperties()
|
||||
@test negProp + prop2 == GraphProperties()
|
||||
|
||||
prop3 = (
|
||||
data = 7.0,
|
||||
computeEffort = 3.0,
|
||||
computeIntensity = 7.0 / 3.0,
|
||||
cost = 0.0,
|
||||
noNodes = -3,
|
||||
noEdges = 2,
|
||||
)::GraphProperties
|
||||
prop3 = (data = 7.0, computeEffort = 3.0, computeIntensity = 7.0 / 3.0, noNodes = -3, noEdges = 2)::GraphProperties
|
||||
|
||||
propSum = prop2 + prop3
|
||||
propSum = prop2 + prop3
|
||||
|
||||
@test propSum.data == 12.0
|
||||
@test propSum.computeEffort == 9.0
|
||||
@test propSum.computeIntensity == 9.0 / 12.0
|
||||
@test propSum.cost == 0.0
|
||||
@test propSum.noNodes == -1
|
||||
@test propSum.noEdges == 5
|
||||
end
|
||||
println("GraphProperties Unit Tests Complete!")
|
||||
@test propSum.data == 12.0
|
||||
@test propSum.computeEffort == 9.0
|
||||
@test propSum.computeIntensity == 9.0 / 12.0
|
||||
@test propSum.noNodes == -1
|
||||
@test propSum.noEdges == 5
|
||||
|
47
test/unit_tests_qed_diagrams.jl
Normal file
47
test/unit_tests_qed_diagrams.jl
Normal file
@ -0,0 +1,47 @@
|
||||
using MetagraphOptimization
|
||||
|
||||
import MetagraphOptimization.gen_diagrams
|
||||
import MetagraphOptimization.isincoming
|
||||
import MetagraphOptimization.types
|
||||
|
||||
|
||||
model = QEDModel()
|
||||
compton = ("Compton Scattering", parse_process("ke->ke", model), 2)
|
||||
compton_3 = ("3-Photon Compton Scattering", parse_process("kkke->ke", QEDModel()), 24)
|
||||
compton_4 = ("4-Photon Compton Scattering", parse_process("kkkke->ke", QEDModel()), 120)
|
||||
bhabha = ("Bhabha Scattering", parse_process("ep->ep", model), 2)
|
||||
moller = ("Møller Scattering", parse_process("ee->ee", model), 2)
|
||||
pair_production = ("Pair production", parse_process("kk->ep", model), 2)
|
||||
pair_annihilation = ("Pair annihilation", parse_process("ep->kk", model), 2)
|
||||
trident = ("Trident", parse_process("ke->epe", model), 8)
|
||||
|
||||
@testset "Known Processes" begin
|
||||
@testset "$name" for (name, process, n) in
|
||||
[compton, bhabha, moller, pair_production, pair_annihilation, trident, compton_3, compton_4]
|
||||
initial_diagram = FeynmanDiagram(process)
|
||||
|
||||
n_particles = 0
|
||||
for type in types(model)
|
||||
if (isincoming(type))
|
||||
n_particles += get(process.inParticles, type, 0)
|
||||
else
|
||||
n_particles += get(process.outParticles, type, 0)
|
||||
end
|
||||
end
|
||||
@test n_particles == length(initial_diagram.particles)
|
||||
@test ismissing(initial_diagram.tie[])
|
||||
@test isempty(initial_diagram.vertices)
|
||||
|
||||
result_diagrams = gen_diagrams(initial_diagram)
|
||||
@test length(result_diagrams) == n
|
||||
|
||||
for d in result_diagrams
|
||||
n_vertices = 0
|
||||
for vs in d.vertices
|
||||
n_vertices += length(vs)
|
||||
end
|
||||
@test n_vertices == n_particles - 2
|
||||
@test !ismissing(d.tie[])
|
||||
end
|
||||
end
|
||||
end
|
291
test/unit_tests_qedmodel.jl
Normal file
291
test/unit_tests_qedmodel.jl
Normal file
@ -0,0 +1,291 @@
|
||||
using MetagraphOptimization
|
||||
using QEDbase
|
||||
using QEDprocesses
|
||||
using StatsBase # for countmap
|
||||
using Random
|
||||
|
||||
import MetagraphOptimization.caninteract
|
||||
import MetagraphOptimization.issame
|
||||
import MetagraphOptimization.interaction_result
|
||||
import MetagraphOptimization.propagation_result
|
||||
import MetagraphOptimization.direction
|
||||
import MetagraphOptimization.spin_or_pol
|
||||
import MetagraphOptimization.QED_vertex
|
||||
|
||||
def_momentum = SFourMomentum(1.0, 0.0, 0.0, 0.0)
|
||||
|
||||
RNG = Random.default_rng()
|
||||
|
||||
testparticleTypes = [
|
||||
PhotonStateful{Incoming},
|
||||
PhotonStateful{Outgoing},
|
||||
FermionStateful{Incoming},
|
||||
FermionStateful{Outgoing},
|
||||
AntiFermionStateful{Incoming},
|
||||
AntiFermionStateful{Outgoing},
|
||||
]
|
||||
|
||||
testparticleTypesPropagated = [
|
||||
PhotonStateful{Outgoing},
|
||||
PhotonStateful{Incoming},
|
||||
FermionStateful{Outgoing},
|
||||
FermionStateful{Incoming},
|
||||
AntiFermionStateful{Outgoing},
|
||||
AntiFermionStateful{Incoming},
|
||||
]
|
||||
|
||||
function compton_groundtruth(input::QEDProcessInput)
|
||||
# p1k1 -> p2k2
|
||||
# formula: −(ie)^2 (u(p2) slashed(ε1) S(p2 − k1) slashed(ε2) u(p1) + u(p2) slashed(ε2) S(p1 + k1) slashed(ε1) u(p1))
|
||||
|
||||
p1 = input.inParticles[findfirst(x -> typeof(x) <: FermionStateful, input.inParticles)]
|
||||
p2 = input.outParticles[findfirst(x -> typeof(x) <: FermionStateful, input.outParticles)]
|
||||
|
||||
k1 = input.inParticles[findfirst(x -> typeof(x) <: PhotonStateful, input.inParticles)]
|
||||
k2 = input.outParticles[findfirst(x -> typeof(x) <: PhotonStateful, input.outParticles)]
|
||||
|
||||
u_p1 = base_state(Electron(), Incoming(), p1.momentum, spin_or_pol(p1))
|
||||
u_p2 = base_state(Electron(), Outgoing(), p2.momentum, spin_or_pol(p2))
|
||||
|
||||
eps_1 = base_state(Photon(), Incoming(), k1.momentum, spin_or_pol(k1))
|
||||
eps_2 = base_state(Photon(), Outgoing(), k2.momentum, spin_or_pol(k2))
|
||||
|
||||
virt1_mom = p2.momentum - k1.momentum
|
||||
@test isapprox(p1.momentum - k2.momentum, virt1_mom)
|
||||
|
||||
virt2_mom = p1.momentum + k1.momentum
|
||||
@test isapprox(p2.momentum + k2.momentum, virt2_mom)
|
||||
|
||||
s_p2_k1 = propagator(Electron(), virt1_mom)
|
||||
s_p1_k1 = propagator(Electron(), virt2_mom)
|
||||
|
||||
diagram1 = u_p2 * (eps_1 * QED_vertex()) * s_p2_k1 * (eps_2 * QED_vertex()) * u_p1
|
||||
diagram2 = u_p2 * (eps_2 * QED_vertex()) * s_p1_k1 * (eps_1 * QED_vertex()) * u_p1
|
||||
|
||||
return diagram1 + diagram2
|
||||
end
|
||||
|
||||
|
||||
@testset "Interaction Result" begin
|
||||
import MetagraphOptimization.QED_conserve_momentum
|
||||
|
||||
for p1 in testparticleTypes, p2 in testparticleTypes
|
||||
if !caninteract(p1, p2)
|
||||
@test_throws AssertionError interaction_result(p1, p2)
|
||||
continue
|
||||
end
|
||||
|
||||
@test interaction_result(p1, p2) in setdiff(testparticleTypes, [p1, p2])
|
||||
@test issame(interaction_result(p1, p2), interaction_result(p2, p1))
|
||||
|
||||
testParticle1 = p1(rand(RNG, SFourMomentum))
|
||||
testParticle2 = p2(rand(RNG, SFourMomentum))
|
||||
p3 = interaction_result(p1, p2)
|
||||
|
||||
resultParticle = QED_conserve_momentum(testParticle1, testParticle2)
|
||||
|
||||
@test issame(typeof(resultParticle), interaction_result(p1, p2))
|
||||
|
||||
totalMom = zero(SFourMomentum)
|
||||
for (p, mom) in [(p1, testParticle1.momentum), (p2, testParticle2.momentum), (p3, resultParticle.momentum)]
|
||||
if (typeof(direction(p)) <: Incoming)
|
||||
totalMom += mom
|
||||
else
|
||||
totalMom -= mom
|
||||
end
|
||||
end
|
||||
|
||||
@test isapprox(totalMom, zero(SFourMomentum); atol = sqrt(eps()))
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Propagation Result" begin
|
||||
for (p, propResult) in zip(testparticleTypes, testparticleTypesPropagated)
|
||||
@test issame(propagation_result(p), propResult)
|
||||
@test direction(propagation_result(p)(def_momentum)) != direction(p(def_momentum))
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Parse Process" begin
|
||||
@testset "Order invariance" begin
|
||||
@test parse_process("ke->ke", QEDModel()) == parse_process("ek->ke", QEDModel())
|
||||
@test parse_process("ke->ke", QEDModel()) == parse_process("ek->ek", QEDModel())
|
||||
@test parse_process("ke->ke", QEDModel()) == parse_process("ke->ek", QEDModel())
|
||||
|
||||
@test parse_process("kkke->eep", QEDModel()) == parse_process("kkek->epe", QEDModel())
|
||||
end
|
||||
|
||||
@testset "Known processes" begin
|
||||
compton_process = QEDProcessDescription(
|
||||
Dict{Type, Int}(PhotonStateful{Incoming} => 1, FermionStateful{Incoming} => 1),
|
||||
Dict{Type, Int}(PhotonStateful{Outgoing} => 1, FermionStateful{Outgoing} => 1),
|
||||
)
|
||||
|
||||
@test parse_process("ke->ke", QEDModel()) == compton_process
|
||||
|
||||
positron_compton_process = QEDProcessDescription(
|
||||
Dict{Type, Int}(PhotonStateful{Incoming} => 1, AntiFermionStateful{Incoming} => 1),
|
||||
Dict{Type, Int}(PhotonStateful{Outgoing} => 1, AntiFermionStateful{Outgoing} => 1),
|
||||
)
|
||||
|
||||
@test parse_process("kp->kp", QEDModel()) == positron_compton_process
|
||||
|
||||
trident_process = QEDProcessDescription(
|
||||
Dict{Type, Int}(PhotonStateful{Incoming} => 1, FermionStateful{Incoming} => 1),
|
||||
Dict{Type, Int}(FermionStateful{Outgoing} => 2, AntiFermionStateful{Outgoing} => 1),
|
||||
)
|
||||
|
||||
@test parse_process("ke->eep", QEDModel()) == trident_process
|
||||
|
||||
pair_production_process = QEDProcessDescription(
|
||||
Dict{Type, Int}(PhotonStateful{Incoming} => 2),
|
||||
Dict{Type, Int}(FermionStateful{Outgoing} => 1, AntiFermionStateful{Outgoing} => 1),
|
||||
)
|
||||
|
||||
@test parse_process("kk->pe", QEDModel()) == pair_production_process
|
||||
|
||||
pair_annihilation_process = QEDProcessDescription(
|
||||
Dict{Type, Int}(FermionStateful{Incoming} => 1, AntiFermionStateful{Incoming} => 1),
|
||||
Dict{Type, Int}(PhotonStateful{Outgoing} => 2),
|
||||
)
|
||||
|
||||
@test parse_process("pe->kk", QEDModel()) == pair_annihilation_process
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Generate Process Inputs" begin
|
||||
@testset "Process $proc_str" for proc_str in ["ke->ke", "kp->kp", "kk->ep", "ep->kk"]
|
||||
# currently can only generate for 2->2 processes
|
||||
process = parse_process(proc_str, QEDModel())
|
||||
|
||||
for i in 1:100
|
||||
input = gen_process_input(process)
|
||||
@test countmap(typeof.(input.inParticles)) == process.inParticles
|
||||
@test countmap(typeof.(input.outParticles)) == process.outParticles
|
||||
|
||||
@test isapprox(
|
||||
sum(getfield.(input.inParticles, :momentum)),
|
||||
sum(getfield.(input.outParticles, :momentum));
|
||||
atol = sqrt(eps()),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@testset "Compton" begin
|
||||
import MetagraphOptimization.insert_node!
|
||||
import MetagraphOptimization.insert_edge!
|
||||
import MetagraphOptimization.make_node
|
||||
|
||||
model = QEDModel()
|
||||
process = parse_process("ke->ke", model)
|
||||
machine = get_machine_info()
|
||||
|
||||
graph = MetagraphOptimization.DAG()
|
||||
|
||||
# manually build a graph for compton
|
||||
graph = DAG()
|
||||
|
||||
# s to output (exit node)
|
||||
d_exit = insert_node!(graph, make_node(DataTask(16)), track = false)
|
||||
|
||||
sum_node = insert_node!(graph, make_node(ComputeTaskQED_Sum(2)), track = false)
|
||||
|
||||
d_s0_sum = insert_node!(graph, make_node(DataTask(16)), track = false)
|
||||
d_s1_sum = insert_node!(graph, make_node(DataTask(16)), track = false)
|
||||
|
||||
# final s compute
|
||||
s0 = insert_node!(graph, make_node(ComputeTaskQED_S2()), track = false)
|
||||
s1 = insert_node!(graph, make_node(ComputeTaskQED_S2()), track = false)
|
||||
|
||||
# data from v0 and v1 to s0
|
||||
d_v0_s0 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_v1_s0 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_v2_s1 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_v3_s1 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
|
||||
# v0 and v1 compute
|
||||
v0 = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false)
|
||||
v1 = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false)
|
||||
v2 = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false)
|
||||
v3 = insert_node!(graph, make_node(ComputeTaskQED_V()), track = false)
|
||||
|
||||
# data from uPhIn, uPhOut, uElIn, uElOut to v0 and v1
|
||||
d_uPhIn_v0 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uElIn_v0 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uPhOut_v1 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uElOut_v1 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
|
||||
# data from uPhIn, uPhOut, uElIn, uElOut to v2 and v3
|
||||
d_uPhOut_v2 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uElIn_v2 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uPhIn_v3 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
d_uElOut_v3 = insert_node!(graph, make_node(DataTask(96)), track = false)
|
||||
|
||||
# uPhIn, uPhOut, uElIn and uElOut computes
|
||||
uPhIn = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false)
|
||||
uPhOut = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false)
|
||||
uElIn = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false)
|
||||
uElOut = insert_node!(graph, make_node(ComputeTaskQED_U()), track = false)
|
||||
|
||||
# data into U
|
||||
d_uPhIn = insert_node!(graph, make_node(DataTask(16), "ki1"), track = false)
|
||||
d_uPhOut = insert_node!(graph, make_node(DataTask(16), "ko1"), track = false)
|
||||
d_uElIn = insert_node!(graph, make_node(DataTask(16), "ei1"), track = false)
|
||||
d_uElOut = insert_node!(graph, make_node(DataTask(16), "eo1"), track = false)
|
||||
|
||||
# now for all the edges
|
||||
insert_edge!(graph, d_uPhIn, uPhIn, track = false)
|
||||
insert_edge!(graph, d_uPhOut, uPhOut, track = false)
|
||||
insert_edge!(graph, d_uElIn, uElIn, track = false)
|
||||
insert_edge!(graph, d_uElOut, uElOut, track = false)
|
||||
|
||||
insert_edge!(graph, uPhIn, d_uPhIn_v0, track = false)
|
||||
insert_edge!(graph, uPhOut, d_uPhOut_v1, track = false)
|
||||
insert_edge!(graph, uElIn, d_uElIn_v0, track = false)
|
||||
insert_edge!(graph, uElOut, d_uElOut_v1, track = false)
|
||||
|
||||
insert_edge!(graph, uPhIn, d_uPhIn_v3, track = false)
|
||||
insert_edge!(graph, uPhOut, d_uPhOut_v2, track = false)
|
||||
insert_edge!(graph, uElIn, d_uElIn_v2, track = false)
|
||||
insert_edge!(graph, uElOut, d_uElOut_v3, track = false)
|
||||
|
||||
insert_edge!(graph, d_uPhIn_v0, v0, track = false)
|
||||
insert_edge!(graph, d_uPhOut_v1, v1, track = false)
|
||||
insert_edge!(graph, d_uElIn_v0, v0, track = false)
|
||||
insert_edge!(graph, d_uElOut_v1, v1, track = false)
|
||||
|
||||
insert_edge!(graph, d_uPhIn_v3, v3, track = false)
|
||||
insert_edge!(graph, d_uPhOut_v2, v2, track = false)
|
||||
insert_edge!(graph, d_uElIn_v2, v2, track = false)
|
||||
insert_edge!(graph, d_uElOut_v3, v3, track = false)
|
||||
|
||||
insert_edge!(graph, v0, d_v0_s0, track = false)
|
||||
insert_edge!(graph, v1, d_v1_s0, track = false)
|
||||
insert_edge!(graph, v2, d_v2_s1, track = false)
|
||||
insert_edge!(graph, v3, d_v3_s1, track = false)
|
||||
|
||||
insert_edge!(graph, d_v0_s0, s0, track = false)
|
||||
insert_edge!(graph, d_v1_s0, s0, track = false)
|
||||
|
||||
insert_edge!(graph, d_v2_s1, s1, track = false)
|
||||
insert_edge!(graph, d_v3_s1, s1, track = false)
|
||||
|
||||
insert_edge!(graph, s0, d_s0_sum, track = false)
|
||||
insert_edge!(graph, s1, d_s1_sum, track = false)
|
||||
|
||||
insert_edge!(graph, d_s0_sum, sum_node, track = false)
|
||||
insert_edge!(graph, d_s1_sum, sum_node, track = false)
|
||||
|
||||
insert_edge!(graph, sum_node, d_exit, track = false)
|
||||
|
||||
input = [gen_process_input(process) for _ in 1:1000]
|
||||
|
||||
compton_function = get_compute_function(graph, process, machine)
|
||||
@test isapprox(compton_function.(input), compton_groundtruth.(input))
|
||||
|
||||
graph_generated = gen_graph(process)
|
||||
|
||||
compton_function = get_compute_function(graph_generated, process, machine)
|
||||
@test isapprox(compton_function.(input), compton_groundtruth.(input))
|
||||
end
|
@ -1,51 +1,49 @@
|
||||
using MetagraphOptimization
|
||||
|
||||
@testset "Task Unit Tests" begin
|
||||
S1 = MetagraphOptimization.ComputeTaskS1()
|
||||
S2 = MetagraphOptimization.ComputeTaskS2()
|
||||
U = MetagraphOptimization.ComputeTaskU()
|
||||
V = MetagraphOptimization.ComputeTaskV()
|
||||
P = MetagraphOptimization.ComputeTaskP()
|
||||
Sum = MetagraphOptimization.ComputeTaskSum()
|
||||
S1 = MetagraphOptimization.ComputeTaskABC_S1()
|
||||
S2 = MetagraphOptimization.ComputeTaskABC_S2()
|
||||
U = MetagraphOptimization.ComputeTaskABC_U()
|
||||
V = MetagraphOptimization.ComputeTaskABC_V()
|
||||
P = MetagraphOptimization.ComputeTaskABC_P()
|
||||
Sum = MetagraphOptimization.ComputeTaskABC_Sum()
|
||||
|
||||
Data10 = MetagraphOptimization.DataTask(10)
|
||||
Data20 = MetagraphOptimization.DataTask(20)
|
||||
Data10 = MetagraphOptimization.DataTask(10)
|
||||
Data20 = MetagraphOptimization.DataTask(20)
|
||||
|
||||
@test MetagraphOptimization.compute_effort(S1) == 11
|
||||
@test MetagraphOptimization.compute_effort(S2) == 12
|
||||
@test MetagraphOptimization.compute_effort(U) == 1
|
||||
@test MetagraphOptimization.compute_effort(V) == 6
|
||||
@test MetagraphOptimization.compute_effort(P) == 0
|
||||
@test MetagraphOptimization.compute_effort(Sum) == 1
|
||||
@test MetagraphOptimization.compute_effort(Data10) == 0
|
||||
@test MetagraphOptimization.compute_effort(Data20) == 0
|
||||
@test MetagraphOptimization.compute_effort(S1) == 11
|
||||
@test MetagraphOptimization.compute_effort(S2) == 12
|
||||
@test MetagraphOptimization.compute_effort(U) == 1
|
||||
@test MetagraphOptimization.compute_effort(V) == 6
|
||||
@test MetagraphOptimization.compute_effort(P) == 0
|
||||
@test MetagraphOptimization.compute_effort(Sum) == 1
|
||||
@test MetagraphOptimization.compute_effort(Data10) == 0
|
||||
@test MetagraphOptimization.compute_effort(Data20) == 0
|
||||
|
||||
@test MetagraphOptimization.data(S1) == 0
|
||||
@test MetagraphOptimization.data(S2) == 0
|
||||
@test MetagraphOptimization.data(U) == 0
|
||||
@test MetagraphOptimization.data(V) == 0
|
||||
@test MetagraphOptimization.data(P) == 0
|
||||
@test MetagraphOptimization.data(Sum) == 0
|
||||
@test MetagraphOptimization.data(Data10) == 10
|
||||
@test MetagraphOptimization.data(Data20) == 20
|
||||
@test MetagraphOptimization.data(S1) == 0
|
||||
@test MetagraphOptimization.data(S2) == 0
|
||||
@test MetagraphOptimization.data(U) == 0
|
||||
@test MetagraphOptimization.data(V) == 0
|
||||
@test MetagraphOptimization.data(P) == 0
|
||||
@test MetagraphOptimization.data(Sum) == 0
|
||||
@test MetagraphOptimization.data(Data10) == 10
|
||||
@test MetagraphOptimization.data(Data20) == 20
|
||||
|
||||
@test S1 != S2
|
||||
@test Data10 != Data20
|
||||
@test S1 != S2
|
||||
@test Data10 != Data20
|
||||
|
||||
Data10_2 = MetagraphOptimization.DataTask(10)
|
||||
Data10_2 = MetagraphOptimization.DataTask(10)
|
||||
|
||||
# two data tasks with same data are identical, their nodes need not be
|
||||
@test Data10_2 == Data10
|
||||
# two data tasks with same data are identical, their nodes need not be
|
||||
@test Data10_2 == Data10
|
||||
|
||||
@test Data10 == Data10
|
||||
@test S1 == S1
|
||||
@test Data10 == Data10
|
||||
@test S1 == S1
|
||||
|
||||
Data10_3 = copy(Data10)
|
||||
Data10_3 = copy(Data10)
|
||||
|
||||
@test Data10_3 == Data10
|
||||
@test Data10_3 == Data10
|
||||
|
||||
S1_2 = copy(S1)
|
||||
S1_2 = copy(S1)
|
||||
|
||||
@test S1_2 == S1
|
||||
@test S1 == MetagraphOptimization.ComputeTaskS1()
|
||||
end
|
||||
println("Task Unit Tests Complete!")
|
||||
@test S1_2 == S1
|
||||
@test S1 == MetagraphOptimization.ComputeTaskABC_S1()
|
||||
|
@ -1,11 +1,10 @@
|
||||
using MetagraphOptimization
|
||||
import MetagraphOptimization.bytes_to_human_readable
|
||||
|
||||
@testset "Unit Tests Utility" begin
|
||||
@test MetagraphOptimization.bytes_to_human_readable(0) == "0.0 B"
|
||||
@test MetagraphOptimization.bytes_to_human_readable(1020) == "1020.0 B"
|
||||
@test MetagraphOptimization.bytes_to_human_readable(1025) == "1.001 KiB"
|
||||
@test MetagraphOptimization.bytes_to_human_readable(684235) == "668.2 KiB"
|
||||
@test MetagraphOptimization.bytes_to_human_readable(86214576) == "82.22 MiB"
|
||||
@test MetagraphOptimization.bytes_to_human_readable(9241457698) == "8.607 GiB"
|
||||
@test MetagraphOptimization.bytes_to_human_readable(3218598654367) == "2.927 TiB"
|
||||
end
|
||||
println("Utility Unit Tests Complete!")
|
||||
@test bytes_to_human_readable(0) == "0.0 B"
|
||||
@test bytes_to_human_readable(1020) == "1020.0 B"
|
||||
@test bytes_to_human_readable(1025) == "1.001 KiB"
|
||||
@test bytes_to_human_readable(684235) == "668.2 KiB"
|
||||
@test bytes_to_human_readable(86214576) == "82.22 MiB"
|
||||
@test bytes_to_human_readable(9241457698) == "8.607 GiB"
|
||||
@test bytes_to_human_readable(3218598654367) == "2.927 TiB"
|
||||
|
Reference in New Issue
Block a user