Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 308C81852A for ; Sat, 18 Jul 2015 22:11:20 +0000 (UTC) Received: (qmail 44673 invoked by uid 500); 18 Jul 2015 22:11:20 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 44600 invoked by uid 500); 18 Jul 2015 22:11:20 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 44591 invoked by uid 99); 18 Jul 2015 22:11:19 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 18 Jul 2015 22:11:19 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id D6C25E0260; Sat, 18 Jul 2015 22:11:19 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: erans@apache.org To: commits@commons.apache.org Date: Sat, 18 Jul 2015 22:11:19 -0000 Message-Id: <8a9405b4fd2c4b8a937b659ae3085426@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [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 Authored: Sun Jul 19 00:02:45 2015 +0200 Committer: Gilles 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! + + "Neuron" class (package "o.a.c.m.ml.neuralnet"): added methods that can be used + to assess concurrency performance. + Removed unnecessary allocations in "BigFraction" (package "o.a.c.m.fraction"). 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 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> execOutput = new ArrayList>(); // 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. *