Commit 642cc545 authored by ='s avatar =

Adding Chooseprecisionphase

parent 8e059428
package daisy
package analysis
import scala.collection.immutable.Seq
import scala.io.Source
import lang.NumAnnotation
import lang.Trees._
import lang.Types._
import lang.Extractors._
import utils._
import FinitePrecision._
import Rational._
import lang.Identifiers._
import lang.TreeOps.allVariablesOf
object ChoosePrecisionPhase extends DaisyPhase {
override val name = "Choose Precision"
override val description = "Chooses the precision of each variable"
// todo: need to start timer?
var reporter: Reporter = null
override def run(ctx:Context, prg:Program): (Context, Program) = {
reporter = ctx.reporter
reporter.info(s"\nStarting $name phase")
val fncsToConsider: Seq[String] = functionsToConsider(ctx, prg)
var randomMP = false
for (opt <- ctx.options) opt match {
case FlagOption("randomMP") => randomMP = true
case _ =>
}
var varPrecisionMap: Map[Identifier, Map[Identifier, Precision]] = Map()
val uniformPrecision = ctx.constantPrecision
prg.defs.filter(fnc =>
!fnc.precondition.isEmpty &&
!fnc.body.isEmpty &&
fncsToConsider.contains(fnc.id.toString)).map(fnc => {
var precisionMap: Map[Identifier, Precision] = Map()
// todo: need to change program to match this precisionMap?
if(randomMP) {
precisionMap = precisionMap ++ fnc.params.map(e => e match { case ValDef(v) => (v -> getRandomPrecision())}).toMap
fnc.body match {
case Some(e) =>
precisionMap = randomType(e, precisionMap, uniformPrecision)._1
case None => ()
}
} else {
precisionMap = allVariablesOf(fnc.body.get).map(id => (id -> uniformPrecision)).toMap
}
reporter.info(s"Chosen Precision map is for ${fnc.id} ${precisionMap.toString}")
varPrecisionMap += fnc.id -> precisionMap
})
val newprg = Program(prg.id,
prg.defs.map({
case FunDef(id, retT, params, pre, body, post, isField) =>
val newb = body match {
case Some(e) => Some(introduceDowncast(e, varPrecisionMap(id), uniformPrecision)._1)
case None => None }
FunDef(id, retT, params, pre, newb, post, isField)}))
(ctx.copy(precision=varPrecisionMap), newprg)
}
def randomType(e:Expr, m:Map[Identifier, Precision], c:Precision) : (Map[Identifier,Precision], Precision) = {
e match {
case Variable(id) => (m, m(id))
case RealLiteral(r) => (m, c)
case ArithOperator(Seq(l, r), recons) =>
val (map_l, t_l) = randomType(l, m, c)
val (map_r, t_r) = randomType(r, map_l, c)
val prec = getUpperBound(t_l, t_r)
(map_r, prec)
case ArithOperator(Seq(u), recons) =>
randomType(u, m, c)
case Let(id, value, body) =>
val (map_value, type_value) = randomType(value, m, c)
val prec_id = getRandomPrecision(highestPrec=type_value)
if(prec_id < type_value) {
}
val new_map = map_value + (id -> prec_id)
randomType(body, new_map, c)
}
}
def introduceDowncast(e:Expr, m:Map[Identifier, Precision], c:Precision) : (Expr, Precision) = {
e match {
case Variable(id) => (e, m(id))
case RealLiteral(r) => (e, c)
case ArithOperator(Seq(l, r), recons) =>
val (new_l, t_l) = introduceDowncast(l, m, c)
val (new_r, t_r) = introduceDowncast(r, m, c)
val prec = getUpperBound(t_l, t_r)
(recons(Seq(new_l, new_r)), prec)
case ArithOperator(Seq(u), recons) =>
val (res, prec) = introduceDowncast(u, m, c)
(recons(Seq(res)), prec)
case Let(id, value, body) =>
val (nv, tv) = introduceDowncast(value, m, c)
val new_value =
if (m(id) < tv) {
Downcast(nv, FinitePrecisionType(m(id)))
} else nv
val (new_body, prec_body) = introduceDowncast(body, m, c)
(Let(id, new_value, new_body), prec_body)
}
}
def buildIdentifierMap(prg:Program) : (Map[String, Identifier], Map[String, Map[String, Identifier]]) = {
def buildIdentifierMapFunction(f:FunDef): Map[String, Identifier] = {
allVariablesOf(f.body.get).map(id => ((id.toString) -> id)).toMap
}
(prg.defs.map(fnc => (fnc.id.name -> fnc.id)).toMap,
prg.defs.map(fnc => (fnc.id.name -> buildIdentifierMapFunction(fnc, fnc.id))).toMap)
}
def parseFile(f:String, fncIdMap:Map[String, Identifier], varIdMap:Map[String, Map[String, Identifier]], reporter:Reporter, dummyId:Identifier) : Map[Identifier, Map[Identifier, Precision]] = {
val bufferedSource = io.Source.fromFile(f)
var currentFunction = ""
var currentTypes:Array[String] = Array()
var currentIdentifier:Identifier = dummyId
var currentFunctionMap:Map[Identifier, Precision] = Map()
var typeMap:Map[Identifier, Map[Identifier, Precision]] = Map()
// input format:
// functionName:
// variablei=typei
// todo: regexp?
for (line <- bufferedSource.getLines) {
if(line.contains(":"))
{
if(!currentFunctionMap.isEmpty) {
typeMap += (currentIdentifier -> currentFunctionMap)
}
currentFunction = line.split(':').head
fncIdMap.get(currentFunction) match {
case Some(i) =>
currentIdentifier = i
currentFunctionMap.clear()
case None => reporter.fatalError(s"$currentFunction was not found in the identifier map.")
}
else if(line.contains("="))
{
currentTypes = line.split('=').map(_.trim)
idMap(currentFunction).get(currentTypes(0)) match {
case Some(id_v) =>
val type_v = currentTypes(1) match {
case "Float" => Float32
case "Double" => Float64
case "DoubleDouble" => DoubleDouble
case "QuadDouble" => QuadDouble
case _ => reporter.fatalError(s"The type of variable $id_v in function $currentFunction is unknown.") }
currentFunctionMap += (id_v -> type_v)
case None => reporter.fatalError(s"${currentTypes(0)} not found in the identifier map of $currentFunction.")
}
}
else
reporter.fatalError(s"Format error in $f")
}
}
typeMap += (currentIdentifier -> currentFunctionMap)
typeMap
}
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