Adjusted interpolation interval during calculation of "fair performance value" (CDF diagram).

MPARM = 1
NPARM = 2
KPARM = 3
FLOPS = 8

HIM = -1
HIN = HIM
HIK = HIM

BASENAME = "cp2k"
FILENAME = system("sh -c \"echo ${FILENAME}\"")
if (FILENAME eq "") {
  FILENAME = BASENAME."-perf.pdf"
}

FILECOUNT = 1 # initial file number
# MULTI =-1: multiple files; no titles
# MULTI = 0: multiple files with titles
# MULTI = 1: single file with titles
MULTI = system("sh -c \"echo ${MULTI}\"")
if (MULTI eq "") {
  MULTI = 1
}

XFLOPS(M, N, K) = 2.0 * M * N * K
NFLOPS(M, N, K) = XFLOPS(column(M), column(N), column(K))
NBYTES(M, N, K, ELEMSIZE) = ELEMSIZE * (column(M) * column(K) + column(K) * column(N) + column(M) * column(N))
AI(M, N, K, ELEMSIZE) = NFLOPS(M, N, K) / NBYTES(M, N, K, ELEMSIZE)

TIME(M, N, K, F) = NFLOPS(M, N, K) * 1E-9 / column(F)
BW(M, N, K, F, ELEMSIZE) = (column(M) * column(K) + column(K) * column(N)) * ELEMSIZE / (TIME(M, N, K, F) * 1024 * 1024 * 1024)

stats BASENAME."-perf.dat" using (column(MPARM)*column(NPARM)*column(KPARM)) nooutput; MNK = STATS_stddev**(1.0/3.0); MAXMNK = int(STATS_max)
stats BASENAME."-perf.dat" using (log(column(FLOPS))) nooutput; NSAMPLES = STATS_records; GEOFLOPS = exp(STATS_sum/STATS_records)
stats BASENAME."-perf.dat" using FLOPS nooutput; MEDFLOPS = STATS_median; AVGFLOPS = STATS_mean; MINFLOPS = STATS_min; MAXFLOPS = STATS_max
stats BASENAME."-perf.dat" using NPARM nooutput; XN = int(STATS_max)
stats BASENAME."-perf.dat" using ((NFLOPS(MPARM,NPARM,KPARM)<=XFLOPS(13,13,13))?column(FLOPS):1/0) nooutput; BIN1_FLOPS = STATS_mean; BIN1_NSAMPLES = STATS_records
stats BASENAME."-perf.dat" using (((XFLOPS(13,13,13)<NFLOPS(MPARM,NPARM,KPARM))&&(NFLOPS(MPARM,NPARM,KPARM)<=XFLOPS(23,23,23)))?column(FLOPS):1/0) nooutput; BIN2_FLOPS = STATS_mean; BIN2_NSAMPLES = STATS_records
stats BASENAME."-perf.dat" using ((XFLOPS(23,23,23)<NFLOPS(MPARM,NPARM,KPARM))?column(FLOPS):1/0) nooutput; BIN3_FLOPS = STATS_mean; BIN3_NSAMPLES = STATS_records
stats BASENAME."-perf.dat" using ((NFLOPS(MPARM,NPARM,KPARM)<=XFLOPS(13,13,13))?BW(MPARM,NPARM,KPARM,FLOPS,8):1/0) nooutput; BIN1_MEMBW = STATS_mean
stats BASENAME."-perf.dat" using (((XFLOPS(13,13,13)<NFLOPS(MPARM,NPARM,KPARM))&&(NFLOPS(MPARM,NPARM,KPARM)<=XFLOPS(23,23,23)))?BW(MPARM,NPARM,KPARM,FLOPS,8):1/0) nooutput; BIN2_MEMBW = STATS_mean
stats BASENAME."-perf.dat" using ((XFLOPS(23,23,23)<NFLOPS(MPARM,NPARM,KPARM))?BW(MPARM,NPARM,KPARM,FLOPS,8):1/0) nooutput; BIN3_MEMBW = STATS_mean
stats BASENAME."-perf.dat" using (log(AI(MPARM,NPARM,KPARM,8))) nooutput; GEOAI = exp(STATS_sum/STATS_records)
stats BASENAME."-perf.dat" using (AI(MPARM,NPARM,KPARM,8)) nooutput; MEDAI = STATS_median; AVGAI = STATS_mean; MINAI = STATS_min; MAXAI = STATS_max
stats BASENAME."-perf.dat" using (log(BW(MPARM,NPARM,KPARM,FLOPS,8))) nooutput; GEOMEMBW = exp(STATS_sum/STATS_records)
stats BASENAME."-perf.dat" using (BW(MPARM,NPARM,KPARM,FLOPS,8)) nooutput; MEDMEMBW = STATS_median; AVGMEMBW = STATS_mean; MINMEMBW = STATS_min; MAXMEMBW = STATS_max

FORMAT(X) = sprintf("%%.%if", ceil(1.0 / MAX(log10(X), 1) - 1.0))
MAX(A, B) = A < B ? B : A

IX(I1, J1, NJ) = int(MAX(I1 - 1, 0) * NJ + MAX(J1 - 1, 0))
I1(IX, NJ) = int(IX / NJ) + 1
J1(IX, NJ) = int(IX) % NJ + 1

set table BASENAME."-perf-avg.dat"
plot BASENAME."-perf.dat" using (IX(column(MPARM), column(NPARM), XN)):FLOPS smooth unique
unset table
set table BASENAME."-perf-mbw.dat"
plot BASENAME."-perf.dat" using (BW(MPARM,NPARM,KPARM,FLOPS,8)):(1.0) smooth cumulative
unset table
set table BASENAME."-perf-cdf.dat"
plot BASENAME."-perf.dat" using FLOPS:(1.0) smooth cumulative
unset table
stats BASENAME."-perf-cdf.dat" using (("".strcol(3)."" eq "i")?($2):(1/0)) nooutput; FREQSUM = STATS_max; FREQN = STATS_records

if (MULTI==1) {
  set output FILENAME
}

FILEEXT = system("sh -c \"echo ".FILENAME." | sed 's/.\\+\\.\\(.\\+\\)/\\1/'\"")
set terminal FILEEXT
set termoption enhanced
#set termoption font ",12"
save_encoding = GPVAL_ENCODING
set encoding utf8

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Performance (Selected Kernels)" }
set origin -0.03, 0
set pm3d interpolate 0, 0
#set colorbox horizontal user origin 0, 0.1 size 1, 0.1
#set autoscale fix
if (0<HIM) { set xrange [*:HIM] }
if (0<HIN) { set yrange [*:HIN] }
if (0<HIK) { set zrange [*:HIK] }
if (0>HIM) { set xrange [*:MNK] }
if (0>HIN) { set yrange [*:MNK] }
if (0>HIK) { set zrange [*:MNK] }
set xlabel "M"
set ylabel "N" offset -3.0
set zlabel "K" offset 1.0
set ticslevel 0
set cblabel "GFLOP/s" offset 1.5
set format x "%g"; set format y "%g"; set format z "%g"; set format cb "%g"
splot BASENAME."-perf.dat" using MPARM:NPARM:KPARM:FLOPS notitle with points pointtype 7 linetype palette

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Performance (K-Average for ".sprintf("%u Kernels", NSAMPLES).")" }
set origin -0.02, 0
set dgrid3d #9, 9
set pm3d interpolate 0, 0 map
set autoscale fix
set xlabel "M"
set ylabel "N" offset -1.5
set cblabel "GFLOP/s" offset 0.5
set format x "%g"; set format y "%g"; set format cb "%g"
set mxtics 2
splot BASENAME."-perf-avg.dat" using (("".strcol(3)."" eq "i")?(I1($1, XN)):(1/0)):(("".strcol(3)."" eq "i")?(J1($1, XN)):(1/0)):2 notitle with pm3d

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Performance (Average per Bin)" }
set style fill solid 0.4 noborder
set boxwidth 0.5
set grid y2tics linecolor "grey"
unset key
unset xtics
set xtics ("MNK <= 13^3" 0, "13^3 < MNK <= 23^3" 1, "23^3 < MNK" 2) scale 0 offset 0, 0.2
set x2tics ("Small" 0, "Medium" 1, "Larger" 2) scale 0
set xlabel "Problem Size (MNK)"
set ytics format ""
set y2tics nomirror
set y2label "GFLOP/s"
set xrange [-0.5:2.5]
set yrange [0:*]
set autoscale fix
set label sprintf("{/=9 ".FORMAT(BIN1_FLOPS)." GFLOP/s}", BIN1_FLOPS) at 0.0, BIN1_FLOPS centre offset 0, -1 front
set label sprintf("{/=9 ".FORMAT(BIN2_FLOPS)." GFLOP/s}", BIN2_FLOPS) at 1.0, BIN2_FLOPS centre offset 0, -1 front
set label sprintf("{/=9 ".FORMAT(BIN3_FLOPS)." GFLOP/s}", BIN3_FLOPS) at 2.0, BIN3_FLOPS centre offset 0, -1 front
set label sprintf("{/=9 (".FORMAT(BIN1_MEMBW)." GB/s)}", BIN1_MEMBW) at 0.0, BIN1_FLOPS centre offset 0, -2 front
set label sprintf("{/=9 (".FORMAT(BIN2_MEMBW)." GB/s)}", BIN2_MEMBW) at 1.0, BIN2_FLOPS centre offset 0, -2 front
set label sprintf("{/=9 (".FORMAT(BIN3_MEMBW)." GB/s)}", BIN3_MEMBW) at 2.0, BIN3_FLOPS centre offset 0, -2 front
set label sprintf("{/=9 N=%u}", BIN1_NSAMPLES) at 0.0, 0.0 centre offset 0, 0.5 front
set label sprintf("{/=9 N=%u}", BIN2_NSAMPLES) at 1.0, 0.0 centre offset 0, 0.5 front
set label sprintf("{/=9 N=%u}", BIN3_NSAMPLES) at 2.0, 0.0 centre offset 0, 0.5 front
plot  BASENAME."-perf.dat" \
      using (0.0):(BIN1_FLOPS) notitle smooth unique with boxes linetype 1 linecolor "grey", \
  ""  using (1.0):(BIN2_FLOPS) notitle smooth unique with boxes linetype 1 linecolor "grey", \
  ""  using (2.0):(BIN3_FLOPS) notitle smooth unique with boxes linetype 1 linecolor "grey"

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Cummulative Performance Distribution (CDF for ".sprintf("%u Kernels", NSAMPLES).")" }
set xlabel "Probability\n\n{/=9 Min.: ".sprintf(FORMAT(MINFLOPS), MINFLOPS)." GFLOP/s   Geo.: ".sprintf(FORMAT(GEOFLOPS), GEOFLOPS)." GFLOP/s   Med.: ".sprintf(FORMAT(MEDFLOPS), MEDFLOPS)." GFLOP/s   Avg.: ".sprintf(FORMAT(AVGFLOPS), AVGFLOPS)." GFLOP/s   Max.: ".sprintf(FORMAT(MAXFLOPS), MAXFLOPS)." GFLOP/s}"
set ylabel "GB/s"
set y2label "GFLOP/s"
set format x "%g%%"
set format y "%g"
set format y2 "%g"
set ytics nomirror
set y2tics nomirror
set grid x y2 linecolor "grey"
set xrange [0:100]
set yrange [0:*]
set y2range [0:*]
set fit quiet
f(x) = b * x + a
fit f(x) BASENAME."-perf-cdf.dat" using (("".strcol(3)."" eq "i")?(100*$2/FREQSUM):(1/0)):1 via a, b
g(x) = (x - a) / b
x50 = 0.5 * (100 + MAX(0, g(0)))
h(x) = d * x + c
dx = 100 / FREQN
fit [x50-2.0*dx:x50+2.0*dx] h(x) BASENAME."-perf-cdf.dat" using (("".strcol(3)."" eq "i")?(100*$2/FREQSUM):(1/0)):1 via c, d
set arrow from x50, second h(x50) to x50, second 0 front
set arrow from x50, second h(x50) to 100, second h(x50) front
set label sprintf("%.0f%%", x50) at x50, second 0.5 * h(x50) left offset 1 front
set label sprintf(FORMAT(h(x50))." GFLOP/s", h(x50)) at 0.5 * (x50 + 100.0), second h(x50) centre offset 0, -1 front
set key left invert
plot  BASENAME."-perf-mbw.dat" using (("".strcol(3)."" eq "i")?(100*$2/FREQSUM):(1/0)):1 axes x1y1 title "Memory Bandwidth" with lines linecolor "grey", \
      BASENAME."-perf-cdf.dat" using (("".strcol(3)."" eq "i")?(100*$2/FREQSUM):(1/0)):1 axes x1y2 title "Compute Performance" with lines linewidth 2

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Arithmetic Intensity (".sprintf("%u Kernels", NSAMPLES).")" }
set grid x y2 linecolor "grey"
set key left #spacing 0.5
set ytics format ""
set y2tics nomirror
set y2label "GFLOP/s"
#set xlabel "FLOPS/Byte\n\n{/=9 ".sprintf("N: %u", NSAMPLES)."   Min.: ".sprintf("%.1f", MINAI)."   Geo.: ".sprintf("%.1f", GEOAI)."   Med.: ".sprintf("%.1f", MEDAI)."   Avg.: ".sprintf("%.1f", AVGAI)."   Max.: ".sprintf("%.1f", MAXAI)."}"
set xlabel "FLOPS/Byte   (Min.: ".sprintf("%.1f", MINAI)."   Geo.: ".sprintf("%.1f", GEOAI)."   Med.: ".sprintf("%.1f", MEDAI)."   Avg.: ".sprintf("%.1f", AVGAI)."   Max.: ".sprintf("%.1f", MAXAI).")"
set yrange [0:*]
set autoscale fix
plot  BASENAME."-perf.dat" using (AI(MPARM,NPARM,KPARM,8)):FLOPS notitle smooth sbezier with lines linecolor "grey", \
                        "" using (AI(MPARM,NPARM,KPARM,8)):FLOPS notitle smooth unique with points pointtype 7 pointsize 0.2

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Memory Bandwidth Consumption (".sprintf("%u Kernels", NSAMPLES).")" }
set grid x y2 linecolor "grey"
set key left #spacing 0.5
set ytics format ""
set y2tics nomirror
set y2label "GB/s"
set xlabel "Problem Size (MNK^{1/3})\n\n{/=9 Min.: ".sprintf("%.0f GB/s", MINMEMBW)."   Geo.: ".sprintf("%.0f GB/s", GEOMEMBW)."   Med.: ".sprintf("%.0f GB/s", MEDMEMBW)."   Avg.: ".sprintf("%.0f GB/s", AVGMEMBW)."   Max.: ".sprintf("%.0f GB/s", MAXMEMBW)."}"
set yrange [0:*]
set autoscale fix
plot  BASENAME."-perf.dat" using ((column(MPARM)*column(NPARM)*column(KPARM))**(1.0/3.0)):(BW(MPARM,NPARM,KPARM,FLOPS,8)) notitle smooth sbezier with lines linecolor "grey", \
                        "" using ((column(MPARM)*column(NPARM)*column(KPARM))**(1.0/3.0)):(BW(MPARM,NPARM,KPARM,FLOPS,8)) notitle smooth unique with points pointtype 7 pointsize 0.2

MPARM = 1
NPARM = 2
KPARM = 3
FLOPS = 8

HIM = -1
HIN = HIM
HIK = HIM

BASENAME = "cp2k"
FILENAME = system("sh -c \"echo ${FILENAME}\"")
if (FILENAME eq "") {
  FILENAME = BASENAME."-perf.pdf"
}

FILECOUNT = 1 # initial file number
# MULTI =-1: multiple files; no titles
# MULTI = 0: multiple files with titles
# MULTI = 1: single file with titles
MULTI = system("sh -c \"echo ${MULTI}\"")
if (MULTI eq "") {
  MULTI = 1
}

XFLOPS(M, N, K) = 2.0 * M * N * K
NFLOPS(M, N, K) = XFLOPS(column(M), column(N), column(K))
NBYTES(M, N, K, ELEMSIZE) = ELEMSIZE * (column(M) * column(K) + column(K) * column(N) + column(M) * column(N))
AI(M, N, K, ELEMSIZE) = NFLOPS(M, N, K) / NBYTES(M, N, K, ELEMSIZE)

TIME(M, N, K, F) = NFLOPS(M, N, K) * 1E-9 / column(F)
BW(M, N, K, F, ELEMSIZE) = (column(M) * column(K) + column(K) * column(N)) * ELEMSIZE / (TIME(M, N, K, F) * 1024 * 1024 * 1024)

stats BASENAME."-perf.dat" using (column(MPARM)*column(NPARM)*column(KPARM)) nooutput; MNK = STATS_stddev**(1.0/3.0); MAXMNK = int(STATS_max)
stats BASENAME."-perf.dat" using (log(column(FLOPS))) nooutput; NSAMPLES = STATS_records; GEOFLOPS = exp(STATS_sum/STATS_records)
stats BASENAME."-perf.dat" using FLOPS nooutput; MEDFLOPS = STATS_median; AVGFLOPS = STATS_mean; MINFLOPS = STATS_min; MAXFLOPS = STATS_max
stats BASENAME."-perf.dat" using NPARM nooutput; XN = int(STATS_max)
stats BASENAME."-perf.dat" using ((NFLOPS(MPARM,NPARM,KPARM)<=XFLOPS(13,13,13))?column(FLOPS):1/0) nooutput; BIN1_FLOPS = STATS_mean; BIN1_NSAMPLES = STATS_records
stats BASENAME."-perf.dat" using (((XFLOPS(13,13,13)<NFLOPS(MPARM,NPARM,KPARM))&&(NFLOPS(MPARM,NPARM,KPARM)<=XFLOPS(23,23,23)))?column(FLOPS):1/0) nooutput; BIN2_FLOPS = STATS_mean; BIN2_NSAMPLES = STATS_records
stats BASENAME."-perf.dat" using ((XFLOPS(23,23,23)<NFLOPS(MPARM,NPARM,KPARM))?column(FLOPS):1/0) nooutput; BIN3_FLOPS = STATS_mean; BIN3_NSAMPLES = STATS_records
stats BASENAME."-perf.dat" using ((NFLOPS(MPARM,NPARM,KPARM)<=XFLOPS(13,13,13))?BW(MPARM,NPARM,KPARM,FLOPS,8):1/0) nooutput; BIN1_MEMBW = STATS_mean
stats BASENAME."-perf.dat" using (((XFLOPS(13,13,13)<NFLOPS(MPARM,NPARM,KPARM))&&(NFLOPS(MPARM,NPARM,KPARM)<=XFLOPS(23,23,23)))?BW(MPARM,NPARM,KPARM,FLOPS,8):1/0) nooutput; BIN2_MEMBW = STATS_mean
stats BASENAME."-perf.dat" using ((XFLOPS(23,23,23)<NFLOPS(MPARM,NPARM,KPARM))?BW(MPARM,NPARM,KPARM,FLOPS,8):1/0) nooutput; BIN3_MEMBW = STATS_mean
stats BASENAME."-perf.dat" using (log(AI(MPARM,NPARM,KPARM,8))) nooutput; GEOAI = exp(STATS_sum/STATS_records)
stats BASENAME."-perf.dat" using (AI(MPARM,NPARM,KPARM,8)) nooutput; MEDAI = STATS_median; AVGAI = STATS_mean; MINAI = STATS_min; MAXAI = STATS_max
stats BASENAME."-perf.dat" using (log(BW(MPARM,NPARM,KPARM,FLOPS,8))) nooutput; GEOMEMBW = exp(STATS_sum/STATS_records)
stats BASENAME."-perf.dat" using (BW(MPARM,NPARM,KPARM,FLOPS,8)) nooutput; MEDMEMBW = STATS_median; AVGMEMBW = STATS_mean; MINMEMBW = STATS_min; MAXMEMBW = STATS_max

FORMAT(X) = sprintf("%%.%if", ceil(1.0 / MAX(log10(X), 1) - 1.0))
MAX(A, B) = A < B ? B : A

IX(I1, J1, NJ) = int(MAX(I1 - 1, 0) * NJ + MAX(J1 - 1, 0))
I1(IX, NJ) = int(IX / NJ) + 1
J1(IX, NJ) = int(IX) % NJ + 1

set table BASENAME."-perf-avg.dat"
plot BASENAME."-perf.dat" using (IX(column(MPARM), column(NPARM), XN)):FLOPS smooth unique
unset table
set table BASENAME."-perf-mbw.dat"
plot BASENAME."-perf.dat" using (BW(MPARM,NPARM,KPARM,FLOPS,8)):(1.0) smooth cumulative
unset table
set table BASENAME."-perf-cdf.dat"
plot BASENAME."-perf.dat" using FLOPS:(1.0) smooth cumulative
unset table
stats BASENAME."-perf-cdf.dat" using (("".strcol(3)."" eq "i")?($2):(1/0)) nooutput; FREQSUM = STATS_max; FREQN = STATS_records

if (MULTI==1) {
  set output FILENAME
}

FILEEXT = system("sh -c \"echo ".FILENAME." | sed 's/.\\+\\.\\(.\\+\\)/\\1/'\"")
set terminal FILEEXT
set termoption enhanced
#set termoption font ",12"
save_encoding = GPVAL_ENCODING
set encoding utf8

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Performance (Selected Kernels)" }
set origin -0.03, 0
set pm3d interpolate 0, 0
#set colorbox horizontal user origin 0, 0.1 size 1, 0.1
#set autoscale fix
if (0<HIM) { set xrange [*:HIM] }
if (0<HIN) { set yrange [*:HIN] }
if (0<HIK) { set zrange [*:HIK] }
if (0>HIM) { set xrange [*:MNK] }
if (0>HIN) { set yrange [*:MNK] }
if (0>HIK) { set zrange [*:MNK] }
set xlabel "M"
set ylabel "N" offset -3.0
set zlabel "K" offset 1.0
set ticslevel 0
set cblabel "GFLOP/s" offset 1.5
set format x "%g"; set format y "%g"; set format z "%g"; set format cb "%g"
splot BASENAME."-perf.dat" using MPARM:NPARM:KPARM:FLOPS notitle with points pointtype 7 linetype palette

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Performance (K-Average for ".sprintf("%u Kernels", NSAMPLES).")" }
set origin -0.02, 0
set dgrid3d #9, 9
set pm3d interpolate 0, 0 map
set autoscale fix
set xlabel "M"
set ylabel "N" offset -1.5
set cblabel "GFLOP/s" offset 0.5
set format x "%g"; set format y "%g"; set format cb "%g"
set mxtics 2
splot BASENAME."-perf-avg.dat" using (("".strcol(3)."" eq "i")?(I1($1, XN)):(1/0)):(("".strcol(3)."" eq "i")?(J1($1, XN)):(1/0)):2 notitle with pm3d

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Performance (Average per Bin)" }
set style fill solid 0.4 noborder
set boxwidth 0.5
set grid y2tics linecolor "grey"
unset key
unset xtics
set xtics ("MNK <= 13^3" 0, "13^3 < MNK <= 23^3" 1, "23^3 < MNK" 2) scale 0 offset 0, 0.2
set x2tics ("Small" 0, "Medium" 1, "Larger" 2) scale 0
set xlabel "Problem Size (MNK)"
set ytics format ""
set y2tics nomirror
set y2label "GFLOP/s"
set xrange [-0.5:2.5]
set yrange [0:*]
set autoscale fix
set label sprintf("{/=9 ".FORMAT(BIN1_FLOPS)." GFLOP/s}", BIN1_FLOPS) at 0.0, BIN1_FLOPS centre offset 0, -1 front
set label sprintf("{/=9 ".FORMAT(BIN2_FLOPS)." GFLOP/s}", BIN2_FLOPS) at 1.0, BIN2_FLOPS centre offset 0, -1 front
set label sprintf("{/=9 ".FORMAT(BIN3_FLOPS)." GFLOP/s}", BIN3_FLOPS) at 2.0, BIN3_FLOPS centre offset 0, -1 front
set label sprintf("{/=9 (".FORMAT(BIN1_MEMBW)." GB/s)}", BIN1_MEMBW) at 0.0, BIN1_FLOPS centre offset 0, -2 front
set label sprintf("{/=9 (".FORMAT(BIN2_MEMBW)." GB/s)}", BIN2_MEMBW) at 1.0, BIN2_FLOPS centre offset 0, -2 front
set label sprintf("{/=9 (".FORMAT(BIN3_MEMBW)." GB/s)}", BIN3_MEMBW) at 2.0, BIN3_FLOPS centre offset 0, -2 front
set label sprintf("{/=9 N=%u}", BIN1_NSAMPLES) at 0.0, 0.0 centre offset 0, 0.5 front
set label sprintf("{/=9 N=%u}", BIN2_NSAMPLES) at 1.0, 0.0 centre offset 0, 0.5 front
set label sprintf("{/=9 N=%u}", BIN3_NSAMPLES) at 2.0, 0.0 centre offset 0, 0.5 front
plot  BASENAME."-perf.dat" \
      using (0.0):(BIN1_FLOPS) notitle smooth unique with boxes linetype 1 linecolor "grey", \
  ""  using (1.0):(BIN2_FLOPS) notitle smooth unique with boxes linetype 1 linecolor "grey", \
  ""  using (2.0):(BIN3_FLOPS) notitle smooth unique with boxes linetype 1 linecolor "grey"

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Cummulative Performance Distribution (CDF for ".sprintf("%u Kernels", NSAMPLES).")" }
set xlabel "Probability\n\n{/=9 Min.: ".sprintf(FORMAT(MINFLOPS), MINFLOPS)." GFLOP/s   Geo.: ".sprintf(FORMAT(GEOFLOPS), GEOFLOPS)." GFLOP/s   Med.: ".sprintf(FORMAT(MEDFLOPS), MEDFLOPS)." GFLOP/s   Avg.: ".sprintf(FORMAT(AVGFLOPS), AVGFLOPS)." GFLOP/s   Max.: ".sprintf(FORMAT(MAXFLOPS), MAXFLOPS)." GFLOP/s}"
set ylabel "GB/s"
set y2label "GFLOP/s"
set format x "%g%%"
set format y "%g"
set format y2 "%g"
set ytics nomirror
set y2tics nomirror
set grid x y2 linecolor "grey"
set xrange [0:100]
set yrange [0:*]
set y2range [0:*]
set fit quiet
f(x) = b * x + a
fit f(x) BASENAME."-perf-cdf.dat" using (("".strcol(3)."" eq "i")?(100*$2/FREQSUM):(1/0)):1 via a, b
g(x) = (x - a) / b
x50 = 0.5 * (100 + MAX(0, g(0)))
h(x) = d * x + c
dx = 100 / FREQN
fit [x50-1.5*dx:x50+1.5*dx] h(x) BASENAME."-perf-cdf.dat" using (("".strcol(3)."" eq "i")?(100*$2/FREQSUM):(1/0)):1 via c, d
set arrow from x50, second h(x50) to x50, second 0 front
set arrow from x50, second h(x50) to 100, second h(x50) front
set label sprintf("%.0f%%", x50) at x50, second 0.5 * h(x50) left offset 1 front
set label sprintf(FORMAT(h(x50))." GFLOP/s", h(x50)) at 0.5 * (x50 + 100.0), second h(x50) centre offset 0, -1 front
set key left invert
plot  BASENAME."-perf-mbw.dat" using (("".strcol(3)."" eq "i")?(100*$2/FREQSUM):(1/0)):1 axes x1y1 title "Memory Bandwidth" with lines linecolor "grey", \
      BASENAME."-perf-cdf.dat" using (("".strcol(3)."" eq "i")?(100*$2/FREQSUM):(1/0)):1 axes x1y2 title "Compute Performance" with lines linewidth 2

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Arithmetic Intensity (".sprintf("%u Kernels", NSAMPLES).")" }
set grid x y2 linecolor "grey"
set key left #spacing 0.5
set ytics format ""
set y2tics nomirror
set y2label "GFLOP/s"
#set xlabel "FLOPS/Byte\n\n{/=9 ".sprintf("N: %u", NSAMPLES)."   Min.: ".sprintf("%.1f", MINAI)."   Geo.: ".sprintf("%.1f", GEOAI)."   Med.: ".sprintf("%.1f", MEDAI)."   Avg.: ".sprintf("%.1f", AVGAI)."   Max.: ".sprintf("%.1f", MAXAI)."}"
set xlabel "FLOPS/Byte   (Min.: ".sprintf("%.1f", MINAI)."   Geo.: ".sprintf("%.1f", GEOAI)."   Med.: ".sprintf("%.1f", MEDAI)."   Avg.: ".sprintf("%.1f", AVGAI)."   Max.: ".sprintf("%.1f", MAXAI).")"
set yrange [0:*]
set autoscale fix
plot  BASENAME."-perf.dat" using (AI(MPARM,NPARM,KPARM,8)):FLOPS notitle smooth sbezier with lines linecolor "grey", \
                        "" using (AI(MPARM,NPARM,KPARM,8)):FLOPS notitle smooth unique with points pointtype 7 pointsize 0.2

reset
if (MULTI<=0) { set output "".FILECOUNT."-".FILENAME; FILECOUNT = FILECOUNT + 1 }
if (MULTI>-1) { set title "Memory Bandwidth Consumption (".sprintf("%u Kernels", NSAMPLES).")" }
set grid x y2 linecolor "grey"
set key left #spacing 0.5
set ytics format ""
set y2tics nomirror
set y2label "GB/s"
set xlabel "Problem Size (MNK^{1/3})\n\n{/=9 Min.: ".sprintf("%.0f GB/s", MINMEMBW)."   Geo.: ".sprintf("%.0f GB/s", GEOMEMBW)."   Med.: ".sprintf("%.0f GB/s", MEDMEMBW)."   Avg.: ".sprintf("%.0f GB/s", AVGMEMBW)."   Max.: ".sprintf("%.0f GB/s", MAXMEMBW)."}"
set yrange [0:*]
set autoscale fix
plot  BASENAME."-perf.dat" using ((column(MPARM)*column(NPARM)*column(KPARM))**(1.0/3.0)):(BW(MPARM,NPARM,KPARM,FLOPS,8)) notitle smooth sbezier with lines linecolor "grey", \
                        "" using ((column(MPARM)*column(NPARM)*column(KPARM))**(1.0/3.0)):(BW(MPARM,NPARM,KPARM,FLOPS,8)) notitle smooth unique with points pointtype 7 pointsize 0.2


tests: gnuplot script: improve style

tests: gnuplot script: improve style

if (!exists("unrelfile")) unrelfile='out1.txt'
if (!exists("relfile")) relfile='out2.txt'
if (!exists("mytitle")) mytitle='Throughput tests'

set title mytitle
set xlabel "Packet size (bytes)"
set ylabel "Throughput (Gbps)"
set grid xtics lw 1 lt 0
set grid ytics lw 1 lt 0
set xtics 0,100,1500
set ytics 0,1,13
set key left top
plot unrelfile using 1:($7/1000) title 'Unreliable sender' with linespoints lw 2 ps 1 pt 6 lt rgb "red", \
     unrelfile using 1:($9/1000) title 'Unreliable receiver' with linespoints lw 2 ps 1 pt 6 lt rgb "#00AA00", \
     relfile using 1:($7/1000) title 'Reliable sender/receiver' with linespoints lw 2 ps 1 pt 6 lt rgb "blue"
pause -1

if (!exists("unrelfile")) unrelfile='out1.txt'
if (!exists("relfile")) relfile='out2.txt'

set title "Throughput tests"
set xlabel "Packet size (bytes)"
set ylabel "Throughput (Gbps)"
set grid xtics lw 1 lt 0
set grid ytics lw 1 lt 0
set xtics 0,100,1500
set ytics 0,1,13
set key left top
plot unrelfile using 1:($7/1000) title 'Unreliable sender' with linespoints, unrelfile using 1:($9/1000) title 'Unreliable receiver' with linespoints, relfile using 1:($7/1000) title 'Reliable sender/receiver' with linespoints,
pause -1


Update concurrency_pipeline.gnu

Update concurrency_pipeline.gnu

reset
set title "Benchmark of concurrency 100, 1000, 5000 (pipelining)"
set boxwidth 0.9
set datafile separator ","
set style data histogram
set style histogram clustered gap 2
set style fill solid 0.7 border
set border lw 0.8

set ylabel "requests / second"
set xtics nomirror rotate by -45
set ytics nomirror

set border 1+2 back
set boxwidth -2

set grid

set term pngcairo font "Times Roman,14"  enhanced size 1024,600 background rgb "gray80"
set output "../concurrency-pipeline.png"

plot 't_concurrency-pipeline.csv' using 2:xticlabels(1) title columnheader(2), '' using 3:xticlabels(1) title columnheader(3), '' using 4:xticlabels(1) title columnheader(4)

reset
set title "Benchmark of concurrency 100, 1000, 5000 (pipelining)"
set boxwidth 0.9
set datafile separator ","
set style data histogram
set style histogram clustered gap 2
set style fill solid 0.7 border
set border lw 0.8

set ylabel "millisecond"
set xtics nomirror rotate by -45
set ytics nomirror

set border 1+2 back
set boxwidth -2

set grid

set term pngcairo font "Times Roman,14"  enhanced size 1024,600 background rgb "gray80"
set output "../concurrency-pipeline.png"

plot 't_concurrency-pipeline.csv' using 2:xticlabels(1) title columnheader(2), '' using 3:xticlabels(1) title columnheader(3), '' using 4:xticlabels(1) title columnheader(4)


formatting cleanup

formatting cleanup

git-svn-id: 69a08f0be502e23ba71eb4e212ee2948ff83149c@340 4e380d45-d1fd-0310-85a7-d18ec86df0ad

# This -*- Makefile -*- is intended for processing with GNU make.

# Change this file according to your paths.

# Instead of modifying this file, you could also set your modified variables
# in make.settings.local (needs to be created first).
-include $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))make.settings.local

USE_BOOST	?= no	# set 'yes' to use Boost libraries or 'no' to not use Boost libraries
USE_LINUX	?= yes	# set 'yes' if you run Linux, 'no' otherwise
USE_MCSTL	?= no	# will be overriden from main Makefile
USE_ICPC	?= no	# will be overriden from main Makefile

STXXL_ROOT	?= $(HOME)/work/stxxl

ifeq ($(strip $(USE_ICPC)),yes)
COMPILER	?= icpc
OPENMPFLAG	?= -openmp
endif

ifeq ($(strip $(USE_MCSTL)),yes)
COMPILER	?= g++-4.2
OPENMPFLAG	?= -fopenmp
LIBNAME		?= mcstxxl
# the base directory of your MCSTL installation
MCSTL_BASE	?= $(HOME)/work/mcstl
# mcstl branch, leave empty for default branch (e.g. if installed from release tarball)
MCSTL_BRANCH	?= #branches/standalone
# only set the following variables if autodetection does not work:
#MCSTL_ROOT		?= $(MCSTL_BASE)/$(MCSTL_BRANCH)
#MCSTL_ORIGINAL_INC_CXX	?= /path/to/your/$(COMPILER)'s/include/c++
#MCSTL_ORIGINALS	?= /where/you/put/the/original/symlink
endif

BOOST_INCLUDE	?= /usr/include/boost-1_33

COMPILER	?= g++
LINKER		?= $(COMPILER)
OPT		?= -O3 # compiler optimization level
WARNINGS	?= -Wall
DEBUG		?= # put here -g option to include the debug information into the binaries

LIBNAME		?= stxxl

#### TROUBLESHOOTING
#
# For automatical checking of order of the output elements in
# the sorters: stxxl::stream::sort, stxxl::stream::merge_runs,
# stxxl::sort, and stxxl::ksort use
#
#STXXL_SPECIFIC	+= -DSTXXL_CHECK_ORDER_IN_SORTS
#
# If your program aborts with message "read/write: wrong parameter"
# or "Invalid argument"
# this could be that your kernel does not support direct I/O
# then try to set it off recompiling the libs and your code with option
#
#STXXL_SPECIFIC	+= -DSTXXL_DIRECT_IO_OFF
#
# But for the best performance it is strongly recommended
# to reconfigure the kernel for the support of the direct I/O.
#
# FIXME: documentation needed
#
#STXXL_SPECIFIC += -DSTXXL_DEBUGMON

#### You usually shouldn't need to change the sections below #####

#### STXXL OPTIONS ###############################################

STXXL_SPECIFIC	+= \
	-DSORT_OPT_PREFETCHING \
	-DUSE_MALLOC_LOCK \
	-DCOUNT_WAIT_TIME \
	-I$(strip $(STXXL_ROOT)) \
	-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
	$(POSIX_MEMALIGN) $(XOPEN_SOURCE)

STXXL_LDLIBS	+= -L$(strip $(STXXL_ROOT))/lib -l$(LIBNAME) -lpthread

STXXL_LIBDEPS	+= $(strip $(STXXL_ROOT))/lib/lib$(LIBNAME).$(LIBEXT)

##################################################################

#### ICPC OPTIONS ################################################

ifeq ($(strip $(USE_ICPC)),yes)

endif

##################################################################

#### MCSTL OPTIONS ###############################################

ifeq ($(strip $(USE_MCSTL)),yes)

# find a KEY=VALUE element in WORDS and return VALUE
# usage: $(call get_value,KEY,WORDS)
get_value		 = $(subst $(1)=,,$(filter $(1)=%,$(2)))
empty			 =#
space			 = $(empty) $(empty)
gcc_version_result	:= $(shell $(COMPILER) -v 2>&1)
gcc_version		 = $(call get_value,THE_GCC_VERSION,$(subst gcc$(space)version$(space),THE_GCC_VERSION=,$(gcc_version_result)))
gcc_prefix		 = $(call get_value,--prefix,$(gcc_version_result))
gcc_gxx_incdir		 = $(call get_value,--with-gxx-include-dir,$(gcc_version_result))
MCSTL_ORIGINAL_INC_CXX	?= $(firstword $(wildcard $(gcc_gxx_incdir) $(gcc_prefix)/include/c++/$(gcc_version)) $(cxx_incdir_from_compile))
ifeq (,$(strip $(MCSTL_ORIGINAL_INC_CXX)))
# do a test compilation, generate dependencies and parse the header paths
compile_test_vector_deps:= $(shell echo -e '\043include <vector>' > cxx-header-path-test.cpp; $(COMPILER) -M cxx-header-path-test.cpp 2>/dev/null; $(RM) cxx-header-path-test.cpp)
cxx_incdir_from_compile	 = $(patsubst %/vector,%,$(firstword $(filter %/vector, $(compile_test_vector_deps))))
export cxx_incdir_from_compile
endif
MCSTL_ORIGINALS		?= $(strip $(MCSTL_BASE))/originals/$(subst /,_,$(MCSTL_ORIGINAL_INC_CXX))
MCSTL_ROOT		?= $(strip $(MCSTL_BASE))$(if $(strip $(MCSTL_BRANCH)),/$(strip $(MCSTL_BRANCH)))

ifeq (,$(strip $(wildcard $(MCSTL_ROOT)/c++/mcstl.h)))
$(error ERROR: could not find a MCSTL installation in MCSTL_ROOT=$(MCSTL_ROOT))
endif
ifeq (,$(strip $(MCSTL_ORIGINAL_INC_CXX)))
$(error ERROR: could not determine MCSTL_ORIGINAL_INC_CXX, please set this variable manually, it's your compilers ($(COMPILER)) include/c++ path)
endif
ifeq (,$(strip $(wildcard $(MCSTL_ORIGINALS)/original)))
$(error ERROR: your mcstl in $(MCSTL_BASE) is not configured properly: $(MCSTL_ORIGINALS)/original does not exist)
endif

MCSTL_CPPFLAGS		+= $(OPENMPFLAG) -I$(MCSTL_ROOT)/c++ -I$(MCSTL_ORIGINALS) -D__MCSTL__
MCSTL_LDFLAGS		+= $(OPENMPFLAG)

endif

##################################################################

#### BOOST OPTIONS ###############################################

BOOST_COMPILER_OPTIONS	 = \
	-DSTXXL_BOOST_TIMESTAMP \
	-DSTXXL_BOOST_CONFIG \
	-DSTXXL_BOOST_FILESYSTEM \
	-DSTXXL_BOOST_THREADS \
	-DSTXXL_BOOST_RANDOM \
	-I$(strip $(BOOST_INCLUDE)) \
	-pthread

BOOST_LINKER_OPTIONS	 = \
	-lboost_thread-gcc-mt \
	-lboost_date_time-gcc-mt \
	-lboost_iostreams-gcc-mt \
	-lboost_filesystem-gcc-mt

##################################################################

#### DEPENDENCIES ################################################

HEADER_FILES_BITS	+= namespace.h

HEADER_FILES_COMMON	+= aligned_alloc.h mutex.h rand.h semaphore.h state.h
HEADER_FILES_COMMON	+= timer.h utils.h gprof.h rwlock.h simple_vector.h
HEADER_FILES_COMMON	+= switch.h tmeta.h log.h exceptions.h debug.h tuple.h
HEADER_FILES_COMMON	+= utils_ledasm.h

HEADER_FILES_IO		+= completion_handler.h io.h iobase.h iostats.h
HEADER_FILES_IO		+= mmap_file.h simdisk_file.h syscall_file.h
HEADER_FILES_IO		+= ufs_file.h wincall_file.h wfs_file.h boostfd_file.h

HEADER_FILES_MNG	+= adaptor.h async_schedule.h block_prefetcher.h
HEADER_FILES_MNG	+= buf_istream.h buf_ostream.h buf_writer.h mng.h
HEADER_FILES_MNG	+= write_pool.h prefetch_pool.h

HEADER_FILES_CONTAINERS	+= pager.h stack.h vector.h priority_queue.h queue.h
HEADER_FILES_CONTAINERS	+= map.h deque.h

HEADER_FILES_CONTAINERS_BTREE	+= btree.h iterator_map.h leaf.h node_cache.h
HEADER_FILES_CONTAINERS_BTREE	+= root_node.h node.h btree_pager.h iterator.h

HEADER_FILES_ALGO	+= adaptor.h inmemsort.h intksort.h run_cursor.h sort.h
HEADER_FILES_ALGO	+= async_schedule.h interleaved_alloc.h ksort.h
HEADER_FILES_ALGO	+= losertree.h scan.h stable_ksort.h random_shuffle.h

HEADER_FILES_STREAM	+= stream.h sort_stream.h

HEADER_FILES_UTILS	+= malloc.h

###################################################################

#### MISC #########################################################

DEPEXT	 = $(LIBNAME).d # extension of dependency files
OBJEXT	 = $(LIBNAME).o	# extension of object files
LIBEXT	 = a		# static library file extension
EXEEXT	 = $(LIBNAME).bin # executable file extension
RM	 = rm -f	# remove file command
LIBGEN	 = ar cr	# library generation
OUT	 = -o		# output file option for the compiler and linker

d	?= $(strip $(DEPEXT))
o	?= $(strip $(OBJEXT))
bin	?= $(strip $(EXEEXT))

###################################################################

#### COMPILE/LINK RULES ###########################################

%.$o: %.cpp ../make.settings
	@$(RM) $*.$d
	$(COMPILER) $(STXXL_COMPILER_OPTIONS) -MD -MF $*.$dT -c $(OUTPUT_OPTION) $< && mv $*.$dT $*.$d

LINK_STXXL	 = $(LINKER) $1 $(STXXL_LINKER_OPTIONS) -o $@

%.$(bin): %.$o $(STXXL_LIBDEPS)
	$(call LINK_STXXL, $<)

###################################################################

STXXL_COMPILER_OPTIONS	+= $(STXXL_SPECIFIC)
STXXL_COMPILER_OPTIONS	+= $(OPT) $(DEBUG) $(WARNINGS)
STXXL_LINKER_OPTIONS	+= $(STXXL_LDLIBS)

ifeq ($(strip $(USE_MCSTL)),yes)
STXXL_COMPILER_OPTIONS	+= $(MCSTL_CPPFLAGS)
STXXL_LINKER_OPTIONS	+= $(MCSTL_LDFLAGS)
endif

ifeq ($(strip $(USE_BOOST)),yes)
STXXL_COMPILER_OPTIONS	+= $(BOOST_COMPILER_OPTIONS)
STXXL_LINKER_OPTIONS	+= $(BOOST_LINKER_OPTIONS)
endif

STXXL_COMPILER_OPTIONS	+= $(CPPFLAGS)

# vim: syn=make

# This -*- Makefile -*- is intended for processing with GNU make.

# Change this file according to your paths.

# Instead of modifying this file, you could also set your modified variables
# in make.settings.local (needs to be created first).
-include $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))make.settings.local

USE_BOOST	?= no	# set 'yes' to use Boost libraries or 'no' to not use Boost libraries
USE_LINUX	?= yes	# set 'yes' if you run Linux, 'no' otherwise
USE_MCSTL	?= no	# will be overriden from main Makefile
USE_ICPC	?= no	# will be overriden from main Makefile

STXXL_ROOT	?= $(HOME)/work/stxxl

ifeq ($(strip $(USE_ICPC)),yes)
COMPILER	?= icpc
OPENMPFLAG	?= -openmp
endif

ifeq ($(strip $(USE_MCSTL)),yes)
COMPILER	?= g++-4.2
OPENMPFLAG	?= -fopenmp
LIBNAME		?= mcstxxl
# the base directory of your MCSTL installation
MCSTL_BASE	?= $(HOME)/work/mcstl
# mcstl branch, leave empty for default branch (e.g. if installed from release tarball)
MCSTL_BRANCH	?= #branches/standalone
# only set the following variables if autodetection does not work:
#MCSTL_ROOT		?= $(MCSTL_BASE)/$(MCSTL_BRANCH)
#MCSTL_ORIGINAL_INC_CXX	?= /path/to/your/$(COMPILER)'s/include/c++
#MCSTL_ORIGINALS	?= /where/you/put/the/original/symlink
endif

BOOST_INCLUDE	?= /usr/include/boost-1_33

COMPILER	?= g++
LINKER		?= $(COMPILER)
OPT		?= -O3 # compiler optimization level
WARNINGS	?= -Wall
DEBUG		?= # put here -g option to include the debug information into the binaries

LIBNAME		?= stxxl

#### TROUBLESHOOTING
#
# For automatical checking of order of the output elements in
# the sorters: stxxl::stream::sort, stxxl::stream::merge_runs,
# stxxl::sort, and stxxl::ksort use
#
#STXXL_SPECIFIC	+= -DSTXXL_CHECK_ORDER_IN_SORTS
#
# If your program aborts with message "read/write: wrong parameter"
# or "Invalid argument"
# this could be that your kernel does not support direct I/O
# then try to set it off recompiling the libs and your code with option
#
#STXXL_SPECIFIC	+= -DSTXXL_DIRECT_IO_OFF
#
# But for the best performance it is strongly recommended
# to reconfigure the kernel for the support of the direct I/O.
#
# FIXME: documentation needed
#
#STXXL_SPECIFIC += -DSTXXL_DEBUGMON

#### You usually shouldn't need to change the sections below #####

#### STXXL OPTIONS ###############################################

STXXL_SPECIFIC	+= \
	-DSORT_OPT_PREFETCHING \
	-DUSE_MALLOC_LOCK \
	-DCOUNT_WAIT_TIME \
	-I$(strip $(STXXL_ROOT)) \
	-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
	$(POSIX_MEMALIGN) $(XOPEN_SOURCE)

STXXL_LDLIBS	+= -L$(strip $(STXXL_ROOT))/lib -l$(LIBNAME) -lpthread

STXXL_LIBDEPS	+= $(strip $(STXXL_ROOT))/lib/lib$(LIBNAME).$(LIBEXT)

##################################################################

#### ICPC OPTIONS ################################################

ifeq ($(strip $(USE_ICPC)),yes)

endif

##################################################################

#### MCSTL OPTIONS ###############################################

ifeq ($(strip $(USE_MCSTL)),yes)

# find a KEY=VALUE element in WORDS and return VALUE
# usage: $(call get_value,KEY,WORDS)
get_value		 = $(subst $(1)=,,$(filter $(1)=%,$(2)))
empty			 =#
space			 = $(empty) $(empty)
gcc_version_result	:= $(shell $(COMPILER) -v 2>&1)
gcc_version		 = $(call get_value,THE_GCC_VERSION,$(subst gcc$(space)version$(space),THE_GCC_VERSION=,$(gcc_version_result)))
gcc_prefix		 = $(call get_value,--prefix,$(gcc_version_result))
gcc_gxx_incdir		 = $(call get_value,--with-gxx-include-dir,$(gcc_version_result))
MCSTL_ORIGINAL_INC_CXX	?= $(firstword $(wildcard $(gcc_gxx_incdir) $(gcc_prefix)/include/c++/$(gcc_version)) $(cxx_incdir_from_compile))
ifeq (,$(strip $(MCSTL_ORIGINAL_INC_CXX)))
# do a test compilation, generate dependencies and parse the header paths
compile_test_vector_deps:= $(shell echo -e '\043include <vector>' > cxx-header-path-test.cpp; $(COMPILER) -M cxx-header-path-test.cpp 2>/dev/null; $(RM) cxx-header-path-test.cpp)
cxx_incdir_from_compile	 = $(patsubst %/vector,%,$(firstword $(filter %/vector, $(compile_test_vector_deps))))
export cxx_incdir_from_compile
endif
MCSTL_ORIGINALS		?= $(strip $(MCSTL_BASE))/originals/$(subst /,_,$(MCSTL_ORIGINAL_INC_CXX))
MCSTL_ROOT		?= $(strip $(MCSTL_BASE))$(if $(strip $(MCSTL_BRANCH)),/$(strip $(MCSTL_BRANCH)))

ifeq (,$(strip $(wildcard $(MCSTL_ROOT)/c++/mcstl.h)))
$(error ERROR: could not find a MCSTL installation in MCSTL_ROOT=$(MCSTL_ROOT))
endif
ifeq (,$(strip $(MCSTL_ORIGINAL_INC_CXX)))
$(error ERROR: could not determine MCSTL_ORIGINAL_INC_CXX, please set this variable manually, it's your compilers ($(COMPILER)) include/c++ path)
endif
ifeq (,$(strip $(wildcard $(MCSTL_ORIGINALS)/original)))
$(error ERROR: your mcstl in $(MCSTL_BASE) is not configured properly: $(MCSTL_ORIGINALS)/original does not exist)
endif

MCSTL_CPPFLAGS		+= $(OPENMPFLAG) -I$(MCSTL_ROOT)/c++ -I$(MCSTL_ORIGINALS) -D__MCSTL__
MCSTL_LDFLAGS		+= $(OPENMPFLAG)

endif

##################################################################

#### BOOST OPTIONS ###############################################

BOOST_LINKER_OPTIONS = -lboost_thread-gcc-mt \
 -lboost_date_time-gcc-mt -lboost_iostreams-gcc-mt \
 -lboost_filesystem-gcc-mt

BOOST_COMPILER_OPTIONS =  \
 -DSTXXL_BOOST_TIMESTAMP \
 -DSTXXL_BOOST_CONFIG \
 -DSTXXL_BOOST_FILESYSTEM \
 -DSTXXL_BOOST_THREADS \
 -DSTXXL_BOOST_RANDOM \
 -I$(strip $(BOOST_INCLUDE)) \
 -pthread

##################################################################

#### DEPENDENCIES ################################################

HEADER_FILES_BITS	+= namespace.h

HEADER_FILES_COMMON	+= aligned_alloc.h mutex.h rand.h semaphore.h state.h
HEADER_FILES_COMMON	+= timer.h utils.h gprof.h rwlock.h simple_vector.h
HEADER_FILES_COMMON	+= switch.h tmeta.h log.h exceptions.h debug.h tuple.h
HEADER_FILES_COMMON	+= utils_ledasm.h

HEADER_FILES_IO		+= completion_handler.h io.h iobase.h iostats.h
HEADER_FILES_IO		+= mmap_file.h simdisk_file.h syscall_file.h
HEADER_FILES_IO		+= ufs_file.h wincall_file.h wfs_file.h boostfd_file.h

HEADER_FILES_MNG	+= adaptor.h async_schedule.h block_prefetcher.h
HEADER_FILES_MNG	+= buf_istream.h buf_ostream.h buf_writer.h mng.h
HEADER_FILES_MNG	+= write_pool.h prefetch_pool.h

HEADER_FILES_CONTAINERS	+= pager.h stack.h vector.h priority_queue.h queue.h
HEADER_FILES_CONTAINERS	+= map.h deque.h

HEADER_FILES_CONTAINERS_BTREE	+= btree.h iterator_map.h leaf.h node_cache.h
HEADER_FILES_CONTAINERS_BTREE	+= root_node.h node.h btree_pager.h iterator.h

HEADER_FILES_ALGO	+= adaptor.h inmemsort.h intksort.h run_cursor.h sort.h
HEADER_FILES_ALGO	+= async_schedule.h interleaved_alloc.h ksort.h
HEADER_FILES_ALGO	+= losertree.h scan.h stable_ksort.h random_shuffle.h

HEADER_FILES_STREAM	+= stream.h sort_stream.h

HEADER_FILES_UTILS	+= malloc.h

###################################################################

###### MISC #######################################################

DEPEXT	 = $(LIBNAME).d # extension of dependency files
OBJEXT	 = $(LIBNAME).o	# extension of object files
LIBEXT	 = a		# static library file extension
EXEEXT	 = $(LIBNAME).bin # executable file extension
RM	 = rm -f	# remove file command
LIBGEN	 = ar cr	# library generation
OUT	 = -o		# output file option for the compiler and linker

d	?= $(strip $(DEPEXT))
o	?= $(strip $(OBJEXT))
bin	?= $(strip $(EXEEXT))

###################################################################

###### COMPILE/LINK RULES #########################################

%.$o: %.cpp ../make.settings
	@$(RM) $*.$d
	$(COMPILER) $(STXXL_COMPILER_OPTIONS) -MD -MF $*.$dT -c $(OUTPUT_OPTION) $< && mv $*.$dT $*.$d

LINK_STXXL	 = $(LINKER) $1 $(STXXL_LINKER_OPTIONS) -o $@

%.$(bin): %.$o $(STXXL_LIBDEPS)
	$(call LINK_STXXL, $<)

###################################################################

STXXL_COMPILER_OPTIONS	+= $(STXXL_SPECIFIC)
STXXL_COMPILER_OPTIONS	+= $(OPT) $(DEBUG) $(WARNINGS)
STXXL_LINKER_OPTIONS	+= $(STXXL_LDLIBS)

ifeq ($(strip $(USE_MCSTL)),yes)
STXXL_COMPILER_OPTIONS	+= $(MCSTL_CPPFLAGS)
STXXL_LINKER_OPTIONS	+= $(MCSTL_LDFLAGS)
endif

ifeq ($(strip $(USE_BOOST)),yes)
STXXL_COMPILER_OPTIONS	+= $(BOOST_COMPILER_OPTIONS)
STXXL_LINKER_OPTIONS	+= $(BOOST_LINKER_OPTIONS)
endif

STXXL_COMPILER_OPTIONS	+= $(CPPFLAGS)

# vim: syn=make


Tweaked analyze_res.plt.

Tweaked analyze_res.plt.

# terminal 0, PostScript 1, PDF 2.
term_type = 2

home_dir_1 = "/home/johan/tlm_workspace/TLM_JB/"
home_dir_2 = "/home/johan/git_repos/jmbgsddb/build/src/"
home_dir_3 = "/home/johan/git_repos/jmbgsddb/python/cavity_model/"

file_name_1 = home_dir_1."MCSModelCenVec.txt"
file_name_2 = home_dir_1."MCSModelRf.txt"
file_name_3 = home_dir_1."MCSModelRmsVec.txt"

file_name_4 = home_dir_2."CenofChg.out"
file_name_5 = home_dir_2."long_tab.out"
file_name_6 = home_dir_2."BeamRMS.out"

file_name_7 = home_dir_3."analyze_res_1.dat"
file_name_8 = home_dir_3."analyze_res_3.dat"
file_name_9 = home_dir_3."analyze_res_2.dat"

if (term_type == 0) set terminal x11
if (term_type == 1) set terminal postscript landscape enhanced color solid \
  lw 2 "Times-Roman" 15
if (term_type == 2) set terminal pdfcairo enhanced color solid

set grid

# Left align legend.
set key Left

set style line 1 lw 1 lc rgb "red"
set style line 2 lw 1 lc rgb "dark-orange"
set style line 3 lw 1 lc rgb "blue"
set style line 4 lw 1 lc rgb "dark-green"
set style line 5 lw 1 lc rgb "purple"
set style line 6 lw 1 lc rgb "cyan"
set style line 7 lw 1 lc rgb "green"

if (term_type != 0) set output "Trans_Orbit_TLM.pdf"
set title "Transverse Orbit (TLM)"
set xlabel "s [m]"; set ylabel ""
plot file_name_1 using 1:2 title "x [mm]" with lines ls 3, \
     file_name_1 using 1:(1e3*$3) title "x' [mrad]" with lines ls 6, \
     file_name_1 using 1:4 title "y [mm]" with lines ls 1, \
     file_name_1 using 1:(1e3*$5) title "y' [mrad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Orbit_TLM.pdf"
set title "Longitudinal Orbit (TLM)"
set xlabel "s [m]"; set ylabel ""
plot file_name_1 using 1:6 title "z [rad]" with lines ls 4, \
     file_name_1 using 1:7 title "z' [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "E_Tot_TLM.pdf"
set title "Total Energy and Phase (TLM)"
set xlabel "s [m]"; set ylabel "[MeV/u]"; set y2label "[rad]"
set ytics nomirror; set y2tics;
plot file_name_2 using 1:2 title "E_tot [MeV/u]" with lines ls 3, \
     file_name_2 using 1:3 axis x1y2 title "{/Symbol j} [rad]" \
     with lines ls 1
if (term_type == 0) pause mouse "click on graph to cont.\n"

set ytics nomirror; unset y2tics; unset y2label

if (term_type != 0) set output "Trans_Beam_Size_TLM.pdf"
set title "Transverse RMS Beam Size (TLM)"
set xlabel "s [m]"; set ylabel ""
plot file_name_3 using 1:2 title "x RMS [mm]" with lines ls 3, \
     file_name_3 using 1:(1e3*$3) title "x' RMS [rad]" with lines ls 6, \
     file_name_3 using 1:4 title "y RMS [mm]" with lines ls 1, \
     file_name_3 using 1:(1e3*$5) title "y' RMS [rad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Beam_Size_TLM.pdf"
set title "Longitudinal RMS Beam Size (TLM)"
set xlabel "s [m]"; set ylabel ""
plot file_name_3 using 1:6 title "z RMS [rad]" with lines ls 4, \
     file_name_3 using 1:7 title "z' RMS [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Trans_Orbit_New_Code.pdf"
set title "Transverse Orbit (New Code)"
set xlabel "s [m]"; set ylabel ""
plot file_name_4 using 1:2 title "x [mm]" with lines ls 3, \
     file_name_4 using 1:(1e3*$3) title "x' [mrad]" with lines ls 6, \
     file_name_4 using 1:4 title "y [mm]" with lines ls 1, \
     file_name_4 using 1:(1e3*$5) title "y' [mrad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Orbit_New_Code.pdf"
set title "Longitudinal Orbit (New Code)"
set xlabel "s [m]"; set ylabel ""
plot file_name_4 using 1:6 title "z [rad]" with lines ls 4, \
     file_name_4 using 1:7 title "z' [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "E_Tot_New_Code.pdf"
set title "Total Energy and Phase (New Code)"
set xlabel "s [m]"; set ylabel "[MeV/u]"; set y2label "[rad]"
set ytics nomirror; set y2tics;
plot file_name_5 using 3:4 title "E_tot [MeV/u]" with lines ls 3, \
     file_name_5 using 3:5 axis x1y2 title "{/Symbol j} [rad]" \
     with lines ls 1
if (term_type == 0) pause mouse "click on graph to cont.\n"

set ytics nomirror; unset y2tics; unset y2label

if (term_type != 0) set output "Trans_Beam_Size_New_Code.pdf"
set title "Transverse RMS Beam Size (New Code)"
set xlabel "s [m]"; set ylabel ""
plot file_name_6 using 1:2 title "x RMS [mm]" with lines ls 3, \
     file_name_6 using 1:(1e3*$3) title "x' RMS [rad]" with lines ls 6, \
     file_name_6 using 1:4 title "y RMS [mm]" with lines ls 1, \
     file_name_6 using 1:(1e3*$5) title "y' RMS [rad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Beam_Size_New_Code.pdf"
set title "Longitudinal RMS Beam Size (New Code)"
set xlabel "s [m]"; set ylabel ""
plot file_name_6 using 1:6 title "z RMS [rad]" with lines ls 4, \
     file_name_6 using 1:7 title "z' RMS [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Trans_Orbit_Diff.pdf"
set title "Transverse Orbit Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel ""
plot file_name_7 using 1:2 title "x [mm]" with lines ls 3, \
     file_name_7 using 1:(1e3*$3) title "x' [mrad]" with lines ls 6, \
     file_name_7 using 1:4 title "y [mm]" with lines ls 1, \
     file_name_7 using 1:(1e3*$5) title "y' [mrad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Orbit_Diff.pdf"
set title "Longitudinal Orbit Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel ""
plot file_name_7 using 1:6 title "z [rad]" with lines ls 4, \
     file_name_7 using 1:7 title "z' [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "E_Tot_Diff.pdf"
set title "Total Energy and Phase Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel "[MeV/u]"; set y2label "[rad]";
set ytics nomirror; set y2tics;
plot file_name_8 using 1:2 title "E_tot" with lines ls 3, \
     file_name_8 using 1:3 axis x1y2 title "{/Symbol j}" with lines ls 1
if (term_type == 0) pause mouse "click on graph to cont.\n"

set ytics nomirror; unset y2tics; unset y2label

if (term_type != 0) set output "Trans_Beam_Size_Diff.pdf"
set title "Transverse RMS Beam Size Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel ""
plot file_name_9 using 1:2 title "x RMS [mm]" with lines ls 3, \
     file_name_9 using 1:(1e3*$3) title "x' RMS [mrad]" with lines ls 6, \
     file_name_9 using 1:4 title "y RMS [mm]" with lines ls 1, \
     file_name_9 using 1:(1e3*$5) title "y' RMS [mrad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Beam_Size_Diff.pdf"
set title "Longitudinal RMS Beam Size Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel ""
plot file_name_9 using 1:6 title "z RMS [rad]" with lines ls 4, \
     file_name_9 using 1:7 title "z' RMS [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

# terminal 0, PostScript 1, PDF 2.
term_type = 2

home_dir_1 = "/home/johan/tlm_workspace/TLM_JB/"
home_dir_2 = "/home/johan/git_repos/jmbgsddb/build/src/"
home_dir_3 = "/home/johan/git_repos/jmbgsddb/python/cavity_model/"

file_name_1 = home_dir_1."MCSModelCenVec.txt"
file_name_2 = home_dir_1."MCSModelRf.txt"
file_name_3 = home_dir_1."MCSModelRmsVec.txt"

file_name_4 = home_dir_2."CenofChg.out"
file_name_5 = home_dir_2."long_tab.out"
file_name_6 = home_dir_2."BeamRMS.out"

file_name_7 = home_dir_3."analyze_res_1.dat"
file_name_8 = home_dir_3."analyze_res_3.dat"
file_name_9 = home_dir_3."analyze_res_2.dat"

if (term_type == 0) set terminal x11
if (term_type == 1) set terminal postscript landscape enhanced color solid \
  lw 2 "Times-Roman" 15
if (term_type == 2) set terminal pdfcairo enhanced color solid

set grid

# Left align legend.
set key Left

set style line 1 lw 1 lc rgb "red"
set style line 2 lw 1 lc rgb "dark-orange"
set style line 3 lw 1 lc rgb "blue"
set style line 4 lw 1 lc rgb "dark-green"
set style line 5 lw 1 lc rgb "purple"
set style line 6 lw 1 lc rgb "cyan"
set style line 7 lw 1 lc rgb "green"

if (term_type != 0) set output "Trans_Orbit_TLM.pdf"
set title "Transverse Orbit (TLM)"
set xlabel "s [m]"; set ylabel ""
plot file_name_1 using 1:2 title "x [mm]" with lines ls 3, \
     file_name_1 using 1:(1e3*$3) title "x' [mrad]" with lines ls 6, \
     file_name_1 using 1:4 title "y [mm]" with lines ls 1, \
     file_name_1 using 1:(1e3*$5) title "y' [mrad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Orbit_TLM.pdf"
set title "Longitudinal Orbit (TLM)"
set xlabel "s [m]"; set ylabel ""
plot file_name_1 using 1:6 title "z [rad]" with lines ls 4, \
     file_name_1 using 1:7 title "z' [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "E_Tot_TLM.pdf"
set title "Total Energy and Phase (TLM)"
set xlabel "s [m]"; set ylabel "[MeV/u]"; set y2label "[rad]"
set ytics nomirror; set y2tics;
plot file_name_2 using 1:2 title "E_tot [MeV/u]" with lines ls 3, \
     file_name_2 using 1:3 axis x1y2 title "{/Symbol j} [rad]" \
     with lines ls 1
if (term_type == 0) pause mouse "click on graph to cont.\n"

set ytics nomirror; unset y2tics; unset y2label

if (term_type != 0) set output "Trans_Beam_Size_TLM.pdf"
set title "Transverse RMS Beam Size (TLM)"
set xlabel "s [m]"; set ylabel ""
plot file_name_3 using 1:2 title "x RMS [mm]" with lines ls 3, \
     file_name_3 using 1:(1e3*$3) title "x' RMS [rad]" with lines ls 6, \
     file_name_3 using 1:4 title "y RMS [mm]" with lines ls 1, \
     file_name_3 using 1:(1e3*$5) title "y' RMS [rad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Beam_Size_TLM.pdf"
set title "Longitudinal RMS Beam Size (TLM)"
set xlabel "s [m]"; set ylabel ""
plot file_name_3 using 1:6 title "z RMS [rad]" with lines ls 4, \
     file_name_3 using 1:7 title "z' RMS [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Trans_Orbit_New_Code.pdf"
set title "Transverse Orbit (New Code)"
set xlabel "s [m]"; set ylabel ""
plot file_name_4 using 1:2 title "x [mm]" with lines ls 3, \
     file_name_4 using 1:(1e3*$3) title "x' [mrad]" with lines ls 6, \
     file_name_4 using 1:4 title "y [mm]" with lines ls 1, \
     file_name_4 using 1:(1e3*$5) title "y' [mrad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Orbit_New_Code.pdf"
set title "Longitudinal Orbit (New Code)"
set xlabel "s [m]"; set ylabel ""
plot file_name_4 using 1:6 title "z [rad]" with lines ls 4, \
     file_name_4 using 1:7 title "z' [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "E_Tot_New_Code.pdf"
set title "Total Energy and Phase (New Code)"
set xlabel "s [m]"; set ylabel "[MeV/u]"; set y2label "[rad]"
set ytics nomirror; set y2tics;
plot file_name_5 using 3:4 title "E_tot [MeV/u]" with lines ls 3, \
     file_name_5 using 3:5 axis x1y2 title "{/Symbol j} [rad]" \
     with lines ls 1
if (term_type == 0) pause mouse "click on graph to cont.\n"

set ytics nomirror; unset y2tics; unset y2label

if (term_type != 0) set output "Trans_Beam_Size_New_Code.pdf"
set title "Transverse RMS Beam Size (New Code)"
set xlabel "s [m]"; set ylabel ""
plot file_name_6 using 1:2 title "x RMS [mm]" with lines ls 3, \
     file_name_6 using 1:(1e3*$3) title "x' RMS [rad]" with lines ls 6, \
     file_name_6 using 1:4 title "y RMS [mm]" with lines ls 1, \
     file_name_6 using 1:(1e3*$5) title "y' RMS [rad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Beam_Size_New_Code.pdf"
set title "Longitudinal RMS Beam Size (New Code)"
set xlabel "s [m]"; set ylabel ""
plot file_name_6 using 1:6 title "z RMS [rad]" with lines ls 4, \
     file_name_6 using 1:7 title "z' RMS [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Trans_Orbit_Diff.pdf"
set title "Transverse Orbit Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel ""
plot file_name_7 using 1:2 title "x [mm]" with lines ls 3, \
     file_name_7 using 1:(1e3*$3) title "x' [mrad]" with lines ls 6, \
     file_name_7 using 1:4 title "y [mm]" with lines ls 1, \
     file_name_7 using 1:(1e3*$5) title "y' [mrad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Orbit_Diff.pdf"
set title "Longitudinal Orbit Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel ""
plot file_name_7 using 1:6 title "z [rad]" with lines ls 4, \
     file_name_7 using 1:7 title "z' [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "E_Tot_Diff.pdf"
set title "Total Energy Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel ""
set ytics nomirror; set y2tics;
plot file_name_8 using 1:2 title "E_tot [MeV/u]" with lines ls 3, \
     file_name_8 using 1:3 axis x1y2 title "{/Symbol j} [rad]" with lines ls 1
if (term_type == 0) pause mouse "click on graph to cont.\n"

set ytics nomirror; unset y2tics; unset y2label

if (term_type != 0) set output "Trans_Beam_Size_Diff.pdf"
set title "Transverse RMS Beam Size Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel ""
plot file_name_9 using 1:2 title "x RMS [mm]" with lines ls 3, \
     file_name_9 using 1:(1e3*$3) title "x' RMS [mrad]" with lines ls 6, \
     file_name_9 using 1:4 title "y RMS [mm]" with lines ls 1, \
     file_name_9 using 1:(1e3*$5) title "y' RMS [mrad]" with lines ls 2
if (term_type == 0) pause mouse "click on graph to cont.\n"

if (term_type != 0) set output "Long_Beam_Size_Diff.pdf"
set title "Longitudinal RMS Beam Size Difference Between New Code and TLM"
set xlabel "s [m]"; set ylabel ""
plot file_name_9 using 1:6 title "z RMS [rad]" with lines ls 4, \
     file_name_9 using 1:7 title "z' RMS [MeV/u]" with lines ls 5
if (term_type == 0) pause mouse "click on graph to cont.\n"


Cleanup.

Cleanup.

:- include(misc(common)).

:- begin_tests('bson_decoder:bson_to_pairs/2').

test('empty doc', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0 % End of top doc.
    ],
    Expected =
    [
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x01, float', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x01, % Tag.
            104,101,108,108,111, 0, % Ename.
            51,51,51,51, 51,51,20,64, % Double data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - 5.05
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x02, string', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x02, % Tag.
            0xc3,0xa4, 0, % Ename.
            6,0,0,0, % String's byte length, incl. nul.
            0xc3,0xa4, 0, 0xc3,0xa4, 0, % String data.
        0 % End of top doc.
    ],
    Expected =
    [
        'ä' - 'ä\0ä'
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x02, nuls not allowed in ename', [throws(bson_error(_))]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x02, % Tag.
            0xc3,0xa4, 0, 0xc3,0xa4, 0, % Ename, INVALID.
            3,0,0,0, % String's byte length, incl. nul.
            0xc3,0xa4, 0, % String data.
        0 % End of top doc.
    ],
    bson_decoder:bson_to_pairs(Bson, _Got).

test('0x03, embedded doc', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x03, % Tag.
            104,101,108,108,111, 0, % Ename.
            38,0,0,0, % Length of embedded doc.
            0x02, % Tag.
                97, 0, % Ename.
                8,0,0,0, % String's byte length, incl. nul.
                97,119,101,115,111,109,101, 0, % String data.
            0x01, % Tag.
                98, 0, % Ename.
                51,51,51,51,51,51,20,64, % Double 8-byte data.
            0x10, % Tag.
                99, 0, % Ename.
                194,7,0,0, % Int32 data.
            0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello -
            [
                'a' - 'awesome',
                'b' - 5.05,
                'c' - 1986
            ]
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x03, embedded empty doc', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x03, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of embedded doc.
            0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - []
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x04, embedded array', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x04, % Tag.
            104,101,108,108,111, 0, % Ename.
            38,0,0,0, % Length of embedded doc.
            0x02, % Tag.
                48, 0, % Ename, index 0.
                8,0,0,0, % String's byte length, incl. nul.
                97,119,101,115,111,109,101, 0, % String data.
            0x01, % Tag.
                49, 0, % Ename, index 1.
                51,51,51,51,51,51,20,64, % Double 8-byte data.
            0x10, % Tag.
                50, 0, % Ename, index 2.
                194,7,0,0, % Int32 data.
            0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - ['awesome', 5.05, 1986]
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x04, embedded empty array', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x04, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of embedded doc.
            0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - []
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, generic', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x00, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(generic, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, function', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x01, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(function, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, old generic', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x02, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(old_generic, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, uuid', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x03, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(uuid, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, md5', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x05, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(md5, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, user defined', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x80, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(user_defined, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x06, undefined', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x06, % Tag.
            104,101,108,108,111, 0, % Ename.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(undefined)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x07, object id', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x07, % Tag.
            104,101,108,108,111, 0, % Ename.
            0x47,0xcc,0x67,0x09, % ObjectID, time.
            0x34,0x75,0x06,      % ObjectID, machine.
            0x1e,0x3d,           % ObjectID, pid.
            0x95,0x36,0x9d,      % ObjectID, inc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - object_id('47cc67093475061e3d95369d')
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x08, boolean true', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x08, % Tag.
            104,101,108,108,111, 0, % Ename.
            1, % Boolean data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(true)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x08, boolean false', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x08, % Tag.
            104,101,108,108,111, 0, % Ename.
            0, % Boolean data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(false)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x08, boolean invalid', [throws(bson_error(invalid_boolean))]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x08, % Tag.
            104,101,108,108,111, 0, % Ename.
            2, % Boolean data, INVALID value.
        0 % End of top doc.
    ],
    bson_decoder:bson_to_pairs(Bson, _Got).

test('0x09, utc datetime', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x09, % Tag.
            104,101,108,108,111, 0, % Ename.
            188,11,99,58,47,1,0,0, % UTC datetime data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - utc(1302354660284) % date(2011, 4, 9, ...)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0A, null', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0A, % Tag.
            104,101,108,108,111, 0, % Ename.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(null)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0B, regex', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0B, % Tag.
            104,101,108,108,111, 0, % Ename.
            97, 0,  % Regex pattern.
            105, 0, % Regex options.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - regex('a','i')
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0C, db pointer', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0C, % Tag.
            104,101,108,108,111, 0, % Ename.
            2,0,0,0, % String's byte length, incl. nul.
            97, 0, % String data.
            0x47,0xcc,0x67,0x09, % ObjectID, time.
            0x34,0x75,0x06,      % ObjectID, machine.
            0x1e,0x3d,           % ObjectID, pid.
            0x95,0x36,0x9d,      % ObjectID, inc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - db_pointer('a', '47cc67093475061e3d95369d')
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0D, js', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0D, % Tag.
            106,115, 0, % Ename.
            9,0,0,0, % String's byte length, incl. nul.
            99,111,100,101,32,46,46,46, 0, % String data.
        0 % End of top doc.
    ],
    Expected =
    [
        js - js('code ...')
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0E, symbol', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0E, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % String's byte length, incl. nul.
            97,116,111,109, 0, % String data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - symbol(atom)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0F, js with scope', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0F, % Tag.
            106,115, 0, % Ename.
            xxx_not_impl,0,0,0, % Length of entire JS with scope.
            9,0,0,0, % String's byte length, incl. nul.
            99,111,100,101,32,46,46,46, 0, % String data.
                xxx_not_impl,0,0,0, % Length of embedded doc.
                0x10, % Tag.
                    104,101,108,108,111, 0, % Ename.
                    32,0,0,0, % Int32 data.
                0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        js - js('code ...', ['hello'-32])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x10, int32', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x10, % Tag.
            104,101,108,108,111, 0, % Ename.
            32,0,0,0, % Int32 data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - 32
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x11, mongostamp', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x11, % Tag.
            104,101,108,108,111, 0, % Ename.
            0,0,0,0, 0,0,0,0, % Int64 mongostamp data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - mongostamp(0)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x12, int64', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x12, % Tag.
            104,101,108,108,111, 0, % Ename.
            32,0,0,0, 0,0,0,0, % Int64 data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - 32
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0xFF, min', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0xFF, % Tag.
            104,101,108,108,111, 0, % Ename.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(min)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x7F, max', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x7F, % Tag.
            104,101,108,108,111, 0, % Ename.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(max)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('invalid bson, missing terminating nul', [throws(bson_error(invalid))]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x10, % Tag.
            104,101,108,108,111, 0, % Ename.
            32,0,0,0 % Int32 data.
        % Missing nul at end-of-doc.
    ],
    bson_decoder:bson_to_pairs(Bson, _Got).

:- end_tests('bson_decoder:bson_to_pairs/2').

:- include(misc(common)).

:- begin_tests('bson_decoder:bson_to_pairs/2').

test('empty doc', [true(Got == Expected)]) :-
    Bson =
    [
        5,0,0,0, % Length of top doc.
        0 % End of top doc.
    ],
    Expected =
    [
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x01, float', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x01, % Tag.
            104,101,108,108,111, 0, % Ename.
            51,51,51,51, 51,51,20,64, % Double data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - 5.05
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x02, string', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x02, % Tag.
            0xc3,0xa4, 0, % Ename.
            6,0,0,0, % String's byte length, incl. nul.
            0xc3,0xa4, 0, 0xc3,0xa4, 0, % String data.
        0 % End of top doc.
    ],
    Expected =
    [
        'ä' - 'ä\0ä'
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x02, nuls not allowed in ename', [throws(bson_error(_))]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x02, % Tag.
            0xc3,0xa4, 0, 0xc3,0xa4, 0, % Ename, INVALID.
            3,0,0,0, % String's byte length, incl. nul.
            0xc3,0xa4, 0, % String data.
        0 % End of top doc.
    ],
    bson_decoder:bson_to_pairs(Bson, _Got).

test('0x03, embedded doc', [true(Got == Expected)]) :-
    Bson =
    [
        50,0,0,0, % Length of top doc.
        0x03, % Tag.
            104,101,108,108,111, 0, % Ename.
            38,0,0,0, % Length of embedded doc.
            0x02, % Tag.
                97, 0, % Ename.
                8,0,0,0, % String's byte length, incl. nul.
                97,119,101,115,111,109,101, 0, % String data.
            0x01, % Tag.
                98, 0, % Ename.
                51,51,51,51,51,51,20,64, % Double 8-byte data.
            0x10, % Tag.
                99, 0, % Ename.
                194,7,0,0, % Int32 data.
            0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello -
            [
                'a' - 'awesome',
                'b' - 5.05,
                'c' - 1986
            ]
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x03, embedded empty doc', [true(Got == Expected)]) :-
    Bson =
    [
        17,0,0,0, % Length of top doc.
        0x03, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of embedded doc.
            0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - []
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x04, embedded array', [true(Got == Expected)]) :-
    Bson =
    [
        50,0,0,0, % Length of top doc.
        0x04, % Tag.
            104,101,108,108,111, 0, % Ename.
            38,0,0,0, % Length of embedded doc.
            0x02, % Tag.
                48, 0, % Ename, index 0.
                8,0,0,0, % String's byte length, incl. nul.
                97,119,101,115,111,109,101, 0, % String data.
            0x01, % Tag.
                49, 0, % Ename, index 1.
                51,51,51,51,51,51,20,64, % Double 8-byte data.
            0x10, % Tag.
                50, 0, % Ename, index 2.
                194,7,0,0, % Int32 data.
            0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - ['awesome', 5.05, 1986]
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x04, embedded empty array', [true(Got == Expected)]) :-
    Bson =
    [
        17,0,0,0, % Length of top doc.
        0x04, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of embedded doc.
            0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - []
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, generic', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x00, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(generic, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, function', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x01, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(function, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, old generic', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x02, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(old_generic, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, uuid', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x03, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(uuid, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, md5', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x05, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(md5, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x05, binary, user defined', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x05, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % Length of binary data.
            0x80, % Subtype.
            0,1,2,1,0, % Binary data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - binary(user_defined, [0,1,2,1,0])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x06, undefined', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x06, % Tag.
            104,101,108,108,111, 0, % Ename.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(undefined)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x07, object id', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x07, % Tag.
            104,101,108,108,111, 0, % Ename.
            0x47,0xcc,0x67,0x09, % ObjectID, time.
            0x34,0x75,0x06,      % ObjectID, machine.
            0x1e,0x3d,           % ObjectID, pid.
            0x95,0x36,0x9d,      % ObjectID, inc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - object_id('47cc67093475061e3d95369d')
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x08, boolean true', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x08, % Tag.
            104,101,108,108,111, 0, % Ename.
            1, % Boolean data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(true)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x08, boolean false', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x08, % Tag.
            104,101,108,108,111, 0, % Ename.
            0, % Boolean data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(false)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x08, boolean invalid', [throws(bson_error(invalid_boolean))]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x08, % Tag.
            104,101,108,108,111, 0, % Ename.
            2, % Boolean data, INVALID value.
        0 % End of top doc.
    ],
    bson_decoder:bson_to_pairs(Bson, _Got).

test('0x09, utc datetime', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x09, % Tag.
            104,101,108,108,111, 0, % Ename.
            188,11,99,58,47,1,0,0, % UTC datetime data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - utc(1302354660284) % date(2011, 4, 9, ...)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0A, null', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0A, % Tag.
            104,101,108,108,111, 0, % Ename.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(null)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0B, regex', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0B, % Tag.
            104,101,108,108,111, 0, % Ename.
            97, 0,  % Regex pattern.
            105, 0, % Regex options.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - regex('a','i')
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0C, db pointer', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0C, % Tag.
            104,101,108,108,111, 0, % Ename.
            2,0,0,0, % String's byte length, incl. nul.
            97, 0, % String data.
            0x47,0xcc,0x67,0x09, % ObjectID, time.
            0x34,0x75,0x06,      % ObjectID, machine.
            0x1e,0x3d,           % ObjectID, pid.
            0x95,0x36,0x9d,      % ObjectID, inc.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - db_pointer('a', '47cc67093475061e3d95369d')
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0D, js', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0D, % Tag.
            106,115, 0, % Ename.
            9,0,0,0, % String's byte length, incl. nul.
            99,111,100,101,32,46,46,46, 0, % String data.
        0 % End of top doc.
    ],
    Expected =
    [
        js - js('code ...')
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0E, symbol', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0E, % Tag.
            104,101,108,108,111, 0, % Ename.
            5,0,0,0, % String's byte length, incl. nul.
            97,116,111,109, 0, % String data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - symbol(atom)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x0F, js with scope', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x0F, % Tag.
            106,115, 0, % Ename.
            xxx_not_impl,0,0,0, % Length of entire JS with scope.
            9,0,0,0, % String's byte length, incl. nul.
            99,111,100,101,32,46,46,46, 0, % String data.
                xxx_not_impl,0,0,0, % Length of embedded doc.
                0x10, % Tag.
                    104,101,108,108,111, 0, % Ename.
                    32,0,0,0, % Int32 data.
                0, % End of embedded doc.
        0 % End of top doc.
    ],
    Expected =
    [
        js - js('code ...', ['hello'-32])
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x10, int32', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x10, % Tag.
            104,101,108,108,111, 0, % Ename.
            32,0,0,0, % Int32 data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - 32
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x11, mongostamp', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x11, % Tag.
            104,101,108,108,111, 0, % Ename.
            0,0,0,0, 0,0,0,0, % Int64 mongostamp data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - mongostamp(0)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x12, int64', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x12, % Tag.
            104,101,108,108,111, 0, % Ename.
            32,0,0,0, 0,0,0,0, % Int64 data.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - 32
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0xFF, min', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0xFF, % Tag.
            104,101,108,108,111, 0, % Ename.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(min)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('0x7F, max', [true(Got == Expected)]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x7F, % Tag.
            104,101,108,108,111, 0, % Ename.
        0 % End of top doc.
    ],
    Expected =
    [
        hello - @(max)
    ],
    bson_decoder:bson_to_pairs(Bson, Got).

test('invalid bson, missing terminating nul', [throws(bson_error(invalid))]) :-
    Bson =
    [
        xxx_not_impl,0,0,0, % Length of top doc.
        0x10, % Tag.
            104,101,108,108,111, 0, % Ename.
            32,0,0,0 % Int32 data.
        % Missing nul at end-of-doc.
    ],
    bson_decoder:bson_to_pairs(Bson, _Got).

:- end_tests('bson_decoder:bson_to_pairs/2').


Optimize output of chart_perf.sh to show all of the tests

Enlarges time axis fonts, hides x axis tics, and sets the size to
values large enough that all test labels can fit without overlapping.

set datafile separator ','

# General config.
set autoscale
set bmargin 22    # For some reason using xticlabels adds tons of whitespaces at the end
set tics font ",4"

# Y (time) axis config
set ylabel "Time (seconds)"
set ytics font ",8"
set logscale y 10

# Chart shape
set style histogram clustered
set boxwidth 0.75 relative
set style fill transparent solid 0.5 noborder
set style histogram gap 0.25

# Grid
set style line 100 lt 1 lc rgb "grey" lw 0.5 # linestyle for the grid
set grid ls 100 # enable grid with specific linestyle

# X axis config
set xtics scale 0 rotate

set terminal svg enhanced size 8192,1024
set output 'perf.svg'
plot csv_2 using 2:xticlabels(1) with boxes lc rgb'red90' axis x1y1 title "after", \
     csv_3 using 2:xticlabels(1) with boxes lc rgb'blue90' axis x1y1 title "before", \
     '' u 0:($2+.1):(sprintf("%3.2f",$4-$2)) with labels rotate left font ",4" notitle

set datafile separator ','

# General config.
set autoscale
set bmargin 22    # For some reason using xticlabels adds tons of whitespaces at the end
set tics font ",4"

# Y (time) axis config
set ylabel "Time"
set logscale y 10

# Chart shape
set style histogram clustered
set boxwidth 0.75 relative
set style fill transparent solid 0.5 noborder
set style histogram gap 0.25

# Grid
set style line 100 lt 1 lc rgb "grey" lw 0.5 # linestyle for the grid
set grid ls 100 # enable grid with specific linestyle

# X axis config
set xtics 1 rotate

set terminal svg enhanced size 2048,1024
set output 'perf.svg'
plot csv_2 using 2:xticlabels(1) with boxes lc rgb'red90' axis x1y1 title "after", \
     csv_3 using 2:xticlabels(1) with boxes lc rgb'blue90' axis x1y1 title "before", \
     '' u 0:($2+.1):(sprintf("%3.2f",$4-$2)) with labels rotate left font ",4" notitle


Fix test.

Fix test.

:- include(misc(common)).

:- use_module(bson(bson), []).
:- use_module(misc(util), []).

up(Conn, Coll) :-
    mongo:new(Conn),
    mongo:get_database(Conn, 'prolongo', Db),
    mongo:get_collection(Db, 'testcoll', Coll).

down(Conn) :-
    mongo:free(Conn).

:- begin_tests('mongo:upsert/3').

test('upsert', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    mongo:delete(Coll, [hello-me]),
    mongo:upsert(Coll, [hello-world], [hello-me]),
    mongo:find_one(Coll, [hello-me], Doc),
    bson:doc_get(Doc, hello, me).

:- end_tests('mongo:upsert/3').

:- begin_tests('mongo:update/3').

test('update normal', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    mongo:delete(Coll, [hello-me]),
    mongo:insert(Coll, [hello-world]),
    mongo:update(Coll, [hello-world], [hello-me]),
    mongo:find_one(Coll, [hello-me], Doc),
    bson:doc_get(Doc, hello, me).

:- end_tests('mongo:update/3').

:- begin_tests('mongo:update_all/3').

test('update multi', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    mongo:delete(Coll, [hello-me]),
    mongo:insert(Coll, [hello-world,num-1]),
    mongo:insert(Coll, [hello-world,num-2]),
    mongo:insert(Coll, [hello-world,num-3]),
    mongo:update_all(Coll, [hello-world], ['$inc'-[num-10]]),
    mongo:find(Coll, [hello-world], [], 0, 3, _Cursor, Docs),
    lists:length(Docs, 3),
    lists:member(Doc1, Docs),
    bson:doc_get(Doc1, num, 11),
    lists:member(Doc2, Docs),
    bson:doc_get(Doc2, num, 12),
    lists:member(Doc3, Docs),
    bson:doc_get(Doc3, num, 13),
    !.

:- end_tests('mongo:update_all/3').

:- begin_tests('mongo:delete/2').

test('delete', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:insert(Coll, [hello-world]),
    mongo:find(Coll, [hello-world], [], 0, 0, _Cursor1, [_|_]),
    mongo:delete(Coll, [hello-world]),
    mongo:find(Coll, [hello-world], [], 0, 0, _Cursor2, []).

:- end_tests('mongo:delete/2').

:- begin_tests('mongo:find/7').

test('cursor', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    mongo:insert(Coll, [hello-world,number-1]),
    mongo:insert(Coll, [hello-world,number-2]),
    mongo:insert(Coll, [hello-world,number-3]),
    mongo:insert(Coll, [hello-world,number-4]),
    mongo:insert(Coll, [hello-world,number-5]),
    mongo:insert(Coll, [hello-world,number-6]),
    mongo:insert(Coll, [hello-world,number-7]),
    mongo:insert(Coll, [hello-world,number-8]),
    mongo:insert(Coll, [hello-world,number-9]),
    mongo:find(Coll, [hello-world], [number-1], 3, 3, Cursor0, Docs0),
    Docs0 =
    [
        ['_id'-object_id(_),number-_],
        ['_id'-object_id(_),number-_],
        ['_id'-object_id(_),number-_]
    ],
    mongo:has_more(Cursor0),
    mongo:get_more(Cursor0, 3, Docs1, Cursor1),
    Docs1 =
    [
        ['_id'-object_id(_),number-_],
        ['_id'-object_id(_),number-_],
        ['_id'-object_id(_),number-_]
    ],
    mongo:has_more(Cursor1),
    mongo:get_more(Cursor1, 3, Docs2, Cursor2),
    Docs2 =
    [
    ],
    \+ mongo:has_more(Cursor2).

test('insert many single, cursor exhaust', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    insert_n_docs(Coll, 1000),
    mongo:find(Coll, [hello-world], [number-1], 0, 0, Cursor, Docs0),
    mongo:exhaust(Cursor, DocsRest),
    lists:length(Docs0, N0),
    lists:length(DocsRest, N),
    1000 is N0 + N.

insert_n_docs(_Coll, 0) :- !.
insert_n_docs(Coll, N) :-
    mongo:insert(Coll, [hello-world,number-N]),
    N1 is N - 1,
    insert_n_docs(Coll, N1).

test('insert batch, cursor exhaust', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    create_n_docs(1000, Docs),
    mongo:insert_batch(Coll, [], Docs),
    mongo:find(Coll, [hello-world], [number-1], 0, 0, Cursor, Docs0),
    mongo:exhaust(Cursor, DocsRest),
    lists:length(Docs0, N0),
    lists:length(DocsRest, N),
    1000 is N0 + N.

create_n_docs(0, []) :- !.
create_n_docs(N, [[hello-world,number-N]|Docs]) :-
    N1 is N - 1,
    create_n_docs(N1, Docs).

test('insert batch, find_all', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    create_n_docs(1000, Docs),
    mongo:insert_batch(Coll, [], Docs),
    mongo:find_all(Coll, [hello-world], [number-1], DocsAll),
    lists:length(DocsAll, 1000).

:- end_tests('mongo:find/7').

:- begin_tests('mongo:find_one/3,4').

test('entire doc', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    Doc = [hello-world, number-42],
    mongo:insert(Coll, Doc),
    mongo:find_one(Coll, Doc, Doc1),
    bson:doc_get(Doc1, number, 42).

test('entire doc', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    Doc = [hello-world, number-42],
    mongo:insert(Coll, Doc),
    mongo:find_one(Coll, Doc, Doc1),
    bson:doc_get(Doc1, number, 42).

test('return fields selector', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    Doc = [hello-world, number-42],
    mongo:insert(Coll, Doc),
    Fields = [number-1],
    mongo:find_one(Coll, Doc, Fields, Doc1),
    bson:doc_get(Doc1, '_id', object_id(_)), % Always returned.
    bson:doc_get(Doc1, number, 42),
    \+ bson:doc_get(Doc1, hello, world).

:- end_tests('mongo:find_one/3,4').

:- begin_tests('mongo:insert/2').

test('insert', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    util:ms_since_epoch(MilliSeconds),
    Doc =
    [
        hello - [åäö,5.05],
        now   - utc(MilliSeconds)
    ],
    mongo:insert(Coll, Doc).

:- end_tests('mongo:insert/2').

/*
:- begin_tests('mongo:command/3').

test('list database infos', [setup(up(Mongo)),cleanup(down(Mongo))]) :-
    mongo:list_database_infos(Mongo, DatabaseInfos),
    database(Database),
    bson:doc_get(DatabaseInfos, Database, Info),
    Info \== +null.
    %bson_format:pp(DatabaseInfos), nl.

test('list database names', [setup(up(Mongo)),cleanup(down(Mongo))]) :-
    mongo:list_database_names(Mongo, DatabaseNames),
    database(Database),
    core:memberchk(Database, DatabaseNames).

% XXX this works now, but I need to fix cursors (only one is shown).
test('list collection names', [setup(up(Mongo)),cleanup(down(Mongo))]) :-
    mongo:list_collection_names(Mongo, Result),
    bson_format:pp(Result).

test('drop collection',
[
    setup(up(Mongo)),
    cleanup(down(Mongo))
]) :-
    collection(Collection),
    mongo:drop_collection(Mongo, Collection, Result),
    write(Result), nl,
    mongo:doc_ok(Result).

% Takes a bit too long when MongoDB reallocates the collection later.
test('drop database', [setup(up(Mongo)),cleanup(down(Mongo))]) :-
    database(Database),
    mongo:drop_database(Mongo, Database, Result),
    bson:doc_get(Result, ok, 1.0).

:- end_tests('mongo:command/3').
*/

:- include(misc(common)).

:- use_module(bson(bson), []).
:- use_module(misc(util), []).

up(Conn, Coll) :-
    mongo:new(Conn),
    mongo:get_database(Conn, 'prolongo', Db),
    mongo:get_collection(Db, 'testcoll', Coll).

down(Conn) :-
    mongo:free(Conn).

:- begin_tests('mongo:upsert/3').

test('upsert', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    mongo:delete(Coll, [hello-me]),
    mongo:upsert(Coll, [hello-world], [hello-me]),
    mongo:find_one(Coll, [hello-me], Doc),
    bson:doc_get(Doc, hello, me).

:- end_tests('mongo:upsert/3').

:- begin_tests('mongo:update/3').

test('update normal', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    mongo:delete(Coll, [hello-me]),
    mongo:insert(Coll, [hello-world]),
    mongo:update(Coll, [hello-world], [hello-me]),
    mongo:find_one(Coll, [hello-me], Doc),
    bson:doc_get(Doc, hello, me).

:- end_tests('mongo:update/3').

:- begin_tests('mongo:update_all/3').

test('update multi', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    mongo:delete(Coll, [hello-me]),
    mongo:insert(Coll, [hello-world,num-1]),
    mongo:insert(Coll, [hello-world,num-2]),
    mongo:insert(Coll, [hello-world,num-3]),
    mongo:update_all(Coll, [hello-world], ['$inc'-[num-10]]),
    mongo:find(Coll, [hello-world], [], 0, 3, _Cursor, [Doc1,Doc2,Doc3]),
    % XXX Maybe this sort order is not guaranteed?
    bson:doc_get(Doc1, num, 11),
    bson:doc_get(Doc2, num, 12),
    bson:doc_get(Doc3, num, 13).

:- end_tests('mongo:update_all/3').

:- begin_tests('mongo:delete/2').

test('delete', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:insert(Coll, [hello-world]),
    mongo:find(Coll, [hello-world], [], 0, 0, _Cursor1, [_|_]),
    mongo:delete(Coll, [hello-world]),
    mongo:find(Coll, [hello-world], [], 0, 0, _Cursor2, []).

:- end_tests('mongo:delete/2').

:- begin_tests('mongo:find/7').

test('cursor', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    mongo:insert(Coll, [hello-world,number-1]),
    mongo:insert(Coll, [hello-world,number-2]),
    mongo:insert(Coll, [hello-world,number-3]),
    mongo:insert(Coll, [hello-world,number-4]),
    mongo:insert(Coll, [hello-world,number-5]),
    mongo:insert(Coll, [hello-world,number-6]),
    mongo:insert(Coll, [hello-world,number-7]),
    mongo:insert(Coll, [hello-world,number-8]),
    mongo:insert(Coll, [hello-world,number-9]),
    mongo:find(Coll, [hello-world], [number-1], 3, 3, Cursor0, Docs0),
    Docs0 =
    [
        ['_id'-object_id(_),number-_],
        ['_id'-object_id(_),number-_],
        ['_id'-object_id(_),number-_]
    ],
    mongo:has_more(Cursor0),
    mongo:get_more(Cursor0, 3, Docs1, Cursor1),
    Docs1 =
    [
        ['_id'-object_id(_),number-_],
        ['_id'-object_id(_),number-_],
        ['_id'-object_id(_),number-_]
    ],
    mongo:has_more(Cursor1),
    mongo:get_more(Cursor1, 3, Docs2, Cursor2),
    Docs2 =
    [
    ],
    \+ mongo:has_more(Cursor2).

test('insert many single, cursor exhaust', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    insert_n_docs(Coll, 1000),
    mongo:find(Coll, [hello-world], [number-1], 0, 0, Cursor, Docs0),
    mongo:exhaust(Cursor, DocsRest),
    lists:length(Docs0, N0),
    lists:length(DocsRest, N),
    1000 is N0 + N.

insert_n_docs(_Coll, 0) :- !.
insert_n_docs(Coll, N) :-
    mongo:insert(Coll, [hello-world,number-N]),
    N1 is N - 1,
    insert_n_docs(Coll, N1).

test('insert batch, cursor exhaust', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    create_n_docs(1000, Docs),
    mongo:insert_batch(Coll, [], Docs),
    mongo:find(Coll, [hello-world], [number-1], 0, 0, Cursor, Docs0),
    mongo:exhaust(Cursor, DocsRest),
    lists:length(Docs0, N0),
    lists:length(DocsRest, N),
    1000 is N0 + N.

create_n_docs(0, []) :- !.
create_n_docs(N, [[hello-world,number-N]|Docs]) :-
    N1 is N - 1,
    create_n_docs(N1, Docs).

test('insert batch, find_all', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    mongo:delete(Coll, [hello-world]),
    create_n_docs(1000, Docs),
    mongo:insert_batch(Coll, [], Docs),
    mongo:find_all(Coll, [hello-world], [number-1], DocsAll),
    lists:length(DocsAll, 1000).

:- end_tests('mongo:find/7').

:- begin_tests('mongo:find_one/3,4').

test('entire doc', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    Doc = [hello-world, number-42],
    mongo:insert(Coll, Doc),
    mongo:find_one(Coll, Doc, Doc1),
    bson:doc_get(Doc1, number, 42).

test('entire doc', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    Doc = [hello-world, number-42],
    mongo:insert(Coll, Doc),
    mongo:find_one(Coll, Doc, Doc1),
    bson:doc_get(Doc1, number, 42).

test('return fields selector', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    Doc = [hello-world, number-42],
    mongo:insert(Coll, Doc),
    Fields = [number-1],
    mongo:find_one(Coll, Doc, Fields, Doc1),
    bson:doc_get(Doc1, '_id', object_id(_)), % Always returned.
    bson:doc_get(Doc1, number, 42),
    \+ bson:doc_get(Doc1, hello, world).

:- end_tests('mongo:find_one/3,4').

:- begin_tests('mongo:insert/2').

test('insert', [setup(up(Conn,Coll)),cleanup(down(Conn))]) :-
    util:ms_since_epoch(MilliSeconds),
    Doc =
    [
        hello - [åäö,5.05],
        now   - utc(MilliSeconds)
    ],
    mongo:insert(Coll, Doc).

:- end_tests('mongo:insert/2').

/*
:- begin_tests('mongo:command/3').

test('list database infos', [setup(up(Mongo)),cleanup(down(Mongo))]) :-
    mongo:list_database_infos(Mongo, DatabaseInfos),
    database(Database),
    bson:doc_get(DatabaseInfos, Database, Info),
    Info \== +null.
    %bson_format:pp(DatabaseInfos), nl.

test('list database names', [setup(up(Mongo)),cleanup(down(Mongo))]) :-
    mongo:list_database_names(Mongo, DatabaseNames),
    database(Database),
    core:memberchk(Database, DatabaseNames).

% XXX this works now, but I need to fix cursors (only one is shown).
test('list collection names', [setup(up(Mongo)),cleanup(down(Mongo))]) :-
    mongo:list_collection_names(Mongo, Result),
    bson_format:pp(Result).

test('drop collection',
[
    setup(up(Mongo)),
    cleanup(down(Mongo))
]) :-
    collection(Collection),
    mongo:drop_collection(Mongo, Collection, Result),
    write(Result), nl,
    mongo:doc_ok(Result).

% Takes a bit too long when MongoDB reallocates the collection later.
test('drop database', [setup(up(Mongo)),cleanup(down(Mongo))]) :-
    database(Database),
    mongo:drop_database(Mongo, Database, Result),
    bson:doc_get(Result, ok, 1.0).

:- end_tests('mongo:command/3').
*/


Add more regex tests

Add more regex tests