commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gilles <gil...@harfang.homelinux.org>
Subject Re: [1/2] [math] MATH-1250
Date Sun, 19 Jul 2015 19:05:05 GMT
Hi.

This is my first attempt at a backport.  Please check that I did
not mess anything...

Also, I must have missed something about how to do it (I've used
"cherry-pick", as James Ring suggested a few days ago) because I
didn't see that it was easier than copying and modifying files
"manually"...


Thanks,
Gilles


On Sun, 19 Jul 2015 18:56:43 -0000, erans@apache.org wrote:
> Repository: commons-math
> Updated Branches:
>   refs/heads/MATH_3_X 49b4bbd41 -> 1c4ebd5bd
>
>
> 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/895f50e6
> Tree: 
> http://git-wip-us.apache.org/repos/asf/commons-math/tree/895f50e6
> Diff: 
> http://git-wip-us.apache.org/repos/asf/commons-math/diff/895f50e6
>
> Branch: refs/heads/MATH_3_X
> Commit: 895f50e696f07942e6694f145f1d8e3d83c5ef84
> Parents: 49b4bbd
> Author: Gilles <erans@apache.org>
> Authored: Sun Jul 19 00:02:45 2015 +0200
> Committer: Gilles <erans@apache.org>
> Committed: Sun Jul 19 20:37:27 2015 +0200
>
> 
> ----------------------------------------------------------------------
>  src/changes/changes.xml                         |  7 +++
>  .../commons/math3/ml/neuralnet/Neuron.java      | 44 ++++++++++++++-
>  .../neuralnet/sofm/KohonenTrainingTaskTest.java | 21 ++++++-
>  .../sofm/TravellingSalesmanSolver.java          | 58 
> ++++++++++++++++----
>  4 files changed, 113 insertions(+), 17 deletions(-)
> 
> ----------------------------------------------------------------------
>
>
> 
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/895f50e6/src/changes/changes.xml
> 
> ----------------------------------------------------------------------
> diff --git a/src/changes/changes.xml b/src/changes/changes.xml
> index c5cdb11..3e6d4be 100644
> --- a/src/changes/changes.xml
> +++ b/src/changes/changes.xml
> @@ -51,6 +51,13 @@ If the output is not quite correct, check for
> invisible trailing spaces!
>    </properties>
>    <body>
>      <release version="3.6" 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>
>        <action dev="psteitz" type="fix" issue="MATH-1245">
>          Fixed error in computing discrete distribution of D
> statistics for small-sample
>          2-sample Kolmogorov-Smirnov tests. Error was causing
> incorrect p-values returned
>
> 
> http://git-wip-us.apache.org/repos/asf/commons-math/blob/895f50e6/src/main/java/org/apache/commons/math3/ml/neuralnet/Neuron.java
> 
> ----------------------------------------------------------------------
> diff --git
> a/src/main/java/org/apache/commons/math3/ml/neuralnet/Neuron.java
> b/src/main/java/org/apache/commons/math3/ml/neuralnet/Neuron.java
> index 51c533f..3fd0c0a 100644
> --- a/src/main/java/org/apache/commons/math3/ml/neuralnet/Neuron.java
> +++ b/src/main/java/org/apache/commons/math3/ml/neuralnet/Neuron.java
> @@ -20,8 +20,10 @@ package org.apache.commons.math3.ml.neuralnet;
>  import java.io.Serializable;
>  import java.io.ObjectInputStream;
>  import java.util.concurrent.atomic.AtomicReference;
> -import org.apache.commons.math3.util.Precision;
> +import java.util.concurrent.atomic.AtomicLong;
> +
>  import 
> org.apache.commons.math3.exception.DimensionMismatchException;
> +import org.apache.commons.math3.util.Precision;
>
>
>  /**
> @@ -40,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.
> @@ -129,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/895f50e6/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/KohonenTrainingTaskTest.java
> 
> ----------------------------------------------------------------------
> diff --git
> 
> a/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/KohonenTrainingTaskTest.java
> 
> b/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/KohonenTrainingTaskTest.java
> index d3f5628..218a709 100644
> ---
> 
> a/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/KohonenTrainingTaskTest.java
> +++
> 
> b/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/KohonenTrainingTaskTest.java
> @@ -30,6 +30,7 @@ import java.util.concurrent.Future;
>
>  import org.apache.commons.math3.Retry;
>  import org.apache.commons.math3.RetryRunner;
> +import 
> org.apache.commons.math3.ml.neuralnet.sofm.KohonenTrainingTask;
>  import org.apache.commons.math3.util.FastMath;
>  import org.junit.Assert;
>  import org.junit.Test;
> @@ -65,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,
> @@ -96,12 +102,16 @@ public class KohonenTrainingTaskTest {
>              new City("i0", 1, 1),
>          };
>
> -        final TravellingSalesmanSolver solver = new
> TravellingSalesmanSolver(squareOfCities, 2);
> +        // Seed that allows the unit test to always succeed.
> +        final long seed = 534712311L;
> +
> +        final TravellingSalesmanSolver solver = new
> TravellingSalesmanSolver(squareOfCities, 2, seed);
>          // printSummary("before.travel.par.dat", solver);
>
>          // 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) {
> @@ -116,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/895f50e6/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/TravellingSalesmanSolver.java
> 
> ----------------------------------------------------------------------
> diff --git
> 
> a/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/TravellingSalesmanSolver.java
> 
> b/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/TravellingSalesmanSolver.java
> index 369ea33..026d8bd 100644
> ---
> 
> a/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/TravellingSalesmanSolver.java
> +++
> 
> b/src/test/java/org/apache/commons/math3/ml/neuralnet/sofm/TravellingSalesmanSolver.java
> @@ -23,23 +23,30 @@ import java.util.Set;
>  import java.util.HashSet;
>  import java.util.Collection;
>  import java.util.Iterator;
> -import org.apache.commons.math3.ml.neuralnet.Neuron;
> -import org.apache.commons.math3.ml.neuralnet.Network;
> -import org.apache.commons.math3.ml.neuralnet.FeatureInitializer;
> -import 
> org.apache.commons.math3.ml.neuralnet.FeatureInitializerFactory;
> +
> +import org.apache.commons.math3.analysis.FunctionUtils;
> +import org.apache.commons.math3.analysis.UnivariateFunction;
> +import org.apache.commons.math3.analysis.function.Constant;
> +import 
> org.apache.commons.math3.analysis.function.HarmonicOscillator;
> +import org.apache.commons.math3.distribution.RealDistribution;
> +import 
> org.apache.commons.math3.distribution.UniformRealDistribution;
> +import 
> org.apache.commons.math3.exception.MathUnsupportedOperationException;
>  import org.apache.commons.math3.ml.distance.DistanceMeasure;
>  import org.apache.commons.math3.ml.distance.EuclideanDistance;
> +import org.apache.commons.math3.ml.neuralnet.FeatureInitializer;
> +import 
> org.apache.commons.math3.ml.neuralnet.FeatureInitializerFactory;
> +import org.apache.commons.math3.ml.neuralnet.Network;
> +import org.apache.commons.math3.ml.neuralnet.Neuron;
>  import org.apache.commons.math3.ml.neuralnet.oned.NeuronString;
> +import 
> org.apache.commons.math3.ml.neuralnet.sofm.KohonenTrainingTask;
> +import 
> org.apache.commons.math3.ml.neuralnet.sofm.KohonenUpdateAction;
> +import 
> org.apache.commons.math3.ml.neuralnet.sofm.LearningFactorFunction;
> +import
> 
> org.apache.commons.math3.ml.neuralnet.sofm.LearningFactorFunctionFactory;
> +import 
> org.apache.commons.math3.ml.neuralnet.sofm.NeighbourhoodSizeFunction;
> +import
> 
> org.apache.commons.math3.ml.neuralnet.sofm.NeighbourhoodSizeFunctionFactory;
>  import org.apache.commons.math3.random.RandomGenerator;
>  import org.apache.commons.math3.random.Well44497b;
> -import 
> org.apache.commons.math3.exception.MathUnsupportedOperationException;
>  import org.apache.commons.math3.util.FastMath;
> -import org.apache.commons.math3.analysis.UnivariateFunction;
> -import org.apache.commons.math3.analysis.FunctionUtils;
> -import 
> org.apache.commons.math3.analysis.function.HarmonicOscillator;
> -import org.apache.commons.math3.analysis.function.Constant;
> -import org.apache.commons.math3.distribution.RealDistribution;
> -import 
> org.apache.commons.math3.distribution.UniformRealDistribution;
>
>  /**
>   * Solves the "Travelling Salesman's Problem" (i.e. trying to find 
> the
> @@ -133,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.
>       *


Mime
View raw message