├── .gitignore
├── README.md
├── dots
├── applyLin-t21.dot
├── applyLin-t22.dot
├── applyLin-v23.dot
├── applyLin-v34.dot
├── applyLin-v42.dot
├── applyLin-v45.dot
├── bitonic-up-1.dot
├── bitonic-up-2.dot
├── bitonic-up-3.dot
├── bitonic-up-4.dot
├── composeLin-t222.dot
├── composeLin-t232.dot
├── composeLin-v234.dot
├── crcSKf-rt2-no-opt.dot
├── crcSKf-rt2.dot
├── dotsp-pt1.dot
├── dotsp-pt2.dot
├── dotsp-pt3.dot
├── dotsp-pt4.dot
├── dotsp-t2t2.dot
├── dotsp-v3t2.dot
├── evalPoly-rt4.dot
├── fibS.dot
├── lsumsp-lt4.dot
├── lsumsp-rt4.dot
├── lsumsp-rt5.dot
├── map-t3.dot
├── map-t4.dot
├── map-v6.dot
├── powers-rt4-no-opt.dot
├── powers-rt4.dot
├── shiftR-iota-v3.dot
├── sum-2.dot
├── sum-4a.dot
├── sum-4b.dot
├── sum-p.dot
├── sum-t4.dot
├── sum-v6-0.dot
├── sum-v6.dot
├── sumSquare-p.dot
├── sumSquare-t2.dot
├── sumSquare-t3.dot
├── sumSquare-t4.dot
├── transpose-pt4.dot
└── transpose-t4p.dot
├── haskell-to-hardware.lhs
├── macros.tex
├── makefile
├── mine.fmt
├── notes.md
└── todo.md
/.gitignore:
--------------------------------------------------------------------------------
1 | figures/*.pdf
2 | *~
3 | Junk*
4 | Old*
5 | Stuff
6 | Unused/
7 |
8 | *.aux
9 | *.log
10 | *.nav
11 | *.out
12 | *.ptb
13 | *.snm
14 | *.toc
15 |
16 | haskell-to-hardware.tex
17 | haskell-to-hardware.pdf
18 |
19 | web-token
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Talk: *From Haskell to Hardware via CCCs*
2 |
3 | This talk describes my project at Tabula Inc for compiling Haskell to hardware.
4 |
5 | * [My blog](http://conal.net/blog) contains a few articles about the approach to compiling Haskell to hardware.
6 | * You can find [the slides (PDF)](http://conal.net/talks/haskell-to-hardware.pdf) in [my talks folder](http://conal.net/talks/).
7 | * There is a [video of the BayHac 2015 version](http://begriffs.com/posts/2015-06-28-haskell-to-hardware.html), thanks to Joe Nelson.
8 | * The compiler is being [developed openly](https://github.com/conal/lambda-ccc/) and is shared freely.
9 | * I gave an earlier version of this talk first at IFIP Working Group 2.8 (functional programming) in 2014 and a [newer version](https://galois.com/blog/2015/04/tech-talk-haskell-hardware-via-cccs/) at Galois in Portland in April 2015.
10 | The video isn't as good as the BayHac version, however, so I don't recommend it.
11 | * There is a [Reddit discussion of the slides](https://www.reddit.com/r/haskell/comments/31yy5z/from_haskell_to_hardware_via_cccs/) (Galois version).
12 |
13 | Abstract:
14 |
15 |
16 |
17 | For the last several years, speed improvements in computing come mainly from increasing parallelism. Imperative programming, however, makes parallelization very difficult due to the many possible dependencies implied by effects. For decades, pure functional programming has held the promise of parallel execution while retaining the very simple semantics that enables practical, rigorous reasoning. This talk describes a prototype compiler from Haskell (not a library) to low-level hardware descriptions for massively parallel execution on reprogrammable logic devices. The compiler works by monomorphizing, miscellaneous other transformations, and conversion to the vocabulary of cartesian closed categories (CCCs), as captured in a small collection of Haskell type classes. One instance of those classes provides an interpretation as parallel circuits. I will show many examples of simple Haskell programs and corresponding compiler-generated circuits.
18 |
19 |
20 |
--------------------------------------------------------------------------------
/dots/applyLin-t21.dot:
--------------------------------------------------------------------------------
1 | digraph applyLin_t21 {
2 | rankdir=LR;
3 | node [shape=Mrecord];
4 | bgcolor=transparent;
5 | ranksep=1.5;
6 | c0 [label="{In|{|||||||||||}}"];
7 | c1 [label="{{|}|Out}"];
8 | c2 [label="{{|}|+|{}}"];
9 | c3 [label="{{|}|+|{}}"];
10 | c4 [label="{{|}|+|{}}"];
11 | c5 [label="{{|}|+|{}}"];
12 | c6 [label="{{|}|+|{}}"];
13 | c7 [label="{{|}|+|{}}"];
14 | c8 [label="{{|}|×|{}}"];
15 | c9 [label="{{|}|×|{}}"];
16 | c10 [label="{{|}|×|{}}"];
17 | c11 [label="{{|}|×|{}}"];
18 | c12 [label="{{|}|×|{}}"];
19 | c13 [label="{{|}|×|{}}"];
20 | c14 [label="{{|}|×|{}}"];
21 | c15 [label="{{|}|×|{}}"];
22 | c4:Out0 -> c1:In0 [label="32",fontsize=10];
23 | c7:Out0 -> c1:In1 [label="32",fontsize=10];
24 | c8:Out0 -> c2:In0 [label="32",fontsize=10];
25 | c9:Out0 -> c2:In1 [label="32",fontsize=10];
26 | c10:Out0 -> c3:In0 [label="32",fontsize=10];
27 | c11:Out0 -> c3:In1 [label="32",fontsize=10];
28 | c2:Out0 -> c4:In0 [label="32",fontsize=10];
29 | c3:Out0 -> c4:In1 [label="32",fontsize=10];
30 | c12:Out0 -> c5:In0 [label="32",fontsize=10];
31 | c13:Out0 -> c5:In1 [label="32",fontsize=10];
32 | c14:Out0 -> c6:In0 [label="32",fontsize=10];
33 | c15:Out0 -> c6:In1 [label="32",fontsize=10];
34 | c5:Out0 -> c7:In0 [label="32",fontsize=10];
35 | c6:Out0 -> c7:In1 [label="32",fontsize=10];
36 | c0:Out0 -> c8:In0 [label="32",fontsize=10];
37 | c0:Out8 -> c8:In1 [label="32",fontsize=10];
38 | c0:Out1 -> c9:In0 [label="32",fontsize=10];
39 | c0:Out9 -> c9:In1 [label="32",fontsize=10];
40 | c0:Out2 -> c10:In0 [label="32",fontsize=10];
41 | c0:Out10 -> c10:In1 [label="32",fontsize=10];
42 | c0:Out3 -> c11:In0 [label="32",fontsize=10];
43 | c0:Out11 -> c11:In1 [label="32",fontsize=10];
44 | c0:Out4 -> c12:In0 [label="32",fontsize=10];
45 | c0:Out8 -> c12:In1 [label="32",fontsize=10];
46 | c0:Out5 -> c13:In0 [label="32",fontsize=10];
47 | c0:Out9 -> c13:In1 [label="32",fontsize=10];
48 | c0:Out6 -> c14:In0 [label="32",fontsize=10];
49 | c0:Out10 -> c14:In1 [label="32",fontsize=10];
50 | c0:Out7 -> c15:In0 [label="32",fontsize=10];
51 | c0:Out11 -> c15:In1 [label="32",fontsize=10];
52 | }
53 |
54 | // Components: 6 add, 8 mul, 14 total. Depth: 3.
55 |
--------------------------------------------------------------------------------
/dots/applyLin-t22.dot:
--------------------------------------------------------------------------------
1 | digraph {
2 | rankdir=LR;
3 | node [shape=Mrecord];
4 | // ratio=1;
5 | ranksep=2.5;
6 | c0 [label="{In|{|||||||||||||||||||}}"];
7 | c1 [label="{{|}|×|{}}"];
8 | c2 [label="{{|}|×|{}}"];
9 | c3 [label="{{|}|×|{}}"];
10 | c4 [label="{{|}|×|{}}"];
11 | c5 [label="{{|}|+|{}}"];
12 | c6 [label="{{|}|+|{}}"];
13 | c7 [label="{{|}|+|{}}"];
14 | c8 [label="{{|}|×|{}}"];
15 | c9 [label="{{|}|×|{}}"];
16 | c10 [label="{{|}|×|{}}"];
17 | c11 [label="{{|}|×|{}}"];
18 | c12 [label="{{|}|+|{}}"];
19 | c13 [label="{{|}|+|{}}"];
20 | c14 [label="{{|}|+|{}}"];
21 | c15 [label="{{|}|×|{}}"];
22 | c16 [label="{{|}|×|{}}"];
23 | c17 [label="{{|}|×|{}}"];
24 | c18 [label="{{|}|×|{}}"];
25 | c19 [label="{{|}|+|{}}"];
26 | c20 [label="{{|}|+|{}}"];
27 | c21 [label="{{|}|+|{}}"];
28 | c22 [label="{{|}|×|{}}"];
29 | c23 [label="{{|}|×|{}}"];
30 | c24 [label="{{|}|×|{}}"];
31 | c25 [label="{{|}|×|{}}"];
32 | c26 [label="{{|}|+|{}}"];
33 | c27 [label="{{|}|+|{}}"];
34 | c28 [label="{{|}|+|{}}"];
35 | c29 [label="{{|||}|Out}"];
36 | c0:Out0 -> c1:In0 [label="32"];
37 | c0:Out16 -> c1:In1 [label="32"];
38 | c0:Out1 -> c2:In0 [label="32"];
39 | c0:Out17 -> c2:In1 [label="32"];
40 | c0:Out2 -> c3:In0 [label="32"];
41 | c0:Out18 -> c3:In1 [label="32"];
42 | c0:Out3 -> c4:In0 [label="32"];
43 | c0:Out19 -> c4:In1 [label="32"];
44 | c1:Out0 -> c5:In0 [label="32"];
45 | c2:Out0 -> c5:In1 [label="32"];
46 | c3:Out0 -> c6:In0 [label="32"];
47 | c4:Out0 -> c6:In1 [label="32"];
48 | c5:Out0 -> c7:In0 [label="32"];
49 | c6:Out0 -> c7:In1 [label="32"];
50 | c0:Out4 -> c8:In0 [label="32"];
51 | c0:Out16 -> c8:In1 [label="32"];
52 | c0:Out5 -> c9:In0 [label="32"];
53 | c0:Out17 -> c9:In1 [label="32"];
54 | c0:Out6 -> c10:In0 [label="32"];
55 | c0:Out18 -> c10:In1 [label="32"];
56 | c0:Out7 -> c11:In0 [label="32"];
57 | c0:Out19 -> c11:In1 [label="32"];
58 | c8:Out0 -> c12:In0 [label="32"];
59 | c9:Out0 -> c12:In1 [label="32"];
60 | c10:Out0 -> c13:In0 [label="32"];
61 | c11:Out0 -> c13:In1 [label="32"];
62 | c12:Out0 -> c14:In0 [label="32"];
63 | c13:Out0 -> c14:In1 [label="32"];
64 | c0:Out8 -> c15:In0 [label="32"];
65 | c0:Out16 -> c15:In1 [label="32"];
66 | c0:Out9 -> c16:In0 [label="32"];
67 | c0:Out17 -> c16:In1 [label="32"];
68 | c0:Out10 -> c17:In0 [label="32"];
69 | c0:Out18 -> c17:In1 [label="32"];
70 | c0:Out11 -> c18:In0 [label="32"];
71 | c0:Out19 -> c18:In1 [label="32"];
72 | c15:Out0 -> c19:In0 [label="32"];
73 | c16:Out0 -> c19:In1 [label="32"];
74 | c17:Out0 -> c20:In0 [label="32"];
75 | c18:Out0 -> c20:In1 [label="32"];
76 | c19:Out0 -> c21:In0 [label="32"];
77 | c20:Out0 -> c21:In1 [label="32"];
78 | c0:Out12 -> c22:In0 [label="32"];
79 | c0:Out16 -> c22:In1 [label="32"];
80 | c0:Out13 -> c23:In0 [label="32"];
81 | c0:Out17 -> c23:In1 [label="32"];
82 | c0:Out14 -> c24:In0 [label="32"];
83 | c0:Out18 -> c24:In1 [label="32"];
84 | c0:Out15 -> c25:In0 [label="32"];
85 | c0:Out19 -> c25:In1 [label="32"];
86 | c22:Out0 -> c26:In0 [label="32"];
87 | c23:Out0 -> c26:In1 [label="32"];
88 | c24:Out0 -> c27:In0 [label="32"];
89 | c25:Out0 -> c27:In1 [label="32"];
90 | c26:Out0 -> c28:In0 [label="32"];
91 | c27:Out0 -> c28:In1 [label="32"];
92 | c7:Out0 -> c29:In0 [label="32"];
93 | c14:Out0 -> c29:In1 [label="32"];
94 | c21:Out0 -> c29:In2 [label="32"];
95 | c28:Out0 -> c29:In3 [label="32"];
96 | }
97 |
--------------------------------------------------------------------------------
/dots/applyLin-v23.dot:
--------------------------------------------------------------------------------
1 | digraph applyLin_v23 {
2 | rankdir=LR;
3 | node [shape=Mrecord];
4 | bgcolor=transparent;
5 | ranksep=1;
6 | c2 [label="{In|{|||||||}}"];
7 | c3 [label="{{||}|Out}"];
8 | c4 [label="{{|}|+|{}}"];
9 | c5 [label="{{|}|+|{}}"];
10 | c6 [label="{{|}|+|{}}"];
11 | c7 [label="{{|}|×|{}}"];
12 | c8 [label="{{|}|×|{}}"];
13 | c9 [label="{{|}|×|{}}"];
14 | c10 [label="{{|}|×|{}}"];
15 | c11 [label="{{|}|×|{}}"];
16 | c12 [label="{{|}|×|{}}"];
17 | c4:Out0 -> c3:In0 [label="32",fontsize=10];
18 | c5:Out0 -> c3:In1 [label="32",fontsize=10];
19 | c6:Out0 -> c3:In2 [label="32",fontsize=10];
20 | c7:Out0 -> c4:In0 [label="32",fontsize=10];
21 | c8:Out0 -> c4:In1 [label="32",fontsize=10];
22 | c9:Out0 -> c5:In0 [label="32",fontsize=10];
23 | c10:Out0 -> c5:In1 [label="32",fontsize=10];
24 | c11:Out0 -> c6:In0 [label="32",fontsize=10];
25 | c12:Out0 -> c6:In1 [label="32",fontsize=10];
26 | c2:Out0 -> c7:In0 [label="32",fontsize=10];
27 | c2:Out6 -> c7:In1 [label="32",fontsize=10];
28 | c2:Out1 -> c8:In0 [label="32",fontsize=10];
29 | c2:Out7 -> c8:In1 [label="32",fontsize=10];
30 | c2:Out2 -> c9:In0 [label="32",fontsize=10];
31 | c2:Out6 -> c9:In1 [label="32",fontsize=10];
32 | c2:Out3 -> c10:In0 [label="32",fontsize=10];
33 | c2:Out7 -> c10:In1 [label="32",fontsize=10];
34 | c2:Out4 -> c11:In0 [label="32",fontsize=10];
35 | c2:Out6 -> c11:In1 [label="32",fontsize=10];
36 | c2:Out5 -> c12:In0 [label="32",fontsize=10];
37 | c2:Out7 -> c12:In1 [label="32",fontsize=10];
38 | }
39 |
40 | // Components: 3 add, 6 mul, 9 total. Depth: 2.
41 |
--------------------------------------------------------------------------------
/dots/applyLin-v34.dot:
--------------------------------------------------------------------------------
1 | digraph {
2 | rankdir=LR;
3 | node [shape=Mrecord];
4 | // ratio=1;
5 | c0 [label="{In|{||||||||||||||}}"];
6 | c1 [label="{{|}|×|{}}"];
7 | c2 [label="{{|}|×|{}}"];
8 | c3 [label="{{|}|×|{}}"];
9 | c4 [label="{{|}|+|{}}"];
10 | c5 [label="{{|}|+|{}}"];
11 | c6 [label="{{|}|×|{}}"];
12 | c7 [label="{{|}|×|{}}"];
13 | c8 [label="{{|}|×|{}}"];
14 | c9 [label="{{|}|+|{}}"];
15 | c10 [label="{{|}|+|{}}"];
16 | c11 [label="{{|}|×|{}}"];
17 | c12 [label="{{|}|×|{}}"];
18 | c13 [label="{{