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;
}