Return-Path: Delivered-To: apmail-incubator-hama-commits-archive@locus.apache.org Received: (qmail 52264 invoked from network); 26 Nov 2008 02:58:18 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 26 Nov 2008 02:58:18 -0000 Received: (qmail 66738 invoked by uid 500); 26 Nov 2008 02:58:29 -0000 Delivered-To: apmail-incubator-hama-commits-archive@incubator.apache.org Received: (qmail 66720 invoked by uid 500); 26 Nov 2008 02:58:29 -0000 Mailing-List: contact hama-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: hama-dev@ Delivered-To: mailing list hama-commits@incubator.apache.org Received: (qmail 66709 invoked by uid 99); 26 Nov 2008 02:58:29 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 25 Nov 2008 18:58:29 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Nov 2008 02:57:00 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 9E40F23888A6; Tue, 25 Nov 2008 18:57:16 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r720716 - in /incubator/hama/trunk: ./ src/examples/org/apache/hama/examples/ src/java/org/apache/hama/ src/java/org/apache/hama/io/ src/java/org/apache/hama/util/ src/test/org/apache/hama/ src/test/org/apache/hama/io/ src/test/org/apache/h... Date: Wed, 26 Nov 2008 02:57:16 -0000 To: hama-commits@incubator.apache.org From: edwardyoon@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20081126025716.9E40F23888A6@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: edwardyoon Date: Tue Nov 25 18:57:15 2008 New Revision: 720716 URL: http://svn.apache.org/viewvc?rev=720716&view=rev Log: Blocking job should be a map/reduce job Modified: incubator/hama/trunk/CHANGES.txt incubator/hama/trunk/src/examples/org/apache/hama/examples/MatrixMultiplication.java incubator/hama/trunk/src/java/org/apache/hama/DenseMatrix.java incubator/hama/trunk/src/java/org/apache/hama/io/BlockID.java incubator/hama/trunk/src/java/org/apache/hama/util/JobManager.java incubator/hama/trunk/src/test/org/apache/hama/TestDenseMatrix.java incubator/hama/trunk/src/test/org/apache/hama/io/TestBlockID.java incubator/hama/trunk/src/test/org/apache/hama/mapred/TestBlockMatrixMapReduce.java Modified: incubator/hama/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/incubator/hama/trunk/CHANGES.txt?rev=720716&r1=720715&r2=720716&view=diff ============================================================================== --- incubator/hama/trunk/CHANGES.txt (original) +++ incubator/hama/trunk/CHANGES.txt Tue Nov 25 18:57:15 2008 @@ -33,6 +33,7 @@ IMPROVEMENTS + HAMA-107: Blocking job should be a map/reduce job (samuel via edwardyoon) HAMA-99: Implement setColumn(int column, Vector vector) (edwardyoon) HAMA-108: Implement add(int i, int j, double value) (edwardyoon) HAMA-103: Reduce an rows of intermediate Modified: incubator/hama/trunk/src/examples/org/apache/hama/examples/MatrixMultiplication.java URL: http://svn.apache.org/viewvc/incubator/hama/trunk/src/examples/org/apache/hama/examples/MatrixMultiplication.java?rev=720716&r1=720715&r2=720716&view=diff ============================================================================== --- incubator/hama/trunk/src/examples/org/apache/hama/examples/MatrixMultiplication.java (original) +++ incubator/hama/trunk/src/examples/org/apache/hama/examples/MatrixMultiplication.java Tue Nov 25 18:57:15 2008 @@ -44,9 +44,9 @@ DenseMatrix b = DenseMatrix.random(conf, row, column); if (!a.isBlocked()) - a.blocking(conf.getNumMapTasks()); + a.blocking_mapred(conf.getNumMapTasks()); if (!b.isBlocked()) - b.blocking(conf.getNumMapTasks()); + b.blocking_mapred(conf.getNumMapTasks()); Matrix c = a.mult(b); Modified: incubator/hama/trunk/src/java/org/apache/hama/DenseMatrix.java URL: http://svn.apache.org/viewvc/incubator/hama/trunk/src/java/org/apache/hama/DenseMatrix.java?rev=720716&r1=720715&r2=720716&view=diff ============================================================================== --- incubator/hama/trunk/src/java/org/apache/hama/DenseMatrix.java (original) +++ incubator/hama/trunk/src/java/org/apache/hama/DenseMatrix.java Tue Nov 25 18:57:15 2008 @@ -1,495 +1,481 @@ -/** - * Copyright 2007 The Apache Software Foundation - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hama; - -import java.io.IOException; - -import org.apache.hadoop.hbase.HConstants; -import org.apache.hadoop.hbase.HTableDescriptor; -import org.apache.hadoop.hbase.client.HTable; -import org.apache.hadoop.hbase.client.Scanner; -import org.apache.hadoop.hbase.io.BatchUpdate; -import org.apache.hadoop.hbase.io.Cell; -import org.apache.hadoop.hbase.io.RowResult; -import org.apache.hadoop.hbase.util.Bytes; -import org.apache.hadoop.io.IntWritable; -import org.apache.hadoop.mapred.JobConf; -import org.apache.hama.algebra.BlockCyclicMultiplyMap; -import org.apache.hama.algebra.BlockCyclicMultiplyReduce; -import org.apache.hama.algebra.RowCyclicAdditionMap; -import org.apache.hama.algebra.RowCyclicAdditionReduce; -import org.apache.hama.algebra.SIMDMultiplyMap; -import org.apache.hama.algebra.SIMDMultiplyReduce; -import org.apache.hama.io.BlockWritable; -import org.apache.hama.io.DoubleEntry; -import org.apache.hama.io.MapWritable; -import org.apache.hama.io.VectorUpdate; -import org.apache.hama.io.VectorWritable; -import org.apache.hama.mapred.BlockCyclicReduce; -import org.apache.hama.mapred.RowCyclicReduce; -import org.apache.hama.util.BytesUtil; -import org.apache.hama.util.JobManager; -import org.apache.hama.util.RandomVariable; - -public class DenseMatrix extends AbstractMatrix implements Matrix { - - static int tryPathLength = Constants.DEFAULT_PATH_LENGTH; - static final String TABLE_PREFIX = DenseMatrix.class.getSimpleName() + "_"; - - /** - * Construct a raw matrix. Just create a table in HBase, but didn't lay any - * schema ( such as dimensions: i, j ) on it. - * - * @param conf configuration object - * @throws IOException throw the exception to let the user know what happend, - * if we didn't create the matrix successfully. - */ - public DenseMatrix(HamaConfiguration conf) throws IOException { - setConfiguration(conf); - - tryToCreateTable(); - - closed = false; - } - - /** - * Create/load a matrix aliased as 'matrixName'. - * - * @param conf configuration object - * @param matrixName the name of the matrix - * @param force if force is true, a new matrix will be created no matter - * 'matrixName' has aliased to an existed matrix; otherwise, - * just try to load an existed matrix alised 'matrixName'. - * @throws IOException - */ - public DenseMatrix(HamaConfiguration conf, String matrixName, boolean force) - throws IOException { - setConfiguration(conf); - // if force is set to true: - // 1) if this matrixName has aliase to other matrix, we will remove - // the old aliase, create a new matrix table, and aliase to it. - // 2) if this matrixName has no aliase to other matrix, we will create - // a new matrix table, and alise to it. - // - // if force is set to false, we just try to load an existed matrix alised - // as 'matrixname'. - - boolean existed = hamaAdmin.matrixExists(matrixName); - - if (force) { - if (existed) { - // remove the old aliase - hamaAdmin.delete(matrixName); - } - // create a new matrix table. - tryToCreateTable(); - // save the new aliase relationship - save(matrixName); - } else { - if (existed) { - // try to get the actual path of the table - matrixPath = hamaAdmin.getPath(matrixName); - // load the matrix - table = new HTable(conf, matrixPath); - // increment the reference - incrementAndGetRef(); - } else { - throw new IOException("Try to load non-existed matrix alised as " - + matrixName); - } - } - - closed = false; - } - - /** - * Load a matrix from an existed matrix table whose tablename is 'matrixpath' !! - * It is an internal used for map/reduce. - * - * @param conf configuration object - * @param matrixpath - * @throws IOException - * @throws IOException - */ - public DenseMatrix(HamaConfiguration conf, String matrixpath) - throws IOException { - setConfiguration(conf); - matrixPath = matrixpath; - // load the matrix - table = new HTable(conf, matrixPath); - // TODO: now we don't increment the reference of the table - // for it's an internal use for map/reduce. - // if we want to increment the reference of the table, - // we don't know where to call Matrix.close in Add & Mul map/reduce - // process to decrement the reference. It seems difficulty. - } - - /** - * Create an m-by-n constant matrix. - * - * @param conf configuration object - * @param m the number of rows. - * @param n the number of columns. - * @param s fill the matrix with this scalar value. - * @throws IOException throw the exception to let the user know what happend, - * if we didn't create the matrix successfully. - */ - public DenseMatrix(HamaConfiguration conf, int m, int n, double s) - throws IOException { - setConfiguration(conf); - - tryToCreateTable(); - - closed = false; - - for (int i = 0; i < m; i++) { - for (int j = 0; j < n; j++) { - set(i, j, s); - } - } - - setDimension(m, n); - } - - /** - * try to create a new matrix with a new random name. try times will be - * (Integer.MAX_VALUE - 4) * DEFAULT_TRY_TIMES; - * - * @throws IOException - */ - private void tryToCreateTable() throws IOException { - int tryTimes = Constants.DEFAULT_TRY_TIMES; - do { - matrixPath = TABLE_PREFIX + RandomVariable.randMatrixPath(tryPathLength); - - if (!admin.tableExists(matrixPath)) { // no table 'matrixPath' in hbase. - tableDesc = new HTableDescriptor(matrixPath); - create(); - return; - } - - tryTimes--; - if (tryTimes <= 0) { // this loop has exhausted DEFAULT_TRY_TIMES. - tryPathLength++; - tryTimes = Constants.DEFAULT_TRY_TIMES; - } - - } while (tryPathLength <= Constants.DEFAULT_MAXPATHLEN); - // exhaustes the try times. - // throw out an IOException to let the user know what happened. - throw new IOException("Try too many times to create a table in hbase."); - } - - /** - * Generate matrix with random elements - * - * @param conf configuration object - * @param m the number of rows. - * @param n the number of columns. - * @return an m-by-n matrix with uniformly distributed random elements. - * @throws IOException - */ - public static DenseMatrix random(HamaConfiguration conf, int m, int n) - throws IOException { - DenseMatrix rand = new DenseMatrix(conf); - DenseVector vector = new DenseVector(); - LOG.info("Create the " + m + " * " + n + " random matrix : " - + rand.getPath()); - - for (int i = 0; i < m; i++) { - vector.clear(); - for (int j = 0; j < n; j++) { - vector.set(j, RandomVariable.rand()); - } - rand.setRow(i, vector); - } - - rand.setDimension(m, n); - return rand; - } - - /** - * Generate identity matrix - * - * @param conf configuration object - * @param m the number of rows. - * @param n the number of columns. - * @return an m-by-n matrix with ones on the diagonal and zeros elsewhere. - * @throws IOException - */ - public static Matrix identity(HamaConfiguration conf, int m, int n) - throws IOException { - Matrix identity = new DenseMatrix(conf); - LOG.info("Create the " + m + " * " + n + " identity matrix : " - + identity.getPath()); - - for (int i = 0; i < m; i++) { - DenseVector vector = new DenseVector(); - for (int j = 0; j < n; j++) { - vector.set(j, (i == j ? 1.0 : 0.0)); - } - identity.setRow(i, vector); - } - - identity.setDimension(m, n); - return identity; - } - - /** - * Gets the double value of (i, j) - * - * @param i ith row of the matrix - * @param j jth column of the matrix - * @return the value of entry, or zero If entry is null - * @throws IOException - */ - public double get(int i, int j) throws IOException { - Cell c = table.get(BytesUtil.intToBytes(i), BytesUtil.getColumnIndex(j)); - return (c != null) ? BytesUtil.bytesToDouble(c.getValue()) : 0; - } - - public Matrix add(Matrix B) throws IOException { - Matrix result = new DenseMatrix(config); - - JobConf jobConf = new JobConf(config); - jobConf.setJobName("addition MR job" + result.getPath()); - - jobConf.setNumMapTasks(config.getNumMapTasks()); - jobConf.setNumReduceTasks(config.getNumReduceTasks()); - - RowCyclicAdditionMap.initJob(this.getPath(), B.getPath(), - RowCyclicAdditionMap.class, IntWritable.class, VectorWritable.class, - jobConf); - RowCyclicReduce.initJob(result.getPath(), RowCyclicAdditionReduce.class, - jobConf); - - JobManager.execute(jobConf, result); - return result; - } - - public Matrix add(double alpha, Matrix B) throws IOException { - // TODO Auto-generated method stub - return null; - } - - public DenseVector getRow(int row) throws IOException { - return new DenseVector(table.getRow(BytesUtil.intToBytes(row))); - } - - public Vector getColumn(int column) throws IOException { - byte[] columnKey = BytesUtil.getColumnIndex(column); - byte[][] c = { columnKey }; - Scanner scan = table.getScanner(c, HConstants.EMPTY_START_ROW); - - MapWritable trunk = new MapWritable(); - - for (RowResult row : scan) { - trunk.put(BytesUtil.bytesToInt(row.getRow()), new DoubleEntry(row - .get(columnKey))); - } - - return new DenseVector(trunk); - } - - public Matrix mult(Matrix B) throws IOException { - Matrix result = new DenseMatrix(config); - - JobConf jobConf = new JobConf(config); - jobConf.setJobName("multiplication MR job : " + result.getPath()); - - jobConf.setNumMapTasks(config.getNumMapTasks()); - jobConf.setNumReduceTasks(config.getNumReduceTasks()); - - if (this.isBlocked() && ((DenseMatrix) B).isBlocked()) { - BlockCyclicMultiplyMap.initJob(this.getPath(), B.getPath(), - BlockCyclicMultiplyMap.class, IntWritable.class, BlockWritable.class, - jobConf); - BlockCyclicReduce.initJob(result.getPath(), - BlockCyclicMultiplyReduce.class, jobConf); - } else { - SIMDMultiplyMap.initJob(this.getPath(), B.getPath(), - SIMDMultiplyMap.class, IntWritable.class, VectorWritable.class, - jobConf); - RowCyclicReduce.initJob(result.getPath(), SIMDMultiplyReduce.class, - jobConf); - } - - JobManager.execute(jobConf, result); - return result; - } - - public Matrix multAdd(double alpha, Matrix B, Matrix C) throws IOException { - // TODO Auto-generated method stub - return null; - } - - public double norm(Norm type) throws IOException { - // TODO Auto-generated method stub - return 0; - } - - public Matrix set(double alpha, Matrix B) throws IOException { - // TODO Auto-generated method stub - return null; - } - - public Matrix set(Matrix B) throws IOException { - // TODO Auto-generated method stub - return null; - } - - public void setRow(int row, Vector vector) throws IOException { - VectorUpdate update = new VectorUpdate(row); - update.putAll(((DenseVector) vector).getEntries().entrySet()); - table.commit(update.getBatchUpdate()); - } - - public void setColumn(int column, Vector vector) throws IOException { - for (int i = 0; i < vector.size(); i++) { - VectorUpdate update = new VectorUpdate(i); - update.put(column, vector.get(i)); - table.commit(update.getBatchUpdate()); - } - } - - public String getType() { - return this.getClass().getSimpleName(); - } - - // ========================================= - - public SubMatrix subMatrix(int i0, int i1, int j0, int j1) throws IOException { - int columnSize = (j1 - j0) + 1; - SubMatrix result = new SubMatrix((i1 - i0) + 1, columnSize); - - for (int i = i0, ii = 0; i <= i1; i++, ii++) { - for (int j = j0, jj = 0; j <= j1; j++, jj++) { - Cell c = table - .get(BytesUtil.intToBytes(i), BytesUtil.getColumnIndex(j)); - result.set(ii, jj, BytesUtil.bytesToDouble(c.getValue())); - } - } - - return result; - } - - /** - * The type of the Matrix to be blocked, must be dense. - * - * TODO: it should be work on map/reduce - */ - public void blocking(int blockNum) throws IOException { - setBlockPosition(blockNum); - setBlockSize(blockNum); - - String[] columns = new String[] { Constants.BLOCK_STARTROW, - Constants.BLOCK_ENDROW, Constants.BLOCK_STARTCOLUMN, - Constants.BLOCK_ENDCOLUMN }; - Scanner scan = table.getScanner(columns); - - for (RowResult row : scan) { - String[] key = Bytes.toString(row.getRow()).split("[,]"); - int blockR = Integer.parseInt(key[0]); - int blockC = Integer.parseInt(key[1]); - setBlock(blockR, blockC, blockMatrix(blockR, blockC)); - } - } - - public boolean isBlocked() throws IOException { - return (table.get(Constants.METADATA, Constants.BLOCK_SIZE) == null) ? false - : true; - } - - public SubMatrix getBlock(int i, int j) throws IOException { - return BytesUtil.bytesToSubMatrix(table.get(String.valueOf(i), - Constants.BLOCK + j).getValue()); - } - - /** - * @return the size of block - * @throws IOException - */ - public int getBlockSize() throws IOException { - return (isBlocked()) ? BytesUtil.bytesToInt(table.get(Constants.METADATA, - Constants.BLOCK_SIZE).getValue()) : -1; - } - - protected void setBlockSize(int blockNum) throws IOException { - BatchUpdate update = new BatchUpdate(Constants.METADATA); - update.put(Constants.BLOCK_SIZE, BytesUtil.intToBytes(blockNum)); - table.commit(update); - } - - protected void setBlock(int i, int j, SubMatrix matrix) throws IOException { - BatchUpdate update = new BatchUpdate(String.valueOf(i)); - update.put(Constants.BLOCK + j, BytesUtil.subMatrixToBytes(matrix)); - table.commit(update); - } - - protected void setBlockPosition(int blockNum) throws IOException { - int block_row_size = this.getRows() / blockNum; - int block_column_size = this.getColumns() / blockNum; - - for (int i = 0; i < blockNum; i++) { - for (int j = 0; j < blockNum; j++) { - int startRow = i * block_row_size; - int endRow = (startRow + block_row_size) - 1; - int startColumn = j * block_column_size; - int endColumn = (startColumn + block_column_size) - 1; - - BatchUpdate update = new BatchUpdate(getBlockKey(i, j)); - update.put(Constants.BLOCK_STARTROW, BytesUtil.intToBytes(startRow)); - update.put(Constants.BLOCK_ENDROW, BytesUtil.intToBytes(endRow)); - update.put(Constants.BLOCK_STARTCOLUMN, BytesUtil - .intToBytes(startColumn)); - update.put(Constants.BLOCK_ENDCOLUMN, BytesUtil.intToBytes(endColumn)); - table.commit(update); - } - } - } - - protected int[] getBlockPosition(int i, int j) throws IOException { - int[] result = new int[4]; - result[0] = BytesUtil.bytesToInt(table.get(getBlockKey(i, j), - Constants.BLOCK_STARTROW).getValue()); - result[1] = BytesUtil.bytesToInt(table.get(getBlockKey(i, j), - Constants.BLOCK_ENDROW).getValue()); - result[2] = BytesUtil.bytesToInt(table.get(getBlockKey(i, j), - Constants.BLOCK_STARTCOLUMN).getValue()); - result[3] = BytesUtil.bytesToInt(table.get(getBlockKey(i, j), - Constants.BLOCK_ENDCOLUMN).getValue()); - return result; - } - - protected String getBlockKey(int i, int j) { - return i + "," + j; - } - - /** - * @param i - * @param j - * @return the sub matrix - * @throws IOException - */ - protected SubMatrix blockMatrix(int i, int j) throws IOException { - int[] pos = getBlockPosition(i, j); - return subMatrix(pos[0], pos[1], pos[2], pos[3]); - } -} +/** + * Copyright 2007 The Apache Software Foundation + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama; + +import java.io.IOException; + +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.client.HTable; +import org.apache.hadoop.hbase.client.Scanner; +import org.apache.hadoop.hbase.io.BatchUpdate; +import org.apache.hadoop.hbase.io.Cell; +import org.apache.hadoop.hbase.io.RowResult; +import org.apache.hadoop.io.IntWritable; +import org.apache.hadoop.mapred.JobConf; +import org.apache.hama.algebra.BlockCyclicMultiplyMap; +import org.apache.hama.algebra.BlockCyclicMultiplyReduce; +import org.apache.hama.algebra.RowCyclicAdditionMap; +import org.apache.hama.algebra.RowCyclicAdditionReduce; +import org.apache.hama.algebra.SIMDMultiplyMap; +import org.apache.hama.algebra.SIMDMultiplyReduce; +import org.apache.hama.io.BlockWritable; +import org.apache.hama.io.DoubleEntry; +import org.apache.hama.io.MapWritable; +import org.apache.hama.io.VectorUpdate; +import org.apache.hama.io.VectorWritable; +import org.apache.hama.mapred.BlockCyclicReduce; +import org.apache.hama.mapred.BlockingMapRed; +import org.apache.hama.mapred.RowCyclicReduce; +import org.apache.hama.util.BytesUtil; +import org.apache.hama.util.JobManager; +import org.apache.hama.util.RandomVariable; + +public class DenseMatrix extends AbstractMatrix implements Matrix { + + static int tryPathLength = Constants.DEFAULT_PATH_LENGTH; + static final String TABLE_PREFIX = DenseMatrix.class.getSimpleName() + "_"; + + /** + * Construct a raw matrix. Just create a table in HBase, but didn't lay any + * schema ( such as dimensions: i, j ) on it. + * + * @param conf configuration object + * @throws IOException throw the exception to let the user know what happend, + * if we didn't create the matrix successfully. + */ + public DenseMatrix(HamaConfiguration conf) throws IOException { + setConfiguration(conf); + + tryToCreateTable(); + + closed = false; + } + + /** + * Create/load a matrix aliased as 'matrixName'. + * + * @param conf configuration object + * @param matrixName the name of the matrix + * @param force if force is true, a new matrix will be created no matter + * 'matrixName' has aliased to an existed matrix; otherwise, + * just try to load an existed matrix alised 'matrixName'. + * @throws IOException + */ + public DenseMatrix(HamaConfiguration conf, String matrixName, boolean force) + throws IOException { + setConfiguration(conf); + // if force is set to true: + // 1) if this matrixName has aliase to other matrix, we will remove + // the old aliase, create a new matrix table, and aliase to it. + // 2) if this matrixName has no aliase to other matrix, we will create + // a new matrix table, and alise to it. + // + // if force is set to false, we just try to load an existed matrix alised + // as 'matrixname'. + + boolean existed = hamaAdmin.matrixExists(matrixName); + + if (force) { + if (existed) { + // remove the old aliase + hamaAdmin.delete(matrixName); + } + // create a new matrix table. + tryToCreateTable(); + // save the new aliase relationship + save(matrixName); + } else { + if (existed) { + // try to get the actual path of the table + matrixPath = hamaAdmin.getPath(matrixName); + // load the matrix + table = new HTable(conf, matrixPath); + // increment the reference + incrementAndGetRef(); + } else { + throw new IOException("Try to load non-existed matrix alised as " + + matrixName); + } + } + + closed = false; + } + + /** + * Load a matrix from an existed matrix table whose tablename is 'matrixpath' !! + * It is an internal used for map/reduce. + * + * @param conf configuration object + * @param matrixpath + * @throws IOException + * @throws IOException + */ + public DenseMatrix(HamaConfiguration conf, String matrixpath) + throws IOException { + setConfiguration(conf); + matrixPath = matrixpath; + // load the matrix + table = new HTable(conf, matrixPath); + // TODO: now we don't increment the reference of the table + // for it's an internal use for map/reduce. + // if we want to increment the reference of the table, + // we don't know where to call Matrix.close in Add & Mul map/reduce + // process to decrement the reference. It seems difficulty. + } + + /** + * Create an m-by-n constant matrix. + * + * @param conf configuration object + * @param m the number of rows. + * @param n the number of columns. + * @param s fill the matrix with this scalar value. + * @throws IOException throw the exception to let the user know what happend, + * if we didn't create the matrix successfully. + */ + public DenseMatrix(HamaConfiguration conf, int m, int n, double s) + throws IOException { + setConfiguration(conf); + + tryToCreateTable(); + + closed = false; + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + set(i, j, s); + } + } + + setDimension(m, n); + } + + /** + * try to create a new matrix with a new random name. try times will be + * (Integer.MAX_VALUE - 4) * DEFAULT_TRY_TIMES; + * + * @throws IOException + */ + private void tryToCreateTable() throws IOException { + int tryTimes = Constants.DEFAULT_TRY_TIMES; + do { + matrixPath = TABLE_PREFIX + RandomVariable.randMatrixPath(tryPathLength); + + if (!admin.tableExists(matrixPath)) { // no table 'matrixPath' in hbase. + tableDesc = new HTableDescriptor(matrixPath); + create(); + return; + } + + tryTimes--; + if (tryTimes <= 0) { // this loop has exhausted DEFAULT_TRY_TIMES. + tryPathLength++; + tryTimes = Constants.DEFAULT_TRY_TIMES; + } + + } while (tryPathLength <= Constants.DEFAULT_MAXPATHLEN); + // exhaustes the try times. + // throw out an IOException to let the user know what happened. + throw new IOException("Try too many times to create a table in hbase."); + } + + /** + * Generate matrix with random elements + * + * @param conf configuration object + * @param m the number of rows. + * @param n the number of columns. + * @return an m-by-n matrix with uniformly distributed random elements. + * @throws IOException + */ + public static DenseMatrix random(HamaConfiguration conf, int m, int n) + throws IOException { + DenseMatrix rand = new DenseMatrix(conf); + DenseVector vector = new DenseVector(); + LOG.info("Create the " + m + " * " + n + " random matrix : " + + rand.getPath()); + + for (int i = 0; i < m; i++) { + vector.clear(); + for (int j = 0; j < n; j++) { + vector.set(j, RandomVariable.rand()); + } + rand.setRow(i, vector); + } + + rand.setDimension(m, n); + return rand; + } + + /** + * Generate identity matrix + * + * @param conf configuration object + * @param m the number of rows. + * @param n the number of columns. + * @return an m-by-n matrix with ones on the diagonal and zeros elsewhere. + * @throws IOException + */ + public static Matrix identity(HamaConfiguration conf, int m, int n) + throws IOException { + Matrix identity = new DenseMatrix(conf); + LOG.info("Create the " + m + " * " + n + " identity matrix : " + + identity.getPath()); + + for (int i = 0; i < m; i++) { + DenseVector vector = new DenseVector(); + for (int j = 0; j < n; j++) { + vector.set(j, (i == j ? 1.0 : 0.0)); + } + identity.setRow(i, vector); + } + + identity.setDimension(m, n); + return identity; + } + + /** + * Gets the double value of (i, j) + * + * @param i ith row of the matrix + * @param j jth column of the matrix + * @return the value of entry, or zero If entry is null + * @throws IOException + */ + public double get(int i, int j) throws IOException { + Cell c = table.get(BytesUtil.intToBytes(i), BytesUtil.getColumnIndex(j)); + return (c != null) ? BytesUtil.bytesToDouble(c.getValue()) : 0; + } + + public Matrix add(Matrix B) throws IOException { + Matrix result = new DenseMatrix(config); + + JobConf jobConf = new JobConf(config); + jobConf.setJobName("addition MR job" + result.getPath()); + + jobConf.setNumMapTasks(config.getNumMapTasks()); + jobConf.setNumReduceTasks(config.getNumReduceTasks()); + + RowCyclicAdditionMap.initJob(this.getPath(), B.getPath(), + RowCyclicAdditionMap.class, IntWritable.class, VectorWritable.class, + jobConf); + RowCyclicReduce.initJob(result.getPath(), RowCyclicAdditionReduce.class, + jobConf); + + JobManager.execute(jobConf, result); + return result; + } + + public Matrix add(double alpha, Matrix B) throws IOException { + // TODO Auto-generated method stub + return null; + } + + public DenseVector getRow(int row) throws IOException { + return new DenseVector(table.getRow(BytesUtil.intToBytes(row))); + } + + public Vector getColumn(int column) throws IOException { + byte[] columnKey = BytesUtil.getColumnIndex(column); + byte[][] c = { columnKey }; + Scanner scan = table.getScanner(c, HConstants.EMPTY_START_ROW); + + MapWritable trunk = new MapWritable(); + + for (RowResult row : scan) { + trunk.put(BytesUtil.bytesToInt(row.getRow()), new DoubleEntry(row + .get(columnKey))); + } + + return new DenseVector(trunk); + } + + public Matrix mult(Matrix B) throws IOException { + Matrix result = new DenseMatrix(config); + + JobConf jobConf = new JobConf(config); + jobConf.setJobName("multiplication MR job : " + result.getPath()); + + jobConf.setNumMapTasks(config.getNumMapTasks()); + jobConf.setNumReduceTasks(config.getNumReduceTasks()); + + if (this.isBlocked() && ((DenseMatrix) B).isBlocked()) { + BlockCyclicMultiplyMap.initJob(this.getPath(), B.getPath(), + BlockCyclicMultiplyMap.class, IntWritable.class, BlockWritable.class, + jobConf); + BlockCyclicReduce.initJob(result.getPath(), + BlockCyclicMultiplyReduce.class, jobConf); + } else { + SIMDMultiplyMap.initJob(this.getPath(), B.getPath(), + SIMDMultiplyMap.class, IntWritable.class, VectorWritable.class, + jobConf); + RowCyclicReduce.initJob(result.getPath(), SIMDMultiplyReduce.class, + jobConf); + } + + JobManager.execute(jobConf, result); + return result; + } + + public Matrix multAdd(double alpha, Matrix B, Matrix C) throws IOException { + // TODO Auto-generated method stub + return null; + } + + public double norm(Norm type) throws IOException { + // TODO Auto-generated method stub + return 0; + } + + public Matrix set(double alpha, Matrix B) throws IOException { + // TODO Auto-generated method stub + return null; + } + + public Matrix set(Matrix B) throws IOException { + // TODO Auto-generated method stub + return null; + } + + public void setRow(int row, Vector vector) throws IOException { + VectorUpdate update = new VectorUpdate(row); + update.putAll(((DenseVector) vector).getEntries().entrySet()); + table.commit(update.getBatchUpdate()); + } + + public void setColumn(int column, Vector vector) throws IOException { + for (int i = 0; i < vector.size(); i++) { + VectorUpdate update = new VectorUpdate(i); + update.put(column, vector.get(i)); + table.commit(update.getBatchUpdate()); + } + } + + public String getType() { + return this.getClass().getSimpleName(); + } + + public SubMatrix subMatrix(int i0, int i1, int j0, int j1) throws IOException { + int columnSize = (j1 - j0) + 1; + SubMatrix result = new SubMatrix((i1 - i0) + 1, columnSize); + + for (int i = i0, ii = 0; i <= i1; i++, ii++) { + for (int j = j0, jj = 0; j <= j1; j++, jj++) { + Cell c = table + .get(BytesUtil.intToBytes(i), BytesUtil.getColumnIndex(j)); + result.set(ii, jj, BytesUtil.bytesToDouble(c.getValue())); + } + } + + return result; + } + + /** + * Using a map/reduce job to block a dense matrix. + * + * @param blockNum + * @throws IOException + */ + public void blocking_mapred(int blockNum) throws IOException { + setBlockPosition(blockNum); + setBlockSize(blockNum); + + JobConf jobConf = new JobConf(config); + jobConf.setJobName("Blocking MR job" + getPath()); + + jobConf.setNumMapTasks(config.getNumMapTasks()); + jobConf.setNumReduceTasks(config.getNumReduceTasks()); + + BlockingMapRed.initJob(getPath(), jobConf); + + JobManager.execute(jobConf); + } + + public boolean isBlocked() throws IOException { + return (table.get(Constants.METADATA, Constants.BLOCK_SIZE) == null) ? + false : true; + } + + public SubMatrix getBlock(int i, int j) throws IOException { + return BytesUtil.bytesToSubMatrix(table.get(String.valueOf(i), + Constants.BLOCK + j).getValue()); + } + + /** + * @return the size of block + * @throws IOException + */ + public int getBlockSize() throws IOException { + return (isBlocked()) ? BytesUtil.bytesToInt(table.get(Constants.METADATA, + Constants.BLOCK_SIZE).getValue()) : -1; + } + + protected void setBlockSize(int blockNum) throws IOException { + BatchUpdate update = new BatchUpdate(Constants.METADATA); + update.put(Constants.BLOCK_SIZE, BytesUtil.intToBytes(blockNum)); + table.commit(update); + } + + public void setBlock(int i, int j, SubMatrix matrix) throws IOException { + BatchUpdate update = new BatchUpdate(String.valueOf(i)); + update.put(Constants.BLOCK + j, BytesUtil.subMatrixToBytes(matrix)); + table.commit(update); + } + + protected void setBlockPosition(int blockNum) throws IOException { + int block_row_size = this.getRows() / blockNum; + int block_column_size = this.getColumns() / blockNum; + + for (int i = 0; i < blockNum; i++) { + for (int j = 0; j < blockNum; j++) { + int startRow = i * block_row_size; + int endRow = (startRow + block_row_size) - 1; + int startColumn = j * block_column_size; + int endColumn = (startColumn + block_column_size) - 1; + + BatchUpdate update = new BatchUpdate(getBlockKey(i, j)); + update.put(Constants.BLOCK_STARTROW, BytesUtil.intToBytes(startRow)); + update.put(Constants.BLOCK_ENDROW, BytesUtil.intToBytes(endRow)); + update.put(Constants.BLOCK_STARTCOLUMN, BytesUtil + .intToBytes(startColumn)); + update.put(Constants.BLOCK_ENDCOLUMN, BytesUtil.intToBytes(endColumn)); + table.commit(update); + } + } + } + + protected int[] getBlockPosition(int i, int j) throws IOException { + int[] result = new int[4]; + result[0] = BytesUtil.bytesToInt(table.get(getBlockKey(i, j), + Constants.BLOCK_STARTROW).getValue()); + result[1] = BytesUtil.bytesToInt(table.get(getBlockKey(i, j), + Constants.BLOCK_ENDROW).getValue()); + result[2] = BytesUtil.bytesToInt(table.get(getBlockKey(i, j), + Constants.BLOCK_STARTCOLUMN).getValue()); + result[3] = BytesUtil.bytesToInt(table.get(getBlockKey(i, j), + Constants.BLOCK_ENDCOLUMN).getValue()); + return result; + } + + protected String getBlockKey(int i, int j) { + return i + "," + j; + } +} Modified: incubator/hama/trunk/src/java/org/apache/hama/io/BlockID.java URL: http://svn.apache.org/viewvc/incubator/hama/trunk/src/java/org/apache/hama/io/BlockID.java?rev=720716&r1=720715&r2=720716&view=diff ============================================================================== --- incubator/hama/trunk/src/java/org/apache/hama/io/BlockID.java (original) +++ incubator/hama/trunk/src/java/org/apache/hama/io/BlockID.java Tue Nov 25 18:57:15 2008 @@ -1,107 +1,118 @@ -/** - * Copyright 2007 The Apache Software Foundation - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hama.io; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; - -import org.apache.hadoop.io.WritableComparable; -import org.apache.hadoop.io.WritableComparator; - -/** A WritableComparable for BlockIDs. */ -public class BlockID implements WritableComparable { - private int row; - private int column; - - public BlockID() { - } - - public BlockID(int row, int column) { - set(row, column); - } - - public void set(int row, int column) { - this.row = row; - this.column = column; - } - - public int getRow() { - return row; - } - - public int getColumn() { - return column; - } - - public void readFields(DataInput in) throws IOException { - row = in.readInt(); - column = in.readInt(); - } - - public void write(DataOutput out) throws IOException { - out.writeInt(row); - out.write(column); - } - - public String toString() { - return row + ", " + column; - } - - public int compareTo(Object o) { - int thisRow = this.row; - int thatRow = ((BlockID) o).row; - int thisColumn = this.column; - int thatColumn = ((BlockID) o).column; - - if (thisRow != thatRow) { - return (thisRow < thatRow ? -1 : 1); - } else { - return (thisColumn < thatColumn ? -1 : (thisColumn == thatColumn ? 0 : 1)); - } - } - - /** - * BlockID Comparator - */ - public static class Comparator extends WritableComparator { - protected Comparator() { - super(BlockID.class); - } - - public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) { - int thisRow = readInt(b1, s1); - int thatRow = readInt(b2, s2); - int thisColumn = readInt(b1, l1); - int thatColumn = readInt(b2, l2); - - if (thisRow != thatRow) { - return (thisRow < thatRow ? -1 : 1); - } else { - return (thisColumn < thatColumn ? -1 : (thisColumn == thatColumn ? 0 - : 1)); - } - } - } - - static { // register this comparator - WritableComparator.define(BlockID.class, new Comparator()); - } -} +/** + * Copyright 2007 The Apache Software Foundation + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.io; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import org.apache.hadoop.io.WritableComparable; +import org.apache.hadoop.io.WritableComparator; + +/** A WritableComparable for BlockIDs. */ +public class BlockID implements WritableComparable { + private int row; + private int column; + + public BlockID() { + } + + public BlockID(int row, int column) { + set(row, column); + } + + public void set(int row, int column) { + this.row = row; + this.column = column; + } + + public int getRow() { + return row; + } + + public int getColumn() { + return column; + } + + public void readFields(DataInput in) throws IOException { + row = in.readInt(); + column = in.readInt(); + } + + public void write(DataOutput out) throws IOException { + out.writeInt(row); + // out.write(column); + out.writeInt(column); + } + + /** + * Make BlockID's string representation be same format. + */ + public String toString() { + return row + "," + column; + } + + @Override + public int hashCode() { + // simply use a prime number + // may be need a more balance hash function + return row * 37 + column; + } + + public int compareTo(Object o) { + int thisRow = this.row; + int thatRow = ((BlockID) o).row; + int thisColumn = this.column; + int thatColumn = ((BlockID) o).column; + + if (thisRow != thatRow) { + return (thisRow < thatRow ? -1 : 1); + } else { + return (thisColumn < thatColumn ? -1 : (thisColumn == thatColumn ? 0 : 1)); + } + } + + /** + * BlockID Comparator + */ + public static class Comparator extends WritableComparator { + protected Comparator() { + super(BlockID.class); + } + + public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) { + int thisRow = readInt(b1, s1); + int thatRow = readInt(b2, s2); + int thisColumn = readInt(b1, l1); + int thatColumn = readInt(b2, l2); + + if (thisRow != thatRow) { + return (thisRow < thatRow ? -1 : 1); + } else { + return (thisColumn < thatColumn ? -1 : (thisColumn == thatColumn ? 0 + : 1)); + } + } + } + + static { // register this comparator + WritableComparator.define(BlockID.class, new Comparator()); + } +} Modified: incubator/hama/trunk/src/java/org/apache/hama/util/JobManager.java URL: http://svn.apache.org/viewvc/incubator/hama/trunk/src/java/org/apache/hama/util/JobManager.java?rev=720716&r1=720715&r2=720716&view=diff ============================================================================== --- incubator/hama/trunk/src/java/org/apache/hama/util/JobManager.java (original) +++ incubator/hama/trunk/src/java/org/apache/hama/util/JobManager.java Tue Nov 25 18:57:15 2008 @@ -40,4 +40,14 @@ result.setDimension(rows, columns); } + /** + * a help method to execute a job + * + * @param jobConf + * @throws IOException + */ + public static void execute(JobConf jobConf) throws IOException { + JobClient.runJob(jobConf); + } + } Modified: incubator/hama/trunk/src/test/org/apache/hama/TestDenseMatrix.java URL: http://svn.apache.org/viewvc/incubator/hama/trunk/src/test/org/apache/hama/TestDenseMatrix.java?rev=720716&r1=720715&r2=720716&view=diff ============================================================================== --- incubator/hama/trunk/src/test/org/apache/hama/TestDenseMatrix.java (original) +++ incubator/hama/trunk/src/test/org/apache/hama/TestDenseMatrix.java Tue Nov 25 18:57:15 2008 @@ -1,333 +1,352 @@ -/** - * Copyright 2007 The Apache Software Foundation - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hama; - -import java.io.IOException; -import java.util.Iterator; - -import junit.extensions.TestSetup; -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -import org.apache.hadoop.hbase.client.HBaseAdmin; -import org.apache.hama.io.DoubleEntry; -import org.apache.log4j.Logger; - -/** - * Matrix test - */ -public class TestDenseMatrix extends TestCase { - static final Logger LOG = Logger.getLogger(TestDenseMatrix.class); - private static int SIZE = 10; - private static Matrix m1; - private static Matrix m2; - private final static String aliase1 = "matrix_aliase_A"; - private final static String aliase2 = "matrix_aliase_B"; - private static HamaConfiguration conf; - private static HBaseAdmin admin; - private static HamaAdmin hamaAdmin; - - public static Test suite() { - TestSetup setup = new TestSetup(new TestSuite(TestDenseMatrix.class)) { - protected void setUp() throws Exception { - HCluster hCluster = new HCluster(); - hCluster.setUp(); - - conf = hCluster.getConf(); - admin = new HBaseAdmin(conf); - hamaAdmin = new HamaAdminImpl(conf, admin); - - m1 = DenseMatrix.random(hCluster.getConf(), SIZE, SIZE); - m2 = DenseMatrix.random(hCluster.getConf(), SIZE, SIZE); - } - - protected void tearDown() { - try { - closeTest(); - } catch (IOException e) { - e.printStackTrace(); - } - } - }; - return setup; - } - - public static void closeTest() throws IOException { - m1.close(); - m2.close(); - } - - public void testEntryAdd() throws IOException { - double origin = m1.get(1, 1); - m1.add(1, 1, 0.5); - - assertEquals(m1.get(1, 1), origin + 0.5); - } - - public void testBlocking() throws IOException, ClassNotFoundException { - assertEquals(((DenseMatrix) m1).isBlocked(), false); - ((DenseMatrix) m1).blocking(2); - assertEquals(((DenseMatrix) m1).isBlocked(), true); - int[] pos = ((DenseMatrix) m1).getBlockPosition(1, 0); - double[][] a = ((DenseMatrix) m1).blockMatrix(1, 0).getDoubles(); - LOG.info(pos[0]+", "+pos[1]+", "+pos[2]+", "+pos[3]); - double[][] b = ((DenseMatrix) m1).subMatrix(pos[0], pos[1], pos[2], pos[3]).getDoubles(); - double[][] c = ((DenseMatrix) m1).getBlock(1, 0).getDoubles(); - assertEquals(((DenseMatrix) m1).getBlockSize(), 2); - assertEquals(c.length, 5); - - for (int i = 0; i < a.length; i++) { - for (int j = 0; j < a.length; j++) { - assertEquals(a[i][j], b[i][j]); - assertEquals(a[i][j], c[i][j]); - assertEquals(b[i][j], c[i][j]); - } - } - } - - /** - * Column vector test. - * - * @param rand - * @throws IOException - */ - public void testGetColumn() throws IOException { - Vector v = m1.getColumn(0); - Iterator it = v.iterator(); - int x = 0; - while (it.hasNext()) { - assertEquals(m1.get(x, 0), it.next().getValue()); - x++; - } - } - - public void testGetSetAttribute() throws IOException { - m1.setRowLabel(0, "row1"); - assertEquals(m1.getRowLabel(0), "row1"); - assertEquals(m1.getRowLabel(1), null); - - m1.setColumnLabel(0, "column1"); - assertEquals(m1.getColumnLabel(0), "column1"); - assertEquals(m1.getColumnLabel(1), null); - } - - public void testSubMatrix() throws IOException { - SubMatrix a = m1.subMatrix(2, 4, 2, 4); - for (int i = 0; i < a.getRows(); i++) { - for (int j = 0; j < a.getColumns(); j++) { - assertEquals(a.get(i, j), m1.get(i + 2, j + 2)); - } - } - - SubMatrix b = m2.subMatrix(0, 2, 0, 2); - SubMatrix c = a.mult(b); - - double[][] C = new double[3][3]; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - for (int k = 0; k < 3; k++) { - C[i][k] += m1.get(i + 2, j + 2) * m2.get(j, k); - } - } - } - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - assertEquals(C[i][j], c.get(i, j)); - } - } - } - - /** - * Test matrices addition - * - * @throws IOException - */ - public void testMatrixAdd() throws IOException { - Matrix result = m1.add(m2); - - assertEquals(result.getRows(), SIZE); - assertEquals(result.getColumns(), SIZE); - - for (int i = 0; i < SIZE; i++) { - for (int j = 0; j < SIZE; j++) { - assertEquals(result.get(i, j), m1.get(i, j) + m2.get(i, j)); - } - } - } - - /** - * Test matrices multiplication - * - * @throws IOException - */ - public void testMatrixMult() throws IOException { - Matrix result = m1.mult(m2); - - assertEquals(result.getRows(), SIZE); - assertEquals(result.getColumns(), SIZE); - - verifyMultResult(m1, m2, result); - } - - public void testSetRow() throws IOException { - Vector v = new DenseVector(); - double[] entries = new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; - - for (int i = 0; i < SIZE; i++) { - v.set(i, entries[i]); - } - - m1.setRow(SIZE + 1, v); - Iterator it = m1.getRow(SIZE + 1).iterator(); - - int i = 0; - while (it.hasNext()) { - assertEquals(entries[i], it.next().getValue()); - i++; - } - } - - public void testSetColumn() throws IOException { - Vector v = new DenseVector(); - double[] entries = new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; - - for (int i = 0; i < SIZE; i++) { - v.set(i, entries[i]); - } - - m1.setColumn(SIZE + 1, v); - Iterator it = m1.getColumn(SIZE + 1).iterator(); - - int i = 0; - while (it.hasNext()) { - assertEquals(entries[i], it.next().getValue()); - i++; - } - } - - public void testLoadSave() throws IOException { - String path1 = m1.getPath(); - // save m1 to aliase1 - m1.save(aliase1); - // load matrix m1 using aliase1 - DenseMatrix loadTest = new DenseMatrix(conf, aliase1, false); - - for (int i = 0; i < loadTest.getRows(); i++) { - for (int j = 0; j < loadTest.getColumns(); j++) { - assertEquals(m1.get(i, j), loadTest.get(i, j)); - } - } - - assertEquals(path1, loadTest.getPath()); - // close loadTest, it just disconnect to the table but didn't delete it. - loadTest.close(); - - // try to close m1 & load matrix m1 using aliase1 again. - m1.close(); - DenseMatrix loadTest2 = new DenseMatrix(conf, aliase1, false); - assertEquals(path1, loadTest2.getPath()); - // remove aliase1 - // because loadTest2 connect the aliase1, so we just remove aliase entry - // but didn't delete the table. - hamaAdmin.delete(aliase1); - assertEquals(true, admin.tableExists(path1)); - // close loadTest2, because it is the last one who reference table 'path1' - // it will do the gc! - loadTest2.close(); - assertEquals(false, admin.tableExists(path1)); - - // if we try to load non-existed matrix using aliase name, it should fail. - DenseMatrix loadTest3 = null; - try { - loadTest3 = new DenseMatrix(conf, aliase1, false); - fail("Try to load a non-existed matrix should fail!"); - } catch (IOException e) { - - } finally { - if (loadTest3 != null) - loadTest3.close(); - } - } - - public void testForceCreate() throws IOException { - String path2 = m2.getPath(); - // save m2 to aliase2 - m2.save(aliase2); - // load matrix m2 using aliase2 - DenseMatrix loadTest = new DenseMatrix(conf, aliase2, false); - - for (int i = 0; i < loadTest.getRows(); i++) { - for (int j = 0; j < loadTest.getColumns(); j++) { - assertEquals(m2.get(i, j), loadTest.get(i, j)); - } - } - - assertEquals(path2, loadTest.getPath()); - - // force to create matrix loadTest2 using aliasename 'aliase2' - DenseMatrix loadTest2 = new DenseMatrix(conf, aliase2, true); - String loadPath2 = loadTest2.getPath(); - assertFalse(path2.equals(loadPath2)); - assertEquals(loadPath2, hamaAdmin.getPath(aliase2)); - assertFalse(path2.equals(hamaAdmin.getPath(aliase2))); - - // try to close m2 & loadTest, it table will be deleted finally - m2.close(); - assertEquals(true, admin.tableExists(path2)); - loadTest.close(); - assertEquals(false, admin.tableExists(path2)); - - // remove 'aliase2' & close loadTest2 - loadTest2.close(); - assertEquals(true, admin.tableExists(loadPath2)); - hamaAdmin.delete(aliase2); - assertEquals(false, admin.tableExists(loadPath2)); - } - - /** - * Verifying multiplication result - * - * @param m1 - * @param m2 - * @param result - * @throws IOException - */ - private void verifyMultResult(Matrix m1, Matrix m2, Matrix result) - throws IOException { - double[][] C = new double[SIZE][SIZE]; - - for (int i = 0; i < SIZE; i++) { - for (int j = 0; j < SIZE; j++) { - for (int k = 0; k < SIZE; k++) { - C[i][k] += m1.get(i, j) * m2.get(j, k); - } - } - } - - for (int i = 0; i < SIZE; i++) { - for (int j = 0; j < SIZE; j++) { - assertEquals(String.valueOf(result.get(i, j)).substring(0, 14), - String.valueOf(C[i][j]).substring(0, 14)); - } - } - } -} +/** + * Copyright 2007 The Apache Software Foundation + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama; + +import java.io.IOException; +import java.util.Iterator; + +import junit.extensions.TestSetup; +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.apache.hama.io.DoubleEntry; +import org.apache.log4j.Logger; + +/** + * Matrix test + */ +public class TestDenseMatrix extends TestCase { + static final Logger LOG = Logger.getLogger(TestDenseMatrix.class); + private static int SIZE = 10; + private static Matrix m1; + private static Matrix m2; + private final static String aliase1 = "matrix_aliase_A"; + private final static String aliase2 = "matrix_aliase_B"; + private static HamaConfiguration conf; + private static HBaseAdmin admin; + private static HamaAdmin hamaAdmin; + + public static Test suite() { + TestSetup setup = new TestSetup(new TestSuite(TestDenseMatrix.class)) { + protected void setUp() throws Exception { + HCluster hCluster = new HCluster(); + hCluster.setUp(); + + conf = hCluster.getConf(); + admin = new HBaseAdmin(conf); + hamaAdmin = new HamaAdminImpl(conf, admin); + + m1 = DenseMatrix.random(hCluster.getConf(), SIZE, SIZE); + m2 = DenseMatrix.random(hCluster.getConf(), SIZE, SIZE); + } + + protected void tearDown() { + try { + closeTest(); + } catch (IOException e) { + e.printStackTrace(); + } + } + }; + return setup; + } + + public static void closeTest() throws IOException { + m1.close(); + m2.close(); + } + + public void testEntryAdd() throws IOException { + double origin = m1.get(1, 1); + m1.add(1, 1, 0.5); + + assertEquals(m1.get(1, 1), origin + 0.5); + } + + public void testBlocking() throws IOException, ClassNotFoundException { + assertEquals(((DenseMatrix) m1).isBlocked(), false); + ((DenseMatrix) m1).blocking_mapred(2); + assertEquals(((DenseMatrix) m1).isBlocked(), true); + int[] pos = ((DenseMatrix) m1).getBlockPosition(1, 0); + double[][] b = ((DenseMatrix) m1).subMatrix(pos[0], pos[1], pos[2], pos[3]).getDoubles(); + double[][] c = ((DenseMatrix) m1).getBlock(1, 0).getDoubles(); + assertEquals(((DenseMatrix) m1).getBlockSize(), 2); + assertEquals(c.length, 5); + + for (int i = 0; i < b.length; i++) { + for (int j = 0; j < b.length; j++) { + assertEquals(b[i][j], c[i][j]); + } + } + } + + /** + * Map/Reduce Blocking Test + * + * @throws IOException + * @throws ClassNotFoundException + */ + public void testMRBlocking() throws IOException, ClassNotFoundException { + assertEquals(((DenseMatrix) m2).isBlocked(), false); + ((DenseMatrix) m2).blocking_mapred(2); + assertEquals(((DenseMatrix) m2).isBlocked(), true); + int[] pos = ((DenseMatrix) m2).getBlockPosition(1, 0); + double[][] b = ((DenseMatrix) m2).subMatrix(pos[0], pos[1], pos[2], pos[3]).getDoubles(); + double[][] c = ((DenseMatrix) m2).getBlock(1, 0).getDoubles(); + assertEquals(((DenseMatrix) m2).getBlockSize(), 2); + assertEquals(c.length, 5); + + for (int i = 0; i < b.length; i++) { + for (int j = 0; j < b.length; j++) { + assertEquals(b[i][j], c[i][j]); + } + } + } + + /** + * Column vector test. + * + * @param rand + * @throws IOException + */ + public void testGetColumn() throws IOException { + Vector v = m1.getColumn(0); + Iterator it = v.iterator(); + int x = 0; + while (it.hasNext()) { + assertEquals(m1.get(x, 0), it.next().getValue()); + x++; + } + } + + public void testGetSetAttribute() throws IOException { + m1.setRowLabel(0, "row1"); + assertEquals(m1.getRowLabel(0), "row1"); + assertEquals(m1.getRowLabel(1), null); + + m1.setColumnLabel(0, "column1"); + assertEquals(m1.getColumnLabel(0), "column1"); + assertEquals(m1.getColumnLabel(1), null); + } + + public void testSubMatrix() throws IOException { + SubMatrix a = m1.subMatrix(2, 4, 2, 4); + for (int i = 0; i < a.getRows(); i++) { + for (int j = 0; j < a.getColumns(); j++) { + assertEquals(a.get(i, j), m1.get(i + 2, j + 2)); + } + } + + SubMatrix b = m2.subMatrix(0, 2, 0, 2); + SubMatrix c = a.mult(b); + + double[][] C = new double[3][3]; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + for (int k = 0; k < 3; k++) { + C[i][k] += m1.get(i + 2, j + 2) * m2.get(j, k); + } + } + } + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + assertEquals(C[i][j], c.get(i, j)); + } + } + } + + /** + * Test matrices addition + * + * @throws IOException + */ + public void testMatrixAdd() throws IOException { + Matrix result = m1.add(m2); + + assertEquals(result.getRows(), SIZE); + assertEquals(result.getColumns(), SIZE); + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + assertEquals(result.get(i, j), m1.get(i, j) + m2.get(i, j)); + } + } + } + + /** + * Test matrices multiplication + * + * @throws IOException + */ + public void testMatrixMult() throws IOException { + Matrix result = m1.mult(m2); + + assertEquals(result.getRows(), SIZE); + assertEquals(result.getColumns(), SIZE); + + verifyMultResult(m1, m2, result); + } + + public void testSetRow() throws IOException { + Vector v = new DenseVector(); + double[] entries = new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + + for (int i = 0; i < SIZE; i++) { + v.set(i, entries[i]); + } + + m1.setRow(SIZE + 1, v); + Iterator it = m1.getRow(SIZE + 1).iterator(); + + int i = 0; + while (it.hasNext()) { + assertEquals(entries[i], it.next().getValue()); + i++; + } + } + + public void testSetColumn() throws IOException { + Vector v = new DenseVector(); + double[] entries = new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; + + for (int i = 0; i < SIZE; i++) { + v.set(i, entries[i]); + } + + m1.setColumn(SIZE + 1, v); + Iterator it = m1.getColumn(SIZE + 1).iterator(); + + int i = 0; + while (it.hasNext()) { + assertEquals(entries[i], it.next().getValue()); + i++; + } + } + + public void testLoadSave() throws IOException { + String path1 = m1.getPath(); + // save m1 to aliase1 + m1.save(aliase1); + // load matrix m1 using aliase1 + DenseMatrix loadTest = new DenseMatrix(conf, aliase1, false); + + for (int i = 0; i < loadTest.getRows(); i++) { + for (int j = 0; j < loadTest.getColumns(); j++) { + assertEquals(m1.get(i, j), loadTest.get(i, j)); + } + } + + assertEquals(path1, loadTest.getPath()); + // close loadTest, it just disconnect to the table but didn't delete it. + loadTest.close(); + + // try to close m1 & load matrix m1 using aliase1 again. + m1.close(); + DenseMatrix loadTest2 = new DenseMatrix(conf, aliase1, false); + assertEquals(path1, loadTest2.getPath()); + // remove aliase1 + // because loadTest2 connect the aliase1, so we just remove aliase entry + // but didn't delete the table. + hamaAdmin.delete(aliase1); + assertEquals(true, admin.tableExists(path1)); + // close loadTest2, because it is the last one who reference table 'path1' + // it will do the gc! + loadTest2.close(); + assertEquals(false, admin.tableExists(path1)); + + // if we try to load non-existed matrix using aliase name, it should fail. + DenseMatrix loadTest3 = null; + try { + loadTest3 = new DenseMatrix(conf, aliase1, false); + fail("Try to load a non-existed matrix should fail!"); + } catch (IOException e) { + + } finally { + if (loadTest3 != null) + loadTest3.close(); + } + } + + public void testForceCreate() throws IOException { + String path2 = m2.getPath(); + // save m2 to aliase2 + m2.save(aliase2); + // load matrix m2 using aliase2 + DenseMatrix loadTest = new DenseMatrix(conf, aliase2, false); + + for (int i = 0; i < loadTest.getRows(); i++) { + for (int j = 0; j < loadTest.getColumns(); j++) { + assertEquals(m2.get(i, j), loadTest.get(i, j)); + } + } + + assertEquals(path2, loadTest.getPath()); + + // force to create matrix loadTest2 using aliasename 'aliase2' + DenseMatrix loadTest2 = new DenseMatrix(conf, aliase2, true); + String loadPath2 = loadTest2.getPath(); + assertFalse(path2.equals(loadPath2)); + assertEquals(loadPath2, hamaAdmin.getPath(aliase2)); + assertFalse(path2.equals(hamaAdmin.getPath(aliase2))); + + // try to close m2 & loadTest, it table will be deleted finally + m2.close(); + assertEquals(true, admin.tableExists(path2)); + loadTest.close(); + assertEquals(false, admin.tableExists(path2)); + + // remove 'aliase2' & close loadTest2 + loadTest2.close(); + assertEquals(true, admin.tableExists(loadPath2)); + hamaAdmin.delete(aliase2); + assertEquals(false, admin.tableExists(loadPath2)); + } + + /** + * Verifying multiplication result + * + * @param m1 + * @param m2 + * @param result + * @throws IOException + */ + private void verifyMultResult(Matrix m1, Matrix m2, Matrix result) + throws IOException { + double[][] C = new double[SIZE][SIZE]; + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + for (int k = 0; k < SIZE; k++) { + C[i][k] += m1.get(i, j) * m2.get(j, k); + } + } + } + + for (int i = 0; i < SIZE; i++) { + for (int j = 0; j < SIZE; j++) { + assertEquals(String.valueOf(result.get(i, j)).substring(0, 14), + String.valueOf(C[i][j]).substring(0, 14)); + } + } + } +} Modified: incubator/hama/trunk/src/test/org/apache/hama/io/TestBlockID.java URL: http://svn.apache.org/viewvc/incubator/hama/trunk/src/test/org/apache/hama/io/TestBlockID.java?rev=720716&r1=720715&r2=720716&view=diff ============================================================================== --- incubator/hama/trunk/src/test/org/apache/hama/io/TestBlockID.java (original) +++ incubator/hama/trunk/src/test/org/apache/hama/io/TestBlockID.java Tue Nov 25 18:57:15 2008 @@ -1,45 +1,68 @@ -/** - * Copyright 2007 The Apache Software Foundation - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.hama.io; - -import junit.framework.TestCase; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class TestBlockID extends TestCase { - final static Log LOG = LogFactory.getLog(TestBlockID.class.getName()); - - /** - * BlockID object compare - */ - public void testCompare() { - BlockID a = new BlockID(1, 3); - BlockID b = new BlockID(1, 1); - assertEquals(a.compareTo(b), 1); - - BlockID c = new BlockID(3, 1); - BlockID d = new BlockID(1, 1); - assertEquals(a.compareTo(c), -1); - - assertEquals(b.compareTo(d), 0); - } - -} +/** + * Copyright 2007 The Apache Software Foundation + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hama.io; + +import java.io.IOException; + +import junit.framework.TestCase; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.io.DataInputBuffer; +import org.apache.hadoop.io.DataOutputBuffer; + +public class TestBlockID extends TestCase { + final static Log LOG = LogFactory.getLog(TestBlockID.class.getName()); + + /** + * BlockID object compare + */ + public void testCompare() { + BlockID a = new BlockID(1, 3); + BlockID b = new BlockID(1, 1); + assertEquals(a.compareTo(b), 1); + + BlockID c = new BlockID(3, 1); + BlockID d = new BlockID(1, 1); + assertEquals(a.compareTo(c), -1); + + assertEquals(b.compareTo(d), 0); + } + + /** + * BlockID object IO + * @throws IOException + */ + public void testIO() throws IOException { + DataOutputBuffer outBuf = new DataOutputBuffer(); + DataInputBuffer inBuf = new DataInputBuffer(); + + BlockID a = new BlockID(1, 3); + outBuf.reset(); + a.write(outBuf); + + inBuf.reset(outBuf.getData(), outBuf.getLength()); + BlockID b = new BlockID(); + b.readFields(inBuf); + + assertEquals(0, a.compareTo(b)); + } + +} Modified: incubator/hama/trunk/src/test/org/apache/hama/mapred/TestBlockMatrixMapReduce.java URL: http://svn.apache.org/viewvc/incubator/hama/trunk/src/test/org/apache/hama/mapred/TestBlockMatrixMapReduce.java?rev=720716&r1=720715&r2=720716&view=diff ============================================================================== --- incubator/hama/trunk/src/test/org/apache/hama/mapred/TestBlockMatrixMapReduce.java (original) +++ incubator/hama/trunk/src/test/org/apache/hama/mapred/TestBlockMatrixMapReduce.java Tue Nov 25 18:57:15 2008 @@ -25,8 +25,8 @@ public void testBlockMatrixMapReduce() throws IOException, ClassNotFoundException { Matrix m1 = DenseMatrix.random(conf, SIZE, SIZE); Matrix m2 = DenseMatrix.random(conf, SIZE, SIZE); - ((DenseMatrix) m1).blocking(2); - ((DenseMatrix) m2).blocking(2); + ((DenseMatrix) m1).blocking_mapred(2); + ((DenseMatrix) m2).blocking_mapred(2); miniMRJob(m1.getPath(), m2.getPath());