import ofc.LogicError
import ofc.util.DirectedGraph
-class ProducerStatement extends Statement {
+object ProducerStatement {
object Context {
private def priority(context: Context) : Int = {
// This ensures that the nesting ordering is Predicate, DerivedExpression, VariableRange
def defines = Set(symbol)
def depends = Expression.findReferencedVariables(expression)
}
+}
+
+class ProducerStatement extends Statement {
+ import ProducerStatement._
var statement = new Comment("Placeholder statement for consumer.")
var ranges : Seq[VariableRange] = Nil
predicates +:= new Predicate(condition)
}
+ def merge(statement: ProducerStatement) {
+ ranges ++= statement.ranges
+ predicates ++= statement.predicates
+ expressions ++= statement.expressions
+ }
+
def toConcrete : Statement = {
val contexts = ranges ++ predicates ++ expressions
val sortedContexts = Context.sort(contexts)
package ofc.generators.onetep
-import ofc.codegen.{NullStatement,FloatLiteral}
+import ofc.codegen.{ProducerStatement,NullStatement,FloatLiteral}
class Assignment(indexBindings: IndexBindings, lhs: DataSpace, rhs: IterationSpace) extends IterationSpace {
- def getOperands = List(lhs, rhs)
+ // TODO: Implement assignment
+ def getOperands = List(rhs)
def getSpatialIndices = Nil
def getDiscreteIndices = Nil
- def getReaderFragment = new NullStatement
- def getSuffixFragment = new NullStatement
+ def getPrefixFragment = new ProducerStatement
+ def getSuffixFragment = new ProducerStatement
+ def getBodyFragment = new ProducerStatement
def getDataValue = new FloatLiteral(0.0)
}
}
*/
+ private def buildStatement(space: IterationSpace) : ProducerStatement = {
+ // TODO: Until we can handle multi-operand nodes
+ assert(space.getOperands.size < 2)
+
+ val result = new ProducerStatement
+ result.merge(space.getBodyFragment)
+ result.merge(space.getPrefixFragment)
+ result.merge(space.getSuffixFragment)
+
+ for(operand <- space.getOperands) {
+ val opStatement = buildStatement(operand)
+ result.merge(opStatement)
+ }
+ result
+ }
+
def generateCode(space: IterationSpace) {
val allSpaces = IterationSpace.flattenPostorder(space)
val allIndices = allSpaces flatMap (_.getIndices)
println(i)
println("")
- val statements = new BlockStatement
- for (op <- IterationSpace.sort(allSpaces)) {
- statements += op.getReaderFragment
- statements += op.getSuffixFragment
- }
-
+ val statement = buildStatement(space)
val fortranGenerator = new FortranGenerator
- val code = fortranGenerator(statements)
+ val code = fortranGenerator(statement)
println(code)
}
}
package ofc.generators.onetep
-import ofc.codegen.{Statement,NullStatement,Expression,FloatType}
+import ofc.codegen.{Statement,ProducerStatement,NullStatement,Expression,FloatType}
object IterationSpace {
def sort(spaces : Traversable[IterationSpace]) : Seq[IterationSpace] = {
val operands = getOperands
operands.toSet ++ operands.flatMap(_.getDependencies)
}
- def getReaderFragment : Statement
- def getSuffixFragment : Statement
+
+ def getBodyFragment : ProducerStatement
+ def getPrefixFragment : ProducerStatement
+ def getSuffixFragment : ProducerStatement
}
trait DataSpace extends IterationSpace {
def getOperands = Nil
- def getReaderFragment = new NullStatement
+ def getPrefixFragment = new ProducerStatement
+ def getBodyFragment = new ProducerStatement
}
trait Matrix extends DataSpace
def getSpatialIndices = operand.getSpatialIndices
def getDiscreteIndices = Nil
def getDataValue = operand.getDataValue
- def getReaderFragment = operand.getReaderFragment
+ def getBodyFragment = operand.getBodyFragment
def getSuffixFragment = operand.getSuffixFragment
+ def getPrefixFragment = operand.getPrefixFragment
}
class PPDFunctionSet private(discreteIndices: Seq[DiscreteIndex],
spatialIndices: Seq[SpatialIndex], data: Expression[FloatType],
- producer: Statement) extends FunctionSet {
+ producer: ProducerStatement) extends FunctionSet {
def getSuffixFragment = producer
def getDiscreteIndices = discreteIndices
package ofc.generators.onetep
-import ofc.codegen.{NullStatement,Comment, FloatLiteral}
+import ofc.codegen.{ProducerStatement,NullStatement,Comment, FloatLiteral}
class SPAM3(name : String) extends Matrix {
override def toString = name
def getSpatialIndices = Nil
def getDiscreteIndices = Nil
def getDataValue = new FloatLiteral(0.0)
- def getSuffixFragment = new Comment("Suffix of "+toString+".")
+ def getSuffixFragment = new ProducerStatement
}
private val pubFFTBoxWidth = for (dim <- 0 to 2) yield FFTBoxInfo.public % FFTBoxInfo.totalPts(dim)
private val ppdWidth = for(dim <- 0 to 2) yield CellInfo.public % CellInfo.ppdWidth(dim)
-}
-class SpatialRestriction(op: IterationSpace) extends IterationSpace {
- def getOperands = List(op)
- def getDiscreteIndices = Nil
- def getSuffixFragment = new NullStatement
- def getDataValue = op.getDataValue
- def getReaderFragment = {
+ private class RestrictionIndex(name: String, value: Expression[IntType]) extends SpatialIndex {
+ def getName = name
+ def getValue = value
+ }
+
+ def apply(op: IterationSpace) : SpatialRestriction = {
import OnetepTypes._
- import SpatialRestriction._
val inputIndices = for(index <- op.getSpatialIndices) yield
index match {
val producer = new ProducerStatement
val origin = for (dim <- 0 to 2)
- yield producer.addExpression("fftbox_origin_pt"+(dim+1), functionCentre(dim) - pubFFTBoxWidth(dim)/2)
+ yield producer.addExpression("fftbox_origin_pt"+(dim+1), (cellWidthPts(dim) + functionCentre(dim) - pubFFTBoxWidth(dim)/2) % cellWidthPts(dim))
val offset = for (dim <- 0 to 2)
yield producer.addExpression("fftbox_offset_pt"+(dim+1),
for (dim <- 0 to 2)
producer.addPredicate(offset(dim) |<| pubFFTBoxWidth(dim))
- producer
- }
-
- def getSpatialIndices = {
- //TODO: Implement me!
- Nil
+ val indices = for(dim <- 0 to 2) yield new RestrictionIndex("restriction_pos"+(dim+1), offset(dim))
+ new SpatialRestriction(op, indices, producer)
}
+}
-/*
- class RestrictedIndex(parent: SpatialRestriction, dimension: Int) extends SpatialIndex {
- def getName = "restriction_index_" + dimension
- def getDependencies = Set()
- def getDenseWidth(names: NameManager) = "pub_fftbox%total_pt"+(dimension+1)
-
- def generateIterationHeader(names: NameManager) = "do "+names(this)+"=1,"+getDenseWidth(names)
- def generateIterationFooter(names: NameManager) = "end do"
- def getDeclarations(names: NameManager) = Nil
- }
-
- val spatialIndices = for (dimension <- 0 until op.getSpatialIndices.size) yield new RestrictedIndex(this, dimension)
-
- def getSpatialIndices = spatialIndices.toList
- def getDiscreteIndices = op.getDiscreteIndices
- def getExternalIndices = Set()
-
- def getConsumerGenerator = Some(new ConsumerGenerator {
- def generate(names: NameManager, indices: Map[Index,String], values : Map[IterationSpace, String]) : String = {
- "!SpatialRestriction consumer."
- }
- })
- def getTransformGenerator = None
- def getProducerGenerator = None
-*/
+class SpatialRestriction private(op: IterationSpace,
+ spatialIndices: Seq[SpatialIndex], producer: ProducerStatement) extends IterationSpace {
+ def getOperands = List(op)
+ def getDiscreteIndices = Nil
+ def getPrefixFragment = new ProducerStatement
+ def getSuffixFragment = new ProducerStatement
+ def getDataValue = op.getDataValue
+ def getBodyFragment = producer
+ def getSpatialIndices = spatialIndices
}
term match {
case (t: IndexedIdentifier) => buildIndexedSpace(t)
- case Operator(Identifier("fftbox"), List(op)) =>
- new SpatialRestriction(buildExpression(op))
+ case Operator(Identifier("fftbox"), List(op)) => SpatialRestriction(buildExpression(op))
/*
case ScalarConstant(s) => new Scalar(s)