From: Francis Russell Date: Thu, 3 May 2012 01:08:17 +0000 (+0100) Subject: Add field scaling operator. X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=7c65bbf1d463b265c1a3176f1b3a75acfb352e40;p=francis%2Fofc.git Add field scaling operator. --- diff --git a/src/ofc/generators/onetep/DensePsincToReciprocal.scala b/src/ofc/generators/onetep/DensePsincToReciprocal.scala new file mode 100644 index 0000000..640be99 --- /dev/null +++ b/src/ofc/generators/onetep/DensePsincToReciprocal.scala @@ -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) +} diff --git a/src/ofc/generators/onetep/FieldFragment.scala b/src/ofc/generators/onetep/FieldFragment.scala index 1ccc07c..0129b94 100644 --- a/src/ofc/generators/onetep/FieldFragment.scala +++ b/src/ofc/generators/onetep/FieldFragment.scala @@ -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 { diff --git a/src/ofc/generators/onetep/InnerProduct.scala b/src/ofc/generators/onetep/InnerProduct.scala index 7f77246..bbbf3f3 100644 --- a/src/ofc/generators/onetep/InnerProduct.scala +++ b/src/ofc/generators/onetep/InnerProduct.scala @@ -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) diff --git a/src/ofc/generators/onetep/Laplacian.scala b/src/ofc/generators/onetep/Laplacian.scala index f1bf392..7d9766d 100644 --- a/src/ofc/generators/onetep/Laplacian.scala +++ b/src/ofc/generators/onetep/Laplacian.scala @@ -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 diff --git a/src/ofc/generators/onetep/PPDFunctionSet.scala b/src/ofc/generators/onetep/PPDFunctionSet.scala index 84267a7..83c10e6 100644 --- a/src/ofc/generators/onetep/PPDFunctionSet.scala +++ b/src/ofc/generators/onetep/PPDFunctionSet.scala @@ -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 diff --git a/src/ofc/generators/onetep/ReciprocalToPsinc.scala b/src/ofc/generators/onetep/ReciprocalToPsinc.scala index 52bcd6b..e138404 100644 --- a/src/ofc/generators/onetep/ReciprocalToPsinc.scala +++ b/src/ofc/generators/onetep/ReciprocalToPsinc.scala @@ -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 } diff --git a/src/ofc/generators/onetep/SPAM3.scala b/src/ofc/generators/onetep/SPAM3.scala index bcffbce..d2d97e1 100644 --- a/src/ofc/generators/onetep/SPAM3.scala +++ b/src/ofc/generators/onetep/SPAM3.scala @@ -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) { } } diff --git a/src/ofc/generators/onetep/ScalarFragment.scala b/src/ofc/generators/onetep/ScalarFragment.scala index 20ff425..850c213 100644 --- a/src/ofc/generators/onetep/ScalarFragment.scala +++ b/src/ofc/generators/onetep/ScalarFragment.scala @@ -1,3 +1,6 @@ package ofc.generators.onetep +import ofc.codegen._ -trait ScalarFragment extends Fragment +trait ScalarFragment extends Fragment { + def getValue : Expression[FloatType] +} diff --git a/src/ofc/generators/onetep/ScalarLiteral.scala b/src/ofc/generators/onetep/ScalarLiteral.scala index 12fb2dc..e3ed04b 100644 --- a/src/ofc/generators/onetep/ScalarLiteral.scala +++ b/src/ofc/generators/onetep/ScalarLiteral.scala @@ -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) - } diff --git a/src/ofc/generators/onetep/ScaledField.scala b/src/ofc/generators/onetep/ScaledField.scala index d7aa6db..e90f004 100644 --- a/src/ofc/generators/onetep/ScaledField.scala +++ b/src/ofc/generators/onetep/ScaledField.scala @@ -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) + }