|
1 | 1 |
|
| 2 | +# Structure |
| 3 | + |
| 4 | +- `src/core` has key algorithms and `src/syntax` key concepts; these |
| 5 | + are the most critical and highest value parts of the project. Should |
| 6 | + be fast and effective, complex algorithms could well be worth it. |
| 7 | +- `src/core/explain.rkt` and `src/core/localize.rkt` are sorta-kinda |
| 8 | + deprecated. Keep them working, but can get slower or worse. |
| 9 | +- The rest of `src` is, conceptually, glue code. Simple is best, |
| 10 | + optimize for maintainability. All of `src` goes through human code |
| 11 | + review and should match surrounding style. |
| 12 | +- Modules layer `utils < syntax < core < reports < api`. Lower layers |
| 13 | + do not import higher layers. |
| 14 | +- `infra/` is for development only. Some code in there is abandon-ware |
| 15 | + of AI-written and unreviewed. Don't reference for code style and not |
| 16 | + all features in there are actually used. Changing users often easier |
| 17 | + than code heroics. |
| 18 | + |
2 | 19 | # Formatting |
3 | 20 |
|
4 | 21 | - Use `map` over `for/list` only if it avoids a `lambda`. |
|
7 | 24 | - Do not code defensively. Do not do runtime type checks or fallback. |
8 | 25 | Prefer to examine all callers to establish types, or if they can |
9 | 26 | differ prefer `match` with explicit patterns for all cases, to |
10 | | - ensure that an unanticipated values at any point cause errors. |
| 27 | + ensure that unanticipated value cause explicit errors. |
11 | 28 | - Format Racket code with `make fmt` at the top level. |
12 | 29 | - Check `git diff` and delete dead code before finishing a task. |
13 | 30 | - Update docs in `www/doc/2.3/` if you change user-visible options. |
14 | | -- Enforce module layering `utils < syntax < core < reports < api`: do not add imports from a lower layer to a higher layer. |
15 | 31 |
|
16 | 32 | # Testing |
17 | 33 |
|
18 | 34 | - If you change the Herbie core, test that your changes work with |
19 | 35 | `racket src/main.rkt report bench/tutorial.fpcore tmp`. This should |
20 | 36 | take about 5-10 seconds and all of the tests should pass with |
21 | 37 | perfect accuracy. You can also use other benchmark suites if asked. |
22 | | -- If you need to store two reports name the folders `tmp-X` for some X. |
23 | 38 | - Arguments come after the word `report` before any other arguments. |
24 | | -- Herbie prints a seed every time it runs; you can pass `--seed N` |
25 | | - after the "report" argument to fix the seed reproducibly. |
26 | | -- You can pass `--timeout T` to time out a benchmark after T seconds. |
27 | | -- After running tests, `tmp` will have one directory per benchmark. |
| 39 | +- Herbie prints a seed every time it runs; pass `--seed N` for |
| 40 | + reproducibility. |
| 41 | +- Pass `--timeout T` to time out a benchmark after T seconds. |
28 | 42 | Each has a detailed `graph.html`, including tracebacks for crashes. |
| 43 | +- After running tests, `tmp` will have one directory per benchmark. |
| 44 | +- For multiple reports name the folders `tmp-<whatever>`. |
29 | 45 | - The default e-graph backend is `egg`; pass `--enable generate:egglog` |
30 | | - to enable the `egglog` backend. You may need to add `~/.cargo/bin` |
31 | | - to the `PATH`. |
| 46 | + to enable the `egglog` backend. |
32 | 47 | - Some files have unit tests; run them with `raco test <file>`. |
33 | 48 |
|
34 | 49 | # Observability |
35 | 50 |
|
36 | | -- `jq` is installed, use it |
37 | 51 | - If you're investigating a single benchmark, copy it to a file named |
38 | 52 | `test.fpcore` and run just that file. |
39 | 53 | - Herbie runs output a `tmp/<benchmark>/timeline.json` with rich |
40 | 54 | observability data for each benchmark. |
41 | | -- A timeline is a list of phases, each a map from key to "table", |
| 55 | +- This timeline is a list of phases, each a map from key to "table", |
42 | 56 | each table is a list of fixed-length arrays. |
43 | 57 | - Timeline types are defined in `src/utils/timeline.rkt`; HTML |
44 | 58 | generation is defined in `src/reports/timeline.rkt`. |
45 | 59 | - Add to the timeline with `(timeline-push! 'type val1 val2 ...)`. The |
46 | 60 | `val`s must be JSON-compatible, so convert symbols to strings. |
47 | | -- Herbie runs generates a profile in `tmp/<benchmark>/profile.json`. |
| 61 | +- Herbie runs generate a profile in `tmp/<benchmark>/profile.json`. |
48 | 62 | - You can also dump GC/memory data to `dump-trace.json` with `--enable |
49 | 63 | dump:trace`, Rival commands with `--enable dump:rival`, and egglog |
50 | 64 | commands with `--enable dump:egglog`. Dumps go in `dump-XXX` in the |
51 | | - current directory. Clean that directory when done. |
| 65 | + current directory. New runs *add files* to those directories, so |
| 66 | + clean up when done. |
0 commit comments