package ofc.generators.onetep
import ofc.codegen._
-class PPDFunctionSet(val basisName: String, dataName: String) extends FunctionSet {
- import OnetepTypes._
+object PPDFunctionSet {
+ private val pubCell = new NamedUnboundVarSymbol[StructType]("pub_cell", OnetepTypes.CellInfo)
- val basis = new NamedUnboundVarSymbol[StructType](basisName, FunctionBasis)
- val data = new NamedUnboundVarSymbol[ArrayType[FloatType]](dataName, new ArrayType[FloatType](1))
- val pubCell = new NamedUnboundVarSymbol[StructType]("pub_cell", OnetepTypes.CellInfo)
+ private class SphereIndex(name: String, value: Expression[IntType]) extends DiscreteIndex {
+ def getName = name
+ def getValue = value
+ }
+
+ private class PositionIndex(name: String, value: Expression[IntType]) extends SpatialIndex {
+ def getName = name
+ def getValue = value
+ }
+
+ def apply(basisName: String, dataName: String) : PPDFunctionSet = {
+ import OnetepTypes._
+
+ val basis = new NamedUnboundVarSymbol[StructType](basisName, FunctionBasis)
+ val data = new NamedUnboundVarSymbol[ArrayType[FloatType]](dataName, new ArrayType[FloatType](1))
- val numSpheres = basis % FunctionBasis.num
- val ppdWidths = for(dim <- 0 to 2) yield pubCell % CellInfo.ppdWidth(dim)
- val cellWidthInPPDs = for(dim <- 0 to 2) yield pubCell % CellInfo.numPPDs(dim)
+ val numSpheres = basis % FunctionBasis.num
+ val ppdWidths = for(dim <- 0 to 2) yield pubCell % CellInfo.ppdWidth(dim)
+ val cellWidthInPPDs = for(dim <- 0 to 2) yield pubCell % CellInfo.numPPDs(dim)
- def getSuffixFragment = {
val producer = new ProducerStatement
val sphereIndex = producer.addIteration("sphere_index", 1, numSpheres)
val numPPDs = (~(basis % FunctionBasis.numPPDsInSphere)).readAt(sphereIndex)
+ (ppdIndices(0)-1))
val dataValue = producer.addExpression("data", data.readAt(ppdDataIndex))
-
- producer
- }
-
- def getDiscreteIndices = List.empty
- def getSpatialIndices = List.empty
-/*
- 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)+", &\n"+finishNames(dim)+", &\n"+offsetNames(dim)+", &\n" +
- denseIndexNames(dim)+", &\n"+tb+"%start_ppds2, &\n"+tb+"%finish_ppds2, &\n" +
- tb+"%start_pts2, &\n"+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, 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")
-
- val allDeclarations = denseIndexNames++startNames++finishNames++offsetNames++Some(ppdPoint)
- allDeclarations.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"
+ val discreteIndices = List[DiscreteIndex](new SphereIndex("sphere", sphereIndex))
+ val spatialIndices = {for ((name, index) <- List[String]("x", "y", "z") zip positions) yield new PositionIndex(name, index)}
+
+ new PPDFunctionSet(discreteIndices, spatialIndices, dataValue, producer)
}
-
- 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 PPDFunctionSet private(discreteIndices: Seq[DiscreteIndex],
+ spatialIndices: Seq[SpatialIndex], data: Expression[FloatType],
+ producer: Statement) extends FunctionSet {
+ def getSuffixFragment = producer
+ def getDiscreteIndices = discreteIndices
+ def getSpatialIndices = spatialIndices
+ def getDataValue = data
+}