List of usage examples for java.nio DoubleBuffer position
public final Buffer position(int newPosition)
From source file:org.mitre.math.linear.BufferRealMatrix.java
/** * Returns the result of postmultiplying this by m. * * @param m matrix to postmultiply by * @return this * m// w w w .j av a 2s . c o m * @throws IllegalArgumentException * if columnDimension(this) != rowDimension(m) */ public BufferRealMatrix multiply(final BufferRealMatrix b) throws IllegalArgumentException { // safety check MatrixUtils.checkMultiplicationCompatible(this, b); try { final BufferRealMatrix c = new BufferRealMatrix(rows, b.columns, null); // allocate one row for our matrix final ByteBuffer abb = ByteBuffer.allocate(BLOCK_SIZE * DOUBLE_BYTE_SIZE); // for some funny reason we can't get an array, even if we wrap it before! So, allocate it here and use latter // final double[] ar = new double[BLOCK_SIZE]; This isn't faster // perform multiplication block-wise, to ensure good cache behavior int blockIndex = 0; for (int iBlock = 0; iBlock < c.blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = Math.min(pStart + BLOCK_SIZE, rows); //System.err.printf("pStart=%d\tpEnd=%d\tblockRows=%d\tblockColumns=%d\n", pStart, pEnd, c.blockRows, c.blockColumns); for (int jBlock = 0; jBlock < c.blockColumns; ++jBlock) { final int jWidth = BLOCK_SIZE; // square block no matter what final int jWidth2 = jWidth + jWidth; final int jWidth3 = jWidth2 + jWidth; final int jWidth4 = jWidth3 + jWidth; // select current product block DoubleBuffer cdb = c.dataFileChannel .map(FileChannel.MapMode.READ_WRITE, c.getBlockOffset(blockIndex), BLOCK_BYTE_SIZE) .asDoubleBuffer(); cdb.clear(); // perform multiplication on current block for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { //final int kWidth = blockWidth(kBlock); final int kWidth = BLOCK_SIZE; LOG.debug(String.format("Getting a block %d and b block %d", iBlock * blockColumns + kBlock, kBlock * b.blockColumns + jBlock)); // walk down the blocks columns DoubleBuffer bdb = b.dataFileChannel .map(FileChannel.MapMode.READ_WRITE, b.getBlockOffset(kBlock * b.blockColumns + jBlock), BLOCK_BYTE_SIZE) .asDoubleBuffer(); bdb.clear(); LOG.debug("Processing blocks"); for (int p = pStart, k = 0; p < pEnd; ++p) { // a's width (# cols) is the same as b's height (# rows) and c's width final int lStart = (p - pStart) * kWidth; // Square padded with zeros final int lEnd = blockWidth(kBlock); // Can stop at the last column in a's block //System.err.printf("k=%d\tp=%d\tlstart=%d\tlend=%d\t\n", k, p, lStart, lEnd); // For each row in a, multiple the columns in b // Can stop at the last column in the c's block which should be the last column in b // walk across A's blocks rows grabbing a row at a time abb.clear(); this.dataFileChannel.position(this.getBlockOffset(iBlock * blockColumns + kBlock) + (lStart * DOUBLE_BYTE_SIZE)); final int r = this.dataFileChannel.read(abb); // relative get into local bytebuffer //System.err.printf("Got %d bytes (%d doubles) for %d block width\n", r, r / DOUBLE_BYTE_SIZE, kWidth); if (r == -1) { LOG.fatal("Unable to read in data"); } abb.clear(); final DoubleBuffer adb = abb.asDoubleBuffer(); adb.clear(); // tried getting access to local copy (array) but it wasn't faster access for (int nStart = 0; nStart < c.blockWidth(jBlock); ++nStart) { double sum = 0; int l = 0; // first column in this row int n = nStart; // do four at a time (why four?) adb.position(l); while (l < lEnd - 3) { sum += adb.get() * bdb.get(n) + adb.get() * bdb.get(n + jWidth) + adb.get() * bdb.get(n + jWidth2) + adb.get() * bdb.get(n + jWidth3); l += 4; n += jWidth4; } while (l < lEnd) { sum += adb.get() * bdb.get(n); n += jWidth; l++; } sum += cdb.get(k); cdb.put(k++, sum); //System.err.printf("k=%d\tn=%d\n", k, n); } // correct k for difference in blockWidth since we are always square k = (p + 1) * BLOCK_SIZE; //System.err.printf("end of p-loop (%d), k=%d\n", p, k); } } this.dataFileChannel.force(false); System.err.printf("Finished block %d\n", blockIndex); // go to next block ++blockIndex; } } return c; } catch (IOException ex) { throw new IllegalArgumentException(ex.getMessage()); } }