Staged meta-programming, new LMS frontend and computation graphs |
|
Ruben Fiszel
LAMP at EPFL
Supervised by
Nada Amin and Prof. Odersky
Semester project II
def f(x: Array[Int], y: Rep[Array[Int]]) => x.zip(y).map(_*_).sum
def g(y: Array[Int]) = f(Array(0, 1, 0, 0, 0), y)
val g = (x: Array[Int]) => x(1)
//Optimisations used: (1*a) = a, (0+a) = a, (0*a) = 0
def f(x: Array[Int], y: Array[Int]) => x.zip(y).map(_*_).sum
def g(y: Array[Int]) = f(Array(0, 1, 0, 0, 0), y)
def matchsearch(regexp: String, text: String): Boolean = ...
def matchsearch(regexp: String, text: Rep[String]): Boolean = ...
//GEN CODE
def f(x: String) = ... //small specialized function for "hello" regex search
//usage
f("hello")
def f(x: String) = compile((x:Rep[String]) => matchsearch("^hello$", x))
Construct the IR from the meta program
Offer common data structures and controls as batteries
Transform the IR and finally generates the object program
trait Exp[+T]
case class Const[T](x: T) extends Exp[T]
case class Sym[T](id: Int) extends Exp[T]
trait Def[+T]
implicit def toAtom(d: Def[T]): Exp[T]
//defined elsewhere
a: Sym[Int](0)
b: Sym[Int](1)
b*(2+a) //user-code is transformed into IR
IntTimes(Sym(1), IntPlus(Const(2), Sym(0)): Exp[Int]
trait IntDsl {
def infix_plus(e1: Rep[Int], e2: Rep[Int]): Rep[Int]
}
trait IntExp extends IntDsl with BaseExp {
case class IntPlus(e1: Exp[Int], e2: Exp[Int]) extends Def[Int]
def infix_plus(e1: Exp[Int], e2: Exp[Int]) = IntPlus(e1, e2)
}
def ifThenElse[A: Rep](a: Boolean, b: A, c: A): A
case class Int(e: Exp[scala.Int]) {
def +(y: Int) = IntPlus(e, y.e)
}
implicit def repInt: Rep[Int] = ...
trait Rep[T] {
type Internal
def from(e:Exp[Internal]): T
def to(x:T):Exp[Internal]
def m: Manifest[Internal] //for reflection purposes
}
trait Prog extends Ints {
//the old way
def ackermann(m: Int): Rep[Int => Int]
= fun {
(n: Rep[Int]) =>
if (m==0) n+1
else if (n==0) a(m-1)(1)
else a(m-1)(a(m)(n-1))
}
}
trait Prog extends Ints {
//the new way
def ackermann(m: scala.Int): Int => Int
(n: Int) =>
if (m==0) n+1
else if (n==0) a(m-1)(1)
else a(m-1)(a(m)(n-1))
}
}
trait ProgImpl extends Prog with IntOptImpl
trait Compile extends ScalaCompile {
self: IntExp =>
val codegen = new ScalaGenInt {
val IR:self.type = self
}
}
object App extends ProgImpl with Compile {
val compiled = compile(prog)
compiled(2)
compiled(3)
}