You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2015/07/19 00:11:19 UTC

[1/2] [math] MATH-1250

Repository: commons-math
Updated Branches:
  refs/heads/master cf4416a84 -> 7a8a77833


MATH-1250

Methods to estimate concurrency performance.


Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/a7fe6138
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/a7fe6138
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/a7fe6138

Branch: refs/heads/master
Commit: a7fe613853516f0abde34821996a0424882bb919
Parents: cf4416a
Author: Gilles <er...@apache.org>
Authored: Sun Jul 19 00:02:45 2015 +0200
Committer: Gilles <er...@apache.org>
Committed: Sun Jul 19 00:02:45 2015 +0200

----------------------------------------------------------------------
 src/changes/changes.xml                         |  4 ++
 .../commons/math4/ml/neuralnet/Neuron.java      | 41 +++++++++++++++++++-
 .../neuralnet/sofm/KohonenTrainingTaskTest.java | 15 ++++++-
 .../sofm/TravellingSalesmanSolver.java          | 29 ++++++++++++++
 4 files changed, 85 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7fe6138/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index bbb67e7..042eb1c 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -54,6 +54,10 @@ If the output is not quite correct, check for invisible trailing spaces!
     </release>
 
     <release version="4.0" date="XXXX-XX-XX" description="">
+      <action dev="erans" type="add" issue="MATH-1250">
+        "Neuron" class (package "o.a.c.m.ml.neuralnet"): added methods that can be used
+        to assess concurrency performance.
+      </action>
       <action dev="erans" type="fix" issue="MATH-1248" due-to="Chris Popp">
         Removed unnecessary allocations in "BigFraction" (package "o.a.c.m.fraction").
       </action>

http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7fe6138/src/main/java/org/apache/commons/math4/ml/neuralnet/Neuron.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/ml/neuralnet/Neuron.java b/src/main/java/org/apache/commons/math4/ml/neuralnet/Neuron.java
index 0f58b3a..eee8151 100644
--- a/src/main/java/org/apache/commons/math4/ml/neuralnet/Neuron.java
+++ b/src/main/java/org/apache/commons/math4/ml/neuralnet/Neuron.java
@@ -20,6 +20,7 @@ package org.apache.commons.math4.ml.neuralnet;
 import java.io.Serializable;
 import java.io.ObjectInputStream;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.commons.math4.exception.DimensionMismatchException;
 import org.apache.commons.math4.util.Precision;
@@ -41,6 +42,10 @@ public class Neuron implements Serializable {
     private final int size;
     /** Neuron data. */
     private final AtomicReference<double[]> features;
+    /** Number of attempts to update a neuron. */
+    private final AtomicLong numberOfAttemptedUpdates = new AtomicLong(0);
+    /** Number of successful updates  of a neuron. */
+    private final AtomicLong numberOfSuccessfulUpdates = new AtomicLong(0);
 
     /**
      * Creates a neuron.
@@ -130,16 +135,48 @@ public class Neuron implements Serializable {
             return false;
         }
 
+        // Increment attempt counter.
+        numberOfAttemptedUpdates.incrementAndGet();
+
         if (features.compareAndSet(current, update.clone())) {
-            // The current thread could atomically update the state.
+            // The current thread could atomically update the state (attempt succeeded).
+            numberOfSuccessfulUpdates.incrementAndGet();
             return true;
         } else {
-            // Some other thread came first.
+            // Some other thread came first (attempt failed).
             return false;
         }
     }
 
     /**
+     * Retrieves the number of calls to the
+     * {@link #compareAndSetFeatures(double[],double[]) compareAndSetFeatures}
+     * method.
+     * Note that if the caller wants to use this method in combination with
+     * {@link #getNumberOfSuccessfulUpdates()}, additional synchronization
+     * may be required to ensure consistency.
+     *
+     * @return the number of update attempts.
+     */
+    public long getNumberOfAttemptedUpdates() {
+        return numberOfAttemptedUpdates.get();
+    }
+
+    /**
+     * Retrieves the number of successful calls to the
+     * {@link #compareAndSetFeatures(double[],double[]) compareAndSetFeatures}
+     * method.
+     * Note that if the caller wants to use this method in combination with
+     * {@link #getNumberOfAttemptedUpdates()}, additional synchronization
+     * may be required to ensure consistency.
+     *
+     * @return the number of successful updates.
+     */
+    public long getNumberOfSuccessfulUpdates() {
+        return numberOfSuccessfulUpdates.get();
+    }
+
+    /**
      * Checks whether the contents of both arrays is the same.
      *
      * @param current Current values.

http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7fe6138/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenTrainingTaskTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenTrainingTaskTest.java b/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenTrainingTaskTest.java
index 0ae33a7..0bd4d2a 100644
--- a/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenTrainingTaskTest.java
+++ b/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenTrainingTaskTest.java
@@ -66,7 +66,12 @@ public class KohonenTrainingTaskTest {
 
         final TravellingSalesmanSolver solver = new TravellingSalesmanSolver(squareOfCities, 2, seed);
         // printSummary("before.travel.seq.dat", solver);
-        solver.createSequentialTask(15000).run();
+        final Runnable task = solver.createSequentialTask(15000);
+        task.run();
+
+        // All update attempts must be successful in the absence of concurrency.
+        Assert.assertEquals(solver.getUpdateRatio(), 1, 0d);
+
         // printSummary("after.travel.seq.dat", solver);
         final City[] result = solver.getCityList();
         Assert.assertEquals(squareOfCities.length,
@@ -105,7 +110,8 @@ public class KohonenTrainingTaskTest {
 
         // Parallel execution.
         final ExecutorService service = Executors.newCachedThreadPool();
-        final Runnable[] tasks = solver.createParallelTasks(3, 5000);
+        final int numProcs = Runtime.getRuntime().availableProcessors();
+        final Runnable[] tasks = solver.createParallelTasks(numProcs, 5000);
         final List<Future<?>> execOutput = new ArrayList<Future<?>>();
         // Run tasks.
         for (Runnable r : tasks) {
@@ -120,6 +126,11 @@ public class KohonenTrainingTaskTest {
         // Terminate all threads.
         service.shutdown();
 
+        if (numProcs > 1) {
+            // We expect that some update attempts will be concurrent.
+            Assert.assertTrue(solver.getUpdateRatio() < 1);
+        }
+
         // printSummary("after.travel.par.dat", solver);
         final City[] result = solver.getCityList();
         Assert.assertEquals(squareOfCities.length,

http://git-wip-us.apache.org/repos/asf/commons-math/blob/a7fe6138/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/TravellingSalesmanSolver.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/TravellingSalesmanSolver.java b/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/TravellingSalesmanSolver.java
index 6fe215d..f11329c 100644
--- a/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/TravellingSalesmanSolver.java
+++ b/src/test/java/org/apache/commons/math4/ml/neuralnet/sofm/TravellingSalesmanSolver.java
@@ -140,6 +140,35 @@ public class TravellingSalesmanSolver {
     }
 
     /**
+     * Measures the network's concurrent update performance.
+     *
+     * @return the ratio between the number of succesful network updates
+     * and the number of update attempts.
+     */
+    public double getUpdateRatio() {
+        return computeUpdateRatio(net);
+    }
+
+    /**
+     * Measures the network's concurrent update performance.
+     *
+     * @param net Network to be trained with the SOFM algorithm.
+     * @return the ratio between the number of successful network updates
+     * and the number of update attempts.
+     */
+    private static double computeUpdateRatio(Network net) {
+        long numAttempts = 0;
+        long numSuccesses = 0;
+
+        for (Neuron n : net) {
+            numAttempts += n.getNumberOfAttemptedUpdates();
+            numSuccesses += n.getNumberOfSuccessfulUpdates();
+        }
+
+        return (double) numSuccesses / (double) numAttempts;
+    }
+
+    /**
      * Creates an iterator that will present a series of city's coordinates in
      * a random order.
      *


[2/2] [math] New private method for factoring out some common code.

Posted by er...@apache.org.
New private method for factoring out some common code.


Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/7a8a7783
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/7a8a7783
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/7a8a7783

Branch: refs/heads/master
Commit: 7a8a7783315917b56b6a71c4f28cec4ed1d91a7f
Parents: a7fe613
Author: Gilles <er...@apache.org>
Authored: Sun Jul 19 00:07:03 2015 +0200
Committer: Gilles <er...@apache.org>
Committed: Sun Jul 19 00:07:03 2015 +0200

----------------------------------------------------------------------
 .../ml/neuralnet/sofm/KohonenUpdateAction.java  | 32 ++++++++++++++------
 1 file changed, 22 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a8a7783/src/main/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenUpdateAction.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenUpdateAction.java b/src/main/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenUpdateAction.java
index ffe6943..b937291 100644
--- a/src/main/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenUpdateAction.java
+++ b/src/main/java/org/apache/commons/math4/ml/neuralnet/sofm/KohonenUpdateAction.java
@@ -146,6 +146,26 @@ public class KohonenUpdateAction implements UpdateAction {
     }
 
     /**
+     * Tries to update a neuron.
+     *
+     * @param n Neuron to be updated.
+     * @param features Training data.
+     * @param learningRate Learning factor.
+     * @return {@code true} if the update succeeded, {@code true} if a
+     * concurrent update has been detected.
+     */
+    private boolean attemptNeuronUpdate(Neuron n,
+                                        double[] features,
+                                        double learningRate) {
+        final double[] expect = n.getFeatures();
+        final double[] update = computeFeatures(expect,
+                                                features,
+                                                learningRate);
+
+        return n.compareAndSetFeatures(expect, update);
+    }
+
+    /**
      * Atomically updates the given neuron.
      *
      * @param n Neuron to be updated.
@@ -156,11 +176,7 @@ public class KohonenUpdateAction implements UpdateAction {
                                           double[] features,
                                           double learningRate) {
         while (true) {
-            final double[] expect = n.getFeatures();
-            final double[] update = computeFeatures(expect,
-                                                    features,
-                                                    learningRate);
-            if (n.compareAndSetFeatures(expect, update)) {
+            if (attemptNeuronUpdate(n, features, learningRate)) {
                 break;
             }
         }
@@ -181,11 +197,7 @@ public class KohonenUpdateAction implements UpdateAction {
         while (true) {
             final Neuron best = MapUtils.findBest(features, net, distance);
 
-            final double[] expect = best.getFeatures();
-            final double[] update = computeFeatures(expect,
-                                                    features,
-                                                    learningRate);
-            if (best.compareAndSetFeatures(expect, update)) {
+            if (attemptNeuronUpdate(best, features, learningRate)) {
                 return best;
             }