--- /dev/null
+package ofc.generators.onetep
+
+class PPDFunctionSet(val basis : String, data : String) extends FunctionSet {
+ class SphereIndex(parent: PPDFunctionSet) extends DiscreteIndex {
+ def getName = "sphere_index"
+ def getDependencies = Set()
+ def getDenseWidth(names: NameManager) = parent.getNumSpheres(names)
+
+ def generateIterationHeader(names: NameManager) = {
+ val indexName = names(this)
+ "do "+indexName+"=1," + parent.getSphere(names) + "%n_ppds_sphere"
+ }
+
+ def generateIterationFooter(names: NameManager) = "end do"
+ def getDeclarations(names: NameManager) = List("integer :: "+names(this))
+ }
+
+ class PPDIndex(parent: PPDFunctionSet) extends DiscreteIndex {
+ var denseIndexNames : List[String] = Nil
+ var startNames : List[String] = Nil
+ var finishNames : List[String] = Nil
+ var offsetNames : List[String] = Nil
+ var ppdPoint : String = ""
+
+ def getName = "ppd_index"
+ def getPPDPoint = ppdPoint
+ def getStartNames = startNames
+ def getFinishNames = finishNames
+ def getOffsetNames = offsetNames
+ def getDependencies = Set[Index](parent.getSphereIndex)
+ def getDensePPDIndices = denseIndexNames
+
+ def getDenseWidth(names: NameManager) = parent.basis+"%max_n_ppds_sphere"
+
+ def generateIterationHeader(names: NameManager) = {
+ val findPPD = "call basis_find_ppd_in_neighbour(" + denseIndexNames.mkString(",") + ", &\n" +
+ parent.getSphere(names) + "%ppd_list(1," + names(this) + "), &\n" +
+ parent.getSphere(names) + "%ppd_list(2," + names(this) + "), &\n" +
+ "pub_cell%n_ppds_a1, pub_cell%n_ppds_a2, pub_cell%n_ppds_a3)"
+
+ val computeRanges = for (dim <- 1 to 2) yield {
+ val tb = parent.getTightbox(names)
+
+ "call basis_lims_1d_in_ppd_in_tight("+startNames(dim)+", "+finishNames(dim)+", "+offsetNames(dim)+", &\n" +
+ denseIndexNames(dim)+", "+tb+"%start_ppds2, "+tb+"%finish_ppds2, &\n" +
+ tb+"%start_pts2, "+tb+"%finish_pts2, pub_cell%n_pt"+dim+")"
+ }
+
+ val loopDeclaration = "do "+names(this)+"=1,"+parent.getSphere(names)+"%n_ppds_sphere"
+
+ val ppdOffsetCalc = ppdPoint + " = " + parent.getSphere(names)+"%offset + ("+names(this)+"-1)*pub_cell%n_pts &\n"+
+ "+ ("+startNames(2)+"-1)*pub_cell%n_pt2*pub_cell%n_pt1 &\n"+
+ "+ ("+startNames(1)+"-1)*pub_cell%n_pt1 + ("+startNames(0)+"-1)"
+
+ (List(findPPD) ++ computeRanges ++ List(loopDeclaration) ++ List(ppdOffsetCalc)).mkString("\n")
+ }
+
+ def generateIterationFooter(names: NameManager) = "end do"
+
+ def getDeclarations(names: NameManager) = {
+ denseIndexNames = (for (dim <- 0 to 2) yield names.newIdentifier("derived_ppd_position_"+dim)).toList
+ startNames = (for (dim <- 0 to 2) yield names.newIdentifier("tightbox_start_"+dim)).toList
+ finishNames = (for (dim <- 0 to 2) yield names.newIdentifier("tightbox_finish_"+dim)).toList
+ offsetNames = (for (dim <- 0 to 2) yield names.newIdentifier("tightbox_offset_"+dim)).toList
+ ppdPoint = names.newIdentifier("fa_point")
+ (denseIndexNames++finishNames++offsetNames++Some(ppdPoint)).map(x => "integer :: " + x) ++ List("integer :: "+names(this))
+ }
+ }
+
+ class IntraPPDIndex(parent: PPDFunctionSet, dimension: Int) extends SpatialIndex {
+ var tbPoint : String = ""
+
+ def getName = "intra_ppd_index_" + dimension
+ private def getPPDIndex = parent.getPPDIndex
+ def getDependencies = {
+ val parentIndex = if (dimension < parent.getSpatialIndices.size-1)
+ Some(parent.getSpatialIndices(dimension+1))
+ else
+ None
+
+ Set[Index](getPPDIndex) ++ parentIndex
+ }
+ def getDenseWidth(names: NameManager) = "pub_cell%total_pt"+(dimension+1)
+ def generateIterationHeader(names: NameManager) = {
+ val findPoint = tbPoint + " = " +
+ names(this) + " - " + getPPDIndex.getStartNames(dimension) + " + " +
+ getPPDIndex.getOffsetNames(dimension) + " + 1"
+
+ val header = "do "+names(this)+"="+getPPDIndex.getStartNames(dimension)+","+getPPDIndex.getFinishNames(dimension)
+
+ List(findPoint, header).mkString("\n")
+ }
+
+ def generateIterationFooter(names: NameManager) = {
+ val incPoint = if (dimension == 0) Some(getPPDIndex.ppdPoint + " = " + getPPDIndex.ppdPoint + " + 1") else None
+ val jumpOffset = "pub_cell%n_pt"+(dimension+1)+"-" +
+ getPPDIndex.getFinishNames(dimension)+"+"+
+ getPPDIndex.getStartNames(dimension)+"-1"
+ val jumpPoint = (List(getPPDIndex.ppdPoint + " = " + getPPDIndex.ppdPoint + " + (" + jumpOffset +")") ++
+ (for (dim <- 0 until dimension) yield "pub_cell%n_pt"+(dim+1))).mkString("*")
+ val endLoop = "end do"
+
+ (incPoint ++ List(endLoop, jumpPoint)).mkString("\n")
+ }
+
+ def getDeclarations(names: NameManager) = {
+ tbPoint = names.newIdentifier("tb_pt"+(dimension+1))
+ List("integer :: "+names(this), "integer :: "+tbPoint)
+ }
+
+ override def getDensePosition(names: NameManager) =
+ tbPoint
+ }
+
+ val ppdIndex = new PPDIndex(this)
+ val sphereIndex = new SphereIndex(this)
+ val spatialIndices = for (dimension <- 0 to 2) yield new IntraPPDIndex(this, dimension)
+
+ def getPPDIndex = ppdIndex
+ def getSphereIndex = sphereIndex
+ def getSphere(names: NameManager) = basis + "%spheres("+names(getSphereIndex)+")"
+ def getTightbox(names: NameManager) = basis + "%tight_boxes("+names(getSphereIndex)+")"
+
+ def getNumSpheres(names: NameManager) = {
+ // TODO: This number is dependent on the parallel distribution
+ basis + "%node_num"
+ }
+
+ def getSpatialIndices = spatialIndices.toList
+ def getDiscreteIndices = List(getSphereIndex)
+ def getExternalIndices = Set(getPPDIndex)
+
+ def getProducerGenerator = Some(new ProducerGenerator {
+ def generate(names: NameManager) = {
+ data+"("+getPPDIndex.getPPDPoint+")"
+ }
+ })
+}
+
+
import ofc.parser.Identifier
import ofc.{InvalidInputException,UnimplementedException}
-object Index {
- def sort(indices: Traversable[Index]) : List[Index] = {
- def helper(input: Index, seen: collection.mutable.Set[Index]) : List[Index] =
- if (seen add input)
- input.getDependencies.toList.flatMap(helper(_, seen)) ++ List(input)
- else
- Nil
-
- val seen = collection.mutable.Set[Index]()
- indices.toList.flatMap(helper(_, seen))
- }
-}
-
-trait Index {
- def getName : String
- def getDependencies : Set[Index]
- def getDenseWidth(names: NameManager) : String
- def getDensePosition(names: NameManager) : String = names(this)
- def generateIterationHeader(names: NameManager) : String
- def generateIterationFooter(names: NameManager) : String
- def getDeclarations(names: NameManager) : List[String]
-}
-
-trait SpatialIndex extends Index
-trait DiscreteIndex extends Index
-
-object IterationSpace {
- def sort(spaces : Traversable[IterationSpace]) : List[IterationSpace] = {
- def helper(input: IterationSpace, seen: collection.mutable.Set[IterationSpace]) : List[IterationSpace] =
- if (seen add input)
- input.getOperands.flatMap(helper(_, seen)) ++ List(input)
- else
- Nil
-
- val seen = collection.mutable.Set[IterationSpace]()
- spaces.toList.flatMap(helper(_, seen))
- }
-
- def flattenPostorder(term: IterationSpace) : Traversable[IterationSpace] =
- term.getOperands.toTraversable.flatMap(flattenPostorder(_)) ++ List(term)
-}
-
trait ConsumerGenerator {
def generate(names: NameManager, indices: Map[Index,String], values : Map[IterationSpace, String]) : String
}
def generate(names: NameManager) : String
}
-trait IterationSpace {
- def getOperands : List[IterationSpace]
- def getSpatialIndices : List[SpatialIndex]
- def getDiscreteIndices : List[DiscreteIndex]
- def getExternalIndices : Set[Index]
- def getInternalIndices : Set[Index] = (getSpatialIndices ++ getDiscreteIndices).toSet
- def getIndices : Set[Index] = getInternalIndices ++ getExternalIndices
- def getDependencies : Set[IterationSpace] = {
- val operands = getOperands
- operands.toSet ++ operands.flatMap(_.getDependencies)
- }
-
- // Code generation
- def getConsumerGenerator : Option[ConsumerGenerator]
- def getTransformGenerator : Option[TransformGenerator]
- def getProducerGenerator : Option[ProducerGenerator]
-}
-
-trait DataSpace extends IterationSpace {
- def getOperands = Nil
- def getConsumerGenerator = None
- def getTransformGenerator = None
-}
-
-trait Matrix extends DataSpace
-trait FunctionSet extends DataSpace
-
-class Assignment(indexBindings: IndexBindings, lhs: DataSpace, rhs: IterationSpace) extends IterationSpace {
- def getIndexBindings = indexBindings
- def getOperands = List(rhs)
- def getSpatialIndices = lhs.getSpatialIndices
- def getDiscreteIndices = lhs.getDiscreteIndices
- def getExternalIndices = Set()
-
- def getConsumerGenerator = None
- def getTransformGenerator = None
- def getProducerGenerator = None
-}
-
-class Scalar(value: Double) extends DataSpace {
- def getSpatialIndices = Nil
- def getDiscreteIndices = Nil
- def getExternalIndices = Set()
- def getProducerGenerator = Some(new ProducerGenerator {
- def generate(names: NameManager) = value.toString
- })
-}
-
-class GeneralInnerProduct(operands: List[IterationSpace], removedIndices: Set[Index]) extends IterationSpace {
-
- class DenseSpatialIndex(parent: GeneralInnerProduct, original: SpatialIndex) extends SpatialIndex{
- def getDependencies = Set()
- def getName = "dense_spatial_index"
- def getDenseWidth(names: NameManager) = original.getDenseWidth(names)
- def generateIterationHeader(names: NameManager) = "do "+names(this)+"=1,"+getDenseWidth(names)
- def generateIterationFooter(names: NameManager) = "end do"
- def getDeclarations(names: NameManager) = List("integer :: "+names(this))
- }
-
- class DenseDiscreteIndex(parent: GeneralInnerProduct, original: DiscreteIndex) extends DiscreteIndex {
- def getDependencies = Set()
- def getName = "dense_discrete_index"
- def getDenseWidth(names: NameManager) = original.getDenseWidth(names)
- def generateIterationHeader(names: NameManager) = "do "+names(this)+"=1,"+getDenseWidth(names)
- def generateIterationFooter(names: NameManager) = "end do"
- def getDeclarations(names: NameManager) = List("integer :: "+names(this))
- }
-
- val spatialIndices =
- for(op <- operands; index <- op.getSpatialIndices; if (!removedIndices.contains(index))) yield
- if (index.getDependencies.intersect(removedIndices).isEmpty)
- index
- else
- new DenseSpatialIndex(this, index)
-
- val discreteIndices =
- for(op <- operands; index <- op.getDiscreteIndices; if (!removedIndices.contains(index))) yield
- if (index.getDependencies.intersect(removedIndices).isEmpty)
- index
- else
- new DenseDiscreteIndex(this, index)
-
- def getOperands = operands
- def getSpatialIndices = spatialIndices
- def getDiscreteIndices = discreteIndices
- def getExternalIndices = Set()
-
- def getConsumerGenerator = None
- def getTransformGenerator = None
- def getProducerGenerator = None
-}
-
-class Reciprocal(op: IterationSpace) extends IterationSpace {
- class BlockIndex(parent: Reciprocal, dimension: Int, original: SpatialIndex) extends SpatialIndex {
- def getName = "reciprocal_index_" + dimension
- def getDependencies = Set()
- def getDenseWidth(names: NameManager) = original.getDenseWidth(names)
- def generateIterationHeader(names: NameManager) = "do "+names(this)+"=1,"+getDenseWidth(names)
- def generateIterationFooter(names: NameManager) = "end do"
- def getDeclarations(names: NameManager) = List("integer :: "+names(this))
- }
-
- val spatialIndices = for (dimension <- 0 until op.getSpatialIndices.size) yield
- new BlockIndex(this, dimension, op.getSpatialIndices(dimension))
-
- def getOperands = List(op)
- def getSpatialIndices = spatialIndices.toList
- def getDiscreteIndices = op.getDiscreteIndices
- def getExternalIndices = Set()
-
- def getConsumerGenerator = None
- def getTransformGenerator = None
- def getProducerGenerator = None
-}
-
-class Laplacian(op: IterationSpace) extends IterationSpace {
- def getOperands = List(op)
- def getSpatialIndices = op.getSpatialIndices
- def getDiscreteIndices = op.getDiscreteIndices
- def getExternalIndices = Set()
-
- def getConsumerGenerator = None
- def getTransformGenerator = None
- def getProducerGenerator = None
-}
-
-class SpatialRestriction(op: IterationSpace) extends IterationSpace {
- 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 getOperands = List(op)
- def getSpatialIndices = spatialIndices.toList
- def getDiscreteIndices = op.getDiscreteIndices
- def getExternalIndices = Set()
-
- def getConsumerGenerator = None
- def getTransformGenerator = None
- def getProducerGenerator = None
-}
-
-class SPAM3(name : String) extends Matrix {
- override def toString = name
- def getName = name
-
- class RowIndex(parent: SPAM3) extends DiscreteIndex {
- override def toString = parent + ".row"
- def getName = "row_index"
- def getDependencies = Set()
- def getDenseWidth(names: NameManager) = "sparse_num_rows("+parent.getName+")"
-
- def generateIterationHeader(names: NameManager) = {
- val indexName = names(this)
- "do "+indexName+"=1,"+getDenseWidth(names)
- }
-
- def generateIterationFooter(names: NameManager) = "end do"
- def getDeclarations(names: NameManager) = List("integer :: "+names(this))
- }
-
- class ColIndex(parent: SPAM3) extends DiscreteIndex {
- override def toString = parent + ".col"
- def getName = "row_index"
- def getDependencies = Set()
- def getDenseWidth(names: NameManager) = "sparse_num_cols("+parent.getName+")"
-
- def generateIterationHeader(names: NameManager) = {
- val indexName = names(this)
- "do "+indexName+"=1,"+getDenseWidth(names)
- }
-
-
- def generateIterationFooter(names: NameManager) = "end do"
- def getDeclarations(names: NameManager) = List("integer :: "+names(this))
- }
-
- val rowIndex = new RowIndex(this)
- val colIndex = new ColIndex(this)
-
- def getSpatialIndices = Nil
- def getDiscreteIndices = List(rowIndex, colIndex)
- def getExternalIndices = Set()
-
- def getProducerGenerator = None
-}
-
-class PPDFunctionSet(val basis : String, data : String) extends FunctionSet {
- class SphereIndex(parent: PPDFunctionSet) extends DiscreteIndex {
- def getName = "sphere_index"
- def getDependencies = Set()
- def getDenseWidth(names: NameManager) = parent.getNumSpheres(names)
-
- def generateIterationHeader(names: NameManager) = {
- val indexName = names(this)
- "do "+indexName+"=1," + parent.getSphere(names) + "%n_ppds_sphere"
- }
-
- def generateIterationFooter(names: NameManager) = "end do"
- def getDeclarations(names: NameManager) = List("integer :: "+names(this))
- }
-
- class PPDIndex(parent: PPDFunctionSet) extends DiscreteIndex {
- var denseIndexNames : List[String] = Nil
- var startNames : List[String] = Nil
- var finishNames : List[String] = Nil
- var offsetNames : List[String] = Nil
- var ppdPoint : String = ""
-
- def getName = "ppd_index"
- def getPPDPoint = ppdPoint
- def getStartNames = startNames
- def getFinishNames = finishNames
- def getOffsetNames = offsetNames
- def getDependencies = Set[Index](parent.getSphereIndex)
- def getDensePPDIndices = denseIndexNames
-
- def getDenseWidth(names: NameManager) = parent.basis+"%max_n_ppds_sphere"
-
- def generateIterationHeader(names: NameManager) = {
- val findPPD = "call basis_find_ppd_in_neighbour(" + denseIndexNames.mkString(",") + ", &\n" +
- parent.getSphere(names) + "%ppd_list(1," + names(this) + "), &\n" +
- parent.getSphere(names) + "%ppd_list(2," + names(this) + "), &\n" +
- "pub_cell%n_ppds_a1, pub_cell%n_ppds_a2, pub_cell%n_ppds_a3)"
-
- val computeRanges = for (dim <- 1 to 2) yield {
- val tb = parent.getTightbox(names)
-
- "call basis_lims_1d_in_ppd_in_tight("+startNames(dim)+", "+finishNames(dim)+", "+offsetNames(dim)+", &\n" +
- denseIndexNames(dim)+", "+tb+"%start_ppds2, "+tb+"%finish_ppds2, &\n" +
- tb+"%start_pts2, "+tb+"%finish_pts2, pub_cell%n_pt"+dim+")"
- }
-
- val loopDeclaration = "do "+names(this)+"=1,"+parent.getSphere(names)+"%n_ppds_sphere"
-
- val ppdOffsetCalc = ppdPoint + " = " + parent.getSphere(names)+"%offset + ("+names(this)+"-1)*pub_cell%n_pts &\n"+
- "+ ("+startNames(2)+"-1)*pub_cell%n_pt2*pub_cell%n_pt1 &\n"+
- "+ ("+startNames(1)+"-1)*pub_cell%n_pt1 + ("+startNames(0)+"-1)"
-
- (List(findPPD) ++ computeRanges ++ List(loopDeclaration) ++ List(ppdOffsetCalc)).mkString("\n")
- }
-
- def generateIterationFooter(names: NameManager) = "end do"
-
- def getDeclarations(names: NameManager) = {
- denseIndexNames = (for (dim <- 0 to 2) yield names.newIdentifier("derived_ppd_position_"+dim)).toList
- startNames = (for (dim <- 0 to 2) yield names.newIdentifier("tightbox_start_"+dim)).toList
- finishNames = (for (dim <- 0 to 2) yield names.newIdentifier("tightbox_finish_"+dim)).toList
- offsetNames = (for (dim <- 0 to 2) yield names.newIdentifier("tightbox_offset_"+dim)).toList
- ppdPoint = names.newIdentifier("fa_point")
- (denseIndexNames++finishNames++offsetNames++Some(ppdPoint)).map(x => "integer :: " + x) ++ List("integer :: "+names(this))
- }
- }
-
- class IntraPPDIndex(parent: PPDFunctionSet, dimension: Int) extends SpatialIndex {
- var tbPoint : String = ""
-
- def getName = "intra_ppd_index_" + dimension
- private def getPPDIndex = parent.getPPDIndex
- def getDependencies = {
- val parentIndex = if (dimension < parent.getSpatialIndices.size-1)
- Some(parent.getSpatialIndices(dimension+1))
- else
- None
-
- Set[Index](getPPDIndex) ++ parentIndex
- }
- def getDenseWidth(names: NameManager) = "pub_cell%total_pt"+(dimension+1)
- def generateIterationHeader(names: NameManager) = {
- val findPoint = tbPoint + " = " +
- names(this) + " - " + getPPDIndex.getStartNames(dimension) + " + " +
- getPPDIndex.getOffsetNames(dimension) + " + 1"
-
- val header = "do "+names(this)+"="+getPPDIndex.getStartNames(dimension)+","+getPPDIndex.getFinishNames(dimension)
-
- List(findPoint, header).mkString("\n")
- }
-
- def generateIterationFooter(names: NameManager) = {
- val incPoint = if (dimension == 0) Some(getPPDIndex.ppdPoint + " = " + getPPDIndex.ppdPoint + " + 1") else None
- val jumpOffset = "pub_cell%n_pt"+(dimension+1)+"-" +
- getPPDIndex.getFinishNames(dimension)+"+"+
- getPPDIndex.getStartNames(dimension)+"-1"
- val jumpPoint = (List(getPPDIndex.ppdPoint + " = " + getPPDIndex.ppdPoint + " + (" + jumpOffset +")") ++
- (for (dim <- 0 until dimension) yield "pub_cell%n_pt"+(dim+1))).mkString("*")
- val endLoop = "end do"
-
- (incPoint ++ List(endLoop, jumpPoint)).mkString("\n")
- }
-
- def getDeclarations(names: NameManager) = {
- tbPoint = names.newIdentifier("tb_pt"+(dimension+1))
- List("integer :: "+names(this), "integer :: "+tbPoint)
- }
-
- override def getDensePosition(names: NameManager) =
- tbPoint
- }
-
- val ppdIndex = new PPDIndex(this)
- val sphereIndex = new SphereIndex(this)
- val spatialIndices = for (dimension <- 0 to 2) yield new IntraPPDIndex(this, dimension)
-
- def getPPDIndex = ppdIndex
- def getSphereIndex = sphereIndex
- def getSphere(names: NameManager) = basis + "%spheres("+names(getSphereIndex)+")"
- def getTightbox(names: NameManager) = basis + "%tight_boxes("+names(getSphereIndex)+")"
-
- def getNumSpheres(names: NameManager) = {
- // TODO: This number is dependent on the parallel distribution
- basis + "%node_num"
- }
-
- def getSpatialIndices = spatialIndices.toList
- def getDiscreteIndices = List(getSphereIndex)
- def getExternalIndices = Set(getPPDIndex)
-
- def getProducerGenerator = Some(new ProducerGenerator {
- def generate(names: NameManager) = {
- data+"("+getPPDIndex.getPPDPoint+")"
- }
- })
-}
-
class BindingIndex(name : String) {
override def toString() = name
}