From 68dfe53b5995913363ac3fa0240e789e6774cf8a Mon Sep 17 00:00:00 2001
From: Christiaan Baaij <christiaan.baaij@gmail.com>
Date: Sun, 13 Dec 2009 21:00:16 +0100
Subject: [PATCH] Add rest of my presentation

---
 Makefile                        |   5 +-
 christiaan/introduction.lhs     |   9 +-
 christiaan/recursion.lhs        |  63 ++++++++++++
 christiaan/reductioncircuit.lhs | 106 +++++++++++++++++++++
 christiaan/structure.lhs        | 164 ++++++++++++++++++++++++++++++++
 treeadder.pdf                   | Bin 0 -> 10052 bytes
 6 files changed, 345 insertions(+), 2 deletions(-)
 create mode 100644 christiaan/recursion.lhs
 create mode 100644 christiaan/reductioncircuit.lhs
 create mode 100644 christiaan/structure.lhs
 create mode 100644 treeadder.pdf

diff --git a/Makefile b/Makefile
index b4b9a3f..ddaa3fc 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,10 @@ LHSRCS = \
 	matthijs/introduction.lhs \
 	christiaan/introduction.lhs \
 	christiaan/fir.lhs \
-	christiaan/dotproduct.lhs
+	christiaan/dotproduct.lhs \
+	christiaan/structure.lhs \
+	christiaan/reductioncircuit.lhs \
+	christiaan/recursion.lhs
 
 LHFORMATS = \
 	talk.fmt
diff --git a/christiaan/introduction.lhs b/christiaan/introduction.lhs
index e88a32b..bb142fa 100644
--- a/christiaan/introduction.lhs
+++ b/christiaan/introduction.lhs
@@ -4,6 +4,13 @@
 \author{Christiaan Baaij}
 \date{December 14, 2009}
 
+\section{Presentation Christiaan}
 \frame{\titlepage \setcounter{framenumber}{1}}
 
-\input{christiaan/fir}
\ No newline at end of file
+\input{christiaan/fir}
+\input{christiaan/structure}
+\input{christiaan/reductioncircuit}
+\input{christiaan/recursion}
+
+\section{Questions}
+\frame{\vspace{2cm}\centerline{\Huge{Questions?}}}
\ No newline at end of file
diff --git a/christiaan/recursion.lhs b/christiaan/recursion.lhs
new file mode 100644
index 0000000..c388355
--- /dev/null
+++ b/christiaan/recursion.lhs
@@ -0,0 +1,63 @@
+\section{Recursion}
+%include talk.fmt
+\frame{
+\frametitle{Future Work: Recursion}
+\begin{itemize}
+  \item The most pressing future work is to support recursive functions.
+  \item Partially explored solution: static loop unrolling
+  \item Unexplored solution: Haskell language extensions, new source language
+\end{itemize}
+}
+
+\subsection{Static loop unrolling}
+\frame{
+\frametitle{Static loop unrolling}
+\begin{itemize}
+  \item Unroll, and simplify recursive definitions at compile time.
+  \item Explored solution: Unrolling number-guided recursive functions using Template Haskell
+\end{itemize}
+}
+
+\frame{
+\frametitle{Template Haskell}
+\begin{itemize}
+  \item Template Haskell allows for compile-time inspection, construction, and manipulation of Haskell code.
+  \item All these functions are expressible in normal Haskell
+\end{itemize}
+}
+
+\frame{
+\frametitle{Tree Adder}
+\begin{verbatim}
+$(do
+  [typ, _] <- [d|{
+treeSum :: Vector D8 (SizedWord D8) -> SizedWord D8;
+treeSum xs = undefined
+  }|]
+  [func] <- [d|{
+treeSum i xs | i < 1     = head xs
+             | otherwise = let (a,b) = split xs
+                           in (treeSum (i-1) a) + 
+                              (treeSum (i-1) b)
+  }|]
+  let func' = unroll Nothing 0 (IntegerL 3) funct
+  return [typ,func']
+)
+\end{verbatim}
+}
+
+\begin{frame}
+   \frametitle{Unrolled tree adder}
+   \begin{figure} 
+      \includegraphics[height=5cm]{treeadder} 
+    \end{figure}
+\end{frame}
+
+\subsection{Input Language}
+\frame{
+\frametitle{Input Language}
+\begin{itemize}
+  \item New source language: One of the problems is that Haskell does not properly support dependent types. Investigate languages with dependent type systems.
+  \item Haskell extentions: Invariant descriptions at the type-level.
+\end{itemize}
+}
\ No newline at end of file
diff --git a/christiaan/reductioncircuit.lhs b/christiaan/reductioncircuit.lhs
new file mode 100644
index 0000000..a4f55f6
--- /dev/null
+++ b/christiaan/reductioncircuit.lhs
@@ -0,0 +1,106 @@
+\section{Restrictions}
+%include talk.fmt
+\frame{
+\frametitle{Too Restrictive?}
+\begin{itemize}
+  \item Is CλasH too restrictive given the fact that a designer can currently not define his own vector transformations, or recursive functions for that matter?
+\end{itemize}
+}
+
+\frame{
+\frametitle{Too Restrictive?}
+\begin{itemize}
+  \item There is certainly room to increase expressivity. But we can already describe non-trivial design in CλasH.
+  \item Example: Reduction circuit
+\end{itemize}
+}
+
+\section{Reduction circuit}
+
+\frame{
+\frametitle{Reduction Circuit}
+\begin{columns}[l]
+\column{0.5\textwidth}
+\begin{figure}
+\includegraphics[height=6.5cm]{reducer}
+\end{figure}
+\column{0.5\textwidth}
+\begin{itemize}
+  \item Reduction circuit sums the floating-point values of each row in a matrix.
+  \item Non-trivial due to pipe-lined floating-point adder.
+  \item Largest restrictions are the fixed-size vectors.
+\end{itemize}
+\end{columns}
+}
+
+\begin{frame}
+   \begin{figure} 
+      \includegraphics[height=9cm]{reducerschematic} 
+    \end{figure}
+\end{frame}
+
+
+\begin{frame}
+\frametitle{FIFO Buffer}
+\begin{itemize}
+  \item Wish:
+\begin{verbatim} 
+fifo :: (State mem) (input, shift) = 
+  (State mem', out1, out2)
+  where
+    out1 | length mem == 0 = NotValid
+         | otherwise       = head mem
+    out2 | length mem < 2  = NotValid
+         | otherwise       = head (tail mem)
+    mem' = drop shift mem ++ [input]
+\end{verbatim}
+\end{itemize}
+\end{frame}
+
+\begin{frame}
+\frametitle{FIFO Buffer}
+\begin{itemize}
+  \item Reality:
+\begin{verbatim} 
+fifo :: (State (Fifo {..})) (inp, shift) = 
+  ( State (Fifo { mem = mem'
+                , ptr = ptr'     
+                })
+  , out1, out2
+  )
+  where
+    ptr'  = ptr - shift + 1
+    mem'' = replace mem ptr (Valid inp)
+    mem'  | shift == 0 = mem''
+          | shift == 1 = (tail mem'') <+ NotValid
+          | otherwise  = ((tail (tail mem'') 
+                          <+ NotValid) <+ NotValid)
+    out1  = head mem
+    out2  = head (tail mem) 
+\end{verbatim}
+\end{itemize}
+\end{frame}
+
+\frame{
+\frametitle{FIFO Buffer}
+\begin{itemize}
+  \item Wish: Dynamically sized vectors
+  \item Reality: Statically sized vectors
+\end{itemize}
+}
+
+\frame{
+\frametitle{Dynamically Sized Vectors}
+\begin{itemize}
+  \item Map all vectors to RAMs:
+  \begin{itemize}
+    \item Store length separately, extra logic
+    \item What happens if size exceeds size of 1 blockRAM?
+  \end{itemize}
+  \item Translate to (shift/circular) Buffers
+  \begin{itemize}
+  \item Requires analysis of data-access
+  \item How do we determine maximum size?
+  \end{itemize}
+\end{itemize}
+}
\ No newline at end of file
diff --git a/christiaan/structure.lhs b/christiaan/structure.lhs
new file mode 100644
index 0000000..2c81397
--- /dev/null
+++ b/christiaan/structure.lhs
@@ -0,0 +1,164 @@
+\section{Structure}
+%include talk.fmt
+\frame{
+\frametitle{Structure}
+\begin{verbatim}
+fir (State pxs) x = (pxs**hs, State (pxs<++x))
+   where hs = $(vectorTH [2::Int16,3,-2,4])
+\end{verbatim}
+\begin{itemize}
+  \item How did we know how big the circuit would have to be? e.g. How many multipliers?
+  \item The size of the circuit is determined by the size of the vectors!
+\end{itemize}
+}
+
+\frame{
+\frametitle{Structure}
+\begin{itemize}
+  \item The size of the vectors determines the size of the circuit.
+  \item How do we know the size of the vectors?
+  \begin{itemize}
+    \item We infer the size
+    \item We specify the size
+  \end{itemize}
+\end{itemize}
+}
+
+\subsection{Size Inference}
+\frame{
+\frametitle{Infer Size}
+\begin{itemize}
+  \item Determine the size by counting the elements inside, at compile-time.
+  \item Base size of new vectors based on size of other vectors of which you already know the size.
+  \item Requires a lot of bookkeeping.
+\end{itemize}
+}
+
+\frame{
+\frametitle{Infer Size}
+\begin{itemize}
+  \item Might not be possible in the general case?
+  \item What is the size of the combinatorial circuit seen below? Infinite? Zero?
+\end{itemize}
+\begin{verbatim}
+    xs ** hs = foldl (+) 0 (zipWith (*) xs hs)  
+\end{verbatim}
+}
+
+\subsection{Size Specification}
+\frame{
+\frametitle{Specify Size}
+\begin{itemize}
+  \item Have the designer specify the size of a vector.
+  \item Two ways to specify
+  \begin{itemize}
+    \item As part of each specific instance / term
+    \item As part of the type
+  \end{itemize}
+\end{itemize}
+}
+
+\frame{
+\frametitle{Some basic concepts}
+\begin{itemize}
+  \item Programming languages express computations
+  \item Computations manipulate values
+  \item Types = Set of values
+  \item Computations can be assigned types to indicate what kind of values to produce or manipulate
+\end{itemize}
+}
+
+\frame{
+\frametitle{Specify Size (term-level)}
+\begin{itemize}
+  \item Size specification at the instance / term level suffers from the same problems as size inference:
+  \begin{itemize}
+    \item Extensive bookkeeping
+    \item Compile Time-Evaluation
+    \item Generality of the solution
+  \end{itemize}
+\end{itemize}
+}
+
+\frame{
+\frametitle{Specify Size (type-level)}
+\begin{itemize}
+  \item The size of the vector becomes part of the type:
+  \begin{itemize}
+    \item Unconstrained Vectors:
+    \begin{verbatim}
+Nat n => Vector n a  
+    \end{verbatim}
+    \item Constrained Vectors:
+    \begin{verbatim}
+Vector 4 a  
+    \end{verbatim}
+  \end{itemize}
+\end{itemize}
+}
+
+\frame{
+\frametitle{Specify Size (type-level)}
+\begin{itemize}
+  \item Not only do we want to indicate the size of vectors
+  \item We also want to manipulate or query the size of a vector
+\end{itemize}
+}
+
+\frame{
+\frametitle{Size Query}
+\begin{itemize}
+  \item Sometimes we want to know something about the size of the vector
+  \item Get the first element of the vector
+  \begin{verbatim}
+first :: Positive n => Vector n a -> a
+  \end{verbatim}
+  \item Only works for vectors that are not empty
+\end{itemize}
+}
+
+\frame{
+\frametitle{Size Manipulation}
+\begin{itemize}
+  \item Sometimes we want to relate the size of one or more vectors to the size of one or more other vectors
+  \item Combine 2 vectors into 1 large vector
+  \begin{verbatim}
+combine :: Vector n1 a -> Vector n2 a -> 
+           Vector (n1 + n2) a    
+  \end{verbatim}
+\end{itemize}
+}
+
+\frame{
+\frametitle{Type-level numbers}
+\begin{itemize}
+  \item Number literals, e.g. 1, 4 , 17, etc. are not allowed in the type signature.
+  \item We must resort to so-called type-level numbers
+  \item When dealing with type-level number,s each instance is a type in it’s own right! e.g. the type-level equivalent of 3 is D3.
+\end{itemize}
+}
+
+\frame{
+\frametitle{Type-level problems}
+\begin{itemize}
+  \item Type systems demand proofs! Otherwise they are of no use to us!
+  \item When dealing with type-level numbers we suddenly have to proof invariants that we normally take for granted.
+  \item For example, commutativity of addition:\\    a + b = b + a
+\end{itemize}
+}
+
+\frame{
+\frametitle{Consequences}
+\begin{itemize}
+  \item Currently such proofs have to specified as part of the programs, and in a very cumbersome way!
+  \item We chose not to expose this need for proofs to the developer.
+  \item Result: a (limited) set of vector transformations is exposed to a developer.
+\end{itemize}
+}
+
+\frame{
+\frametitle{Consequences}
+\begin{itemize}
+  \item The largest consequence of not allowing any type of vector transforming functions is that a developer can no longer specify recursive functions!
+\end{itemize}
+}
\ No newline at end of file
diff --git a/treeadder.pdf b/treeadder.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..f547b57bb31085b991ccd13d16906c30d10c77e7
GIT binary patch
literal 10052
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
bR{WZ0PB3Ff*e{O@fIuKj1_mjm=a~NwC_UCD

literal 0
HcmV?d00001

-- 
2.30.2