* that computes an FIR (ef pop 1, push 1, peek x) and we want to replace it with an FFT. * Note that N is the block size of the input that we are looking at. */ int x = linearRep.getPeekCount(); int N = calculateN(x); int filterSize = N+2*(x-1);
* and we want to replace it with an frequency version using the FFT.*/ int x = linearRep.getPeekCount(); int N = calculateN(x); int filterSize = N+2*(x-1);
    public boolean makeReplacement(SIRStream self) {	LinearPrinter.println(" processing " + self.getIdent());	// make sure we can replace this.	if (!canReplace(self, this.linearityInformation)) {	    return false;	}	LinearFilterRepresentation linearRep = this.linearityInformation.getLinearRepresentation(self);	/** set the target FFT size appropriately if it hasn't already been set */	/* now is when we get to the fun part, we have a linear representation	 * that computes an FIR (ef pop 1, push 1, peek x) and we want to replace it with an FFT.	 * Note that N is the block size of the input that we are looking at. */	int x = linearRep.getPeekCount();	int N = calculateN(x);	int filterSize = N+2*(x-1); // this is the size of the overall filter	LinearPrinter.println("  creating frequency filter.\n" +			      "   N+(x-1)=" + (N+x-1) + " (outputs per steady state)\n" + 			      "   x=" + x + " (peek, original filter size)\n" +			      "   filterSize=" + filterSize + " (FFT size)");		/////////////// Create the new fields for this filter.	int numWeightFields = linearRep.getPushCount(); // Eg the number of columns in the matrix	JFieldDeclaration[] newFields = self.getFields();		/* make the fields to hold the transform of the weights. Note that the	   weights are stored in "half complex array" format which is the output format	   generated by FFTW. The first weight field corresponds to the weight field of	   the right most column, the next weight field corresponds to the weight field	   of the next right most column, etc. */	JVariableDefinition[] weightFields = new JVariableDefinition[numWeightFields];	for (int i=0; i<numWeightFields; i++) {	    weightFields[i] = makeWeightField(FILTER_WEIGHTS_PREFIX + "_" + i);	    newFields = appendFieldDeclaration(newFields, weightFields[i]);	}		/* make the fields to hold the partial results between executions. These	   fields are also stored in half complex array format, and each corresponds	   to the same column as does the weight fields. */	JVariableDefinition[] partialFields = new JVariableDefinition[numWeightFields];	for (int i=0; i<numWeightFields; i++) {	    partialFields[i] = makeWeightField(PARTIAL_BUFFER_PREFIX + "_" + i);	    newFields = appendFieldDeclaration(newFields, partialFields[i]);	}	/* make the input and temp buffer fields. */	JVariableDefinition inputBufferField  = makeWeightField(INPUT_BUFFER_NAME);	newFields = appendFieldDeclaration(newFields, inputBufferField);	JVariableDefinition tempBufferField  = makeWeightField(TEMP_BUFFER_NAME);	newFields = appendFieldDeclaration(newFields, tempBufferField); 	/** make enough output buffers to hold the appropriate outputs. **/	JVariableDefinition outputBufferFields[] = new JVariableDefinition[numWeightFields];	for (int i=0; i<numWeightFields; i++) {	    outputBufferFields[i] = makeWeightField(OUTPUT_BUFFER_NAME + "_" + i);	    newFields = appendFieldDeclaration(newFields, outputBufferFields[i]);	}				/* make a new init function */	JMethodDeclaration freqInit = makeNewInit(linearRep,						  weightFields, partialFields,						  inputBufferField, tempBufferField,						  outputBufferFields,						  filterSize, x);		/* make the init work function */	JMethodDeclaration freqInitWork = makeNewWork(INITWORK,						      weightFields, partialFields,						      inputBufferField, tempBufferField,						      outputBufferFields,						      filterSize, x, N);		/* make a new work function */	JMethodDeclaration freqWork = makeNewWork(WORK,						  weightFields, partialFields,						  inputBufferField, tempBufferField,						  outputBufferFields,						  filterSize, x, N);			LinearPrinter.println("  done building new IR nodes for " + self.getIdent());		LinearPrinter.println("  creating new two stage filter...");	// Create a new filter that contains all of the new pieces that we have built	SIRStream replacement;	/* Note, we need to have initPeek-initPop == peek-Pop for some scheduling reason	 * so therefore, we set the peek rate of the work function to be N+2(x-1) even though	 * it really only needs to be N+x-1.*/	replacement = new SIRTwoStageFilter(self.getParent(),              /* parent */					   "TwoStageFreq"+self.getIdent(),/* ident */					   newFields,                     /* fields */					   new JMethodDeclaration[0],     /* methods Note:									     -- init, work, and									     initWork are special. */					   new JIntLiteral(N+x-1),        /* peek (w/ extra x-1 window...)*/					   new JIntLiteral(N+x-1),        /* pop */					   new JIntLiteral((N+x-1)*numWeightFields), /* push (note that the											push count needs to											be scaled by the											number of outputs											(because each FIR											filter outputs N+x-1 */					   freqWork,                      /* work */					   N+x-1,                         /* initPeek */					   N+x-1,                         /* initPop */					   N*numWeightFields,             /* initPush */					   freqInitWork,                  /* initWork */					   self.getInputType(),           /* input type */					   self.getOutputType());         /* output type */	// need to explicitly set the init function	replacement.setInit(freqInit);	// if we have a pop rate greater than one, then put a decimator next to <replacement>	if (linearRep.getPopCount()>1) {	    SIRPipeline wrapper = new SIRPipeline(self.getParent(), replacement.getIdent()+"_dec_wrap");	    wrapper.setInit(SIRStream.makeEmptyInit());	    wrapper.add(replacement);	    wrapper.add(makeDecimatorForFrequencyNode(linearRep.getPushCount(), linearRep.getPopCount(), replacement.getOutputType()));	    // now remember this new wrapper as our replacement instead of the original	    replacement = wrapper;	}	// do unrolling on the new filter.  (Unrolling is part of	// filter loweing; will get field propagation and stuff node	// optimization, etc., as added bonus.)	Flattener.lowerFilterContents(replacement, false);		// now replace the current filter (self) with the frequency version	self.getParent().replace(self, replacement);		LinearPrinter.println("  done replacing.");		// return true since we replaced something	return true;    }