@Override public final void binarySpmv( final CartesianProductVector cartesianProductVector, final ChartCell chartCell) { final Future<?>[] futures = new Future[grammarThreads]; final PackedArrayChart.TemporaryChartCell[] temporaryCells = threadLocalTemporaryCellArrays.get(); // Iterate over binary grammar segments for (int i = 0; i < grammarThreads; i++) { final int segmentStart = binaryRowSegments[i]; final int segmentEnd = binaryRowSegments[i + 1]; final PackedArrayChart.TemporaryChartCell tmpCell = temporaryCells[i]; if (cellSelector.hasCellConstraints() && cellSelector.isCellOnlyFactored(chartCell.start(), chartCell.end())) { futures[i] = threadPool.submit( new Runnable() { @Override public void run() { tmpCell.clear(); // Multiply by the factored grammar rule matrix binarySpmvMultiply( cartesianProductVector, grammar.factoredCscBinaryPopulatedColumns, grammar.factoredCscBinaryPopulatedColumnOffsets, grammar.factoredCscBinaryRowIndices, grammar.factoredCscBinaryProbabilities, tmpCell.packedChildren, tmpCell.insideProbabilities, tmpCell.midpoints, segmentStart, segmentEnd); } }); } else { futures[i] = threadPool.submit( new Runnable() { @Override public void run() { tmpCell.clear(); // Multiply by the full grammar rule matrix binarySpmvMultiply( cartesianProductVector, grammar.cscBinaryPopulatedColumns, grammar.cscBinaryPopulatedColumnOffsets, grammar.cscBinaryRowIndices, grammar.cscBinaryProbabilities, tmpCell.packedChildren, tmpCell.insideProbabilities, tmpCell.midpoints, segmentStart, segmentEnd); } }); } } final PackedArrayChartCell packedArrayCell = (PackedArrayChartCell) chartCell; packedArrayCell.allocateTemporaryStorage(); try { // Wait for the first task to finish and use its arrays as the temporary cell storage futures[0].get(); final TemporaryChartCell tmpCell = packedArrayCell.tmpCell; // TODO Eliminate this extra arraycopy final int arrayLength = temporaryCells[0].insideProbabilities.length; System.arraycopy( temporaryCells[0].insideProbabilities, 0, tmpCell.insideProbabilities, 0, arrayLength); System.arraycopy(temporaryCells[0].packedChildren, 0, tmpCell.packedChildren, 0, arrayLength); System.arraycopy(temporaryCells[0].midpoints, 0, tmpCell.midpoints, 0, arrayLength); // Wait for each other task to complete and merge results into the main temporary storage for (int i = 1; i < grammarThreads; i++) { futures[i].get(); final PackedArrayChart.TemporaryChartCell threadTmpCell = temporaryCells[i]; for (int j = 0; j < arrayLength; j++) { if (threadTmpCell.insideProbabilities[j] > tmpCell.insideProbabilities[j]) { tmpCell.insideProbabilities[j] = threadTmpCell.insideProbabilities[j]; tmpCell.packedChildren[j] = threadTmpCell.packedChildren[j]; tmpCell.midpoints[j] = threadTmpCell.midpoints[j]; } } } } catch (final InterruptedException e) { e.printStackTrace(); } catch (final ExecutionException e) { e.printStackTrace(); } }