Giter Site home page Giter Site logo

etch's Introduction

Etch

This repository implements indexed streams, a representation for fused contraction programs like those found in sparse tensor algebra and relational algebra.

Correctness proofs and compiler are written in the Lean 4 language.

Directory structure

Compiler and benchmarks

etch4
├── Etch                          # the compiler
│   ├── Basic.lean                # compiler core
│   ├── C.lean
│   ├── Compile.lean
│   ├── LVal.lean
│   ├── Op.lean
│   ├── ShapeInference.lean
│   ├── Stream.lean
│   ├── Add.lean                  # basic streams
│   ├── Mul.lean
│   ├── Benchmark.lean            # benchmark queries
│   ├── Benchmark
│   │   └── ...
│   ├── Verification              # stream model formalization
│   │   └── README.md
│   ├── KRelation.lean            # work in progress
│   ├── Omni.lean
│   └── InductiveStream…
├── Makefile                      # workflows
├── bench                         # benchmark auxiliary files (SQL files, data generators, etc.)
│   └── ...
├── bench-….cpp                   # benchmark drivers
├── common.h
├── operators.h
├── graphs                        # run benchmarks; plot graphs
│   └── ...
├── taco                          # TACO-compiled kernels as baseline
│   └── ...
└── taco_kernels.c

Build compiler and proofs

First install Lean 4. In the etch4 directory, run

lake update
lake exe cache get
lake build

Then, load Etch/Benchmark.lean in your editor.

Compile benchmarks

While loading the Etch/Benchmark.lean in your editor, Lean will automatically compile all the benchmarks and write them to etch4/gen_….c.

Alternatively, you can compile by running make gen_tpch_q5.c FORCE_REGEN=1.

Running benchmarks

Only Linux is supported right now.

Dependencies you need to have before running any benchmarks:

Other dependencies (e.g., baselines) are automatically downloaded by the Makefile.

Run individual benchmarks

You can run an individual benchmark by calling make. Here are some examples:

make run-tpch-x1-q5-duckdb
make run-tpch-x1-q5-duckdbforeign
make run-tpch-x1-q5-etch
make run-tpch-x1-q5-sqlite

make run-wcoj-x1000-etch

If any test data need to be (re-)generated, the above commands will automatically do so.

For a full list of supported targets, run make list-benchmarks.

Run all benchmarks

Run graphs/run.sh. This will run all the benchmarks shown in our PLDI 2023 paper, and save the results in bench-output/.

Note: this will take a long time (≥1.5 hours).

Generate graphs

Make sure all the benchmarks have been run with graphs/run.sh.

Make sure the benchmark results are stored in bench-output/.

Make sure you have Poetry (a Python package manager) installed.

Then run:

cd graphs
poetry install
poetry shell
cd ..
python graphs/graph.py

Graphs will be generated in PDF form in the root directory.

Running benchmarks in Docker

We also provide a Dockerfile to simplify the process of setting up an environment. This is primarily useful for artifact evaluation. See graphs/Dockerfile for details.

If you will be developing Etch locally, we recommend going through the previous steps instead.

Publications

This repository implements indexed streams as defined in the paper:

Scott Kovach, Praneeth Kolichala, Tiancheng Gu, and Fredrik Kjolstad. 2023. Indexed Streams: A Formal Intermediate Representation for Fused Contraction Programs. To appear in Proc. ACM Program. Lang. 7, PLDI, Article 154 (June 2023), 25 pages. https://doi.org/10.1145/3591268

Old Correctness proofs

These were written originally but recently automatically ported to Lean4.

.
└── src
    └── verification
        ├── code_generation           # WIP code generation proofs
        │   └── ...
        ├── semantics                 # correctness proofs
        │   ├── README.md
        │   └── ...
        └── test.lean

Build old proofs

First install Lean 3. In the root directory, run

leanproject get-mathlib-cache
leanproject build

etch's People

Contributors

david-broman avatar fredrikbk avatar kmill avatar kovach avatar prakol16 avatar timothygu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

etch's Issues

Etch/StreamFusion/Proofs/StreamMul.lean:148:8: error: tactic 'rewrite' failed, did not find instance of the pattern in the target expression

./././Etch/StreamFusion/Proofs/StreamMul.lean:148:8: error: tactic 'rewrite' failed, did not find instance of the pattern in the target expression
(evalMultiset a (a.seek (mul.valid.fst q) ((mul a b).index q, (mul a b).ready q))) j
case pos
ι : Type
inst✝³ : LinearOrder ι
α : Type u
inst✝² : NonUnitalNonAssocSemiring α
a b : Stream ι α
inst✝¹ : IsStrictLawful a
inst✝ : IsStrictLawful b
q : { q // (mul a b).valid q = true }
j : ι
hj : ((mul a b).index q, (mul a b).ready q) ≤ (j, false)
⊢ (eval a (a.seek (mul.valid.fst q) ((mul a b).index q, (mul a b).ready q))) j *
(eval b (b.seek (mul.valid.snd q) ((mul a b).index q, (mul a b).ready q))) j =
(eval a ↑(mul.valid.fst q)) j * (eval b ↑(mul.valid.snd q)) j
./././Etch/StreamFusion/Proofs/StreamMul.lean:173:28: error: tactic 'rewrite' failed, did not find instance of the pattern in the target expression
(evalMultiset ?m.79551 (?m.79551.seek ?q ?i)) ?j
case e_a
ι : Type
inst✝³ : LinearOrder ι
α : Type u
inst✝² : NonUnitalNonAssocSemiring α
a b : Stream ι α
inst✝¹ : IsStrictLawful a
inst✝ : IsStrictLawful b
q : { q // (mul a b).valid q = true }
i : Lex (ι × Bool)
j : ι
h : i ≤ (j, false)
⊢ (eval a (a.seek (mul.valid.fst q) i)) j = (eval a (↑q).1) j
./././Etch/StreamFusion/Proofs/StreamMul.lean:173:28: error: tactic 'rewrite' failed, did not find instance of the pattern in the target expression
(evalMultiset ?m.79652 (?m.79652.seek ?q ?i)) ?j
case e_a
ι : Type
inst✝³ : LinearOrder ι
α : Type u
inst✝² : NonUnitalNonAssocSemiring α
a b : Stream ι α
inst✝¹ : IsStrictLawful a
inst✝ : IsStrictLawful b
q : { q // (mul a b).valid q = true }
i : Lex (ι × Bool)
j : ι
h : i ≤ (j, false)
⊢ (eval b (b.seek (mul.valid.snd q) i)) j = (eval b (↑q).2) j
./././Etch/StreamFusion/Proofs/StreamMul.lean:173:52: warning: aesop: failed to prove the goal after exhaustive search.
./././Etch/StreamFusion/Proofs/StreamMul.lean:173:52: warning: aesop: failed to prove the goal after exhaustive search.
./././Etch/StreamFusion/Proofs/StreamMul.lean:171:66: error: unsolved goals
ι : Type
inst : LinearOrder ι
α : Type u
inst_1 : NonUnitalNonAssocSemiring α
a b : Stream ι α
inst_2 : IsStrictLawful a
inst_3 : IsStrictLawful b
i : Lex (ι × Bool)
j : ι
h : i ≤ (j, false)
val : (mul a b).σ
property : (mul a b).valid val = true
⊢ (eval a (a.seek (mul.valid.fst { val := val, property := property }) i)) j = (eval a val.1) j

ι : Type
inst : LinearOrder ι
α : Type u
inst_1 : NonUnitalNonAssocSemiring α
a b : Stream ι α
inst_2 : IsStrictLawful a
inst_3 : IsStrictLawful b
i : Lex (ι × Bool)
j : ι
h : i ≤ (j, false)
val : (mul a b).σ
property : (mul a b).valid val = true
⊢ (eval b (b.seek (mul.valid.snd { val := val, property := property }) i)) j = (eval b val.2) j
./././Etch/StreamFusion/Proofs/StreamMul.lean:177:15: error: type mismatch
mul_seek_spec a b
has type
∀ (q : { q // (mul a b).valid q = true }) (i : Lex (ι × Bool)) (j : ι),
i ≤ (j, false) → (eval (mul a b) ((mul a b).seek q i)) j = (eval (mul a b) ↑q) j : Prop
but is expected to have type
∀ (q : { x // (mul a b).valid x = true }) (i : StreamOrder ι) (j : ι),
i ≤ (j, false) → (evalMultiset (mul a b) ((mul a b).seek q i)) j = (evalMultiset (mul a b) ↑q) j : Prop

Etch/StreamFusion/Proofs/Imap.lean:60:4: error: tactic 'apply' failed, failed to unify

./././Etch/StreamFusion/Proofs/Imap.lean:60:4: error: tactic 'apply' failed, failed to unify
(evalMultiset s (s.seek ?q ?i)) ?j = (evalMultiset s ↑?q) ?j
with
(eval s (s.seek q (g (s.index q) j₁, b))) i = (eval s ↑q) i
case pos
ι ι' : Type
inst✝³ : LinearOrder ι
inst✝² : LinearOrder ι'
α : Type u_1
s : Stream ι α
inst✝¹ : AddZeroClass α
inst✝ : IsLawful s
f : ι → ι'
g : ι → ι' → ι
hf : Monotone f
hg : ∀ (j : ι'), Monotone fun x => g x j
hfg : ∀ (i : ι) (j : ι'), compareOfLessAndEq j (f i) = compareOfLessAndEq (g i j) i
this : IsBounded (imap_general f g s)
q : { x // s.valid x = true }
j₁ : ι'
b : Bool
i : ι
hj : (j₁, b) ≤ (f i, false)
le : s.index q ≤ i
⊢ (eval s (s.seek q (g (s.index q) j₁, b))) i = (eval s ↑q) i

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.