]> git.unchartedbackwaters.co.uk Git - francis/ofc.git/commitdiff
Move multiple IterationSpace classes into new files.
authorFrancis Russell <francis@unchartedbackwaters.co.uk>
Tue, 7 Feb 2012 18:03:57 +0000 (18:03 +0000)
committerFrancis Russell <francis@unchartedbackwaters.co.uk>
Tue, 7 Feb 2012 18:03:57 +0000 (18:03 +0000)
src/ofc/generators/onetep/Assignment.scala [new file with mode: 0644]
src/ofc/generators/onetep/GeneralInnerProduct.scala [new file with mode: 0644]
src/ofc/generators/onetep/Index.scala [new file with mode: 0644]
src/ofc/generators/onetep/IterationSpace.scala [new file with mode: 0644]
src/ofc/generators/onetep/Laplacian.scala [new file with mode: 0644]
src/ofc/generators/onetep/PPDFunctionSet.scala [new file with mode: 0644]
src/ofc/generators/onetep/Reciprocal.scala [new file with mode: 0644]
src/ofc/generators/onetep/SPAM3.scala [new file with mode: 0644]
src/ofc/generators/onetep/Scalar.scala [new file with mode: 0644]
src/ofc/generators/onetep/SpatialRestriction.scala [new file with mode: 0644]
src/ofc/generators/onetep/Tree.scala

diff --git a/src/ofc/generators/onetep/Assignment.scala b/src/ofc/generators/onetep/Assignment.scala
new file mode 100644 (file)
index 0000000..4d779c4
--- /dev/null
@@ -0,0 +1,13 @@
+package ofc.generators.onetep
+
+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
+}
diff --git a/src/ofc/generators/onetep/GeneralInnerProduct.scala b/src/ofc/generators/onetep/GeneralInnerProduct.scala
new file mode 100644 (file)
index 0000000..6b8e9b6
--- /dev/null
@@ -0,0 +1,47 @@
+package ofc.generators.onetep
+
+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
+}
+
+
diff --git a/src/ofc/generators/onetep/Index.scala b/src/ofc/generators/onetep/Index.scala
new file mode 100644 (file)
index 0000000..2b3e5c0
--- /dev/null
@@ -0,0 +1,29 @@
+package ofc.generators.onetep
+
+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
+
+
diff --git a/src/ofc/generators/onetep/IterationSpace.scala b/src/ofc/generators/onetep/IterationSpace.scala
new file mode 100644 (file)
index 0000000..bf02a19
--- /dev/null
@@ -0,0 +1,44 @@
+package ofc.generators.onetep
+
+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 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
diff --git a/src/ofc/generators/onetep/Laplacian.scala b/src/ofc/generators/onetep/Laplacian.scala
new file mode 100644 (file)
index 0000000..e2d9649
--- /dev/null
@@ -0,0 +1,14 @@
+package ofc.generators.onetep
+
+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
+}
+
+
diff --git a/src/ofc/generators/onetep/PPDFunctionSet.scala b/src/ofc/generators/onetep/PPDFunctionSet.scala
new file mode 100644 (file)
index 0000000..a9e0b39
--- /dev/null
@@ -0,0 +1,140 @@
+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+")"
+    }
+  })
+}
+
+
diff --git a/src/ofc/generators/onetep/Reciprocal.scala b/src/ofc/generators/onetep/Reciprocal.scala
new file mode 100644 (file)
index 0000000..b16d5f3
--- /dev/null
@@ -0,0 +1,26 @@
+package ofc.generators.onetep
+
+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
+}
+
+
diff --git a/src/ofc/generators/onetep/SPAM3.scala b/src/ofc/generators/onetep/SPAM3.scala
new file mode 100644 (file)
index 0000000..abbe79b
--- /dev/null
@@ -0,0 +1,48 @@
+package ofc.generators.onetep
+
+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
+}
+
+
diff --git a/src/ofc/generators/onetep/Scalar.scala b/src/ofc/generators/onetep/Scalar.scala
new file mode 100644 (file)
index 0000000..2eb8437
--- /dev/null
@@ -0,0 +1,12 @@
+package ofc.generators.onetep
+
+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
+  })
+}
+
+
diff --git a/src/ofc/generators/onetep/SpatialRestriction.scala b/src/ofc/generators/onetep/SpatialRestriction.scala
new file mode 100644 (file)
index 0000000..89df1f2
--- /dev/null
@@ -0,0 +1,26 @@
+package ofc.generators.onetep
+
+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
+}
+
+
index 78ac56b90ee0b6a0ccbde8464a356e896f6b97b1..738f571513deac962d6cd303ba7e3336e17a2567 100644 (file)
@@ -4,48 +4,6 @@ import ofc.parser
 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
 }
@@ -58,337 +16,6 @@ trait TransformGenerator {
   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
 }