lean4-htt/tests/bench
Leonardo de Moura 2120883307 refactor: heterogeneous operators
@Kha I had some unexpected surprises, but it is a good change.
Here is the summary.

1- We could get rid of `a %ₙ b` and `ModN` class. We can use `HMod`
instead. It was a positive surprise since I didn't remember we had
this `ModN` class.

2- Coercions are never used in heterogeneous operators. This is
expected since `a * b` is now notation for `HMul.hMul a b`, and
`a` and `b` may have different types. I manually added instances such
as `HMul Nat Int Int`. However, I did not try to add generic instances
such as
```
instance [Coe a b] [Mul b] : HMul a b b where
  hMul x y := mul (coe x) y
```
I will try later.

3- Give `h : cs.size > 0`, I got a type error at
```
let idx : Fin cs.size := ⟨cs.size - 1, Nat.predLt h⟩
```
`Nat.predLt h` has type `Nat.pred cs.size < cs.size`
However, `Nat.pred cs.size` doesn't unify with `cs.size - 1`.
The problem is that we can't synthesize the `HSub` instance until
we apply the default instances.
It worked before because `isDefEq` would force the pending TC
problem `Sub Nat` to be resolved, and after that we would be able
to reduce `cs.size - 1` and establish that it is definitionally
equal to `Nat.pred cs.size`.
I considered two possible workarounds
a) `let idx : Fin cs.size := ⟨cs.size - (1:Nat), Nat.predLt h⟩`
b) `let idx : Fin cs.size := ⟨cs.size - 1, by exact Nat.predLt h⟩`
The first one works because we are not providing enough information
for synthesizing the `HSub` instance. The second works because it
postpones the elaboration of `Nat.predLt h`. The default instances
will be applied before we start applying tactics.

4- The `.` notation is affected too. For example, `(x + 1).toUInt8`
doesn't work since we don't know the type of `x+1` until we apply
default instances. I fixed it by using `(x + (1:Nat)).toUInt8`.
Another possible fix is `Nat.toUInt8 (x + 1)`.
Similarly, `(x+1).fold ...` doesn't work.

5- The following code failed to be elaborated
```
indent (push s!"{ss'}\n") (some (0 - Format.getIndent (← getOptions)))
```
It was working before, but it relied on how the expected type is
propagated. The elaborator process
```
some (0 - Format.getIndent (← getOptions))
```
with expected type `(Option Int)`. So, the `-` is interpreted as
`Int.sub` although `Format.getIndent (← getOptions)` has type `Nat`.
In the new `HSub`, the expected type doesn't really influence TC
resolution since it is an `outparam`. So, we failed with the error
failed to synthesize `HSub Nat Nat Int`.
One possible fix was to add the instance `HSub Nat Nat Int` with
`Int.sub`, but I used the following fix
```
some ((0 : Int) - Format.getIndent (← getOptions))
```
which makes it clear that we want the `Int.sub` operator instead of
`Nat.sub`.
2020-12-01 14:02:46 -08:00
..
.gitignore feat: stop compiling Lean code as C++, remove --cpp option 2020-05-14 14:45:33 +02:00
accumulate_profile.py feat: separate benchmark for profiling the stdlib per-file 2020-10-29 11:53:03 +01:00
arith_eval.ml chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
binarytrees.ghc-6.hs chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
binarytrees.lean chore: move tests to new frontend 2020-10-23 14:07:26 -07:00
binarytrees.lean.args chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
binarytrees.lean.expected.out chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
binarytrees.ocaml-2.ml chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
binarytrees.swift feat(tests/bench): add safe binarytrees.swift from https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/binarytrees-swift-1.html 2019-05-30 19:33:38 +02:00
compile.sh chore: factor out and unify common test behavior; retrieve lean from PATH 2020-05-14 14:38:52 +02:00
const_fold.hs chore(tests/bench): rename benchmarks 2019-05-30 16:25:41 +02:00
const_fold.lean chore: avoid Has prefix in type classes 2020-10-27 18:29:19 -07:00
const_fold.lean.args chore: lower const_fold inputs again to prevent stack overflow in sanitized build 2020-02-28 13:23:39 +01:00
const_fold.lean.expected.out chore: lower const_fold inputs again to prevent stack overflow in sanitized build 2020-02-28 13:23:39 +01:00
const_fold.ml chore(tests/bench): rename benchmarks 2019-05-30 16:25:41 +02:00
const_fold.sml chore(tests/bench): rename benchmarks 2019-05-30 16:25:41 +02:00
const_fold.swift chore(tests/bench): rename benchmarks 2019-05-30 16:25:41 +02:00
cross.nix chore: update cross benchsuite 2020-08-21 16:05:40 +02:00
cross.yaml chore: update cross benchsuite 2020-08-21 16:05:40 +02:00
deriv.hs chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
deriv.lean chore: avoid Has prefix in type classes 2020-10-27 18:29:19 -07:00
deriv.lean.args chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
deriv.lean.expected.out chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
deriv.ml chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
deriv.sml chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
deriv.swift test(tests/bench): add deriv.swift 2019-05-30 11:34:58 -07:00
disable-st.patch chore: update cross benches 2020-08-18 11:44:29 +02:00
full-stdlib.exec.yaml feat: separate benchmark for profiling the stdlib per-file 2020-10-29 11:53:03 +01:00
ghc-gc.py chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
lean-gc.py chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
Makefile chore: update cross benchsuite 2020-08-21 16:05:40 +02:00
mlkit-gc.py chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
nixpkgs.nix chore: update cross benches 2020-08-18 11:44:29 +02:00
ocaml-gc.py chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
perf.py chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
qsort.hs chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
qsort.lean refactor: heterogeneous operators 2020-12-01 14:02:46 -08:00
qsort.lean.args chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
qsort.lean.expected.out test(tests/bench): add benchmarks as regular ctests with lowered inputs 2019-09-02 10:52:24 +02:00
qsort.ml chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
qsort.sml chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
qsort.swift feat(tests/bench): add qsort.swift 2019-05-31 00:40:09 +02:00
rbmap.hs chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
rbmap.lean chore: move tests to new frontend 2020-10-23 14:07:26 -07:00
rbmap.lean.args chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
rbmap.lean.expected.out chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
rbmap.library.lean chore(*): update equation syntax in files and old parser 2019-08-09 11:11:34 +02:00
rbmap.ml chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
rbmap.sml chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
rbmap.swift tests(tests/bench): add rbmap.swift 2019-05-30 14:47:06 -07:00
rbmap2.lean chore(tests/bench): fix benchmarks 2019-08-10 12:52:42 +02:00
rbmap3.lean chore: avoid Has prefix in type classes 2020-10-27 18:29:19 -07:00
rbmap4.lean chore(tests/bench): fix benchmarks 2019-08-10 12:52:42 +02:00
rbmap500k.lean chore(tests/bench/rbmap500k): add new test 2019-09-11 18:01:56 -07:00
rbmap_checkpoint.hs chore: cross bench suite: fix fatal laziness in rbmap_checkpoint.hs 2019-11-15 16:39:14 +01:00
rbmap_checkpoint.lean chore: move tests to new frontend 2020-10-23 14:07:26 -07:00
rbmap_checkpoint.lean.args chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
rbmap_checkpoint.lean.expected.out chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
rbmap_checkpoint.ml test(tests/bench/rbmap_checkpoint): OCaml version using myLen 2019-05-30 07:40:53 -07:00
rbmap_checkpoint.sml chore(tests/bench/rbmap_checkpoint): use myLean 2019-05-30 07:30:07 -07:00
rbmap_checkpoint.swift test(tests/bench/rbmap_checkpoint): add swift version 2019-05-30 14:35:58 -07:00
rbmap_checkpoint2.lean chore(tests/bench): fix benchmarks 2019-08-10 12:52:42 +02:00
rbmap_checkpoint2.sml chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
rbmap_checkpoint_cpp_lean3.cpp test(tests/bench): add C++ versions of rbmap benchmarks 2019-06-22 06:58:27 -07:00
rbmap_checkpoint_cpp_std.cpp test(tests/bench): add C++ versions of rbmap benchmarks 2019-06-22 06:58:27 -07:00
rbmap_cpp_lean3.cpp test(tests/bench): add C++ versions of rbmap benchmarks 2019-06-22 06:58:27 -07:00
rbmap_cpp_std.cpp test(tests/bench): add C++ versions of rbmap benchmarks 2019-06-22 06:58:27 -07:00
README.md chore: bench cross suite: move default.nix and update README 2019-11-15 16:39:14 +01:00
report.py chore: fix cross bench suite 2019-11-15 16:39:14 +01:00
run.sh chore(tests/bench): move out from playground/ 2019-05-29 16:33:50 +02:00
speedcenter.exec.velcom.yaml chore: remove broken & redundant "new parser Core.lean" benchmark 2020-11-13 21:08:46 +01:00
speedcenter.yaml chore: remove old speedcenter config 2020-10-29 11:53:03 +01:00
test_single.sh chore: factor out and unify common test behavior; retrieve lean from PATH 2020-05-14 14:38:52 +02:00
unionfind.lean chore: move tests to new frontend 2020-10-23 14:07:26 -07:00
unionfind.lean.args chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
unionfind.lean.expected.out chore: adjust "small" bench/ inputs to be reasonable for interpreter 2020-02-28 10:04:13 +01:00
unionfind_clean.lean chore(frontends/lean): use => instead of := in match-expressions 2019-07-04 11:38:38 -07:00

Lean Benchmark Suites

This folder contains multiple small Lean programs for benchmarking used by two separate benchmark suites based on the temci benchmarking tool:

  • The light-weight "Speedcenter" suite benchmarks the current build of Lean. It can be used for quick comparisons on the cmdline and powers the Lean Speedcenter website.
  • The heavy-weight "Cross" suite benchmarks multiple Lean configurations and other functional compilers against each other and generates CSV and HTML reports from that. It was created for the paper "Counting Immutable Beans - Reference Counting Optimized for Purely Functional Programming" (IFL19).

Speedcenter Suite

Requirements:

  • A local Lean build in ../../build/release. Build at least the bin target.
  • temci. Using Nix, open a nix-shell in the project root directory to add a compatible version to your PATH. Alternatively, try pip3 install git+https://github.com/parttimenerd/temci.git.

To execute the suite and save the results in base.yaml, run (in this folder)

temci exec --config speedcenter.yaml --out base.yaml

Other interesting exec flags:

  • use --runs N to modify the default number of 10 runs per benchmark
  • use --included_blocks fast to excluded slow benchmarks like the stdlib benchmark. You can replace fast with any benchmark name or label in speedcenter.exec.yaml.

If you have multiple saved result files, you can compare them with

temci report --config speedcenter.yaml report1.yaml report2.yaml ...

Cross Suite

We recommend using Nix for building/obtaining all Lean variants and used compilers in a reproducible way. After installing Nix, running the benchmarks is as easy as

nix-shell cross.nix --pure --run make

This will record 50 runs for each benchmark configuration (this can be changed with runs in cross.yaml), generate results in report_lean.csv and report_cross.csv, and print them to stdout in a tabulated format. It will also generate HTML reports in report/ comparing the time-based benchmarks.

In order to reduce noise in the benchmarking data, you may instead want to try calling make inside a temci shell:

nix-shell cross.nix --pure --run "temci short shell --sudo --preset usable --cpuset_active make"

Using root powers, this will temporarily configure your machine similarly to the LLVM benchmarking recommendations and move all your other processes to a single CPU core.