return;
// Put the data in a format appropriate for passing to the GPU.
// Most of this function is devoted to this task.
int i = 0, j = 0, k = 0, numEnsemblesCollectingSpikes = 0;
NEFEnsemble workingNode;
Termination[] terminations;
DecodedOrigin[] origins;
float[][][][] terminationTransforms = new float[myGPUEnsembles.length][][][];
int[][] isDecodedTermination = new int[myGPUEnsembles.length][];
float[][] terminationTau = new float[myGPUEnsembles.length][];
float[][][] encoders = new float[myGPUEnsembles.length][][];
float[][][][] decoders = new float[myGPUEnsembles.length][][][];
float[][] neuronData = new float[myGPUEnsembles.length][];
EnsembleData ensembleData = new EnsembleData();
int[][] ensembleDataArray = new int[myGPUEnsembles.length][];
int[] collectSpikes = new int[myGPUEnsembles.length];
int[][] outputRequiredOnCPU = new int[myGPUNetworkArrays.length][];
int[] isSpikingEnsemble = new int[myGPUEnsembles.length];
float maxTimeStep = ((LIFSpikeGenerator) ((SpikingNeuron) ((NEFEnsembleImpl) myGPUEnsembles[0])
.getNodes()[0]).getGenerator()).getMaxTimeStep();
// We put the list of projections in terms of the GPU nodes
// For each projection we record 4 numbers: the index of the origin
// ensemble, the index of the origin in its ensemble, the index of
// the termination ensemble and the index of the termination in its ensemble
int[][] adjustedProjections = new int[myGPUProjections.length][6];
inputOnGPU = new boolean[myGPUNetworkArrays.length][];
Node workingArray;
int networkArrayOffset = 0;
NetworkArrayData networkArrayData = new NetworkArrayData();
int[][] networkArrayDataArray = new int[myGPUNetworkArrays.length][];
int totalInputSize = 0;
// store networkArray data
for(i = 0; i < myGPUNetworkArrays.length; i++){
networkArrayData.reset();
workingArray = myGPUNetworkArrays[i];
networkArrayData.indexOfFirstNode = networkArrayOffset;
if(workingArray instanceof NEFEnsembleImpl){
networkArrayOffset++;
}else{
networkArrayOffset += ((NetworkImpl) workingArray).getNodes().length;
}
networkArrayData.endIndex = networkArrayOffset;
Termination[] networkArrayTerminations = workingArray.getTerminations();
networkArrayData.numTerminations = networkArrayTerminations.length;
for(j = 0; j < networkArrayTerminations.length; j++){
networkArrayData.totalInputSize += networkArrayTerminations[j].getDimensions();
}
totalInputSize += networkArrayData.totalInputSize;
Origin[] networkArrayOrigins;
if(workingArray instanceof NEFEnsembleImpl)
{
networkArrayOrigins = ((NEFEnsembleImpl) workingArray).getDecodedOrigins();
}else{
networkArrayOrigins = workingArray.getOrigins();
}
networkArrayData.numOrigins = networkArrayOrigins.length;
for(j = 0; j < networkArrayOrigins.length; j++){
networkArrayData.totalOutputSize += networkArrayOrigins[j].getDimensions();
}
if(workingArray instanceof NEFEnsembleImpl){
networkArrayData.numNeurons = ((NEFEnsembleImpl) workingArray).getNeurons();
}else{
Node[] subNodes = ((NetworkImpl) workingArray).getNodes();
for(j = 0; j < subNodes.length; j++){
networkArrayData.numNeurons += ((NEFEnsembleImpl) subNodes[j]).getNeurons();
}
}
networkArrayDataArray[i] = networkArrayData.getAsArray();
inputOnGPU[i] = new boolean[networkArrayTerminations.length];
outputRequiredOnCPU[i] = new int[networkArrayOrigins.length];
for(j = 0; j < networkArrayTerminations.length; j++){
Termination termination = networkArrayTerminations[j];
boolean terminationWrapped = termination instanceof TerminationWrapper;
if(terminationWrapped)
termination = ((TerminationWrapper) termination).getBaseTermination();
k = 0;
boolean projectionMatches = false;
while(!projectionMatches && k < myGPUProjections.length){
Termination projectionTermination = myGPUProjections[k].getTermination();
boolean projectionTerminationWrapped = projectionTermination instanceof TerminationWrapper;
if(projectionTerminationWrapped)
projectionTermination = ((TerminationWrapper) projectionTermination).getBaseTermination();
projectionMatches = termination == projectionTermination;
if(projectionMatches)
break;
k++;
}
if (projectionMatches) {
adjustedProjections[k][2] = i;
adjustedProjections[k][3] = j;
adjustedProjections[k][4] = termination.getDimensions();
adjustedProjections[k][5] = -1;
inputOnGPU[i][j] = true;
} else {
inputOnGPU[i][j] = false;
}
}
for (j = 0; j < networkArrayOrigins.length; j++) {
Origin origin = networkArrayOrigins[j];
boolean originWrapped = origin instanceof OriginWrapper;
if(originWrapped)
origin = ((OriginWrapper) origin).getWrappedOrigin();
for (k = 0; k < myGPUProjections.length; k++) {
Origin projectionOrigin = myGPUProjections[k].getOrigin();
boolean projectionOriginWrapped = projectionOrigin instanceof OriginWrapper;
if(projectionOriginWrapped)
projectionOrigin = ((OriginWrapper) projectionOrigin).getWrappedOrigin();
if (origin == projectionOrigin) {
adjustedProjections[k][0] = i;
adjustedProjections[k][1] = j;
}
}
outputRequiredOnCPU[i][j] = (origin.getRequiredOnCPU() || requireAllOutputsOnCPU) ? 1 : 0;
// even if its not explicitly required on the CPU, it might be implicitly
// if it is attached to a projection whose termination is on the CPU
if(outputRequiredOnCPU[i][j] == 0){
for (k = 0; k < nonGPUProjections.length; k++) {
Origin projectionOrigin = nonGPUProjections[k].getOrigin();
boolean projectionOriginWrapped = projectionOrigin instanceof OriginWrapper;
if(projectionOriginWrapped)
projectionOrigin = ((OriginWrapper) projectionOrigin).getWrappedOrigin();
if (origin == projectionOrigin){
outputRequiredOnCPU[i][j] = 1;
}
}
}
}
}
nonGPUProjections = null;
// store NEFEnsemble data
for (i = 0; i < myGPUEnsembles.length; i++) {
workingNode = myGPUEnsembles[i];
ensembleData.reset();
ensembleData.dimension = workingNode.getDimension();
ensembleData.numNeurons = workingNode.getNodeCount();
isSpikingEnsemble[i] = (workingNode.getMode() == SimulationMode.DEFAULT) ? 1 : 0;
terminations = workingNode.getTerminations();
int terminationDim = 0;
ensembleData.maxTransformDimension = 0;
terminationTransforms[i] = new float[terminations.length][][];
terminationTau[i] = new float[terminations.length];
isDecodedTermination[i] = new int[terminations.length];
for (j = 0; j < terminations.length; j++) {
if (terminations[j] instanceof DecodedTermination) {
terminationTransforms[i][j] = ((DecodedTermination) terminations[j])
.getTransform();
terminationTau[i][j] = terminations[j].getTau();
terminationDim = terminations[j].getDimensions();
ensembleData.totalInputSize += terminationDim;
if (terminationDim > ensembleData.maxTransformDimension) {
ensembleData.maxTransformDimension = terminationDim;
}
isDecodedTermination[i][j] = 1;
ensembleData.numDecodedTerminations++;
} else if (terminations[j] instanceof EnsembleTermination) {
terminationTransforms[i][j] = new float[1][1];
// when we do learning, this will have to be changed, as well as some code in the NengoGPU library.
// currently it assumes all neurons in the ensemble have the same weight for each non-decoded termination
// (mainly just to support gates which have uniform negative weights).
// When we do learning, will have to extract the whole weight matrix.
Termination[] neuronTerminations = ((EnsembleTermination) terminations[j]).getNodeTerminations();
terminationTransforms[i][j][0] = ((PlasticNodeTermination) neuronTerminations[0]).getWeights();
terminationTau[i][j] = terminations[j].getTau();
isDecodedTermination[i][j] = 0;
terminationDim = terminations[j].getDimensions();
ensembleData.totalInputSize += terminationDim;
ensembleData.nonDecodedTransformSize += terminationDim;
ensembleData.numNonDecodedTerminations++;
}
}
encoders[i] = workingNode.getEncoders();
float[] radii = workingNode.getRadii();
for (j = 0; j < encoders[i].length; j++) {
for (k = 0; k < encoders[i][j].length; k++)
encoders[i][j][k] = encoders[i][j][k] / radii[k];
}
origins = ((NEFEnsembleImpl) workingNode).getDecodedOrigins();
ensembleData.numOrigins = origins.length;
ensembleData.maxDecoderDimension = 0;
decoders[i] = new float[origins.length][][];
int originDim;
for (j = 0; j < origins.length; j++) {
decoders[i][j] = origins[j].getDecoders();
originDim = origins[j].getDimensions();
ensembleData.totalOutputSize += originDim;
if (originDim > ensembleData.maxDecoderDimension) {
ensembleData.maxDecoderDimension = originDim;
}
}
neuronData[i] = ((NEFEnsembleImpl) workingNode).getStaticNeuronData();
//collectSpikes[i] = (workingNode.isCollectingSpikes() || requireAllOutputsOnCPU) ? 1 : 0;
collectSpikes[i] = workingNode.isCollectingSpikes() ? 1 : 0;
numEnsemblesCollectingSpikes++;
ensembleDataArray[i] = ensembleData.getAsArray();
}