]> git.unchartedbackwaters.co.uk Git - francis/ofc.git/commitdiff
Add field scaling operator.
authorFrancis Russell <francis@unchartedbackwaters.co.uk>
Thu, 3 May 2012 01:08:17 +0000 (02:08 +0100)
committerFrancis Russell <francis@unchartedbackwaters.co.uk>
Thu, 3 May 2012 01:08:17 +0000 (02:08 +0100)
src/ofc/generators/onetep/DensePsincToReciprocal.scala [new file with mode: 0644]
src/ofc/generators/onetep/FieldFragment.scala
src/ofc/generators/onetep/InnerProduct.scala
src/ofc/generators/onetep/Laplacian.scala
src/ofc/generators/onetep/PPDFunctionSet.scala
src/ofc/generators/onetep/ReciprocalToPsinc.scala
src/ofc/generators/onetep/SPAM3.scala
src/ofc/generators/onetep/ScalarFragment.scala
src/ofc/generators/onetep/ScalarLiteral.scala
src/ofc/generators/onetep/ScaledField.scala

diff --git a/src/ofc/generators/onetep/DensePsincToReciprocal.scala b/src/ofc/generators/onetep/DensePsincToReciprocal.scala
new file mode 100644 (file)
index 0000000..640be99
--- /dev/null
@@ -0,0 +1,33 @@
+package ofc.generators.onetep
+import ofc.codegen._
+
+class DensePsincToReciprocal(op: DensePsincFragment, indices: Map[NamedIndex, Expression[IntType]]) extends ReciprocalFragment {
+  import OnetepTypes.FunctionBasis
+  val reciprocalBox = new DeclaredVarSymbol[ArrayType[ComplexType]]("reciprocal_box", new ArrayType[ComplexType](3))
+
+  def setup(context: GenerationContext) {
+    import OnetepTypes.FFTBoxInfo
+
+    op.setup(context)
+    context.addDeclaration(reciprocalBox)
+
+    val fftboxSize : Seq[Expression[IntType]] = op.getSize
+    context += new AllocateStatement(reciprocalBox, fftboxSize)
+
+    val fourierParams : Seq[Expression[_]] = Seq(new CharLiteral('C'), new CharLiteral('F'), op.getBuffer, op.getBuffer, reciprocalBox)
+    context += new FunctionCallStatement(new FunctionCall(OnetepFunctions.fourier_apply_box_pair, fourierParams))
+    op.teardown(context)
+  }
+
+  def teardown(context: GenerationContext) {
+    context += new DeallocateStatement(reciprocalBox)
+  }
+
+  def getSize = for (dim <- 0 to 2) yield OnetepTypes.FFTBoxInfo.public % OnetepTypes.FFTBoxInfo.totalPts(dim)
+
+  def getBuffer = reciprocalBox
+
+  def toPsinc = new ReciprocalToPsinc(this)
+
+  def toDensePsinc = new ReciprocalToPsinc(this)
+}
index 1ccc07ce0fee55b65a55baaba7ca1c2ec68a82c6..0129b94b180fee2b324261cb8a46ce25dd3fe554 100644 (file)
@@ -4,10 +4,17 @@ import ofc.codegen._
 trait FieldFragment extends Fragment {
   def toReciprocal : ReciprocalFragment
   def toPsinc : PsincFragment
+  def toDensePsinc : DensePsincFragment
 }
 
 trait PsincFragment extends FieldFragment {
   def toPsinc = this
+  def getSize : Seq[Expression[IntType]] 
+}
+
+trait DensePsincFragment extends PsincFragment {
+  def getBuffer : Expression[ArrayType[FloatType]]
+  def toDensePsinc = this
 }
 
 trait ReciprocalFragment extends FieldFragment {
index 7f77246ae5583c7945a59b0eb4e0ca7215f9274d..bbbf3f31a922896a8ca6b595b8972e88afa7a595 100644 (file)
@@ -9,6 +9,8 @@ class InnerProduct(left: Field, right: Field) extends Scalar {
       right.setup(context)
     }
 
+    def getValue = throw new ofc.UnimplementedException("rargh!")
+
     def teardown(context: GenerationContext) {
       left.teardown(context)
       right.teardown(context)
index f1bf392bccdd1c5b7ebee64459d42f56b1253443..7d9766d936e56e6a76d354b2d50586d141e6d31e 100644 (file)
@@ -65,6 +65,8 @@ class Laplacian(op: Field)  extends Field {
     def getBuffer = transformed
 
     def toPsinc = new ReciprocalToPsinc(this)
+
+    def toDensePsinc = new ReciprocalToPsinc(this)
   }
   
   private def getOperand = op
index 84267a74d55ad1b830495c9ec8ae0c8d4e2bcd8c..83c10e6c2017f671675888e6f91eebedc2a43d1f 100644 (file)
@@ -1,6 +1,6 @@
 package ofc.generators.onetep
 import ofc.codegen._
-import ofc.LogicError
+import ofc.{LogicError,UnimplementedException}
 /*
 object PPDFunctionSet {
   private class SphereIndex(name: String, value: Expression[IntType]) extends DiscreteIndex {
@@ -105,10 +105,14 @@ class PPDFunctionSet(basisName: String, dataName: String, indices: Seq[NamedInde
   class LocalFragment(parent: PPDFunctionSet, indices: Map[NamedIndex, Expression[IntType]]) extends PsincFragment {
     def setup(context: GenerationContext) {}
     def teardown(context: GenerationContext) {}
-    def toReciprocal : ReciprocalFragment = new LocalReciprocal(parent, indices)
+    def toReciprocal : ReciprocalFragment = toDensePsinc.toReciprocal
+
+    //FIXME: implement me!
+    def getSize = throw new UnimplementedException("Implement me!")
+    def toDensePsinc = new LocalDense(parent, indices)
   }
 
-  class LocalReciprocal(parent: PPDFunctionSet, indices: Map[NamedIndex, Expression[IntType]]) extends ReciprocalFragment {
+  class LocalDense(parent: PPDFunctionSet, indices: Map[NamedIndex, Expression[IntType]]) extends DensePsincFragment {
     import OnetepTypes.FunctionBasis
 
     val sphereIndex = indices.get(parent.getSphereIndex) match {
@@ -120,18 +124,15 @@ class PPDFunctionSet(basisName: String, dataName: String, indices: Seq[NamedInde
     val tightbox = (~(basis % FunctionBasis.tightBoxes)).at(sphereIndex)
     val sphere = (~(basis % FunctionBasis.spheres)).at(sphereIndex) 
     val fftboxOffset = for(dim <- 0 to 2) yield new DeclaredVarSymbol[IntType]("fftbox_offset"+(dim+1)) 
-    val reciprocalBox = new DeclaredVarSymbol[ArrayType[ComplexType]]("reciprocal_box", new ArrayType[ComplexType](3))
 
     def setup(context: GenerationContext) {
       import OnetepTypes.FFTBoxInfo
 
       context.addDeclaration(fftbox)
-      context.addDeclaration(reciprocalBox)
       fftboxOffset.map(context.addDeclaration(_))
 
       val fftboxSize : Seq[Expression[IntType]] = getSize
       context += new AllocateStatement(fftbox, fftboxSize)
-      context += new AllocateStatement(reciprocalBox, fftboxSize)
       context += new FunctionCallStatement(new FunctionCall(OnetepFunctions.basis_ket_start_wrt_fftbox,
         fftboxOffset.map(new VarRef[IntType](_)) ++ fftboxSize))
 
@@ -143,22 +144,17 @@ class PPDFunctionSet(basisName: String, dataName: String, indices: Seq[NamedInde
       basisCopyParams :+= sphere
 
       context += new FunctionCallStatement(new FunctionCall(OnetepFunctions.basis_copy_function_to_fftbox, basisCopyParams))
-
-      val fourierParams : Seq[Expression[_]] = Seq(new CharLiteral('C'), new CharLiteral('F'), fftbox, fftbox, reciprocalBox)
-      context += new FunctionCallStatement(new FunctionCall(OnetepFunctions.fourier_apply_box_pair, fourierParams))
-
-      context += new DeallocateStatement(fftbox)
     }
 
     def teardown(context: GenerationContext) {
-      context += new DeallocateStatement(reciprocalBox)
+      context += new DeallocateStatement(fftbox)
     }
 
     def getSize = for (dim <- 0 to 2) yield OnetepTypes.FFTBoxInfo.public % OnetepTypes.FFTBoxInfo.totalPts(dim)
 
-    def getBuffer = reciprocalBox
+    def getBuffer = fftbox
 
-    def toPsinc = new ReciprocalToPsinc(this)
+    def toReciprocal = new DensePsincToReciprocal(this, indices)
   }
 
   private def getSphereIndex = indices.head
index 52bcd6b04a46804228c05a39f2df3340c20f9b28..e1384042be67cf5d73fa2ec2bf68645f54a50da7 100644 (file)
@@ -1,7 +1,7 @@
 package ofc.generators.onetep
 import ofc.codegen._
 
-class ReciprocalToPsinc(op: ReciprocalFragment) extends PsincFragment {
+class ReciprocalToPsinc(op: ReciprocalFragment) extends DensePsincFragment {
   val fftbox = new DeclaredVarSymbol[ArrayType[FloatType]]("fftbox", new ArrayType[FloatType](3))
 
   def toReciprocal = op
@@ -24,4 +24,6 @@ class ReciprocalToPsinc(op: ReciprocalFragment) extends PsincFragment {
   }
 
   def getSize = for (dim <- 0 to 2) yield OnetepTypes.FFTBoxInfo.public % OnetepTypes.FFTBoxInfo.totalPts(dim)
+
+  def getBuffer = fftbox
 }
index bcffbce1a26983d9ecaa2e04cb158f02fc2ff5b6..d2d97e1e26738707b2238f621e0ea9d538a52c4f 100644 (file)
@@ -6,6 +6,8 @@ class SPAM3(name : String, indices: Seq[NamedIndex]) extends Scalar {
     def setup(context: GenerationContext) {
     }
 
+    def getValue = throw new ofc.UnimplementedException("rargh!")
+
     def teardown(context: GenerationContext) {
     }
   }
index 20ff425b79649710fab8bb4956322034d7b1e273..850c21314ea5ec3897a9dab9fc8e713a35935349 100644 (file)
@@ -1,3 +1,6 @@
 package ofc.generators.onetep
+import ofc.codegen._
 
-trait ScalarFragment extends Fragment
+trait ScalarFragment extends Fragment {
+  def getValue : Expression[FloatType]
+}
index 12fb2dcd5657339f8b49a7f008dca80a2d7e7837..e3ed04b079e59d0553e02f2830c44ec9ca511be5 100644 (file)
@@ -6,11 +6,13 @@ class ScalarLiteral(s: Double) extends Scalar {
     def setup(context: GenerationContext) {
     }
 
+    def getValue =
+      new FloatLiteral(s)
+
     def teardown(context: GenerationContext) {
     }
   }
 
   def getFragment(indices: Map[NamedIndex, Expression[IntType]]) : ScalarFragment =
     new LocalFragment(s)
-
 }
index d7aa6dbb58dcc83c90096c064cf1e48a9628dd46..e90f0041ba26cc98ac899df44dad32100bca52fd 100644 (file)
@@ -2,6 +2,62 @@ package ofc.generators.onetep
 import ofc.codegen._
 
 class ScaledField(op: Field, factor: Scalar) extends Field {
-  def getFragment(indices: Map[NamedIndex, Expression[IntType]]) : FieldFragment =
-    op.getFragment(indices)
+  class LocalFragment(parent: ScaledField, indices: Map[NamedIndex, Expression[IntType]]) extends DensePsincFragment {
+    val transformed = new DeclaredVarSymbol[ArrayType[FloatType]]("scaled", new ArrayType[FloatType](3))
+    val scaleFragment = parent.getScalingFactor.getFragment(indices)
+    val opFragment = parent.getOperand.getFragment(indices).toDensePsinc
+
+    def setup(context: GenerationContext) {
+      context.addDeclaration(transformed)
+      opFragment.setup(context)
+      scaleFragment.setup(context)
+
+      context += new AllocateStatement(transformed, opFragment.getSize)
+
+      val indices = for(dim <- 0 to 2) yield {
+        val index = new DeclaredVarSymbol[IntType]("i"+(dim+1))
+        context.addDeclaration(index)
+        index
+      }
+
+      // Construct loops
+      val loops = for(dim <- 0 to 2) yield new ForLoop(indices(dim), 1, getSize(dim))
+
+      // Nest loops and add outer to context
+      for(dim <- 1 to 2) loops(dim) += loops(dim-1)
+      context += loops(2)
+      
+      val index = indices.map(new VarRef[IntType](_))
+      
+      loops(0) += new AssignStatement(transformed.at(index: _*), 
+        opFragment.getBuffer.at(index: _*) * scaleFragment.getValue)
+
+      opFragment.teardown(context)
+      scaleFragment.teardown(context)
+    }
+
+    private def magnitude(vector: Seq[Expression[FloatType]]) = {
+      var result : Expression[FloatType] = new FloatLiteral(0.0)
+      for(element <- vector) result += element * element
+      result
+    }
+
+    def teardown(context: GenerationContext) {
+      context += new DeallocateStatement(transformed)
+    }
+
+    def getSize = opFragment.getSize
+
+    def getBuffer = transformed
+
+    def toReciprocal = new DensePsincToReciprocal(this, indices)
+  }
+  
+  private def getOperand = op
+
+  private def getScalingFactor = factor
+
+  def getFragment(indices: Map[NamedIndex, Expression[IntType]]) = 
+    new LocalFragment(this, indices)
+
 }