Skip to content

Optimizations to multi-process and multi-rank Datadeps - #739

Merged
jpsamaroo merged 26 commits into
masterfrom
jps/hierarchical-mp-mr
Sep 17, 2026
Merged

jpsamaroo merged 26 commits into
masterfrom
jps/hierarchical-mp-mr

Conversation

@jpsamaroo

Copy link
Copy Markdown
Member

Written by Claude Opus

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Dagger benchmarks: dirty vs master

Multi-threaded benchmarks (4 threads)

Dagger benchmarks: dirty vs master

Summary by job

Job Regressions Improvements Within noise
stencil/dagger ⚠️ 1 12 2
array/dagger 0 29 6
linalg/dagger 0 6 3
sparse/dagger 0 3 0

⚠️ Regressions (time > 25.0% and outside the reported ±spread; allocs/memory > 25.0%)

  • stencil/dagger/N=256 (block 128)/assign (const) (time): +38.7%

Improvements

  • array/dagger/N=1024 (block 128)/norm (memory): -48.5%
  • array/dagger/N=1024 (block 512)/norm (memory): -48.1%
  • array/dagger/N=256 (block 128)/norm (memory): -47.1%
  • array/dagger/N=1024 (block 128)/norm (allocs): -42.6%
  • array/dagger/N=256 (block 256)/norm (memory): -42.1%
  • array/dagger/N=1024 (block 512)/norm (allocs): -41.6%
  • array/dagger/N=256 (block 128)/norm (allocs): -41.3%
  • array/dagger/N=1024 (block 512)/broadcast (X .+ 1) (allocs): -38.9%
  • array/dagger/N=1024 (block 128)/broadcast (X .+ 1) (allocs): -38.7%
  • array/dagger/N=1024 (block 128)/map (sin.(X)) (allocs): -38.6%
  • array/dagger/N=256 (block 128)/broadcast (X .+ 1) (allocs): -38.4%
  • array/dagger/N=256 (block 128)/norm (time): -38.1%
  • array/dagger/N=1024 (block 128)/alloc (rand) (time): -37.3%
  • array/dagger/N=256 (block 256)/broadcast (X .+ 1) (allocs): -37.2%
  • array/dagger/N=1024 (block 128)/norm (time): -37.1%
  • array/dagger/N=256 (block 256)/norm (allocs): -36.6%
  • array/dagger/N=256 (block 128)/map (sin.(X)) (allocs): -35.5%
  • array/dagger/N=1024 (block 512)/map (sin.(X)) (allocs): -35.3%
  • array/dagger/N=1024 (block 128)/reduce (sum) (memory): -34.6%
  • linalg/dagger/N=1024 (block 128)/qr (allocs): -33.8%
  • sparse/dagger/N=1024 (block 64)/spgemm (S*S) (allocs): -33.4%
  • sparse/dagger/N=256 (block 16)/spgemm (S*S) (allocs): -33.2%
  • sparse/dagger/N=256 (block 16)/spgemm (S*S) (memory): -33.0%
  • stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) (allocs): -32.8%
  • stencil/dagger/N=1024 (block 512)/assign (const) (time): -32.5%
  • array/dagger/N=256 (block 256)/map (sin.(X)) (allocs): -32.0%
  • array/dagger/N=1024 (block 128)/add (X + X) (allocs): -31.2%
  • array/dagger/N=1024 (block 128)/broadcast (X .+ 1) (time): -29.7%
  • array/dagger/N=1024 (block 128)/transpose (permutedims) (allocs): -28.8%
  • stencil/dagger/N=1024 (block 128)/neighbors (Wrap) (allocs): -28.8%
  • array/dagger/N=1024 (block 128)/reduce (sum) (allocs): -28.7%
  • array/dagger/N=1024 (block 128)/add (X + X) (time): -28.7%
  • stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) (allocs): -28.6%
  • array/dagger/N=1024 (block 512)/add (X + X) (allocs): -28.5%
  • stencil/dagger/N=1024 (block 128)/neighbors (Pad) (allocs): -28.4%
  • stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) (allocs): -28.3%
  • stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) (time): -28.2%
  • stencil/dagger/N=1024 (block 128)/neighbors (Clamp) (allocs): -28.2%
  • stencil/dagger/N=1024 (block 128)/neighbors (Reflect) (allocs): -27.9%
  • array/dagger/N=256 (block 128)/add (X + X) (allocs): -27.6%
  • linalg/dagger/N=256 (block 128)/qr (allocs): -27.6%
  • linalg/dagger/N=1024 (block 512)/matmul (A*A) (allocs): -27.4%
  • linalg/dagger/N=256 (block 128)/matmul (A*A) (allocs): -26.7%
  • linalg/dagger/N=1024 (block 128)/cholesky (allocs): -26.5%
  • stencil/dagger/N=1024 (block 128)/neighbors (Wrap) (memory): -26.2%
  • linalg/dagger/N=1024 (block 512)/qr (allocs): -26.2%
  • array/dagger/N=1024 (block 128)/reduce (sum) (time): -25.8%
  • stencil/dagger/N=1024 (block 128)/assign (const) (allocs): -25.5%
  • array/dagger/N=1024 (block 128)/map (sin.(X)) (time): -25.4%
  • stencil/dagger/N=1024 (block 128)/neighbors (Reflect) (time): -25.3%
Within noise (11 metric(s) past threshold but inside the ±spread; not counted)
  • array/dagger/N=256 (block 128)/map (sin.(X)) (time): 107.5%
  • array/dagger/N=1024 (block 512)/broadcast (X .+ 1) (time): 75.3%
  • linalg/dagger/N=256 (block 256)/cholesky (time): 58.6%
  • stencil/dagger/N=256 (block 128)/update (+) (time): 56.7%
  • array/dagger/N=1024 (block 512)/norm (time): 52.7%
  • array/dagger/N=256 (block 128)/broadcast (X .+ 1) (time): 47.6%
  • linalg/dagger/N=1024 (block 512)/matvec (A*x) (time): 32.7%
  • stencil/dagger/N=1024 (block 512)/multi-expr (time): 27.0%
  • array/dagger/N=1024 (block 512)/add (X + X) (time): -25.2%
  • array/dagger/N=1024 (block 512)/alloc (rand) (time): -30.7%
  • linalg/dagger/N=256 (block 256)/solve (A\b via lu) (time): -31.7%

Median time

master dirty master / dirty
array/dagger/N=1024 (block 128)/add (X + X) 0.0317 ± 0.0018 s 22.6 ± 0.36 ms 1.4 ± 0.083
array/dagger/N=1024 (block 128)/alloc (rand) 8.89 ± 1.1 ms 5.58 ± 1 ms 1.59 ± 0.35
array/dagger/N=1024 (block 128)/broadcast (X .+ 1) 13 ± 0.38 ms 9.14 ± 0.33 ms 1.42 ± 0.067
array/dagger/N=1024 (block 128)/map (sin.(X)) 12 ± 0.29 ms 8.98 ± 0.05 ms 1.34 ± 0.033
array/dagger/N=1024 (block 128)/norm 14.5 ± 1.9 ms 9.09 ± 0.042 ms 1.59 ± 0.21
array/dagger/N=1024 (block 128)/reduce (sum) 27.7 ± 3.1 ms 20.5 ± 0.76 ms 1.35 ± 0.16
array/dagger/N=1024 (block 128)/transpose (permutedims) 14.1 ± 0.9 ms 10.6 ± 0.88 ms 1.33 ± 0.14
array/dagger/N=1024 (block 512)/add (X + X) 4.7 ± 0.99 ms 3.51 ± 1.3 ms 1.34 ± 0.57
array/dagger/N=1024 (block 512)/alloc (rand) 2.06 ± 0.81 ms 1.43 ± 0.53 ms 1.44 ± 0.78
array/dagger/N=1024 (block 512)/broadcast (X .+ 1) 2.13 ± 1.4 ms 3.74 ± 2.8 ms 0.57 ± 0.58
array/dagger/N=1024 (block 512)/map (sin.(X)) 5.84 ± 0.53 ms 5.31 ± 0.76 ms 1.1 ± 0.19
array/dagger/N=1024 (block 512)/norm 1.25 ± 0.77 ms 1.9 ± 0.76 ms 0.655 ± 0.48
array/dagger/N=1024 (block 512)/reduce (sum) 1.86 ± 1.2 ms 1.73 ± 2.3 ms 1.08 ± 1.6
array/dagger/N=1024 (block 512)/transpose (permutedims) 5.26 ± 0.79 ms 4.06 ± 0.51 ms 1.3 ± 0.25
array/dagger/N=256 (block 128)/add (X + X) 2.99 ± 0.26 ms 2.71 ± 0.8 ms 1.1 ± 0.34
array/dagger/N=256 (block 128)/alloc (rand) 0.877 ± 0.092 ms 0.784 ± 0.46 ms 1.12 ± 0.67
array/dagger/N=256 (block 128)/broadcast (X .+ 1) 1.39 ± 1.8 ms 2.06 ± 1.1 ms 0.677 ± 0.97
array/dagger/N=256 (block 128)/map (sin.(X)) 1.1 ± 0.012 ms 2.27 ± 3.2 ms 0.482 ± 0.68
array/dagger/N=256 (block 128)/norm 1.22 ± 0.09 ms 0.756 ± 0.076 ms 1.62 ± 0.2
array/dagger/N=256 (block 128)/reduce (sum) 2.16 ± 0.44 ms 2.06 ± 0.49 ms 1.05 ± 0.33
array/dagger/N=256 (block 128)/transpose (permutedims) 1.47 ± 0.12 ms 1.59 ± 0.2 ms 0.921 ± 0.14
array/dagger/N=256 (block 256)/add (X + X) 0.889 ± 0.059 ms 0.768 ± 0.23 ms 1.16 ± 0.35
array/dagger/N=256 (block 256)/alloc (rand) 0.574 ± 0.055 ms 0.546 ± 0.017 ms 1.05 ± 0.11
array/dagger/N=256 (block 256)/broadcast (X .+ 1) 0.527 ± 0.029 ms 0.414 ± 0.018 ms 1.27 ± 0.09
array/dagger/N=256 (block 256)/map (sin.(X)) 0.961 ± 0.015 ms 1.11 ± 0.37 ms 0.865 ± 0.29
array/dagger/N=256 (block 256)/norm 0.385 ± 0.033 ms 0.378 ± 0.021 ms 1.02 ± 0.1
array/dagger/N=256 (block 256)/reduce (sum) 0.605 ± 0.042 ms 0.563 ± 0.053 ms 1.08 ± 0.13
array/dagger/N=256 (block 256)/transpose (permutedims) 0.689 ± 0.037 ms 0.735 ± 0.082 ms 0.937 ± 0.12
linalg/dagger/N=1024 (block 128)/cholesky 0.071 ± 0.017 s 0.0687 ± 0.003 s 1.03 ± 0.25
linalg/dagger/N=1024 (block 128)/lu 0.151 ± 0.021 s 0.134 ± 0.0041 s 1.13 ± 0.16
linalg/dagger/N=1024 (block 128)/matmul (A*A) 0.173 ± 0.011 s 0.179 ± 0.019 s 0.966 ± 0.12
linalg/dagger/N=1024 (block 128)/matvec (A*x) 12.3 ± 2.3 ms 13.8 ± 2.6 ms 0.894 ± 0.24
linalg/dagger/N=1024 (block 128)/qr 0.162 ± 0.026 s 0.135 ± 0.02 s 1.21 ± 0.26
linalg/dagger/N=1024 (block 128)/solve (A\b via lu) 0.206 ± 0.027 s 0.183 ± 0.042 s 1.12 ± 0.3
linalg/dagger/N=1024 (block 128)/svd 24.5 s 24.7 s 0.992
linalg/dagger/N=1024 (block 128)/syrk (A'*A) 0.124 ± 0.016 s 0.102 ± 0.0042 s 1.22 ± 0.17
linalg/dagger/N=1024 (block 512)/cholesky 20.2 ± 5.1 ms 21.2 ± 4.6 ms 0.953 ± 0.32
linalg/dagger/N=1024 (block 512)/lu 0.0414 ± 0.0061 s 0.0393 ± 0.00093 s 1.05 ± 0.16
linalg/dagger/N=1024 (block 512)/matmul (A*A) 0.0418 ± 0.004 s 0.0456 ± 0.014 s 0.916 ± 0.29
linalg/dagger/N=1024 (block 512)/matvec (A*x) 1.9 ± 0.18 ms 2.52 ± 2.7 ms 0.753 ± 0.81
linalg/dagger/N=1024 (block 512)/qr 0.114 ± 0.0018 s 0.119 ± 0.0057 s 0.958 ± 0.048
linalg/dagger/N=1024 (block 512)/solve (A\b via lu) 0.0484 ± 0.0036 s 0.0489 ± 0.0037 s 0.989 ± 0.11
linalg/dagger/N=1024 (block 512)/svd 0.0351 h 0.0348 h 1.01
linalg/dagger/N=1024 (block 512)/syrk (A'*A) 0.0371 ± 0.0013 s 0.0394 ± 0.00092 s 0.941 ± 0.04
linalg/dagger/N=256 (block 128)/cholesky 6.88 ± 0.26 ms 8.47 ± 0.76 ms 0.813 ± 0.079
linalg/dagger/N=256 (block 128)/lu 8.14 ± 0.27 ms 9.92 ± 2.7 ms 0.82 ± 0.23
linalg/dagger/N=256 (block 128)/matmul (A*A) 4.97 ± 4 ms 4.65 ± 0.25 ms 1.07 ± 0.86
linalg/dagger/N=256 (block 128)/matvec (A*x) 1.91 ± 0.28 ms 2.19 ± 0.5 ms 0.875 ± 0.24
linalg/dagger/N=256 (block 128)/qr 10.1 ± 2.9 ms 9.84 ± 2.4 ms 1.02 ± 0.39
linalg/dagger/N=256 (block 128)/solve (A\b via lu) 13.7 ± 1.6 ms 17.1 ± 6.4 ms 0.802 ± 0.32
linalg/dagger/N=256 (block 128)/svd 0.536 ± 0.056 s 0.575 ± 0.022 s 0.932 ± 0.1
linalg/dagger/N=256 (block 128)/syrk (A'*A) 8.05 ± 5 ms 6.86 ± 2.6 ms 1.17 ± 0.85
linalg/dagger/N=256 (block 256)/cholesky 1.89 ± 0.063 ms 3 ± 1.1 ms 0.63 ± 0.23
linalg/dagger/N=256 (block 256)/lu 3.34 ± 0.13 ms 3.33 ± 0.17 ms 1 ± 0.063
linalg/dagger/N=256 (block 256)/matmul (A*A) 2.13 ± 0.047 ms 2.17 ± 0.39 ms 0.984 ± 0.18
linalg/dagger/N=256 (block 256)/matvec (A*x) 0.871 ± 0.013 ms 0.752 ± 0.034 ms 1.16 ± 0.055
linalg/dagger/N=256 (block 256)/qr 4.04 ± 0.45 ms 4.18 ± 0.72 ms 0.967 ± 0.2
linalg/dagger/N=256 (block 256)/solve (A\b via lu) 8.95 ± 3.9 ms 6.11 ± 2.2 ms 1.46 ± 0.82
linalg/dagger/N=256 (block 256)/svd 0.47 ± 0.023 s 0.48 ± 0.0033 s 0.98 ± 0.049
linalg/dagger/N=256 (block 256)/syrk (A'*A) 2.79 ± 0.7 ms 2.72 ± 0.53 ms 1.03 ± 0.33
sparse/dagger/N=1024 (block 64)/cg solve (laplacian) 0.498 ± 0.0084 s 0.431 ± 0.014 s 1.16 ± 0.042
sparse/dagger/N=1024 (block 64)/spgemm (S*S) 0.417 ± 0.012 s 0.336 ± 0.0031 s 1.24 ± 0.038
sparse/dagger/N=1024 (block 64)/spmv (S*x) 30.4 ± 9 ms 27.3 ± 0.75 ms 1.11 ± 0.33
sparse/dagger/N=256 (block 16)/cg solve (laplacian) 0.491 ± 0.021 s 0.438 ± 0.0078 s 1.12 ± 0.052
sparse/dagger/N=256 (block 16)/spgemm (S*S) 0.415 ± 0.012 s 0.33 ± 0.004 s 1.26 ± 0.041
sparse/dagger/N=256 (block 16)/spmv (S*x) 0.0329 ± 0.0038 s 27.3 ± 2.3 ms 1.2 ± 0.17
stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) 0.0362 ± 0.0022 s 26 ± 0.15 ms 1.39 ± 0.085
stencil/dagger/N=1024 (block 128)/assign (const) 13.5 ± 0.28 ms 11.1 ± 0.068 ms 1.22 ± 0.026
stencil/dagger/N=1024 (block 128)/multi-expr 28.2 ± 0.25 ms 23.1 ± 2 ms 1.22 ± 0.1
stencil/dagger/N=1024 (block 128)/neighbors (Clamp) 22.3 ± 0.42 ms 17.3 ± 0.24 ms 1.29 ± 0.03
stencil/dagger/N=1024 (block 128)/neighbors (Pad) 22.2 ± 0.89 ms 17.1 ± 1 ms 1.3 ± 0.095
stencil/dagger/N=1024 (block 128)/neighbors (Reflect) 23.1 ± 0.72 ms 17.2 ± 0.26 ms 1.34 ± 0.046
stencil/dagger/N=1024 (block 128)/neighbors (Wrap) 23.2 ± 0.43 ms 18 ± 1.2 ms 1.29 ± 0.088
stencil/dagger/N=1024 (block 128)/update (+) 14.8 ± 0.073 ms 12.7 ± 0.87 ms 1.17 ± 0.081
stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) 7.5 ± 0.86 ms 8.87 ± 1.6 ms 0.845 ± 0.18
stencil/dagger/N=1024 (block 512)/assign (const) 1.82 ± 0.2 ms 1.23 ± 0.36 ms 1.48 ± 0.47
stencil/dagger/N=1024 (block 512)/multi-expr 2.65 ± 1.1 ms 3.36 ± 0.53 ms 0.787 ± 0.36
stencil/dagger/N=1024 (block 512)/neighbors (Clamp) 6.11 ± 0.23 ms 6.43 ± 0.53 ms 0.951 ± 0.086
stencil/dagger/N=1024 (block 512)/neighbors (Pad) 6.66 ± 0.071 ms 6.47 ± 0.13 ms 1.03 ± 0.024
stencil/dagger/N=1024 (block 512)/neighbors (Reflect) 6.16 ± 0.17 ms 7.18 ± 1.3 ms 0.858 ± 0.16
stencil/dagger/N=1024 (block 512)/neighbors (Wrap) 6.64 ± 0.15 ms 6.13 ± 2.2 ms 1.08 ± 0.4
stencil/dagger/N=1024 (block 512)/update (+) 1.5 ± 0.059 ms 1.77 ± 0.58 ms 0.848 ± 0.28
stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) 4.07 ± 1.2 ms 3.49 ± 1.2 ms 1.17 ± 0.52
stencil/dagger/N=256 (block 128)/assign (const) 1.49 ± 0.074 ms 2.07 ± 0.14 ms 0.721 ± 0.06
stencil/dagger/N=256 (block 128)/multi-expr 2.77 ± 2.9 ms 2.45 ± 2.8 ms 1.13 ± 1.8
stencil/dagger/N=256 (block 128)/neighbors (Clamp) 1.97 ± 0.36 ms 2.15 ± 0.18 ms 0.914 ± 0.18
stencil/dagger/N=256 (block 128)/neighbors (Pad) 2.16 ± 1.6 ms 1.98 ± 0.25 ms 1.09 ± 0.83
stencil/dagger/N=256 (block 128)/neighbors (Reflect) 1.96 ± 0.059 ms 1.73 ± 0.28 ms 1.14 ± 0.19
stencil/dagger/N=256 (block 128)/neighbors (Wrap) 2.03 ± 0.058 ms 1.77 ± 0.17 ms 1.15 ± 0.11
stencil/dagger/N=256 (block 128)/update (+) 1.27 ± 0.087 ms 2 ± 0.99 ms 0.638 ± 0.32
stencil/dagger/N=256 (block 256)/alloc (neighbors Wrap) 1.86 ± 0.02 ms 1.68 ± 0.039 ms 1.11 ± 0.028
stencil/dagger/N=256 (block 256)/assign (const) 0.573 ± 0.016 ms 0.588 ± 0.025 ms 0.975 ± 0.049
stencil/dagger/N=256 (block 256)/multi-expr 1.2 ± 0.29 ms 0.94 ± 0.0064 ms 1.27 ± 0.31
stencil/dagger/N=256 (block 256)/neighbors (Clamp) 1.45 ± 0.031 ms 1.28 ± 0.19 ms 1.14 ± 0.17
stencil/dagger/N=256 (block 256)/neighbors (Pad) 1.43 ± 0.037 ms 1.33 ± 0.051 ms 1.08 ± 0.05
stencil/dagger/N=256 (block 256)/neighbors (Reflect) 1.37 ± 0.073 ms 1.43 ± 0.1 ms 0.959 ± 0.085
stencil/dagger/N=256 (block 256)/neighbors (Wrap) 1.53 ± 1 ms 1.36 ± 0.1 ms 1.12 ± 0.77
stencil/dagger/N=256 (block 256)/update (+) 0.608 ± 0.041 ms 0.566 ± 0.046 ms 1.07 ± 0.11
time_to_load 0.962 ± 0.0099 s 0.971 ± 0.0032 s 0.99 ± 0.011

Allocations / memory

master dirty master / dirty
array/dagger/N=1024 (block 128)/add (X + X) 0.0771 M allocs: 11.1 MB 0.053 M allocs: 10.1 MB 1.1
array/dagger/N=1024 (block 128)/alloc (rand) 21.7 k allocs: 8.72 MB 16.9 k allocs: 8.53 MB 1.02
array/dagger/N=1024 (block 128)/broadcast (X .+ 1) 28.1 k allocs: 8.99 MB 17.3 k allocs: 8.55 MB 1.05
array/dagger/N=1024 (block 128)/map (sin.(X)) 25.9 k allocs: 8.89 MB 15.9 k allocs: 8.49 MB 1.05
array/dagger/N=1024 (block 128)/norm 29.8 k allocs: 1.03 MB 17.1 k allocs: 0.528 MB 1.94
array/dagger/N=1024 (block 128)/reduce (sum) 0.0623 M allocs: 2.21 MB 0.0444 M allocs: 1.44 MB 1.53
array/dagger/N=1024 (block 128)/transpose (permutedims) 0.0356 M allocs: 9.46 MB 25.3 k allocs: 9.04 MB 1.05
array/dagger/N=1024 (block 512)/add (X + X) 5.46 k allocs: 8.22 MB 3.9 k allocs: 8.16 MB 1.01
array/dagger/N=1024 (block 512)/alloc (rand) 1.42 k allocs: 8.05 MB 1.08 k allocs: 8.03 MB 1
array/dagger/N=1024 (block 512)/broadcast (X .+ 1) 1.82 k allocs: 8.06 MB 1.11 k allocs: 8.04 MB 1
array/dagger/N=1024 (block 512)/map (sin.(X)) 1.67 k allocs: 8.06 MB 1.08 k allocs: 8.03 MB 1
array/dagger/N=1024 (block 512)/norm 1.9 k allocs: 0.0657 MB 1.11 k allocs: 0.0341 MB 1.93
array/dagger/N=1024 (block 512)/reduce (sum) 3.22 k allocs: 0.114 MB 2.63 k allocs: 0.088 MB 1.29
array/dagger/N=1024 (block 512)/transpose (permutedims) 2.78 k allocs: 8.12 MB 2.19 k allocs: 8.1 MB 1
array/dagger/N=256 (block 128)/add (X + X) 5.49 k allocs: 0.723 MB 3.98 k allocs: 0.662 MB 1.09
array/dagger/N=256 (block 128)/alloc (rand) 1.42 k allocs: 0.547 MB 1.12 k allocs: 0.536 MB 1.02
array/dagger/N=256 (block 128)/broadcast (X .+ 1) 1.82 k allocs: 0.564 MB 1.12 k allocs: 0.536 MB 1.05
array/dagger/N=256 (block 128)/map (sin.(X)) 1.69 k allocs: 0.558 MB 1.09 k allocs: 0.534 MB 1.05
array/dagger/N=256 (block 128)/norm 1.89 k allocs: 0.0653 MB 1.11 k allocs: 0.0346 MB 1.89
array/dagger/N=256 (block 128)/reduce (sum) 3.01 k allocs: 0.106 MB 2.69 k allocs: 0.0899 MB 1.17
array/dagger/N=256 (block 128)/transpose (permutedims) 2.81 k allocs: 0.621 MB 2.23 k allocs: 0.597 MB 1.04
array/dagger/N=256 (block 256)/add (X + X) 1.68 k allocs: 0.576 MB 1.34 k allocs: 0.562 MB 1.02
array/dagger/N=256 (block 256)/alloc (rand) 0.425 k allocs: 0.514 MB 0.344 k allocs: 0.511 MB 1.01
array/dagger/N=256 (block 256)/broadcast (X .+ 1) 0.503 k allocs: 0.518 MB 0.316 k allocs: 0.51 MB 1.01
array/dagger/N=256 (block 256)/map (sin.(X)) 0.472 k allocs: 0.517 MB 0.321 k allocs: 0.51 MB 1.01
array/dagger/N=256 (block 256)/norm 0.508 k allocs: 18.2 kB 0.322 k allocs: 10.5 kB 1.73
array/dagger/N=256 (block 256)/reduce (sum) 0.68 k allocs: 26.4 kB 0.596 k allocs: 22.2 kB 1.19
array/dagger/N=256 (block 256)/transpose (permutedims) 0.976 k allocs: 0.548 MB 0.844 k allocs: 0.542 MB 1.01
linalg/dagger/N=1024 (block 128)/cholesky 0.105 M allocs: 15.4 MB 0.0774 M allocs: 14.3 MB 1.08
linalg/dagger/N=1024 (block 128)/lu 0.302 M allocs: 23.6 MB 0.234 M allocs: 20.9 MB 1.13
linalg/dagger/N=1024 (block 128)/matmul (A*A) 0.234 M allocs: 16 MB 0.185 M allocs: 14.1 MB 1.13
linalg/dagger/N=1024 (block 128)/matvec (A*x) 0.0413 M allocs: 1.66 MB 0.0328 M allocs: 1.32 MB 1.26
linalg/dagger/N=1024 (block 128)/qr 0.225 M allocs: 24.9 MB 0.149 M allocs: 21.9 MB 1.14
linalg/dagger/N=1024 (block 128)/solve (A\b via lu) 0.381 M allocs: 26.8 MB 0.289 M allocs: 23.2 MB 1.16
linalg/dagger/N=1024 (block 128)/svd 2.36 M allocs: 2.27 GB 2.38 M allocs: 2.28 GB 0.995
linalg/dagger/N=1024 (block 128)/syrk (A'*A) 0.172 M allocs: 17.2 MB 0.134 M allocs: 15.8 MB 1.09
linalg/dagger/N=1024 (block 512)/cholesky 7.05 k allocs: 10.3 MB 5.46 k allocs: 10.2 MB 1.01
linalg/dagger/N=1024 (block 512)/lu 14.8 k allocs: 14.6 MB 11.7 k allocs: 14.5 MB 1.01
linalg/dagger/N=1024 (block 512)/matmul (A*A) 7.25 k allocs: 8.28 MB 5.26 k allocs: 8.2 MB 1.01
linalg/dagger/N=1024 (block 512)/matvec (A*x) 4.18 k allocs: 0.181 MB 3.45 k allocs: 0.153 MB 1.19
linalg/dagger/N=1024 (block 512)/qr 11.6 k allocs: 9.61 MB 8.57 k allocs: 9.49 MB 1.01
linalg/dagger/N=1024 (block 512)/solve (A\b via lu) 24.7 k allocs: 15.1 MB 20.1 k allocs: 14.9 MB 1.01
linalg/dagger/N=1024 (block 512)/svd 0.0468 M allocs: 0.197 GB 0.0375 M allocs: 0.197 GB 1
linalg/dagger/N=1024 (block 512)/syrk (A'*A) 8.54 k allocs: 20.4 MB 6.42 k allocs: 20.3 MB 1
linalg/dagger/N=256 (block 128)/cholesky 6.92 k allocs: 0.912 MB 5.42 k allocs: 0.851 MB 1.07
linalg/dagger/N=256 (block 128)/lu 14.4 k allocs: 1.47 MB 11.6 k allocs: 1.36 MB 1.08
linalg/dagger/N=256 (block 128)/matmul (A*A) 7.24 k allocs: 0.781 MB 5.3 k allocs: 0.704 MB 1.11
linalg/dagger/N=256 (block 128)/matvec (A*x) 4.26 k allocs: 0.18 MB 3.4 k allocs: 0.145 MB 1.24
linalg/dagger/N=256 (block 128)/qr 11.5 k allocs: 1.25 MB 8.34 k allocs: 1.13 MB 1.11
linalg/dagger/N=256 (block 128)/solve (A\b via lu) 24.4 k allocs: 1.92 MB 20 k allocs: 1.73 MB 1.11
linalg/dagger/N=256 (block 128)/svd 0.0461 M allocs: 14.6 MB 0.0371 M allocs: 14.2 MB 1.03
linalg/dagger/N=256 (block 128)/syrk (A'*A) 8.41 k allocs: 1.59 MB 6.4 k allocs: 1.51 MB 1.05
linalg/dagger/N=256 (block 256)/cholesky 2.61 k allocs: 0.622 MB 2.18 k allocs: 0.605 MB 1.03
linalg/dagger/N=256 (block 256)/lu 4.9 k allocs: 1.23 MB 4.06 k allocs: 1.2 MB 1.03
linalg/dagger/N=256 (block 256)/matmul (A*A) 1.8 k allocs: 0.58 MB 1.38 k allocs: 0.563 MB 1.03
linalg/dagger/N=256 (block 256)/matvec (A*x) 1.66 k allocs: 0.0772 MB 1.43 k allocs: 0.0682 MB 1.13
linalg/dagger/N=256 (block 256)/qr 3.49 k allocs: 0.785 MB 2.8 k allocs: 0.758 MB 1.04
linalg/dagger/N=256 (block 256)/solve (A\b via lu) 9.98 k allocs: 1.47 MB 8.38 k allocs: 1.41 MB 1.04
linalg/dagger/N=256 (block 256)/svd 14.7 k allocs: 6.7 MB 12.4 k allocs: 6.61 MB 1.01
linalg/dagger/N=256 (block 256)/syrk (A'*A) 2.79 k allocs: 2.13 MB 2.22 k allocs: 2.11 MB 1.01
sparse/dagger/N=1024 (block 64)/cg solve (laplacian) 2.02 M allocs: 0.0794 GB 1.72 M allocs: 0.0684 GB 1.16
sparse/dagger/N=1024 (block 64)/spgemm (S*S) 2.37 M allocs: 0.127 GB 1.58 M allocs: 0.0975 GB 1.3
sparse/dagger/N=1024 (block 64)/spmv (S*x) 0.14 M allocs: 5.59 MB 0.119 M allocs: 4.79 MB 1.17
sparse/dagger/N=256 (block 16)/cg solve (laplacian) 2.02 M allocs: 0.0794 GB 1.72 M allocs: 0.0682 GB 1.16
sparse/dagger/N=256 (block 16)/spgemm (S*S) 2.35 M allocs: 0.0899 GB 1.57 M allocs: 0.0603 GB 1.49
sparse/dagger/N=256 (block 16)/spmv (S*x) 0.144 M allocs: 5.76 MB 0.119 M allocs: 4.79 MB 1.2
stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) 0.0988 M allocs: 12 MB 0.0664 M allocs: 10.7 MB 1.12
stencil/dagger/N=1024 (block 128)/assign (const) 0.0337 M allocs: 1.39 MB 25.1 k allocs: 1.05 MB 1.32
stencil/dagger/N=1024 (block 128)/multi-expr 0.0759 M allocs: 3.21 MB 0.0582 M allocs: 2.49 MB 1.29
stencil/dagger/N=1024 (block 128)/neighbors (Clamp) 0.0687 M allocs: 3.18 MB 0.0494 M allocs: 2.41 MB 1.32
stencil/dagger/N=1024 (block 128)/neighbors (Pad) 0.0682 M allocs: 3.16 MB 0.0488 M allocs: 2.39 MB 1.32
stencil/dagger/N=1024 (block 128)/neighbors (Reflect) 0.0683 M allocs: 3.2 MB 0.0493 M allocs: 2.44 MB 1.31
stencil/dagger/N=1024 (block 128)/neighbors (Wrap) 0.0682 M allocs: 2.97 MB 0.0485 M allocs: 2.19 MB 1.36
stencil/dagger/N=1024 (block 128)/update (+) 0.0425 M allocs: 1.84 MB 0.0329 M allocs: 1.43 MB 1.28
stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) 6.88 k allocs: 8.29 MB 4.93 k allocs: 8.21 MB 1.01
stencil/dagger/N=1024 (block 512)/assign (const) 2.67 k allocs: 0.116 MB 2.19 k allocs: 0.0972 MB 1.2
stencil/dagger/N=1024 (block 512)/multi-expr 5.88 k allocs: 0.258 MB 4.83 k allocs: 0.215 MB 1.2
stencil/dagger/N=1024 (block 512)/neighbors (Clamp) 5.04 k allocs: 0.281 MB 3.86 k allocs: 0.234 MB 1.2
stencil/dagger/N=1024 (block 512)/neighbors (Pad) 4.91 k allocs: 0.277 MB 3.74 k allocs: 0.23 MB 1.2
stencil/dagger/N=1024 (block 512)/neighbors (Reflect) 5.04 k allocs: 0.312 MB 3.85 k allocs: 0.265 MB 1.18
stencil/dagger/N=1024 (block 512)/neighbors (Wrap) 4.89 k allocs: 0.218 MB 3.72 k allocs: 0.171 MB 1.27
stencil/dagger/N=1024 (block 512)/update (+) 3.14 k allocs: 0.139 MB 2.67 k allocs: 0.119 MB 1.17
stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) 6.93 k allocs: 0.789 MB 4.95 k allocs: 0.71 MB 1.11
stencil/dagger/N=256 (block 128)/assign (const) 2.63 k allocs: 0.114 MB 2.19 k allocs: 0.0968 MB 1.18
stencil/dagger/N=256 (block 128)/multi-expr 5.85 k allocs: 0.257 MB 4.88 k allocs: 0.217 MB 1.18
stencil/dagger/N=256 (block 128)/neighbors (Clamp) 5.07 k allocs: 0.236 MB 3.87 k allocs: 0.188 MB 1.25
stencil/dagger/N=256 (block 128)/neighbors (Pad) 4.9 k allocs: 0.231 MB 3.73 k allocs: 0.184 MB 1.25
stencil/dagger/N=256 (block 128)/neighbors (Reflect) 5.04 k allocs: 0.244 MB 3.84 k allocs: 0.195 MB 1.25
stencil/dagger/N=256 (block 128)/neighbors (Wrap) 4.94 k allocs: 0.22 MB 3.77 k allocs: 0.173 MB 1.27
stencil/dagger/N=256 (block 128)/update (+) 3.19 k allocs: 0.141 MB 2.65 k allocs: 0.118 MB 1.2
stencil/dagger/N=256 (block 256)/alloc (neighbors Wrap) 2.09 k allocs: 0.596 MB 1.61 k allocs: 0.577 MB 1.03
stencil/dagger/N=256 (block 256)/assign (const) 0.932 k allocs: 0.0465 MB 0.838 k allocs: 0.0427 MB 1.09
stencil/dagger/N=256 (block 256)/multi-expr 2.01 k allocs: 0.0995 MB 1.78 k allocs: 0.0905 MB 1.1
stencil/dagger/N=256 (block 256)/neighbors (Clamp) 1.57 k allocs: 0.0844 MB 1.29 k allocs: 0.0737 MB 1.15
stencil/dagger/N=256 (block 256)/neighbors (Pad) 1.53 k allocs: 0.083 MB 1.25 k allocs: 0.0721 MB 1.15
stencil/dagger/N=256 (block 256)/neighbors (Reflect) 1.59 k allocs: 0.093 MB 1.31 k allocs: 0.0816 MB 1.14
stencil/dagger/N=256 (block 256)/neighbors (Wrap) 1.52 k allocs: 0.0762 MB 1.26 k allocs: 0.0661 MB 1.15
stencil/dagger/N=256 (block 256)/update (+) 1.07 k allocs: 0.053 MB 0.952 k allocs: 0.0482 MB 1.1
time_to_load 0.199 k allocs: 11.5 kB 0.199 k allocs: 11.5 kB 1

Plots

Distributed benchmarks (4 processes)

Dagger benchmarks: dirty vs master

Summary by job

Job Regressions Improvements Within noise
stencil/dagger 0 26 0
linalg/dagger 0 15 3
array/dagger 0 10 0
sparse/dagger 0 0 0

No time regressions beyond 35.0% or allocation regressions beyond 25.0% (timing changes inside the reported ±spread don't count) 🎉

Improvements

  • stencil/dagger/N=1024 (block 128)/update (+) (time): -61.6%
  • stencil/dagger/N=1024 (block 128)/multi-expr (time): -58.8%
  • linalg/dagger/N=1024 (block 128)/solve (A\b via lu) (allocs): -57.8%
  • linalg/dagger/N=1024 (block 128)/syrk (A'*A) (allocs): -56.2%
  • linalg/dagger/N=1024 (block 128)/solve (A\b via lu) (memory): -55.6%
  • stencil/dagger/N=1024 (block 512)/update (+) (time): -50.9%
  • stencil/dagger/N=1024 (block 128)/assign (const) (time): -50.2%
  • array/dagger/N=1024 (block 128)/transpose (permutedims) (time): -46.3%
  • array/dagger/N=256 (block 256)/norm (memory): -44.2%
  • linalg/dagger/N=256 (block 128)/matmul (A*A) (allocs): -42.6%
  • linalg/dagger/N=1024 (block 128)/syrk (A'*A) (memory): -41.9%
  • stencil/dagger/N=256 (block 128)/update (+) (time): -41.5%
  • array/dagger/N=256 (block 256)/map (sin.(X)) (allocs): -40.7%
  • linalg/dagger/N=1024 (block 512)/cholesky (allocs): -39.9%
  • linalg/dagger/N=256 (block 128)/qr (allocs): -39.8%
  • stencil/dagger/N=1024 (block 128)/update (+) (allocs): -38.9%
  • array/dagger/N=256 (block 256)/norm (allocs): -38.2%
  • stencil/dagger/N=1024 (block 128)/multi-expr (allocs): -36.6%
  • stencil/dagger/N=1024 (block 128)/update (+) (memory): -36.6%
  • linalg/dagger/N=256 (block 128)/syrk (A'*A) (allocs): -36.2%
  • array/dagger/N=256 (block 256)/alloc (rand) (allocs): -35.7%
  • stencil/dagger/N=256 (block 128)/multi-expr (time): -35.1%
  • array/dagger/N=256 (block 256)/broadcast (X .+ 1) (allocs): -34.8%
  • linalg/dagger/N=1024 (block 512)/solve (A\b via lu) (allocs): -34.6%
  • linalg/dagger/N=1024 (block 128)/matmul (A*A) (allocs): -33.9%
  • array/dagger/N=1024 (block 128)/transpose (permutedims) (allocs): -33.7%
  • stencil/dagger/N=1024 (block 128)/multi-expr (memory): -33.5%
  • stencil/dagger/N=1024 (block 128)/assign (const) (allocs): -33.0%
  • stencil/dagger/N=256 (block 128)/update (+) (allocs): -30.9%
  • stencil/dagger/N=1024 (block 512)/update (+) (allocs): -30.0%
  • array/dagger/N=256 (block 128)/alloc (rand) (allocs): -29.4%
  • stencil/dagger/N=1024 (block 128)/assign (const) (memory): -29.3%
  • stencil/dagger/N=256 (block 128)/update (+) (memory): -28.8%
  • linalg/dagger/N=1024 (block 128)/qr (allocs): -28.8%
  • stencil/dagger/N=1024 (block 512)/multi-expr (allocs): -27.8%
  • stencil/dagger/N=1024 (block 512)/update (+) (memory): -27.6%
  • stencil/dagger/N=256 (block 128)/neighbors (Pad) (allocs): -27.6%
  • stencil/dagger/N=256 (block 128)/multi-expr (allocs): -27.1%
  • array/dagger/N=1024 (block 512)/norm (allocs): -26.8%
  • linalg/dagger/N=256 (block 128)/matvec (A*x) (allocs): -26.5%
  • linalg/dagger/N=1024 (block 512)/matmul (A*A) (allocs): -26.4%
  • linalg/dagger/N=1024 (block 128)/matvec (A*x) (allocs): -26.1%
  • array/dagger/N=1024 (block 512)/norm (memory): -25.9%
  • stencil/dagger/N=256 (block 128)/neighbors (Wrap) (allocs): -25.9%
  • linalg/dagger/N=1024 (block 512)/syrk (A'*A) (allocs): -25.6%
  • stencil/dagger/N=1024 (block 512)/neighbors (Wrap) (allocs): -25.6%
  • stencil/dagger/N=1024 (block 512)/multi-expr (memory): -25.6%
  • stencil/dagger/N=256 (block 128)/neighbors (Reflect) (allocs): -25.5%
  • stencil/dagger/N=1024 (block 128)/neighbors (Pad) (allocs): -25.2%
  • stencil/dagger/N=256 (block 128)/multi-expr (memory): -25.1%
  • stencil/dagger/N=1024 (block 512)/neighbors (Pad) (allocs): -25.1%
Within noise (3 metric(s) past threshold but inside the ±spread; not counted)
  • linalg/dagger/N=1024 (block 128)/syrk (A'*A) (time): -37.2%
  • linalg/dagger/N=1024 (block 128)/solve (A\b via lu) (time): -39.5%
  • linalg/dagger/N=1024 (block 128)/matmul (A*A) (time): -50.4%

Median time

master dirty master / dirty
array/dagger/N=1024 (block 128)/add (X + X) 0.161 ± 0.011 s 0.114 ± 0.0031 s 1.41 ± 0.1
array/dagger/N=1024 (block 128)/alloc (rand) 31.2 ± 0.61 ms 28.7 ± 0.83 ms 1.08 ± 0.038
array/dagger/N=1024 (block 128)/broadcast (X .+ 1) 0.0449 ± 0.0011 s 0.0411 ± 0.00091 s 1.09 ± 0.036
array/dagger/N=1024 (block 128)/map (sin.(X)) 0.047 ± 0.0024 s 0.044 ± 0.0026 s 1.07 ± 0.084
array/dagger/N=1024 (block 128)/norm 0.039 ± 0.00041 s 0.0364 ± 0.0007 s 1.07 ± 0.023
array/dagger/N=1024 (block 128)/reduce (sum) 0.0636 ± 0.0065 s 0.0591 ± 0.0012 s 1.08 ± 0.11
array/dagger/N=1024 (block 128)/transpose (permutedims) 0.0503 ± 0.00053 s 27 ± 1.3 ms 1.86 ± 0.089
array/dagger/N=1024 (block 512)/add (X + X) 11.6 ± 3.7 ms 14.9 ± 1.6 ms 0.781 ± 0.26
array/dagger/N=1024 (block 512)/alloc (rand) 4.08 ± 1.7 ms 3.69 ± 2.1 ms 1.1 ± 0.79
array/dagger/N=1024 (block 512)/broadcast (X .+ 1) 4.42 ± 1.1 ms 4.71 ± 0.4 ms 0.939 ± 0.24
array/dagger/N=1024 (block 512)/map (sin.(X)) 10.6 ± 1.5 ms 11 ± 0.66 ms 0.968 ± 0.14
array/dagger/N=1024 (block 512)/norm 2.17 ± 0.29 ms 2.43 ± 0.12 ms 0.895 ± 0.13
array/dagger/N=1024 (block 512)/reduce (sum) 3.3 ± 0.088 ms 3.48 ± 0.33 ms 0.947 ± 0.094
array/dagger/N=1024 (block 512)/transpose (permutedims) 8 ± 0.38 ms 9.34 ± 0.54 ms 0.856 ± 0.064
array/dagger/N=256 (block 128)/add (X + X) 6.74 ± 0.079 ms 5.62 ± 0.072 ms 1.2 ± 0.021
array/dagger/N=256 (block 128)/alloc (rand) 2.22 ± 0.05 ms 2.63 ± 0.13 ms 0.844 ± 0.046
array/dagger/N=256 (block 128)/broadcast (X .+ 1) 2.65 ± 0.064 ms 2.6 ± 0.16 ms 1.02 ± 0.069
array/dagger/N=256 (block 128)/map (sin.(X)) 2.64 ± 0.45 ms 2.45 ± 0.42 ms 1.08 ± 0.26
array/dagger/N=256 (block 128)/norm 1.89 ± 0.018 ms 1.97 ± 0.047 ms 0.959 ± 0.025
array/dagger/N=256 (block 128)/reduce (sum) 3.69 ± 0.69 ms 3.88 ± 0.095 ms 0.952 ± 0.18
array/dagger/N=256 (block 128)/transpose (permutedims) 3.32 ± 0.013 ms 2.34 ± 0.042 ms 1.42 ± 0.026
array/dagger/N=256 (block 256)/add (X + X) 1.56 ± 0.2 ms 1.45 ± 0.089 ms 1.07 ± 0.15
array/dagger/N=256 (block 256)/alloc (rand) 0.736 ± 0.033 ms 0.804 ± 0.031 ms 0.914 ± 0.055
array/dagger/N=256 (block 256)/broadcast (X .+ 1) 0.336 ± 0.017 ms 0.398 ± 0.05 ms 0.843 ± 0.11
array/dagger/N=256 (block 256)/map (sin.(X)) 1.18 ± 0.02 ms 0.83 ± 0.0082 ms 1.42 ± 0.028
array/dagger/N=256 (block 256)/norm 0.339 ± 0.021 ms 0.344 ± 0.011 ms 0.985 ± 0.069
array/dagger/N=256 (block 256)/reduce (sum) 0.527 ± 0.045 ms 0.53 ± 0.05 ms 0.994 ± 0.13
array/dagger/N=256 (block 256)/transpose (permutedims) 0.74 ± 0.017 ms 0.791 ± 0.046 ms 0.936 ± 0.058
linalg/dagger/N=1024 (block 128)/cholesky 0.423 ± 0.0013 s 0.32 ± 0.0054 s 1.32 ± 0.023
linalg/dagger/N=1024 (block 128)/lu 0.301 ± 0.0026 s 0.286 ± 0.14 s 1.05 ± 0.52
linalg/dagger/N=1024 (block 128)/matmul (A*A) 0.473 ± 0.24 s 0.235 ± 0.0065 s 2.02 ± 1
linalg/dagger/N=1024 (block 128)/matvec (A*x) 0.158 ± 0.00065 s 0.115 ± 0.006 s 1.38 ± 0.073
linalg/dagger/N=1024 (block 128)/qr 0.342 ± 0.011 s 0.3 ± 0.11 s 1.14 ± 0.4
linalg/dagger/N=1024 (block 128)/solve (A\b via lu) 0.993 ± 0.26 s 0.601 ± 0.24 s 1.65 ± 0.79
linalg/dagger/N=1024 (block 128)/svd 51.6 s 44.6 s 1.16
linalg/dagger/N=1024 (block 128)/syrk (A'*A) 0.713 ± 0.13 s 0.448 ± 0.18 s 1.59 ± 0.72
linalg/dagger/N=1024 (block 512)/cholesky 0.0461 ± 0.0021 s 0.0379 ± 0.0019 s 1.21 ± 0.082
linalg/dagger/N=1024 (block 512)/lu 0.0442 ± 0.00052 s 0.0419 ± 0.0007 s 1.05 ± 0.021
linalg/dagger/N=1024 (block 512)/matmul (A*A) 0.0387 ± 0.0021 s 0.0366 ± 0.0017 s 1.06 ± 0.075
linalg/dagger/N=1024 (block 512)/matvec (A*x) 10.8 ± 0.26 ms 8.82 ± 0.39 ms 1.22 ± 0.062
linalg/dagger/N=1024 (block 512)/qr 0.109 ± 0.0006 s 0.109 ± 0.002 s 0.999 ± 0.019
linalg/dagger/N=1024 (block 512)/solve (A\b via lu) 0.0661 ± 0.0027 s 0.0569 ± 0.0037 s 1.16 ± 0.089
linalg/dagger/N=1024 (block 512)/svd 0.0353 h 0.0352 h 1
linalg/dagger/N=1024 (block 512)/syrk (A'*A) 0.0419 ± 0.0016 s 0.0422 ± 0.0077 s 0.992 ± 0.18
linalg/dagger/N=256 (block 128)/cholesky 22.3 ± 0.52 ms 18.3 ± 0.47 ms 1.22 ± 0.042
linalg/dagger/N=256 (block 128)/lu 16.8 ± 0.81 ms 13.5 ± 0.34 ms 1.24 ± 0.068
linalg/dagger/N=256 (block 128)/matmul (A*A) 13.3 ± 0.48 ms 8.85 ± 0.81 ms 1.5 ± 0.15
linalg/dagger/N=256 (block 128)/matvec (A*x) 12.7 ± 0.21 ms 10.4 ± 1.6 ms 1.22 ± 0.18
linalg/dagger/N=256 (block 128)/qr 15.6 ± 0.53 ms 11.7 ± 1.1 ms 1.33 ± 0.13
linalg/dagger/N=256 (block 128)/solve (A\b via lu) 30.2 ± 0.64 ms 26.5 ± 0.91 ms 1.14 ± 0.046
linalg/dagger/N=256 (block 128)/svd 0.68 ± 0.016 s 0.653 ± 0.066 s 1.04 ± 0.11
linalg/dagger/N=256 (block 128)/syrk (A'*A) 14.6 ± 0.52 ms 9.83 ± 1.5 ms 1.49 ± 0.23
linalg/dagger/N=256 (block 256)/cholesky 2.74 ± 0.072 ms 2.62 ± 0.38 ms 1.04 ± 0.15
linalg/dagger/N=256 (block 256)/lu 4.63 ± 0.12 ms 4.63 ± 0.27 ms 0.999 ± 0.063
linalg/dagger/N=256 (block 256)/matmul (A*A) 2.31 ± 0.081 ms 2.46 ± 0.077 ms 0.939 ± 0.044
linalg/dagger/N=256 (block 256)/matvec (A*x) 1.33 ± 0.055 ms 1.33 ± 0.047 ms 1 ± 0.055
linalg/dagger/N=256 (block 256)/qr 5.02 ± 0.1 ms 4.84 ± 0.17 ms 1.04 ± 0.042
linalg/dagger/N=256 (block 256)/solve (A\b via lu) 7.79 ± 0.97 ms 7.33 ± 0.098 ms 1.06 ± 0.13
linalg/dagger/N=256 (block 256)/svd 0.506 ± 0.035 s 0.434 ± 0.019 s 1.17 ± 0.095
linalg/dagger/N=256 (block 256)/syrk (A'*A) 3.7 ± 0.048 ms 3.77 ± 0.31 ms 0.981 ± 0.081
sparse/dagger/N=1024 (block 64)/cg solve (laplacian) 10.4 s 8.05 s 1.29
sparse/dagger/N=1024 (block 64)/spgemm (S*S) 5.54 s 5.31 s 1.04
sparse/dagger/N=1024 (block 64)/spmv (S*x) 0.48 ± 0.024 s 0.353 ± 0.022 s 1.36 ± 0.11
sparse/dagger/N=256 (block 16)/cg solve (laplacian) 11.8 s 8.09 s 1.46
sparse/dagger/N=256 (block 16)/spgemm (S*S) 5.76 s 5.2 s 1.11
sparse/dagger/N=256 (block 16)/spmv (S*x) 0.462 ± 0.014 s 0.332 ± 0.014 s 1.39 ± 0.071
stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) 1.79 ± 0.37 s 1.78 ± 0.75 s 1 ± 0.47
stencil/dagger/N=1024 (block 128)/assign (const) 0.0495 ± 0.00094 s 24.7 ± 0.83 ms 2.01 ± 0.078
stencil/dagger/N=1024 (block 128)/multi-expr 0.125 ± 0.0034 s 0.0516 ± 0.00056 s 2.43 ± 0.072
stencil/dagger/N=1024 (block 128)/neighbors (Clamp) 1.3 ± 0.0078 s 0.926 ± 0.0023 s 1.4 ± 0.0091
stencil/dagger/N=1024 (block 128)/neighbors (Pad) 1.2 ± 0.013 s 0.852 ± 0.00079 s 1.41 ± 0.016
stencil/dagger/N=1024 (block 128)/neighbors (Reflect) 1.29 ± 4.9e-05 s 0.935 ± 0.004 s 1.38 ± 0.0058
stencil/dagger/N=1024 (block 128)/neighbors (Wrap) 1.41 ± 0.0075 s 1.03 ± 0.0063 s 1.37 ± 0.011
stencil/dagger/N=1024 (block 128)/update (+) 0.0719 ± 0.00047 s 27.6 ± 0.2 ms 2.6 ± 0.025
stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) 0.0662 ± 0.0026 s 0.0503 ± 0.0023 s 1.32 ± 0.079
stencil/dagger/N=1024 (block 512)/assign (const) 3.7 ± 0.23 ms 2.44 ± 0.055 ms 1.52 ± 0.099
stencil/dagger/N=1024 (block 512)/multi-expr 8.14 ± 0.76 ms 6.01 ± 0.38 ms 1.35 ± 0.15
stencil/dagger/N=1024 (block 512)/neighbors (Clamp) 0.0431 ± 0.0041 s 0.0346 ± 0.0015 s 1.25 ± 0.13
stencil/dagger/N=1024 (block 512)/neighbors (Pad) 0.0364 ± 0.0019 s 28 ± 1.8 ms 1.3 ± 0.11
stencil/dagger/N=1024 (block 512)/neighbors (Reflect) 0.0428 ± 0.0018 s 0.0357 ± 0.00027 s 1.2 ± 0.05
stencil/dagger/N=1024 (block 512)/neighbors (Wrap) 0.0753 ± 0.0028 s 0.056 ± 0.00076 s 1.34 ± 0.053
stencil/dagger/N=1024 (block 512)/update (+) 5.84 ± 0.2 ms 2.87 ± 0.022 ms 2.04 ± 0.072
stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) 0.055 ± 0.00081 s 0.0473 ± 0.0041 s 1.16 ± 0.1
stencil/dagger/N=256 (block 128)/assign (const) 3.3 ± 6 ms 2.35 ± 0.065 ms 1.4 ± 2.5
stencil/dagger/N=256 (block 128)/multi-expr 7.01 ± 0.29 ms 4.55 ± 0.16 ms 1.54 ± 0.083
stencil/dagger/N=256 (block 128)/neighbors (Clamp) 0.0332 ± 0.0007 s 26.4 ± 3.7 ms 1.26 ± 0.18
stencil/dagger/N=256 (block 128)/neighbors (Pad) 28.4 ± 1.2 ms 19.6 ± 3 ms 1.45 ± 0.23
stencil/dagger/N=256 (block 128)/neighbors (Reflect) 0.0372 ± 0.0021 s 26.2 ± 0.75 ms 1.42 ± 0.091
stencil/dagger/N=256 (block 128)/neighbors (Wrap) 0.0665 ± 0.0023 s 0.0477 ± 0.0012 s 1.39 ± 0.061
stencil/dagger/N=256 (block 128)/update (+) 4.28 ± 0.049 ms 2.5 ± 0.068 ms 1.71 ± 0.05
stencil/dagger/N=256 (block 256)/alloc (neighbors Wrap) 2.06 ± 0.11 ms 2.07 ± 0.084 ms 0.993 ± 0.068
stencil/dagger/N=256 (block 256)/assign (const) 0.641 ± 0.015 ms 0.636 ± 0.01 ms 1.01 ± 0.029
stencil/dagger/N=256 (block 256)/multi-expr 1.37 ± 0.067 ms 1.43 ± 0.036 ms 0.961 ± 0.053
stencil/dagger/N=256 (block 256)/neighbors (Clamp) 1.45 ± 0.034 ms 1.38 ± 0.045 ms 1.06 ± 0.043
stencil/dagger/N=256 (block 256)/neighbors (Pad) 1.37 ± 0.07 ms 1.32 ± 0.33 ms 1.04 ± 0.27
stencil/dagger/N=256 (block 256)/neighbors (Reflect) 1.38 ± 0.059 ms 1.4 ± 0.069 ms 0.984 ± 0.064
stencil/dagger/N=256 (block 256)/neighbors (Wrap) 1.41 ± 0.0048 ms 1.49 ± 0.027 ms 0.947 ± 0.018
stencil/dagger/N=256 (block 256)/update (+) 0.701 ± 0.055 ms 0.869 ± 0.044 ms 0.806 ± 0.075
time_to_load 0.967 ± 0.017 s 0.967 ± 0.0056 s 1 ± 0.019

Allocations / memory

master dirty master / dirty
array/dagger/N=1024 (block 128)/add (X + X) 0.251 M allocs: 23 MB 0.196 M allocs: 20.9 MB 1.1
array/dagger/N=1024 (block 128)/alloc (rand) 0.0488 M allocs: 4.24 MB 0.0378 M allocs: 3.75 MB 1.13
array/dagger/N=1024 (block 128)/broadcast (X .+ 1) 0.105 M allocs: 6.61 MB 0.0935 M allocs: 6.13 MB 1.08
array/dagger/N=1024 (block 128)/map (sin.(X)) 0.105 M allocs: 6.59 MB 0.0948 M allocs: 6.18 MB 1.07
array/dagger/N=1024 (block 128)/norm 0.0687 M allocs: 3.1 MB 0.0561 M allocs: 2.59 MB 1.19
array/dagger/N=1024 (block 128)/reduce (sum) 0.112 M allocs: 4.75 MB 0.0938 M allocs: 3.97 MB 1.2
array/dagger/N=1024 (block 128)/transpose (permutedims) 0.0892 M allocs: 6.2 MB 0.0592 M allocs: 4.91 MB 1.26
array/dagger/N=1024 (block 512)/add (X + X) 12.9 k allocs: 12.5 MB 9.88 k allocs: 12.4 MB 1.01
array/dagger/N=1024 (block 512)/alloc (rand) 2.72 k allocs: 4.11 MB 2.08 k allocs: 4.09 MB 1.01
array/dagger/N=1024 (block 512)/broadcast (X .+ 1) 3.52 k allocs: 4.15 MB 2.82 k allocs: 4.13 MB 1.01
array/dagger/N=1024 (block 512)/map (sin.(X)) 3.34 k allocs: 4.14 MB 2.69 k allocs: 4.12 MB 1.01
array/dagger/N=1024 (block 512)/norm 3.18 k allocs: 0.133 MB 2.33 k allocs: 0.0987 MB 1.35
array/dagger/N=1024 (block 512)/reduce (sum) 5.28 k allocs: 0.21 MB 4.12 k allocs: 0.163 MB 1.29
array/dagger/N=1024 (block 512)/transpose (permutedims) 5.4 k allocs: 4.25 MB 4.25 k allocs: 4.2 MB 1.01
array/dagger/N=256 (block 128)/add (X + X) 12.6 k allocs: 1.28 MB 9.67 k allocs: 1.15 MB 1.11
array/dagger/N=256 (block 128)/alloc (rand) 2.81 k allocs: 0.367 MB 1.99 k allocs: 0.336 MB 1.09
array/dagger/N=256 (block 128)/broadcast (X .+ 1) 3.41 k allocs: 0.395 MB 2.71 k allocs: 0.371 MB 1.07
array/dagger/N=256 (block 128)/map (sin.(X)) 3.19 k allocs: 0.384 MB 2.62 k allocs: 0.367 MB 1.05
array/dagger/N=256 (block 128)/norm 3.26 k allocs: 0.137 MB 2.47 k allocs: 0.105 MB 1.3
array/dagger/N=256 (block 128)/reduce (sum) 5.2 k allocs: 0.209 MB 4.28 k allocs: 0.17 MB 1.23
array/dagger/N=256 (block 128)/transpose (permutedims) 5.54 k allocs: 0.505 MB 4.23 k allocs: 0.45 MB 1.12
array/dagger/N=256 (block 256)/add (X + X) 2.5 k allocs: 0.616 MB 2.03 k allocs: 0.596 MB 1.03
array/dagger/N=256 (block 256)/alloc (rand) 0.535 k allocs: 0.52 MB 0.344 k allocs: 0.513 MB 1.01
array/dagger/N=256 (block 256)/broadcast (X .+ 1) 0.5 k allocs: 0.518 MB 0.326 k allocs: 0.51 MB 1.01
array/dagger/N=256 (block 256)/map (sin.(X)) 0.536 k allocs: 0.519 MB 0.318 k allocs: 0.51 MB 1.02
array/dagger/N=256 (block 256)/norm 0.516 k allocs: 18.1 kB 0.319 k allocs: 10.1 kB 1.79
array/dagger/N=256 (block 256)/reduce (sum) 0.675 k allocs: 26 kB 0.594 k allocs: 21.9 kB 1.18
array/dagger/N=256 (block 256)/transpose (permutedims) 1.24 k allocs: 0.563 MB 1.13 k allocs: 0.558 MB 1.01
linalg/dagger/N=1024 (block 128)/cholesky 0.619 M allocs: 0.038 GB 0.483 M allocs: 0.0328 GB 1.16
linalg/dagger/N=1024 (block 128)/lu 0.644 M allocs: 0.043 GB 0.521 M allocs: 0.0432 GB 0.996
linalg/dagger/N=1024 (block 128)/matmul (A*A) 0.597 M allocs: 0.0362 GB 0.395 M allocs: 29.2 MB 1.27
linalg/dagger/N=1024 (block 128)/matvec (A*x) 0.264 M allocs: 17.1 MB 0.195 M allocs: 14.2 MB 1.2
linalg/dagger/N=1024 (block 128)/qr 0.469 M allocs: 0.0405 GB 0.334 M allocs: 0.0353 GB 1.15
linalg/dagger/N=1024 (block 128)/solve (A\b via lu) 1.31 M allocs: 0.0892 GB 0.553 M allocs: 0.0396 GB 2.25
linalg/dagger/N=1024 (block 128)/svd 16.3 M allocs: 2.55 GB 12.7 M allocs: 2.41 GB 1.06
linalg/dagger/N=1024 (block 128)/syrk (A'*A) 0.73 M allocs: 0.0497 GB 0.32 M allocs: 29.6 MB 1.72
linalg/dagger/N=1024 (block 512)/cholesky 0.0339 M allocs: 15.5 MB 20.3 k allocs: 14.9 MB 1.04
linalg/dagger/N=1024 (block 512)/lu 26.5 k allocs: 19.1 MB 20.5 k allocs: 18.9 MB 1.01
linalg/dagger/N=1024 (block 512)/matmul (A*A) 17.2 k allocs: 12.7 MB 12.7 k allocs: 12.5 MB 1.01
linalg/dagger/N=1024 (block 512)/matvec (A*x) 16.5 k allocs: 4.72 MB 13.2 k allocs: 4.58 MB 1.03
linalg/dagger/N=1024 (block 512)/qr 21.3 k allocs: 14 MB 16.4 k allocs: 13.8 MB 1.01
linalg/dagger/N=1024 (block 512)/solve (A\b via lu) 0.0524 M allocs: 20.3 MB 0.0343 M allocs: 19.5 MB 1.04
linalg/dagger/N=1024 (block 512)/svd 0.168 M allocs: 0.308 GB 0.14 M allocs: 0.307 GB 1
linalg/dagger/N=1024 (block 512)/syrk (A'*A) 18.3 k allocs: 24.8 MB 13.6 k allocs: 24.6 MB 1.01
linalg/dagger/N=256 (block 128)/cholesky 0.0327 M allocs: 2.33 MB 25.9 k allocs: 2.05 MB 1.14
linalg/dagger/N=256 (block 128)/lu 0.0325 M allocs: 2.51 MB 25 k allocs: 2.2 MB 1.14
linalg/dagger/N=256 (block 128)/matmul (A*A) 22 k allocs: 1.68 MB 12.6 k allocs: 1.27 MB 1.33
linalg/dagger/N=256 (block 128)/matvec (A*x) 22.5 k allocs: 1.24 MB 16.6 k allocs: 0.981 MB 1.27
linalg/dagger/N=256 (block 128)/qr 26.4 k allocs: 2.17 MB 15.9 k allocs: 1.7 MB 1.27
linalg/dagger/N=256 (block 128)/solve (A\b via lu) 0.0562 M allocs: 3.56 MB 0.045 M allocs: 3.1 MB 1.15
linalg/dagger/N=256 (block 128)/svd 0.221 M allocs: 29.3 MB 0.18 M allocs: 27.6 MB 1.06
linalg/dagger/N=256 (block 128)/syrk (A'*A) 22.4 k allocs: 2.46 MB 14.3 k allocs: 2.1 MB 1.17
linalg/dagger/N=256 (block 256)/cholesky 3.93 k allocs: 0.688 MB 3.55 k allocs: 0.673 MB 1.02
linalg/dagger/N=256 (block 256)/lu 7.29 k allocs: 1.34 MB 6.57 k allocs: 1.32 MB 1.02
linalg/dagger/N=256 (block 256)/matmul (A*A) 2.56 k allocs: 0.617 MB 2.24 k allocs: 0.606 MB 1.02
linalg/dagger/N=256 (block 256)/matvec (A*x) 2.58 k allocs: 0.121 MB 2.35 k allocs: 0.112 MB 1.09
linalg/dagger/N=256 (block 256)/qr 5.18 k allocs: 0.868 MB 4.52 k allocs: 0.842 MB 1.03
linalg/dagger/N=256 (block 256)/solve (A\b via lu) 15 k allocs: 1.72 MB 13.6 k allocs: 1.67 MB 1.03
linalg/dagger/N=256 (block 256)/svd 21.9 k allocs: 7.05 MB 19.7 k allocs: 6.96 MB 1.01
linalg/dagger/N=256 (block 256)/syrk (A'*A) 4.16 k allocs: 2.2 MB 3.6 k allocs: 2.18 MB 1.01
sparse/dagger/N=1024 (block 64)/cg solve (laplacian) 15.9 M allocs: 0.722 GB 14.1 M allocs: 0.649 GB 1.11
sparse/dagger/N=1024 (block 64)/spgemm (S*S) 8.98 M allocs: 0.425 GB 8.71 M allocs: 0.421 GB 1.01
sparse/dagger/N=1024 (block 64)/spmv (S*x) 0.776 M allocs: 0.0329 GB 0.611 M allocs: 27 MB 1.24
sparse/dagger/N=256 (block 16)/cg solve (laplacian) 17.1 M allocs: 0.772 GB 14 M allocs: 0.643 GB 1.2
sparse/dagger/N=256 (block 16)/spgemm (S*S) 9.25 M allocs: 0.419 GB 8.46 M allocs: 0.39 GB 1.07
sparse/dagger/N=256 (block 16)/spmv (S*x) 0.777 M allocs: 0.0325 GB 0.603 M allocs: 25.9 MB 1.28
stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) 2.22 M allocs: 0.107 GB 1.69 M allocs: 0.0884 GB 1.21
stencil/dagger/N=1024 (block 128)/assign (const) 0.0865 M allocs: 4.04 MB 0.0579 M allocs: 2.85 MB 1.41
stencil/dagger/N=1024 (block 128)/multi-expr 0.213 M allocs: 9.71 MB 0.135 M allocs: 6.46 MB 1.5
stencil/dagger/N=1024 (block 128)/neighbors (Clamp) 1.9 M allocs: 0.0835 GB 1.42 M allocs: 0.0653 GB 1.28
stencil/dagger/N=1024 (block 128)/neighbors (Pad) 1.74 M allocs: 0.0769 GB 1.3 M allocs: 0.0597 GB 1.29
stencil/dagger/N=1024 (block 128)/neighbors (Reflect) 1.88 M allocs: 0.0831 GB 1.43 M allocs: 0.0654 GB 1.27
stencil/dagger/N=1024 (block 128)/neighbors (Wrap) 2.06 M allocs: 0.0904 GB 1.59 M allocs: 0.0726 GB 1.25
stencil/dagger/N=1024 (block 128)/update (+) 0.127 M allocs: 5.71 MB 0.0774 M allocs: 3.62 MB 1.58
stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) 0.0957 M allocs: 16.2 MB 0.0724 M allocs: 15.2 MB 1.06
stencil/dagger/N=1024 (block 512)/assign (const) 5.52 k allocs: 0.253 MB 4.16 k allocs: 0.196 MB 1.29
stencil/dagger/N=1024 (block 512)/multi-expr 13.1 k allocs: 0.596 MB 9.5 k allocs: 0.444 MB 1.34
stencil/dagger/N=1024 (block 512)/neighbors (Clamp) 0.0619 M allocs: 2.8 MB 0.0468 M allocs: 2.19 MB 1.28
stencil/dagger/N=1024 (block 512)/neighbors (Pad) 0.0448 M allocs: 2.05 MB 0.0336 M allocs: 1.6 MB 1.28
stencil/dagger/N=1024 (block 512)/neighbors (Reflect) 0.0619 M allocs: 2.82 MB 0.0472 M allocs: 2.24 MB 1.26
stencil/dagger/N=1024 (block 512)/neighbors (Wrap) 0.118 M allocs: 5.31 MB 0.0878 M allocs: 4.08 MB 1.3
stencil/dagger/N=1024 (block 512)/update (+) 7.52 k allocs: 0.339 MB 5.26 k allocs: 0.245 MB 1.38
stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) 0.0947 M allocs: 4.91 MB 0.0723 M allocs: 3.99 MB 1.23
stencil/dagger/N=256 (block 128)/assign (const) 5.52 k allocs: 0.255 MB 4.34 k allocs: 0.205 MB 1.24
stencil/dagger/N=256 (block 128)/multi-expr 12.7 k allocs: 0.58 MB 9.23 k allocs: 0.434 MB 1.34
stencil/dagger/N=256 (block 128)/neighbors (Clamp) 0.0611 M allocs: 2.74 MB 0.0474 M allocs: 2.19 MB 1.25
stencil/dagger/N=256 (block 128)/neighbors (Pad) 0.0455 M allocs: 2.04 MB 0.0329 M allocs: 1.53 MB 1.33
stencil/dagger/N=256 (block 128)/neighbors (Reflect) 0.0637 M allocs: 2.85 MB 0.0475 M allocs: 2.19 MB 1.3
stencil/dagger/N=256 (block 128)/neighbors (Wrap) 0.116 M allocs: 5.21 MB 0.0863 M allocs: 3.99 MB 1.31
stencil/dagger/N=256 (block 128)/update (+) 7.48 k allocs: 0.34 MB 5.17 k allocs: 0.242 MB 1.41
stencil/dagger/N=256 (block 256)/alloc (neighbors Wrap) 2.74 k allocs: 0.628 MB 2.54 k allocs: 0.622 MB 1.01
stencil/dagger/N=256 (block 256)/assign (const) 1.21 k allocs: 0.0619 MB 1.12 k allocs: 0.0583 MB 1.06
stencil/dagger/N=256 (block 256)/multi-expr 2.83 k allocs: 0.144 MB 2.65 k allocs: 0.137 MB 1.05
stencil/dagger/N=256 (block 256)/neighbors (Clamp) 2.07 k allocs: 0.109 MB 1.81 k allocs: 0.0981 MB 1.11
stencil/dagger/N=256 (block 256)/neighbors (Pad) 2.02 k allocs: 0.107 MB 1.76 k allocs: 0.0966 MB 1.11
stencil/dagger/N=256 (block 256)/neighbors (Reflect) 2.07 k allocs: 0.117 MB 1.8 k allocs: 0.106 MB 1.1
stencil/dagger/N=256 (block 256)/neighbors (Wrap) 2.02 k allocs: 0.1 MB 1.88 k allocs: 0.0966 MB 1.04
stencil/dagger/N=256 (block 256)/update (+) 1.51 k allocs: 0.0766 MB 1.5 k allocs: 0.076 MB 1.01
time_to_load 0.199 k allocs: 11.5 kB 0.199 k allocs: 11.5 kB 1

Plots

MPI benchmarks (4 ranks)

Dagger benchmarks: dirty vs master

Summary by job

Job Regressions Improvements Within noise
stencil/dagger 0 81 0
linalg/dagger 0 62 2
array/dagger 0 34 0
sparse/dagger 0 14 0

No time regressions beyond 35.0% or allocation regressions beyond 25.0% (timing changes inside the reported ±spread don't count) 🎉

Improvements

  • linalg/dagger/N=256 (block 128)/matmul (A*A) (time): -79.7%
  • linalg/dagger/N=1024 (block 128)/matmul (A*A) (time): -77.4%
  • linalg/dagger/N=1024 (block 128)/cholesky (time): -76.8%
  • linalg/dagger/N=1024 (block 128)/syrk (A'*A) (time): -69.0%
  • linalg/dagger/N=256 (block 128)/qr (time): -62.8%
  • linalg/dagger/N=1024 (block 128)/qr (time): -61.7%
  • array/dagger/N=1024 (block 512)/transpose (permutedims) (time): -59.5%
  • stencil/dagger/N=1024 (block 128)/update (+) (allocs): -54.2%
  • sparse/dagger/N=256 (block 16)/cg solve (laplacian) (time): -53.8%
  • stencil/dagger/N=1024 (block 128)/multi-expr (allocs): -53.4%
  • stencil/dagger/N=1024 (block 128)/assign (const) (allocs): -52.0%
  • array/dagger/N=1024 (block 128)/transpose (permutedims) (allocs): -51.9%
  • stencil/dagger/N=1024 (block 128)/update (+) (memory): -51.8%
  • stencil/dagger/N=1024 (block 512)/neighbors (Wrap) (allocs): -51.1%
  • stencil/dagger/N=256 (block 128)/neighbors (Wrap) (allocs): -51.1%
  • stencil/dagger/N=1024 (block 128)/multi-expr (memory): -51.0%
  • array/dagger/N=1024 (block 128)/add (X + X) (allocs): -50.9%
  • stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) (allocs): -50.6%
  • stencil/dagger/N=1024 (block 128)/neighbors (Wrap) (allocs): -50.6%
  • stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) (allocs): -50.6%
  • stencil/dagger/N=1024 (block 128)/neighbors (Reflect) (allocs): -50.6%
  • stencil/dagger/N=1024 (block 128)/neighbors (Clamp) (allocs): -50.6%
  • stencil/dagger/N=1024 (block 128)/neighbors (Pad) (allocs): -50.5%
  • stencil/dagger/N=1024 (block 512)/neighbors (Clamp) (allocs): -50.5%
  • stencil/dagger/N=1024 (block 512)/neighbors (Reflect) (allocs): -50.4%
  • stencil/dagger/N=256 (block 128)/neighbors (Reflect) (allocs): -50.4%
  • stencil/dagger/N=256 (block 128)/neighbors (Clamp) (allocs): -50.4%
  • stencil/dagger/N=256 (block 128)/update (+) (allocs): -50.3%
  • stencil/dagger/N=1024 (block 512)/update (+) (allocs): -50.3%
  • stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) (allocs): -50.3%
  • stencil/dagger/N=256 (block 128)/neighbors (Pad) (allocs): -49.6%
  • stencil/dagger/N=1024 (block 512)/neighbors (Pad) (allocs): -49.5%
  • stencil/dagger/N=1024 (block 128)/assign (const) (memory): -49.5%
  • stencil/dagger/N=256 (block 128)/neighbors (Wrap) (memory): -49.4%
  • stencil/dagger/N=1024 (block 512)/neighbors (Wrap) (memory): -49.3%
  • stencil/dagger/N=1024 (block 128)/neighbors (Wrap) (memory): -48.7%
  • stencil/dagger/N=256 (block 128)/neighbors (Clamp) (memory): -48.6%
  • stencil/dagger/N=256 (block 128)/neighbors (Reflect) (memory): -48.6%
  • stencil/dagger/N=1024 (block 512)/neighbors (Clamp) (memory): -48.6%
  • stencil/dagger/N=1024 (block 512)/neighbors (Reflect) (memory): -48.5%
  • stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) (memory): -48.5%
  • stencil/dagger/N=256 (block 128)/multi-expr (allocs): -48.5%
  • stencil/dagger/N=1024 (block 128)/neighbors (Clamp) (memory): -48.5%
  • stencil/dagger/N=1024 (block 128)/neighbors (Reflect) (memory): -48.5%
  • stencil/dagger/N=1024 (block 512)/multi-expr (allocs): -48.5%
  • stencil/dagger/N=1024 (block 128)/neighbors (Pad) (memory): -48.4%
  • linalg/dagger/N=1024 (block 512)/matmul (A*A) (time): -48.2%
  • linalg/dagger/N=1024 (block 128)/cholesky (allocs): -48.2%
  • sparse/dagger/N=1024 (block 64)/cg solve (laplacian) (time): -48.2%
  • stencil/dagger/N=256 (block 128)/update (+) (memory): -48.0%
  • stencil/dagger/N=1024 (block 512)/update (+) (memory): -48.0%
  • stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) (memory): -47.8%
  • stencil/dagger/N=256 (block 128)/neighbors (Pad) (memory): -47.7%
  • stencil/dagger/N=1024 (block 512)/neighbors (Pad) (memory): -47.6%
  • linalg/dagger/N=1024 (block 128)/matvec (A*x) (allocs): -47.1%
  • stencil/dagger/N=1024 (block 512)/neighbors (Pad) (time): -47.1%
  • sparse/dagger/N=256 (block 16)/cg solve (laplacian) (allocs): -47.0%
  • array/dagger/N=256 (block 128)/add (X + X) (allocs): -46.9%
  • array/dagger/N=1024 (block 512)/add (X + X) (allocs): -46.9%
  • linalg/dagger/N=1024 (block 128)/qr (allocs): -46.9%
  • sparse/dagger/N=1024 (block 64)/cg solve (laplacian) (allocs): -46.9%
  • stencil/dagger/N=256 (block 256)/update (+) (allocs): -46.4%
  • stencil/dagger/N=256 (block 128)/multi-expr (memory): -46.2%
  • stencil/dagger/N=1024 (block 512)/multi-expr (memory): -46.2%
  • linalg/dagger/N=1024 (block 512)/qr (allocs): -46.1%
  • sparse/dagger/N=1024 (block 64)/spmv (S*x) (allocs): -46.1%
  • sparse/dagger/N=256 (block 16)/spmv (S*x) (allocs): -46.0%
  • linalg/dagger/N=256 (block 128)/qr (allocs): -46.0%
  • array/dagger/N=1024 (block 128)/add (X + X) (memory): -45.9%
  • linalg/dagger/N=256 (block 128)/matvec (A*x) (allocs): -45.9%
  • linalg/dagger/N=1024 (block 512)/matvec (A*x) (allocs): -45.8%
  • stencil/dagger/N=1024 (block 512)/neighbors (Reflect) (time): -45.7%
  • linalg/dagger/N=1024 (block 128)/solve (A\b via lu) (time): -45.7%
  • array/dagger/N=256 (block 128)/transpose (permutedims) (allocs): -45.5%
  • stencil/dagger/N=256 (block 128)/assign (const) (allocs): -45.5%
  • array/dagger/N=1024 (block 512)/transpose (permutedims) (allocs): -45.5%
  • stencil/dagger/N=1024 (block 512)/assign (const) (allocs): -45.5%
  • linalg/dagger/N=1024 (block 128)/matvec (A*x) (memory): -45.2%
  • sparse/dagger/N=256 (block 16)/cg solve (laplacian) (memory): -45.1%
  • sparse/dagger/N=1024 (block 64)/cg solve (laplacian) (memory): -45.1%
  • linalg/dagger/N=256 (block 128)/matmul (A*A) (allocs): -45.0%
  • linalg/dagger/N=1024 (block 128)/syrk (A'*A) (allocs): -45.0%
  • linalg/dagger/N=1024 (block 512)/cholesky (allocs): -44.9%
  • linalg/dagger/N=256 (block 128)/cholesky (allocs): -44.9%
  • linalg/dagger/N=1024 (block 512)/matmul (A*A) (allocs): -44.9%
  • stencil/dagger/N=1024 (block 128)/update (+) (time): -44.8%
  • linalg/dagger/N=256 (block 256)/matvec (A*x) (allocs): -44.7%
  • linalg/dagger/N=256 (block 128)/syrk (A'*A) (allocs): -44.7%
  • linalg/dagger/N=1024 (block 512)/syrk (A'*A) (allocs): -44.6%
  • stencil/dagger/N=256 (block 256)/neighbors (Wrap) (allocs): -44.5%
  • stencil/dagger/N=256 (block 256)/neighbors (Pad) (allocs): -44.5%
  • stencil/dagger/N=256 (block 256)/neighbors (Clamp) (allocs): -44.4%
  • stencil/dagger/N=256 (block 256)/neighbors (Reflect) (allocs): -44.4%
  • sparse/dagger/N=1024 (block 64)/spmv (S*x) (memory): -44.3%
  • sparse/dagger/N=256 (block 16)/spmv (S*x) (memory): -44.2%
  • stencil/dagger/N=256 (block 256)/update (+) (memory): -44.1%
  • stencil/dagger/N=256 (block 256)/multi-expr (allocs): -44.0%
  • linalg/dagger/N=1024 (block 128)/cholesky (memory): -44.0%
  • linalg/dagger/N=256 (block 128)/matvec (A*x) (memory): -43.9%
  • array/dagger/N=1024 (block 128)/transpose (permutedims) (memory): -43.9%
  • linalg/dagger/N=1024 (block 512)/matvec (A*x) (memory): -43.9%
  • array/dagger/N=1024 (block 128)/add (X + X) (time): -43.5%
  • stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) (memory): -43.4%
  • stencil/dagger/N=1024 (block 512)/neighbors (Clamp) (time): -43.3%
  • linalg/dagger/N=1024 (block 128)/qr (memory): -43.3%
  • stencil/dagger/N=1024 (block 512)/assign (const) (memory): -43.0%
  • stencil/dagger/N=256 (block 128)/assign (const) (memory): -43.0%
  • linalg/dagger/N=1024 (block 128)/matmul (A*A) (allocs): -42.9%
  • linalg/dagger/N=256 (block 256)/matvec (A*x) (memory): -42.8%
  • stencil/dagger/N=1024 (block 128)/multi-expr (time): -42.7%
  • stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) (time): -42.7%
  • linalg/dagger/N=256 (block 128)/qr (memory): -42.5%
  • array/dagger/N=256 (block 128)/add (X + X) (memory): -42.5%
  • stencil/dagger/N=1024 (block 512)/neighbors (Wrap) (time): -42.2%
  • array/dagger/N=1024 (block 128)/transpose (permutedims) (time): -42.2%
  • stencil/dagger/N=1024 (block 128)/assign (const) (time): -42.2%
  • linalg/dagger/N=1024 (block 128)/syrk (A'*A) (memory): -42.0%
  • linalg/dagger/N=256 (block 256)/matmul (A*A) (allocs): -42.0%
  • linalg/dagger/N=256 (block 128)/matmul (A*A) (memory): -42.0%
  • stencil/dagger/N=256 (block 256)/neighbors (Wrap) (memory): -41.9%
  • array/dagger/N=256 (block 256)/add (X + X) (allocs): -41.9%
  • linalg/dagger/N=256 (block 256)/cholesky (allocs): -41.7%
  • linalg/dagger/N=256 (block 256)/qr (allocs): -41.7%
  • stencil/dagger/N=256 (block 256)/multi-expr (memory): -41.6%
  • stencil/dagger/N=256 (block 256)/neighbors (Pad) (memory): -41.6%
  • stencil/dagger/N=256 (block 256)/neighbors (Clamp) (memory): -41.5%
  • linalg/dagger/N=256 (block 256)/syrk (A'*A) (allocs): -41.5%
  • linalg/dagger/N=256 (block 128)/cholesky (memory): -41.4%
  • stencil/dagger/N=256 (block 256)/alloc (neighbors Wrap) (allocs): -41.3%
  • stencil/dagger/N=256 (block 256)/neighbors (Reflect) (memory): -41.0%
  • linalg/dagger/N=1024 (block 128)/solve (A\b via lu) (allocs): -40.8%
  • linalg/dagger/N=1024 (block 128)/lu (allocs): -40.7%
  • array/dagger/N=1024 (block 512)/add (X + X) (time): -40.6%
  • linalg/dagger/N=1024 (block 128)/lu (time): -40.6%
  • linalg/dagger/N=256 (block 128)/solve (A\b via lu) (allocs): -40.6%
  • array/dagger/N=256 (block 256)/transpose (permutedims) (allocs): -40.4%
  • linalg/dagger/N=256 (block 128)/lu (allocs): -40.4%
  • stencil/dagger/N=256 (block 256)/assign (const) (allocs): -40.4%
  • linalg/dagger/N=1024 (block 128)/matmul (A*A) (memory): -40.4%
  • linalg/dagger/N=256 (block 256)/solve (A\b via lu) (allocs): -40.0%
  • linalg/dagger/N=256 (block 256)/lu (allocs): -39.9%
  • linalg/dagger/N=1024 (block 512)/solve (A\b via lu) (allocs): -39.8%
  • linalg/dagger/N=1024 (block 512)/lu (allocs): -39.8%
  • stencil/dagger/N=1024 (block 512)/update (+) (time): -39.2%
  • stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) (time): -38.8%
  • array/dagger/N=256 (block 128)/transpose (permutedims) (memory): -38.7%
  • stencil/dagger/N=1024 (block 128)/neighbors (Wrap) (time): -38.7%
  • linalg/dagger/N=256 (block 128)/syrk (A'*A) (memory): -38.6%
  • linalg/dagger/N=1024 (block 128)/solve (A\b via lu) (memory): -38.6%
  • stencil/dagger/N=1024 (block 128)/neighbors (Pad) (time): -38.5%
  • linalg/dagger/N=256 (block 128)/solve (A\b via lu) (memory): -38.4%
  • linalg/dagger/N=1024 (block 128)/lu (memory): -38.4%
  • stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) (time): -38.3%
  • linalg/dagger/N=256 (block 128)/lu (memory): -38.2%
  • stencil/dagger/N=1024 (block 128)/neighbors (Clamp) (time): -38.2%
  • stencil/dagger/N=256 (block 256)/assign (const) (memory): -37.8%
  • linalg/dagger/N=256 (block 256)/solve (A\b via lu) (memory): -37.6%
  • sparse/dagger/N=256 (block 16)/spgemm (S*S) (allocs): -37.5%
  • sparse/dagger/N=1024 (block 64)/spgemm (S*S) (allocs): -37.5%
  • linalg/dagger/N=256 (block 256)/lu (memory): -37.5%
  • linalg/dagger/N=1024 (block 512)/lu (memory): -37.4%
  • linalg/dagger/N=1024 (block 512)/solve (A\b via lu) (memory): -37.3%
  • stencil/dagger/N=1024 (block 128)/neighbors (Reflect) (time): -36.8%
  • stencil/dagger/N=256 (block 128)/neighbors (Clamp) (time): -36.7%
  • stencil/dagger/N=256 (block 128)/neighbors (Wrap) (time): -36.3%
  • sparse/dagger/N=256 (block 16)/spgemm (S*S) (memory): -35.3%
  • array/dagger/N=1024 (block 128)/alloc (rand) (allocs): -35.1%
  • sparse/dagger/N=1024 (block 64)/spgemm (S*S) (memory): -34.4%
  • array/dagger/N=1024 (block 128)/norm (memory): -32.8%
  • array/dagger/N=256 (block 128)/alloc (rand) (allocs): -32.5%
  • array/dagger/N=256 (block 128)/norm (memory): -32.5%
  • array/dagger/N=1024 (block 512)/alloc (rand) (allocs): -32.5%
  • linalg/dagger/N=1024 (block 512)/qr (memory): -32.2%
  • array/dagger/N=1024 (block 512)/norm (memory): -32.1%
  • linalg/dagger/N=1024 (block 512)/matmul (A*A) (memory): -30.7%
  • array/dagger/N=256 (block 128)/norm (allocs): -30.5%
  • array/dagger/N=256 (block 256)/norm (memory): -30.5%
  • array/dagger/N=1024 (block 128)/norm (allocs): -30.4%
  • array/dagger/N=1024 (block 512)/norm (allocs): -30.2%
  • linalg/dagger/N=1024 (block 512)/cholesky (memory): -29.3%
  • array/dagger/N=256 (block 256)/norm (allocs): -29.1%
  • array/dagger/N=256 (block 256)/alloc (rand) (allocs): -28.3%
  • linalg/dagger/N=256 (block 256)/cholesky (memory): -28.1%
  • array/dagger/N=1024 (block 512)/broadcast (X .+ 1) (allocs): -27.9%
  • linalg/dagger/N=256 (block 256)/qr (memory): -27.7%
  • array/dagger/N=256 (block 256)/map (sin.(X)) (allocs): -26.9%
  • array/dagger/N=256 (block 128)/broadcast (X .+ 1) (allocs): -26.4%
  • array/dagger/N=1024 (block 128)/broadcast (X .+ 1) (allocs): -26.2%
  • array/dagger/N=256 (block 256)/broadcast (X .+ 1) (allocs): -25.8%
  • array/dagger/N=256 (block 128)/map (sin.(X)) (allocs): -25.2%
  • stencil/dagger/N=256 (block 256)/alloc (neighbors Wrap) (memory): -25.1%
Within noise (2 metric(s) past threshold but inside the ±spread; not counted)
  • linalg/dagger/N=1024 (block 512)/cholesky (time): 40.9%
  • linalg/dagger/N=256 (block 128)/syrk (A'*A) (time): -44.5%

Median time

master dirty master / dirty
array/dagger/N=1024 (block 128)/add (X + X) 0.206 ± 0.003 s 0.116 ± 0.0012 s 1.77 ± 0.031
array/dagger/N=1024 (block 128)/alloc (rand) 0.0423 ± 0.00079 s 27.6 ± 0.11 ms 1.53 ± 0.029
array/dagger/N=1024 (block 128)/broadcast (X .+ 1) 22.4 ± 0.4 ms 16.9 ± 0.16 ms 1.32 ± 0.027
array/dagger/N=1024 (block 128)/map (sin.(X)) 24 ± 0.025 ms 19.7 ± 0.34 ms 1.22 ± 0.021
array/dagger/N=1024 (block 128)/norm 25.2 ± 0.017 ms 18.2 ± 0.11 ms 1.38 ± 0.0081
array/dagger/N=1024 (block 128)/reduce (sum) 0.0442 ± 0.00054 s 0.0376 ± 0.00086 s 1.18 ± 0.03
array/dagger/N=1024 (block 128)/transpose (permutedims) 0.0958 ± 0.00071 s 0.0554 ± 0.0013 s 1.73 ± 0.043
array/dagger/N=1024 (block 512)/add (X + X) 18.3 ± 0.63 ms 10.9 ± 0.079 ms 1.68 ± 0.059
array/dagger/N=1024 (block 512)/alloc (rand) 5.04 ± 0.25 ms 3.5 ± 0.1 ms 1.44 ± 0.081
array/dagger/N=1024 (block 512)/broadcast (X .+ 1) 3.07 ± 0.28 ms 2.78 ± 0.23 ms 1.11 ± 0.14
array/dagger/N=1024 (block 512)/map (sin.(X)) 6.03 ± 0.062 ms 6.08 ± 0.063 ms 0.992 ± 0.015
array/dagger/N=1024 (block 512)/norm 5.47 ± 0.21 ms 5.46 ± 0.15 ms 1 ± 0.047
array/dagger/N=1024 (block 512)/reduce (sum) 3.15 ± 0.042 ms 2.93 ± 0.063 ms 1.07 ± 0.027
array/dagger/N=1024 (block 512)/transpose (permutedims) 18.8 ± 1.1 ms 7.61 ± 0.19 ms 2.47 ± 0.16
array/dagger/N=256 (block 128)/add (X + X) 13.4 ± 0.049 ms 9.54 ± 0.46 ms 1.41 ± 0.068
array/dagger/N=256 (block 128)/alloc (rand) 3.7 ± 0.073 ms 2.93 ± 0.18 ms 1.26 ± 0.08
array/dagger/N=256 (block 128)/broadcast (X .+ 1) 1.71 ± 0.068 ms 1.36 ± 0.048 ms 1.26 ± 0.067
array/dagger/N=256 (block 128)/map (sin.(X)) 1.74 ± 0.11 ms 1.53 ± 0.01 ms 1.14 ± 0.073
array/dagger/N=256 (block 128)/norm 2 ± 0.064 ms 1.69 ± 0.037 ms 1.19 ± 0.046
array/dagger/N=256 (block 128)/reduce (sum) 3.11 ± 0.18 ms 2.83 ± 0.13 ms 1.1 ± 0.081
array/dagger/N=256 (block 128)/transpose (permutedims) 6.97 ± 0.15 ms 4.78 ± 0.056 ms 1.46 ± 0.035
array/dagger/N=256 (block 256)/add (X + X) 4.34 ± 0.053 ms 3.39 ± 0.082 ms 1.28 ± 0.035
array/dagger/N=256 (block 256)/alloc (rand) 1.73 ± 0.061 ms 1.55 ± 0.069 ms 1.12 ± 0.063
array/dagger/N=256 (block 256)/broadcast (X .+ 1) 0.645 ± 0.026 ms 0.539 ± 0.0078 ms 1.2 ± 0.052
array/dagger/N=256 (block 256)/map (sin.(X)) 1.36 ± 0.0044 ms 1.31 ± 0.018 ms 1.04 ± 0.014
array/dagger/N=256 (block 256)/norm 1.18 ± 0.039 ms 1.1 ± 0.051 ms 1.08 ± 0.061
array/dagger/N=256 (block 256)/reduce (sum) 0.829 ± 0.011 ms 0.797 ± 0.034 ms 1.04 ± 0.046
array/dagger/N=256 (block 256)/transpose (permutedims) 2.39 ± 0.046 ms 2.09 ± 0.066 ms 1.14 ± 0.042
linalg/dagger/N=1024 (block 128)/cholesky 3.5 s 0.812 ± 0.12 s 4.31
linalg/dagger/N=1024 (block 128)/lu 29.5 s 17.5 s 1.68
linalg/dagger/N=1024 (block 128)/matmul (A*A) 6.64 s 1.5 ± 0.15 s 4.42
linalg/dagger/N=1024 (block 128)/matvec (A*x) 0.192 ± 0.0036 s 0.134 ± 0.00069 s 1.44 ± 0.028
linalg/dagger/N=1024 (block 128)/qr 3.54 s 1.36 ± 0.11 s 2.61
linalg/dagger/N=1024 (block 128)/solve (A\b via lu) 31.4 s 17.1 s 1.84
linalg/dagger/N=1024 (block 128)/syrk (A'*A) 3.71 s 1.15 ± 0.07 s 3.22
linalg/dagger/N=1024 (block 512)/cholesky 0.119 ± 0.021 s 0.168 ± 0.095 s 0.71 ± 0.42
linalg/dagger/N=1024 (block 512)/lu 11.1 s 7.99 s 1.39
linalg/dagger/N=1024 (block 512)/matmul (A*A) 0.226 ± 0.036 s 0.117 ± 0.0026 s 1.93 ± 0.31
linalg/dagger/N=1024 (block 512)/matvec (A*x) 22.4 ± 0.32 ms 15.4 ± 0.3 ms 1.46 ± 0.035
linalg/dagger/N=1024 (block 512)/qr 0.605 ± 0.27 s 0.395 ± 0.17 s 1.53 ± 0.95
linalg/dagger/N=1024 (block 512)/solve (A\b via lu) 10.6 s 8.02 s 1.33
linalg/dagger/N=1024 (block 512)/syrk (A'*A) 0.227 ± 0.041 s 0.166 ± 0.018 s 1.36 ± 0.29
linalg/dagger/N=256 (block 128)/cholesky 0.112 ± 0.062 s 0.0764 ± 0.049 s 1.46 ± 1.2
linalg/dagger/N=256 (block 128)/lu 1.85 ± 0.00099 s 1.36 ± 0.0089 s 1.36 ± 0.009
linalg/dagger/N=256 (block 128)/matmul (A*A) 0.217 ± 0.096 s 0.0442 ± 0.011 s 4.92 ± 2.5
linalg/dagger/N=256 (block 128)/matvec (A*x) 20.4 ± 0.36 ms 14.1 ± 0.076 ms 1.45 ± 0.027
linalg/dagger/N=256 (block 128)/qr 0.183 ± 0.008 s 0.068 ± 0.016 s 2.69 ± 0.65
linalg/dagger/N=256 (block 128)/solve (A\b via lu) 1.91 ± 0.0015 s 1.41 ± 0.0046 s 1.35 ± 0.0045
linalg/dagger/N=256 (block 128)/syrk (A'*A) 0.148 ± 0.034 s 0.0821 ± 0.045 s 1.8 ± 1.1
linalg/dagger/N=256 (block 256)/cholesky 17 ± 1.4 ms 12.3 ± 2.2 ms 1.38 ± 0.28
linalg/dagger/N=256 (block 256)/lu 0.709 ± 0.0065 s 0.546 ± 0.006 s 1.3 ± 0.019
linalg/dagger/N=256 (block 256)/matmul (A*A) 5.44 ± 0.29 ms 5.65 ± 1.1 ms 0.961 ± 0.19
linalg/dagger/N=256 (block 256)/matvec (A*x) 5.02 ± 0.14 ms 4.15 ± 0.046 ms 1.21 ± 0.036
linalg/dagger/N=256 (block 256)/qr 10.6 ± 2.8 ms 9.09 ± 0.27 ms 1.17 ± 0.31
linalg/dagger/N=256 (block 256)/solve (A\b via lu) 0.729 ± 0.0069 s 0.56 ± 0.0021 s 1.3 ± 0.013
linalg/dagger/N=256 (block 256)/syrk (A'*A) 10.2 ± 2.1 ms 10.5 ± 0.99 ms 0.97 ± 0.22
sparse/dagger/N=1024 (block 64)/cg solve (laplacian) 14.3 s 7.42 s 1.93
sparse/dagger/N=1024 (block 64)/spgemm (S*S) 7.31 s 4.91 s 1.49
sparse/dagger/N=1024 (block 64)/spmv (S*x) 0.679 ± 0.002 s 0.467 ± 0.0011 s 1.45 ± 0.0054
sparse/dagger/N=256 (block 16)/cg solve (laplacian) 13.9 s 6.45 s 2.16
sparse/dagger/N=256 (block 16)/spgemm (S*S) 7 s 5 s 1.4
sparse/dagger/N=256 (block 16)/spmv (S*x) 0.662 ± 0.0041 s 0.475 ± 0.002 s 1.39 ± 0.011
stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) 1.54 ± 0.038 s 0.949 ± 0.018 s 1.62 ± 0.05
stencil/dagger/N=1024 (block 128)/assign (const) 0.0924 ± 0.00086 s 0.0534 ± 0.00067 s 1.73 ± 0.027
stencil/dagger/N=1024 (block 128)/multi-expr 0.242 ± 0.00052 s 0.138 ± 0.0013 s 1.75 ± 0.017
stencil/dagger/N=1024 (block 128)/neighbors (Clamp) 1.36 ± 0.018 s 0.842 ± 0.0055 s 1.62 ± 0.024
stencil/dagger/N=1024 (block 128)/neighbors (Pad) 1.26 ± 0.013 s 0.775 ± 0.0017 s 1.62 ± 0.017
stencil/dagger/N=1024 (block 128)/neighbors (Reflect) 1.32 ± 0.008 s 0.834 ± 0.0018 s 1.58 ± 0.01
stencil/dagger/N=1024 (block 128)/neighbors (Wrap) 1.5 ± 0.0024 s 0.92 ± 0.006 s 1.63 ± 0.011
stencil/dagger/N=1024 (block 128)/update (+) 0.154 ± 0.0035 s 0.085 ± 0.0015 s 1.81 ± 0.052
stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) 0.136 ± 0.0023 s 0.0778 ± 0.00066 s 1.75 ± 0.033
stencil/dagger/N=1024 (block 512)/assign (const) 6.86 ± 0.48 ms 4.92 ± 0.07 ms 1.39 ± 0.1
stencil/dagger/N=1024 (block 512)/multi-expr 17.9 ± 0.35 ms 12 ± 0.69 ms 1.5 ± 0.092
stencil/dagger/N=1024 (block 512)/neighbors (Clamp) 0.0937 ± 0.0021 s 0.0531 ± 0.00033 s 1.77 ± 0.04
stencil/dagger/N=1024 (block 512)/neighbors (Pad) 0.0728 ± 0.0017 s 0.0385 ± 0.00065 s 1.89 ± 0.054
stencil/dagger/N=1024 (block 512)/neighbors (Reflect) 0.0976 ± 0.0037 s 0.053 ± 0.00077 s 1.84 ± 0.075
stencil/dagger/N=1024 (block 512)/neighbors (Wrap) 0.132 ± 0.0049 s 0.0762 ± 0.00031 s 1.73 ± 0.065
stencil/dagger/N=1024 (block 512)/update (+) 11.6 ± 0.41 ms 7.04 ± 0.15 ms 1.65 ± 0.068
stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) 0.119 ± 0.0064 s 0.0731 ± 0.00041 s 1.63 ± 0.088
stencil/dagger/N=256 (block 128)/assign (const) 6.81 ± 0.17 ms 4.8 ± 0.15 ms 1.42 ± 0.057
stencil/dagger/N=256 (block 128)/multi-expr 16.3 ± 0.46 ms 11.4 ± 0.35 ms 1.43 ± 0.06
stencil/dagger/N=256 (block 128)/neighbors (Clamp) 0.0769 ± 0.00075 s 0.0487 ± 0.00022 s 1.58 ± 0.017
stencil/dagger/N=256 (block 128)/neighbors (Pad) 0.0515 ± 0.00092 s 0.0335 ± 0.00041 s 1.54 ± 0.033
stencil/dagger/N=256 (block 128)/neighbors (Reflect) 0.0762 ± 0.00031 s 0.0501 ± 0.00039 s 1.52 ± 0.013
stencil/dagger/N=256 (block 128)/neighbors (Wrap) 0.113 ± 0.0025 s 0.072 ± 0.00026 s 1.57 ± 0.035
stencil/dagger/N=256 (block 128)/update (+) 10.3 ± 0.14 ms 6.73 ± 0.07 ms 1.52 ± 0.026
stencil/dagger/N=256 (block 256)/alloc (neighbors Wrap) 6.4 ± 0.076 ms 5.62 ± 0.098 ms 1.14 ± 0.024
stencil/dagger/N=256 (block 256)/assign (const) 2.18 ± 0.087 ms 1.88 ± 0.085 ms 1.16 ± 0.07
stencil/dagger/N=256 (block 256)/multi-expr 5.12 ± 0.18 ms 3.9 ± 0.093 ms 1.32 ± 0.055
stencil/dagger/N=256 (block 256)/neighbors (Clamp) 5.29 ± 0.063 ms 4.46 ± 0.16 ms 1.19 ± 0.046
stencil/dagger/N=256 (block 256)/neighbors (Pad) 5.35 ± 0.11 ms 4.25 ± 0.088 ms 1.26 ± 0.037
stencil/dagger/N=256 (block 256)/neighbors (Reflect) 5.4 ± 0.068 ms 4.35 ± 0.045 ms 1.24 ± 0.02
stencil/dagger/N=256 (block 256)/neighbors (Wrap) 5.29 ± 0.22 ms 4.35 ± 0.096 ms 1.22 ± 0.057
stencil/dagger/N=256 (block 256)/update (+) 3.11 ± 0.059 ms 2.33 ± 0.03 ms 1.34 ± 0.031
time_to_load 1.02 ± 0.032 s 0.983 ± 0.016 s 1.03 ± 0.036

Allocations / memory

master dirty master / dirty
array/dagger/N=1024 (block 128)/add (X + X) 0.655 M allocs: 0.035 GB 0.321 M allocs: 19.4 MB 1.85
array/dagger/N=1024 (block 128)/alloc (rand) 0.1 M allocs: 6.83 MB 0.065 M allocs: 5.25 MB 1.3
array/dagger/N=1024 (block 128)/broadcast (X .+ 1) 0.0408 M allocs: 3.53 MB 30.1 k allocs: 3.07 MB 1.15
array/dagger/N=1024 (block 128)/map (sin.(X)) 0.0386 M allocs: 3.43 MB 29 k allocs: 3.03 MB 1.13
array/dagger/N=1024 (block 128)/norm 0.0512 M allocs: 2.01 MB 0.0356 M allocs: 1.35 MB 1.49
array/dagger/N=1024 (block 128)/reduce (sum) 0.0813 M allocs: 3 MB 0.0749 M allocs: 2.65 MB 1.14
array/dagger/N=1024 (block 128)/transpose (permutedims) 0.303 M allocs: 17.7 MB 0.146 M allocs: 9.96 MB 1.78
array/dagger/N=1024 (block 512)/add (X + X) 0.0449 M allocs: 4.32 MB 23.8 k allocs: 3.28 MB 1.32
array/dagger/N=1024 (block 512)/alloc (rand) 8.16 k allocs: 2.4 MB 5.51 k allocs: 2.28 MB 1.05
array/dagger/N=1024 (block 512)/broadcast (X .+ 1) 2.58 k allocs: 2.09 MB 1.86 k allocs: 2.07 MB 1.01
array/dagger/N=1024 (block 512)/map (sin.(X)) 2.37 k allocs: 2.09 MB 1.79 k allocs: 2.06 MB 1.01
array/dagger/N=1024 (block 512)/norm 3.36 k allocs: 0.131 MB 2.35 k allocs: 0.0892 MB 1.47
array/dagger/N=1024 (block 512)/reduce (sum) 4.74 k allocs: 0.174 MB 4.31 k allocs: 0.154 MB 1.13
array/dagger/N=1024 (block 512)/transpose (permutedims) 21 k allocs: 3.09 MB 11.5 k allocs: 2.62 MB 1.18
array/dagger/N=256 (block 128)/add (X + X) 0.0449 M allocs: 2.44 MB 23.8 k allocs: 1.4 MB 1.74
array/dagger/N=256 (block 128)/alloc (rand) 8.15 k allocs: 0.524 MB 5.5 k allocs: 0.402 MB 1.31
array/dagger/N=256 (block 128)/broadcast (X .+ 1) 2.52 k allocs: 0.218 MB 1.86 k allocs: 0.19 MB 1.15
array/dagger/N=256 (block 128)/map (sin.(X)) 2.39 k allocs: 0.212 MB 1.79 k allocs: 0.187 MB 1.13
array/dagger/N=256 (block 128)/norm 3.31 k allocs: 0.13 MB 2.3 k allocs: 0.0874 MB 1.48
array/dagger/N=256 (block 128)/reduce (sum) 4.79 k allocs: 0.176 MB 4.35 k allocs: 0.155 MB 1.13
array/dagger/N=256 (block 128)/transpose (permutedims) 21 k allocs: 1.22 MB 11.5 k allocs: 0.746 MB 1.63
array/dagger/N=256 (block 256)/add (X + X) 14.1 k allocs: 1.24 MB 8.22 k allocs: 0.944 MB 1.31
array/dagger/N=256 (block 256)/alloc (rand) 3.51 k allocs: 0.676 MB 2.52 k allocs: 0.629 MB 1.08
array/dagger/N=256 (block 256)/broadcast (X .+ 1) 0.677 k allocs: 0.525 MB 0.502 k allocs: 0.518 MB 1.01
array/dagger/N=256 (block 256)/map (sin.(X)) 0.659 k allocs: 0.524 MB 0.482 k allocs: 0.517 MB 1.01
array/dagger/N=256 (block 256)/norm 0.969 k allocs: 0.0392 MB 0.687 k allocs: 27.9 kB 1.44
array/dagger/N=256 (block 256)/reduce (sum) 1 k allocs: 0.0396 MB 0.864 k allocs: 0.033 MB 1.2
array/dagger/N=256 (block 256)/transpose (permutedims) 6.67 k allocs: 0.852 MB 3.98 k allocs: 0.719 MB 1.19
linalg/dagger/N=1024 (block 128)/cholesky 1.53 M allocs: 0.0796 GB 0.792 M allocs: 0.0446 GB 1.79
linalg/dagger/N=1024 (block 128)/lu 0.0492 G allocs: 2.35 GB 29.2 M allocs: 1.45 GB 1.62
linalg/dagger/N=1024 (block 128)/matmul (A*A) 3.36 M allocs: 0.166 GB 1.92 M allocs: 0.0987 GB 1.68
linalg/dagger/N=1024 (block 128)/matvec (A*x) 0.607 M allocs: 31.1 MB 0.321 M allocs: 17.1 MB 1.82
linalg/dagger/N=1024 (block 128)/qr 2.32 M allocs: 0.119 GB 1.23 M allocs: 0.0672 GB 1.76
linalg/dagger/N=1024 (block 128)/solve (A\b via lu) 0.0502 G allocs: 2.4 GB 29.7 M allocs: 1.47 GB 1.63
linalg/dagger/N=1024 (block 128)/syrk (A'*A) 2.53 M allocs: 0.127 GB 1.39 M allocs: 0.0737 GB 1.72
linalg/dagger/N=1024 (block 512)/cholesky 0.0862 M allocs: 6.44 MB 0.0475 M allocs: 4.55 MB 1.42
linalg/dagger/N=1024 (block 512)/lu 18 M allocs: 0.858 GB 10.8 M allocs: 0.537 GB 1.6
linalg/dagger/N=1024 (block 512)/matmul (A*A) 0.0999 M allocs: 7.06 MB 0.0551 M allocs: 4.89 MB 1.44
linalg/dagger/N=1024 (block 512)/matvec (A*x) 0.0609 M allocs: 3.13 MB 0.033 M allocs: 1.76 MB 1.78
linalg/dagger/N=1024 (block 512)/qr 0.122 M allocs: 8.49 MB 0.0657 M allocs: 5.75 MB 1.48
linalg/dagger/N=1024 (block 512)/solve (A\b via lu) 18.1 M allocs: 0.868 GB 10.9 M allocs: 0.545 GB 1.59
linalg/dagger/N=1024 (block 512)/syrk (A'*A) 0.0983 M allocs: 13 MB 0.0544 M allocs: 10.9 MB 1.2
linalg/dagger/N=256 (block 128)/cholesky 0.0862 M allocs: 4.56 MB 0.0475 M allocs: 2.67 MB 1.71
linalg/dagger/N=256 (block 128)/lu 4.59 M allocs: 0.218 GB 2.74 M allocs: 0.135 GB 1.62
linalg/dagger/N=256 (block 128)/matmul (A*A) 0.1 M allocs: 5.2 MB 0.055 M allocs: 3.02 MB 1.72
linalg/dagger/N=256 (block 128)/matvec (A*x) 0.0609 M allocs: 3.13 MB 0.033 M allocs: 1.76 MB 1.78
linalg/dagger/N=256 (block 128)/qr 0.122 M allocs: 6.42 MB 0.0658 M allocs: 3.69 MB 1.74
linalg/dagger/N=256 (block 128)/solve (A\b via lu) 4.72 M allocs: 0.225 GB 2.8 M allocs: 0.138 GB 1.62
linalg/dagger/N=256 (block 128)/syrk (A'*A) 0.0983 M allocs: 5.52 MB 0.0544 M allocs: 3.39 MB 1.63
linalg/dagger/N=256 (block 256)/cholesky 23.6 k allocs: 1.75 MB 13.8 k allocs: 1.26 MB 1.39
linalg/dagger/N=256 (block 256)/lu 2.03 M allocs: 0.0985 GB 1.22 M allocs: 0.0616 GB 1.6
linalg/dagger/N=256 (block 256)/matmul (A*A) 14.6 k allocs: 1.26 MB 8.46 k allocs: 0.955 MB 1.32
linalg/dagger/N=256 (block 256)/matvec (A*x) 17.3 k allocs: 0.911 MB 9.6 k allocs: 0.521 MB 1.75
linalg/dagger/N=256 (block 256)/qr 27.6 k allocs: 2.07 MB 16.1 k allocs: 1.5 MB 1.38
linalg/dagger/N=256 (block 256)/solve (A\b via lu) 2.08 M allocs: 0.101 GB 1.25 M allocs: 0.0629 GB 1.6
linalg/dagger/N=256 (block 256)/syrk (A'*A) 21.3 k allocs: 3.11 MB 12.4 k allocs: 2.68 MB 1.16
sparse/dagger/N=1024 (block 64)/cg solve (laplacian) 28.1 M allocs: 1.41 GB 15 M allocs: 0.775 GB 1.82
sparse/dagger/N=1024 (block 64)/spgemm (S*S) 18.1 M allocs: 0.89 GB 11.3 M allocs: 0.584 GB 1.52
sparse/dagger/N=1024 (block 64)/spmv (S*x) 2.12 M allocs: 0.106 GB 1.14 M allocs: 0.0593 GB 1.79
sparse/dagger/N=256 (block 16)/cg solve (laplacian) 28.1 M allocs: 1.41 GB 14.9 M allocs: 0.775 GB 1.82
sparse/dagger/N=256 (block 16)/spgemm (S*S) 18.1 M allocs: 0.869 GB 11.3 M allocs: 0.562 GB 1.55
sparse/dagger/N=256 (block 16)/spmv (S*x) 2.12 M allocs: 0.106 GB 1.14 M allocs: 0.0593 GB 1.79
stencil/dagger/N=1024 (block 128)/alloc (neighbors Wrap) 3.98 M allocs: 0.199 GB 1.98 M allocs: 0.104 GB 1.92
stencil/dagger/N=1024 (block 128)/assign (const) 0.294 M allocs: 15.3 MB 0.141 M allocs: 7.75 MB 1.98
stencil/dagger/N=1024 (block 128)/multi-expr 0.812 M allocs: 0.0415 GB 0.378 M allocs: 20.8 MB 2.04
stencil/dagger/N=1024 (block 128)/neighbors (Clamp) 3.49 M allocs: 0.173 GB 1.72 M allocs: 0.0891 GB 1.94
stencil/dagger/N=1024 (block 128)/neighbors (Pad) 3.26 M allocs: 0.162 GB 1.61 M allocs: 0.0835 GB 1.94
stencil/dagger/N=1024 (block 128)/neighbors (Reflect) 3.49 M allocs: 0.173 GB 1.72 M allocs: 0.0891 GB 1.94
stencil/dagger/N=1024 (block 128)/neighbors (Wrap) 3.88 M allocs: 0.192 GB 1.92 M allocs: 0.0987 GB 1.95
stencil/dagger/N=1024 (block 128)/update (+) 0.518 M allocs: 27.2 MB 0.237 M allocs: 13.1 MB 2.08
stencil/dagger/N=1024 (block 512)/alloc (neighbors Wrap) 0.317 M allocs: 18 MB 0.156 M allocs: 10.2 MB 1.77
stencil/dagger/N=1024 (block 512)/assign (const) 20.5 k allocs: 1.07 MB 11.2 k allocs: 0.607 MB 1.76
stencil/dagger/N=1024 (block 512)/multi-expr 0.0549 M allocs: 2.87 MB 28.3 k allocs: 1.54 MB 1.86
stencil/dagger/N=1024 (block 512)/neighbors (Clamp) 0.211 M allocs: 10.7 MB 0.104 M allocs: 5.5 MB 1.94
stencil/dagger/N=1024 (block 512)/neighbors (Pad) 0.145 M allocs: 7.41 MB 0.0733 M allocs: 3.88 MB 1.91
stencil/dagger/N=1024 (block 512)/neighbors (Reflect) 0.211 M allocs: 10.7 MB 0.104 M allocs: 5.51 MB 1.94
stencil/dagger/N=1024 (block 512)/neighbors (Wrap) 0.309 M allocs: 15.6 MB 0.151 M allocs: 7.9 MB 1.97
stencil/dagger/N=1024 (block 512)/update (+) 0.0344 M allocs: 1.8 MB 17.1 k allocs: 0.936 MB 1.92
stencil/dagger/N=256 (block 128)/alloc (neighbors Wrap) 0.317 M allocs: 16.1 MB 0.156 M allocs: 8.29 MB 1.94
stencil/dagger/N=256 (block 128)/assign (const) 20.5 k allocs: 1.07 MB 11.2 k allocs: 0.607 MB 1.76
stencil/dagger/N=256 (block 128)/multi-expr 0.0549 M allocs: 2.87 MB 28.3 k allocs: 1.54 MB 1.86
stencil/dagger/N=256 (block 128)/neighbors (Clamp) 0.211 M allocs: 10.7 MB 0.104 M allocs: 5.49 MB 1.95
stencil/dagger/N=256 (block 128)/neighbors (Pad) 0.145 M allocs: 7.4 MB 0.0732 M allocs: 3.87 MB 1.91
stencil/dagger/N=256 (block 128)/neighbors (Reflect) 0.211 M allocs: 10.7 MB 0.104 M allocs: 5.49 MB 1.95
stencil/dagger/N=256 (block 128)/neighbors (Wrap) 0.308 M allocs: 15.6 MB 0.151 M allocs: 7.89 MB 1.98
stencil/dagger/N=256 (block 128)/update (+) 0.0344 M allocs: 1.8 MB 17.1 k allocs: 0.936 MB 1.92
stencil/dagger/N=256 (block 256)/alloc (neighbors Wrap) 17.2 k allocs: 1.4 MB 10.1 k allocs: 1.05 MB 1.34
stencil/dagger/N=256 (block 256)/assign (const) 6.52 k allocs: 0.346 MB 3.89 k allocs: 0.215 MB 1.61
stencil/dagger/N=256 (block 256)/multi-expr 16.6 k allocs: 0.878 MB 9.28 k allocs: 0.513 MB 1.71
stencil/dagger/N=256 (block 256)/neighbors (Clamp) 13.8 k allocs: 0.733 MB 7.67 k allocs: 0.429 MB 1.71
stencil/dagger/N=256 (block 256)/neighbors (Pad) 13.7 k allocs: 0.732 MB 7.62 k allocs: 0.428 MB 1.71
stencil/dagger/N=256 (block 256)/neighbors (Reflect) 13.8 k allocs: 0.741 MB 7.67 k allocs: 0.437 MB 1.7
stencil/dagger/N=256 (block 256)/neighbors (Wrap) 13.7 k allocs: 0.726 MB 7.61 k allocs: 0.422 MB 1.72
stencil/dagger/N=256 (block 256)/update (+) 10.1 k allocs: 0.533 MB 5.39 k allocs: 0.298 MB 1.79
time_to_load 0.199 k allocs: 11.5 kB 0.199 k allocs: 11.5 kB 1

Plots

Full results and plots (download the benchmark-results-* artifacts).

@jpsamaroo
jpsamaroo force-pushed the jps/hierarchical-mp-mr branch from 4a2eeeb to 58a7165 Compare August 20, 2026 23:34
@jpsamaroo
jpsamaroo changed the base branch from jps/mpi-bad-scale-stencil to master August 20, 2026 23:38
@jpsamaroo
jpsamaroo marked this pull request as draft September 4, 2026 23:50
@jpsamaroo
jpsamaroo force-pushed the jps/hierarchical-mp-mr branch 3 times, most recently from f513e22 to f2801a7 Compare September 13, 2026 00:56
@jpsamaroo
jpsamaroo marked this pull request as ready for review September 14, 2026 17:59
jpsamaroo and others added 19 commits September 17, 2026 07:34
…anning

Turning a prepared spec into scheduler thunks needs nothing from the
planner, but it was running inline and accounted for ~40% of per-task
planning cost in a multi-worker region. `AsyncEnqueueQueue` hands each
batch to a submitter task instead, preserving FIFO order (the syncdeps
recorded during planning rely on it) and keeping a synchronous drain for
the two points that need a task to really exist: a value dependency's
`fetch`, and the end of the region. It is used only when there is a
spare thread to submit on, and never under uniform execution, where a
rank's submission runs collectives that must stay ordered against
planning's own.

`DATADEPS_BATCH_LIMIT` goes from 4 to 16, which is where the scheduler
round-trip stops amortizing (256 independent `InOut` tasks over 4
workers: 69 us/task unbatched, 55 at 16, 53.5 unbounded) while still
bounding how far planning runs ahead of execution. Together these take
that region from 31.2 ms to 16.9 ms.

Attributing planning cost is hard from a profile, because the expensive
parts are blocking waits inside communication rather than hot loops, so
this also adds per-phase timing behind `JULIA_DAGGER_HIER_TIMING=1`
(off by default, one `Ref` read per phase) and records what it found in
the module header. The MPI hang warning now carries a backtrace, since
which call site is waiting is the whole diagnosis for a wait cycle.

Co-authored-by: Cursor <cursoragent@cursor.com>
A chunk's aliasing info cannot be computed locally: under Distributed it
is a `remotecall_fetch` to the owner, and under MPI a broadcast from the
owner that every rank must join. Planning asks the same questions
repeatedly -- once per unique argument to build the DAG, again for every
slot, again for the write-back epilogue -- so a region spent hundreds of
round-trips re-deriving a handful of distinct answers. Under MPI each is
a global synchronization point, which is what made replicated planning
scale so poorly with rank count.

Three changes, all invisible to the user:

* `ChunkAinfoMemo`, a per-region memo keyed on argument identity, the
  dependency modifier and the acceleration. Per-region because aliasing
  info describes where a value's memory currently is: stable while one
  region plans, but a later region's chunk may reuse a freed address.
  Keys are rank-uniform, so every rank hits and misses on exactly the
  same calls and the remaining broadcasts are still collective.
* `batch_aliasing` / `batch_ainfos`, which resolve a whole uniform list
  of arguments in one exchange per owning rank rather than one broadcast
  each, and seed the memo with the results. Phase 1 now goes through
  these, so the rest of planning finds its answers already computed.
* Copies made by Datadeps recorded their own destination-side ainfo
  eagerly, costing a second rendezvous per slot on top of the transfer.
  That ainfo only matters when the copy is itself the source of a later
  move, which most regions never do, so copies are now recorded
  unresolved and resolved lazily on the first `derived` miss, as one
  batch. Safe under SPMD because the trigger is uniform.

Slot generation halved for a 4-rank stencil sweep (1.97 -> 0.96
ms/sweep), and the 2-rank MPI test suite went from 12m20s to 10m07s.

Co-authored-by: Cursor <cursoragent@cursor.com>
…t samples

The regressions/improvements lists in the CI report require opening the
report to see, and the "within noise" breakdown was buried behind a
<details> section entirely -- there was no way to tell at a glance which
suite/method jobs actually moved. Add a summary table (job, regression
count, improvement count, within-noise count) at the top of both the
Markdown report and the stdout summary, grouped by the `suite/method`
prefix that the `BENCHMARK` spec already uses to identify one job.

Also bump the default BENCHMARK_SAMPLES from 5 to 7 for less noisy CI
comparisons.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHPKqRaGTGLt7CPKyZGuPe
`mpi_deadlock_detect` timed each wait on its own and threw once one
exceeded 120s. That reads a long wait as a deadlock, but how long a rank
waits for a peer is bounded by the peer's *backlog*, not by anything
about the wait itself -- and `DATADEPS_UNIFORM_DEFER` deliberately lets
that backlog grow, submitting a region's whole task set in one burst so
planning is not interleaved with execution. A non-owner then reaches a
task's `execute!` metadata wait long before the owner starts it, and if
the owner still has to JIT the task body first, one legitimate wait runs
past any fixed timeout.

That is the MPI CPU CI failure: the `@stencil` 4D case (81 blocks x 80
`Wrap()` neighbors, 82 inputs) takes minutes to compile on first use, so
rank 1 aborted the run on a wait that was making perfectly good progress.
The suite passed with the detector disabled, and every stall warning fell
in the first repetition -- the compiling one -- with later repetitions of
the same region clean at ~3s.

Count the cross-rank operations each rank completes (finished requests,
delivered broadcast payloads) and restart a wait's clock whenever that
counter moves. The thresholds then measure a stall rather than a wait. A
real cycle still trips them, once the work that does not depend on it has
drained; verified by a rank waiting on a message that never comes, which
still errors at exactly the timeout.

Wait-loop state moves into an isbits `DeadlockTimer` so the loops keep
allocating nothing, and the two periods pick up env-var overrides, which
is what made the false positive falsifiable in the first place.

2 ranks x 2 threads, test/mpi.jl: 420/446 pass, 10m04s, no warnings
(master: 18m03s; this branch before the fix: exit 1 at 14m42s).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NHPKqRaGTGLt7CPKyZGuPe
…ories

TimespanLogging's typed-category storage (LogCategory/steal_typed, from
"Make TimespanLogging cheap enough to leave on") is a lock-free per-thread
alternative to the custom HierPlanStats struct HIER_TIMING built for itself
because the old TimespanLogging was too slow to measure planning with. It
is now cheap enough to reuse directly.

HierPlanStats (mutable struct with Atomics, a locked samples Dict, and a
ScopedValue to thread it through parallel partition planning) is replaced
by three LogCategory declarations (LogHierPhase/LogHierSlot/LogHierAinfo)
and hier_log!, a thin wrapper around TimespanLogging's internal `_emit`
gated by `HIER_TIMING[]` directly rather than the shared `enable!` bits --
so this diagnostic stays independent of whatever else `enable_logging!`/
`disable_logging!` is doing. report_hier_stats steals this region's events
right after planning finishes and builds the same breakdown the old code
printed. This assumes one region plans at a time (true today), so it's
documented rather than solved with a region id.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GaPaEAUCJMwpQjFFPbU7Ck
Stencil setup launched both input and destination DArrays but waited only for the input. The timed body therefore absorbed a nondeterministic share of destination allocation and scheduling, producing multi-fold Distributed regressions. Materialize both arrays before timing so the benchmark measures only the stencil.
BenchmarkTools applies its seconds budget independently, so rank timing skew let one rank stop while peers entered another collective sample. It also let a fast rank time its wait for a peer's prior GC as part of the next operation. Drive samples in lockstep, barrier before timing, and stop from the maximum per-sample wall time across ranks. A synthetic skew test changed sample counts from [5,2,2,2] to [2,2,2,2]; a four-rank allocation sample measured 1.93 ms instead of CI's spurious 14-35 ms. Declare JSON3 explicitly because both benchmark workers import it.
BenchmarkTools 1.8 changed generated sample functions to write into a Ref. The old internal call failed every MPI leaf, and the worker then reported an empty successful manifest. Dispatch to either sampling API, abort on SPMD leaf failures, and reject missing or empty manifests so CI cannot pass without measurements.\n\nVerified with 4 local ranks: the reduced array matrix now completes 14/14 leaves (previously 0/14 with MethodError).
A 16-task synchronous batch withholds most small Krylov regions until planning finishes, serializing planning against execution on one-thread Distributed drivers. Retain 16 for the asynchronous submitter, where it amortizes handoff overhead, but restore the synchronous batch to 4.\n\nDistributed CG (1024, block 64, 4 processes; one post-warmup run):\n  batch 16: 8.22 s, 16.85M allocs, 832.9 MB\n  batch  8: 7.91 s, 16.59M allocs, 818.6 MB\n  batch  4: 6.92 s, 15.90M allocs, 783.1 MB\n\nThe Distributed datadeps suite passes (1462 pass, 2 broken), as does the allocation suite (19/19).
DArray construction is asynchronous. The sparse SpMV/CG and dense matvec/solve setups waited for their matrix but not their vector, allowing vector creation and placement to leak into the timed operation. Await every fixture before sampling so scheduler changes cannot shift setup work into these measurements.
Multiple disjoint copy tasks were each registered as owner of the whole destination, so a later whole-object consumer could run after only the last-registered copy and be overwritten by a slower sibling. Make the final copy depend on its earlier siblings, preserving their parallelism while making the recorded owner a truthful batch-completion point.\n\nValidated with the four-rank delayed ChunkView race (9/9 repeated passes) and the Distributed datadeps suite (1462 passed, 2 expected broken).
MPI SVD uses a Distributed-only processor grid and dies before sampling. Probe it during suite construction so unsupported revision/backend combinations are omitted, and persist failures from every rank before MPI.Abort so the orchestrator reports the real leaf and CapturedException. Preserve ordinary external-worker exception text as well.\n\nA four-rank end-to-end benchmark smoke produced a nonempty 22-leaf completion manifest with all supported Array, LinearAlgebra, and Stencil leaves.
Define generated stencil kernels and their boundary-condition bindings on every Distributed worker, then use a deterministic cyclic fixture grid only when real Distributed workers exist. This prevents remote UndefVar/world-age failures and stops driver-local BenchmarkTools allocation counts from varying with accidental tile ownership while retaining MPI-aware arbitrary placement under MPI.\n\nExact N=1024 comparisons completed all 16 stencil and 14 array leaves on both revisions: stencil improved 12/16 times and 14/16 memory samples, while array removed the visible allocation regressions and retained the large X+X improvement.
A whole-object consumer must wait for every disjoint remainder copy. Recording only the last copy as whole-object owner loses sibling producers; forcing the last copy to depend on siblings repairs correctness but serializes an otherwise parallel tail. Launch pieces independently, then record one logical whole-object writer backed by a CopyBatchOwner. Expand its physical producers for live writer, history, and free dependencies, while leaving singleton copies on the direct path.

Two-worker 4x4 ChunkView plus whole read/write steady-state GC minima (10 warmups, GC, 5 runs): before e04a672 13,833 allocations / 679,952 bytes; after 14,255 / 706,384 (+422 / +26,432), the cost of explicit fan-in. Allocation suite: 19/19; Distributed datadeps: 1,462 passed, 2 pre-existing broken; four-rank focused race: 8 repetitions passed; full four-rank MPI suite: 443-470 passed per rank.
hier_log! gates event emission but cannot gate evaluation of its arguments. Per-argument aliasing and slot creation still read the clock even with HIER_TIMING=false; guard both start timestamps and duration construction, preserving enabled diagnostics and all scheduling/dependency behavior.

Julia 1.12 GC minima, 10 warmups then GC.gc() and 5 runs, 10,000 four-argument aliasing batches: before and after 160,000 allocations / 5,760,000 bytes; minimum elapsed 11.25 -> 8.63 ms (-23.3%). Timing on/off and identity/general slots: 15 passed. Unmodified allocation bounds: 19 passed.
The task-local vector macro reads a mutable global and infers Any. The newly pooled aliasing-result buffer therefore made every element store a dynamically dispatched boxed Pair; deferred copy-info scratch had the same problem for iteration and batch dispatch. Assert the declared concrete vector types at the use sites, retaining pooling and exactly the same contents and ownership semantics. Check inferred results on sequential and threaded paths.

Julia 1.12 GC minima, 10 warmups then GC.gc() and 5 runs, 10,000 four-argument aliasing batches: 160,000 -> 120,000 allocations (-25%), 5,760,000 -> 3,840,000 bytes (-33.3%), minimum elapsed after gating clocks 8.63 -> 7.56 ms. Scratch/timing tests: 17 passed; allocation suite: 19 passed without changing bounds.
Replicated planning checks the same integer against every peer. MPI.isend serialized that identical value separately for each peer, allocating an IOBuffer and serialization state each time. Reuse one serialized byte vector for all completed nonblocking sends, preserving the reserved tag, peer order, receive wire format, cooperative waits, and deadlock detection. Retain the general raw-parts transport for non-integer values and the no-communication single-rank path.

Four ranks, Julia 1.12, 10 warmups then GC.gc() and 5 measurements of 1,000 checks: 93,000 -> 69,000 allocations (-25.8%), 5,280,000 -> 3,744,000 bytes (-29.1%), minimum elapsed 7.64 -> 7.35 ms. Actual MPI chunk/uniformity tests: 126 passed per rank with two threads; focused mixed-width/BigInt/array/mismatch recovery tests passed with four ranks and with one rank. Both regressed SpGEMM sizes completed 10 warmups and 5 measurements per rank with orderly backend teardown.
Non-const task-local globals erase inference even though reusable_vector and reusable_dict already declare concrete container types. Assert those types before empty! in the macro expansions so every caller retains inferred scratch, and escape supplied type expressions to preserve caller-side name resolution.

Remove redundant datadeps and scheduler call-site assertions. Add inference checks for caller-defined types, aliases, unions, and abstract elements, plus reuse, clearing, and task isolation coverage. Update the scratch inference lesson.

Profile: Julia 1.12.6, 4 threads, 10 warmups, GC.gc(), minimum of 5 Base.gc_num() measurements; each run fills and iterates 1,000 batches of 32 pairs. Vector: 127,979 allocations / 3,583,664 bytes -> 0 / 0. Dict: 128,986 allocations / 3,599,776 bytes -> 0 / 0. code_warntype shows concrete scratch and entry locals with Int return types.

Validation: test/reuse.jl passes (14 new macro checks); test/allocations.jl passes all 19 checks with unchanged bounds; Distributed datadeps passes 2,083 checks with 2 existing expected-broken tests; four-rank, two-thread MPI passes 126 uniformity/chunk checks plus 27 sparse/dense operation checks per rank.
Distributed RPCs do not inherit the driver region memo. Merge remote Phase 1 answers into that memo with the original local chunk/view and dependency modifier keys, so Phase 4 does not ask each owner again. Keep local and MPI batching unchanged; a typed merge barrier restores the RPC result type.

Julia 1.13, one driver thread plus three one-thread workers: a 64-chunk batch/plan probe, after 10 warmups and GC, minimum of 5 Base.gc_num deltas: 18,397 allocations / 822,992 bytes before, 9,118 / 393,128 after. Redundant remote queries drop from 48 to zero; minimum elapsed time drops from 6.262 ms to 1.024 ms.

Validation: Distributed datadeps 2,137 passed, 2 existing broken; allocation suite 19 passed with all bounds unchanged. New memo tests cover local, single-remote, and multiple-owner batches with modifiers and views.
Keep each backend report readable in the combined GitHub comment: summarize the outcomes, then list the individual regressions and improvements, before the full timing/allocation tables and plots. Classification, thresholds, and exit behavior are unchanged.

Validation: 14 rendering assertions pass across reports with and without regressions/improvements, including within-noise entries.
Arbitrary input placement changes data movement and the driver allocation share between samples and revisions. Match the existing array/stencil fixture policy with cyclic rows under Distributed; keep MPI on its native allocator. Pin the SPD destination too: assigning G does not propagate placement through similar(G), so form the SPD fixture with an explicitly assigned destination and mul! in untimed setup.

Measured operations and normal output allocation remain unchanged. No scheduler heuristics, BLAS settings, classification thresholds, allocation bounds, or sample budgets change.

Matched-layout Julia 1.13 check, driver 1 thread plus 3 one-thread workers, BLAS 1: 10 warmups then GC and minimum of 5 Base.gc_num deltas. Master -> branch: SYRK128 302,929 allocs / 30,448,824 bytes -> 274,930 / 29,212,920; matmul512 16,321 / 13,295,376 -> 14,393 / 13,211,776; Cholesky512 19,695 / 15,596,896 -> 19,903 / 15,612,016. Minimum times: 127.59 -> 103.11 ms, 50.36 -> 46.84 ms, 24.01 -> 25.71 ms respectively. Local results are not a guarantee of CI timing.

Validation: 9 Distributed fixture checks, including exact SPD layout and numerical products/factorization; 8 fixture checks on each of 4 MPI ranks, including execution of all three affected benchmark entries.
A shared condition notified every unrelated waiter for each metadata delivery, making a large submitted region pay a quadratic wakeup cost. Give each FIFO a lazily allocated condition sharing the registry lock; retain slots until every consumer leaves, and preserve heartbeat/shutdown notification, including already-woken consumers.

Julia 1.13, one thread: ten warmups, GC.gc(), minimum of five runs delivering 1024 tags: 395.105 ms -> 2.849 ms. Allocation count/bytes: 15375 / 877448 -> 17442 / 1095872 (blocked-only conditions; queued delivery avoids them). Deterministic FIFO, targeted wakeup, heartbeat, multiple-consumer and shutdown tests: 64 pass with four threads. Full SpGEMM timings remain noisy; no batching, scheduling, sampling or thresholds changed.
Uncontended receives now register a lease with nothing; competitors attach a one-shot event under the registry lock. Explicit locked blocks remove captured event boxing. Both receive paths release in finally, including failures.

Julia 1.13, one thread, ten warmups, GC.gc(), min of five 10000-guard runs: 50000 allocations / 1760000 bytes / 0.998 ms -> zero allocations / zero bytes / 0.544 ms. No Core.Box in recv_yield lowering. Four-thread lifecycle tests pass on Julia 1.12 and 1.13. Full four-rank one-thread MPI suite passes (446/473/458/470 tests). Warm SpGEMM loses 2-3 million allocations; concurrent timings are not speedup claims. No scheduling, sampling or thresholds changed.
Temporary completion and placement callers often dispatch once, yet initialized all 32 task-local slots, channels and monitors. Initialize each slot on demand without changing capacity or overflow behavior. Preserve cleared dynamic scope, setup-before-schedule and registration-before-publication; skip unassigned slots during finalization.

Julia 1.13, ten warmups, GC.gc(), minimum of five runs creating 100 single-use 32-slot caches: 75100 allocations / 4004800 bytes / 5.744 ms -> 6800 allocations / 296000 bytes / 0.318 ms. Slot initialization and cached dispatch infer Task returns. Reuse suites pass on Julia 1.12 and 1.13 with four threads; all 19 unchanged allocation-bound/scope checks pass. Final combined fixes pass lifecycle and sparse/dense product, Cholesky and LU reconstruction checks on each of four MPI ranks with two threads. No pool sizing, scheduling, sampling or thresholds changed.
@jpsamaroo
jpsamaroo force-pushed the jps/hierarchical-mp-mr branch from 4958109 to 974f201 Compare September 17, 2026 14:36
The defaults LFU can immediately evict a new frequency-1 entry when its
resident entries are hotter. Those signatures keep taking the dynamically
typed fallback, even after deep warmup. Splat the existing full type vector
for non-keyword signatures rather than its identical view, and avoid
specializing the generic fallback on arguments it never inspects.

Keep custom type-based defaults, keyword filtering, explicit options,
signature representation, cache capacity and eviction policy unchanged.
In particular, do not add a keyword-signature copy on the cached path.
Add custom/default dispatch coverage and a repeated-miss allocation guard
using a fresh task-local cache. Leave existing allocation bounds unchanged.

Julia 1.13, 10 warmups + GC, minimum of 5 Base.gc_num measurements:
- Cold four-type default population: 217 allocs / 9,088 bytes -> 49 / 1,792.
- Cached population: unchanged at 1 alloc / 256 bytes.
- Distributed LU 1024/128: 405,166 / 36,317,096 -> 396,400 / 35,955,080.
- Distributed LU solve 1024/128: 511,038 / 40,974,680 -> 484,016 / 39,796,616.
The Distributed probes use 3 one-thread workers and matched cyclic fixtures.
The actual CI worker setup additionally shows lower allocations for all
four rand cases and LU/solve, with LU/solve memory lower by about 13-14%.
Julia 1.12 also measures 49 / 1,792 for repeated cold default population.

Validated unchanged allocation-suite bounds, option/default and reuse
tests, and Distributed LU/solve correctness on Julia 1.12 and 1.13.
The typed defaults cache still boxed findmin's (frequency, key) result on
every eviction. This is particularly costly for signatures immediately
evicted after insertion: warmup never eliminates those repeated misses.

Scan frequencies directly, initializing from the first entry and updating
only for a strictly smaller frequency. This preserves the original first-
minimum tie breaking, capacity, admission and eviction decisions exactly.
Do not resize caches or change their retention policy.

Add an allocation guard and compare exact values, contents and frequencies
against the original findmin algorithm after mixed hits/misses at capacities
0, 1, 8 and 256. Check empty! too. Leave existing allocation bounds unchanged.

Julia 1.13, 10 warmups + GC, minimum of 5 Base.gc_num measurements:
- 10,000 repeated evictions: 10,000 allocs / 320,000 bytes -> 0 / 0.
- Cold four-type default population: 49 / 1,792 -> 25 / 1,024.
- Cached default population: unchanged at 1 / 256.
Julia 1.12 also measures zero allocations for the eviction probe and
25 / 1,024 for cold default population. A separate 40,000-operation
randomized probe verified exact equivalence to the original eviction code
on both Julia versions.

Validated the complete allocation, option/default and reuse suites with
Distributed workers on Julia 1.13; all allocation bounds remain green.
@jpsamaroo
jpsamaroo merged commit b3155f5 into master Sep 17, 2026
28 of 41 checks passed
@jpsamaroo
jpsamaroo deleted the jps/hierarchical-mp-mr branch September 17, 2026 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant