Repository: reef
Updated Branches:
  refs/heads/master 71951320e -> 6983326aa


[REEF-1002] Add a Vortex example that incurs large serialization cost

This addressed the issue by
  * Adding a matrix multiplication example based on @johnyangk's code.
  * Defining user-defined input/output to incur serialization cost.
  * Use a callback to check Tasklet execution results.

JIRA:
  [REEF-1002](https://issues.apache.org/jira/browse/REEF-1002)

Pull Request:
  Closes #709


Project: http://git-wip-us.apache.org/repos/asf/reef/repo
Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/6983326a
Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/6983326a
Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/6983326a

Branch: refs/heads/master
Commit: 6983326aad2e522f8e60f777aab24a01b53459dc
Parents: 7195132
Author: Yunseong Lee <[email protected]>
Authored: Mon Nov 23 14:48:37 2015 +0800
Committer: Byung-Gon Chun <[email protected]>
Committed: Mon Dec 7 20:23:37 2015 +0900

----------------------------------------------------------------------
 .../examples/matmul/IdentityMatMulStart.java    | 156 ++++++++++++++++++
 .../reef/vortex/examples/matmul/MatMul.java     |  36 ++++
 .../vortex/examples/matmul/MatMulException.java |  32 ++++
 .../vortex/examples/matmul/MatMulFunction.java  |  42 +++++
 .../vortex/examples/matmul/MatMulInput.java     |  64 +++++++
 .../vortex/examples/matmul/MatMulOutput.java    |  53 ++++++
 .../reef/vortex/examples/matmul/Matrix.java     |  68 ++++++++
 .../reef/vortex/examples/matmul/RowMatrix.java  | 165 +++++++++++++++++++
 .../vortex/examples/matmul/package-info.java    |  22 +++
 9 files changed, 638 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/reef/blob/6983326a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/IdentityMatMulStart.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/IdentityMatMulStart.java
 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/IdentityMatMulStart.java
new file mode 100644
index 0000000..092d64d
--- /dev/null
+++ 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/IdentityMatMulStart.java
@@ -0,0 +1,156 @@
+/*
+ * 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.reef.vortex.examples.matmul;
+
+import org.apache.reef.vortex.api.FutureCallback;
+import org.apache.reef.vortex.api.VortexStart;
+import org.apache.reef.vortex.api.VortexThreadPool;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * MatMul User Code Example.
+ * This example multiplies two matrices by distributing computation to 
multiple Tasklets.
+ * Each Tasklet receives split of the matrix on the left side, and copy of the 
matrix on the right side.
+ * To check whether the result is correct, Identity matrix is multiplied on 
the right side.
+ */
+final class IdentityMatMulStart implements VortexStart {
+  private static final Logger LOG = 
Logger.getLogger(IdentityMatMulStart.class.getName());
+  private static final int DIVIDE_FACTOR = 10000;
+  private static final int NUM_ROWS = 100000;
+  private static final int NUM_COLUMNS = 10;
+
+  @Inject
+  private IdentityMatMulStart() {
+  }
+
+  /**
+   * Perform a simple vector multiplication on Vortex.
+   */
+  @Override
+  public void start(final VortexThreadPool vortexThreadPool) {
+    final List<Matrix<Double>> leftSplits = generateMatrixSplits(NUM_ROWS, 
NUM_COLUMNS, DIVIDE_FACTOR);
+    final Matrix<Double> right = generateIdentityMatrix(NUM_COLUMNS);
+
+    // Measure job finish time starting from here..
+    final double start = System.currentTimeMillis();
+
+    // Define callback that is invoked when Tasklets finish.
+    final CountDownLatch latch = new CountDownLatch(DIVIDE_FACTOR);
+    final FutureCallback<MatMulOutput> callback = new 
FutureCallback<MatMulOutput>() {
+      @Override
+      public void onSuccess(final MatMulOutput output) {
+        final int index = output.getIndex();
+        final Matrix<Double> result = output.getResult();
+        // Compare the result from the original matrix.
+        if (result.equals(leftSplits.get(index))) {
+          latch.countDown();
+        } else {
+          throw new RuntimeException(index + " th result is not correct.");
+        }
+      }
+
+      @Override
+      public void onFailure(final Throwable t) {
+        throw new RuntimeException(t);
+      }
+    };
+
+    // Submit Tasklets and register callback.
+    final MatMulFunction matMulFunction = new MatMulFunction();
+    for (int i = 0; i < DIVIDE_FACTOR; i++) {
+      vortexThreadPool.submit(matMulFunction, new MatMulInput(i, 
leftSplits.get(i), right), callback);
+    }
+
+    try {
+      // Wait until all Tasklets finish.
+      latch.await();
+      LOG.log(Level.INFO, "Job Finish Time: " + (System.currentTimeMillis() - 
start));
+    } catch (final InterruptedException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  /**
+   * Generate a matrix with random values.
+   * @param numRows number of matrix's rows.
+   * @param numColumns number of matrix's columns.
+   * @return Matrix that consists of random values.
+   */
+  private Matrix<Double> generateRandomMatrix(final int numRows, final int 
numColumns) {
+    final List<List<Double>> rows = new ArrayList<>(numRows);
+    final Random random = new Random();
+    for (int i = 0; i < numRows; i++) {
+      final List<Double> row = new ArrayList<>(numColumns);
+      for (int j = 0; j < numColumns; j++) {
+        row.add(random.nextDouble());
+      }
+      rows.add(row);
+    }
+    return new RowMatrix(rows);
+  }
+
+  /**
+   * Generate an identity matrix.
+   * @param numDimension number of rows and columns of the identity matrix.
+   * @return Identity matrix.
+   */
+  private Matrix<Double> generateIdentityMatrix(final int numDimension) {
+    final List<List<Double>> rows = new ArrayList<>(numDimension);
+    for (int i = 0; i < numDimension; i++) {
+      final List<Double> row = new ArrayList<>(numDimension);
+      for (int j = 0; j < numDimension; j++) {
+        final double value = i == j ? 1 : 0;
+        row.add(value);
+      }
+      rows.add(row);
+    }
+    return new RowMatrix(rows);
+  }
+
+  /**
+   * Generate sub-matrices which splits a matrix as many as {@param 
divideFactor}.
+   * Note that the matrix is split in row-wise, so the number of columns 
remain same while
+   * the number of rows is divided by {@param divideFactor}.
+   * @param numRows Number of rows of the original Matrix.
+   * @param numColumns Number of columns of the original Matrix.
+   * @param divideFactor Number of partitions to split the matrix into.
+   * @return List of matrices divided into multiple sub-matrices.
+   */
+  private List<Matrix<Double>> generateMatrixSplits(final int numRows, final 
int numColumns, final int divideFactor) {
+    final List<Matrix<Double>> splits = new ArrayList<>(divideFactor);
+
+    int remainingNumSplits = divideFactor;
+    int remainingNumRows = numRows;
+    for (int i = 0; i < divideFactor; i++) {
+      final int splitNumRows = (remainingNumRows + remainingNumSplits - 1) / 
remainingNumSplits;
+      splits.add(generateRandomMatrix(splitNumRows, numColumns));
+
+      remainingNumRows -= splitNumRows;
+      remainingNumSplits--;
+    }
+    return splits;
+  }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/6983326a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMul.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMul.java
 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMul.java
new file mode 100644
index 0000000..a09bf59
--- /dev/null
+++ 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMul.java
@@ -0,0 +1,36 @@
+/*
+ * 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.reef.vortex.examples.matmul;
+
+import org.apache.reef.vortex.driver.VortexLauncher;
+
+/**
+ * User's main function.
+ */
+final class MatMul {
+  private MatMul() {
+  }
+
+  /**
+   * Launch the vortex job, passing appropriate arguments.
+   */
+  public static void main(final String[] args) {
+    VortexLauncher.launchLocal("Vortex_Example_MatMul", 
IdentityMatMulStart.class, 2, 1024, 4, 2000);
+  }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/6983326a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulException.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulException.java
 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulException.java
new file mode 100644
index 0000000..e07e977
--- /dev/null
+++ 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulException.java
@@ -0,0 +1,32 @@
+/*
+ * 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.reef.vortex.examples.matmul;
+
+/**
+ * Exception used in the MatMul example.
+ */
+class MatMulException extends Exception {
+  /**
+   * Constructor of MatMulException.
+   * @param message Message to inform users.
+   */
+  MatMulException(final String message) {
+    super(message);
+  }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/6983326a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulFunction.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulFunction.java
 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulFunction.java
new file mode 100644
index 0000000..2a2374a
--- /dev/null
+++ 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulFunction.java
@@ -0,0 +1,42 @@
+/*
+ * 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.reef.vortex.examples.matmul;
+
+import org.apache.reef.vortex.api.VortexFunction;
+
+/**
+ * Computes multiplication of two matrices.
+ */
+final class MatMulFunction implements VortexFunction<MatMulInput, 
MatMulOutput> {
+  /**
+   * Computes multiplication of two matrices.
+   * @param input Input which contains two matrices to multiply,
+   *              and index of the sub-matrix in the entire result.
+   * @return Output which contains the sub-matrix and index of it in the 
entire result.
+   * @throws Exception If the two matrices cannot be multiplied.
+   */
+  @Override
+  public MatMulOutput call(final MatMulInput input) throws Exception {
+    final int index = input.getIndex();
+    final Matrix<Double> leftMatrix = input.getLeftMatrix();
+    final Matrix<Double> rightMatrix = input.getRightMatrix();
+    final Matrix<Double> result = leftMatrix.multiply(rightMatrix);
+    return new MatMulOutput(index, result);
+  }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/6983326a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulInput.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulInput.java
 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulInput.java
new file mode 100644
index 0000000..86be004
--- /dev/null
+++ 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulInput.java
@@ -0,0 +1,64 @@
+/*
+ * 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.reef.vortex.examples.matmul;
+
+import java.io.Serializable;
+
+/**
+ * Input of {@link MatMulFunction} which contains two matrices to multiply,
+ * and index of the sub-matrix in the entire result.
+ */
+class MatMulInput implements Serializable {
+  private final int index;
+  private final Matrix<Double> leftMatrix;
+  private final Matrix<Double> rightMatrix;
+
+  /**
+   * Constructor of MatMulInput which consists of two matrices.
+   * @param index Index of the resulting sub-matrix in the entire matrix.
+   * @param leftMatrix Matrix to multiply on the left side.
+   * @param rightMatrix Matrix to multiply on the right side.
+   */
+  MatMulInput(final int index, final Matrix<Double> leftMatrix, final 
Matrix<Double> rightMatrix) {
+    this.index = index;
+    this.leftMatrix = leftMatrix;
+    this.rightMatrix = rightMatrix;
+  }
+
+  /**
+   * @return Index of the resulting sub-matrix in the entire matrix.
+   */
+  int getIndex() {
+    return index;
+  }
+
+  /**
+   * @return Matrix to multiply on the left side.
+   */
+  Matrix<Double> getLeftMatrix() {
+    return leftMatrix;
+  }
+
+  /**
+   * @return Matrix to multiply on the right side.
+   */
+  Matrix<Double> getRightMatrix() {
+    return rightMatrix;
+  }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/6983326a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulOutput.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulOutput.java
 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulOutput.java
new file mode 100644
index 0000000..42c118c
--- /dev/null
+++ 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/MatMulOutput.java
@@ -0,0 +1,53 @@
+/*
+ * 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.reef.vortex.examples.matmul;
+
+import java.io.Serializable;
+
+/**
+ * Output of {@link MatMulFunction} which contains the sub-matrix and index of 
it in the entire result.
+ */
+class MatMulOutput implements Serializable {
+  private final int index;
+  private final Matrix<Double> result;
+
+  /**
+   * Constructor of the output.
+   * @param index Index of the sub-matrix in the entire result.
+   * @param result Result of multiplication (sub-matrix).
+   */
+  MatMulOutput(final int index, final Matrix<Double> result) {
+    this.index = index;
+    this.result = result;
+  }
+
+  /**
+   * @return Index of the sub-matrix in the entire matrix.
+   */
+  int getIndex() {
+    return index;
+  }
+
+  /**
+   * @return Result of multiplication (sub-matrix).
+   */
+  Matrix<Double> getResult() {
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/6983326a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/Matrix.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/Matrix.java
 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/Matrix.java
new file mode 100644
index 0000000..0b1fe2e
--- /dev/null
+++ 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/Matrix.java
@@ -0,0 +1,68 @@
+/*
+ * 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.reef.vortex.examples.matmul;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Interface of serializable Matrix.
+ * @param <T> Type of elements in Matrix.
+ */
+interface Matrix<T> extends Serializable {
+
+  /**
+   * Add another matrix. Note that dimensions of two matrices should be 
identical.
+   * @param matrix Another matrix to add.
+   * @return Result of adding two matrices.
+   * @throws MatMulException
+   */
+  Matrix<T> add(Matrix<T> matrix) throws MatMulException;
+
+  /**
+   * Multiply another matrix on the right. Note that the number of {@param 
matrix}'s columns
+   * should be equal to the number of this matrix's rows.
+   * @param matrix Another matrix to multiply.
+   * @return Result of multiplying two matrices.
+   */
+  Matrix<T> multiply(Matrix<T> matrix) throws MatMulException;
+
+  /**
+   * Get the transpose of the matrix.
+   * @return Result of transpose.
+   */
+  Matrix<T> transpose();
+
+  /**
+   * Get the rows of the matrix. It is highly recommended to return {@link 
java.util.Collections.UnmodifiableList}
+   * for making the result immutable.
+   * @return Rows of the matrix.
+   */
+  List<List<T>> getRows();
+
+  /**
+   * @return Number of rows.
+   */
+  int getNumRows();
+
+  /**
+   * @return Number of columns.
+   */
+  int getNumColumns();
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/6983326a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/RowMatrix.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/RowMatrix.java
 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/RowMatrix.java
new file mode 100644
index 0000000..a0ca817
--- /dev/null
+++ 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/RowMatrix.java
@@ -0,0 +1,165 @@
+/*
+ * 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.reef.vortex.examples.matmul;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Row-oriented matrix implementation used in {@link MatMul} example.
+ */
+final class RowMatrix implements Matrix<Double> {
+  private final List<List<Double>> rows;
+
+  /**
+   * Constructor of matrix which creates an empty matrix of size (numRow x 
numColumn).
+   * @param rows Rows of the matrix.
+   */
+  RowMatrix(final List<List<Double>> rows) {
+    // Create a deep copy of the matrix to make it immutable to changes 
somewhere else.
+    this.rows = deepCopy(rows);
+  }
+
+  @Override
+  public Matrix<Double> add(final Matrix<Double> matrix) throws 
MatMulException {
+    if (this.getNumRows() != matrix.getNumRows() || this.getNumColumns() != 
matrix.getNumColumns()) {
+      throw new MatMulException("The dimension of two matrices should be same 
to add.");
+    }
+    final List<List<Double>> result = new ArrayList<>(getNumRows());
+    for (int i = 0; i < getNumRows(); i++) {
+      result.add(new ArrayList<Double>(matrix.getNumColumns()));
+    }
+
+    for (int i = 0; i < getNumRows(); i++) {
+      final List<Double> row1 = getRows().get(i);
+      final List<Double> row2 = matrix.getRows().get(i);
+      for (int j = 0; j < getNumColumns(); j++) {
+        result.get(i).add(row1.get(j) + row2.get(j));
+      }
+    }
+    return new RowMatrix(result);
+  }
+
+  @Override
+  public Matrix<Double> multiply(final Matrix<Double> matrix) throws 
MatMulException {
+    if (this.getNumColumns() != matrix.getNumRows()) {
+      throw new MatMulException("The number of columns of matrix to multiply 
should be same to the number of rows.");
+    }
+    final List<List<Double>> result = new ArrayList<>(getNumRows());
+    for (int i = 0; i < getNumRows(); i++) {
+      result.add(new ArrayList<Double>(matrix.getNumColumns()));
+    }
+
+    // result(i, j) = leftMatrix.row(i) * rightMatrix.col(j)
+    final Matrix<Double> transpose = matrix.transpose();
+    for (int i = 0; i < getNumRows(); i++) {
+      final List<Double> row = getRows().get(i);
+
+      for (int j = 0; j < getNumColumns(); j++) {
+        final List<Double> col = transpose.getRows().get(j);
+        result.get(i).add(dot(row, col));
+      }
+    }
+    return new RowMatrix(result);
+  }
+
+  @Override
+  public Matrix<Double> transpose() {
+    // Initialize empty vectors.
+    final ArrayList<List<Double>> transpose = new ArrayList<>(getNumColumns());
+    for (int i = 0; i < getNumRows(); i++) {
+      transpose.add(new ArrayList<Double>(getNumRows()));
+    }
+
+    // Each element in rows is added to corresponding column in transpose 
matrix.
+    for (final List<Double> row : getRows()) {
+      for (int i = 0; i < row.size(); i++) {
+        transpose.get(i).add(row.get(i));
+      }
+    }
+    return new RowMatrix(transpose);
+  }
+
+  @Override
+  public List<List<Double>> getRows() {
+    return Collections.unmodifiableList(rows);
+  }
+
+  @Override
+  public int getNumRows() {
+    return rows.size();
+  }
+
+  @Override
+  public int getNumColumns() {
+    return rows.get(0).size();
+  }
+
+  @Override
+  public boolean equals(final Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    RowMatrix rowMatrix = (RowMatrix) o;
+
+    return !(rows != null ? !rows.equals(rowMatrix.rows) : rowMatrix.rows != 
null);
+  }
+
+  @Override
+  public int hashCode() {
+    return rows != null ? rows.hashCode() : 0;
+  }
+
+   /**
+   * Create a deep copy to make the matrix immutable.
+   * @param original Original matrix.
+   * @return Deep copy of the matrix.
+   */
+  private List<List<Double>> deepCopy(final List<List<Double>> original) {
+    final List<List<Double>> result = new ArrayList<>(original.size());
+    for (final List<Double> originalRow : original) {
+      final List<Double> row = new ArrayList<>(originalRow.size());
+      for (final double element : originalRow) {
+        row.add(element);
+      }
+      result.add(row);
+    }
+    return result;
+  }
+
+  /**
+   * @return Inner product of two vectors.
+   */
+  private double dot(final List<Double> vector1, final List<Double> vector2) 
throws MatMulException {
+    if (vector1.size() != vector2.size()) {
+      throw new MatMulException("The dimension of vectors should be equal.");
+    }
+
+    double result = 0.0;
+    for (int i = 0; i < vector1.size(); i++) {
+      result += vector1.get(i) * vector2.get(i);
+    }
+    return result;
+  }
+}

http://git-wip-us.apache.org/repos/asf/reef/blob/6983326a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/package-info.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/package-info.java
 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/package-info.java
new file mode 100644
index 0000000..fc7832b
--- /dev/null
+++ 
b/lang/java/reef-applications/reef-vortex/src/main/java/org/apache/reef/vortex/examples/matmul/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+/**
+ * A Simple Vortex matrix multiplication example.
+ */
+package org.apache.reef.vortex.examples.matmul;

Reply via email to