Commit 2f848c4b authored by Eva Darulova's avatar Eva Darulova
Browse files

Fix abs-errors for fixed-points and regression tests

parent a76dcc9a
...@@ -129,7 +129,7 @@ object CodeGenerationPhase extends DaisyPhase { ...@@ -129,7 +129,7 @@ object CodeGenerationPhase extends DaisyPhase {
* @param fixed the (uniform) fixed-point precision to use * @param fixed the (uniform) fixed-point precision to use
// TODO: we also need to adjust the types, no? // TODO: we also need to adjust the types, no?
*/ */
private def toFixedPointCode(expr: Expr, fixed: Fixed): Expr = (expr: @unchecked) match { def toFixedPointCode(expr: Expr, fixed: Fixed): Expr = (expr: @unchecked) match {
case x @ Variable(id) => fixed match { case x @ Variable(id) => fixed match {
case Fixed(16) => Variable(id.changeType(Int32Type)) case Fixed(16) => Variable(id.changeType(Int32Type))
case Fixed(32) => Variable(id.changeType(Int64Type)) case Fixed(32) => Variable(id.changeType(Int64Type))
......
...@@ -15,36 +15,38 @@ object FinitePrecision { ...@@ -15,36 +15,38 @@ object FinitePrecision {
// if it's an integer, it's definitely representable // if it's an integer, it's definitely representable
if (r.isWhole) { if (r.isWhole) {
true true
} else if (prec == DoubleDouble || prec == QuadDouble) {
// don't want to deal with those huge number here right now,
// so return the safe answer
false
} else { } else {
val nominator = r.n.abs prec match {
val denominator = r.d.abs case DoubleDouble | QuadDouble => false
case Fixed(_) => false
val (nomBound, denomBound) = (prec: @unchecked) match { case Float32 | Float64 =>
case Float32 =>
// 2^23 - 1, 2^8 -1 val nominator = r.n.abs
(8388607l, 255l) val denominator = r.d.abs
case Float64 =>
// 2^52 - 1, 2^11 -1 val (nomBound, denomBound) = (prec: @unchecked) match {
(4503599627370496l, 2047l) case Float32 =>
} // 2^23 - 1, 2^8 -1
(8388607l, 255l)
case Float64 =>
// 2^52 - 1, 2^11 -1
(4503599627370496l, 2047l)
}
if (nominator <= nomBound && denominator <= denomBound) { if (nominator <= nomBound && denominator <= denomBound) {
val exponent: Double = math.log(denominator.toDouble) / math.log(2) val exponent: Double = math.log(denominator.toDouble) / math.log(2)
if (exponent.isWhole) {
// maybe the log computations isn't sound due to roundoffs, let's sanity check:
assert(math.pow(2, exponent) == denominator)
true
} else {
false
}
if (exponent.isWhole) {
// maybe the log computations isn't sound due to roundoffs, let's sanity check:
assert(math.pow(2, exponent) == denominator)
true
} else { } else {
false false
} }
} else {
false
} }
} }
} }
......
...@@ -106,6 +106,41 @@ object RangeRegressionFunctions { ...@@ -106,6 +106,41 @@ object RangeRegressionFunctions {
} }
def kepler0(x1: Real, x2: Real, x3: Real, x4: Real, x5: Real, x6: Real): Real = {
require(4 <= x1 && x1 <= 6.36 && 4 <= x2 && x2 <= 6.36 && 4 <= x3 && x3 <= 6.36 &&
4 <= x4 && x4 <= 6.36 && 4 <= x5 && x5 <= 6.36 && 4 <= x6 && x6 <= 6.36)
x2 * x5 + x3 * x6 - x2 * x3 - x5 * x6 + x1 * (-x1 + x2 + x3 - x4 + x5 + x6)
} // 1.15e-15
def kepler1(x1: Real, x2: Real, x3: Real, x4: Real): Real = {
require(4 <= x1 && x1 <= 6.36 && 4 <= x2 && x2 <= 6.36 && 4 <= x3 && x3 <= 6.36 &&
4 <= x4 && x4 <= 6.36)
x1 * x4 * (-x1 + x2 + x3 - x4) + x2 * (x1 - x2 + x3 + x4) + x3 * (x1 + x2 - x3 + x4) -
x2 * x3 * x4 - x1 * x3 - x1 * x2 - x4
} // 4.50e–13
def kepler2(x1: Real, x2: Real, x3: Real, x4: Real, x5: Real, x6: Real): Real = {
require(4 <= x1 && x1 <= 6.36 && 4 <= x2 && x2 <= 6.36 && 4 <= x3 && x3 <= 6.36 &&
4 <= x4 && x4 <= 6.36 && 4 <= x5 && x5 <= 6.36 && 4 <= x6 && x6 <= 6.36)
x1 * x4 * (-x1 + x2 + x3 - x4 + x5 + x6) + x2 * x5 * (x1 - x2 + x3 + x4 - x5 + x6) +
x3* x6 * (x1 + x2 - x3 + x4 + x5 - x6) - x2 * x3 * x4 -
x1* x3* x5 - x1 * x2 * x6 - x4 * x5 * x6
} //2.08e–12
def himmilbeau(x1: Real, x2: Real) = {
require(-5 <= x1 && x1 <= 5 && -5 <= x2 && x2 <= 5)
(x1*x1 + x2 - 11)*(x1 * x1 + x2 - 11) + (x1 + x2*x2 - 7)*(x1 + x2*x2 - 7)
} //1.43e–12
/*def jetEngine(x1: Real, x2: Real) = { /*def jetEngine(x1: Real, x2: Real) = {
require(-5 <= x1 && x1 <= 5 && -20 <= x2 && x2 <= 5) require(-5 <= x1 && x1 <= 5 && -20 <= x2 && x2 <= 5)
x1 + ( x1 + (
......
package daisy
package test.regression
import scala.collection.immutable.Seq
import org.scalatest.FunSuite
import utils.FinitePrecision._
/**
Regression test for the fixed-point arithmetic code generation.
*/
class FixedpointCodegenRegressionTest extends FunSuite {
val inputFile: String = "src/test/resources/AbsErrorRegressionFunctions.scala"
val context = Context(
reporter = new DefaultReporter(Set()),
options = List(),
files = List(inputFile)
)
val inputPrg = frontend.ExtractionPhase(context)
val pipeline = analysis.SpecsProcessingPhase andThen
transform.SSATransformerPhase andThen
analysis.RangeErrorPhase
test("codegen-doppler-fixed32") {
val ctx = context.copy(options=Seq(
ChoiceOption("rangeMethod", "interval"),
ChoiceOption("precision", "Fixed32"),
ListOption("functions", List("doppler"))))
val (_, program) = pipeline.run(ctx, inputPrg.deepCopy)
val fnc = program.defs.find(_.id.toString == "doppler").get
//println(fnc.body.get)
val newBody = backend.CodeGenerationPhase.toFixedPointCode(fnc.body.get, Fixed(32))
//println(newBody)
assert(newBody.toString ===
"(let (_tmp := ((2576980378 * T) >> 31)) in\n" +
" (let (t1 := (((2779984691 << 4) + _tmp) >> 4)) in\n" +
" (let (_tmp1 := -(t1)) in\n" +
" (let (_tmp4 := ((_tmp1 * v) >> 31)) in\n" +
" (let (_tmp2 := (((t1 << 2) + u) >> 2)) in\n" +
" (let (_tmp3 := (((t1 << 2) + u) >> 2)) in\n" +
" (let (_tmp5 := ((_tmp2 * _tmp3) >> 32)) in\n" +
" ((_tmp4 << 29) / _tmp5))))))))"
)
}
test("codegen-sine-fixed32") {
val ctx = context.copy(options=Seq(
ChoiceOption("rangeMethod", "interval"),
ChoiceOption("precision", "Fixed32"),
ListOption("functions", List("sine"))))
val (_, program) = pipeline.run(ctx, inputPrg.deepCopy)
val fnc = program.defs.find(_.id.toString == "sine").get
//println(fnc.body.get)
val newBody = backend.CodeGenerationPhase.toFixedPointCode(fnc.body.get, Fixed(32))
assert(newBody.toString ===
"(let (_tmp229 := ((x * x) >> 32)) in\n" +
" (let (_tmp230 := ((_tmp229 * x) >> 31)) in\n" +
" (let (_tmp231 := ((_tmp230 << 31) / 3221225472)) in\n" +
" (let (_tmp236 := (((x << 1) - _tmp231) >> 2)) in\n" +
" (let (_tmp232 := ((x * x) >> 32)) in\n" +
" (let (_tmp233 := ((_tmp232 * x) >> 31)) in\n" +
" (let (_tmp234 := ((_tmp233 * x) >> 32)) in\n" +
" (let (_tmp235 := ((_tmp234 * x) >> 32)) in\n" +
" (let (_tmp237 := ((_tmp235 << 29) / 4026531840)) in\n" +
" (let (_tmp244 := (((_tmp236 << 2) + _tmp237) >> 2)) in\n" +
" (let (_tmp238 := ((x * x) >> 32)) in\n" +
" (let (_tmp239 := ((_tmp238 * x) >> 31)) in\n" +
" (let (_tmp240 := ((_tmp239 * x) >> 32)) in\n" +
" (let (_tmp241 := ((_tmp240 * x) >> 32)) in\n" +
" (let (_tmp242 := ((_tmp241 * x) >> 31)) in\n" +
" (let (_tmp243 := ((_tmp242 * x) >> 32)) in\n" +
" (let (_tmp245 := ((_tmp243 << 24) / 2642411520)) in\n" +
" (((_tmp244 << 2) - _tmp245) >> 2))))))))))))))))))"
)
}
test("codegen-rigidBody1-fixed32") {
val ctx = context.copy(options=Seq(
ChoiceOption("rangeMethod", "interval"),
ChoiceOption("precision", "Fixed32"),
ListOption("functions", List("rigidBody1"))))
val (_, program) = pipeline.run(ctx, inputPrg.deepCopy)
val fnc = program.defs.find(_.id.toString == "rigidBody1").get
val newBody = backend.CodeGenerationPhase.toFixedPointCode(fnc.body.get, Fixed(32))
//println(newBody)
assert(newBody.toString ===
"(let (_tmp510 := -(x1)) in\n" +
" (let (_tmp512 := ((_tmp510 * x2) >> 32)) in\n" +
" (let (_tmp511 := ((2147483648 * x2) >> 31)) in\n" +
" (let (_tmp513 := ((_tmp511 * x3) >> 32)) in\n" +
" (let (_tmp514 := ((_tmp512 - (_tmp513 << 1)) >> 2)) in\n" +
" (let (_tmp515 := (((_tmp514 << 6) - x1) >> 6)) in\n" +
" (((_tmp515 << 6) - x3) >> 6)))))))")
}
test("codegen-turbine1-fixed32") {
val ctx = context.copy(options=Seq(
ChoiceOption("rangeMethod", "interval"),
ChoiceOption("precision", "Fixed32"),
ListOption("functions", List("turbine1"))))
val (_, program) = pipeline.run(ctx, inputPrg.deepCopy)
val fnc = program.defs.find(_.id.toString == "turbine1").get
val newBody = backend.CodeGenerationPhase.toFixedPointCode(fnc.body.get, Fixed(32))
//println(newBody)
assert(newBody.toString ===
"(let (_tmp771 := ((r * r) >> 32)) in\n" +
" (let (_tmp772 := ((2147483648 << 28) / _tmp771)) in\n" +
" (let (_tmp781 := (((3221225472 << 2) + _tmp772) >> 2)) in\n" +
" (let (_tmp773 := ((2147483648 * v) >> 31)) in\n" +
" (let (_tmp774 := ((3221225472 - (_tmp773 << 2)) >> 2)) in\n" +
" (let (_tmp777 := ((536870912 * _tmp774) >> 29)) in\n" +
" (let (_tmp775 := ((w * w) >> 32)) in\n" +
" (let (_tmp776 := ((_tmp775 * r) >> 32)) in\n" +
" (let (_tmp778 := ((_tmp776 * r) >> 32)) in\n" +
" (let (_tmp779 := ((_tmp777 * _tmp778) >> 32)) in\n" +
" (let (_tmp780 := ((2147483648 - (v << 2)) >> 2)) in\n" +
" (let (_tmp782 := ((_tmp779 << 30) / _tmp780)) in\n" +
" (let (_tmp783 := ((_tmp781 - (_tmp782 << 4)) >> 4)) in\n" +
" (((_tmp783 << 3) - 2415919104) >> 3))))))))))))))")
}
test("codegen-turbine2-fixed32") {
val ctx = context.copy(options=Seq(
ChoiceOption("rangeMethod", "interval"),
ChoiceOption("precision", "Fixed32"),
ListOption("functions", List("turbine2"))))
val (_, program) = pipeline.run(ctx, inputPrg.deepCopy)
val fnc = program.defs.find(_.id.toString == "turbine2").get
val newBody = backend.CodeGenerationPhase.toFixedPointCode(fnc.body.get, Fixed(32))
//println(newBody)
assert(newBody.toString ===
"(let (_tmp1013 := ((3221225472 * v) >> 31)) in\n" +
" (let (_tmp1009 := ((2147483648 * v) >> 31)) in\n" +
" (let (_tmp1007 := ((w * w) >> 32)) in\n" +
" (let (_tmp1008 := ((_tmp1007 * r) >> 32)) in\n" +
" (let (_tmp1010 := ((_tmp1008 * r) >> 32)) in\n" +
" (let (_tmp1011 := ((_tmp1009 * _tmp1010) >> 31)) in\n" +
" (let (_tmp1012 := ((2147483648 - (v << 2)) >> 2)) in\n" +
" (let (_tmp1014 := ((_tmp1011 << 29) / _tmp1012)) in\n" +
" (let (_tmp1015 := ((_tmp1013 - (_tmp1014 << 2)) >> 2)) in\n" +
" (((_tmp1015 << 5) - 2684354560) >> 5))))))))))")
}
test("codegen-kepler0-fixed32") {
val ctx = context.copy(options=Seq(
ChoiceOption("rangeMethod", "interval"),
ChoiceOption("precision", "Fixed32"),
ListOption("functions", List("kepler0"))))
val (_, program) = pipeline.run(ctx, inputPrg.deepCopy)
val fnc = program.defs.find(_.id.toString == "kepler0").get
backend.CodeGenerationPhase.reporter = ctx.reporter
val newBody = backend.CodeGenerationPhase.toFixedPointCode(fnc.body.get, Fixed(32))
//println(newBody)
assert(newBody.toString ===
"(let (_tmp1252 := ((x2 * x5) >> 32)) in\n" +
" (let (_tmp1253 := ((x3 * x6) >> 32)) in\n" +
" (let (_tmp1254 := ((_tmp1252 + _tmp1253) >> 1)) in\n" +
" (let (_tmp1255 := ((x2 * x3) >> 32)) in\n" +
" (let (_tmp1256 := (((_tmp1254 << 1) - _tmp1255) >> 1)) in\n" +
" (let (_tmp1257 := ((x5 * x6) >> 32)) in\n" +
" (let (_tmp1264 := ((_tmp1256 << 1) - _tmp1257)) in\n" +
" (let (_tmp1258 := -(x1)) in\n" +
" (let (_tmp1259 := ((_tmp1258 + x2) << 1)) in\n" +
" (let (_tmp1260 := ((_tmp1259 + (x3 << 1)) >> 2)) in\n" +
" (let (_tmp1261 := ((_tmp1260 << 1) - x4)) in\n" +
" (let (_tmp1262 := ((_tmp1261 + x5) >> 1)) in\n" +
" (let (_tmp1263 := (((_tmp1262 << 1) + x6) >> 2)) in\n" +
" (let (_tmp1265 := ((x1 * _tmp1263) >> 31)) in\n" +
" ((_tmp1264 + (_tmp1265 << 1)) >> 2)))))))))))))))")
}
test("codegen-himmilbeau-fixed32") {
val ctx = context.copy(options=Seq(
ChoiceOption("rangeMethod", "interval"),
ChoiceOption("precision", "Fixed32"),
ListOption("functions", List("himmilbeau"))))
val (_, program) = pipeline.run(ctx, inputPrg.deepCopy)
val fnc = program.defs.find(_.id.toString == "himmilbeau").get
val newBody = backend.CodeGenerationPhase.toFixedPointCode(fnc.body.get, Fixed(32))
//println(newBody)
assert(newBody.toString ===
"(let (_tmp1547 := ((x1 * x1) >> 31)) in\n" +
" (let (_tmp1548 := (((_tmp1547 << 2) + x2) >> 2)) in\n" +
" (let (_tmp1551 := (((_tmp1548 << 1) - 2952790016) >> 2)) in\n" +
" (let (_tmp1549 := ((x1 * x1) >> 31)) in\n" +
" (let (_tmp1550 := (((_tmp1549 << 2) + x2) >> 2)) in\n" +
" (let (_tmp1552 := (((_tmp1550 << 1) - 2952790016) >> 2)) in\n" +
" (let (_tmp1559 := ((_tmp1551 * _tmp1552) >> 31)) in\n" +
" (let (_tmp1553 := ((x2 * x2) >> 31)) in\n" +
" (let (_tmp1554 := ((x1 + (_tmp1553 << 2)) >> 2)) in\n" +
" (let (_tmp1557 := (((_tmp1554 << 2) - 3758096384) >> 3)) in\n" +
" (let (_tmp1555 := ((x2 * x2) >> 31)) in\n" +
" (let (_tmp1556 := ((x1 + (_tmp1555 << 2)) >> 2)) in\n" +
" (let (_tmp1558 := (((_tmp1556 << 2) - 3758096384) >> 3)) in\n" +
" (let (_tmp1560 := ((_tmp1557 * _tmp1558) >> 31)) in\n" +
" ((_tmp1559 + _tmp1560) >> 1)))))))))))))))")
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment