Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Casting ops #106

Open
wants to merge 5 commits into
base: develop-0.9.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/common/CastingOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ trait CastingOpsExp extends CastingOps with BaseExp with EffectExp {
}).asInstanceOf[Exp[A]]
}

trait CastingOpsExpOpt extends CastingOpsExp {
this: ImplicitOps =>

override def rep_isinstanceof[A,B](lhs: Exp[A], mA: Manifest[A], mB: Manifest[B])(implicit pos: SourceContext) =
if (mA <:< mB) unit(true) else super.rep_isinstanceof(lhs, mA, mB)
override def rep_asinstanceof[A,B:Manifest](lhs: Exp[A], mA: Manifest[A], mB: Manifest[B])(implicit pos: SourceContext) : Exp[B] =
if (mA == mB) lhs.asInstanceOf[Exp[B]] else super.rep_asinstanceof(lhs, mA, mB)
}

trait ScalaGenCastingOps extends ScalaGenBase {
val IR: CastingOpsExp
import IR._
Expand Down
16 changes: 8 additions & 8 deletions src/common/ImplicitOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ trait ImplicitOps extends Base {
}

trait ImplicitOpsExp extends ImplicitOps with BaseExp {
case class ImplicitConvert[X,Y](x: Exp[X])(implicit val mX: Manifest[X], val mY: Manifest[Y]) extends Def[Y]
case class ImplicitConvert[X,Y](x: Exp[X], mY: Manifest[Y])(implicit val mX: Manifest[X]) extends Def[Y]

def implicit_convert[X,Y](x: Exp[X])(implicit c: X => Y, mX: Manifest[X], mY: Manifest[Y], pos: SourceContext) : Rep[Y] = {
if (mX == mY) x.asInstanceOf[Rep[Y]] else ImplicitConvert[X,Y](x)
if (mX == mY) x.asInstanceOf[Rep[Y]] else ImplicitConvert[X,Y](x, mY)
}

override def mirror[A:Manifest](e: Def[A], f: Transformer)(implicit pos: SourceContext): Exp[A] = (e match {
case im@ImplicitConvert(x) => toAtom(ImplicitConvert(f(x))(im.mX,im.mY))(mtype(manifest[A]),pos)
case im@ImplicitConvert(x, mY) => toAtom(ImplicitConvert(f(x), mY)(im.mX))(mtype(manifest[A]),pos)
case _ => super.mirror(e,f)
}).asInstanceOf[Exp[A]]

Expand All @@ -33,9 +33,9 @@ trait ScalaGenImplicitOps extends ScalaGenBase {
import IR._

override def emitNode(sym: Sym[Any], rhs: Def[Any]) = rhs match {
// TODO: this valDef is redundant; we really just want the conversion to be a no-op in the generated code.
// TODO: but we still need to link the defs together
case ImplicitConvert(x) => emitValDef(sym, quote(x))
// Make sure it's typed to trigger the implicit conversion
// Otherwise we can get type mismatch in generated code
case ImplicitConvert(x, mY) => emitTypedValDef(sym, quote(x))
case _ => super.emitNode(sym, rhs)
}
}
Expand All @@ -46,8 +46,8 @@ trait CLikeGenImplicitOps extends CLikeGenBase {

override def emitNode(sym: Sym[Any], rhs: Def[Any]) = {
rhs match {
case im@ImplicitConvert(x) =>
gen"${im.mY} $sym = (${im.mY})$x;"
case ImplicitConvert(x, mY) =>
gen"$mY $sym = ($mY)$x;"
case _ => super.emitNode(sym, rhs)
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/common/Packages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ trait ScalaOpsPkgExp extends ScalaOpsPkg
with FunctionsExp with EqualExp with IfThenElseExp with VariablesExp with WhileExp with TupleOpsExp with ListOpsExp
with SeqOpsExp with DSLOpsExp with MathOpsExp with CastingOpsExp with SetOpsExp with ObjectOpsExp with ArrayBufferOpsExp

trait ScalaOpsPkgExpOpt extends ScalaOpsPkgExp
with ArrayOpsExpOpt with BooleanOpsExpOpt with CastingOpsExpOpt with EqualExpOpt with IfThenElseExpOpt
with ListOpsExpOpt with NumericOpsExpOpt with ObjectOpsExpOpt with OrderingOpsExpOpt with PrimitiveOpsExpOpt
with StructExpOpt with VariablesExpOpt

/**
* Code gen: each target must define a code generator package.
Expand Down
311 changes: 191 additions & 120 deletions src/common/PrimitiveOps.scala

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/internal/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ trait Config {
val verbosity = System.getProperty("lms.verbosity","0").toInt
val sourceinfo = System.getProperty("lms.sourceinfo","0").toInt
val addControlDeps = System.getProperty("lms.controldeps","true").toBoolean

val scalaExplicitTypes = System.getProperty("lms.scala.explicitTypes","false").toBoolean

// memory management type for C++ target (refcnt or gc)
val cppMemMgr = System.getProperty("lms.cpp.memmgr","malloc")
Expand Down
32 changes: 25 additions & 7 deletions src/internal/ScalaCodegen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,25 @@ trait ScalaCodegen extends GenericCodegen with Config {
fileName.substring(i + 1)
}

def emitValDef(sym: Sym[Any], rhs: String): Unit = {
val extra = if ((sourceinfo < 2) || sym.pos.isEmpty) "" else {
val context = sym.pos(0)
" // " + relativePath(context.fileName) + ":" + context.line
private def valDefExtra(sym: IR.Sym[Any]): String = {
sym.pos.headOption match {
case Some(context) if sourceinfo >= 2 =>
" // " + relativePath(context.fileName) + ":" + context.line
case _ => ""
}
stream.println("val " + quote(sym) + " = " + rhs + extra)
}


def emitValDef(sym: Sym[Any], rhs: String): Unit = {
if (scalaExplicitTypes)
emitTypedValDef(sym, rhs)
else
stream.println(src"val $sym = $rhs" + valDefExtra(sym))
}

def emitTypedValDef(sym: Sym[Any], rhs: String): Unit = {
stream.println(src"val $sym: ${sym.tp} = $rhs" + valDefExtra(sym))
}

def emitVarDef(sym: Sym[Variable[Any]], rhs: String): Unit = {
stream.println("var " + quote(sym) + ": " + remap(sym.tp) + " = " + rhs)
}
Expand Down Expand Up @@ -132,7 +143,14 @@ trait ScalaNestedCodegen extends GenericNestedCodegen with ScalaCodegen {
else
super.emitValDef(sym,rhs)
}


// special case for recursive vals
override def emitTypedValDef(sym: Sym[Any], rhs: String): Unit = {
if (recursive contains sym)
stream.println(quote(sym) + " = " + rhs) // we have a forward declaration above.
else
super.emitTypedValDef(sym,rhs)
}
}


Expand Down
4 changes: 2 additions & 2 deletions test-out/epfl/test11-stencil0.check
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ def apply(x0:Array[Double]): Array[Double] = {
val x1 = new Array[Double](20)
var x3 : Int = 0
val x14 = while (x3 < 20) {
val x4 = x3.doubleValue()
val x4 = x3.toDouble
val x5 = 2.0 * x4
val x6 = x5 + 3.0
val x7 = x3 + 1
val x8 = x7.doubleValue()
val x8 = x7.toDouble
val x9 = 2.0 * x8
val x10 = x9 + 3.0
val x11 = x6 + x10
Expand Down
51 changes: 22 additions & 29 deletions test-out/epfl/test11-stencil1.check
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
Map(Sym(10) -> Sym(16), Sym(4) -> Sym(8), Sym(6) -> Sym(12), Sym(7) -> Sym(13), Sym(11) -> Sym(17), Sym(3) -> Sym(7), Sym(5) -> Sym(9), Sym(8) -> Sym(14), Sym(9) -> Sym(15), Sym(2) -> Sym(6))
r0:
TP(Sym(3),IntDoubleValue(Sym(2)))
TP(Sym(3),IntToDouble(Sym(2)))
TP(Sym(4),DoubleTimes(Const(2.0),Sym(3)))
TP(Sym(5),DoublePlus(Sym(4),Const(3.0)))
TP(Sym(6),IntPlus(Sym(2),Const(1)))
TP(Sym(7),IntDoubleValue(Sym(6)))
TP(Sym(7),IntToDouble(Sym(6)))
TP(Sym(8),DoubleTimes(Const(2.0),Sym(7)))
TP(Sym(9),DoublePlus(Sym(8),Const(3.0)))
TP(Sym(10),DoublePlus(Sym(5),Sym(9)))
TP(Sym(11),Reflect(ArrayUpdate(Sym(1),Sym(2),Sym(10)),Summary(false,false,false,false,false,false,List(Sym(1)),List(Sym(1)),List(Sym(1)),List(Sym(1))),List(Sym(1))))
r1:
TP(Sym(12),IntPlus(Sym(2),Const(2)))
TP(Sym(13),IntDoubleValue(Sym(12)))
TP(Sym(13),IntToDouble(Sym(12)))
TP(Sym(14),DoubleTimes(Const(2.0),Sym(13)))
TP(Sym(15),DoublePlus(Sym(14),Const(3.0)))
TP(Sym(16),DoublePlus(Sym(9),Sym(15)))
TP(Sym(17),Reflect(ArrayUpdate(Sym(1),Sym(6),Sym(16)),Summary(false,false,false,false,false,false,List(Sym(1)),List(Sym(1)),List(Sym(1)),List(Sym(1))),List(Sym(1))))
r2:
TP(Sym(18),IntPlus(Sym(2),Const(3)))
TP(Sym(19),IntDoubleValue(Sym(18)))
TP(Sym(19),IntToDouble(Sym(18)))
TP(Sym(20),DoubleTimes(Const(2.0),Sym(19)))
TP(Sym(21),DoublePlus(Sym(20),Const(3.0)))
TP(Sym(22),DoublePlus(Sym(15),Sym(21)))
Expand All @@ -28,41 +28,34 @@ overlap1:
(Sym(9),Sym(15))
(Sym(6),Sym(12))
overlap2:
var inits: List(Sym(9), Sym(6)) -> List(Variable(Sym(32)), Variable(Sym(33)))
var inits: List(Sym(9), Sym(6)) -> List(Variable(Sym(25)), Variable(Sym(26)))
will become var reads: List(Sym(9), Sym(6))
will become var writes: List(Sym(15), Sym(12))
var reads: List((Sym(9),Sym(36)), (Sym(6),Sym(37)))
var reads: List((Sym(9),Sym(29)), (Sym(6),Sym(30)))
var writes: List((Sym(15),Const(())), (Sym(12),Const(())))
/*****************************************
Emitting Generated Code
*******************************************/
class staged$0 extends ((Array[Double])=>(Array[Double])) {
def apply(x0:Array[Double]): Array[Double] = {
val x1 = new Array[Double](20)
val x24 = 0.doubleValue()
val x25 = 2.0 * x24
val x26 = x25 + 3.0
val x27 = 1.doubleValue()
val x28 = 2.0 * x27
val x29 = x28 + 3.0
val x30 = x26 + x29
val x31 = x1(0) = x30
var x32: Double = x29
var x33: Int = 1
var x35 : Int = 1
val x48 = while (x35 < 20) {
val x36 = x32
val x37 = x33
val x39 = x35 + 1
val x40 = x39.doubleValue()
val x41 = 2.0 * x40
val x42 = x41 + 3.0
val x43 = x36 + x42
val x44 = x1(x37) = x43
x32 = x42
x33 = x39
val x24 = x1(0) = 8.0
var x25: Double = 5.0
var x26: Int = 1
var x28 : Int = 1
val x41 = while (x28 < 20) {
val x29 = x25
val x30 = x26
val x32 = x28 + 1
val x33 = x32.toDouble
val x34 = 2.0 * x33
val x35 = x34 + 3.0
val x36 = x29 + x35
val x37 = x1(x30) = x36
x25 = x35
x26 = x32

x35 = x35 + 1
x28 = x28 + 1
}
x1
}
Expand Down
4 changes: 1 addition & 3 deletions test-src/epfl/test11-shonan/TestStencil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class TestStencil extends FileDiffSuite {
with BooleanOps with OrderingOps
with LiftVariables with IfThenElse with Print {
def staticData[T:Manifest](x: T): Rep[T]
def infix_toDouble(x: Rep[Int]): Rep[Double]
def test(x: Rep[Array[Double]]): Rep[Array[Double]]
}
trait Impl extends DSL with Runner with ArrayOpsExpOpt with NumericOpsExpOpt
Expand All @@ -29,8 +28,7 @@ class TestStencil extends FileDiffSuite {
with IfThenElseExpOpt with PrintExp with PrimitiveOpsExp
with CompileScala { self =>
//override val verbosity = 1
def infix_toDouble(x: Rep[Int]): Rep[Double] = int_double_value(x)


val codegen = new ScalaGenNumericOps with ScalaGenStaticData with ScalaGenOrderingOps
with ScalaGenArrayOps with ScalaGenRangeOps with ScalaGenBooleanOps
with ScalaGenVariables with ScalaGenIfThenElse with ScalaGenPrimitiveOps
Expand Down
2 changes: 1 addition & 1 deletion test-src/epfl/test13-dynamic-jit/TestInterpret.scala
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ class TestInterpret extends FileDiffSuite {
trait Impl extends DSL with VectorExp with ArithExp with OrderingOpsExpOpt with BooleanOpsExp
with EqualExpOpt with IfThenElseFatExp with LoopsFatExp with WhileExp
with RangeOpsExp with PrintExp with FatExpressions with CompileScala
with NumericOpsExp with PrimitiveOpsExp with ArrayOpsExp with HashMapOpsExp with CastingOpsExp with StaticDataExp
with NumericOpsExp with PrimitiveOpsExp with ArrayOpsExp with HashMapOpsExp with CastingOpsExpOpt with StaticDataExp
with InterpretStagedExp { self =>
override val verbosity = 1
dumpGeneratedCode = true
Expand Down
2 changes: 1 addition & 1 deletion test-src/epfl/test13-dynamic-jit/TestStable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class TestStable extends FileDiffSuite {
trait Impl extends DSL with VectorExp with ArithExp with OrderingOpsExpOpt with BooleanOpsExp
with EqualExpOpt with IfThenElseFatExp with LoopsFatExp with WhileExp
with RangeOpsExp with PrintExp with FatExpressions with CompileScala
with PrimitiveOpsExp with ArrayOpsExp with HashMapOpsExp with CastingOpsExp with StaticDataExp
with PrimitiveOpsExp with ArrayOpsExp with HashMapOpsExp with CastingOpsExpOpt with StaticDataExp
with StableVarsExp { self =>
override val verbosity = 1
dumpGeneratedCode = true
Expand Down