private void computeTransitionMatrices( Beagle beagle, int[][] probabilityIndices, double[][] edgeLengths, int[] counts) { Timer timer; if (MEASURE_RUN_TIME) { timer = new Timer(); timer.start(); } if (DEBUG) { System.out.print("Computing matrices:"); } for (int i = 0; i < eigenCount; i++) { if (DEBUG) { for (int j = 0; j < counts[i]; j++) { // System.out.print(" " + probabilityIndices[i][j]); System.out.print(" " + probabilityIndices[i][j] + " (" + edgeLengths[i][j] + ")"); } } if (counts[i] > 0) { beagle.updateTransitionMatrices( eigenBufferHelper.getOffsetIndex(i), probabilityIndices[i], null, // firstDerivativeIndices null, // secondDerivativeIndices edgeLengths[i], counts[i]); } } if (DEBUG) { System.out.println(); } if (MEASURE_RUN_TIME) { timer.stop(); double timeInSeconds = timer.toSeconds(); updateTime += timeInSeconds; } } // END: computeTransitionMatrices
private void convolveMatrices(Beagle beagle, List<Deque<Integer>> convolutionList) { Timer timer; if (MEASURE_RUN_TIME) { timer = new Timer(); timer.start(); } while (convolutionList.size() > 0) { int[] firstConvolutionBuffers = new int[nodeCount]; int[] secondConvolutionBuffers = new int[nodeCount]; int[] resultConvolutionBuffers = new int[nodeCount]; int operationsCount = 0; List<Deque<Integer>> empty = new ArrayList<Deque<Integer>>(); for (Deque<Integer> convolve : convolutionList) { if (convolve.size() > 3) { firstConvolutionBuffers[operationsCount] = convolve.pop(); secondConvolutionBuffers[operationsCount] = convolve.pop(); int buffer; boolean done; do { done = true; buffer = popAvailableBuffer(); if (buffer < 0) { // no buffers available // throw new RuntimeException("All out of buffers"); // we have run out of buffers, process what we have and continue... if (DEBUG) { System.out.println("Ran out of buffers for convolving - computing current list."); System.out.print("Convolving " + operationsCount + " matrices:"); for (int i = 0; i < operationsCount; i++) { System.out.print( " " + firstConvolutionBuffers[i] + "*" + secondConvolutionBuffers[i] + "->" + resultConvolutionBuffers[i]); } System.out.println(); } if (operationsCount > 0) { convolveAndRelease( beagle, firstConvolutionBuffers, secondConvolutionBuffers, resultConvolutionBuffers, operationsCount); // copy the uncompleted operation back down to the beginning of the operations list firstConvolutionBuffers[0] = firstConvolutionBuffers[operationsCount]; secondConvolutionBuffers[0] = secondConvolutionBuffers[operationsCount]; // reset the operation count operationsCount = 0; done = false; // there should be enough spare buffers to get a resultConvolutionBuffer for this // operation now } else { // only one partially setup operation so there would be none to free up // in this case we will use the reserve buffer resultConvolutionBuffers[operationsCount] = getReserveBuffer(); convolveAndRelease( beagle, firstConvolutionBuffers, secondConvolutionBuffers, resultConvolutionBuffers, 1); convolve.push(getReserveBuffer()); done = true; // break out of the do loop } } } while (!done); if (buffer >= 0) { // if the buffer is still negative then the loop above will have used the reserve buffer // to complete the convolution. resultConvolutionBuffers[operationsCount] = buffer; convolve.push(buffer); operationsCount++; } } else if (convolve.size() == 3) { firstConvolutionBuffers[operationsCount] = convolve.pop(); secondConvolutionBuffers[operationsCount] = convolve.pop(); resultConvolutionBuffers[operationsCount] = convolve.pop(); operationsCount++; } else { throw new RuntimeException("Unexpected convolve list size"); } if (convolve.size() == 0) { empty.add(convolve); } } if (DEBUG) { System.out.print("Convolving " + operationsCount + " matrices:"); for (int i = 0; i < operationsCount; i++) { System.out.print( " " + firstConvolutionBuffers[i] + "*" + secondConvolutionBuffers[i] + "->" + resultConvolutionBuffers[i]); } System.out.println(); } convolveAndRelease( beagle, firstConvolutionBuffers, secondConvolutionBuffers, resultConvolutionBuffers, operationsCount); convolutionList.removeAll(empty); } if (MEASURE_RUN_TIME) { timer.stop(); double timeInSeconds = timer.toSeconds(); convolveTime += timeInSeconds; } } // END: convolveTransitionMatrices