code: protected final void multiply() {
  		final int step = blockStripeSize, blockSize = blockStripeSize * blockStripeSize;
  
  		for (int m = fromM; m < toM; m += step) {
  			final int aRows = matrixA.layout.getRowsInBlock(m);
  
  			for (int k = fromK; k < toK; k += step) {
  				final int bCols = matrixB.layout.getColumnsInBlock(k);
  
  				final double[] cBlock = new double[aRows * bCols];
  
  				for (int n = fromN; n < toN; n += step) {
  
  					// ensure a and b are in optimal block order before
  					// multiplication
  					final double[] aBlock = matrixA.layout.toRowMajorBlock(matrixA, m, n);
  					final double[] bBlock = matrixB.layout.toColMajorBlock(matrixB, n, k);
  
  					if (aBlock != null && bBlock != null) {
  						if (aBlock.length == blockSize && bBlock.length == blockSize) {
  							multiplyAxB(aBlock, bBlock, cBlock, step);
  						} else {
  							int aCols = aBlock.length / aRows;
  							int bRows = bBlock.length / bCols;
  							verifyTrue(aCols == bRows, "aCols!=bRows");
  							multiplyRowMajorTimesColumnMajorBlocks(aBlock, bBlock, cBlock, aRows,
  									aCols, bCols);
  						}
  					}
  				}
  
  				matrixC.addBlockData(m, k, cBlock);
  			}
  		}
  	}
docs: Multiply blocks of two matrices A,B and add to C.
  <p>
  Blocks of Matrix B are transformed to column-major layout (if not
  already) to facilitate multiplication.<br>
  (If matrices have been created optimally, B should already be
  column-major)