Compare commits
10 Commits
scheduling
...
heterogene
Author | SHA1 | Date | |
---|---|---|---|
e5d214a6fc | |||
82ed774b7e | |||
92e0eeaaef | |||
c90346e948 | |||
938bf216e5 | |||
04d5673b44 | |||
b7560685d4 | |||
16274919e4 | |||
2709eeb3dc | |||
5a30f57e1f |
@ -1,5 +1,5 @@
|
||||
indent = 4
|
||||
margin = 80
|
||||
margin = 120
|
||||
always_for_in = true
|
||||
for_in_replacement = "in"
|
||||
whitespace_typedefs = true
|
||||
|
@ -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,56 +21,34 @@ 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
|
||||
- name: Instantiate
|
||||
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()'
|
||||
julia --project=./ -e 'using Pkg; Pkg.instantiate()'
|
||||
julia --project=./ -e 'using Pkg; Pkg.add(url="https://github.com/QEDjl-project/QEDprocesses.jl/")'
|
||||
|
||||
- name: Format check
|
||||
run: |
|
||||
julia --project=./ -e 'using JuliaFormatter; format(".", verbose=true)'
|
||||
julia --project=./ -e 'using JuliaFormatter; format(".", verbose=true, ignore=[".julia/*"])'
|
||||
julia --project=./ -e '
|
||||
out = Cmd(`git diff --name-only`) |> read |> String
|
||||
if out == ""
|
||||
exit(0)
|
||||
else
|
||||
@error "Some files have not been formatted !!!"
|
||||
@error "Some files have not been formatted!!!"
|
||||
write(stdout, out)
|
||||
exit(1)
|
||||
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 +61,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
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -5,6 +5,7 @@
|
||||
|
||||
# Files generated by invoking Julia with --track-allocation
|
||||
*.mem
|
||||
*.pb.gz
|
||||
|
||||
# System-specific files and directories generated by the BinaryProvider and BinDeps packages
|
||||
# They contain absolute paths specific to the host computer, and so should not be committed
|
||||
@ -26,3 +27,6 @@ Manifest.toml
|
||||
|
||||
# vscode workspace directory
|
||||
.vscode
|
||||
.julia
|
||||
**/.ipynb_checkpoints/
|
||||
*.bkp
|
||||
|
@ -5,9 +5,17 @@ version = "0.1.0"
|
||||
|
||||
[deps]
|
||||
AccurateArithmetic = "22286c92-06ac-501d-9306-4abd417d9753"
|
||||
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
|
||||
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
||||
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
|
||||
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"
|
||||
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
||||
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
|
||||
[extras]
|
||||
|
46
README.md
46
README.md
@ -42,7 +42,7 @@ Problems:
|
||||
- Lots of testing required because mistakes will propagate and multiply.
|
||||
|
||||
## Other TODOs
|
||||
- Reduce memory footprint of the graph, are the UUIDs too large?
|
||||
- Reduce memory footprint of the graph
|
||||
- Memory layout of Nodes? They should lie linearly in memory, right now probably on heap?
|
||||
- Add scaling functions
|
||||
|
||||
@ -50,18 +50,18 @@ 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
|
||||
Times are from my home machine: AMD Ryzen 7900X3D, 64GB DDR5 RAM @ 6000MHz (not necessarily up to date, check Jupyter Notebooks in `notebooks/` instead)
|
||||
|
||||
```
|
||||
$ 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
|
||||
|
16
data/qed_ke-kke_reduction_optimizer.csv
Normal file
16
data/qed_ke-kke_reduction_optimizer.csv
Normal file
@ -0,0 +1,16 @@
|
||||
operations,graph_nodes,graph_edges,graph_ce,graph_dt,graph_ci,gen_func_t,cpu_compile_t,cpu_st_t,cpu_mt_t,gpu_compile_t,gpu_t
|
||||
0,77,101,252.0,6240.0,0.04038461538461539,0.02087051,8.691e-6,3.405098066,0.244763721,1.565749515,0.936213163
|
||||
1,76,99,246.0,6240.0,0.03942307692307692,0.020658734,9.36e-6,3.244313848,0.230460257,1.548012602,0.887605389
|
||||
2,75,97,240.0,6240.0,0.038461538461538464,0.045333482,8.74e-6,3.163679857,0.217614064,1.52780456,0.816496837
|
||||
3,74,95,234.0,6240.0,0.0375,0.020314034,9.081e-6,2.956421016,0.183415997,1.524262179,0.793770075
|
||||
4,73,93,228.0,6240.0,0.03653846153846154,0.033579409,8.52e-6,2.845414866,0.19168374,1.50907807,0.742734411
|
||||
5,72,92,228.0,6144.0,0.037109375,0.019736718,8.87e-6,2.827109937,0.207452606,1.497203204,0.719774022
|
||||
6,71,90,222.0,6144.0,0.0361328125,0.043612693,1.01e-5,2.62776692,0.166492497,1.602060948,0.668929854
|
||||
7,70,89,222.0,6048.0,0.03670634920634921,0.042731148,1.053e-5,2.631288029,0.185812224,1.514154792,0.694503947
|
||||
8,69,87,216.0,6048.0,0.03571428571428571,0.042148711,8.19e-6,2.493343257,0.183595081,1.506478504,0.652420896
|
||||
9,68,86,216.0,5952.0,0.036290322580645164,0.041568955,8.571e-6,2.487317627,0.147773078,1.472141844,0.653143947
|
||||
10,67,85,216.0,5856.0,0.036885245901639344,0.041307868,9.13e-6,2.491634709,0.175728138,1.482162906,0.63058774
|
||||
11,66,84,216.0,5760.0,0.0375,0.041265756,8.43e-6,2.516916643,0.180420842,1.463053866,0.650627815
|
||||
12,65,83,205.0,5760.0,0.035590277777777776,0.039711293,9.22e-6,2.479664249,0.178013433,1.459566956,0.652477867
|
||||
13,64,82,205.0,5664.0,0.03619350282485876,0.030866093,8.87e-6,2.485424881,0.179983608,1.564961227,0.647932468
|
||||
14,63,81,205.0,5568.0,0.03681752873563218,0.029946916,8.93e-6,2.469922022,0.179443854,1.485935831,0.651804318
|
|
176
data/qed_ke-kkke_greedy_optimizer_GlobalMetricEstimator().csv
Normal file
176
data/qed_ke-kkke_greedy_optimizer_GlobalMetricEstimator().csv
Normal file
@ -0,0 +1,176 @@
|
||||
operations,graph_nodes,graph_edges,graph_ce,graph_dt,graph_ci,gen_func_t,cpu_compile_t,cpu_st_t,cpu_mt_t,gpu_compile_t,gpu_t
|
||||
0,356,493,1399.0,30528.0,0.0458267819706499,0.077070556,2.6761e-5,17.804336617,0.960385595,10.618577031,4.95440474
|
||||
1,354,491,1399.0,30432.0,0.04597134595162986,1.030851104,2.37e-5,17.726472964,0.933074463,2.174912444,4.959474851
|
||||
2,352,489,1399.0,30336.0,0.04611682489451477,0.376282553,2.3861e-5,17.935912907,0.968087391,2.238665483,4.912705328
|
||||
3,350,487,1399.0,30240.0,0.04626322751322751,0.076651194,4.2451e-5,17.976779783,0.977130996,2.246167674,4.954520005
|
||||
4,348,485,1399.0,30144.0,0.04641056263269639,0.223709216,2.8031e-5,17.67129111,0.97799748,2.175788856,4.923999491
|
||||
5,346,483,1399.0,30048.0,0.04655883919062833,0.076034997,4.3191e-5,17.766336956,0.967055891,2.187609178,4.922574669
|
||||
6,344,481,1399.0,29952.0,0.04670806623931624,0.398917781,4.3422e-5,17.709032771,0.971142926,2.170963978,4.917191185
|
||||
7,342,479,1399.0,29856.0,0.04685825294748124,0.352569343,4.3801e-5,17.690255833,0.952966242,2.159295978,4.945842152
|
||||
8,340,477,1399.0,29760.0,0.04700940860215054,0.117620751,4.2992e-5,17.905787431,0.749896479,2.19940915,4.922882222
|
||||
9,338,475,1399.0,29664.0,0.04716154261057174,0.318053898,2.3481e-5,17.522775542,0.745113955,2.202366151,4.928734427
|
||||
10,336,473,1399.0,29568.0,0.047314664502164504,0.184069985,2.3381e-5,17.529935879,0.74637911,2.238397648,4.919919125
|
||||
11,334,471,1399.0,29472.0,0.047468783930510315,0.086029218,2.365e-5,17.560859257,0.75559668,2.249242933,4.956561058
|
||||
12,332,469,1399.0,29376.0,0.04762391067538126,0.077326472,2.4361e-5,17.559317648,0.746726769,2.1818156,4.938490196
|
||||
13,330,467,1399.0,29280.0,0.047780054644808743,0.169738661,2.342e-5,17.517109121,0.751453942,2.187781478,4.923659727
|
||||
14,328,465,1399.0,29184.0,0.047937225877192985,0.077817676,2.315e-5,17.533304215,0.745481303,2.209343496,4.960503415
|
||||
15,326,463,1399.0,29088.0,0.04809543454345434,0.171584444,2.352e-5,17.579912576,0.754778436,2.210370024,4.934281254
|
||||
16,324,461,1399.0,28992.0,0.04825469094922737,0.084223667,2.305e-5,17.570464754,0.751290178,2.22797709,4.939806799
|
||||
17,322,459,1399.0,28896.0,0.04841500553709856,0.123005102,2.3661e-5,17.605650973,0.756929676,2.269940175,4.937928844
|
||||
18,320,457,1399.0,28800.0,0.04857638888888889,0.086677986,2.37e-5,17.5539199,0.746367967,2.264938904,4.959258096
|
||||
19,318,455,1399.0,28704.0,0.04873885172798216,0.12293158,2.3711e-5,17.609395222,0.755783994,2.264754078,4.92827168
|
||||
20,316,453,1399.0,28608.0,0.04890240492170023,0.124475123,2.4281e-5,17.597716228,0.75106304,2.20218749,4.933120236
|
||||
21,314,451,1399.0,28512.0,0.04906705948372615,0.112172177,2.6391e-5,17.623178954,0.755694751,2.186417905,4.921509117
|
||||
22,312,449,1399.0,28416.0,0.04923282657657658,0.219362642,2.321e-5,17.593459902,0.747914841,2.168628993,4.952994795
|
||||
23,310,447,1399.0,28320.0,0.049399717514124294,0.080729209,2.358e-5,17.571675834,0.755489634,2.209531477,4.951190234
|
||||
24,308,445,1399.0,28224.0,0.049567743764172334,0.080235835,2.3271e-5,17.615791747,0.750314688,2.21464245,4.949496195
|
||||
25,306,443,1399.0,28128.0,0.049736916951080776,0.124106403,2.374e-5,17.60716179,0.753826187,2.186184237,4.920128786
|
||||
26,304,441,1399.0,28032.0,0.04990724885844749,0.080715608,2.3781e-5,17.581988477,0.750266997,2.209826064,4.937813884
|
||||
27,302,439,1399.0,27936.0,0.05007875143184422,0.080606465,2.4071e-5,17.633096607,0.749125265,2.198599437,4.935320693
|
||||
28,300,437,1399.0,27840.0,0.0502514367816092,0.081056137,2.3781e-5,17.564695624,0.746230293,2.225110355,4.939656214
|
||||
29,298,435,1399.0,27744.0,0.05042531718569781,0.096545225,2.379e-5,17.58144781,0.747458632,2.263551336,4.924245431
|
||||
30,296,433,1399.0,27648.0,0.050600405092592594,0.120638697,2.383e-5,17.574370836,0.748933285,2.234417803,4.915183371
|
||||
31,294,431,1399.0,27552.0,0.0507767131242741,0.125073582,2.393e-5,17.627352699,0.754384428,2.214199106,4.938130459
|
||||
32,292,429,1399.0,27456.0,0.05095425407925408,0.12314953,2.468e-5,17.697160429,0.796488763,2.261473826,4.956976138
|
||||
33,290,427,1399.0,27360.0,0.051133040935672516,0.125481487,2.354e-5,17.636971006,0.748416796,2.222200724,4.948970096
|
||||
34,288,425,1399.0,27264.0,0.051313086854460094,0.094052012,2.4301e-5,17.62971842,0.805139938,2.205015347,4.959455536
|
||||
35,286,423,1399.0,27168.0,0.051494405182567725,0.08136377,2.4041e-5,17.621304482,0.747718686,2.244362062,4.941432169
|
||||
36,284,421,1399.0,27072.0,0.05167700945626478,0.080217839,2.3921e-5,17.61427713,0.747754586,2.212103901,4.933185029
|
||||
37,282,417,1399.0,26976.0,0.051860913404507714,0.126372199,2.376e-5,17.601417663,0.750036789,2.163344775,4.926698186
|
||||
38,280,414,1399.0,26880.0,0.052046130952380955,0.125444544,2.476e-5,17.612452443,0.748155225,2.195259021,4.91594575
|
||||
39,278,412,1399.0,26784.0,0.05223267622461171,0.083158944,2.4551e-5,17.599589645,0.741671021,2.208064301,4.9351555
|
||||
40,276,410,1399.0,26688.0,0.05242056354916067,0.083321959,2.4101e-5,17.567124159,0.748238012,2.197233222,4.954754226
|
||||
41,274,408,1399.0,26592.0,0.052609807460890494,0.084803792,2.3901e-5,17.549365204,0.754817994,2.229499405,4.94957165
|
||||
42,272,405,1399.0,26496.0,0.05280042270531401,0.127648261,2.3851e-5,17.582852416,0.750759497,2.230398721,4.937220319
|
||||
43,270,401,1399.0,26400.0,0.052992424242424244,0.128445184,2.428e-5,17.596647819,0.75777713,2.160922996,4.937371146
|
||||
44,268,399,1399.0,26304.0,0.053185827250608275,0.129526096,2.5081e-5,17.594476326,0.746906342,2.219401891,4.93357998
|
||||
45,266,397,1399.0,26208.0,0.05338064713064713,0.129819495,2.4731e-5,17.568331366,0.750368555,2.18948505,4.922275732
|
||||
46,264,394,1399.0,26112.0,0.05357689950980392,0.087649075,2.462e-5,17.585414218,0.751605626,2.198684054,4.941424565
|
||||
47,262,391,1399.0,26016.0,0.05377460024600246,0.089110637,2.4551e-5,17.614139291,0.750622403,2.168793662,4.953321773
|
||||
48,260,389,1399.0,25920.0,0.053973765432098766,0.090307061,2.45e-5,17.633806293,0.749096576,2.224521298,4.930813246
|
||||
49,258,387,1399.0,25824.0,0.054174411400247834,0.133480181,2.461e-5,17.634768586,0.756613261,2.201452177,4.972809945
|
||||
50,256,385,1399.0,25728.0,0.05437655472636816,0.134254424,2.425e-5,17.606323938,0.748779206,2.216818872,4.939295094
|
||||
51,254,382,1399.0,25632.0,0.05458021223470662,0.134016868,2.4531e-5,17.5926305,0.75625873,2.227679889,4.968213894
|
||||
52,252,379,1399.0,25536.0,0.054785401002506263,0.135650945,2.4601e-5,17.642803637,0.751975585,2.226011125,4.9285844
|
||||
53,250,375,1399.0,25440.0,0.054992138364779876,0.136647933,2.4161e-5,17.799738254,0.76667472,2.165144989,4.930427128
|
||||
54,248,373,1399.0,25344.0,0.05520044191919192,0.123103164,2.4461e-5,17.745879754,0.760526742,2.161495227,4.940492285
|
||||
55,246,370,1399.0,25248.0,0.05541032953105197,0.09476826,2.3511e-5,17.596131758,0.756924114,2.180021837,4.954121771
|
||||
56,244,365,1399.0,25152.0,0.05562181933842239,0.095345787,2.4171e-5,17.612023424,0.747989147,2.215139082,4.945396527
|
||||
57,242,362,1399.0,25056.0,0.05583492975734355,0.139570128,2.3801e-5,17.630922372,0.750668446,2.186529739,4.961981394
|
||||
58,240,359,1399.0,24960.0,0.05604967948717949,0.097466916,2.4451e-5,17.61078772,0.7485922,2.217673752,4.95291513
|
||||
59,238,357,1399.0,24864.0,0.05626608751608752,0.138599302,2.3601e-5,17.586404505,0.756929027,2.233374301,4.935342135
|
||||
60,236,352,1399.0,24768.0,0.05648417312661499,0.147210964,2.4911e-5,17.650436019,0.74908103,2.157077946,4.937714591
|
||||
61,234,350,1399.0,24672.0,0.05670395590142672,0.099491094,2.3601e-5,17.608002511,0.756924473,2.165309665,4.932434479
|
||||
62,232,348,1399.0,24576.0,0.056925455729166664,0.141929827,2.454e-5,17.605756917,0.749178717,2.234082435,4.957629943
|
||||
63,230,344,1399.0,24480.0,0.057148692810457515,0.142483983,2.4211e-5,17.623883273,0.758216784,2.210078838,4.930940098
|
||||
64,228,341,1399.0,24384.0,0.057373687664041995,0.101524943,2.4371e-5,17.662312587,0.751128917,2.22449657,4.96708528
|
||||
65,226,339,1399.0,24288.0,0.05760046113306983,0.102619253,2.3831e-5,17.610112922,0.758167777,2.187456785,4.957519684
|
||||
66,224,337,1399.0,24192.0,0.05782903439153439,0.10351088,2.3401e-5,17.611932402,0.749178457,2.236980212,4.933450322
|
||||
67,222,335,1399.0,24096.0,0.05805942895086321,0.148780402,2.3711e-5,17.636035095,0.75707833,2.252138664,4.951632995
|
||||
68,220,333,1399.0,24000.0,0.058291666666666665,0.148311059,2.4851e-5,17.617252052,0.750104986,2.22330739,4.9243139
|
||||
69,218,329,1399.0,23904.0,0.05852576974564926,0.151678794,2.4181e-5,17.627742278,0.755299894,2.248062201,4.951401482
|
||||
70,216,326,1399.0,23808.0,0.05876176075268817,0.15082361,2.3851e-5,17.647410652,0.752445605,2.240948426,4.949599133
|
||||
71,214,323,1399.0,23712.0,0.05899966261808367,0.153382492,2.4011e-5,17.654743596,0.752802907,2.253819342,4.966250371
|
||||
72,212,320,1399.0,23616.0,0.05923949864498645,0.151516131,2.3931e-5,17.672908543,0.750257716,2.220003155,4.944782327
|
||||
73,210,317,1399.0,23520.0,0.059481292517006804,0.154244628,2.386e-5,17.60330678,0.750422813,2.211295295,4.943727837
|
||||
74,208,313,1399.0,23424.0,0.05972506830601093,0.153767234,2.4291e-5,17.640950842,0.74988433,2.24794966,4.952712228
|
||||
75,206,311,1399.0,23328.0,0.05997085048010974,0.155927375,2.406e-5,17.589128666,0.749120129,2.253801308,4.953014816
|
||||
76,204,306,1399.0,23232.0,0.06021866391184573,0.15464184,2.4521e-5,17.662616581,0.750484429,2.227511412,4.924026259
|
||||
77,202,304,1399.0,23136.0,0.06046853388658368,0.157807248,2.4041e-5,17.611953814,0.755679546,2.178734374,4.943974526
|
||||
78,200,301,1399.0,23040.0,0.06072048611111111,0.155978707,2.4051e-5,17.624250437,0.794935481,2.247188963,4.940403894
|
||||
79,198,298,1399.0,22944.0,0.06097454672245467,0.158377905,2.5091e-5,17.634938402,0.754743461,2.245248812,4.919902064
|
||||
80,196,296,1399.0,22848.0,0.061230742296918765,0.158750786,2.4511e-5,17.6360904,0.750867213,2.200032233,4.942215648
|
||||
81,194,293,1399.0,22752.0,0.061489099859353025,0.161152794,2.4831e-5,17.780761042,0.765338482,2.204873372,4.939655562
|
||||
82,192,290,1399.0,22656.0,0.061749646892655365,0.160175486,2.318e-5,17.798147683,0.76168194,2.230891056,4.955801153
|
||||
83,190,287,1399.0,22560.0,0.06201241134751773,0.159868767,2.4791e-5,17.764165058,0.796377137,2.239618185,4.928054627
|
||||
84,188,283,1399.0,22464.0,0.06227742165242165,0.160933577,2.4221e-5,17.798426962,0.848255338,2.218112612,4.932433146
|
||||
85,186,280,1399.0,22368.0,0.06254470672389127,0.163393917,2.4371e-5,17.808464853,0.765692696,2.213490844,4.943298137
|
||||
86,184,277,1399.0,22272.0,0.06281429597701149,0.163792118,2.4261e-5,17.805783627,0.761027705,2.232891092,4.919454211
|
||||
87,182,275,1399.0,22176.0,0.06308621933621934,0.162177953,2.43e-5,17.797665375,0.761040026,2.236586089,4.951072155
|
||||
88,180,271,1399.0,22080.0,0.06336050724637682,0.165377424,2.557e-5,17.805099359,0.763146286,2.212611436,4.921150887
|
||||
89,178,268,1399.0,21984.0,0.06363719068413391,0.166754373,2.5141e-5,17.770997205,0.764361801,2.199943181,4.934748884
|
||||
90,176,266,1399.0,21888.0,0.06391630116959064,0.167241957,2.4571e-5,17.770223198,0.759580227,2.247867501,4.935730147
|
||||
91,174,264,1399.0,21792.0,0.06419787077826726,0.169623073,2.5e-5,17.771153368,0.750276145,2.243455929,4.939933808
|
||||
92,172,261,1399.0,21696.0,0.06448193215339233,0.168358288,2.5181e-5,17.799224982,0.760906435,2.210000929,4.943923374
|
||||
93,170,259,1399.0,21600.0,0.06476851851851852,0.170287483,2.529e-5,17.79271252,0.763151029,2.205444892,4.924953813
|
||||
94,168,254,1399.0,21504.0,0.06505766369047619,0.168986856,2.5021e-5,17.775583682,0.760237647,2.222811993,4.951301097
|
||||
95,166,250,1399.0,21408.0,0.06534940209267563,0.171662521,2.4401e-5,17.636022254,0.749599438,2.234944605,4.958431762
|
||||
96,164,246,1399.0,21312.0,0.06564376876876876,0.170911431,2.4481e-5,17.633556045,0.788097892,2.198060879,4.922871993
|
||||
97,162,244,1399.0,21216.0,0.06594079939668175,0.172387252,2.4781e-5,17.620254381,0.799269067,2.202436673,4.936411908
|
||||
98,160,241,1399.0,21120.0,0.0662405303030303,0.171830017,2.581e-5,17.656653806,0.750275098,2.200933622,4.94776375
|
||||
99,158,238,1399.0,21024.0,0.06654299847792998,0.174560093,2.447e-5,17.625724723,0.756745741,2.249721096,4.958786002
|
||||
100,156,235,1399.0,20928.0,0.06684824159021406,0.178996759,2.453e-5,17.669194606,0.749422535,2.218089817,4.960858653
|
||||
101,154,231,1399.0,20832.0,0.0671562980030722,0.175032127,2.3871e-5,17.642586975,0.754643863,2.194675279,4.944134534
|
||||
102,152,229,1399.0,20736.0,0.06746720679012345,0.176393906,2.4731e-5,17.592973556,0.749943551,2.229565622,4.927935661
|
||||
103,150,225,1399.0,20640.0,0.06778100775193799,0.178017631,2.412e-5,17.630568322,0.755272802,2.221125776,4.952348991
|
||||
104,148,223,1399.0,20544.0,0.0680977414330218,0.175897841,2.36e-5,17.661766307,0.749293633,2.2201698,4.963634779
|
||||
105,146,221,1399.0,20448.0,0.06841744913928012,0.178367362,2.5001e-5,17.654508999,0.755361234,2.185187066,4.938710949
|
||||
106,144,218,1399.0,20352.0,0.06874017295597484,0.178791594,2.502e-5,17.649520916,0.749748217,2.238645461,4.955141284
|
||||
107,142,216,1399.0,20256.0,0.06906595576619273,0.175900502,2.3291e-5,17.648252045,0.755157659,2.250102545,4.948078116
|
||||
108,140,212,1399.0,20160.0,0.06939484126984127,0.180050739,2.3901e-5,17.642556024,0.751139061,2.195233955,4.92102672
|
||||
109,138,210,1399.0,20064.0,0.06972687400318979,0.182587052,2.492e-5,17.631301401,0.754040144,2.177296385,4.948297571
|
||||
110,136,207,1399.0,19968.0,0.07006209935897435,0.181449712,2.4401e-5,17.618787463,0.748940439,2.251932822,4.950366155
|
||||
111,134,203,1399.0,19872.0,0.07040056360708534,0.183466877,2.407e-5,17.658532693,0.756589176,2.240568188,4.97337861
|
||||
112,132,201,1399.0,19776.0,0.0707423139158576,0.181545084,2.485e-5,17.63441504,0.751343023,2.183033772,4.975534251
|
||||
113,130,199,1399.0,19680.0,0.07108739837398374,0.177809314,2.417e-5,17.627163359,0.754577307,2.211080446,4.977438563
|
||||
114,128,195,1399.0,19584.0,0.07143586601307189,0.183038393,2.5541e-5,17.63366534,0.751510139,2.237832092,4.969644912
|
||||
115,126,191,1399.0,19488.0,0.07178776683087028,0.186344151,2.4971e-5,17.711808739,0.759177,2.236586017,4.951292022
|
||||
116,124,187,1399.0,19392.0,0.07214315181518152,0.184833587,2.475e-5,17.648467279,0.749564641,2.179772409,4.97017709
|
||||
117,122,183,1399.0,19296.0,0.07250207296849089,0.193249355,2.3811e-5,17.639230223,0.755564354,2.195109482,4.982434629
|
||||
118,120,180,1399.0,19200.0,0.07286458333333333,0.186818046,2.372e-5,17.635977046,0.750626058,2.243877912,4.972608068
|
||||
119,118,177,1399.0,19104.0,0.07323073701842546,0.189204719,2.4961e-5,17.791522288,0.766082656,2.242948358,4.980365418
|
||||
120,116,173,1399.0,19008.0,0.07360058922558922,0.186391669,2.4181e-5,17.645956891,0.750893368,2.197914806,4.98745469
|
||||
121,114,171,1399.0,18912.0,0.07397419627749577,0.19060573,2.4701e-5,17.771140583,0.765197694,2.20643796,4.959618561
|
||||
122,112,169,1399.0,18816.0,0.0743516156462585,0.188466188,2.381e-5,17.795228145,0.759434429,2.26208531,4.965068853
|
||||
123,110,165,1399.0,18720.0,0.07473290598290598,0.191524927,2.3841e-5,17.779734215,0.767242896,2.242967333,4.950554681
|
||||
124,108,161,1399.0,18624.0,0.07511812714776632,0.189450326,2.3601e-5,17.807849571,0.762371273,2.196711688,4.966122065
|
||||
125,106,157,1399.0,18528.0,0.0755073402417962,0.191473057,2.357e-5,17.632877767,0.755845465,2.188474891,4.977562868
|
||||
126,104,153,1399.0,18432.0,0.0759006076388889,0.191382079,2.3851e-5,17.775729988,0.758861116,2.278116886,4.979965119
|
||||
127,102,151,1399.0,18336.0,0.07629799301919721,0.192296369,2.394e-5,17.777918793,0.764981303,2.224818047,4.949944943
|
||||
128,100,149,1399.0,18240.0,0.07669956140350877,0.191424719,2.4331e-5,17.856475915,0.76057459,2.201588049,4.941974925
|
||||
129,98,146,1399.0,18144.0,0.07710537918871252,0.194280932,2.3951e-5,17.779963845,0.766401736,2.223182601,4.961465017
|
||||
130,96,142,1399.0,18048.0,0.07751551418439716,0.192850597,2.3861e-5,17.765033828,0.760509569,2.250897799,4.967399083
|
||||
131,94,138,1399.0,17952.0,0.07793003565062388,0.194741823,2.38e-5,17.778261696,0.764271609,2.248898068,4.975998565
|
||||
132,92,136,1399.0,17856.0,0.07834901433691756,0.193567295,2.5281e-5,17.791322862,0.759809249,2.216694812,4.962092553
|
||||
133,90,132,1399.0,17760.0,0.07877252252252252,0.196949912,2.4641e-5,17.775924767,0.766636532,2.192664527,4.943809886
|
||||
134,88,129,1399.0,17664.0,0.07920063405797101,0.19423328,2.4491e-5,17.775940481,0.759698903,2.241454301,4.965419114
|
||||
135,86,125,1399.0,17568.0,0.07963342440801457,0.196021362,2.4541e-5,17.749824568,0.77002309,2.244133161,4.973507276
|
||||
136,84,123,1399.0,17472.0,0.08007097069597069,0.195945063,2.4791e-5,17.793381264,0.758984676,2.223761942,4.967845004
|
||||
137,82,120,1399.0,17376.0,0.0805133517495396,0.196404909,2.5491e-5,17.781126567,0.76777764,2.208548873,4.942758101
|
||||
138,80,116,1399.0,17280.0,0.08096064814814814,0.197313346,2.469e-5,17.785944557,0.814271788,2.200296465,4.939179018
|
||||
139,78,114,1399.0,17184.0,0.08141294227188083,0.155633427,2.5181e-5,17.79491891,0.767423131,2.233213884,4.963944358
|
||||
140,76,111,1399.0,17088.0,0.08187031835205992,0.194686919,2.4311e-5,17.835512877,0.761171578,2.216772786,4.968370761
|
||||
141,74,108,1399.0,16992.0,0.0823328625235405,0.19895497,2.4301e-5,17.80769545,0.768202031,2.212642548,4.971369432
|
||||
142,72,106,1399.0,16896.0,0.08280066287878787,0.197589165,2.4241e-5,17.817799582,0.760097766,2.219367009,4.967751237
|
||||
143,70,102,1399.0,16800.0,0.08327380952380953,0.200103786,2.425e-5,17.804210307,0.767108387,2.264925155,4.965506236
|
||||
144,68,99,1399.0,16704.0,0.08375239463601533,0.196633322,2.5371e-5,17.822197608,0.762852947,2.20877412,4.971541033
|
||||
145,66,97,1399.0,16608.0,0.08423651252408478,0.200144552,2.4801e-5,17.823667792,0.766965999,2.209992675,4.969252216
|
||||
146,64,93,1399.0,16512.0,0.08472625968992248,0.199816644,2.4901e-5,17.838429006,0.764432365,2.241092809,4.961995819
|
||||
147,62,89,1399.0,16416.0,0.08522173489278752,0.187325579,2.5321e-5,17.811923957,0.767393244,2.227406228,4.960056608
|
||||
148,60,85,1399.0,16320.0,0.08572303921568628,0.198893612,2.4451e-5,17.82940565,0.760747136,2.209815727,4.971563658
|
||||
149,58,83,1399.0,16224.0,0.08623027613412229,0.201039293,2.4651e-5,17.817639935,0.767607352,2.210546374,4.97066195
|
||||
150,56,81,1399.0,16128.0,0.08674355158730158,0.199841932,2.414e-5,17.82203287,0.760048809,2.243550629,4.954439346
|
||||
151,54,79,1399.0,16032.0,0.0872629740518962,0.2011596,2.4741e-5,17.804574042,0.767800679,2.250206119,4.955980994
|
||||
152,52,75,1399.0,15936.0,0.08778865461847389,0.19971389,2.4331e-5,17.829821975,0.762018993,2.205143141,4.970086548
|
||||
153,50,73,1399.0,15840.0,0.08832070707070708,0.201368798,2.4881e-5,17.836101646,0.767371477,2.218711432,4.96364023
|
||||
154,48,71,1399.0,15744.0,0.08885924796747967,0.200798594,2.4491e-5,17.830384655,0.765407907,2.286796949,4.939295093
|
||||
155,46,67,1399.0,15648.0,0.08940439672801637,0.202551163,2.5121e-5,17.827221721,0.768466657,2.262575248,4.943430916
|
||||
156,44,65,1399.0,15552.0,0.08995627572016461,0.198816901,2.578e-5,17.840506569,0.760760306,2.220630133,4.952844324
|
||||
157,42,63,1399.0,15456.0,0.09051501035196688,0.201424744,2.5021e-5,17.814439397,0.767553139,2.196934945,4.958506547
|
||||
158,40,59,1399.0,15360.0,0.09108072916666667,0.202145126,2.565e-5,17.808712307,0.76137146,2.235801178,4.949559042
|
||||
159,38,55,1399.0,15264.0,0.0916535639412998,0.201663393,2.4591e-5,17.784477195,0.766209648,2.249329555,4.964028527
|
||||
160,36,53,1399.0,15168.0,0.09223364978902954,0.199579456,2.5461e-5,17.900752023,0.761934363,2.209582978,4.950507063
|
||||
161,34,48,1399.0,15072.0,0.09282112526539278,0.159541692,2.5211e-5,17.769415534,0.935609132,2.216664395,4.962977201
|
||||
162,32,44,1399.0,14976.0,0.09341613247863248,0.201979445,2.5581e-5,17.802148727,0.758630938,2.257162782,4.954367291
|
||||
163,30,40,1399.0,14880.0,0.09401881720430108,0.203381244,2.5411e-5,17.808584074,0.768160516,2.239967841,4.949515694
|
||||
164,28,35,1399.0,14784.0,0.09462932900432901,0.200707381,2.5071e-5,17.811958674,0.765546396,2.222827481,4.962523474
|
||||
165,26,31,1399.0,14688.0,0.09524782135076253,0.203476579,2.4431e-5,17.791537057,0.759747517,2.210172596,4.96717851
|
||||
166,24,29,1399.0,14592.0,0.09587445175438597,0.38619058,2.5161e-5,17.784565893,0.765981903,2.205094732,4.970469758
|
||||
167,22,25,1399.0,14496.0,0.09650938189845475,0.209174268,2.6071e-5,17.886396985,0.762283972,2.251379768,4.9348063
|
||||
168,20,21,1399.0,14400.0,0.09715277777777778,0.184182012,2.5331e-5,17.791795342,0.760972528,2.229551257,4.941190792
|
||||
169,18,17,1399.0,14304.0,0.09780480984340045,0.203935864,2.572e-5,17.823665061,0.762353868,2.199132836,4.965200905
|
||||
170,16,15,1399.0,14208.0,0.09846565315315316,0.200164969,2.4631e-5,17.792385586,0.76804392,2.174965407,4.972074439
|
||||
171,14,13,1399.0,14112.0,0.09913548752834467,0.204567903,2.5071e-5,17.806154396,0.759505453,2.2340466,4.972671228
|
||||
172,12,11,1399.0,14016.0,0.09981449771689498,0.201861418,2.5971e-5,18.529840195,0.789347616,2.23167521,4.947890089
|
||||
173,10,9,1399.0,13920.0,0.1005028735632184,0.202902727,2.4951e-5,17.865867105,0.761004999,2.194876208,4.93177029
|
||||
174,8,7,1399.0,13824.0,0.10120081018518519,0.198079003,2.4651e-5,17.791197743,0.767399089,2.226370372,4.951979965
|
|
82
data/qed_ke-kkke_reduction_optimizer.csv
Normal file
82
data/qed_ke-kkke_reduction_optimizer.csv
Normal file
@ -0,0 +1,82 @@
|
||||
operations,graph_nodes,graph_edges,graph_ce,graph_dt,graph_ci,gen_func_t,cpu_compile_t,cpu_st_t,cpu_mt_t,gpu_compile_t,gpu_t
|
||||
0,356,493,1399.0,30528.0,0.0458267819706499,0.084389903,2.4971e-5,17.802549835,0.960409581,2.406448706,4.927079076
|
||||
1,351,483,1369.0,30528.0,0.044844077568134175,0.126855933,2.9211e-5,16.868735557,0.927387188,2.257632484,4.697683068
|
||||
2,346,478,1369.0,30048.0,0.04556043663471779,0.08319682,3.5431e-5,16.871399152,0.834869326,2.264361993,4.701280771
|
||||
3,341,473,1314.0,30048.0,0.04373003194888179,0.124422234,2.392e-5,16.454231193,0.856669072,2.271991539,4.68580348
|
||||
4,336,463,1284.0,30048.0,0.042731629392971246,0.121696991,2.2921e-5,15.881542683,0.816430136,2.213686135,4.449106524
|
||||
5,331,458,1284.0,29568.0,0.04342532467532467,0.124024888,2.314e-5,15.879200155,0.799333453,2.194093083,4.435654931
|
||||
6,326,448,1254.0,29568.0,0.04241071428571429,0.121610951,2.2e-5,15.325702423,0.833341953,2.203843882,4.199677306
|
||||
7,321,438,1224.0,29568.0,0.041396103896103896,0.118972208,2.1631e-5,14.367273685,0.711553932,2.16189756,3.948872646
|
||||
8,316,433,1224.0,29088.0,0.04207920792079208,0.074826839,2.2031e-5,14.367107152,0.792981221,2.169096496,3.961630969
|
||||
9,311,428,1169.0,29088.0,0.04018839383938394,0.116237162,2.15e-5,14.416973472,0.788583102,2.092186151,3.946339564
|
||||
10,306,418,1139.0,29088.0,0.03915704070407041,0.114647398,2.031e-5,13.671420757,0.745657392,2.037551329,3.657411205
|
||||
11,301,408,1109.0,29088.0,0.03812568756875687,0.11434652,1.951e-5,13.093103664,0.686554396,2.065489584,3.441139671
|
||||
12,296,403,1109.0,28608.0,0.03876538031319911,0.112282663,1.8991e-5,13.11525848,0.705183633,2.0639299,3.422598036
|
||||
13,291,398,1109.0,28128.0,0.039426905574516495,0.111549203,1.9661e-5,13.08100601,0.700772882,2.065935946,3.41679234
|
||||
14,286,388,1079.0,28128.0,0.0383603526734926,0.109881396,1.907e-5,11.871746271,0.665244638,2.063828106,3.187580585
|
||||
15,281,378,1049.0,28128.0,0.037293799772468716,0.108444747,1.7961e-5,10.963517612,0.62180291,2.037926216,2.935137574
|
||||
16,276,373,1049.0,27648.0,0.03794126157407408,0.107959773,1.874e-5,11.021594456,0.541779823,2.003876106,2.931304737
|
||||
17,271,368,1049.0,27168.0,0.03861160188457008,0.105629068,1.8241e-5,11.017450178,0.581974375,2.017201027,2.952118903
|
||||
18,266,363,1049.0,26688.0,0.0393060551558753,0.107303406,1.8301e-5,11.028597789,0.556078309,2.037535226,2.911405619
|
||||
19,261,358,994.0,26688.0,0.03724520383693045,0.106584986,1.7111e-5,10.789192026,0.525275525,2.011931363,2.931360979
|
||||
20,256,353,939.0,26688.0,0.035184352517985615,0.105743463,1.7521e-5,10.50283261,0.535253087,1.962456949,2.941274646
|
||||
21,255,351,933.0,26688.0,0.03495953237410072,0.105189187,1.7471e-5,10.739591259,0.555102576,2.013201521,2.896175037
|
||||
22,254,350,933.0,26592.0,0.035085740072202165,0.105895137,1.6631e-5,10.68514711,0.571809578,1.974934611,2.890503396
|
||||
23,253,348,927.0,26592.0,0.0348601083032491,0.104181459,1.817e-5,10.344271645,0.572483889,2.002875753,2.842241926
|
||||
24,252,347,927.0,26496.0,0.034986413043478264,0.103568232,1.7471e-5,10.363216025,0.602207417,1.943794016,2.811132729
|
||||
25,247,342,927.0,26016.0,0.035631918819188195,0.102006829,1.669e-5,10.360319761,0.588967585,1.942523675,2.838431844
|
||||
26,246,340,921.0,26016.0,0.03540129151291513,0.103244544,1.672e-5,10.140255758,0.565172778,1.980058606,2.776594151
|
||||
27,245,339,921.0,25920.0,0.03553240740740741,0.102991317,1.723e-5,10.166352736,0.588556746,2.025713505,2.754827976
|
||||
28,244,337,915.0,25920.0,0.03530092592592592,0.102527335,1.6261e-5,9.965044496,0.527648944,1.966870364,2.708992883
|
||||
29,243,335,909.0,25920.0,0.035069444444444445,0.101020632,1.6541e-5,9.899918186,0.530837495,1.99964346,2.686936268
|
||||
30,242,334,909.0,25824.0,0.03519981412639405,0.099846559,1.614e-5,9.924451078,0.532149983,1.992832633,2.667590089
|
||||
31,241,333,909.0,25728.0,0.035331156716417914,0.103293156,1.634e-5,9.893503718,0.500188044,1.971455575,2.661440862
|
||||
32,236,328,909.0,25248.0,0.036002851711026615,0.110948742,1.5851e-5,9.916889596,0.515528547,2.014256204,2.691654688
|
||||
33,235,326,903.0,25248.0,0.03576520912547528,0.099799239,1.658e-5,9.667648582,0.561210643,1.981308261,2.647665444
|
||||
34,234,324,897.0,25248.0,0.035527566539923956,0.099455409,1.6561e-5,9.588166052,0.544847505,1.932560182,2.56349283
|
||||
35,233,323,897.0,25152.0,0.035663167938931296,0.103335368,1.6271e-5,9.590387462,0.542413718,1.965145602,2.559435691
|
||||
36,232,321,891.0,25152.0,0.03542461832061069,0.097770562,1.6571e-5,9.362808632,0.543288523,2.017894491,2.498672404
|
||||
37,231,320,891.0,25056.0,0.03556034482758621,0.100428616,1.5941e-5,9.340302395,0.548822639,1.994799194,2.525394
|
||||
38,230,319,891.0,24960.0,0.03569711538461538,0.056667955,1.5341e-5,9.356871677,0.537041949,1.921246656,2.507595034
|
||||
39,225,314,891.0,24480.0,0.036397058823529414,0.099323026,1.636e-5,9.383625024,0.506403697,1.972101141,2.529248938
|
||||
40,220,309,836.0,24480.0,0.03415032679738562,0.096789665,1.645e-5,9.524601658,0.473707387,1.980933173,2.524768525
|
||||
41,215,304,836.0,24000.0,0.034833333333333334,0.053463925,1.671e-5,9.520567128,0.487585179,1.942542795,2.535491481
|
||||
42,214,302,830.0,24000.0,0.034583333333333334,0.096303802,1.6011e-5,9.137262758,0.4297148,1.950560163,2.478408276
|
||||
43,213,301,830.0,23904.0,0.034722222222222224,0.070596338,1.6901e-5,9.143790565,0.492842898,1.949332161,2.476752284
|
||||
44,212,299,824.0,23904.0,0.034471218206157964,0.09696925,1.612e-5,9.089211511,0.456930617,2.022026121,2.419473874
|
||||
45,211,297,818.0,23904.0,0.03422021419009371,0.052526649,1.536e-5,8.807671694,0.471203239,1.970488502,2.372441242
|
||||
46,210,296,818.0,23808.0,0.03435819892473118,0.096716114,1.5701e-5,8.806210783,0.451452844,1.960073481,2.387451098
|
||||
47,209,295,818.0,23712.0,0.034497300944669365,0.05145174,1.6061e-5,8.867215342,0.450895098,1.968012818,2.394204111
|
||||
48,204,290,818.0,23232.0,0.03521005509641873,0.093248236,1.9521e-5,8.844517253,0.476030278,1.963827031,2.389413849
|
||||
49,203,288,812.0,23232.0,0.034951790633608815,0.093881584,1.527e-5,8.849095772,0.446415074,1.974782212,2.332439097
|
||||
50,202,287,812.0,23136.0,0.03509681881051176,0.050473481,1.5851e-5,8.784636116,0.469233287,1.953068913,2.321316886
|
||||
51,201,285,806.0,23136.0,0.034837482710926695,0.092750242,1.5541e-5,8.632088328,0.491467054,1.945455141,2.29300329
|
||||
52,200,284,806.0,23040.0,0.03498263888888889,0.092540087,1.7161e-5,8.637677414,0.471865872,1.975464118,2.259260411
|
||||
53,199,282,800.0,23040.0,0.034722222222222224,0.092944049,1.5261e-5,8.624992966,0.478249573,1.931707577,2.232058939
|
||||
54,198,281,800.0,22944.0,0.03486750348675035,0.091660013,1.575e-5,8.680034605,0.429976994,2.022314921,2.224544849
|
||||
55,197,279,794.0,22944.0,0.03460599721059972,0.092591389,1.582e-5,8.266084761,0.442472956,1.949268775,2.165130527
|
||||
56,196,278,794.0,22848.0,0.03475140056022409,0.090376966,1.529e-5,8.26930839,0.438461132,1.960119483,2.169387658
|
||||
57,191,273,739.0,22848.0,0.03234418767507003,0.090398736,1.589e-5,8.061516101,0.468233752,1.825342557,2.144808638
|
||||
58,186,268,739.0,22368.0,0.03303826895565093,0.090566151,1.5781e-5,8.051685873,0.472555774,1.827021946,2.175475243
|
||||
59,185,266,733.0,22368.0,0.03277002861230329,0.046301524,1.4931e-5,7.809555195,0.466519375,1.819191936,2.095906173
|
||||
60,184,264,727.0,22368.0,0.03250178826895565,0.087977349,1.4771e-5,7.825535183,0.452072238,1.820734702,2.06485156
|
||||
61,183,263,727.0,22272.0,0.032641882183908046,0.08908488,1.4591e-5,7.77560322,0.445728609,1.804235078,2.06763398
|
||||
62,182,262,727.0,22176.0,0.03278318903318903,0.076517376,1.461e-5,7.754359737,0.421063625,1.812681957,2.076417548
|
||||
63,181,260,721.0,22176.0,0.032512626262626264,0.088983767,1.4091e-5,7.616158878,0.422402602,1.868182992,2.016601005
|
||||
64,180,259,721.0,22080.0,0.03265398550724638,0.089172453,1.467e-5,7.63910266,0.402654247,1.844390793,2.031385412
|
||||
65,175,254,666.0,22080.0,0.03016304347826087,0.091971222,1.3851e-5,7.35822511,0.443635961,1.719023302,2.007792679
|
||||
66,170,249,666.0,21600.0,0.030833333333333334,0.073480651,1.3871e-5,7.291999508,0.434965958,1.750073777,1.999358953
|
||||
67,169,247,660.0,21600.0,0.030555555555555555,0.085309774,1.7211e-5,7.245192983,0.412650069,1.744681817,1.962798523
|
||||
68,168,245,654.0,21600.0,0.03027777777777778,0.089043539,1.367e-5,7.024436477,0.421292773,1.722710908,1.890918459
|
||||
69,167,243,648.0,21600.0,0.03,0.084353527,1.428e-5,6.8832018,0.415786727,1.715216258,1.830282141
|
||||
70,166,242,648.0,21504.0,0.030133928571428572,0.084367977,1.3441e-5,6.899982477,0.419080281,1.707637056,1.843529005
|
||||
71,165,241,648.0,21408.0,0.030269058295964126,0.085701815,1.4031e-5,6.936174291,0.377346024,1.704252961,1.85218872
|
||||
72,164,240,648.0,21312.0,0.030405405405405407,0.083910355,1.3601e-5,6.9051589,0.389477478,1.75740328,1.867258596
|
||||
73,159,235,593.0,21312.0,0.0278246996996997,0.082135195,1.3351e-5,7.031037571,0.356084586,1.631072,1.797434919
|
||||
74,154,230,593.0,20832.0,0.028465821812596007,0.080356395,1.358e-5,7.040766129,0.405151789,1.620631997,1.781269114
|
||||
75,153,228,587.0,20832.0,0.02817780337941628,0.066967517,1.3391e-5,6.644186555,0.395240289,1.641155866,1.743666486
|
||||
76,152,226,581.0,20832.0,0.02788978494623656,0.080763676,1.298e-5,6.633937959,0.388869331,1.630064054,1.701302723
|
||||
77,151,225,581.0,20736.0,0.028018904320987654,0.080671833,1.2781e-5,6.622133299,0.392564435,1.625932508,1.711411428
|
||||
78,150,224,581.0,20640.0,0.02814922480620155,0.080368195,1.358e-5,6.599986437,0.397419271,1.657700695,1.694756709
|
||||
79,149,222,575.0,20640.0,0.027858527131782947,0.080015475,1.298e-5,6.281191715,0.37819019,1.622522233,1.656839741
|
||||
80,148,221,575.0,20544.0,0.027988707165109036,0.065331671,1.334e-5,6.313635402,0.380955078,1.627111603,1.638795233
|
|
79
data/qed_ke-kkkkke_reduction_optimizer.csv
Normal file
79
data/qed_ke-kkkkke_reduction_optimizer.csv
Normal file
@ -0,0 +1,79 @@
|
||||
operations,graph_nodes,graph_edges,graph_ce,graph_dt,graph_ci,gen_func_t,cpu_compile_t,cpu_st_t,cpu_mt_t,gpu_compile_t,gpu_t
|
||||
0,15866,21617,66249.0,1.314048e6,0.050415966540035065,6.468999136,0.001398329,8.478099553,0.43958521,0.0,0.0
|
||||
10,14676,19713,60656.0,1.279776e6,0.0473957942639962,5.993535435,0.000745961,7.192805963,0.417393835,0.0,0.0
|
||||
20,13774,18527,56334.0,1.243296e6,0.04531020770596865,5.489738392,0.000682889,6.652182167,0.336339503,0.0,0.0
|
||||
30,13352,17940,53276.0,1.236672e6,0.04308013765978368,5.169906767,0.000675318,6.370526843,0.313517861,0.0,0.0
|
||||
40,12714,17168,51163.0,1.199712e6,0.042646068389746876,4.845906388,0.000634457,6.124306725,0.311820244,0.0,0.0
|
||||
50,12004,16270,48473.0,1.163232e6,0.04167096503534978,4.433653313,0.000596017,5.760561483,0.320897852,0.0,0.0
|
||||
60,11750,15983,48022.0,1.144224e6,0.04196905501020779,4.316924709,0.000596237,5.738809149,0.283214404,0.0,0.0
|
||||
70,11538,15697,47325.0,1.133184e6,0.04176285581158929,4.201152631,0.000554855,5.438337093,0.313985744,0.0,0.0
|
||||
80,11434,15550,46814.0,1.129536e6,0.04144533684628024,4.216359254,0.000553545,5.429706297,0.268223845,0.0,0.0
|
||||
90,11066,15085,46232.0,1.10352e6,0.041895026823256486,3.924567625,0.000560535,5.412444055,0.274917428,0.0,0.0
|
||||
100,10848,14847,44297.0,1.100352e6,0.04025711772232885,3.848048388,0.000527955,5.127227854,0.294706757,0.0,0.0
|
||||
110,10462,14382,42261.0,1.084512e6,0.038967756926617685,3.674674179,0.000509054,4.922064369,0.276530272,0.0,0.0
|
||||
120,10304,14191,41810.0,1.07472e6,0.038903156170909635,3.58233155,0.000516074,5.02371138,0.266906519,0.0,0.0
|
||||
130,10200,14067,41437.0,1.068864e6,0.03876732680677804,3.529160319,0.000501634,4.863804478,0.24639169,0.0,0.0
|
||||
140,10042,13871,40956.0,1.059552e6,0.03865407266467337,3.346890818,0.000488403,4.753116119,0.254509861,0.0,0.0
|
||||
150,9956,13765,40583.0,1.055424e6,0.038451844945727974,3.41847396,0.000500654,4.756966153,0.255966291,0.0,0.0
|
||||
160,9906,13690,40433.0,1.053024e6,0.03839703558513386,3.405093274,0.000496774,4.812050085,0.24421971,0.0,0.0
|
||||
170,9838,13597,40283.0,1.048896e6,0.038405142168527674,3.348340057,0.000481363,4.669473296,0.234701411,0.0,0.0
|
||||
180,9242,12790,37708.0,1.02336e6,0.03684724828017511,3.063089187,0.000449352,4.335668832,0.228471471,0.0,0.0
|
||||
190,9120,12648,37082.0,1.017984e6,0.03642689865459575,2.994073054,0.000429002,4.181894908,0.224361729,0.0,0.0
|
||||
200,9052,12555,36932.0,1.013856e6,0.03642726383233911,3.046147594,0.000427282,4.151250123,0.212513705,0.0,0.0
|
||||
210,8912,12405,36366.0,1.005792e6,0.03615658108237091,2.937579863,0.000433982,4.261727394,0.214012817,0.0,0.0
|
||||
220,8808,12281,35993.0,999936.0,0.035995303699436765,2.892146284,0.000432382,4.198423468,0.219749812,0.0,0.0
|
||||
230,8626,12061,35765.0,986112.0,0.03626869970145379,2.752333211,0.000414672,4.035044142,0.241721263,0.0,0.0
|
||||
240,8426,11841,34336.0,980256.0,0.03502758463095355,2.714773746,0.000414522,4.036870861,0.235365769,0.0,0.0
|
||||
250,8118,11464,33416.0,961728.0,0.03474579090969588,2.579966689,0.000402461,3.870568035,0.20937257,0.0,0.0
|
||||
260,7942,11242,32634.0,953664.0,0.034219599355747934,2.520293442,0.000391581,3.72881432,0.191238985,0.0,0.0
|
||||
270,7838,11100,32153.0,949536.0,0.0338618019748593,2.456319106,0.000383211,3.635092003,0.187908484,0.0,0.0
|
||||
280,7716,10940,31672.0,943680.0,0.033562224482875554,2.402192681,0.00037687,3.594882506,0.194062713,0.0,0.0
|
||||
290,7576,10772,30745.0,939552.0,0.032723042471305475,2.338714319,0.00037334,3.556085038,0.194369971,0.0,0.0
|
||||
300,7376,10529,30487.0,924480.0,0.0329774575977847,2.279512925,0.00036552,3.504723807,0.191079171,0.0,0.0
|
||||
310,7218,10310,29868.0,917376.0,0.03255807869401423,2.207692656,0.000355539,3.30937664,0.181261073,0.0,0.0
|
||||
320,7078,10137,29417.0,909312.0,0.03235083227759009,2.147511905,0.000352659,3.30461376,0.18005858,0.0,0.0
|
||||
330,6860,9848,28991.0,895200.0,0.032384941912421805,2.078259266,0.00033941,3.211808988,0.172834084,0.0,0.0
|
||||
340,6702,9611,28264.0,889824.0,0.03176358470888625,2.069880378,0.000318959,3.033092324,0.154811992,0.0,0.0
|
||||
350,6616,9505,27891.0,885696.0,0.03149048883589855,2.005510172,0.000326369,3.008426711,0.173417779,0.0,0.0
|
||||
360,6512,9391,27325.0,881088.0,0.03101279327377061,1.968347618,0.000315789,2.921325386,0.168873786,0.0,0.0
|
||||
370,6426,9280,27175.0,875232.0,0.03104891046031224,1.92734893,0.000315548,2.990437001,0.181187901,0.0,0.0
|
||||
380,6358,9187,27025.0,871104.0,0.031023850194695467,1.889258172,0.000308689,2.846738111,0.181651873,0.0,0.0
|
||||
390,6272,9081,26652.0,866976.0,0.030741335400287898,1.840892272,0.000329279,2.825270586,0.177422669,0.0,0.0
|
||||
400,6204,8993,26532.0,862368.0,0.03076644773460982,1.820608708,0.000296329,2.759355249,0.175583708,0.0,0.0
|
||||
410,6118,8864,26274.0,858240.0,0.030613814317673377,1.783961229,0.000290708,2.707626007,0.172954176,0.0,0.0
|
||||
420,6014,8740,25901.0,852384.0,0.030386539400082593,1.774576254,0.000288998,2.694176581,0.173939173,0.0,0.0
|
||||
430,5928,8629,25498.0,848736.0,0.030042321758473777,1.7065974,0.000284277,2.675798329,0.170062674,0.0,0.0
|
||||
440,5842,8523,25125.0,844608.0,0.029747527847238008,1.685087395,0.000287118,2.688215586,0.166480549,0.0,0.0
|
||||
450,5738,8399,24752.0,838752.0,0.02951051085422151,1.673553823,0.000274969,2.523253333,0.167824913,0.0,0.0
|
||||
460,5670,8316,24662.0,833664.0,0.02958266159987717,1.625105871,0.000272178,2.52817126,0.164730041,0.0,0.0
|
||||
470,5548,8161,24211.0,827328.0,0.029264088729016785,1.583826656,0.000262318,2.419247276,0.160768733,0.0,0.0
|
||||
480,5426,8006,23760.0,820992.0,0.028940598690364826,1.58433006,0.000264708,2.454129792,0.155746163,0.0,0.0
|
||||
490,5358,7918,23640.0,816384.0,0.028956961429915332,1.520887155,0.000253268,2.329551174,0.153813499,0.0,0.0
|
||||
500,5272,7807,23237.0,812736.0,0.02859108000629971,1.488167166,0.000248837,2.282665244,0.154234105,0.0,0.0
|
||||
510,5150,7647,22756.0,806880.0,0.028202458853856832,1.448681065,0.000247727,2.275316917,0.149501885,0.0,0.0
|
||||
520,5028,7487,22022.0,803232.0,0.02741673638500458,1.43939862,0.000236057,2.14942739,0.146771977,0.0,0.0
|
||||
530,4906,7350,21679.0,795168.0,0.02726342106322186,1.367826149,0.000242258,2.188588822,0.148076932,0.0,0.0
|
||||
540,4838,7257,21529.0,791040.0,0.027216069983818772,1.341798982,0.000230357,2.096237881,0.141709174,0.0,0.0
|
||||
550,4752,7151,21156.0,786912.0,0.02688483591557887,1.339939443,0.000227267,2.062687036,0.13782156,0.0,0.0
|
||||
560,4684,7068,21066.0,781824.0,0.026944683202357565,1.327848904,0.000222317,2.00294804,0.139508498,0.0,0.0
|
||||
570,4634,6993,20916.0,779424.0,0.02683520137948023,1.276183945,0.000224717,2.021180753,0.13573571,0.0,0.0
|
||||
580,4548,6882,20766.0,773568.0,0.026844440307768676,1.235522514,0.000212457,1.917354147,0.128401984,0.0,0.0
|
||||
590,4498,6807,20616.0,771168.0,0.026733474418025645,1.267249751,0.000212506,1.899792552,0.133449083,0.0,0.0
|
||||
600,4376,6657,20195.0,764352.0,0.0264210730134807,1.209891149,0.000205326,1.850663451,0.129490109,0.0,0.0
|
||||
610,4326,6582,20045.0,761952.0,0.026307431439250767,1.18887911,0.000203196,1.819359467,0.129183977,0.0,0.0
|
||||
620,4204,6422,19564.0,756096.0,0.02587502116133401,1.172245936,0.000212366,1.757557943,0.125887084,0.0,0.0
|
||||
630,3836,5980,17558.0,741504.0,0.02367890126014155,1.043747354,0.000175996,1.554965777,0.115650062,0.0,0.0
|
||||
640,3732,5856,17438.0,733440.0,0.023775632635253053,1.010298683,0.000174715,1.562411059,0.113877446,0.0,0.0
|
||||
650,3628,5714,16957.0,729312.0,0.023250680093019175,0.985957627,0.000170445,1.474744854,0.110990727,0.0,0.0
|
||||
660,3506,5549,16446.0,723936.0,0.022717477788091765,0.948042334,0.000161975,1.420057878,0.106426767,0.0,0.0
|
||||
670,3420,5448,16103.0,719328.0,0.0223861715378798,0.921840457,0.000156765,1.356400004,0.10491163,0.0,0.0
|
||||
680,3316,5319,15700.0,713952.0,0.021990273855945496,0.892707383,0.000162605,1.335548894,0.100909488,0.0,0.0
|
||||
690,3212,5200,15357.0,707616.0,0.02170244878578212,0.89578919,0.000149085,1.299462304,0.099173414,0.0,0.0
|
||||
700,2916,4871,13850.0,693792.0,0.019962755407960886,0.781393124,0.000134984,1.179737113,0.096642976,0.0,0.0
|
||||
710,2722,4598,13123.0,684960.0,0.019158782994627425,0.725161332,0.000122213,1.056813282,0.08619269,0.0,0.0
|
||||
720,2636,4492,12750.0,680832.0,0.018727086858432038,0.701632434,0.000128984,1.019551067,0.085388434,0.0,0.0
|
||||
730,2532,4373,12407.0,674496.0,0.018394475282284845,0.675037355,0.000119134,0.993660466,0.082709493,0.0,0.0
|
||||
740,2428,4231,11926.0,670368.0,0.017790228650532244,0.6435086,0.000109403,0.927737064,0.078423743,0.0,0.0
|
||||
750,2342,4125,11553.0,666240.0,0.017340597982708934,0.619218823,0.000106693,0.883708241,0.075467284,0.0,0.0
|
||||
760,2274,4032,11403.0,662112.0,0.017222161809482384,0.635081649,0.000103493,0.919860114,0.074058132,0.0,0.0
|
||||
770,2234,3977,11313.0,659712.0,0.017148392025611175,0.593953439,0.000110543,0.84404911,0.077019298,0.0,0.0
|
|
@ -27,6 +27,7 @@ makedocs(
|
||||
"Diff" => "lib/internals/diff.md",
|
||||
"Utility" => "lib/internals/utility.md",
|
||||
"Code Generation" => "lib/internals/code_gen.md",
|
||||
"Devices" => "lib/internals/devices.md",
|
||||
],
|
||||
"Contribution" => "contribution.md",
|
||||
],
|
||||
|
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>
|
75
docs/src/flowchart.drawio
Normal file
75
docs/src/flowchart.drawio
Normal file
@ -0,0 +1,75 @@
|
||||
<mxfile host="Electron" modified="2023-09-17T13:34:45.840Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.1 Chrome/114.0.5735.134 Electron/25.6.0 Safari/537.36" etag="e0c8qLevhaP_q_R2fyC9" version="21.6.1" type="device">
|
||||
<diagram name="Page-1" id="Vy0cA1nkMPfy-3cC5ahA">
|
||||
<mxGraphModel dx="1185" dy="707" 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="yG8qeggDCLqQ8GwY7ugi-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" edge="1" parent="1" source="yG8qeggDCLqQ8GwY7ugi-1" target="yG8qeggDCLqQ8GwY7ugi-2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-1" value="Process Generator Script" style="rounded=1;whiteSpace=wrap;html=1;shadow=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="120" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" edge="1" parent="1" source="yG8qeggDCLqQ8GwY7ugi-2" target="yG8qeggDCLqQ8GwY7ugi-3">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-2" value="Process Parser" style="rounded=1;whiteSpace=wrap;html=1;shadow=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="220" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;shadow=1;" edge="1" parent="1" source="yG8qeggDCLqQ8GwY7ugi-3" target="yG8qeggDCLqQ8GwY7ugi-6">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" edge="1" parent="1" source="yG8qeggDCLqQ8GwY7ugi-3" target="yG8qeggDCLqQ8GwY7ugi-12">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-3" value="Optimizer" style="rounded=1;whiteSpace=wrap;html=1;shadow=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="320" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.75;entryDx=0;entryDy=0;exitX=0;exitY=0.75;exitDx=0;exitDy=0;shadow=1;" edge="1" parent="1" source="yG8qeggDCLqQ8GwY7ugi-6" target="yG8qeggDCLqQ8GwY7ugi-3">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-6" value="Fast Cost Estimator<br>(Global Metrics)" style="rounded=1;whiteSpace=wrap;html=1;shadow=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="340" y="320" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" edge="1" parent="1" source="yG8qeggDCLqQ8GwY7ugi-12" target="yG8qeggDCLqQ8GwY7ugi-13">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="80" y="450" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-12" value="Scheduler" style="rounded=1;whiteSpace=wrap;html=1;shadow=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="420" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;shadow=1;" edge="1" parent="1" source="yG8qeggDCLqQ8GwY7ugi-13" target="yG8qeggDCLqQ8GwY7ugi-3">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="120" y="380" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="80" y="350" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;shadow=1;" edge="1" parent="1" source="yG8qeggDCLqQ8GwY7ugi-12" target="yG8qeggDCLqQ8GwY7ugi-18">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="240" y="500" />
|
||||
<mxPoint x="240" y="500" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-13" value="Accurate Cost Estimator<br>(Machine Specific)" style="rounded=1;whiteSpace=wrap;html=1;shadow=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="370" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;shadow=1;" edge="1" parent="1" source="yG8qeggDCLqQ8GwY7ugi-18" target="yG8qeggDCLqQ8GwY7ugi-20">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-18" value="Code Generator" style="rounded=1;whiteSpace=wrap;html=1;shadow=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="520" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yG8qeggDCLqQ8GwY7ugi-20" value="Executor" style="rounded=1;whiteSpace=wrap;html=1;shadow=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="180" y="620" width="120" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
@ -1,8 +1,23 @@
|
||||
# Code Generation
|
||||
|
||||
## Main
|
||||
## Types
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["code_gen/main.jl"]
|
||||
Pages = ["code_gen/type.jl"]
|
||||
Order = [:type, :constant, :function]
|
||||
```
|
||||
|
||||
## Function Generation
|
||||
Implementations for generation of a callable function. A function generated this way cannot immediately be called. One Julia World Age has to pass before this is possible, which happens when the global Julia scope advances. If the DAG and therefore the generated function becomes too large, use the tape machine instead, since compiling large functions becomes infeasible.
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["code_gen/function.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
## Tape Machine
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["code_gen/tabe_machine.jl"]
|
||||
Order = [:function]
|
||||
```
|
59
docs/src/lib/internals/devices.md
Normal file
59
docs/src/lib/internals/devices.md
Normal file
@ -0,0 +1,59 @@
|
||||
# Devices
|
||||
|
||||
## Interface
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["devices/interface.jl"]
|
||||
Order = [:type, :constant, :function]
|
||||
```
|
||||
|
||||
## Detect
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["devices/detect.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
## Measure
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["devices/measure.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
## Implementations
|
||||
|
||||
### General
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["devices/impl.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
||||
|
||||
### NUMA
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["devices/numa/impl.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
||||
|
||||
### CUDA
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["devices/cuda/impl.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
||||
|
||||
### ROCm
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["devices/rocm/impl.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
||||
|
||||
### oneAPI
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["devices/oneapi/impl.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
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]
|
||||
```
|
@ -1,5 +1,21 @@
|
||||
# Models
|
||||
|
||||
## Interface
|
||||
|
||||
The interface that has to be implemented for a model to be usable is defined in `src/models/interface.jl`.
|
||||
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/interface.jl"]
|
||||
Order = [:type, :constant, :function]
|
||||
```
|
||||
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/print.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
## ABC-Model
|
||||
|
||||
### Types
|
||||
@ -44,6 +60,67 @@ Pages = ["models/abc/compute.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
### Print
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["models/abc/print.jl"]
|
||||
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]
|
||||
```
|
22
docs/src/lib/internals/scheduler.md
Normal file
22
docs/src/lib/internals/scheduler.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Scheduler
|
||||
|
||||
## Interface
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["scheduler/interface.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
||||
|
||||
## Types
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["scheduler/type.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
||||
|
||||
## Greedy
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["scheduler/greedy.jl"]
|
||||
Order = [:type, :function]
|
||||
```
|
@ -21,16 +21,16 @@ Pages = ["task/compare.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
## Compute
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["task/compute.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
## Properties
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["task/properties.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
||||
## Print
|
||||
```@autodocs
|
||||
Modules = [MetagraphOptimization]
|
||||
Pages = ["task/print.jl"]
|
||||
Order = [:function]
|
||||
```
|
||||
|
@ -1,3 +1,7 @@
|
||||
# Manual
|
||||
|
||||
This will become a manual.
|
||||
## Jupyter Notebooks
|
||||
|
||||
In the `notebooks` directory are notebooks containing some examples of the usage of this repository.
|
||||
|
||||
- `abc_model_showcase`: A simple showcase of the intended usage of the ABC Model implementation.
|
||||
|
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
@ -1,3 +1,9 @@
|
||||
[deps]
|
||||
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
|
||||
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
||||
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
|
||||
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
||||
MetagraphOptimization = "3e869610-d48d-4942-ba70-c1b702a33ca4"
|
||||
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||
QEDprocesses = "46de9c38-1bb3-4547-a1ec-da24d767fdad"
|
||||
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
|
||||
|
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))
|
@ -13,16 +13,15 @@ function bench_txt(filepath::String, bench::Bool = true)
|
||||
return
|
||||
end
|
||||
|
||||
model = ABCModel()
|
||||
|
||||
println(name, ":")
|
||||
g = parse_abc(filepath)
|
||||
g = parse_dag(filepath, model)
|
||||
print(g)
|
||||
println(
|
||||
" Graph size in memory: ",
|
||||
bytes_to_human_readable(MetagraphOptimization.mem(g)),
|
||||
)
|
||||
println(" Graph size in memory: ", bytes_to_human_readable(MetagraphOptimization.mem(g)))
|
||||
|
||||
if (bench)
|
||||
@btime parse_abc($filepath)
|
||||
@btime parse_dag($filepath, $model)
|
||||
end
|
||||
|
||||
println(" Get Operations: ")
|
||||
|
@ -12,7 +12,7 @@ function gen_plot(filepath)
|
||||
return
|
||||
end
|
||||
|
||||
g = parse_abc(filepath)
|
||||
g = parse_dag(filepath, ABCModel())
|
||||
|
||||
Random.seed!(1)
|
||||
|
||||
@ -48,23 +48,10 @@ function gen_plot(filepath)
|
||||
|
||||
println("\rDone.")
|
||||
|
||||
plot(
|
||||
[x[1], x[2]],
|
||||
[y[1], y[2]],
|
||||
linestyle = :solid,
|
||||
linewidth = 1,
|
||||
color = :red,
|
||||
legend = false,
|
||||
)
|
||||
plot([x[1], x[2]], [y[1], y[2]], linestyle = :solid, linewidth = 1, color = :red, legend = false)
|
||||
# Create lines connecting the reference point to each data point
|
||||
for i in 3:length(x)
|
||||
plot!(
|
||||
[x[i - 1], x[i]],
|
||||
[y[i - 1], y[i]],
|
||||
linestyle = :solid,
|
||||
linewidth = 1,
|
||||
color = :red,
|
||||
)
|
||||
plot!([x[i - 1], x[i]], [y[i - 1], y[i]], linestyle = :solid, linewidth = 1, color = :red)
|
||||
end
|
||||
|
||||
return gui()
|
||||
|
@ -12,7 +12,7 @@ function gen_plot(filepath)
|
||||
return
|
||||
end
|
||||
|
||||
g = parse_abc(filepath)
|
||||
g = parse_dag(filepath, ABCModel())
|
||||
|
||||
Random.seed!(1)
|
||||
|
||||
@ -60,14 +60,7 @@ function gen_plot(filepath)
|
||||
push!(y, props.computeEffort)
|
||||
pop_operation!(g)
|
||||
|
||||
push!(
|
||||
names,
|
||||
"NF: (" *
|
||||
string(props.data) *
|
||||
", " *
|
||||
string(props.computeEffort) *
|
||||
")",
|
||||
)
|
||||
push!(names, "NF: (" * string(props.data) * ", " * string(props.computeEffort) * ")")
|
||||
end
|
||||
for op in opt.nodeReductions
|
||||
push_operation!(g, op)
|
||||
@ -76,14 +69,7 @@ function gen_plot(filepath)
|
||||
push!(y, props.computeEffort)
|
||||
pop_operation!(g)
|
||||
|
||||
push!(
|
||||
names,
|
||||
"NR: (" *
|
||||
string(props.data) *
|
||||
", " *
|
||||
string(props.computeEffort) *
|
||||
")",
|
||||
)
|
||||
push!(names, "NR: (" * string(props.data) * ", " * string(props.computeEffort) * ")")
|
||||
end
|
||||
for op in opt.nodeSplits
|
||||
push_operation!(g, op)
|
||||
@ -92,33 +78,13 @@ function gen_plot(filepath)
|
||||
push!(y, props.computeEffort)
|
||||
pop_operation!(g)
|
||||
|
||||
push!(
|
||||
names,
|
||||
"NS: (" *
|
||||
string(props.data) *
|
||||
", " *
|
||||
string(props.computeEffort) *
|
||||
")",
|
||||
)
|
||||
push!(names, "NS: (" * string(props.data) * ", " * string(props.computeEffort) * ")")
|
||||
end
|
||||
|
||||
plot(
|
||||
[x0, x[1]],
|
||||
[y0, y[1]],
|
||||
linestyle = :solid,
|
||||
linewidth = 1,
|
||||
color = :red,
|
||||
legend = false,
|
||||
)
|
||||
plot([x0, x[1]], [y0, y[1]], linestyle = :solid, linewidth = 1, color = :red, legend = false)
|
||||
# Create lines connecting the reference point to each data point
|
||||
for i in 2:length(x)
|
||||
plot!(
|
||||
[x0, x[i]],
|
||||
[y0, y[i]],
|
||||
linestyle = :solid,
|
||||
linewidth = 1,
|
||||
color = :red,
|
||||
)
|
||||
plot!([x0, x[i]], [y0, y[i]], linestyle = :solid, linewidth = 1, color = :red)
|
||||
end
|
||||
#scatter!(x, y, label=names)
|
||||
|
||||
|
@ -1,59 +0,0 @@
|
||||
|
||||
function test_random_walk(g::DAG, n::Int64)
|
||||
# the purpose here is to do "random" operations and reverse them again and validate that the graph stays the same and doesn't diverge
|
||||
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 reset_graph!(g)
|
||||
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
|
148
examples/qed_bench.jl
Normal file
148
examples/qed_bench.jl
Normal file
@ -0,0 +1,148 @@
|
||||
using MetagraphOptimization
|
||||
using LIKWID
|
||||
using CUDA
|
||||
using UUIDs
|
||||
|
||||
function cpu_bench(compute_function, inputs)
|
||||
compute_function.(inputs[begin:10]) # make sure it's compiled
|
||||
|
||||
time = @elapsed Threads.@threads for i in eachindex(inputs)
|
||||
@invokelatest compute_function(inputs[i])
|
||||
end
|
||||
rate = length(inputs) / time
|
||||
return (time, rate)
|
||||
end
|
||||
|
||||
function gpu_bench(compute_function, inputs)
|
||||
CUDA.@sync compute_function.(inputs[begin:10]) # make sure it's compiled
|
||||
|
||||
time = @elapsed CUDA.@sync compute_function.(inputs)
|
||||
rate = length(inputs) / time
|
||||
|
||||
return (time, rate)
|
||||
end
|
||||
|
||||
function bench_process(
|
||||
process::MetagraphOptimization.AbstractProcessDescription,
|
||||
func,
|
||||
io::IO = stdout;
|
||||
use_likwid = true,
|
||||
)
|
||||
println(io, "\n--- Benchmarking $(process) ---")
|
||||
|
||||
NFLOPs = GraphProperties(graph).computeEffort
|
||||
if use_likwid
|
||||
input = gen_process_input(process)
|
||||
func(input) # compile first
|
||||
_, events = @perfmon "FLOPS_DP" func(input)
|
||||
NFLOPs = first(events["FLOPS_DP"])["RETIRED_SSE_AVX_FLOPS_ALL"]
|
||||
end
|
||||
|
||||
nInputs = 10000000 # ten million
|
||||
println(io, "Generating $nInputs inputs with $(Threads.nthreads()) threads...")
|
||||
|
||||
inputs = Vector{typeof(gen_process_input(process))}()
|
||||
resize!(inputs, nInputs)
|
||||
processes = Vector{typeof(process)}()
|
||||
for i in 1:Threads.nthreads()
|
||||
push!(processes, copy(process))
|
||||
end
|
||||
|
||||
Threads.@threads for i in eachindex(inputs)
|
||||
inputs[i] = gen_process_input(processes[Threads.nthreads()])
|
||||
end
|
||||
|
||||
println(io, "Benchmarking CPU with $(Threads.nthreads()) threads...")
|
||||
(time_cpu, rate_cpu) = cpu_bench(func, inputs)
|
||||
flops_cpu = (rate_cpu * NFLOPs) / 1024^3
|
||||
|
||||
println(io, "Benchmarking GPU...")
|
||||
cuInputs = CuArray(inputs)
|
||||
(time_gpu, rate_gpu) = gpu_bench(func, cuInputs)
|
||||
flops_gpu = (rate_gpu * NFLOPs) / 1024^3
|
||||
|
||||
println(io, "\nBenchmark Summary for $(process):")
|
||||
|
||||
if use_likwid
|
||||
println(io, "Measured FLOPS by LIKWID: $NFLOPs")
|
||||
else
|
||||
println(io, "Total graph compute effort: $NFLOPs")
|
||||
end
|
||||
println(io, "Total input size: $(bytes_to_human_readable(Base.summarysize(inputs)))")
|
||||
println(io, "CPU, $(Threads.nthreads()) threads")
|
||||
println(io, " Time: $time_cpu")
|
||||
println(io, " Rate: $rate_cpu")
|
||||
println(io, " GFLOPS: $flops_cpu")
|
||||
println(io, "GPU, $(name(first(CUDA.devices())))")
|
||||
println(io, " Time: $time_gpu")
|
||||
println(io, " Rate: $rate_gpu")
|
||||
return println(io, " GFLOPS: $flops_gpu")
|
||||
end
|
||||
|
||||
# use "mock" machine that only uses cpu
|
||||
machine = Machine(
|
||||
[
|
||||
MetagraphOptimization.NumaNode(
|
||||
0,
|
||||
1,
|
||||
MetagraphOptimization.default_strategy(MetagraphOptimization.NumaNode),
|
||||
-1.0,
|
||||
UUIDs.uuid1(),
|
||||
),
|
||||
],
|
||||
[-1.0;;],
|
||||
)
|
||||
optimizer = ReductionOptimizer()
|
||||
|
||||
# sadly cannot put these in functions because the world age must increase after the function is created which happens only in the global scope
|
||||
|
||||
# compton
|
||||
process = parse_process("ke->ke", QEDModel())
|
||||
graph = gen_graph(process)
|
||||
optimize_to_fixpoint!(optimizer, graph)
|
||||
compute_func = get_compute_function(graph, process, machine)
|
||||
bench_process(process, compute_func)
|
||||
|
||||
# 2-photon compton
|
||||
process = parse_process("ke->kke", QEDModel())
|
||||
graph = gen_graph(process)
|
||||
optimize_to_fixpoint!(optimizer, graph)
|
||||
compute_func = get_compute_function(graph, process, machine)
|
||||
bench_process(process, compute_func)
|
||||
|
||||
# 3-photon compton
|
||||
process = parse_process("ke->kkke", QEDModel())
|
||||
graph = gen_graph(process)
|
||||
optimize_to_fixpoint!(optimizer, graph)
|
||||
compute_func = get_compute_function(graph, process, machine)
|
||||
bench_process(process, compute_func)
|
||||
|
||||
# AB->AB
|
||||
process = parse_process("AB->AB", ABCModel())
|
||||
graph = parse_dag("input/AB->AB.txt", ABCModel())
|
||||
optimize_to_fixpoint!(optimizer, graph)
|
||||
compute_func = get_compute_function(graph, process, machine)
|
||||
bench_process(process, compute_func)
|
||||
|
||||
# AB->AB^3
|
||||
process = parse_process("AB->ABBB", ABCModel())
|
||||
graph = parse_dag("input/AB->ABBB.txt", ABCModel())
|
||||
optimize_to_fixpoint!(optimizer, graph)
|
||||
compute_func = get_compute_function(graph, process, machine)
|
||||
bench_process(process, compute_func)
|
||||
|
||||
exit(0)
|
||||
|
||||
# 4-photon compton
|
||||
process = parse_process("ke->kkkke", QEDModel())
|
||||
graph = gen_graph(process)
|
||||
optimize_to_fixpoint!(optimizer, graph)
|
||||
compute_func = get_compute_function(graph, process, machine)
|
||||
bench_process(process, compute_func)
|
||||
|
||||
# AB->AB^5
|
||||
process = parse_process("AB->ABBBBB", ABCModel())
|
||||
graph = parse_dag("input/AB->ABBBBB.txt", ABCModel())
|
||||
optimize_to_fixpoint!(optimizer, graph)
|
||||
compute_func = get_compute_function(graph, process, machine)
|
||||
bench_process(process, compute_func)
|
542
examples/reduction.ipynb
Normal file
542
examples/reduction.ipynb
Normal file
File diff suppressed because one or more lines are too long
BIN
images/qed_ke-kke_exec_1000000_inputs.pdf
Normal file
BIN
images/qed_ke-kke_exec_1000000_inputs.pdf
Normal file
Binary file not shown.
BIN
images/qed_ke-kke_graph_properties.pdf
Normal file
BIN
images/qed_ke-kke_graph_properties.pdf
Normal file
Binary file not shown.
BIN
images/qed_ke-kkke_exec_1000000_inputs.pdf
Normal file
BIN
images/qed_ke-kkke_exec_1000000_inputs.pdf
Normal file
Binary file not shown.
BIN
images/qed_ke-kkke_graph_properties.pdf
Normal file
BIN
images/qed_ke-kkke_graph_properties.pdf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
images/qed_ke-kkkke_exec_100000_inputs.pdf
Normal file
BIN
images/qed_ke-kkkke_exec_100000_inputs.pdf
Normal file
Binary file not shown.
BIN
images/qed_ke-kkkke_graph_properties.pdf
Normal file
BIN
images/qed_ke-kkkke_graph_properties.pdf
Normal file
Binary file not shown.
BIN
images/qed_ke-kkkkke_exec_10000_inputs.pdf
Normal file
BIN
images/qed_ke-kkkkke_exec_10000_inputs.pdf
Normal file
Binary file not shown.
BIN
images/qed_ke-kkkkke_graph_properties.pdf
Normal file
BIN
images/qed_ke-kkkkke_graph_properties.pdf
Normal file
Binary file not shown.
Binary file not shown.
429
notebooks/abc_model_large.ipynb
Normal file
429
notebooks/abc_model_large.ipynb
Normal file
@ -0,0 +1,429 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"using MetagraphOptimization"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"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": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Graph:\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->ABBBBB\"\n",
|
||||
"process = parse_process(process_str, model)\n",
|
||||
"graph = parse_dag(\"../input/$process_str.txt\", model)\n",
|
||||
"print(graph)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"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": [
|
||||
" 0.184484 seconds (2.75 M allocations: 153.561 MiB, 15.46% gc time)\n",
|
||||
"Graph:\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": [
|
||||
"@time optimize_to_fixpoint!(ReductionOptimizer(), graph)\n",
|
||||
"print(graph)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" 0.822702 seconds (574.85 k allocations: 48.098 MiB, 0.90% gc time)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"compute__8dffb17a_8f2e_11ee_2d70_13a063f6b2e1 (generic function with 1 method)"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"@time compute_AB_AB5_reduced = get_compute_function(graph, process, machine)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" 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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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->ABBBBB':\n",
|
||||
" 2 Incoming particles:\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"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"@time inputs = [gen_process_input(process) for _ in 1:1000]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"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",
|
||||
"#compute_bench = @benchmark compute_AB_AB5.(inputs)\n",
|
||||
"compute_bench_reduced = @benchmark compute_AB_AB5_reduced.(inputs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
407
notebooks/abc_model_showcase.ipynb
Normal file
407
notebooks/abc_model_showcase.ipynb
Normal file
@ -0,0 +1,407 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "20768e45-df62-4638-ba33-b0ccf239f1aa",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"using Revise\n",
|
||||
"using MetagraphOptimization\n",
|
||||
"using BenchmarkTools"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "ff5f4a49",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Found 1 NUMA nodes\n",
|
||||
"CUDA is non-functional\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Machine(MetagraphOptimization.AbstractDevice[MetagraphOptimization.NumaNode(0x0000, 0x0001, MetagraphOptimization.LocalVariables(), -1.0, UUID(\"a89974f6-6212-11ee-0866-0f591a3b69ea\"))], [-1.0;;])"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Get our machine's info\n",
|
||||
"machine = get_machine_info()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "9df482a4-ca44-44c5-9ea7-7a2977d529be",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"ABCModel()"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Create a model identifier\n",
|
||||
"model = ABCModel()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "30b16872-07f7-4d47-8ff8-8c3a849c9d4e",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"ABC Process: 'AB->ABBB'"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Create a process in our model\n",
|
||||
"process_str = \"AB->ABBB\"\n",
|
||||
"process = parse_process(process_str, model)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "043bd9e2-f89a-4362-885a-8c89d4cdd76f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Total: 280, ComputeTaskABC_P"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Graph:\n",
|
||||
" Nodes: \n",
|
||||
" Edges: 385\n",
|
||||
" Total Compute Effort: 1075.0\n",
|
||||
" Total Data Transfer: 10944.0\n",
|
||||
" Total Compute Intensity: 0.09822733918128655\n"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
": 6, ComputeTaskABC_U: 6, \n",
|
||||
" ComputeTaskABC_V: 64, ComputeTaskABC_Sum: 1, ComputeTaskABC_S2: 24, \n",
|
||||
" ComputeTaskABC_S1: 36, DataTask: 143"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Read the graph (of the same process) from a file\n",
|
||||
"graph = parse_dag(\"../input/$process_str.txt\", model)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "02f01ad3-fd10-48d5-a0e0-c03dc83c80a4",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Input for ABC Process: 'AB->ABBB':\n",
|
||||
" 2 Incoming particles:\n",
|
||||
" A: [5.77986599979293, 0.0, 0.0, 5.692701553354288]\n",
|
||||
" B: [5.77986599979293, 0.0, 0.0, -5.692701553354288]\n",
|
||||
" 4 Outgoing Particles:\n",
|
||||
" A: [-3.8835293143673746, -1.4292027910861678, 2.8576090179942106, 1.968057422378813]\n",
|
||||
" B: [-1.1554024905063585, -0.1464656500147254, -0.2082400426692148, 0.5197487980391896]\n",
|
||||
" B: [-2.849749730594798, -1.0177034035100576, -2.464951858896686, -0.09677625137882176]\n",
|
||||
" B: [-3.6710504641173287, 2.5933718446109513, -0.1844171164283155, -2.391029969039186]\n"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Generate some random input data for our process\n",
|
||||
"input_data = gen_process_input(process)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "083fb1be-ce2a-47f9-afb9-60a6fdfaed0b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"compute__af4450a2_6212_11ee_2601_cde7cf2aedc1 (generic function with 1 method)"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Get the function computing the result of the process from a ProcessInput\n",
|
||||
"AB_AB3_compute = get_compute_function(graph, process, machine)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "a40c9500-8f79-4f04-b3c5-59b72a6b7ba9",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"-1.8924431710735022e-13"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Actually compute a result using the generated function and the input data\n",
|
||||
"result = AB_AB3_compute(input_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "80c70010",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# We can also mute the graph by applying some operations to it\n",
|
||||
"optimize_to_fixpoint!(ReductionOptimizer(), graph)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "5b192b44",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# The result should be the same as before (we can use execute to save having to generate the function ourselves)\n",
|
||||
"@assert result ≈ execute(graph, process, machine, input_data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "9b2f4a3f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1000-element Vector{Float64}:\n",
|
||||
" -2.1491995259940396e-11\n",
|
||||
" -1.04995646459455e-11\n",
|
||||
" 5.821760691187782e-15\n",
|
||||
" -6.556969485683705e-14\n",
|
||||
" -1.3588086164373753e-14\n",
|
||||
" -1.8789662441593694e-13\n",
|
||||
" -2.131973301835892e-13\n",
|
||||
" -5.3359759072004825e-12\n",
|
||||
" -9.053914191490223e-13\n",
|
||||
" -5.61107901706923e-13\n",
|
||||
" -5.063492275603428e-11\n",
|
||||
" 2.9168508985811397e-15\n",
|
||||
" -1.6420151378194157e-13\n",
|
||||
" ⋮\n",
|
||||
" 1.0931677247833436e-13\n",
|
||||
" -7.704755306462797e-16\n",
|
||||
" -1.8385907037491397e-12\n",
|
||||
" -6.036215596560059e-14\n",
|
||||
" -9.98872401400362e-12\n",
|
||||
" 3.4861755637292935e-13\n",
|
||||
" -1.1051119822969222e-10\n",
|
||||
" -2.496572513216201e-12\n",
|
||||
" -3.8682427847201926e-11\n",
|
||||
" 7.904149696653438e-15\n",
|
||||
" -7.606811743178716e-11\n",
|
||||
" -5.100594937480292e-13"
|
||||
]
|
||||
},
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Now we can generate a function and use it on lots of inputs\n",
|
||||
"inputs = [gen_process_input(process) for _ in 1:1000]\n",
|
||||
"AB_AB3_reduced_compute = get_compute_function(graph, process, machine)\n",
|
||||
"\n",
|
||||
"results = AB_AB3_reduced_compute.(inputs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "d43e4ff0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"BenchmarkTools.Trial: 879 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[1m4.567 ms\u001b[22m\u001b[39m … \u001b[35m14.334 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m0.00% … 54.51%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m4.998 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[1m5.686 ms\u001b[22m\u001b[39m ± \u001b[32m 1.414 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m9.09% ± 14.49%\n",
|
||||
"\n",
|
||||
" \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[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 \u001b[39m▁\u001b[39m▁\u001b[39m \u001b[39m \u001b[39m \u001b[39m \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[34m█\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█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▄\u001b[39m▅\u001b[39m▆\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",
|
||||
" 4.57 ms\u001b[90m \u001b[39m\u001b[90mHistogram: \u001b[39m\u001b[90m\u001b[1mlog(\u001b[22m\u001b[39m\u001b[90mfrequency\u001b[39m\u001b[90m\u001b[1m)\u001b[22m\u001b[39m\u001b[90m by time\u001b[39m 10 ms \u001b[0m\u001b[1m<\u001b[22m\n",
|
||||
"\n",
|
||||
" Memory estimate\u001b[90m: \u001b[39m\u001b[33m6.17 MiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m143006\u001b[39m."
|
||||
]
|
||||
},
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"@benchmark results = AB_AB3_compute.($inputs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "e18d9546",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"BenchmarkTools.Trial: 1089 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[1m3.637 ms\u001b[22m\u001b[39m … \u001b[35m10.921 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m 0.00% … 59.52%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m4.098 ms \u001b[22m\u001b[39m\u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmedian\u001b[90m): \u001b[39m 0.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.587 ms\u001b[22m\u001b[39m ± \u001b[32m 1.334 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m10.21% ± 15.77%\n",
|
||||
"\n",
|
||||
" \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[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 \u001b[39m \u001b[39m \u001b[39m \u001b[39m▁\u001b[39m▁\u001b[39m \u001b[39m▁\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[34m█\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▄\u001b[39m▆\u001b[39m▆\u001b[39m▆\u001b[39m█\u001b[39m█\u001b[39m▇\u001b[39m█\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",
|
||||
" 3.64 ms\u001b[90m \u001b[39m\u001b[90mHistogram: \u001b[39m\u001b[90m\u001b[1mlog(\u001b[22m\u001b[39m\u001b[90mfrequency\u001b[39m\u001b[90m\u001b[1m)\u001b[22m\u001b[39m\u001b[90m by time\u001b[39m 8.78 ms \u001b[0m\u001b[1m<\u001b[22m\n",
|
||||
"\n",
|
||||
" Memory estimate\u001b[90m: \u001b[39m\u001b[33m5.26 MiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m123006\u001b[39m."
|
||||
]
|
||||
},
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"@benchmark results = AB_AB3_reduced_compute.($inputs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "13efed12-3547-400b-a7a2-5dfae9a973a2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Set a different caching strategy\n",
|
||||
"MetagraphOptimization.set_cache_strategy(machine.devices[1], MetagraphOptimization.Dictionary())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"id": "ef62716b-a219-4f6e-9150-f984d3734839",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"BenchmarkTools.Trial: 331 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[1m12.148 ms\u001b[22m\u001b[39m … \u001b[35m24.164 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m 0.00% … 13.35%\n",
|
||||
" Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m15.412 ms \u001b[22m\u001b[39m\u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmedian\u001b[90m): \u001b[39m17.47%\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[1m15.117 ms\u001b[22m\u001b[39m ± \u001b[32m 2.194 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m12.31% ± 8.95%\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[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 \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[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▃\u001b[39m▃\u001b[39m▂\u001b[39m▂\u001b[39m▁\u001b[39m▂\u001b[39m \u001b[39m▃\n",
|
||||
" 12.1 ms\u001b[90m Histogram: frequency by time\u001b[39m 21 ms \u001b[0m\u001b[1m<\u001b[22m\n",
|
||||
"\n",
|
||||
" Memory estimate\u001b[90m: \u001b[39m\u001b[33m27.46 MiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m118013\u001b[39m."
|
||||
]
|
||||
},
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# ... and bench again\n",
|
||||
"AB_AB3_reduced_dict_compute = get_compute_function(graph, process, machine)\n",
|
||||
"@benchmark results = AB_AB3_reduced_dict_compute.($inputs)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "5461ffd4-6a0e-4f1f-b1f1-3a2854a8ae88",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"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
|
||||
}
|
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
|
||||
}
|
155
notebooks/large_compton.ipynb
Normal file
155
notebooks/large_compton.ipynb
Normal file
@ -0,0 +1,155 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"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: 15866, DataTask: 7937, ComputeTaskQED_S2: 720, \n",
|
||||
" ComputeTaskQED_Sum: 1, ComputeTaskQED_V: 4320, ComputeTaskQED_S1: 2880, \n",
|
||||
" ComputeTaskQED_U: 8\n",
|
||||
" Edges: 21617\n",
|
||||
" Total Compute Effort: 66249.0\n",
|
||||
" Total Data Transfer: 1.314048e6\n",
|
||||
" Total Compute Intensity: 0.050415966540035065\n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"machine = get_machine_info()\n",
|
||||
"model = QEDModel()\n",
|
||||
"process = parse_process(\"ke->kkkkke\", 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: 2234, DataTask: 1121, ComputeTaskQED_S2: 720, \n",
|
||||
" ComputeTaskQED_Sum: 1, ComputeTaskQED_V: 312, ComputeTaskQED_S1: 72, \n",
|
||||
" ComputeTaskQED_U: 8\n",
|
||||
" Edges: 3977\n",
|
||||
" Total Compute Effort: 11313.0\n",
|
||||
" Total Data Transfer: 659712.0\n",
|
||||
" Total Compute Intensity: 0.017148392025611175\n"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"optimizer = ReductionOptimizer()\n",
|
||||
"\n",
|
||||
"compute_compton = get_compute_function(graph, process, machine)\n",
|
||||
"optimize_to_fixpoint!(optimizer, graph)\n",
|
||||
"graph"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Calculated 133942.0 results/s, 11162.0 results/s per thread for QED Process: 'ke->kkkkke' (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)\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Calculated 17124.0 results/s, 1427.0 results/s per thread for QED Process: 'ke->kkkkke' (12 threads)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"bench_result = @benchmark begin\n",
|
||||
" Threads.@threads :static for i in eachindex(inputs)\n",
|
||||
" outputs[i] = compute_compton(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
|
||||
}
|
69
notebooks/profiling.ipynb
Normal file
69
notebooks/profiling.ipynb
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"using Revise; using MetagraphOptimization; using BenchmarkTools; using ProfileView\n",
|
||||
"using Base.Threads\n",
|
||||
"nthreads()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"model = ABCModel()\n",
|
||||
"process_str = \"AB->ABBBBB\"\n",
|
||||
"process = parse_process(process_str, model)\n",
|
||||
"graph = parse_dag(\"../input/$process_str.txt\", model)\n",
|
||||
"print(graph)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@ProfileView.profview optimize_to_fixpoint!(ReductionOptimizer(), graph)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@ProfileView.profview comp_func = get_compute_function(graph, process, get_machine_info())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"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"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
62
results/FWK8999_QED.txt
Normal file
62
results/FWK8999_QED.txt
Normal file
@ -0,0 +1,62 @@
|
||||
CPU: AMD EPYC 7452 32 Cores, 64 Threads | 122.8 GFLOPS (?, source: https://www.cpubenchmark.net/cpu.php?cpu=AMD+EPYC+7452)
|
||||
GPU: A30 24GB | 5.161 TFLOPS (source: https://www.techpowerup.com/gpu-specs/a30-pcie.c3792)
|
||||
|
||||
Benchmark Summary for QED Process: 'ke->ke':
|
||||
Measured FLOPS by LIKWID: 5657.0
|
||||
Total input size: 1.394 GiB
|
||||
CPU, 64 threads
|
||||
Time: 0.594810558
|
||||
Rate: 1.681207548437632e7
|
||||
GFLOPS: 88.57428190774921
|
||||
GPU, NVIDIA A30
|
||||
Time: 1.547648257
|
||||
Rate: 6.461416510353748e6
|
||||
GFLOPS: 34.041919930904314
|
||||
|
||||
Benchmark Summary for QED Process: 'ke->kke':
|
||||
Measured FLOPS by LIKWID: 16256.0
|
||||
Total input size: 1.768 GiB
|
||||
CPU, 64 threads
|
||||
Time: 1.294064702
|
||||
Rate: 7.7275888790914565e6
|
||||
GFLOPS: 116.99244828756034
|
||||
GPU, NVIDIA A30
|
||||
Time: 4.973188906
|
||||
Rate: 2.0107822544072892e6
|
||||
GFLOPS: 30.442398346629826
|
||||
|
||||
Benchmark Summary for QED Process: 'ke->kkke':
|
||||
Measured FLOPS by LIKWID: 43433.0
|
||||
Total input size: 2.632 GiB
|
||||
CPU, 64 threads
|
||||
Time: 3.232029091
|
||||
Rate: 3.094031556784648e6
|
||||
GFLOPS: 125.15398916399816
|
||||
GPU, NVIDIA A30
|
||||
Time: 14.597070187
|
||||
Rate: 685068.9810963502
|
||||
GFLOPS: 27.711131662091034
|
||||
|
||||
Benchmark Summary for ABC Process: 'AB->AB':
|
||||
Measured FLOPS by LIKWID: 41.0
|
||||
Total input size: 2.201 GiB
|
||||
CPU, 64 threads
|
||||
Time: 0.688079611
|
||||
Rate: 1.453320203089116e7
|
||||
GFLOPS: 0.5549390644454747
|
||||
GPU, NVIDIA A30
|
||||
Time: 0.013803574
|
||||
Rate: 7.244500590933913e8
|
||||
GFLOPS: 27.662564462822903
|
||||
|
||||
Benchmark Summary for ABC Process: 'AB->ABBB':
|
||||
Measured FLOPS by LIKWID: 899.0
|
||||
Total input size: 3.079 GiB
|
||||
CPU, 64 threads
|
||||
Time: 0.855687624
|
||||
Rate: 1.1686507692204276e7
|
||||
GFLOPS: 9.784633680518386
|
||||
GPU, NVIDIA A30
|
||||
Time: 0.014804518
|
||||
Rate: 6.754694749265056e8
|
||||
GFLOPS: 565.542893445984
|
@ -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
|
||||
|
@ -6,20 +6,20 @@ julia --project=./examples -t 4 -e 'import Pkg; Pkg.instantiate()'
|
||||
|
||||
#for i in $(seq $minthreads $maxthreads)
|
||||
# printf "(AB->AB, $i) "
|
||||
# julia --project=./examples -t $i -O3 -e 'using MetagraphOptimization; using BenchmarkTools; @btime get_operations(graph) setup=(graph = parse_abc("input/AB->AB.txt"))'
|
||||
# julia --project=./examples -t $i -O3 -e 'using MetagraphOptimization; using BenchmarkTools; @btime get_operations(graph) setup=(graph = parse_dag("input/AB->AB.txt"), ABCModel())'
|
||||
#end
|
||||
|
||||
#for i in $(seq $minthreads $maxthreads)
|
||||
# printf "(AB->ABBB, $i) "
|
||||
# julia --project=./examples -t $i -O3 -e 'using MetagraphOptimization; using BenchmarkTools; @btime get_operations(graph) setup=(graph = parse_abc("input/AB->ABBB.txt"))'
|
||||
# julia --project=./examples -t $i -O3 -e 'using MetagraphOptimization; using BenchmarkTools; @btime get_operations(graph) setup=(graph = parse_dag("input/AB->ABBB.txt"), ABCModel())'
|
||||
#end
|
||||
|
||||
#for i in $(seq $minthreads $maxthreads)
|
||||
# printf "(AB->ABBBBB, $i) "
|
||||
# julia --project=./examples -t $i -O3 -e 'using MetagraphOptimization; using BenchmarkTools; @btime get_operations(graph) setup=(graph = parse_abc("input/AB->ABBBBB.txt"))'
|
||||
# julia --project=./examples -t $i -O3 -e 'using MetagraphOptimization; using BenchmarkTools; @btime get_operations(graph) setup=(graph = parse_dag("input/AB->ABBBBB.txt"), ABCModel())'
|
||||
#end
|
||||
|
||||
for i in $(seq $minthreads $maxthreads)
|
||||
printf "(AB->ABBBBBBB, $i) "
|
||||
julia --project=./examples -t $i -O3 -e 'using MetagraphOptimization; using BenchmarkTools; @btime get_operations(graph) setup=(graph = parse_abc("input/AB->ABBBBBBB.txt"))'
|
||||
julia --project=./examples -t $i -O3 -e 'using MetagraphOptimization; using BenchmarkTools; @btime get_operations(graph) setup=(graph = parse_dag("input/AB->ABBBBBBB.txt"), ABCModel())'
|
||||
end
|
||||
|
@ -5,32 +5,40 @@ A module containing tools to work on DAGs.
|
||||
"""
|
||||
module MetagraphOptimization
|
||||
|
||||
using QEDbase
|
||||
|
||||
# graph types
|
||||
export DAG
|
||||
export Node
|
||||
export Edge
|
||||
export ComputeTaskNode
|
||||
export DataTaskNode
|
||||
export AbstractTask
|
||||
export AbstractComputeTask
|
||||
export AbstractDataTask
|
||||
export DataTask
|
||||
export FusedComputeTask
|
||||
export PossibleOperations
|
||||
export GraphProperties
|
||||
|
||||
# graph functions
|
||||
export make_node
|
||||
export make_edge
|
||||
export insert_node
|
||||
export insert_edge
|
||||
export insert_node!
|
||||
export insert_edge!
|
||||
export is_entry_node
|
||||
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 is_valid
|
||||
export operation_stack_length
|
||||
export is_valid, is_scheduled
|
||||
|
||||
# graph operation related
|
||||
export Operation
|
||||
export AppliedOperation
|
||||
export NodeFusion
|
||||
@ -42,23 +50,56 @@ export can_pop
|
||||
export reset_graph!
|
||||
export get_operations
|
||||
|
||||
export parse_abc
|
||||
export ComputeTaskP
|
||||
export ComputeTaskS1
|
||||
export ComputeTaskS2
|
||||
export ComputeTaskV
|
||||
export ComputeTaskU
|
||||
export ComputeTaskSum
|
||||
|
||||
export execute
|
||||
export gen_particles
|
||||
# ABC model
|
||||
export ParticleValue
|
||||
export Particle
|
||||
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 gen_tape, execute_tape
|
||||
|
||||
# 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
|
||||
|
||||
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.==
|
||||
@ -72,12 +113,14 @@ import Base.insert!
|
||||
import Base.collect
|
||||
|
||||
|
||||
include("devices/interface.jl")
|
||||
include("task/type.jl")
|
||||
include("node/type.jl")
|
||||
include("diff/type.jl")
|
||||
include("properties/type.jl")
|
||||
include("operation/type.jl")
|
||||
include("graph/type.jl")
|
||||
include("scheduler/type.jl")
|
||||
|
||||
include("trie.jl")
|
||||
include("utility.jl")
|
||||
@ -99,6 +142,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")
|
||||
@ -111,16 +155,53 @@ include("properties/utility.jl")
|
||||
|
||||
include("task/create.jl")
|
||||
include("task/compare.jl")
|
||||
include("task/print.jl")
|
||||
include("task/compute.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")
|
||||
|
||||
include("models/abc/types.jl")
|
||||
include("models/abc/particle.jl")
|
||||
include("models/abc/compute.jl")
|
||||
include("models/abc/create.jl")
|
||||
include("models/abc/properties.jl")
|
||||
include("models/abc/parse.jl")
|
||||
include("models/abc/print.jl")
|
||||
|
||||
include("code_gen/main.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")
|
||||
|
||||
include("devices/numa/impl.jl")
|
||||
include("devices/cuda/impl.jl")
|
||||
# can currently not use AMDGPU because of incompatability with the newest rocm drivers
|
||||
# include("devices/rocm/impl.jl")
|
||||
# oneapi seems also broken for now
|
||||
# include("devices/oneapi/impl.jl")
|
||||
|
||||
include("scheduler/interface.jl")
|
||||
include("scheduler/greedy.jl")
|
||||
|
||||
include("code_gen/type.jl")
|
||||
include("code_gen/tape_machine.jl")
|
||||
include("code_gen/function.jl")
|
||||
|
||||
end # module MetagraphOptimization
|
||||
|
40
src/code_gen/function.jl
Normal file
40
src/code_gen/function.jl
Normal file
@ -0,0 +1,40 @@
|
||||
"""
|
||||
get_compute_function(graph::DAG, process::AbstractProcessDescription, machine::Machine)
|
||||
|
||||
Return a function of signature `compute_<id>(input::AbstractProcessInput)`, which will return the result of the DAG computation on the given input.
|
||||
"""
|
||||
function get_compute_function(graph::DAG, process::AbstractProcessDescription, machine::Machine)
|
||||
tape = gen_tape(graph, process, machine)
|
||||
|
||||
initCaches = Expr(:block, tape.initCachesCode...)
|
||||
assignInputs = Expr(:block, expr_from_fc.(tape.inputAssignCode)...)
|
||||
code = Expr(:block, expr_from_fc.(tape.computeCode)...)
|
||||
|
||||
functionId = to_var_name(UUIDs.uuid1(rng[1]))
|
||||
resSym = eval(gen_access_expr(entry_device(tape.machine), tape.outputSymbol))
|
||||
expr = Meta.parse(
|
||||
"function compute_$(functionId)(data_input::AbstractProcessInput) $(initCaches); $(assignInputs); $code; return $resSym; end",
|
||||
)
|
||||
|
||||
func = eval(expr)
|
||||
|
||||
return func
|
||||
end
|
||||
|
||||
"""
|
||||
execute(graph::DAG, process::AbstractProcessDescription, machine::Machine, input::AbstractProcessInput)
|
||||
|
||||
Execute the code of the given `graph` on the given input particles.
|
||||
|
||||
This is essentially shorthand for
|
||||
```julia
|
||||
tape = gen_tape(graph, process, machine)
|
||||
return execute_tape(tape, input)
|
||||
```
|
||||
|
||||
See also: [`parse_dag`](@ref), [`parse_process`](@ref), [`gen_process_input`](@ref)
|
||||
"""
|
||||
function execute(graph::DAG, process::AbstractProcessDescription, machine::Machine, input::AbstractProcessInput)
|
||||
tape = gen_tape(graph, process, machine)
|
||||
return execute_tape(tape, input)
|
||||
end
|
@ -1,126 +0,0 @@
|
||||
using DataStructures
|
||||
|
||||
"""
|
||||
gen_code(graph::DAG)
|
||||
|
||||
Generate the code for a given graph. The return value is a tuple of:
|
||||
|
||||
- `code::Expr`: The julia expression containing the code for the whole graph.
|
||||
- `inputSymbols::Dict{String, Symbol}`: A dictionary of symbols mapping the names of the input nodes of the graph to the symbols their inputs should be provided on.
|
||||
- `outputSymbol::Symbol`: The symbol of the final calculated value
|
||||
|
||||
See also: [`execute`](@ref)
|
||||
"""
|
||||
function gen_code(graph::DAG)
|
||||
code = Vector{Expr}()
|
||||
sizehint!(code, length(graph.nodes))
|
||||
|
||||
nodeQueue = PriorityQueue{Node, Int}()
|
||||
inputSyms = Dict{String, Symbol}()
|
||||
|
||||
# use a priority equal to the number of unseen children -> 0 are nodes that can be added
|
||||
for node in get_entry_nodes(graph)
|
||||
enqueue!(nodeQueue, node => 0)
|
||||
push!(inputSyms, node.name => Symbol("data_$(to_var_name(node.id))_in"))
|
||||
end
|
||||
|
||||
node = nothing
|
||||
while !isempty(nodeQueue)
|
||||
@assert peek(nodeQueue)[2] == 0
|
||||
node = dequeue!(nodeQueue)
|
||||
|
||||
push!(code, get_expression(node))
|
||||
for parent in node.parents
|
||||
# reduce the priority of all parents by one
|
||||
if (!haskey(nodeQueue, parent))
|
||||
enqueue!(nodeQueue, parent => length(parent.children) - 1)
|
||||
else
|
||||
nodeQueue[parent] = nodeQueue[parent] - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# node is now the last node we looked at -> the output node
|
||||
outSym = Symbol("data_$(to_var_name(node.id))")
|
||||
|
||||
return (
|
||||
code = Expr(:block, code...),
|
||||
inputSymbols = inputSyms,
|
||||
outputSymbol = outSym,
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
execute(generated_code, input::Dict{ParticleType, Vector{Particle}})
|
||||
|
||||
Execute the given `generated_code` (as returned by [`gen_code`](@ref)) on the given input particles.
|
||||
"""
|
||||
function execute(generated_code, input::Dict{ParticleType, Vector{Particle}})
|
||||
(code, inputSymbols, outputSymbol) = generated_code
|
||||
|
||||
assignInputs = Vector{Expr}()
|
||||
for (name, symbol) in inputSymbols
|
||||
type = nothing
|
||||
if startswith(name, "A")
|
||||
type = A
|
||||
elseif startswith(name, "B")
|
||||
type = B
|
||||
else
|
||||
type = C
|
||||
end
|
||||
index = parse(Int, name[2:end])
|
||||
|
||||
push!(
|
||||
assignInputs,
|
||||
Meta.parse(
|
||||
"$(symbol) = ParticleValue(Particle($(input[type][index]).P0, $(input[type][index]).P1, $(input[type][index]).P2, $(input[type][index]).P3, $(type)), 1.0)",
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
assignInputs = Expr(:block, assignInputs...)
|
||||
eval(assignInputs)
|
||||
eval(code)
|
||||
|
||||
eval(Meta.parse("result = $outputSymbol"))
|
||||
return result
|
||||
end
|
||||
|
||||
"""
|
||||
execute(graph::DAG, input::Dict{ParticleType, Vector{Particle}})
|
||||
|
||||
Execute the given `generated_code` (as returned by [`gen_code`](@ref)) on the given input particles.
|
||||
The input particles should be sorted correctly into the dictionary to their according [`ParticleType`](@ref)s.
|
||||
|
||||
See also: [`gen_particles`](@ref)
|
||||
"""
|
||||
function execute(graph::DAG, input::Dict{ParticleType, Vector{Particle}})
|
||||
(code, inputSymbols, outputSymbol) = gen_code(graph)
|
||||
|
||||
assignInputs = Vector{Expr}()
|
||||
for (name, symbol) in inputSymbols
|
||||
type = nothing
|
||||
if startswith(name, "A")
|
||||
type = A
|
||||
elseif startswith(name, "B")
|
||||
type = B
|
||||
else
|
||||
type = C
|
||||
end
|
||||
index = parse(Int, name[2:end])
|
||||
|
||||
push!(
|
||||
assignInputs,
|
||||
Meta.parse(
|
||||
"$(symbol) = ParticleValue(Particle($(input[type][index]).P0, $(input[type][index]).P1, $(input[type][index]).P2, $(input[type][index]).P3, $(type)), 1.0)",
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
assignInputs = Expr(:block, assignInputs...)
|
||||
eval(assignInputs)
|
||||
eval(code)
|
||||
|
||||
eval(Meta.parse("result = $outputSymbol"))
|
||||
return result
|
||||
end
|
182
src/code_gen/tape_machine.jl
Normal file
182
src/code_gen/tape_machine.jl
Normal file
@ -0,0 +1,182 @@
|
||||
function call_fc(fc::FunctionCall{VectorT, 0}, cache::Dict{Symbol, Any}) where {VectorT <: SVector{1}}
|
||||
cache[fc.return_symbol] = fc.func(cache[fc.arguments[1]])
|
||||
return nothing
|
||||
end
|
||||
|
||||
function call_fc(fc::FunctionCall{VectorT, 1}, cache::Dict{Symbol, Any}) where {VectorT <: SVector{1}}
|
||||
cache[fc.return_symbol] = fc.func(fc.additional_arguments[1], cache[fc.arguments[1]])
|
||||
return nothing
|
||||
end
|
||||
|
||||
function call_fc(fc::FunctionCall{VectorT, 0}, cache::Dict{Symbol, Any}) where {VectorT <: SVector{2}}
|
||||
cache[fc.return_symbol] = fc.func(cache[fc.arguments[1]], cache[fc.arguments[2]])
|
||||
return nothing
|
||||
end
|
||||
|
||||
function call_fc(fc::FunctionCall{VectorT, 1}, cache::Dict{Symbol, Any}) where {VectorT <: SVector{2}}
|
||||
cache[fc.return_symbol] = fc.func(fc.additional_arguments[1], cache[fc.arguments[1]], cache[fc.arguments[2]])
|
||||
return nothing
|
||||
end
|
||||
|
||||
function call_fc(fc::FunctionCall{VectorT, 1}, cache::Dict{Symbol, Any}) where {VectorT}
|
||||
cache[fc.return_symbol] = fc.func(fc.additional_arguments[1], getindex.(Ref(cache), fc.arguments)...)
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
call_fc(fc::FunctionCall, cache::Dict{Symbol, Any})
|
||||
|
||||
Execute the given [`FunctionCall`](@ref) on the dictionary.
|
||||
|
||||
Several more specialized versions of this function exist to reduce vector unrolling work for common cases.
|
||||
"""
|
||||
function call_fc(fc::FunctionCall{VectorT, M}, cache::Dict{Symbol, Any}) where {VectorT, M}
|
||||
cache[fc.return_symbol] = fc.func(fc.additional_arguments..., getindex.(Ref(cache), fc.arguments)...)
|
||||
return nothing
|
||||
end
|
||||
|
||||
function expr_from_fc(fc::FunctionCall{VectorT, 0}) where {VectorT}
|
||||
return Meta.parse(
|
||||
"$(eval(gen_access_expr(fc.device, fc.return_symbol))) = $(fc.func)($(unroll_symbol_vector(eval.(gen_access_expr.(Ref(fc.device), fc.arguments)))))",
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
expr_from_fc(fc::FunctionCall)
|
||||
|
||||
For a given function call, return an expression evaluating it.
|
||||
"""
|
||||
function expr_from_fc(fc::FunctionCall{VectorT, M}) where {VectorT, M}
|
||||
func_call = Expr(
|
||||
:call,
|
||||
Symbol(fc.func),
|
||||
fc.additional_arguments...,
|
||||
eval.(gen_access_expr.(Ref(fc.device), fc.arguments))...,
|
||||
)
|
||||
|
||||
expr = :($(eval(gen_access_expr(fc.device, fc.return_symbol))) = $func_call)
|
||||
return expr
|
||||
end
|
||||
|
||||
"""
|
||||
gen_cache_init_code(machine::Machine)
|
||||
|
||||
For each [`AbstractDevice`](@ref) in the given [`Machine`](@ref), returning a `Vector{Expr}` doing the initialization.
|
||||
"""
|
||||
function gen_cache_init_code(machine::Machine)
|
||||
initializeCaches = Vector{Expr}()
|
||||
|
||||
for device in machine.devices
|
||||
push!(initializeCaches, gen_cache_init_code(device))
|
||||
end
|
||||
|
||||
return initializeCaches
|
||||
end
|
||||
|
||||
"""
|
||||
part_from_x(type::Type, index::Int, x::AbstractProcessInput)
|
||||
|
||||
Return the [`ParticleValue`](@ref) of the given type of particle with the given `index` from the given process input.
|
||||
|
||||
Function is wrapped into a [`FunctionCall`](@ref) in [`gen_input_assignment_code`](@ref).
|
||||
"""
|
||||
part_from_x(type::Type, index::Int, x::AbstractProcessInput) =
|
||||
ParticleValue{type, ComplexF64}(get_particle(x, type, index), one(ComplexF64))
|
||||
|
||||
"""
|
||||
gen_input_assignment_code(
|
||||
inputSymbols::Dict{String, Vector{Symbol}},
|
||||
processDescription::AbstractProcessDescription,
|
||||
machine::Machine,
|
||||
processInputSymbol::Symbol = :input,
|
||||
)
|
||||
|
||||
Return a `Vector{Expr}` doing the input assignments from the given `processInputSymbol` onto the `inputSymbols`.
|
||||
"""
|
||||
function gen_input_assignment_code(
|
||||
inputSymbols::Dict{String, Vector{Symbol}},
|
||||
processDescription::AbstractProcessDescription,
|
||||
machine::Machine,
|
||||
processInputSymbol::Symbol = :input,
|
||||
)
|
||||
@assert length(inputSymbols) >=
|
||||
sum(values(in_particles(processDescription))) + sum(values(out_particles(processDescription))) "Number of input Symbols is smaller than the number of particles in the process description"
|
||||
|
||||
assignInputs = Vector{FunctionCall}()
|
||||
for (name, symbols) in inputSymbols
|
||||
(type, index) = type_index_from_name(model(processDescription), name)
|
||||
# make a function for this, since we can't use anonymous functions in the FunctionCall
|
||||
|
||||
for symbol in symbols
|
||||
device = entry_device(machine)
|
||||
push!(
|
||||
assignInputs,
|
||||
FunctionCall(
|
||||
# x is the process input
|
||||
part_from_x,
|
||||
SVector{1, Symbol}(processInputSymbol),
|
||||
SVector{2, Any}(type, index),
|
||||
symbol,
|
||||
device,
|
||||
),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
return assignInputs
|
||||
end
|
||||
|
||||
"""
|
||||
gen_tape(graph::DAG, process::AbstractProcessDescription, machine::Machine)
|
||||
|
||||
Generate the code for a given graph. The return value is a [`Tape`](@ref).
|
||||
|
||||
See also: [`execute`](@ref), [`execute_tape`](@ref)
|
||||
"""
|
||||
function gen_tape(graph::DAG, process::AbstractProcessDescription, machine::Machine)
|
||||
schedule = schedule_dag(GreedyScheduler(), graph, machine)
|
||||
|
||||
# get inSymbols
|
||||
inputSyms = Dict{String, Vector{Symbol}}()
|
||||
for node in get_entry_nodes(graph)
|
||||
if !haskey(inputSyms, node.name)
|
||||
inputSyms[node.name] = Vector{Symbol}()
|
||||
end
|
||||
|
||||
push!(inputSyms[node.name], Symbol("$(to_var_name(node.id))_in"))
|
||||
end
|
||||
|
||||
# get outSymbol
|
||||
outSym = Symbol(to_var_name(get_exit_node(graph).id))
|
||||
|
||||
initCaches = gen_cache_init_code(machine)
|
||||
assignInputs = gen_input_assignment_code(inputSyms, process, machine, :input)
|
||||
|
||||
return Tape(initCaches, assignInputs, schedule, inputSyms, outSym, Dict(), process, machine)
|
||||
end
|
||||
|
||||
"""
|
||||
execute_tape(tape::Tape, input::AbstractProcessInput)
|
||||
|
||||
Execute the given tape with the given input.
|
||||
|
||||
For implementation reasons, this disregards the set [`CacheStrategy`](@ref) of the devices and always uses a dictionary.
|
||||
"""
|
||||
function execute_tape(tape::Tape, input::AbstractProcessInput)
|
||||
cache = Dict{Symbol, Any}()
|
||||
cache[:input] = input
|
||||
# simply execute all the code snippets here
|
||||
# TODO: `@assert` that process input fits the tape.process
|
||||
for expr in tape.initCachesCode
|
||||
@eval $expr
|
||||
end
|
||||
|
||||
for function_call in tape.inputAssignCode
|
||||
call_fc(function_call, cache)
|
||||
end
|
||||
for function_call in tape.computeCode
|
||||
call_fc(function_call, cache)
|
||||
end
|
||||
|
||||
return cache[tape.outputSymbol]
|
||||
end
|
19
src/code_gen/type.jl
Normal file
19
src/code_gen/type.jl
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
"""
|
||||
Tape
|
||||
|
||||
TODO: update docs
|
||||
- `code::Vector{Expr}`: The julia expression containing the code for the whole graph.
|
||||
- `inputSymbols::Dict{String, Vector{Symbol}}`: A dictionary of symbols mapping the names of the input nodes of the graph to the symbols their inputs should be provided on.
|
||||
- `outputSymbol::Symbol`: The symbol of the final calculated value
|
||||
"""
|
||||
struct Tape
|
||||
initCachesCode::Vector{Expr}
|
||||
inputAssignCode::Vector{FunctionCall}
|
||||
computeCode::Vector{FunctionCall}
|
||||
inputSymbols::Dict{String, Vector{Symbol}}
|
||||
outputSymbol::Symbol
|
||||
cache::Dict{Symbol, Any}
|
||||
process::AbstractProcessDescription
|
||||
machine::Machine
|
||||
end
|
53
src/devices/cuda/impl.jl
Normal file
53
src/devices/cuda/impl.jl
Normal file
@ -0,0 +1,53 @@
|
||||
using CUDA
|
||||
|
||||
"""
|
||||
CUDAGPU <: AbstractGPU
|
||||
|
||||
Representation of a specific CUDA GPU that code can run on. Implements the [`AbstractDevice`](@ref) interface.
|
||||
"""
|
||||
mutable struct CUDAGPU <: AbstractGPU
|
||||
device::Any # TODO: what's the cuda device type?
|
||||
cacheStrategy::CacheStrategy
|
||||
FLOPS::Float64
|
||||
end
|
||||
|
||||
push!(DEVICE_TYPES, CUDAGPU)
|
||||
|
||||
CACHE_STRATEGIES[CUDAGPU] = [LocalVariables()]
|
||||
|
||||
default_strategy(::Type{T}) where {T <: CUDAGPU} = LocalVariables()
|
||||
|
||||
function measure_device!(device::CUDAGPU; verbose::Bool)
|
||||
if verbose
|
||||
println("Measuring CUDA GPU $(device.device)")
|
||||
end
|
||||
|
||||
# TODO implement
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
get_devices(deviceType::Type{T}; verbose::Bool) where {T <: CUDAGPU}
|
||||
|
||||
Return a Vector of [`CUDAGPU`](@ref)s available on the current machine. If `verbose` is true, print some additional information.
|
||||
"""
|
||||
function get_devices(deviceType::Type{T}; verbose::Bool = false) where {T <: CUDAGPU}
|
||||
devices = Vector{AbstractDevice}()
|
||||
|
||||
if !CUDA.functional()
|
||||
if verbose
|
||||
println("CUDA is non-functional")
|
||||
end
|
||||
return devices
|
||||
end
|
||||
|
||||
CUDADevices = CUDA.devices()
|
||||
if verbose
|
||||
println("Found $(length(CUDADevices)) CUDA devices")
|
||||
end
|
||||
for device in CUDADevices
|
||||
push!(devices, CUDAGPU(device, default_strategy(CUDAGPU), -1))
|
||||
end
|
||||
|
||||
return devices
|
||||
end
|
23
src/devices/detect.jl
Normal file
23
src/devices/detect.jl
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
"""
|
||||
get_machine_info(verbose::Bool)
|
||||
|
||||
Return the [`Machine`](@ref) currently running on. The parameter `verbose` defaults to true when interactive.
|
||||
"""
|
||||
function get_machine_info(; verbose::Bool = Base.is_interactive)
|
||||
devices = Vector{AbstractDevice}()
|
||||
|
||||
for device in device_types()
|
||||
devs = get_devices(device, verbose = verbose)
|
||||
for dev in devs
|
||||
push!(devices, dev)
|
||||
end
|
||||
end
|
||||
|
||||
noDevices = length(devices)
|
||||
@assert noDevices > 0 "No devices were found, but at least one NUMA node should always be available!"
|
||||
|
||||
transferRates = Matrix{Float64}(undef, noDevices, noDevices)
|
||||
fill!(transferRates, -1)
|
||||
return Machine(devices, transferRates)
|
||||
end
|
52
src/devices/impl.jl
Normal file
52
src/devices/impl.jl
Normal file
@ -0,0 +1,52 @@
|
||||
"""
|
||||
device_types()
|
||||
|
||||
Return a vector of available and implemented device types.
|
||||
|
||||
See also: [`DEVICE_TYPES`](@ref)
|
||||
"""
|
||||
function device_types()
|
||||
return DEVICE_TYPES
|
||||
end
|
||||
|
||||
"""
|
||||
entry_device(machine::Machine)
|
||||
|
||||
Return the "entry" device, i.e., the device that starts CPU threads and GPU kernels, and takes input values and returns the output value.
|
||||
"""
|
||||
function entry_device(machine::Machine)
|
||||
return machine.devices[1]
|
||||
end
|
||||
|
||||
"""
|
||||
strategies(t::Type{T}) where {T <: AbstractDevice}
|
||||
|
||||
Return a vector of available [`CacheStrategy`](@ref)s for the given [`AbstractDevice`](@ref).
|
||||
The caching strategies are used in code generation.
|
||||
"""
|
||||
function strategies(t::Type{T}) where {T <: AbstractDevice}
|
||||
if !haskey(CACHE_STRATEGIES, t)
|
||||
error("Trying to get strategies for $T, but it has no strategies defined!")
|
||||
end
|
||||
|
||||
return CACHE_STRATEGIES[t]
|
||||
end
|
||||
|
||||
"""
|
||||
cache_strategy(device::AbstractDevice)
|
||||
|
||||
Returns the cache strategy set for this device.
|
||||
"""
|
||||
function cache_strategy(device::AbstractDevice)
|
||||
return device.cacheStrategy
|
||||
end
|
||||
|
||||
"""
|
||||
set_cache_strategy(device::AbstractDevice, cacheStrategy::CacheStrategy)
|
||||
|
||||
Sets the device's cache strategy. After this call, [`cache_strategy`](@ref) should return `cacheStrategy` on the given device.
|
||||
"""
|
||||
function set_cache_strategy(device::AbstractDevice, cacheStrategy::CacheStrategy)
|
||||
device.cacheStrategy = cacheStrategy
|
||||
return nothing
|
||||
end
|
108
src/devices/interface.jl
Normal file
108
src/devices/interface.jl
Normal file
@ -0,0 +1,108 @@
|
||||
"""
|
||||
AbstractDevice
|
||||
|
||||
Abstract base type for every device, like GPUs, CPUs or any other compute devices.
|
||||
Every implementation needs to implement various functions and needs a member `cacheStrategy`.
|
||||
"""
|
||||
abstract type AbstractDevice end
|
||||
|
||||
abstract type AbstractCPU <: AbstractDevice end
|
||||
|
||||
abstract type AbstractGPU <: AbstractDevice end
|
||||
|
||||
"""
|
||||
Machine
|
||||
|
||||
A representation of a machine to execute on. Contains information about its architecture (CPUs, GPUs, maybe more). This representation can be used to make a more accurate cost prediction of a [`DAG`](@ref) state.
|
||||
|
||||
See also: [`Scheduler`](@ref)
|
||||
"""
|
||||
struct Machine
|
||||
devices::Vector{AbstractDevice}
|
||||
|
||||
transferRates::Matrix{Float64}
|
||||
end
|
||||
|
||||
"""
|
||||
CacheStrategy
|
||||
|
||||
Abstract base type for caching strategies.
|
||||
|
||||
See also: [`strategies`](@ref)
|
||||
"""
|
||||
abstract type CacheStrategy end
|
||||
|
||||
"""
|
||||
LocalVariables <: CacheStrategy
|
||||
|
||||
A caching strategy relying solely on local variables for every input and output.
|
||||
|
||||
Implements the [`CacheStrategy`](@ref) interface.
|
||||
"""
|
||||
struct LocalVariables <: CacheStrategy end
|
||||
|
||||
"""
|
||||
Dictionary <: CacheStrategy
|
||||
|
||||
A caching strategy relying on a dictionary of Symbols to store every input and output.
|
||||
|
||||
Implements the [`CacheStrategy`](@ref) interface.
|
||||
"""
|
||||
struct Dictionary <: CacheStrategy end
|
||||
|
||||
"""
|
||||
DEVICE_TYPES::Vector{Type}
|
||||
|
||||
Global vector of available and implemented device types. Each implementation of a [`AbstractDevice`](@ref) should add its concrete type to this vector.
|
||||
|
||||
See also: [`device_types`](@ref), [`get_devices`](@ref)
|
||||
"""
|
||||
DEVICE_TYPES = Vector{Type}()
|
||||
|
||||
"""
|
||||
CACHE_STRATEGIES::Dict{Type{AbstractDevice}, Symbol}
|
||||
|
||||
Global dictionary of available caching strategies per device. Each implementation of [`AbstractDevice`](@ref) should add its available strategies to the dictionary.
|
||||
|
||||
See also: [`strategies`](@ref)
|
||||
"""
|
||||
CACHE_STRATEGIES = Dict{Type, Vector{CacheStrategy}}()
|
||||
|
||||
"""
|
||||
default_strategy(deviceType::Type{T}) where {T <: AbstractDevice}
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractDevice`](@ref). Returns the default [`CacheStrategy`](@ref) to use on the given device type.
|
||||
See also: [`cache_strategy`](@ref), [`set_cache_strategy`](@ref)
|
||||
"""
|
||||
function default_strategy end
|
||||
|
||||
"""
|
||||
get_devices(t::Type{T}; verbose::Bool) where {T <: AbstractDevice}
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractDevice`](@ref). Returns a `Vector{Type}` of the devices for the given [`AbstractDevice`](@ref) Type available on the current machine.
|
||||
"""
|
||||
function get_devices end
|
||||
|
||||
"""
|
||||
measure_device!(device::AbstractDevice; verbose::Bool)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractDevice`](@ref). Measures the compute speed of the given device and writes into it.
|
||||
"""
|
||||
function measure_device! end
|
||||
|
||||
"""
|
||||
gen_cache_init_code(device::AbstractDevice)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractDevice`](@ref) and at least one [`CacheStrategy`](@ref). Returns an `Expr` initializing this device's variable cache.
|
||||
|
||||
The strategy is a symbol
|
||||
"""
|
||||
function gen_cache_init_code end
|
||||
|
||||
"""
|
||||
gen_access_expr(device::AbstractDevice, symbol::Symbol)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractDevice`](@ref) and at least one [`CacheStrategy`](@ref).
|
||||
Return an `Expr` or `QuoteNode` accessing the variable identified by [`symbol`].
|
||||
"""
|
||||
function gen_access_expr end
|
22
src/devices/measure.jl
Normal file
22
src/devices/measure.jl
Normal file
@ -0,0 +1,22 @@
|
||||
"""
|
||||
measure_devices(machine::Machine; verbose::Bool)
|
||||
|
||||
Measure FLOPS, RAM, cache sizes and what other properties can be extracted for the devices in the given machine.
|
||||
"""
|
||||
function measure_devices!(machine::Machine; verbose::Bool = Base.is_interactive())
|
||||
for device in machine.devices
|
||||
measure_device!(device; verbose = verbose)
|
||||
end
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
measure_transfer_rates(machine::Machine; verbose::Bool)
|
||||
|
||||
Measure the transfer rates between devices in the machine.
|
||||
"""
|
||||
function measure_transfer_rates!(machine::Machine; verbose::Bool = Base.is_interactive())
|
||||
# TODO implement
|
||||
return nothing
|
||||
end
|
96
src/devices/numa/impl.jl
Normal file
96
src/devices/numa/impl.jl
Normal file
@ -0,0 +1,96 @@
|
||||
using NumaAllocators
|
||||
|
||||
"""
|
||||
NumaNode <: AbstractCPU
|
||||
|
||||
Representation of a specific CPU that code can run on. Implements the [`AbstractDevice`](@ref) interface.
|
||||
"""
|
||||
mutable struct NumaNode <: AbstractCPU
|
||||
numaId::UInt16
|
||||
threads::UInt16
|
||||
cacheStrategy::CacheStrategy
|
||||
FLOPS::Float64
|
||||
id::UUID
|
||||
end
|
||||
|
||||
push!(DEVICE_TYPES, NumaNode)
|
||||
|
||||
CACHE_STRATEGIES[NumaNode] = [LocalVariables()]
|
||||
|
||||
default_strategy(::Type{T}) where {T <: NumaNode} = LocalVariables()
|
||||
|
||||
function measure_device!(device::NumaNode; verbose::Bool)
|
||||
if verbose
|
||||
println("Measuring Numa Node $(device.numaId)")
|
||||
end
|
||||
|
||||
# TODO implement
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
get_devices(deviceType::Type{T}; verbose::Bool) where {T <: NumaNode}
|
||||
|
||||
Return a Vector of [`NumaNode`](@ref)s available on the current machine. If `verbose` is true, print some additional information.
|
||||
"""
|
||||
function get_devices(deviceType::Type{T}; verbose::Bool = false) where {T <: NumaNode}
|
||||
devices = Vector{AbstractDevice}()
|
||||
noNumaNodes = highest_numa_node()
|
||||
|
||||
if (verbose)
|
||||
println("Found $(noNumaNodes + 1) NUMA nodes")
|
||||
end
|
||||
for i in 0:noNumaNodes
|
||||
push!(devices, NumaNode(i, 1, default_strategy(NumaNode), -1, UUIDs.uuid1(rng[1])))
|
||||
end
|
||||
|
||||
return devices
|
||||
end
|
||||
|
||||
"""
|
||||
gen_cache_init_code(device::NumaNode)
|
||||
|
||||
Generate code for initializing the [`LocalVariables`](@ref) strategy on a [`NumaNode`](@ref).
|
||||
"""
|
||||
function gen_cache_init_code(device::NumaNode)
|
||||
if typeof(device.cacheStrategy) <: LocalVariables
|
||||
# don't need to initialize anything
|
||||
return Expr(:block)
|
||||
elseif typeof(device.cacheStrategy) <: Dictionary
|
||||
return Meta.parse("cache_$(to_var_name(device.id)) = Dict{Symbol, Any}()")
|
||||
# TODO: sizehint?
|
||||
end
|
||||
|
||||
return error("Unimplemented cache strategy \"$(device.cacheStrategy)\" for device \"$(device)\"")
|
||||
end
|
||||
|
||||
"""
|
||||
gen_access_expr(device::NumaNode, symbol::Symbol)
|
||||
|
||||
Generate code to access the variable designated by `symbol` on a [`NumaNode`](@ref), using the [`CacheStrategy`](@ref) set in the device.
|
||||
"""
|
||||
function gen_access_expr(device::NumaNode, symbol::Symbol)
|
||||
return _gen_access_expr(device, device.cacheStrategy, symbol)
|
||||
end
|
||||
|
||||
"""
|
||||
_gen_access_expr(device::NumaNode, ::LocalVariables, symbol::Symbol)
|
||||
|
||||
Internal function for dispatch, used in [`gen_access_expr`](@ref).
|
||||
"""
|
||||
function _gen_access_expr(device::NumaNode, ::LocalVariables, symbol::Symbol)
|
||||
s = Symbol("data_$symbol")
|
||||
quoteNode = Meta.parse(":($s)")
|
||||
return quoteNode
|
||||
end
|
||||
|
||||
"""
|
||||
_gen_access_expr(device::NumaNode, ::Dictionary, symbol::Symbol)
|
||||
|
||||
Internal function for dispatch, used in [`gen_access_expr`](@ref).
|
||||
"""
|
||||
function _gen_access_expr(device::NumaNode, ::Dictionary, symbol::Symbol)
|
||||
accessStr = ":(cache_$(to_var_name(device.id))[:$symbol])"
|
||||
quoteNode = Meta.parse(accessStr)
|
||||
return quoteNode
|
||||
end
|
53
src/devices/oneapi/impl.jl
Normal file
53
src/devices/oneapi/impl.jl
Normal file
@ -0,0 +1,53 @@
|
||||
using oneAPI
|
||||
|
||||
"""
|
||||
oneAPIGPU <: AbstractGPU
|
||||
|
||||
Representation of a specific Intel GPU that code can run on. Implements the [`AbstractDevice`](@ref) interface.
|
||||
"""
|
||||
mutable struct oneAPIGPU <: AbstractGPU
|
||||
device::Any
|
||||
cacheStrategy::CacheStrategy
|
||||
FLOPS::Float64
|
||||
end
|
||||
|
||||
push!(DEVICE_TYPES, oneAPIGPU)
|
||||
|
||||
CACHE_STRATEGIES[oneAPIGPU] = [LocalVariables()]
|
||||
|
||||
default_strategy(::Type{T}) where {T <: oneAPIGPU} = LocalVariables()
|
||||
|
||||
function measure_device!(device::oneAPIGPU; verbose::Bool)
|
||||
if verbose
|
||||
println("Measuring oneAPI GPU $(device.device)")
|
||||
end
|
||||
|
||||
# TODO implement
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
get_devices(deviceType::Type{T}; verbose::Bool = false) where {T <: oneAPIGPU}
|
||||
|
||||
Return a Vector of [`oneAPIGPU`](@ref)s available on the current machine. If `verbose` is true, print some additional information.
|
||||
"""
|
||||
function get_devices(deviceType::Type{T}; verbose::Bool = false) where {T <: oneAPIGPU}
|
||||
devices = Vector{AbstractDevice}()
|
||||
|
||||
if !oneAPI.functional()
|
||||
if verbose
|
||||
println("oneAPI is non-functional")
|
||||
end
|
||||
return devices
|
||||
end
|
||||
|
||||
oneAPIDevices = oneAPI.devices()
|
||||
if verbose
|
||||
println("Found $(length(oneAPIDevices)) oneAPI devices")
|
||||
end
|
||||
for device in oneAPIDevices
|
||||
push!(devices, oneAPIGPU(device, default_strategy(oneAPIGPU), -1))
|
||||
end
|
||||
|
||||
return devices
|
||||
end
|
53
src/devices/rocm/impl.jl
Normal file
53
src/devices/rocm/impl.jl
Normal file
@ -0,0 +1,53 @@
|
||||
using AMDGPU
|
||||
|
||||
"""
|
||||
ROCmGPU <: AbstractGPU
|
||||
|
||||
Representation of a specific AMD GPU that code can run on. Implements the [`AbstractDevice`](@ref) interface.
|
||||
"""
|
||||
mutable struct ROCmGPU <: AbstractGPU
|
||||
device::Any
|
||||
cacheStrategy::CacheStrategy
|
||||
FLOPS::Float64
|
||||
end
|
||||
|
||||
push!(DEVICE_TYPES, ROCmGPU)
|
||||
|
||||
CACHE_STRATEGIES[ROCmGPU] = [LocalVariables()]
|
||||
|
||||
default_strategy(::Type{T}) where {T <: ROCmGPU} = LocalVariables()
|
||||
|
||||
function measure_device!(device::ROCmGPU; verbose::Bool)
|
||||
if verbose
|
||||
println("Measuring ROCm GPU $(device.device)")
|
||||
end
|
||||
|
||||
# TODO implement
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
get_devices(deviceType::Type{T}; verbose::Bool = false) where {T <: ROCmGPU}
|
||||
|
||||
Return a Vector of [`ROCmGPU`](@ref)s available on the current machine. If `verbose` is true, print some additional information.
|
||||
"""
|
||||
function get_devices(deviceType::Type{T}; verbose::Bool = false) where {T <: ROCmGPU}
|
||||
devices = Vector{AbstractDevice}()
|
||||
|
||||
if !AMDGPU.functional()
|
||||
if verbose
|
||||
println("AMDGPU is non-functional")
|
||||
end
|
||||
return devices
|
||||
end
|
||||
|
||||
AMDDevices = AMDGPU.devices()
|
||||
if verbose
|
||||
println("Found $(length(AMDDevices)) AMD devices")
|
||||
end
|
||||
for device in AMDDevices
|
||||
push!(devices, ROCmGPU(device, default_strategy(ROCmGPU), -1))
|
||||
end
|
||||
|
||||
return devices
|
||||
end
|
@ -6,6 +6,6 @@ Pretty-print a [`Diff`](@ref). Called via print, println and co.
|
||||
function show(io::IO, diff::Diff)
|
||||
print(io, "Nodes: ")
|
||||
print(io, length(diff.addedNodes) + length(diff.removedNodes))
|
||||
print(io, " Edges: ")
|
||||
print(io, ", Edges: ")
|
||||
return print(io, length(diff.addedEdges) + length(diff.removedEdges))
|
||||
end
|
||||
|
@ -4,8 +4,8 @@
|
||||
A named tuple representing a difference of added and removed nodes and edges on a [`DAG`](@ref).
|
||||
"""
|
||||
const Diff = NamedTuple{
|
||||
(:addedNodes, :removedNodes, :addedEdges, :removedEdges),
|
||||
Tuple{Vector{Node}, Vector{Node}, Vector{Edge}, Vector{Edge}},
|
||||
(:addedNodes, :removedNodes, :addedEdges, :removedEdges, :updatedChildren),
|
||||
Tuple{Vector{Node}, Vector{Node}, Vector{Edge}, Vector{Edge}, Vector{Tuple{Node, AbstractTask}}},
|
||||
}
|
||||
|
||||
function Diff()
|
||||
@ -14,5 +14,8 @@ function Diff()
|
||||
removedNodes = Vector{Node}(),
|
||||
addedEdges = Vector{Edge}(),
|
||||
removedEdges = Vector{Edge}(),
|
||||
|
||||
# children were updated in the task, updatedChildren[x][2] is the task before the update
|
||||
updatedChildren = Vector{Tuple{Node, AbstractTask}}(),
|
||||
)::Diff
|
||||
end
|
||||
|
81
src/estimator/global_metric.jl
Normal file
81
src/estimator/global_metric.jl
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
"""
|
||||
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
|
||||
|
||||
function String(::GlobalMetricEstimator)
|
||||
return "global_metric"
|
||||
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
|
@ -1,3 +1,5 @@
|
||||
using DataStructures
|
||||
|
||||
"""
|
||||
in(node::Node, graph::DAG)
|
||||
|
||||
@ -17,21 +19,56 @@ function in(edge::Edge, graph::DAG)
|
||||
return false
|
||||
end
|
||||
|
||||
return n1 in n2.children
|
||||
return n1 in children(n2)
|
||||
end
|
||||
|
||||
"""
|
||||
==(n1::Node, n2::Node, g::DAG)
|
||||
is_dependent(graph::DAG, n1::Node, n2::Node)
|
||||
|
||||
Check equality of two nodes in a graph.
|
||||
Returns whether `n1` is dependent on `n2` in the given `graph`.
|
||||
"""
|
||||
function ==(n1::Node, n2::Node, g::DAG)
|
||||
if typeof(n1) != typeof(n2)
|
||||
function is_dependent(graph::DAG, n1::Node, n2::Node)
|
||||
if !(n1 in graph) || !(n2 in graph)
|
||||
return false
|
||||
end
|
||||
if !(n1 in g) || !(n2 in g)
|
||||
if n1 == n2
|
||||
return false
|
||||
end
|
||||
|
||||
return n1.task == n2.task && children(n1) == children(n2)
|
||||
queue = Deque{Node}()
|
||||
push!(queue, n1)
|
||||
|
||||
# TODO: this is probably not the best way to do this, deduplication in the queue would help
|
||||
while !isempty(queue)
|
||||
current = popfirst!(queue)
|
||||
if current == n2
|
||||
return true
|
||||
end
|
||||
|
||||
for c in current.children
|
||||
push!(queue, c)
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
"""
|
||||
pairwise_independent(graph::DAG, nodes::Vector{Node})
|
||||
|
||||
Returns true if all given `nodes` are independent of each other, i.e., no path exists from any member of `nodes` to any other member.
|
||||
|
||||
See [`is_dependent`](@ref)
|
||||
"""
|
||||
function pairwise_independent(graph::DAG, nodes::Vector{<:Node})
|
||||
checked_set = Vector{Node}()
|
||||
for n in nodes
|
||||
for c in checked_set
|
||||
if is_dependent(graph, c, n) || is_dependent(graph, n, c)
|
||||
return false
|
||||
end
|
||||
end
|
||||
push!(checked_set, n)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
@ -38,8 +38,7 @@ end
|
||||
|
||||
Return `true` if [`pop_operation!`](@ref) is possible, `false` otherwise.
|
||||
"""
|
||||
can_pop(graph::DAG) =
|
||||
!isempty(graph.operationsToApply) || !isempty(graph.appliedOperations)
|
||||
can_pop(graph::DAG) = !isempty(graph.operationsToApply) || !isempty(graph.appliedOperations)
|
||||
|
||||
"""
|
||||
reset_graph!(graph::DAG)
|
||||
|
@ -15,12 +15,7 @@ Insert the node into the graph.
|
||||
|
||||
See also: [`remove_node!`](@ref), [`insert_edge!`](@ref), [`remove_edge!`](@ref)
|
||||
"""
|
||||
function insert_node!(
|
||||
graph::DAG,
|
||||
node::Node,
|
||||
track = true,
|
||||
invalidate_cache = true,
|
||||
)
|
||||
function insert_node!(graph::DAG, node::Node; track = true, invalidate_cache = true)
|
||||
# 1: mute
|
||||
push!(graph.nodes, node)
|
||||
|
||||
@ -50,19 +45,13 @@ 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"
|
||||
function insert_edge!(graph::DAG, node1::Node, node2::Node; track = true, invalidate_cache = true)
|
||||
@assert (node2 ∉ parents(node1)) && (node1 ∉ children(node2)) "Edge to insert already exists"
|
||||
|
||||
# 1: mute
|
||||
# edge points from child to parent
|
||||
push!(node1.parents, node2)
|
||||
push!(node2.children, node1)
|
||||
add_parent!(node1, node2)
|
||||
add_child!(node2, node1)
|
||||
|
||||
# 2: keep track
|
||||
if (track)
|
||||
@ -95,13 +84,8 @@ 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"
|
||||
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"
|
||||
|
||||
# 1: mute
|
||||
delete!(graph.nodes, node)
|
||||
@ -134,29 +118,22 @@ Remove the edge between node1 (child) and node2 (parent) into the graph.
|
||||
|
||||
See also: [`insert_node!`](@ref), [`remove_node!`](@ref), [`insert_edge!`](@ref)
|
||||
"""
|
||||
function remove_edge!(
|
||||
graph::DAG,
|
||||
node1::Node,
|
||||
node2::Node,
|
||||
track = true,
|
||||
invalidate_cache = true,
|
||||
)
|
||||
function remove_edge!(graph::DAG, node1::Node, node2::Node; track = true, invalidate_cache = true)
|
||||
# 1: mute
|
||||
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)
|
||||
remove_parent!(node1, node2)
|
||||
remove_child!(node2, node1)
|
||||
|
||||
#=@assert begin
|
||||
removed = pre_length1 - length(node1.parents)
|
||||
removed <= 1
|
||||
removed = pre_length1 - length(node1.parents)
|
||||
removed <= 1
|
||||
end "removed more than one node from node1's parents"=#
|
||||
|
||||
#=@assert begin
|
||||
removed = pre_length2 - length(node2.children)
|
||||
removed <= 1
|
||||
removed = pre_length2 - length(children(node2))
|
||||
removed <= 1
|
||||
end "removed more than one node from node2's children"=#
|
||||
|
||||
# 2: keep track
|
||||
@ -181,6 +158,66 @@ function remove_edge!(
|
||||
return nothing
|
||||
end
|
||||
|
||||
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...)"
|
||||
|
||||
replace!(task.t1_inputs, before => after)
|
||||
replace!(task.t2_inputs, before => after)
|
||||
|
||||
# recursively descend down the tree, but only in the tasks where we're replacing things
|
||||
if replacedIn1 > 0
|
||||
replace_children!(task.first_func, before, after)
|
||||
end
|
||||
if replacedIn2 > 0
|
||||
replace_children!(task.second_func, before, after)
|
||||
end
|
||||
|
||||
return nothing
|
||||
end
|
||||
|
||||
function replace_children!(task::AbstractTask, before, after)
|
||||
return nothing
|
||||
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(task(n)) <: FusedComputeTask)
|
||||
return nothing
|
||||
end
|
||||
|
||||
taskBefore = copy(task(n))
|
||||
|
||||
#=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 children(n)
|
||||
push!(child_ids, "$(child.id)")
|
||||
end
|
||||
println("From $(child_before) to $(child_after) in $n with children $(child_ids)")
|
||||
@assert false
|
||||
end=#
|
||||
|
||||
replace_children!(task(n), child_before, child_after)
|
||||
|
||||
#=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 children(n)
|
||||
push!(child_ids, "$(child.id)")
|
||||
end
|
||||
println("From $(child_before) to $(child_after) in $n with children $(child_ids)")
|
||||
@assert false
|
||||
end=#
|
||||
|
||||
# keep track
|
||||
if (track)
|
||||
push!(graph.diff.updatedChildren, (n, taskBefore))
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
get_snapshot_diff(graph::DAG)
|
||||
|
||||
@ -203,9 +240,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)
|
||||
@ -62,9 +62,5 @@ function show(io::IO, graph::DAG)
|
||||
properties = get_properties(graph)
|
||||
println(io, " Total Compute Effort: ", properties.computeEffort)
|
||||
println(io, " Total Data Transfer: ", properties.data)
|
||||
return println(
|
||||
io,
|
||||
" Total Compute Intensity: ",
|
||||
properties.computeIntensity,
|
||||
)
|
||||
return println(io, " Total Compute Intensity: ", properties.computeIntensity)
|
||||
end
|
||||
|
@ -34,6 +34,7 @@ end
|
||||
Return a vector of the graph's entry nodes.
|
||||
"""
|
||||
function get_entry_nodes(graph::DAG)
|
||||
apply_all!(graph)
|
||||
result = Vector{Node}()
|
||||
for node in graph.nodes
|
||||
if (is_entry_node(node))
|
||||
@ -42,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
|
||||
|
@ -10,6 +10,7 @@ mutable struct PossibleOperations
|
||||
nodeFusions::Set{NodeFusion}
|
||||
nodeReductions::Set{NodeReduction}
|
||||
nodeSplits::Set{NodeSplit}
|
||||
nodeVectorizations::Set{NodeVectorization}
|
||||
end
|
||||
|
||||
"""
|
||||
@ -17,14 +18,14 @@ end
|
||||
|
||||
The representation of the graph as a set of [`Node`](@ref)s.
|
||||
|
||||
A DAG can be loaded using the appropriate parse function, e.g. [`parse_abc`](@ref).
|
||||
A DAG can be loaded using the appropriate parse_dag function, e.g. [`parse_dag`](@ref).
|
||||
|
||||
[`Operation`](@ref)s can be applied on it using [`push_operation!`](@ref) and reverted using [`pop_operation!`](@ref) like a stack.
|
||||
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 +37,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.
|
||||
@ -52,11 +53,7 @@ end
|
||||
Construct and return an empty [`PossibleOperations`](@ref) object.
|
||||
"""
|
||||
function PossibleOperations()
|
||||
return PossibleOperations(
|
||||
Set{NodeFusion}(),
|
||||
Set{NodeReduction}(),
|
||||
Set{NodeSplit}(),
|
||||
)
|
||||
return PossibleOperations(Set{NodeFusion}(), Set{NodeReduction}(), Set{NodeSplit}(), Set{NodeVectorization}())
|
||||
end
|
||||
|
||||
"""
|
||||
|
@ -59,3 +59,19 @@ function is_valid(graph::DAG)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
"""
|
||||
is_scheduled(graph::DAG)
|
||||
|
||||
Validate that the entire graph has been scheduled, i.e., every [`ComputeTaskNode`](@ref) has its `.device` set.
|
||||
"""
|
||||
function is_scheduled(graph::DAG)
|
||||
for node in graph.nodes
|
||||
if (node isa DataTaskNode)
|
||||
continue
|
||||
end
|
||||
@assert !ismissing(node.device)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
@ -1,42 +1,47 @@
|
||||
using AccurateArithmetic
|
||||
using StaticArrays
|
||||
|
||||
"""
|
||||
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,213 +49,44 @@ For valid inputs, both input particles should have the same momenta at this poin
|
||||
|
||||
12 FLOP.
|
||||
"""
|
||||
function compute(::ComputeTaskS2, data1::ParticleValue, data2::ParticleValue)
|
||||
return data1.v * inner_edge(data1.p) * data2.v
|
||||
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)"
|
||||
=#
|
||||
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...)
|
||||
compute(::ComputeTaskABC_Sum, data::AbstractArray)
|
||||
|
||||
Compute a sum over the vector. Use an algorithm that accounts for accumulated errors in long sums with potentially large differences in magnitude of the summands.
|
||||
|
||||
Linearly many FLOP with growing data.
|
||||
"""
|
||||
function compute(::ComputeTaskSum, data::Vector{Float64})
|
||||
return sum_kbn(data)
|
||||
function compute(::ComputeTaskABC_Sum, data...)::Float64
|
||||
return sum(data)
|
||||
end
|
||||
|
||||
"""
|
||||
compute(t::FusedComputeTask, data)
|
||||
|
||||
Compute a [`FusedComputeTask`](@ref). This simply asserts false and should not be called. Fused Compute Tasks generate their expressions directly through the other tasks instead.
|
||||
"""
|
||||
function compute(t::FusedComputeTask, data)
|
||||
@assert false "This is not implemented and should never be called"
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskP, inSymbol::Symbol, outSymbol::Symbol)
|
||||
|
||||
Generate and return code evaluating [`ComputeTaskP`](@ref) on `inSymbol`, providing the output on `outSymbol`.
|
||||
"""
|
||||
function get_expression(::ComputeTaskP, inSymbol::Symbol, outSymbol::Symbol)
|
||||
return Meta.parse("$outSymbol = compute(ComputeTaskP(), $inSymbol)")
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskU, inSymbol::Symbol, outSymbol::Symbol)
|
||||
|
||||
Generate code evaluating [`ComputeTaskU`](@ref) on `inSymbol`, providing the output on `outSymbol`.
|
||||
`inSymbol` should be of type [`ParticleValue`](@ref), `outSymbol` will be of type [`ParticleValue`](@ref).
|
||||
"""
|
||||
function get_expression(::ComputeTaskU, inSymbol::Symbol, outSymbol::Symbol)
|
||||
return Meta.parse("$outSymbol = compute(ComputeTaskU(), $inSymbol)")
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskV, inSymbol1::Symbol, inSymbol2::Symbol, outSymbol::Symbol)
|
||||
|
||||
Generate code evaluating [`ComputeTaskV`](@ref) on `inSymbol1` and `inSymbol2`, providing the output on `outSymbol`.
|
||||
`inSymbol1` and `inSymbol2` should be of type [`ParticleValue`](@ref), `outSymbol` will be of type [`ParticleValue`](@ref).
|
||||
"""
|
||||
function get_expression(
|
||||
::ComputeTaskV,
|
||||
inSymbol1::Symbol,
|
||||
inSymbol2::Symbol,
|
||||
outSymbol::Symbol,
|
||||
)
|
||||
return Meta.parse(
|
||||
"$outSymbol = compute(ComputeTaskV(), $inSymbol1, $inSymbol2)",
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskS2, inSymbol1::Symbol, inSymbol2::Symbol, outSymbol::Symbol)
|
||||
|
||||
Generate code evaluating [`ComputeTaskS2`](@ref) on `inSymbol1` and `inSymbol2`, providing the output on `outSymbol`.
|
||||
`inSymbol1` and `inSymbol2` should be of type [`ParticleValue`](@ref), `outSymbol` will be of type `Float64`.
|
||||
"""
|
||||
function get_expression(
|
||||
::ComputeTaskS2,
|
||||
inSymbol1::Symbol,
|
||||
inSymbol2::Symbol,
|
||||
outSymbol::Symbol,
|
||||
)
|
||||
return Meta.parse(
|
||||
"$outSymbol = compute(ComputeTaskS2(), $inSymbol1, $inSymbol2)",
|
||||
)
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskS1, inSymbol::Symbol, outSymbol::Symbol)
|
||||
|
||||
Generate code evaluating [`ComputeTaskS1`](@ref) on `inSymbol`, providing the output on `outSymbol`.
|
||||
`inSymbol` should be of type [`ParticleValue`](@ref), `outSymbol` will be of type [`ParticleValue`](@ref).
|
||||
"""
|
||||
function get_expression(::ComputeTaskS1, inSymbol::Symbol, outSymbol::Symbol)
|
||||
return Meta.parse("$outSymbol = compute(ComputeTaskS1(), $inSymbol)")
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(::ComputeTaskSum, inSymbols::Vector{Symbol}, outSymbol::Symbol)
|
||||
|
||||
Generate code evaluating [`ComputeTaskSum`](@ref) on `inSymbols`, providing the output on `outSymbol`.
|
||||
`inSymbols` should be of type [`Float64`], `outSymbol` will be of type [`Float64`].
|
||||
"""
|
||||
function get_expression(
|
||||
::ComputeTaskSum,
|
||||
inSymbols::Vector{Symbol},
|
||||
outSymbol::Symbol,
|
||||
)
|
||||
return quote
|
||||
$outSymbol = compute(ComputeTaskSum(), [$(inSymbols...)])
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(t::FusedComputeTask, inSymbols::Vector{Symbol}, outSymbol::Symbol)
|
||||
|
||||
Generate code evaluating a [`FusedComputeTask`](@ref) on `inSymbols`, providing the output on `outSymbol`.
|
||||
`inSymbols` should be of the correct types and may be heterogeneous. `outSymbol` will be of the type of the output of `T2` of t.
|
||||
"""
|
||||
function get_expression(
|
||||
t::FusedComputeTask,
|
||||
inSymbols::Vector{Symbol},
|
||||
outSymbol::Symbol,
|
||||
)
|
||||
(T1, T2) = get_types(t)
|
||||
c1 = children(T1())
|
||||
c2 = children(T2())
|
||||
|
||||
expr1 = nothing
|
||||
expr2 = nothing
|
||||
|
||||
# TODO need to figure out how to know which inputs belong to which subtask
|
||||
# since we order the vectors with the child nodes we can't just split
|
||||
if (c1 == 1)
|
||||
expr1 = get_expression(T1(), inSymbols[begin], :intermediate)
|
||||
elseif (c1 == 2)
|
||||
expr1 =
|
||||
get_expression(T1(), inSymbols[begin], inSymbols[2], :intermediate)
|
||||
else
|
||||
expr1 = get_expression(T1(), inSymbols[begin:c1], :intermediate)
|
||||
end
|
||||
|
||||
if (c2 == 1)
|
||||
expr2 = get_expression(T2(), :intermediate, outSymbol)
|
||||
elseif c2 == 2
|
||||
expr2 =
|
||||
get_expression(T2(), :intermediate, inSymbols[c1 + 1], outSymbol)
|
||||
else
|
||||
expr2 = get_expression(
|
||||
T2(),
|
||||
:intermediate * inSymbols[(c1 + 1):end],
|
||||
outSymbol,
|
||||
)
|
||||
end
|
||||
|
||||
return Expr(:block, expr1, expr2)
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(node::ComputeTaskNode)
|
||||
|
||||
Generate and return code for a given [`ComputeTaskNode`](@ref).
|
||||
"""
|
||||
function get_expression(node::ComputeTaskNode)
|
||||
t = typeof(node.task)
|
||||
@assert length(node.children) == children(node.task) || t <: ComputeTaskSum
|
||||
|
||||
if (t <: ComputeTaskU || t <: ComputeTaskP || t <: ComputeTaskS1) # single input
|
||||
symbolIn = Symbol("data_$(to_var_name(node.children[1].id))")
|
||||
symbolOut = Symbol("data_$(to_var_name(node.id))")
|
||||
return get_expression(t(), symbolIn, symbolOut)
|
||||
elseif (t <: ComputeTaskS2 || t <: ComputeTaskV) # double input
|
||||
symbolIn1 = Symbol("data_$(to_var_name(node.children[1].id))")
|
||||
symbolIn2 = Symbol("data_$(to_var_name(node.children[2].id))")
|
||||
symbolOut = Symbol("data_$(to_var_name(node.id))")
|
||||
return get_expression(t(), symbolIn1, symbolIn2, symbolOut)
|
||||
elseif (t <: ComputeTaskSum || t <: FusedComputeTask) # vector input
|
||||
inSymbols = Vector{Symbol}()
|
||||
for child in node.children
|
||||
push!(inSymbols, Symbol("data_$(to_var_name(child.id))"))
|
||||
end
|
||||
outSymbol = Symbol("data_$(to_var_name(node.id))")
|
||||
return get_expression(t(), inSymbols, outSymbol)
|
||||
else
|
||||
error("Unknown compute task")
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
get_expression(node::DataTaskNode)
|
||||
|
||||
Generate and return code for a given [`DataTaskNode`](@ref).
|
||||
"""
|
||||
function get_expression(node::DataTaskNode)
|
||||
# TODO: do things to transport data from/to gpu, between numa nodes, etc.
|
||||
@assert length(node.children) <= 1
|
||||
|
||||
inSymbol = nothing
|
||||
if (length(node.children) == 1)
|
||||
inSymbol = Symbol("data_$(to_var_name(node.children[1].id))")
|
||||
else
|
||||
inSymbol = Symbol("data_$(to_var_name(node.id))_in")
|
||||
end
|
||||
outSymbol = Symbol("data_$(to_var_name(node.id))")
|
||||
|
||||
dataTransportExp = Meta.parse("$outSymbol = $inSymbol")
|
||||
|
||||
return dataTransportExp
|
||||
function compute(::ComputeTaskABC_Sum, data::AbstractArray)::Float64
|
||||
return sum(data)
|
||||
end
|
||||
|
@ -1,74 +1,86 @@
|
||||
using QEDbase
|
||||
using Random
|
||||
using Roots
|
||||
using ForwardDiff
|
||||
|
||||
"""
|
||||
Particle(rng)
|
||||
ComputeTaskABC_Sum() = ComputeTaskABC_Sum(0)
|
||||
|
||||
Return a randomly generated particle.
|
||||
"""
|
||||
function Particle(rng, type::ParticleType)
|
||||
function _svector_from_type_in(processDescription::ABCProcessDescription, type, particles)
|
||||
if haskey(in_particles(processDescription), type)
|
||||
return SVector{in_particles(processDescription)[type], type}(filter(x -> typeof(x) <: type, particles))
|
||||
end
|
||||
return SVector{0, type}()
|
||||
end
|
||||
|
||||
p1 = rand(rng, Float64)
|
||||
p2 = rand(rng, Float64)
|
||||
p3 = rand(rng, Float64)
|
||||
m = mass(type)
|
||||
|
||||
# keep the momenta of the particles on-shell
|
||||
p4 = sqrt(p1^2 + p2^2 + p3^2 + m^2)
|
||||
|
||||
return Particle(p1, p2, p3, p4, type)
|
||||
function _svector_from_type_out(processDescription::ABCProcessDescription, type, particles)
|
||||
if haskey(out_particles(processDescription), type)
|
||||
return SVector{out_particles(processDescription)[type], type}(filter(x -> typeof(x) <: type, particles))
|
||||
end
|
||||
return SVector{0, type}()
|
||||
end
|
||||
|
||||
"""
|
||||
gen_particles(n::Int)
|
||||
gen_process_input(processDescription::ABCProcessDescription)
|
||||
|
||||
Return a Vector of `n` randomly generated [`Particle`](@ref)s.
|
||||
Return a ProcessInput of randomly generated [`ABCParticle`](@ref)s from a [`ABCProcessDescription`](@ref). The process description can be created manually or parsed from a string using [`parse_process`](@ref).
|
||||
|
||||
Note: This does not take into account the preservation of momenta required for an actual valid process!
|
||||
Note: This uses RAMBO to create a valid process with conservation of momentum and energy.
|
||||
"""
|
||||
function gen_particles(ns::Dict{ParticleType, Int})
|
||||
particles = Dict{ParticleType, Vector{Particle}}()
|
||||
rng = MersenneTwister(0)
|
||||
function gen_process_input(processDescription::ABCProcessDescription)
|
||||
inParticleTypes = keys(processDescription.inParticles)
|
||||
outParticleTypes = keys(processDescription.outParticles)
|
||||
|
||||
|
||||
if ns == Dict((A => 2), (B => 2))
|
||||
rho = 1.0
|
||||
|
||||
omega = rand(rng, Float64)
|
||||
theta = rand(rng, Float64) * π
|
||||
phi = rand(rng, Float64) * π
|
||||
|
||||
particles[A] = Vector{Particle}()
|
||||
particles[B] = Vector{Particle}()
|
||||
|
||||
push!(particles[A], Particle(omega, 0, 0, omega, A))
|
||||
push!(particles[B], Particle(omega, 0, 0, -omega, B))
|
||||
push!(
|
||||
particles[A],
|
||||
Particle(
|
||||
omega,
|
||||
rho * cos(theta) * cos(phi),
|
||||
rho * cos(theta) * sin(phi),
|
||||
rho * sin(theta),
|
||||
A,
|
||||
),
|
||||
)
|
||||
push!(
|
||||
particles[B],
|
||||
Particle(
|
||||
omega,
|
||||
-rho * cos(theta) * cos(phi),
|
||||
-rho * cos(theta) * sin(phi),
|
||||
-rho * sin(theta),
|
||||
B,
|
||||
),
|
||||
)
|
||||
return particles
|
||||
end
|
||||
|
||||
for (type, n) in ns
|
||||
particles[type] = Vector{Particle}()
|
||||
for i in 1:n
|
||||
push!(particles[type], Particle(rng, type))
|
||||
massSum = 0
|
||||
inputMasses = Vector{Float64}()
|
||||
for (particle, n) in processDescription.inParticles
|
||||
for _ in 1:n
|
||||
massSum += mass(particle)
|
||||
push!(inputMasses, mass(particle))
|
||||
end
|
||||
end
|
||||
return particles
|
||||
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{ABCParticle}()
|
||||
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{ABCParticle}()
|
||||
final_momenta = generate_physical_massive_moms(rng[threadid()], massSum, outputMasses)
|
||||
index = 1
|
||||
for (particle, n) in processDescription.outParticles
|
||||
for _ in 1:n
|
||||
mom = final_momenta[index]
|
||||
push!(outputParticles, particle(SFourMomentum(-mom.E, mom.px, mom.py, mom.pz)))
|
||||
index += 1
|
||||
end
|
||||
end
|
||||
|
||||
inA = _svector_from_type_in(processDescription, ParticleA, inputParticles)
|
||||
inB = _svector_from_type_in(processDescription, ParticleB, inputParticles)
|
||||
inC = _svector_from_type_in(processDescription, ParticleC, inputParticles)
|
||||
|
||||
outA = _svector_from_type_out(processDescription, ParticleA, outputParticles)
|
||||
outB = _svector_from_type_out(processDescription, ParticleB, outputParticles)
|
||||
outC = _svector_from_type_out(processDescription, ParticleC, outputParticles)
|
||||
|
||||
processInput = ABCProcessInput(processDescription, inA, inB, inC, outA, outB, outC)
|
||||
|
||||
return return processInput
|
||||
end
|
||||
|
@ -32,13 +32,13 @@ function parse_edges(input::AbstractString)
|
||||
end
|
||||
|
||||
"""
|
||||
parse_abc(filename::String; verbose::Bool = false)
|
||||
parse_dag(filename::String, model::ABCModel; verbose::Bool = false)
|
||||
|
||||
Read an abc-model process from the given file. If `verbose` is set to true, print some progress information to stdout.
|
||||
|
||||
Returns a valid [`DAG`](@ref).
|
||||
"""
|
||||
function parse_abc(filename::String, verbose::Bool = false)
|
||||
function parse_dag(filename::AbstractString, model::ABCModel, verbose::Bool = false)
|
||||
file = open(filename, "r")
|
||||
|
||||
if (verbose)
|
||||
@ -63,10 +63,9 @@ function parse_abc(filename::String, verbose::Bool = false)
|
||||
end
|
||||
sizehint!(graph.nodes, estimate_no_nodes)
|
||||
|
||||
sum_node = insert_node!(graph, make_node(ComputeTaskSum()), false, false)
|
||||
global_data_out =
|
||||
insert_node!(graph, make_node(DataTask(FLOAT_SIZE)), false, false)
|
||||
insert_edge!(graph, sum_node, global_data_out, false, 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)
|
||||
|
||||
# remember the data out nodes for connection
|
||||
dataOutNodes = Dict()
|
||||
@ -81,10 +80,7 @@ function parse_abc(filename::String, verbose::Bool = false)
|
||||
noNodes += 1
|
||||
if (noNodes % 100 == 0)
|
||||
if (verbose)
|
||||
percent = string(
|
||||
round(100.0 * noNodes / nodesToRead, digits = 2),
|
||||
"%",
|
||||
)
|
||||
percent = string(round(100.0 * noNodes / nodesToRead, digits = 2), "%")
|
||||
print("\rReading Nodes... $percent")
|
||||
end
|
||||
end
|
||||
@ -93,30 +89,20 @@ function parse_abc(filename::String, verbose::Bool = false)
|
||||
data_in = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE), string(node)),
|
||||
false,
|
||||
false,
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
) # read particle data node
|
||||
compute_P =
|
||||
insert_node!(graph, make_node(ComputeTaskP()), false, false) # compute P node
|
||||
data_Pu = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
false,
|
||||
false,
|
||||
) # transfer data from P to u (one ParticleValue object)
|
||||
compute_u =
|
||||
insert_node!(graph, make_node(ComputeTaskU()), false, false) # compute U node
|
||||
data_out = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
false,
|
||||
false,
|
||||
) # transfer data out from u (one ParticleValue object)
|
||||
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 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 ABCParticleValue object)
|
||||
|
||||
insert_edge!(graph, data_in, compute_P, false, false)
|
||||
insert_edge!(graph, compute_P, data_Pu, false, false)
|
||||
insert_edge!(graph, data_Pu, compute_u, false, false)
|
||||
insert_edge!(graph, compute_u, data_out, false, false)
|
||||
insert_edge!(graph, data_in, compute_P, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, compute_P, data_Pu, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, data_Pu, 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[node] = data_out
|
||||
@ -126,63 +112,48 @@ function parse_abc(filename::String, verbose::Bool = false)
|
||||
in1 = capt.captures[1]
|
||||
in2 = capt.captures[2]
|
||||
|
||||
compute_v =
|
||||
insert_node!(graph, make_node(ComputeTaskV()), false, false)
|
||||
data_out = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
false,
|
||||
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()),
|
||||
false,
|
||||
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)),
|
||||
false,
|
||||
false,
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
)
|
||||
|
||||
insert_edge!(graph, dataOutNodes[in1], compute_S, false, false)
|
||||
insert_edge!(graph, compute_S, data_S_v, false, false)
|
||||
insert_edge!(graph, dataOutNodes[in1], compute_S, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, compute_S, data_S_v, track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, data_S_v, compute_v, false, false)
|
||||
insert_edge!(graph, data_S_v, compute_v, track = false, invalidate_cache = false)
|
||||
else
|
||||
insert_edge!(graph, dataOutNodes[in1], compute_v, false, false)
|
||||
insert_edge!(graph, dataOutNodes[in1], compute_v, track = false, invalidate_cache = false)
|
||||
end
|
||||
|
||||
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()),
|
||||
false,
|
||||
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)),
|
||||
false,
|
||||
false,
|
||||
track = false,
|
||||
invalidate_cache = false,
|
||||
)
|
||||
|
||||
insert_edge!(graph, dataOutNodes[in2], compute_S, false, false)
|
||||
insert_edge!(graph, compute_S, data_S_v, false, false)
|
||||
insert_edge!(graph, dataOutNodes[in2], compute_S, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, compute_S, data_S_v, track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, data_S_v, compute_v, false, false)
|
||||
insert_edge!(graph, data_S_v, compute_v, track = false, invalidate_cache = false)
|
||||
else
|
||||
insert_edge!(graph, dataOutNodes[in2], compute_v, false, false)
|
||||
insert_edge!(graph, dataOutNodes[in2], compute_v, track = false, invalidate_cache = false)
|
||||
end
|
||||
|
||||
insert_edge!(graph, compute_v, data_out, false, false)
|
||||
insert_edge!(graph, compute_v, data_out, track = false, invalidate_cache = false)
|
||||
dataOutNodes[node] = data_out
|
||||
|
||||
elseif occursin(regex_m, node)
|
||||
@ -193,43 +164,31 @@ function parse_abc(filename::String, verbose::Bool = false)
|
||||
in3 = capt.captures[3]
|
||||
|
||||
# in2 + in3 with a v
|
||||
compute_v =
|
||||
insert_node!(graph, make_node(ComputeTaskV()), false, false)
|
||||
data_v = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(PARTICLE_VALUE_SIZE)),
|
||||
false,
|
||||
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)
|
||||
|
||||
insert_edge!(graph, dataOutNodes[in2], compute_v, false, false)
|
||||
insert_edge!(graph, dataOutNodes[in3], compute_v, false, false)
|
||||
insert_edge!(graph, compute_v, data_v, false, false)
|
||||
insert_edge!(graph, dataOutNodes[in2], compute_v, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, dataOutNodes[in3], compute_v, track = false, invalidate_cache = false)
|
||||
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()), false, false)
|
||||
data_out = insert_node!(
|
||||
graph,
|
||||
make_node(DataTask(FLOAT_SIZE)),
|
||||
false,
|
||||
false,
|
||||
) # output of a S2 task is only a float
|
||||
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, false, false)
|
||||
insert_edge!(graph, dataOutNodes[in1], compute_S2, false, false)
|
||||
insert_edge!(graph, compute_S2, data_out, false, false)
|
||||
insert_edge!(graph, data_v, compute_S2, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, dataOutNodes[in1], compute_S2, track = false, invalidate_cache = false)
|
||||
insert_edge!(graph, compute_S2, data_out, track = false, invalidate_cache = false)
|
||||
|
||||
insert_edge!(graph, data_out, sum_node, false, false)
|
||||
insert_edge!(graph, data_out, sum_node, track = false, invalidate_cache = false)
|
||||
add_child!(task(sum_node).func)
|
||||
elseif occursin(regex_plus, node)
|
||||
if (verbose)
|
||||
println("\rReading Nodes Complete ")
|
||||
println("Added ", length(graph.nodes), " nodes")
|
||||
end
|
||||
else
|
||||
@assert false (
|
||||
"Unknown node '$node' while reading from file $filename"
|
||||
)
|
||||
@assert false ("Unknown node '$node' while reading from file $filename")
|
||||
end
|
||||
end
|
||||
|
||||
@ -244,6 +203,46 @@ function parse_abc(filename::String, verbose::Bool = false)
|
||||
if (verbose)
|
||||
println("Done")
|
||||
end
|
||||
|
||||
# don't actually need to read the edges
|
||||
return graph
|
||||
end
|
||||
|
||||
"""
|
||||
parse_process(string::AbstractString, model::ABCModel)
|
||||
|
||||
Parse a string representation of a process, such as "AB->ABBB" into the corresponding [`ABCProcessDescription`](@ref).
|
||||
"""
|
||||
function parse_process(str::AbstractString, model::ABCModel)
|
||||
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)
|
||||
inCount = count(x -> x == String(t)[1], inStr)
|
||||
outCount = count(x -> x == String(t)[1], outStr)
|
||||
if inCount != 0
|
||||
inParticles[t] = inCount
|
||||
end
|
||||
if outCount != 0
|
||||
outParticles[t] = outCount
|
||||
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 ABCProcessDescription(inParticles, outParticles)
|
||||
end
|
||||
|
@ -1,130 +1,232 @@
|
||||
"""
|
||||
ParticleType
|
||||
using StaticArrays
|
||||
|
||||
A Particle Type in the ABC Model as an enum, with types `A`, `B` and `C`.
|
||||
"""
|
||||
@enum ParticleType A = 1 B = 2 C = 3
|
||||
import QEDbase.mass
|
||||
|
||||
"""
|
||||
PARTICLE_MASSES
|
||||
ABCModel <: AbstractPhysicsModel
|
||||
|
||||
A constant dictionary containing the masses of the different [`ParticleType`](@ref)s.
|
||||
Singleton definition for identification of the ABC-Model.
|
||||
"""
|
||||
const PARTICLE_MASSES =
|
||||
Dict{ParticleType, Float64}(A => 1.0, B => 1.0, C => 0.0)
|
||||
struct ABCModel <: AbstractPhysicsModel end
|
||||
|
||||
"""
|
||||
Particle
|
||||
ABCParticle
|
||||
|
||||
A struct describing a particle of the ABC-Model. It has the 4 momentum parts P0...P3 and a [`ParticleType`](@ref).
|
||||
|
||||
`sizeof(Particle())` = 40 Byte
|
||||
Base type for all particles in the [`ABCModel`](@ref).
|
||||
"""
|
||||
struct Particle
|
||||
P0::Float64
|
||||
P1::Float64
|
||||
P2::Float64
|
||||
P3::Float64
|
||||
abstract type ABCParticle <: AbstractParticle end
|
||||
|
||||
type::ParticleType
|
||||
"""
|
||||
ParticleA <: ABCParticle
|
||||
|
||||
An 'A' particle in the ABC Model.
|
||||
"""
|
||||
struct ParticleA <: ABCParticle
|
||||
momentum::SFourMomentum
|
||||
end
|
||||
|
||||
"""
|
||||
ParticleValue
|
||||
ParticleB <: ABCParticle
|
||||
|
||||
A struct describing a particle during a calculation of a Feynman Diagram, together with the value that's being calculated.
|
||||
|
||||
`sizeof(ParticleValue())` = 48 Byte
|
||||
A 'B' particle in the ABC Model.
|
||||
"""
|
||||
struct ParticleValue
|
||||
p::Particle
|
||||
v::Float64
|
||||
struct ParticleB <: ABCParticle
|
||||
momentum::SFourMomentum
|
||||
end
|
||||
|
||||
"""
|
||||
mass(t::ParticleType)
|
||||
ParticleC <: ABCParticle
|
||||
|
||||
A 'C' particle in the ABC Model.
|
||||
"""
|
||||
struct ParticleC <: ABCParticle
|
||||
momentum::SFourMomentum
|
||||
end
|
||||
|
||||
"""
|
||||
ABCProcessDescription <: AbstractProcessDescription
|
||||
|
||||
A description of a process in the ABC-Model. Contains the input and output particles.
|
||||
|
||||
See also: [`in_particles`](@ref), [`out_particles`](@ref), [`parse_process`](@ref)
|
||||
"""
|
||||
struct ABCProcessDescription <: AbstractProcessDescription
|
||||
inParticles::Dict{Type, Int}
|
||||
outParticles::Dict{Type, Int}
|
||||
end
|
||||
|
||||
"""
|
||||
ABCProcessInput <: AbstractProcessInput
|
||||
|
||||
Input for a ABC Process. Contains the [`ABCProcessDescription`](@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 ABCProcessInput{N1, N2, N3, N4, N5, N6} <: AbstractProcessInput
|
||||
process::ABCProcessDescription
|
||||
inA::SVector{N1, ParticleA}
|
||||
inB::SVector{N2, ParticleB}
|
||||
inC::SVector{N3, ParticleC}
|
||||
outA::SVector{N4, ParticleA}
|
||||
outB::SVector{N5, ParticleB}
|
||||
outC::SVector{N6, ParticleC}
|
||||
end
|
||||
|
||||
ABCParticleValue{ParticleType <: ABCParticle} = ParticleValue{ParticleType, ComplexF64}
|
||||
|
||||
"""
|
||||
mass(t::Type{T}) where {T <: ABCParticle}
|
||||
|
||||
Return the mass (at rest) of the given particle type.
|
||||
"""
|
||||
mass(t::ParticleType) = PARTICLE_MASSES[t]
|
||||
mass(::ParticleA) = 1.0
|
||||
mass(::ParticleB) = 1.0
|
||||
mass(::ParticleC) = 0.0
|
||||
|
||||
mass(::Type{ParticleA}) = 1.0
|
||||
mass(::Type{ParticleB}) = 1.0
|
||||
mass(::Type{ParticleC}) = 0.0
|
||||
|
||||
"""
|
||||
remaining_type(t1::ParticleType, t2::ParticleType)
|
||||
interaction_result(t1::Type{T1}, t2::Type{T2}) where {T1 <: ABCParticle, T2 <: ABCParticle}
|
||||
|
||||
For 2 given (non-equal) particle types, return the third of ABC.
|
||||
"""
|
||||
function remaining_type(t1::ParticleType, t2::ParticleType)
|
||||
function interaction_result(t1::Type{T1}, t2::Type{T2}) where {T1 <: ABCParticle, T2 <: ABCParticle}
|
||||
@assert t1 != t2
|
||||
if t1 != A && t2 != A
|
||||
return A
|
||||
elseif t1 != B && t2 != B
|
||||
return B
|
||||
if t1 != ParticleA && t2 != ParticleA
|
||||
return ParticleA
|
||||
elseif t1 != ParticleB && t2 != ParticleB
|
||||
return ParticleB
|
||||
else
|
||||
return C
|
||||
return ParticleC
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
square(p::Particle)
|
||||
types(::ABCModel)
|
||||
|
||||
Return a Vector of the possible types of particle in the [`ABCModel`](@ref).
|
||||
"""
|
||||
function types(::ABCModel)
|
||||
return [ParticleA, ParticleB, ParticleC]
|
||||
end
|
||||
|
||||
"""
|
||||
square(p::ABCParticle)
|
||||
|
||||
Return the square of the particle's momentum as a `Float` value.
|
||||
|
||||
Takes 7 effective FLOP.
|
||||
"""
|
||||
function square(p::Particle)
|
||||
return p.P0 * p.P0 - p.P1 * p.P1 - p.P2 * p.P2 - p.P3 * p.P3
|
||||
function square(p::ABCParticle)
|
||||
return getMass2(p.momentum)
|
||||
end
|
||||
|
||||
"""
|
||||
inner_edge(p::Particle)
|
||||
ABC_inner_edge(p::ABCParticle)
|
||||
|
||||
Return the factor of the inner edge with the given (virtual) particle.
|
||||
|
||||
Takes 10 effective FLOP. (3 here + 10 in square(p))
|
||||
Takes 10 effective FLOP. (3 here + 7 in square(p))
|
||||
"""
|
||||
function inner_edge(p::Particle)
|
||||
return 1.0 / (square(p) - mass(p.type) * mass(p.type))
|
||||
function ABC_inner_edge(p::ABCParticle)
|
||||
return 1.0 / (square(p) - mass(p)^2)
|
||||
end
|
||||
|
||||
"""
|
||||
outer_edge(p::Particle)
|
||||
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::Particle)
|
||||
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::Particle, p2::Particle)
|
||||
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::Particle, p2::Particle)
|
||||
p3 = Particle(
|
||||
p1.P0 + p2.P0,
|
||||
p1.P1 + p2.P1,
|
||||
p1.P2 + p2.P2,
|
||||
p1.P3 + p2.P3,
|
||||
remaining_type(p1.type, p2.type),
|
||||
)
|
||||
|
||||
function ABC_conserve_momentum(p1::ABCParticle, p2::ABCParticle)
|
||||
t3 = interaction_result(typeof(p1), typeof(p2))
|
||||
p3 = t3(p1.momentum + p2.momentum)
|
||||
return p3
|
||||
end
|
||||
|
||||
function copy(process::ABCProcessDescription)
|
||||
return ABCProcessDescription(copy(process.inParticles), copy(process.outParticles))
|
||||
end
|
||||
|
||||
model(::ABCProcessDescription) = ABCModel()
|
||||
model(::ABCProcessInput) = ABCModel()
|
||||
|
||||
function type_index_from_name(::ABCModel, name::String)
|
||||
if startswith(name, "A")
|
||||
return (ParticleA, parse(Int, name[2:end]))
|
||||
elseif startswith(name, "B")
|
||||
return (ParticleB, parse(Int, name[2:end]))
|
||||
elseif startswith(name, "C")
|
||||
return (ParticleC, parse(Int, name[2:end]))
|
||||
else
|
||||
throw("Invalid name for a particle in the ABC model")
|
||||
end
|
||||
end
|
||||
|
||||
function String(::Type{ParticleA})
|
||||
return "A"
|
||||
end
|
||||
function String(::Type{ParticleB})
|
||||
return "B"
|
||||
end
|
||||
function String(::Type{ParticleC})
|
||||
return "C"
|
||||
end
|
||||
|
||||
function in_particles(process::ABCProcessDescription)
|
||||
return process.inParticles
|
||||
end
|
||||
|
||||
function out_particles(process::ABCProcessDescription)
|
||||
return process.outParticles
|
||||
end
|
||||
|
||||
function get_particle(input::ABCProcessInput, t::Type{Particle}, n::Int)::Particle where {Particle}
|
||||
if (t <: ParticleA)
|
||||
if (n > length(input.inA))
|
||||
return input.outA[n - length(input.inA)]
|
||||
else
|
||||
return input.inA[n]
|
||||
end
|
||||
elseif (t <: ParticleB)
|
||||
if (n > length(input.inB))
|
||||
return input.outB[n - length(input.inB)]
|
||||
else
|
||||
return input.inB[n]
|
||||
end
|
||||
elseif (t <: ParticleC)
|
||||
if (n > length(input.inC))
|
||||
return input.outC[n - length(input.inC)]
|
||||
else
|
||||
return input.inC[n]
|
||||
end
|
||||
end
|
||||
@assert false "Invalid type given"
|
||||
end
|
||||
|
69
src/models/abc/print.jl
Normal file
69
src/models/abc/print.jl
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
"""
|
||||
show(io::IO, process::ABCProcessDescription)
|
||||
|
||||
Pretty print an [`ABCProcessDescription`](@ref) (no newlines).
|
||||
|
||||
```jldoctest
|
||||
julia> using MetagraphOptimization
|
||||
|
||||
julia> print(parse_process("AB->ABBB", ABCModel()))
|
||||
ABC Process: 'AB->ABBB'
|
||||
```
|
||||
"""
|
||||
function show(io::IO, process::ABCProcessDescription)
|
||||
# types() gives the types in order (ABC) instead of random like keys() would
|
||||
print(io, "ABC Process: \'")
|
||||
for type in types(ABCModel())
|
||||
for _ in 1:get(process.inParticles, type, 0)
|
||||
print(io, String(type))
|
||||
end
|
||||
end
|
||||
print(io, "->")
|
||||
for type in types(ABCModel())
|
||||
for _ in 1:get(process.outParticles, type, 0)
|
||||
print(io, String(type))
|
||||
end
|
||||
end
|
||||
print(io, "'")
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, processInput::ABCProcessInput)
|
||||
|
||||
Pretty print an [`ABCProcessInput`](@ref) (with newlines).
|
||||
"""
|
||||
function show(io::IO, processInput::ABCProcessInput)
|
||||
println(io, "Input for $(processInput.process):")
|
||||
println(io, "Incoming particles:")
|
||||
if !isempty(processInput.inA)
|
||||
println(io, " $(processInput.inA)")
|
||||
end
|
||||
if !isempty(processInput.inB)
|
||||
println(io, " $(processInput.inB)")
|
||||
end
|
||||
if !isempty(processInput.inC)
|
||||
println(io, " $(processInput.inC)")
|
||||
end
|
||||
println(io, "Outgoing particles:")
|
||||
if !isempty(processInput.outA)
|
||||
println(io, " $(processInput.outA)")
|
||||
end
|
||||
if !isempty(processInput.outB)
|
||||
println(io, " $(processInput.outB)")
|
||||
end
|
||||
if !isempty(processInput.outC)
|
||||
println(io, " $(processInput.outC)")
|
||||
end
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, particle::T) where {T <: ABCParticle}
|
||||
|
||||
Pretty print an [`ABCParticle`](@ref) (no newlines).
|
||||
"""
|
||||
function show(io::IO, particle::T) where {T <: ABCParticle}
|
||||
print(io, "$(String(typeof(particle))): $(particle.momentum)")
|
||||
return nothing
|
||||
end
|
@ -1,165 +1,91 @@
|
||||
"""
|
||||
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)
|
||||
children(::ComputeTaskABC_S1)
|
||||
|
||||
Print the data task to io.
|
||||
Return the number of children of a ComputeTaskABC_S1 (always 1).
|
||||
"""
|
||||
function show(io::IO, t::DataTask)
|
||||
return print(io, "Data", t.data)
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskS1)
|
||||
|
||||
Print the S1 task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskS1) = print("ComputeS1")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskS2)
|
||||
|
||||
Print the S2 task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskS2) = print("ComputeS2")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskP)
|
||||
|
||||
Print the P task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskP) = print("ComputeP")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskU)
|
||||
|
||||
Print the U task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskU) = print("ComputeU")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskV)
|
||||
|
||||
Print the V task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskV) = print("ComputeV")
|
||||
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskSum)
|
||||
|
||||
Print the sum task to io.
|
||||
"""
|
||||
show(io::IO, t::ComputeTaskSum) = print("ComputeSum")
|
||||
|
||||
"""
|
||||
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(::ComputeTaskS1)
|
||||
|
||||
Return the number of children of a ComputeTaskS1 (always 1).
|
||||
"""
|
||||
children(::ComputeTaskS1) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskS2)
|
||||
|
||||
Return the number of children of a ComputeTaskS2 (always 2).
|
||||
"""
|
||||
children(::ComputeTaskS2) = 2
|
||||
|
||||
"""
|
||||
children(::ComputeTaskP)
|
||||
|
||||
Return the number of children of a ComputeTaskP (always 1).
|
||||
"""
|
||||
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(::ComputeTaskSum)
|
||||
|
||||
Return the number of children of a ComputeTaskSum, since this is variable and the task doesn't know
|
||||
how many children it will sum over, return a wildcard -1.
|
||||
|
||||
TODO: this is kind of bad because it means we can't fuse with a sum task
|
||||
"""
|
||||
children(::ComputeTaskSum) = -1
|
||||
|
||||
"""
|
||||
children(t::FusedComputeTask)
|
||||
|
||||
Return the number of children of a FusedComputeTask. It's the sum of the children of both tasks minus one.
|
||||
"""
|
||||
function children(t::FusedComputeTask)
|
||||
(T1, T2) = get_types(t)
|
||||
return children(T1()) + children(T2()) - 1 # one of the inputs is the output of T1 and thus not a child of the node
|
||||
children(::ComputeTaskABC_S1) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskABC_S2)
|
||||
|
||||
Return the number of children of a ComputeTaskABC_S2 (always 2).
|
||||
"""
|
||||
children(::ComputeTaskABC_S2) = 2
|
||||
|
||||
"""
|
||||
children(::ComputeTaskABC_P)
|
||||
|
||||
Return the number of children of a ComputeTaskABC_P (always 1).
|
||||
"""
|
||||
children(::ComputeTaskABC_P) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskABC_U)
|
||||
|
||||
Return the number of children of a ComputeTaskABC_U (always 1).
|
||||
"""
|
||||
children(::ComputeTaskABC_U) = 1
|
||||
|
||||
"""
|
||||
children(::ComputeTaskABC_V)
|
||||
|
||||
Return the number of children of a ComputeTaskABC_V (always 2).
|
||||
"""
|
||||
children(::ComputeTaskABC_V) = 2
|
||||
|
||||
"""
|
||||
children(::ComputeTaskABC_Sum)
|
||||
|
||||
Return the number of children of a ComputeTaskABC_Sum.
|
||||
"""
|
||||
children(t::ComputeTaskABC_Sum) = t.children_number
|
||||
|
||||
function add_child!(t::ComputeTaskABC_Sum)
|
||||
t.children_number += 1
|
||||
return nothing
|
||||
end
|
||||
|
@ -1,65 +1,51 @@
|
||||
"""
|
||||
DataTask <: AbstractDataTask
|
||||
|
||||
Task representing a specific data transfer in the ABC Model.
|
||||
"""
|
||||
struct DataTask <: AbstractDataTask
|
||||
data::UInt64
|
||||
end
|
||||
|
||||
"""
|
||||
ComputeTaskS1 <: AbstractComputeTask
|
||||
ComputeTaskABC_S1 <: AbstractTaskFunction
|
||||
|
||||
S task with a single child.
|
||||
"""
|
||||
struct ComputeTaskS1 <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_S1 <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskS2 <: AbstractComputeTask
|
||||
ComputeTaskABC_S2 <: AbstractTaskFunction
|
||||
|
||||
S task with two children.
|
||||
"""
|
||||
struct ComputeTaskS2 <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_S2 <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskP <: AbstractComputeTask
|
||||
ComputeTaskABC_P <: AbstractTaskFunction
|
||||
|
||||
P task with no children.
|
||||
"""
|
||||
struct ComputeTaskP <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_P <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskV <: AbstractComputeTask
|
||||
ComputeTaskABC_V <: AbstractTaskFunction
|
||||
|
||||
v task with two children.
|
||||
"""
|
||||
struct ComputeTaskV <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_V <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskU <: AbstractComputeTask
|
||||
ComputeTaskABC_U <: AbstractTaskFunction
|
||||
|
||||
u task with a single child.
|
||||
"""
|
||||
struct ComputeTaskU <: AbstractComputeTask end
|
||||
struct ComputeTaskABC_U <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskSum <: AbstractComputeTask
|
||||
ComputeTaskABC_Sum <: AbstractTaskFunction
|
||||
|
||||
Task that sums all its inputs, n children.
|
||||
"""
|
||||
struct ComputeTaskSum <: AbstractComputeTask end
|
||||
mutable struct ComputeTaskABC_Sum <: AbstractTaskFunction
|
||||
children_number::Int
|
||||
end
|
||||
|
||||
"""
|
||||
ABC_TASKS
|
||||
|
||||
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]
|
||||
|
120
src/models/interface.jl
Normal file
120
src/models/interface.jl
Normal file
@ -0,0 +1,120 @@
|
||||
import QEDbase.mass
|
||||
import QEDbase.AbstractParticle
|
||||
|
||||
"""
|
||||
AbstractPhysicsModel
|
||||
|
||||
Base type for a model, e.g. ABC-Model or QED. This is used to dispatch many functions.
|
||||
"""
|
||||
abstract type AbstractPhysicsModel end
|
||||
|
||||
"""
|
||||
ParticleValue{ParticleType <: AbstractParticle}
|
||||
|
||||
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, ValueType}
|
||||
p::ParticleType
|
||||
v::ValueType
|
||||
end
|
||||
|
||||
"""
|
||||
AbstractProcessDescription
|
||||
|
||||
Base type for process descriptions. An object of this type of a corresponding [`AbstractPhysicsModel`](@ref) should uniquely identify a process in that model.
|
||||
|
||||
See also: [`parse_process`](@ref)
|
||||
"""
|
||||
abstract type AbstractProcessDescription end
|
||||
|
||||
"""
|
||||
AbstractProcessInput
|
||||
|
||||
Base type for process inputs. An object of this type contains the input values (e.g. momenta) of the particles in a process.
|
||||
|
||||
See also: [`gen_process_input`](@ref)
|
||||
"""
|
||||
abstract type AbstractProcessInput end
|
||||
|
||||
"""
|
||||
interaction_result(t1::Type{T1}, t2::Type{T2}) where {T1 <: AbstractParticle, T2 <: AbstractParticle}
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractParticle`](@ref), returning the result particle type when the two given particles interact.
|
||||
"""
|
||||
function interaction_result end
|
||||
|
||||
"""
|
||||
types(::AbstractPhysicsModel)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractPhysicsModel`](@ref), returning a `Vector` of the available particle types in the model.
|
||||
"""
|
||||
function types end
|
||||
|
||||
"""
|
||||
in_particles(::AbstractProcessDescription)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractProcessDescription`](@ref).
|
||||
Returns a `<: Dict{Type{AbstractParticle}, Int}` object, representing the number of incoming particles for the process per particle type.
|
||||
|
||||
|
||||
in_particles(::AbstractProcessInput)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractProcessInput`](@ref).
|
||||
Returns a `<: Vector{AbstractParticle}` object with the values of all incoming particles for the corresponding `ProcessDescription`.
|
||||
"""
|
||||
function in_particles end
|
||||
|
||||
"""
|
||||
out_particles(::AbstractProcessDescription)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractProcessDescription`](@ref).
|
||||
Returns a `<: Dict{Type{AbstractParticle}, Int}` object, representing the number of outgoing particles for the process per particle type.
|
||||
|
||||
|
||||
out_particles(::AbstractProcessInput)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractProcessInput`](@ref).
|
||||
Returns a `<: Vector{AbstractParticle}` object with the values of all outgoing particles for the corresponding `ProcessDescription`.
|
||||
"""
|
||||
function out_particles end
|
||||
|
||||
"""
|
||||
get_particle(::AbstractProcessInput, t::Type, n::Int)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractProcessInput`](@ref).
|
||||
Returns the `n`th particle of type `t`.
|
||||
"""
|
||||
function get_particle end
|
||||
|
||||
"""
|
||||
parse_process(::AbstractString, ::AbstractPhysicsModel)
|
||||
|
||||
Interface function that must be implemented for every subtype of [`AbstractPhysicsModel`](@ref).
|
||||
Returns a `ProcessDescription` object.
|
||||
"""
|
||||
function parse_process end
|
||||
|
||||
"""
|
||||
gen_process_input(::AbstractProcessDescription)
|
||||
|
||||
Interface function that must be implemented for every specific [`AbstractProcessDescription`](@ref).
|
||||
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
|
10
src/models/print.jl
Normal file
10
src/models/print.jl
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
"""
|
||||
show(io::IO, particleValue::ParticleValue)
|
||||
|
||||
Pretty print a [`ParticleValue`](@ref), no newlines.
|
||||
"""
|
||||
function show(io::IO, particleValue::ParticleValue)
|
||||
print(io, "($(particleValue.p), value: $(particleValue.v))")
|
||||
return nothing
|
||||
end
|
124
src/models/qed/compute.jl
Normal file
124
src/models/qed/compute.jl
Normal file
@ -0,0 +1,124 @@
|
||||
using StaticArrays
|
||||
|
||||
"""
|
||||
compute(::ComputeTaskQED_P, data::QEDParticleValue)
|
||||
|
||||
Return the particle as is and initialize the Value.
|
||||
"""
|
||||
function compute(::ComputeTaskQED_P, data::QEDParticleValue{P}) where {P <: QEDParticle}
|
||||
# TODO do we actually need this for anything?
|
||||
return ParticleValue{P, DiracMatrix}(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}}
|
||||
part::P = data.p
|
||||
state = base_state(particle(part), direction(part), momentum(part), spin_or_pol(part))
|
||||
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(momentum(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},
|
||||
) 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)(momentum(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
|
||||
|
||||
function compute(
|
||||
::ComputeTaskQED_S2,
|
||||
data1::ParticleValue{P1},
|
||||
data2::ParticleValue{P2},
|
||||
) 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}) where {P <: QEDParticle}
|
||||
newP = propagation_result(P)
|
||||
new_p = newP(momentum(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...)
|
||||
compute(::ComputeTaskQED_Sum, data::AbstractArray)
|
||||
|
||||
Compute a sum over the vector. Use an algorithm that accounts for accumulated errors in long sums with potentially large differences in magnitude of the summands.
|
||||
|
||||
Linearly many FLOP with growing data.
|
||||
"""
|
||||
function compute(::ComputeTaskQED_Sum, data...)::ComplexF64
|
||||
# TODO: want to use sum_kbn here but it doesn't seem to support ComplexF64, do it element-wise?
|
||||
return sum(data)
|
||||
end
|
||||
|
||||
function compute(::ComputeTaskQED_Sum, data::AbstractArray)::ComplexF64
|
||||
# TODO: want to use sum_kbn here but it doesn't seem to support ComplexF64, do it element-wise?
|
||||
return sum(data)
|
||||
end
|
189
src/models/qed/create.jl
Normal file
189
src/models/qed/create.jl
Normal file
@ -0,0 +1,189 @@
|
||||
|
||||
ComputeTaskQED_Sum() = ComputeTaskQED_Sum(0)
|
||||
|
||||
function _svector_from_type(processDescription::QEDProcessDescription, type, particles)
|
||||
if haskey(in_particles(processDescription), type)
|
||||
return SVector{in_particles(processDescription)[type], type}(filter(x -> typeof(x) <: type, particles))
|
||||
end
|
||||
if haskey(out_particles(processDescription), type)
|
||||
return SVector{out_particles(processDescription)[type], type}(filter(x -> typeof(x) <: type, particles))
|
||||
end
|
||||
return SVector{0, type}()
|
||||
end
|
||||
|
||||
"""
|
||||
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))
|
||||
|
||||
|
||||
particles = Vector{QEDParticle}()
|
||||
initialMomenta = generate_initial_moms(massSum, inputMasses)
|
||||
index = 1
|
||||
for (particle, n) in processDescription.inParticles
|
||||
for _ in 1:n
|
||||
mom = initialMomenta[index]
|
||||
push!(particles, particle(mom))
|
||||
index += 1
|
||||
end
|
||||
end
|
||||
|
||||
final_momenta = generate_physical_massive_moms(rng[threadid()], massSum, outputMasses)
|
||||
index = 1
|
||||
for (particle, n) in processDescription.outParticles
|
||||
for _ in 1:n
|
||||
push!(particles, particle(final_momenta[index]))
|
||||
index += 1
|
||||
end
|
||||
end
|
||||
|
||||
inFerms = _svector_from_type(processDescription, FermionStateful{Incoming, SpinUp}, particles)
|
||||
outFerms = _svector_from_type(processDescription, FermionStateful{Outgoing, SpinUp}, particles)
|
||||
inAntiferms = _svector_from_type(processDescription, AntiFermionStateful{Incoming, SpinUp}, particles)
|
||||
outAntiferms = _svector_from_type(processDescription, AntiFermionStateful{Outgoing, SpinUp}, particles)
|
||||
inPhotons = _svector_from_type(processDescription, PhotonStateful{Incoming, PolX}, particles)
|
||||
outPhotons = _svector_from_type(processDescription, PhotonStateful{Outgoing, PolX}, particles)
|
||||
|
||||
processInput =
|
||||
QEDProcessInput(processDescription, inFerms, outFerms, inAntiferms, outAntiferms, inPhotons, outPhotons)
|
||||
|
||||
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, SpinUp}, -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
|
408
src/models/qed/particle.jl
Normal file
408
src/models/qed/particle.jl
Normal file
@ -0,0 +1,408 @@
|
||||
using QEDprocesses
|
||||
using StaticArrays
|
||||
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
|
||||
|
||||
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, Pol <: AbstractDefinitePolarization} <: QEDParticle{Direction}
|
||||
momentum::SFourMomentum
|
||||
end
|
||||
|
||||
PhotonStateful{Direction}(mom::SFourMomentum) where {Direction <: ParticleDirection} =
|
||||
PhotonStateful{Direction, PolX}(mom)
|
||||
|
||||
PhotonStateful{Dir, Pol}(ph::PhotonStateful) where {Dir, Pol} = PhotonStateful{Dir, Pol}(ph.momentum)
|
||||
|
||||
"""
|
||||
FermionStateful <: QEDParticle
|
||||
|
||||
A fermion of the [`QEDModel`](@ref) with its state.
|
||||
"""
|
||||
struct FermionStateful{Direction <: ParticleDirection, Spin <: AbstractDefiniteSpin} <: QEDParticle{Direction}
|
||||
momentum::SFourMomentum
|
||||
# TODO: mass for electron/muon/tauon representation?
|
||||
end
|
||||
|
||||
FermionStateful{Direction}(mom::SFourMomentum) where {Direction <: ParticleDirection} =
|
||||
FermionStateful{Direction, SpinUp}(mom)
|
||||
|
||||
FermionStateful{Dir, Spin}(f::FermionStateful) where {Dir, Spin} = FermionStateful{Dir, Spin}(f.momentum)
|
||||
|
||||
"""
|
||||
AntiFermionStateful <: QEDParticle
|
||||
|
||||
An anti-fermion of the [`QEDModel`](@ref) with its state.
|
||||
"""
|
||||
struct AntiFermionStateful{Direction <: ParticleDirection, Spin <: AbstractDefiniteSpin} <: QEDParticle{Direction}
|
||||
momentum::SFourMomentum
|
||||
# TODO: mass for electron/muon/tauon representation?
|
||||
end
|
||||
|
||||
AntiFermionStateful{Direction}(mom::SFourMomentum) where {Direction <: ParticleDirection} =
|
||||
AntiFermionStateful{Direction, SpinUp}(mom)
|
||||
|
||||
AntiFermionStateful{Dir, Spin}(f::AntiFermionStateful) where {Dir, Spin} = AntiFermionStateful{Dir, Spin}(f.momentum)
|
||||
|
||||
"""
|
||||
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, Spin1}},
|
||||
::Type{FermionStateful{Outgoing, Spin2}},
|
||||
) where {Spin1, Spin2} = PhotonStateful{Incoming, PolX}
|
||||
interaction_result(
|
||||
::Type{FermionStateful{Incoming, Spin1}},
|
||||
::Type{AntiFermionStateful{Incoming, Spin2}},
|
||||
) where {Spin1, Spin2} = PhotonStateful{Incoming, PolX}
|
||||
interaction_result(::Type{FermionStateful{Incoming, Spin1}}, ::Type{<:PhotonStateful}) where {Spin1} =
|
||||
FermionStateful{Outgoing, SpinUp}
|
||||
|
||||
interaction_result(
|
||||
::Type{FermionStateful{Outgoing, Spin1}},
|
||||
::Type{FermionStateful{Incoming, Spin2}},
|
||||
) where {Spin1, Spin2} = PhotonStateful{Incoming, PolX}
|
||||
interaction_result(
|
||||
::Type{FermionStateful{Outgoing, Spin1}},
|
||||
::Type{AntiFermionStateful{Outgoing, Spin2}},
|
||||
) where {Spin1, Spin2} = PhotonStateful{Incoming, PolX}
|
||||
interaction_result(::Type{FermionStateful{Outgoing, Spin1}}, ::Type{<:PhotonStateful}) where {Spin1} =
|
||||
FermionStateful{Incoming, SpinUp}
|
||||
|
||||
# antifermion mirror
|
||||
interaction_result(::Type{AntiFermionStateful{Incoming, Spin}}, t2::Type{<:QEDParticle}) where {Spin} =
|
||||
interaction_result(FermionStateful{Outgoing, Spin}, t2)
|
||||
interaction_result(::Type{AntiFermionStateful{Outgoing, Spin}}, t2::Type{<:QEDParticle}) where {Spin} =
|
||||
interaction_result(FermionStateful{Incoming, Spin}, 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, Spin}}) where {Spin <: AbstractDefiniteSpin} =
|
||||
FermionStateful{Outgoing, Spin}
|
||||
propagation_result(::Type{FermionStateful{Outgoing, Spin}}) where {Spin <: AbstractDefiniteSpin} =
|
||||
FermionStateful{Incoming, Spin}
|
||||
propagation_result(::Type{AntiFermionStateful{Incoming, Spin}}) where {Spin <: AbstractDefiniteSpin} =
|
||||
AntiFermionStateful{Outgoing, Spin}
|
||||
propagation_result(::Type{AntiFermionStateful{Outgoing, Spin}}) where {Spin <: AbstractDefiniteSpin} =
|
||||
AntiFermionStateful{Incoming, Spin}
|
||||
propagation_result(::Type{PhotonStateful{Incoming, Pol}}) where {Pol <: AbstractDefinitePolarization} =
|
||||
PhotonStateful{Outgoing, Pol}
|
||||
propagation_result(::Type{PhotonStateful{Outgoing, Pol}}) where {Pol <: AbstractDefinitePolarization} =
|
||||
PhotonStateful{Incoming, Pol}
|
||||
|
||||
"""
|
||||
types(::QEDModel)
|
||||
|
||||
Return a Vector of the possible types of particle in the [`QEDModel`](@ref).
|
||||
"""
|
||||
function types(::QEDModel)
|
||||
return [
|
||||
PhotonStateful{Incoming, PolX},
|
||||
PhotonStateful{Outgoing, PolX},
|
||||
FermionStateful{Incoming, SpinUp},
|
||||
FermionStateful{Outgoing, SpinUp},
|
||||
AntiFermionStateful{Incoming, SpinUp},
|
||||
AntiFermionStateful{Outgoing, SpinUp},
|
||||
]
|
||||
end
|
||||
|
||||
# type piracy?
|
||||
String(::Type{Incoming}) = "Incoming"
|
||||
String(::Type{Outgoing}) = "Outgoing"
|
||||
|
||||
String(::Type{PolX}) = "polx"
|
||||
String(::Type{PolY}) = "poly"
|
||||
|
||||
String(::Type{SpinUp}) = "spinup"
|
||||
String(::Type{SpinDown}) = "spindown"
|
||||
|
||||
String(::Incoming) = "i"
|
||||
String(::Outgoing) = "o"
|
||||
|
||||
function String(::Type{<:PhotonStateful})
|
||||
return "k"
|
||||
end
|
||||
function String(::Type{<:FermionStateful})
|
||||
return "e"
|
||||
end
|
||||
function String(::Type{<:AntiFermionStateful})
|
||||
return "p"
|
||||
end
|
||||
|
||||
function unique_name(::Type{PhotonStateful{Dir, Pol}}) where {Dir, Pol}
|
||||
return String(PhotonStateful) * String(Dir) * String(Pol)
|
||||
end
|
||||
function unique_name(::Type{FermionStateful{Dir, Spin}}) where {Dir, Spin}
|
||||
return String(FermionStateful) * String(Dir) * String(Spin)
|
||||
end
|
||||
function unique_name(::Type{AntiFermionStateful{Dir, Spin}}) where {Dir, Spin}
|
||||
return String(AntiFermionStateful) * String(Dir) * String(Spin)
|
||||
end
|
||||
|
||||
@inline particle(::PhotonStateful) = Photon()
|
||||
@inline particle(::FermionStateful) = Electron()
|
||||
@inline particle(::AntiFermionStateful) = Positron()
|
||||
|
||||
@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{Dir, Pol}) where {Dir, Pol <: AbstractDefinitePolarization} = Pol()
|
||||
@inline spin_or_pol(p::FermionStateful{Dir, Spin}) where {Dir, Spin <: AbstractDefiniteSpin} = Spin()
|
||||
@inline spin_or_pol(p::AntiFermionStateful{Dir, Spin}) where {Dir, Spin <: AbstractDefiniteSpin} = Spin()
|
||||
|
||||
@inline direction(
|
||||
::Type{P},
|
||||
) where {P <: Union{FermionStateful{Incoming}, AntiFermionStateful{Incoming}, PhotonStateful{Incoming}}} = Incoming()
|
||||
@inline direction(
|
||||
::Type{P},
|
||||
) where {P <: Union{FermionStateful{Outgoing}, AntiFermionStateful{Outgoing}, PhotonStateful{Outgoing}}} = Outgoing()
|
||||
|
||||
@inline direction(
|
||||
::P,
|
||||
) where {P <: Union{FermionStateful{Incoming}, AntiFermionStateful{Incoming}, PhotonStateful{Incoming}}} = Incoming()
|
||||
@inline direction(
|
||||
::P,
|
||||
) where {P <: Union{FermionStateful{Outgoing}, AntiFermionStateful{Outgoing}, PhotonStateful{Outgoing}}} = Outgoing()
|
||||
|
||||
@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, Spin}) where {Dir, Spin} =
|
||||
FermionStateful{Dir, Spin}(-p.momentum, p.spin)
|
||||
@inline invert_momentum(p::AntiFermionStateful{Dir, Spin}) where {Dir, Spin} =
|
||||
AntiFermionStateful{Dir, Spin}(-p.momentum, p.spin)
|
||||
@inline invert_momentum(k::PhotonStateful{Dir, Spin}) where {Dir, Spin} =
|
||||
PhotonStateful{Dir, Spin}(-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, PolX}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "ko")
|
||||
return (PhotonStateful{Outgoing, PolX}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "ei")
|
||||
return (FermionStateful{Incoming, SpinUp}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "eo")
|
||||
return (FermionStateful{Outgoing, SpinUp}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "pi")
|
||||
return (AntiFermionStateful{Incoming, SpinUp}, parse(Int, name[3:end]))
|
||||
elseif startswith(name, "po")
|
||||
return (AntiFermionStateful{Outgoing, SpinUp}, 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)
|
||||
return propagator(particle(p), p.momentum)
|
||||
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::P1,
|
||||
p2::P2,
|
||||
) where {
|
||||
Dir1 <: ParticleDirection,
|
||||
Dir2 <: ParticleDirection,
|
||||
SpinPol1 <: AbstractSpinOrPolarization,
|
||||
SpinPol2 <: AbstractSpinOrPolarization,
|
||||
P1 <: Union{FermionStateful{Dir1, SpinPol1}, AntiFermionStateful{Dir1, SpinPol1}, PhotonStateful{Dir1, SpinPol1}},
|
||||
P2 <: Union{FermionStateful{Dir2, SpinPol2}, AntiFermionStateful{Dir2, SpinPol2}, PhotonStateful{Dir2, SpinPol2}},
|
||||
}
|
||||
P3 = interaction_result(P1, P2)
|
||||
p1_mom = p1.momentum
|
||||
if (Dir1 <: Outgoing)
|
||||
p1_mom *= -1
|
||||
end
|
||||
p2_mom = p2.momentum
|
||||
if (Dir2 <: Outgoing)
|
||||
p2_mom *= -1
|
||||
end
|
||||
|
||||
p3_mom = p1_mom + p2_mom
|
||||
if (typeof(direction(P3)) <: Incoming)
|
||||
return P3(-p3_mom)
|
||||
end
|
||||
return P3(p3_mom)
|
||||
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{N1, N2, N3, N4, N5, N6} <: AbstractProcessInput
|
||||
process::QEDProcessDescription
|
||||
inFerms::SVector{N1, FermionStateful{Incoming, SpinUp}}
|
||||
outFerms::SVector{N2, FermionStateful{Outgoing, SpinUp}}
|
||||
inAntiferms::SVector{N3, AntiFermionStateful{Incoming, SpinUp}}
|
||||
outAntiferms::SVector{N4, AntiFermionStateful{Outgoing, SpinUp}}
|
||||
inPhotons::SVector{N5, PhotonStateful{Incoming, PolX}}
|
||||
outPhotons::SVector{N6, PhotonStateful{Outgoing, PolX}}
|
||||
end
|
||||
|
||||
"""
|
||||
model(::AbstractProcessDescription)
|
||||
|
||||
Return the model of this process description.
|
||||
"""
|
||||
model(::QEDProcessDescription) = QEDModel()
|
||||
model(::QEDProcessInput) = QEDModel()
|
||||
|
||||
function copy(process::QEDProcessDescription)
|
||||
return QEDProcessDescription(copy(process.inParticles), copy(process.outParticles))
|
||||
end
|
||||
|
||||
==(p1::QEDProcessDescription, p2::QEDProcessDescription) =
|
||||
p1.inParticles == p2.inParticles && p1.outParticles == p2.outParticles
|
||||
|
||||
function in_particles(process::QEDProcessDescription)
|
||||
return process.inParticles
|
||||
end
|
||||
|
||||
function out_particles(process::QEDProcessDescription)
|
||||
return process.outParticles
|
||||
end
|
||||
|
||||
function get_particle(input::QEDProcessInput, t::Type{Particle}, n::Int)::Particle where {Particle}
|
||||
if (t <: FermionStateful{Incoming})
|
||||
return input.inFerms[n]
|
||||
elseif (t <: FermionStateful{Outgoing})
|
||||
return input.outFerms[n]
|
||||
elseif (t <: AntiFermionStateful{Incoming})
|
||||
return input.inAntiferms[n]
|
||||
elseif (t <: AntiFermionStateful{Outgoing})
|
||||
return input.outAntiferms[n]
|
||||
elseif (t <: PhotonStateful{Incoming})
|
||||
return input.inPhotons[n]
|
||||
elseif (t <: PhotonStateful{Outgoing})
|
||||
return input.outPhotons[n]
|
||||
end
|
||||
@assert false "Invalid type given"
|
||||
end
|
158
src/models/qed/print.jl
Normal file
158
src/models/qed/print.jl
Normal file
@ -0,0 +1,158 @@
|
||||
|
||||
"""
|
||||
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
|
||||
|
||||
|
||||
"""
|
||||
String(process::QEDProcessDescription)
|
||||
|
||||
Create a short string suitable as a filename or similar, describing the given process.
|
||||
|
||||
```jldoctest
|
||||
julia> using MetagraphOptimization
|
||||
|
||||
julia> String(parse_process("ke->ke", QEDModel()))
|
||||
qed_ke-ke
|
||||
|
||||
julia> print(parse_process("kk->ep", QEDModel()))
|
||||
qed_kk-ep
|
||||
```
|
||||
"""
|
||||
function String(process::QEDProcessDescription)
|
||||
# types() gives the types in order (QED) instead of random like keys() would
|
||||
str = "qed_"
|
||||
for type in types(QEDModel())
|
||||
for _ in 1:get(process.inParticles, type, 0)
|
||||
str = str * String(type)
|
||||
end
|
||||
end
|
||||
str = str * "-"
|
||||
for type in types(QEDModel())
|
||||
for _ in 1:get(process.outParticles, type, 0)
|
||||
str = str * String(type)
|
||||
end
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, processInput::QEDProcessInput)
|
||||
|
||||
Pretty print a [`QEDProcessInput`](@ref) (with newlines).
|
||||
"""
|
||||
function show(io::IO, processInput::QEDProcessInput)
|
||||
println(io, "Input for $(processInput.process):")
|
||||
if !isempty(processInput.inFerms)
|
||||
println(io, " $(processInput.inFerms)")
|
||||
end
|
||||
if !isempty(processInput.outFerms)
|
||||
println(io, " $(processInput.outFerms)")
|
||||
end
|
||||
if !isempty(processInput.inAntiferms)
|
||||
println(io, " $(processInput.inAntiferms)")
|
||||
end
|
||||
if !isempty(processInput.outAntiferms)
|
||||
println(io, " $(processInput.outAntiferms)")
|
||||
end
|
||||
if !isempty(processInput.inPhotons)
|
||||
println(io, " $(processInput.inPhotons)")
|
||||
end
|
||||
if !isempty(processInput.outPhotons)
|
||||
println(io, " $(processInput.outPhotons)")
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
show(io::IO, particle::T) where {T <: QEDParticle}
|
||||
|
||||
Pretty print a [`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
|
93
src/models/qed/properties.jl
Normal file
93
src/models/qed/properties.jl
Normal file
@ -0,0 +1,93 @@
|
||||
# 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
|
||||
|
||||
"""
|
||||
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 <: AbstractTaskFunction
|
||||
|
||||
S task with a single child.
|
||||
"""
|
||||
struct ComputeTaskQED_S1 <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_S2 <: AbstractTaskFunction
|
||||
|
||||
S task with two children.
|
||||
"""
|
||||
struct ComputeTaskQED_S2 <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_P <: AbstractTaskFunction
|
||||
|
||||
P task with no children.
|
||||
"""
|
||||
struct ComputeTaskQED_P <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_V <: AbstractTaskFunction
|
||||
|
||||
v task with two children.
|
||||
"""
|
||||
struct ComputeTaskQED_V <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_U <: AbstractTaskFunction
|
||||
|
||||
u task with a single child.
|
||||
"""
|
||||
struct ComputeTaskQED_U <: AbstractTaskFunction end
|
||||
|
||||
"""
|
||||
ComputeTaskQED_Sum <: AbstractTaskFunction
|
||||
|
||||
Task that sums all its inputs, n children.
|
||||
"""
|
||||
mutable struct ComputeTaskQED_Sum <: AbstractTaskFunction
|
||||
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
|
||||
|
@ -7,38 +7,24 @@ DataTaskNode(t::AbstractDataTask, name = "") = DataTaskNode(
|
||||
missing,
|
||||
missing,
|
||||
missing,
|
||||
missing,
|
||||
name,
|
||||
)
|
||||
ComputeTaskNode(t::AbstractComputeTask) = ComputeTaskNode(
|
||||
t,
|
||||
Vector{Node}(),
|
||||
Vector{Node}(),
|
||||
UUIDs.uuid1(rng[threadid()]),
|
||||
missing,
|
||||
missing,
|
||||
Vector{NodeFusion}(),
|
||||
t, # task
|
||||
Vector{Node}(), # parents
|
||||
Vector{Node}(), # children
|
||||
UUIDs.uuid1(rng[threadid()]), # id
|
||||
missing, # node reduction
|
||||
missing, # node vectorization
|
||||
missing, # node split
|
||||
Vector{NodeFusion}(), # node fusions
|
||||
missing, # device
|
||||
)
|
||||
|
||||
copy(m::Missing) = missing
|
||||
copy(n::ComputeTaskNode) = ComputeTaskNode(
|
||||
copy(n.task),
|
||||
copy(n.parents),
|
||||
copy(n.children),
|
||||
UUIDs.uuid1(rng[threadid()]),
|
||||
copy(n.nodeReduction),
|
||||
copy(n.nodeSplit),
|
||||
copy(n.nodeFusions),
|
||||
)
|
||||
copy(n::DataTaskNode) = DataTaskNode(
|
||||
copy(n.task),
|
||||
copy(n.parents),
|
||||
copy(n.children),
|
||||
UUIDs.uuid1(rng[threadid()]),
|
||||
copy(n.nodeReduction),
|
||||
copy(n.nodeSplit),
|
||||
copy(n.nodeFusion),
|
||||
n.name,
|
||||
)
|
||||
copy(n::ComputeTaskNode) = ComputeTaskNode(copy(task(n)))
|
||||
copy(n::DataTaskNode) = DataTaskNode(copy(task(n)), n.name)
|
||||
|
||||
"""
|
||||
make_node(t::AbstractTask)
|
||||
@ -63,9 +49,14 @@ end
|
||||
|
||||
Construct and return a new [`ComputeTaskNode`](@ref) with the given task.
|
||||
"""
|
||||
function make_node(t::AbstractComputeTask)
|
||||
return ComputeTaskNode(t)
|
||||
end
|
||||
make_node(t::AbstractComputeTask) = ComputeTaskNode(t)
|
||||
|
||||
"""
|
||||
make_node(t::AbstractTaskFunction)
|
||||
|
||||
Construct and return a new [`ComputeTaskNode`](@ref) with a default [`ComputeTask`](@ref) with the given task function.
|
||||
"""
|
||||
make_node(t::AbstractTaskFunction) = ComputeTaskNode(ComputeTask(t))
|
||||
|
||||
"""
|
||||
make_edge(n1::Node, n2::Node)
|
||||
|
@ -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
|
||||
|
||||
"""
|
||||
@ -22,5 +22,6 @@ end
|
||||
Return the uuid as a string usable as a variable name in code generation.
|
||||
"""
|
||||
function to_var_name(id::UUID)
|
||||
return replace(string(id), "-" => "_")
|
||||
str = "_" * replace(string(id), "-" => "_")
|
||||
return str
|
||||
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,160 @@ 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
|
||||
|
||||
function add_child!(n::DataTaskNode{<:AbstractDataTask}, child::Node)
|
||||
push!(n.children, child)
|
||||
return nothing
|
||||
end
|
||||
|
||||
function add_parent!(n::DataTaskNode{<:AbstractDataTask}, parent::Node)
|
||||
push!(n.parents, parent)
|
||||
return nothing
|
||||
end
|
||||
|
||||
function remove_child!(n::DataTaskNode{<:AbstractDataTask}, child::Node)
|
||||
for i in eachindex(n.children)
|
||||
if (n.children[i] == child)
|
||||
splice!(n.children, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function remove_parent!(n::DataTaskNode{<:AbstractDataTask}, parent::Node)
|
||||
for i in eachindex(n.parents)
|
||||
if (n.parents[i] == parent)
|
||||
splice!(n.parents, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
"""
|
||||
add_child(n::ComputeTaskNode{<:ComputeTask}, child::Node)
|
||||
|
||||
Add a child to the compute node.
|
||||
"""
|
||||
function add_child!(n::ComputeTaskNode{<:ComputeTask}, child::Node)
|
||||
push!(n.children, child)
|
||||
push!(n.task.arguments, Argument(child.id))
|
||||
return nothing
|
||||
end
|
||||
|
||||
function add_parent!(n::ComputeTaskNode{<:ComputeTask}, parent::Node)
|
||||
push!(n.parents, parent)
|
||||
return nothing
|
||||
end
|
||||
|
||||
function remove_child!(n::ComputeTaskNode{<:ComputeTask}, child::Node)
|
||||
for i in eachindex(n.children)
|
||||
if (n.children[i] == child)
|
||||
splice!(n.children, i)
|
||||
@assert n.task.func.arguments[i].id == child.id
|
||||
splice!(n.task.func.arguments, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function remove_parent!(n::ComputeTaskNode{<:ComputeTask}, parent::Node)
|
||||
for i in eachindex(n.parents)
|
||||
if (n.parents[i] == parent)
|
||||
splice!(n.parents, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
|
||||
|
||||
function add_child!(n::ComputeTaskNode{<:FusedComputeTask}, child::Node, which::Symbol = :first)
|
||||
push!(n.children, child)
|
||||
|
||||
if which == :first || which == :both
|
||||
push!(n.task.first_func_arguments, child.id)
|
||||
if which == :second || which == :both
|
||||
push!(n.task.second_func_arguments, child.id)
|
||||
end
|
||||
|
||||
if which != :first && which != :second && which != :both
|
||||
@assert false "Tried to add child to symbol $(which) of fused compute task, but only :both, :first, and :second are allowed"
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function add_parent!(n::ComputeTaskNode{<:FusedComputeTask}, parent::Node)
|
||||
push!(n.parents, parent)
|
||||
return nothing
|
||||
end
|
||||
|
||||
function remove_child!(n::ComputeTaskNode{<:FusedComputeTask}, child::Node)
|
||||
for i in eachindex(n.children)
|
||||
if (n.children[i] == child)
|
||||
splice!(n.children, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for field in (:first_func_arguments, :second_func_arguments)
|
||||
for i in eachindex(getfield(n.task, field))
|
||||
if (getfield(n.task, field)[i].id == child.id)
|
||||
splice!(getfield(n.task, field), i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function remove_parent!(n::ComputeTaskNode{<:FusedComputeTask}, parent::Node)
|
||||
for i in eachindex(n.parents)
|
||||
if (n.parents[i] == parent)
|
||||
splice!(n.parents, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
|
||||
|
||||
function add_child!(n::ComputeTaskNode{<:VectorizedComputeTask}, child::Node)
|
||||
push!(n.children, child)
|
||||
push!(n.task.arguments, Argument(child.id))
|
||||
return nothing
|
||||
end
|
||||
|
||||
function add_parent!(n::ComputeTaskNode{<:VectorizedComputeTask}, parent::Node)
|
||||
push!(n.parents, parent)
|
||||
return nothing
|
||||
end
|
||||
|
||||
function remove_child!(n::ComputeTaskNode{<:VectorizedComputeTask}, child::Node)
|
||||
for i in eachindex(n.children)
|
||||
if (n.children[i] == child)
|
||||
splice!(n.children, i)
|
||||
@assert n.task.func.arguments[i].id == child.id
|
||||
splice!(n.task.func.arguments, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function remove_parent!(n::ComputeTaskNode{<:VectorizedComputeTask}, parent::Node)
|
||||
for i in eachindex(n.parents)
|
||||
if (n.parents[i] == parent)
|
||||
splice!(n.parents, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
@ -3,7 +3,7 @@ using UUIDs
|
||||
using Base.Threads
|
||||
|
||||
# TODO: reliably find out how many threads we're running with (nthreads() returns 1 when precompiling :/)
|
||||
rng = [Random.MersenneTwister(0) for _ in 1:32]
|
||||
rng = [Random.MersenneTwister(0) for _ in 1:64]
|
||||
|
||||
"""
|
||||
Node
|
||||
@ -24,16 +24,18 @@ abstract type Operation end
|
||||
Any node that transfers data and does no computation.
|
||||
|
||||
# Fields
|
||||
`.task`: The node's data task type. Usually [`DataTask`](@ref).\\
|
||||
`.parents`: A vector of the node's parents (i.e. nodes that depend on this one).\\
|
||||
`.children`: A vector of the node's children (i.e. nodes that this one depends on).\\
|
||||
`.id`: The node's id. Improves the speed of comparisons.\\
|
||||
`.nodeReduction`: Either this node's [`NodeReduction`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeSplit`: Either this node's [`NodeSplit`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeFusion`: Either this node's [`NodeFusion`](@ref) or `missing`, if none. There can only be at most one for DataTaskNodes.
|
||||
`.task`: The node's data task type. Usually [`DataTask`](@ref).\\
|
||||
`.parents`: A vector of the node's parents (i.e. nodes that depend on this one).\\
|
||||
`.children`: A vector of the node's children (i.e. nodes that this one depends on).\\
|
||||
`.id`: The node's id. Improves the speed of comparisons and is used as a unique identifier.\\
|
||||
`.nodeVectorization`: Always `missing`, since a data node can't be vectorized.\\
|
||||
`.nodeReduction`: Either this node's [`NodeReduction`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeSplit`: Either this node's [`NodeSplit`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.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}
|
||||
@ -47,6 +49,9 @@ mutable struct DataTaskNode <: Node
|
||||
# Can't use the NodeReduction type here because it's not yet defined
|
||||
nodeReduction::Union{Operation, Missing}
|
||||
|
||||
# data nodes can't be vectorized
|
||||
nodeVectorization::Missing
|
||||
|
||||
# the NodeSplit involving this node, if it exists
|
||||
nodeSplit::Union{Operation, Missing}
|
||||
|
||||
@ -60,28 +65,35 @@ end
|
||||
"""
|
||||
ComputeTaskNode <: Node
|
||||
|
||||
Any node that transfers data and does no computation.
|
||||
Any node that computes a result from inputs using an [`AbstractComputeTask`](@ref).
|
||||
|
||||
# Fields
|
||||
`.task`: The node's data task type. Usually [`DataTask`](@ref).\\
|
||||
`.parents`: A vector of the node's parents (i.e. nodes that depend on this one).\\
|
||||
`.children`: A vector of the node's children (i.e. nodes that this one depends on).\\
|
||||
`.id`: The node's id. Improves the speed of comparisons.\\
|
||||
`.nodeReduction`: Either this node's [`NodeReduction`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeSplit`: Either this node's [`NodeSplit`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeFusion`: A vector of this node's [`NodeFusion`](@ref)s. For a ComputeTaskNode there can be any number of these, unlike the DataTaskNodes.
|
||||
`.task`: The node's compute task type. A concrete subtype of [`AbstractComputeTask`](@ref).\\
|
||||
`.parents`: A vector of the node's parents (i.e. nodes that depend on this one).\\
|
||||
`.children`: A vector of the node's children (i.e. nodes that this one depends on).\\
|
||||
`.id`: The node's id. Improves the speed of comparisons and is used as a unique identifier.\\
|
||||
`.nodeReduction`: Either this node's [`NodeReduction`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeVectorization`: Either this node's [`NodeVectorization`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.nodeSplit`: Either this node's [`NodeSplit`](@ref) or `missing`, if none. There can only be at most one.\\
|
||||
`.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
|
||||
|
||||
nodeReduction::Union{Operation, Missing}
|
||||
nodeVectorization::Union{Operation, Missing}
|
||||
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}
|
||||
end
|
||||
|
||||
"""
|
||||
@ -95,8 +107,5 @@ The child is the prerequisite node of the parent.
|
||||
"""
|
||||
struct Edge
|
||||
# edge points from child to parent
|
||||
edge::Union{
|
||||
Tuple{DataTaskNode, ComputeTaskNode},
|
||||
Tuple{ComputeTaskNode, DataTaskNode},
|
||||
}
|
||||
edge::Union{Tuple{DataTaskNode, ComputeTaskNode}, Tuple{ComputeTaskNode, DataTaskNode}}
|
||||
end
|
||||
|
@ -22,12 +22,24 @@ function is_valid_node(graph::DAG, node::Node)
|
||||
@assert node in child.parents "Node is not a parent of its child!"
|
||||
end
|
||||
|
||||
if !ismissing(node.nodeReduction)
|
||||
#=if !ismissing(node.nodeReduction)
|
||||
@assert is_valid(graph, node.nodeReduction)
|
||||
end
|
||||
if !ismissing(node.nodeSplit)
|
||||
@assert is_valid(graph, node.nodeSplit)
|
||||
end=#
|
||||
|
||||
if !(typeof(task(node)) <: FusedComputeTask)
|
||||
# the remaining checks are only necessary for fused compute tasks
|
||||
return true
|
||||
end
|
||||
|
||||
# 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 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
|
||||
end
|
||||
|
||||
@ -41,9 +53,9 @@ This also calls [`is_valid_node(graph::DAG, node::Node)`](@ref).
|
||||
function is_valid(graph::DAG, node::ComputeTaskNode)
|
||||
@assert is_valid_node(graph, node)
|
||||
|
||||
for nf in node.nodeFusions
|
||||
#=for nf in node.nodeFusions
|
||||
@assert is_valid(graph, nf)
|
||||
end
|
||||
end=#
|
||||
return true
|
||||
end
|
||||
|
||||
@ -57,8 +69,8 @@ This also calls [`is_valid_node(graph::DAG, node::Node)`](@ref).
|
||||
function is_valid(graph::DAG, node::DataTaskNode)
|
||||
@assert is_valid_node(graph, node)
|
||||
|
||||
if !ismissing(node.nodeFusion)
|
||||
#=if !ismissing(node.nodeFusion)
|
||||
@assert is_valid(graph, node.nodeFusion)
|
||||
end
|
||||
end=#
|
||||
return true
|
||||
end
|
||||
|
@ -34,12 +34,7 @@ Apply the given [`NodeFusion`](@ref) to the graph. Generic wrapper around [`node
|
||||
Return an [`AppliedNodeFusion`](@ref) object generated from the graph's [`Diff`](@ref).
|
||||
"""
|
||||
function apply_operation!(graph::DAG, operation::NodeFusion)
|
||||
diff = node_fusion!(
|
||||
graph,
|
||||
operation.input[1],
|
||||
operation.input[2],
|
||||
operation.input[3],
|
||||
)
|
||||
diff = node_fusion!(graph, operation.input[1], operation.input[2], operation.input[3])
|
||||
|
||||
graph.properties += GraphProperties(diff)
|
||||
|
||||
@ -124,17 +119,24 @@ function revert_diff!(graph::DAG, diff::Diff)
|
||||
# add removed nodes, remove added nodes, same for edges
|
||||
# note the order
|
||||
for edge in diff.addedEdges
|
||||
remove_edge!(graph, edge.edge[1], edge.edge[2], false)
|
||||
remove_edge!(graph, edge.edge[1], edge.edge[2], track = false)
|
||||
end
|
||||
for node in diff.addedNodes
|
||||
remove_node!(graph, node, false)
|
||||
remove_node!(graph, node, track = false)
|
||||
end
|
||||
|
||||
for node in diff.removedNodes
|
||||
insert_node!(graph, node, false)
|
||||
insert_node!(graph, node, track = false)
|
||||
end
|
||||
for edge in diff.removedEdges
|
||||
insert_edge!(graph, edge.edge[1], edge.edge[2], false)
|
||||
insert_edge!(graph, edge.edge[1], edge.edge[2], track = false)
|
||||
end
|
||||
|
||||
for (node, t) in diff.updatedChildren
|
||||
# node must be fused compute task at this point
|
||||
@assert typeof(task(node)) <: FusedComputeTask
|
||||
|
||||
node.task = t
|
||||
end
|
||||
|
||||
graph.properties -= GraphProperties(diff)
|
||||
@ -149,21 +151,24 @@ Fuse nodes n1 -> n2 -> n3 together into one node, return the applied difference
|
||||
|
||||
For details see [`NodeFusion`](@ref).
|
||||
"""
|
||||
function node_fusion!(
|
||||
graph::DAG,
|
||||
n1::ComputeTaskNode,
|
||||
n2::DataTaskNode,
|
||||
n3::ComputeTaskNode,
|
||||
)
|
||||
# @assert is_valid_node_fusion_input(graph, n1, n2, n3)
|
||||
function node_fusion!(graph::DAG, n1::ComputeTaskNode, n2::DataTaskNode, n3::ComputeTaskNode)
|
||||
@assert is_valid_node_fusion_input(graph, n1, n2, n3)
|
||||
|
||||
# clear snapshot
|
||||
get_snapshot_diff(graph)
|
||||
|
||||
# save children and parents
|
||||
n1_children = children(n1)
|
||||
n3_parents = parents(n3)
|
||||
n3_children = children(n3)
|
||||
n1Children = copy(children(n1))
|
||||
n3Parents = copy(parents(n3))
|
||||
|
||||
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}()
|
||||
for child in n1Children
|
||||
push!(n1Inputs, Symbol(to_var_name(child.id)))
|
||||
end
|
||||
|
||||
# remove the edges and nodes that will be replaced by the fused node
|
||||
remove_edge!(graph, n1, n2)
|
||||
@ -172,29 +177,38 @@ function node_fusion!(
|
||||
remove_node!(graph, n2)
|
||||
|
||||
# get n3's children now so it automatically excludes n2
|
||||
n3_children = children(n3)
|
||||
n3Children = copy(children(n3))
|
||||
|
||||
n3Inputs = Vector{Symbol}()
|
||||
for child in n3Children
|
||||
push!(n3Inputs, Symbol(to_var_name(child.id)))
|
||||
end
|
||||
|
||||
remove_node!(graph, n3)
|
||||
|
||||
# create new node with the fused compute task
|
||||
new_node =
|
||||
ComputeTaskNode(FusedComputeTask{typeof(n1.task), typeof(n3.task)}())
|
||||
insert_node!(graph, new_node)
|
||||
newNode = ComputeTaskNode(FusedComputeTask(n1Task.func, n3Task.func, Symbol(to_var_name(n2.id))))
|
||||
insert_node!(graph, newNode)
|
||||
|
||||
for child in n1_children
|
||||
for child in n1Children
|
||||
remove_edge!(graph, child, n1)
|
||||
insert_edge!(graph, child, new_node)
|
||||
insert_edge!(graph, child, newNode)
|
||||
end
|
||||
|
||||
for child in n3_children
|
||||
for child in n3Children
|
||||
remove_edge!(graph, child, n3)
|
||||
if !(child in n1_children)
|
||||
insert_edge!(graph, child, new_node)
|
||||
if !(child in n1Children)
|
||||
insert_edge!(graph, child, newNode)
|
||||
end
|
||||
end
|
||||
|
||||
for parent in n3_parents
|
||||
for parent in n3Parents
|
||||
remove_edge!(graph, n3, parent)
|
||||
insert_edge!(graph, new_node, parent)
|
||||
insert_edge!(graph, newNode, parent)
|
||||
|
||||
# important! update the parent node's child names in case they are fused compute tasks
|
||||
# needed for compute generation so the fused compute task can correctly match inputs to its component tasks
|
||||
update_child!(graph, parent, Symbol(to_var_name(n3.id)), Symbol(to_var_name(newNode.id)))
|
||||
end
|
||||
|
||||
return get_snapshot_diff(graph)
|
||||
@ -208,39 +222,50 @@ Reduce the given nodes together into one node, return the applied difference to
|
||||
For details see [`NodeReduction`](@ref).
|
||||
"""
|
||||
function node_reduction!(graph::DAG, nodes::Vector{Node})
|
||||
# @assert is_valid_node_reduction_input(graph, nodes)
|
||||
@assert is_valid_node_reduction_input(graph, nodes)
|
||||
|
||||
# clear snapshot
|
||||
get_snapshot_diff(graph)
|
||||
|
||||
n1 = nodes[1]
|
||||
n1_children = children(n1)
|
||||
n1Children = copy(children(n1))
|
||||
|
||||
n1_parents = Set(n1.parents)
|
||||
new_parents = Set{Node}()
|
||||
n1Parents = Set(n1.parents)
|
||||
|
||||
# set of the new parents of n1
|
||||
newParents = Set{Node}()
|
||||
|
||||
# names of the previous children that n1 now replaces per parent
|
||||
newParentsChildNames = Dict{Node, Symbol}()
|
||||
|
||||
# remove all of the nodes' parents and children and the nodes themselves (except for first node)
|
||||
for i in 2:length(nodes)
|
||||
n = nodes[i]
|
||||
for child in n1_children
|
||||
for child in n1Children
|
||||
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
|
||||
push!(new_parents, parent)
|
||||
push!(newParents, parent)
|
||||
newParentsChildNames[parent] = Symbol(to_var_name(n.id))
|
||||
end
|
||||
|
||||
remove_node!(graph, n)
|
||||
end
|
||||
|
||||
setdiff!(new_parents, n1_parents)
|
||||
|
||||
for parent in new_parents
|
||||
for parent in newParents
|
||||
# now add parents of all input nodes to n1 without duplicates
|
||||
insert_edge!(graph, n1, parent)
|
||||
if !(parent in n1Parents)
|
||||
# don't double insert edges
|
||||
insert_edge!(graph, n1, parent)
|
||||
end
|
||||
|
||||
# this has to be done for all parents, even the ones of n1 because they can be duplicate
|
||||
prevChild = newParentsChildNames[parent]
|
||||
update_child!(graph, parent, prevChild, Symbol(to_var_name(n1.id)))
|
||||
end
|
||||
|
||||
return get_snapshot_diff(graph)
|
||||
@ -253,31 +278,37 @@ 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)
|
||||
# @assert is_valid_node_split_input(graph, n1)
|
||||
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)
|
||||
|
||||
n1_parents = parents(n1)
|
||||
n1_children = children(n1)
|
||||
n1Parents = copy(parents(n1))
|
||||
n1Children = copy(children(n1))
|
||||
|
||||
for parent in n1_parents
|
||||
for parent in n1Parents
|
||||
remove_edge!(graph, n1, parent)
|
||||
end
|
||||
for child in n1_children
|
||||
for child in n1Children
|
||||
remove_edge!(graph, child, n1)
|
||||
end
|
||||
remove_node!(graph, n1)
|
||||
|
||||
for parent in n1_parents
|
||||
n_copy = copy(n1)
|
||||
insert_node!(graph, n_copy)
|
||||
insert_edge!(graph, n_copy, parent)
|
||||
for parent in n1Parents
|
||||
nCopy = copy(n1)
|
||||
|
||||
for child in n1_children
|
||||
insert_edge!(graph, child, n_copy)
|
||||
insert_node!(graph, nCopy)
|
||||
insert_edge!(graph, nCopy, parent)
|
||||
|
||||
for child in n1Children
|
||||
insert_edge!(graph, child, nCopy)
|
||||
end
|
||||
|
||||
update_child!(graph, parent, Symbol(to_var_name(n1.id)), Symbol(to_var_name(nCopy.id)))
|
||||
end
|
||||
|
||||
return get_snapshot_diff(graph)
|
||||
|
@ -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)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user