at.dms.kjc.backendSupport
Class BackEndFactory<ComputeNodesType extends ComputeNodesI<?>,ComputeNodeType extends ComputeNode<?>,CodeStoreType extends ComputeCodeStore<?>,ComputeNodeSelectorArgType>

java.lang.Object
  extended by at.dms.kjc.backendSupport.BackEndFactory<ComputeNodesType,ComputeNodeType,CodeStoreType,ComputeNodeSelectorArgType>
Type Parameters:
ComputeNodesType - Instantiate to type of a collection of ComputeNodes.
ComputeNodeType - Instantiate to type of an individual ComputeNode
CodeStoreType - Instantiate to type of a ComputeCodeStore.
ComputeNodeSelectorArgType - Instantiate to base type of array of extra arguments to getComputeNode. (Necessary for overriding method with reasonable types.)
Direct Known Subclasses:
CellBackendFactory, RawBackEndFactory, UniBackEndFactory

public abstract class BackEndFactory<ComputeNodesType extends ComputeNodesI<?>,ComputeNodeType extends ComputeNode<?>,CodeStoreType extends ComputeCodeStore<?>,ComputeNodeSelectorArgType>
extends Object

Factor out parts of back end that need matching types. A BackEndFactory should generate the parts needed for a back end.

Author:
dimock
See Also:
BackEndAbsFactory

Field Summary
protected  Layout<ComputeNodeType> layout
           
 
Constructor Summary
BackEndFactory()
           
 
Method Summary
abstract
<T extends BackEndScaffold>
T
getBackEndMain()
           
abstract  Channel getChannel(Edge e)
          Back end needs to generate subclasses of channel.
abstract  Channel getChannel(SliceNode src, SliceNode dst)
          Back end needs to generate subclasses of channel.
 Collection<Channel> getChannels()
          Back end needs to accumulate channels to pass to the code emitter.
abstract  CodeStoreHelper getCodeStoreHelper(SliceNode node)
          Select a CodeStoreHelper subclass given a SliceNode.
abstract  CodeStoreType getComputeCodeStore(ComputeNodeType parent)
           
abstract  ComputeNodeType getComputeNode(ComputeNodeSelectorArgType specifier)
          Get a specified compute node.
abstract  ComputeNodesType getComputeNodes()
           
 Layout<ComputeNodeType> getLayout()
          Get saved copy of Layout.
abstract  void processFilterSliceNode(FilterSliceNode filter, SchedulingPhase whichPhase, ComputeNodesType computeNodes)
          Process a filter slice node: find the correct ProcElement(s) and add code and buffers.
abstract  void processFilterSlices(Slice slice, SchedulingPhase whichPhase, ComputeNodesType computeNodes)
          Process all filter slice nodes in a Slice (just one in a SimpleSlice): find the correct ProcElement(s) and add filter code.
abstract  void processInputSliceNode(InputSliceNode input, SchedulingPhase whichPhase, ComputeNodesType computeNodes)
          Process an input slice node: find the correct ProcElement(s) and add joiner code, and buffers.
abstract  void processOutputSliceNode(OutputSliceNode output, SchedulingPhase whichPhase, ComputeNodesType computeNodes)
          Process an output slice node: find the correct ProcElement(s) and add splitter code, and buffers.
 void setLayout(Layout<ComputeNodeType> layout)
          Keep a copy of the Layout: the mapping from SliceNode to ComputeNode.
 boolean sliceHasDownstreamChannel(Slice s)
           
 boolean sliceHasUpstreamChannel(Slice s)
           
 boolean sliceNeedsJoinerCode(Slice s)
          Slice needs code for a joiner if it has input from more than one source.
 boolean sliceNeedsJoinerWorkFunction(Slice s)
          Slice needs work function for a joiner.
 boolean sliceNeedsPeekBuffer(Slice s)
          Does slice need a peek buffer before first filter? Really depends on where input is coming from: filter on this ComputeNode? Joiner on this ComputeNode?, Filter on another Compute Node? If so is there shared memory? ...
 boolean sliceNeedsPokeBuffer(Slice s)
          Does slice need a buffer between its final filter and its splitter?
 boolean sliceNeedsSplitterCode(Slice s)
          Slice needs code for a splitter if it has output on more than one edge.
 boolean sliceNeedsSplitterWorkFunction(Slice s)
          Haven't yet found a situation where we need to buffer output to splitter but may well: perhaps if prework pushes different number of items from what work pushes?
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

layout

protected Layout<ComputeNodeType extends ComputeNode<?>> layout
Constructor Detail

BackEndFactory

public BackEndFactory()
Method Detail

getBackEndMain

public abstract <T extends BackEndScaffold> T getBackEndMain()
Type Parameters:
... - needs same parameterization as this so as to be able to refer to this.
Returns:
Singleton to generate Channels and ComputeCodeStores for the ComputeNodes.

processInputSliceNode

public abstract void processInputSliceNode(InputSliceNode input,
                                           SchedulingPhase whichPhase,
                                           ComputeNodesType computeNodes)
Process an input slice node: find the correct ProcElement(s) and add joiner code, and buffers. please delegate work to some other object.

Parameters:
input - the InputSliceNode
whichPhase - INIT / PRIMEPUMP / STEADY
computeNodes - the available compute nodes.

processFilterSlices

public abstract void processFilterSlices(Slice slice,
                                         SchedulingPhase whichPhase,
                                         ComputeNodesType computeNodes)
Process all filter slice nodes in a Slice (just one in a SimpleSlice): find the correct ProcElement(s) and add filter code. please delegate work to some other object.

Parameters:
slice - Slice containing filters
whichPhase - INIT / PRIMEPUMP / STEADY
computeNodes - the available compute nodes.

processFilterSliceNode

public abstract void processFilterSliceNode(FilterSliceNode filter,
                                            SchedulingPhase whichPhase,
                                            ComputeNodesType computeNodes)
Process a filter slice node: find the correct ProcElement(s) and add code and buffers. please delegate work to some other object.

Parameters:
filter - the FilterSliceNode.
whichPhase - INIT / PRIMEPUMP / STEADY
computeNodes - the available compute nodes.

processOutputSliceNode

public abstract void processOutputSliceNode(OutputSliceNode output,
                                            SchedulingPhase whichPhase,
                                            ComputeNodesType computeNodes)
Process an output slice node: find the correct ProcElement(s) and add splitter code, and buffers. please delegate work to some other object.

Parameters:
output - the OutputSliceNode.
whichPhase - INIT / PRIMEPUMP / STEADY
computeNodes - the available compute nodes.

getComputeNodes

public abstract ComputeNodesType getComputeNodes()
Returns:
Get the (unique) collection of nodes involved in computation.

getComputeCodeStore

public abstract CodeStoreType getComputeCodeStore(ComputeNodeType parent)
Returns:
A (unique per parent) ComputeCodeStore.

getComputeNode

public abstract ComputeNodeType getComputeNode(ComputeNodeSelectorArgType specifier)
Get a specified compute node. Assumes that BackEndFactory.getComputeNodes() returns a collection of ComputeNode including the desired node.

Parameters:
specifier - Different instantiations will have different number of arguments to specify which node, so a specifier (String, int, array[int]...) here.
Returns:
a (unique per specifier) ComputeNode

setLayout

public void setLayout(Layout<ComputeNodeType> layout)
Keep a copy of the Layout: the mapping from SliceNode to ComputeNode.

Parameters:
layout -

getLayout

public Layout<ComputeNodeType> getLayout()
Get saved copy of Layout.

Returns:

getChannels

public Collection<Channel> getChannels()
Back end needs to accumulate channels to pass to the code emitter. This function should return that collection of channels.

Returns:
some collection of Channel s for the code emitter's use.

getChannel

public abstract Channel getChannel(Edge e)
Back end needs to generate subclasses of channel. Routine here to get a channel that implements communication over an edge.

Parameters:
e - the edge.
Returns:
a channel: preexisting or newly created.

getChannel

public abstract Channel getChannel(SliceNode src,
                                   SliceNode dst)
Back end needs to generate subclasses of channel. Routine here to get a channel from a source to a destination.

Parameters:
src -
dst -
Returns:
a channel: preexisting or newly created.

getCodeStoreHelper

public abstract CodeStoreHelper getCodeStoreHelper(SliceNode node)
Select a CodeStoreHelper subclass given a SliceNode. A CodeStoreHelper generates wrapper code combining code for channels with code for a SliceNode.

Parameters:
node - the SliceNode.
Returns:
an instance of CodeStoreHelper

sliceNeedsPokeBuffer

public boolean sliceNeedsPokeBuffer(Slice s)
Does slice need a buffer between its final filter and its splitter?


sliceNeedsPeekBuffer

public boolean sliceNeedsPeekBuffer(Slice s)
Does slice need a peek buffer before first filter? Really depends on where input is coming from: filter on this ComputeNode? Joiner on this ComputeNode?, Filter on another Compute Node? If so is there shared memory? ... Answer is false unless bufferring is needed to deal with unconsumed inputs or extra peeks.

Parameters:
s - a Slice
Returns:
whether first filter needs a peek buffer.

sliceHasUpstreamChannel

public boolean sliceHasUpstreamChannel(Slice s)
Returns:
true if slice has an upstream channel that it needs to receive data from, false otherwise. May want to set false if upstream channel is to off-chip device and code for a filter controls that device, but this implementation seems a good default.

sliceHasDownstreamChannel

public boolean sliceHasDownstreamChannel(Slice s)
Returns:
true if slice has a downstream channel that it needs to send data to, false otherwise May want to set false if downstream channel is to off-chip device and code for a filter controls that device, but this implementation seems a good default.

sliceNeedsJoinerCode

public boolean sliceNeedsJoinerCode(Slice s)
Slice needs code for a joiner if it has input from more than one source.

Parameters:
s - Slice
Returns:

sliceNeedsJoinerWorkFunction

public boolean sliceNeedsJoinerWorkFunction(Slice s)
Slice needs work function for a joiner. We distinguish this from sliceNeedsJoinerCode(Slice) since there may need to be code generated for a joiner, but the work function may be rolled into the code for a filter.

Parameters:
s - Slice
Returns:

sliceNeedsSplitterCode

public boolean sliceNeedsSplitterCode(Slice s)
Slice needs code for a splitter if it has output on more than one edge.

Parameters:
s -
Returns:

sliceNeedsSplitterWorkFunction

public boolean sliceNeedsSplitterWorkFunction(Slice s)
Haven't yet found a situation where we need to buffer output to splitter but may well: perhaps if prework pushes different number of items from what work pushes?

Parameters:
s -
Returns: