From a95529f6e48e543f6b7b0ac2ef6345b6cc3f4039 Mon Sep 17 00:00:00 2001 From: Thomas Ibel Date: Mon, 24 Feb 2014 20:24:13 +0100 Subject: [PATCH 1/7] create Partitioner for NET35 --- src/Numerics/Compatibility.cs | 50 ++++++++++++++++++++++++ src/Numerics/Threading/CommonParallel.cs | 16 +++++--- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/Numerics/Compatibility.cs b/src/Numerics/Compatibility.cs index 0f605d90..5a8ef9e1 100644 --- a/src/Numerics/Compatibility.cs +++ b/src/Numerics/Compatibility.cs @@ -37,6 +37,7 @@ namespace MathNet.Numerics namespace MathNet.Numerics { using System; + using System.Collections.Concurrent; using System.Collections.Generic; internal static class ObjectComparer @@ -130,5 +131,54 @@ namespace MathNet.Numerics } } } + + internal static class Partitioner + { + public static OrderablePartitioner> Create(int fromInclusive, int toExclusive) + { + var rangeSize = Math.Max(1, (toExclusive - fromInclusive) / Control.NumberOfParallelWorkerThreads); + return Create(fromInclusive, toExclusive, rangeSize); + } + + public static OrderablePartitioner> Create(int fromInclusive, int toExclusive, int rangeSize) + { + if (toExclusive <= fromInclusive) + { + throw new ArgumentOutOfRangeException("toExclusive"); + } + if (rangeSize <= 0) + { + throw new ArgumentOutOfRangeException("rangeSize"); + } + + return System.Collections.Concurrent.Partitioner.Create(CreateRanges(fromInclusive, toExclusive, rangeSize)); + } + + private static IEnumerable> CreateRanges(int fromInclusive, int toExclusive, int rangeSize) + { + bool flag = false; + int num = fromInclusive; + while (num < toExclusive && !flag) + { + int item = num; + int num2; + try + { + num2 = checked(num + rangeSize); + } + catch (OverflowException) + { + num2 = toExclusive; + flag = true; + } + if (num2 > toExclusive) + { + num2 = toExclusive; + } + yield return new Tuple(item, num2); + num += rangeSize; + } + } + } } #endif diff --git a/src/Numerics/Threading/CommonParallel.cs b/src/Numerics/Threading/CommonParallel.cs index fabb548b..b7ccd152 100644 --- a/src/Numerics/Threading/CommonParallel.cs +++ b/src/Numerics/Threading/CommonParallel.cs @@ -31,14 +31,18 @@ namespace MathNet.Numerics.Threading { using System; + using System.Collections.Generic; using System.Threading.Tasks; -#if (PORTABLE || NET35) +#if NET35 + using Partitioner = MathNet.Numerics.Partitioner; +#endif + +#if PORTABLE using System.Linq; using Properties; #else using System.Collections.Concurrent; - using System.Collections.Generic; #endif /// @@ -88,7 +92,7 @@ namespace MathNet.Numerics.Threading return; } -#if (PORTABLE || NET35) +#if PORTABLE var tasks = new Task[Math.Min(maxDegreeOfParallelism, length/rangeSize)]; rangeSize = (toExclusive - fromInclusive)/tasks.Length; @@ -146,7 +150,7 @@ namespace MathNet.Numerics.Threading } // Common case -#if (PORTABLE || NET35) +#if PORTABLE var tasks = new Task[actions.Length]; for (var i = 0; i < tasks.Length; i++) { @@ -211,7 +215,7 @@ namespace MathNet.Numerics.Threading return reduce(mapped); } -#if (PORTABLE || NET35) +#if PORTABLE var tasks = new Task[Control.NumberOfParallelWorkerThreads]; var size = (toExclusive - fromInclusive) / tasks.Length; @@ -317,7 +321,7 @@ namespace MathNet.Numerics.Threading return reduce(mapped); } -#if (PORTABLE || NET35) +#if PORTABLE var tasks = new Task[Control.NumberOfParallelWorkerThreads]; var size = array.Length / tasks.Length; From 8eafbcb88c47bbf01a63b7bbf49fc85bee5e4de7 Mon Sep 17 00:00:00 2001 From: Thomas Ibel Date: Mon, 24 Feb 2014 21:40:40 +0100 Subject: [PATCH 2/7] build Parallel class for portable --- src/Numerics/Compatibility.cs | 133 +++++++++++++++++++++++ src/Numerics/Threading/CommonParallel.cs | 121 +-------------------- 2 files changed, 138 insertions(+), 116 deletions(-) diff --git a/src/Numerics/Compatibility.cs b/src/Numerics/Compatibility.cs index 5a8ef9e1..c18e5b0b 100644 --- a/src/Numerics/Compatibility.cs +++ b/src/Numerics/Compatibility.cs @@ -2,6 +2,10 @@ namespace MathNet.Numerics { using System; + using System.Threading; + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] public class SerializableAttribute : Attribute @@ -12,6 +16,135 @@ namespace MathNet.Numerics public class SpecialNameAttribute : Attribute { } + + internal static class Partitioner + { + public static IEnumerable> Create(int fromInclusive, int toExclusive) + { + var rangeSize = Math.Max(1, (toExclusive - fromInclusive) / Control.NumberOfParallelWorkerThreads); + return Create(fromInclusive, toExclusive, rangeSize); + } + + public static IEnumerable> Create(int fromInclusive, int toExclusive, int rangeSize) + { + if (toExclusive <= fromInclusive) + { + throw new ArgumentOutOfRangeException("toExclusive"); + } + if (rangeSize <= 0) + { + throw new ArgumentOutOfRangeException("rangeSize"); + } + + return CreateRanges(fromInclusive, toExclusive, rangeSize); + } + + private static IEnumerable> CreateRanges(int fromInclusive, int toExclusive, int rangeSize) + { + bool flag = false; + int num = fromInclusive; + while (num < toExclusive && !flag) + { + int item = num; + int num2; + try + { + num2 = checked(num + rangeSize); + } + catch (OverflowException) + { + num2 = toExclusive; + flag = true; + } + if (num2 > toExclusive) + { + num2 = toExclusive; + } + yield return new Tuple(item, num2); + num += rangeSize; + } + } + } + + internal class ParallelOptions + { + public TaskScheduler TaskScheduler { get; set; } + public int MaxDegreeOfParallelism { get; set; } + public CancellationToken CancellationToken { get; set; } + + public ParallelOptions() + { + TaskScheduler = TaskScheduler.Default; + MaxDegreeOfParallelism = -1; + CancellationToken = CancellationToken.None; + } + } + + internal class ParallelLoopState + { + } + + internal static class Parallel + { + public static void ForEach(IEnumerable source, ParallelOptions parallelOptions, Action body) + { + var chunks = source.ToArray(); + var tasks = new Task[chunks.Length]; + + for (var i = 0; i < tasks.Length; i++) + { + var chunk = chunks[i]; + tasks[i] = Task.Factory.StartNew(() => body(chunk), parallelOptions.CancellationToken, TaskCreationOptions.None, parallelOptions.TaskScheduler); + } + + Task.WaitAll(tasks, parallelOptions.CancellationToken); + } + + public static void Invoke(ParallelOptions parallelOptions, params Action[] actions) + { + var tasks = new Task[actions.Length]; + + for (var i = 0; i < tasks.Length; i++) + { + var action = actions[i]; + if (action == null) + { + throw new ArgumentException(String.Format(Properties.Resources.ArgumentItemNull, "actions"), "actions"); + } + + tasks[i] = Task.Factory.StartNew(action, parallelOptions.CancellationToken, TaskCreationOptions.None, parallelOptions.TaskScheduler); + } + + Task.WaitAll(tasks); + } + + public static void ForEach( + IEnumerable source, + ParallelOptions parallelOptions, + Func localInit, + Func body, + Action localFinally) + { + var chunks = source.ToArray(); + var tasks = new Task[chunks.Length]; + var loopState = new ParallelLoopState(); + + for (var i = 0; i < tasks.Length; i++) + { + var chunk = chunks[i]; + + tasks[i] = Task.Factory.StartNew(() => + { + var local = localInit(); + local = body(chunk, loopState, local); + localFinally(local); + return local; + }, parallelOptions.CancellationToken, TaskCreationOptions.None, parallelOptions.TaskScheduler); + } + + Task.WaitAll(tasks, parallelOptions.CancellationToken); + } + } } #endif diff --git a/src/Numerics/Threading/CommonParallel.cs b/src/Numerics/Threading/CommonParallel.cs index b7ccd152..50cf31aa 100644 --- a/src/Numerics/Threading/CommonParallel.cs +++ b/src/Numerics/Threading/CommonParallel.cs @@ -38,10 +38,7 @@ namespace MathNet.Numerics.Threading using Partitioner = MathNet.Numerics.Partitioner; #endif -#if PORTABLE - using System.Linq; - using Properties; -#else +#if !PORTABLE using System.Collections.Concurrent; #endif @@ -92,30 +89,11 @@ namespace MathNet.Numerics.Threading return; } -#if PORTABLE - var tasks = new Task[Math.Min(maxDegreeOfParallelism, length/rangeSize)]; - rangeSize = (toExclusive - fromInclusive)/tasks.Length; - - // partition the jobs into separate sets for each but the last worked thread - for (var i = 0; i < tasks.Length - 1; i++) - { - var start = fromInclusive + (i*rangeSize); - var stop = fromInclusive + ((i + 1)*rangeSize); - - tasks[i] = Task.Factory.StartNew(() => body(start, stop)); - } - - // add another set for last worker thread - tasks[tasks.Length - 1] = - Task.Factory.StartNew(() => body(fromInclusive + ((tasks.Length - 1)*rangeSize), toExclusive)); - - Task.WaitAll(tasks); -#else + // Common case Parallel.ForEach( Partitioner.Create(fromInclusive, toExclusive, rangeSize), new ParallelOptions {MaxDegreeOfParallelism = maxDegreeOfParallelism}, - (range, loopState) => body(range.Item1, range.Item2)); -#endif + range => body(range.Item1, range.Item2)); } /// @@ -150,27 +128,12 @@ namespace MathNet.Numerics.Threading } // Common case -#if PORTABLE - var tasks = new Task[actions.Length]; - for (var i = 0; i < tasks.Length; i++) - { - Action action = actions[i]; - if (action == null) - { - throw new ArgumentException(String.Format(Resources.ArgumentItemNull, "actions"), "actions"); - } - - tasks[i] = Task.Factory.StartNew(action); - } - Task.WaitAll(tasks); -#else Parallel.Invoke( new ParallelOptions { MaxDegreeOfParallelism = Control.NumberOfParallelWorkerThreads }, actions); -#endif } /// @@ -215,43 +178,7 @@ namespace MathNet.Numerics.Threading return reduce(mapped); } -#if PORTABLE - var tasks = new Task[Control.NumberOfParallelWorkerThreads]; - var size = (toExclusive - fromInclusive) / tasks.Length; - - // partition the jobs into separate sets for each but the last worked thread - for (var i = 0; i < tasks.Length - 1; i++) - { - var start = fromInclusive + (i * size); - var stop = fromInclusive + ((i + 1) * size); - - tasks[i] = Task.Factory.StartNew(() => - { - var mapped = new T[stop - start]; - for (int k = 0; k < mapped.Length; k++) - { - mapped[k] = select(k + start); - } - return reduce(mapped); - }); - } - - // add another set for last worker thread - tasks[tasks.Length - 1] = Task.Factory.StartNew(() => - { - var start = fromInclusive + ((tasks.Length - 1) * size); - var mapped = new T[toExclusive - start]; - for (int k = 0; k < mapped.Length; k++) - { - mapped[k] = select(k + start); - } - return reduce(mapped); - }); - - return Task.Factory - .ContinueWhenAll(tasks, tsk => reduce(tsk.Select(t => t.Result).ToArray())) - .Result; -#else + // Common case var intermediateResults = new List(); var syncLock = new object(); var maxThreads = Control.DisableParallelization ? 1 : Control.NumberOfParallelWorkerThreads; @@ -277,7 +204,6 @@ namespace MathNet.Numerics.Threading } }); return reduce(intermediateResults.ToArray()); -#endif } /// @@ -321,43 +247,7 @@ namespace MathNet.Numerics.Threading return reduce(mapped); } -#if PORTABLE - var tasks = new Task[Control.NumberOfParallelWorkerThreads]; - var size = array.Length / tasks.Length; - - // partition the jobs into separate sets for each but the last worked thread - for (var i = 0; i < tasks.Length - 1; i++) - { - var start = (i * size); - var stop = ((i + 1) * size); - - tasks[i] = Task.Factory.StartNew(() => - { - var mapped = new TOut[stop - start]; - for (int k = 0; k < mapped.Length; k++) - { - mapped[k] = select(k + start, array[k + start]); - } - return reduce(mapped); - }); - } - - // add another set for last worker thread - tasks[tasks.Length - 1] = Task.Factory.StartNew(() => - { - var start = ((tasks.Length - 1) * size); - var mapped = new TOut[array.Length - start]; - for (int k = 0; k < mapped.Length; k++) - { - mapped[k] = select(k + start, array[k + start]); - } - return reduce(mapped); - }); - - return Task.Factory - .ContinueWhenAll(tasks, tsk => reduce(tsk.Select(t => t.Result).ToArray())) - .Result; -#else + // Common case var intermediateResults = new List(); var syncLock = new object(); var maxThreads = Control.DisableParallelization ? 1 : Control.NumberOfParallelWorkerThreads; @@ -383,7 +273,6 @@ namespace MathNet.Numerics.Threading } }); return reduce(intermediateResults.ToArray()); -#endif } /// From bec32e2a0290b3ec8f9ac8e000d2696807204cad Mon Sep 17 00:00:00 2001 From: Thomas Ibel Date: Tue, 25 Feb 2014 00:07:28 +0100 Subject: [PATCH 3/7] small fixes in portable Parallel implementation --- src/Numerics/Compatibility.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Numerics/Compatibility.cs b/src/Numerics/Compatibility.cs index c18e5b0b..122e7e00 100644 --- a/src/Numerics/Compatibility.cs +++ b/src/Numerics/Compatibility.cs @@ -115,7 +115,7 @@ namespace MathNet.Numerics tasks[i] = Task.Factory.StartNew(action, parallelOptions.CancellationToken, TaskCreationOptions.None, parallelOptions.TaskScheduler); } - Task.WaitAll(tasks); + Task.WaitAll(tasks, parallelOptions.CancellationToken); } public static void ForEach( @@ -132,13 +132,11 @@ namespace MathNet.Numerics for (var i = 0; i < tasks.Length; i++) { var chunk = chunks[i]; - tasks[i] = Task.Factory.StartNew(() => { var local = localInit(); local = body(chunk, loopState, local); localFinally(local); - return local; }, parallelOptions.CancellationToken, TaskCreationOptions.None, parallelOptions.TaskScheduler); } From 960574053c4ec92bf82e61e7ac48c09ed9413ed0 Mon Sep 17 00:00:00 2001 From: tibel Date: Tue, 25 Feb 2014 16:26:06 +0100 Subject: [PATCH 4/7] add CreateParallelOptions to show how to set the TaskScheduler --- src/Numerics/Compatibility.cs | 22 +++--------- src/Numerics/Threading/CommonParallel.cs | 46 ++++++++++-------------- 2 files changed, 22 insertions(+), 46 deletions(-) diff --git a/src/Numerics/Compatibility.cs b/src/Numerics/Compatibility.cs index 122e7e00..4499bde4 100644 --- a/src/Numerics/Compatibility.cs +++ b/src/Numerics/Compatibility.cs @@ -27,15 +27,8 @@ namespace MathNet.Numerics public static IEnumerable> Create(int fromInclusive, int toExclusive, int rangeSize) { - if (toExclusive <= fromInclusive) - { - throw new ArgumentOutOfRangeException("toExclusive"); - } - if (rangeSize <= 0) - { - throw new ArgumentOutOfRangeException("rangeSize"); - } - + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); + if (rangeSize <= 0) throw new ArgumentOutOfRangeException("rangeSize"); return CreateRanges(fromInclusive, toExclusive, rangeSize); } @@ -273,15 +266,8 @@ namespace MathNet.Numerics public static OrderablePartitioner> Create(int fromInclusive, int toExclusive, int rangeSize) { - if (toExclusive <= fromInclusive) - { - throw new ArgumentOutOfRangeException("toExclusive"); - } - if (rangeSize <= 0) - { - throw new ArgumentOutOfRangeException("rangeSize"); - } - + if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive"); + if (rangeSize <= 0) throw new ArgumentOutOfRangeException("rangeSize"); return System.Collections.Concurrent.Partitioner.Create(CreateRanges(fromInclusive, toExclusive, rangeSize)); } diff --git a/src/Numerics/Threading/CommonParallel.cs b/src/Numerics/Threading/CommonParallel.cs index 50cf31aa..f98575cf 100644 --- a/src/Numerics/Threading/CommonParallel.cs +++ b/src/Numerics/Threading/CommonParallel.cs @@ -47,6 +47,15 @@ namespace MathNet.Numerics.Threading /// public static class CommonParallel { + private static ParallelOptions CreateParallelOptions() + { + return new ParallelOptions + { + MaxDegreeOfParallelism = Control.NumberOfParallelWorkerThreads, + //TaskScheduler = Control.TaskScheduler, + }; + } + /// /// Executes a for loop in which iterations may run in parallel. /// @@ -80,10 +89,8 @@ namespace MathNet.Numerics.Threading return; } - var maxDegreeOfParallelism = Control.NumberOfParallelWorkerThreads; - // Special case: not worth to parallelize, inline - if (Control.DisableParallelization || maxDegreeOfParallelism < 2 || (rangeSize*2) > length) + if (Control.DisableParallelization || Control.NumberOfParallelWorkerThreads < 2 || (rangeSize * 2) > length) { body(fromInclusive, toExclusive); return; @@ -92,7 +99,7 @@ namespace MathNet.Numerics.Threading // Common case Parallel.ForEach( Partitioner.Create(fromInclusive, toExclusive, rangeSize), - new ParallelOptions {MaxDegreeOfParallelism = maxDegreeOfParallelism}, + CreateParallelOptions(), range => body(range.Item1, range.Item2)); } @@ -129,10 +136,7 @@ namespace MathNet.Numerics.Threading // Common case Parallel.Invoke( - new ParallelOptions - { - MaxDegreeOfParallelism = Control.NumberOfParallelWorkerThreads - }, + CreateParallelOptions(), actions); } @@ -146,14 +150,8 @@ namespace MathNet.Numerics.Threading /// The selected value. public static T Aggregate(int fromInclusive, int toExclusive, Func select, Func reduce) { - if (select == null) - { - throw new ArgumentNullException("select"); - } - if (reduce == null) - { - throw new ArgumentNullException("reduce"); - } + if (select == null) throw new ArgumentNullException("select"); + if (reduce == null) throw new ArgumentNullException("reduce"); // Special case: no action if (fromInclusive >= toExclusive) @@ -181,10 +179,9 @@ namespace MathNet.Numerics.Threading // Common case var intermediateResults = new List(); var syncLock = new object(); - var maxThreads = Control.DisableParallelization ? 1 : Control.NumberOfParallelWorkerThreads; Parallel.ForEach( Partitioner.Create(fromInclusive, toExclusive), - new ParallelOptions {MaxDegreeOfParallelism = maxThreads}, + CreateParallelOptions(), () => new List(), (range, loop, localData) => { @@ -215,14 +212,8 @@ namespace MathNet.Numerics.Threading /// The selected value. public static TOut Aggregate(T[] array, Func select, Func reduce) { - if (select == null) - { - throw new ArgumentNullException("select"); - } - if (reduce == null) - { - throw new ArgumentNullException("reduce"); - } + if (select == null) throw new ArgumentNullException("select"); + if (reduce == null) throw new ArgumentNullException("reduce"); // Special case: no action if (array == null || array.Length == 0) @@ -250,10 +241,9 @@ namespace MathNet.Numerics.Threading // Common case var intermediateResults = new List(); var syncLock = new object(); - var maxThreads = Control.DisableParallelization ? 1 : Control.NumberOfParallelWorkerThreads; Parallel.ForEach( Partitioner.Create(0, array.Length), - new ParallelOptions {MaxDegreeOfParallelism = maxThreads}, + CreateParallelOptions(), () => new List(), (range, loop, localData) => { From 8f0a48354ca4aef9d320ff279bc2554f56fc1209 Mon Sep 17 00:00:00 2001 From: Thomas Ibel Date: Tue, 25 Feb 2014 18:35:07 +0100 Subject: [PATCH 5/7] remove Control.DisableParallelization --- src/Numerics/Control.cs | 9 +-------- src/Numerics/Threading/CommonParallel.cs | 8 ++++---- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs index edecd791..54073258 100644 --- a/src/Numerics/Control.cs +++ b/src/Numerics/Control.cs @@ -61,7 +61,6 @@ namespace MathNet.Numerics // Parallelization & Threading _numberOfThreads = Environment.ProcessorCount; - DisableParallelization = _numberOfThreads < 2; _blockSize = 512; _parallelizeOrder = 64; _parallelizeElements = 300; @@ -93,7 +92,6 @@ namespace MathNet.Numerics public static void UseSingleThread() { _numberOfThreads = 1; - DisableParallelization = true; ThreadSafeRandomNumberGenerators = false; } @@ -125,11 +123,6 @@ namespace MathNet.Numerics /// public static bool ThreadSafeRandomNumberGenerators { get; set; } - /// - /// Gets or sets a value indicating whether parallelization shall be disabled globally. - /// - public static bool DisableParallelization { get; set; } - /// /// Gets or sets the linear algebra provider. Consider to use UseNativeMKL or UseManaged instead. /// @@ -197,7 +190,7 @@ namespace MathNet.Numerics /// true if the operation should be parallelized; false otherwise. public static bool ParallelizeOperation(int elements) { - return !DisableParallelization && NumberOfParallelWorkerThreads >= 2 && elements >= ParallelizeElements; + return NumberOfParallelWorkerThreads >= 2 && elements >= ParallelizeElements; } /// diff --git a/src/Numerics/Threading/CommonParallel.cs b/src/Numerics/Threading/CommonParallel.cs index f98575cf..d8c12729 100644 --- a/src/Numerics/Threading/CommonParallel.cs +++ b/src/Numerics/Threading/CommonParallel.cs @@ -90,7 +90,7 @@ namespace MathNet.Numerics.Threading } // Special case: not worth to parallelize, inline - if (Control.DisableParallelization || Control.NumberOfParallelWorkerThreads < 2 || (rangeSize * 2) > length) + if (Control.NumberOfParallelWorkerThreads < 2 || (rangeSize * 2) > length) { body(fromInclusive, toExclusive); return; @@ -125,7 +125,7 @@ namespace MathNet.Numerics.Threading } // Special case: straight execution without parallelism - if (Control.DisableParallelization || Control.NumberOfParallelWorkerThreads < 2) + if (Control.NumberOfParallelWorkerThreads < 2) { for (int i = 0; i < actions.Length; i++) { @@ -166,7 +166,7 @@ namespace MathNet.Numerics.Threading } // Special case: straight execution without parallelism - if (Control.DisableParallelization || Control.NumberOfParallelWorkerThreads < 2) + if (Control.NumberOfParallelWorkerThreads < 2) { var mapped = new T[toExclusive - fromInclusive]; for (int k = 0; k < mapped.Length; k++) @@ -228,7 +228,7 @@ namespace MathNet.Numerics.Threading } // Special case: straight execution without parallelism - if (Control.DisableParallelization || Control.NumberOfParallelWorkerThreads < 2) + if (Control.NumberOfParallelWorkerThreads < 2) { var mapped = new TOut[array.Length]; for (int k = 0; k < mapped.Length; k++) From 0da254f1cce389ac670099e9724618eb9ab12a86 Mon Sep 17 00:00:00 2001 From: Thomas Ibel Date: Tue, 25 Feb 2014 18:45:54 +0100 Subject: [PATCH 6/7] remove Control.ParallelizeOperation() --- src/Numerics/Control.cs | 10 -- .../ManagedLinearAlgebraProvider.Complex.cs | 144 ++++-------------- .../ManagedLinearAlgebraProvider.Complex32.cs | 144 ++++-------------- .../ManagedLinearAlgebraProvider.Double.cs | 126 ++++----------- .../ManagedLinearAlgebraProvider.Single.cs | 126 ++++----------- 5 files changed, 120 insertions(+), 430 deletions(-) diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs index 54073258..52dc2f8b 100644 --- a/src/Numerics/Control.cs +++ b/src/Numerics/Control.cs @@ -183,16 +183,6 @@ namespace MathNet.Numerics set { _parallelizeElements = Math.Max(3, value); } } - /// - /// Given the number elements, should the operation be parallelized. - /// - /// The number elements to check. - /// true if the operation should be parallelized; false otherwise. - public static bool ParallelizeOperation(int elements) - { - return NumberOfParallelWorkerThreads >= 2 && elements >= ParallelizeElements; - } - /// /// Maximum number of columns to print in ToString methods by default. /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs index 75021366..7afcebea 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex.cs @@ -82,43 +82,23 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } else if (alpha.IsOne()) { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = y[i] + x[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = y[index] + x[index]; + result[i] = y[i] + x[i]; } - } + }); } else { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = y[i] + (alpha*x[i]); - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = y[index] + (alpha*x[index]); + result[i] = y[i] + (alpha*x[i]); } - } + }); } } @@ -146,23 +126,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } else { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, x.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = alpha*x[i]; - } - }); - } - else + CommonParallel.For(0, x.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = alpha*x[index]; + result[i] = alpha*x[i]; } - } + }); } } @@ -178,23 +148,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentNullException("x"); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, x.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i].Conjugate(); - } - }); - } - else + CommonParallel.For(0, x.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index].Conjugate(); + result[i] = x[i].Conjugate(); } - } + }); } /// @@ -262,23 +222,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i] + y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index] + y[index]; + result[i] = x[i] + y[i]; } - } + }); } /// @@ -313,23 +263,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i] - y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index] - y[index]; + result[i] = x[i] - y[i]; } - } + }); } /// @@ -364,23 +304,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i]*y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index]*y[index]; + result[i] = x[i] * y[i]; } - } + }); } /// @@ -415,23 +345,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) + CommonParallel.For(0, y.Length, 4096, (a, b) => { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i]/y[i]; - } - }); - } - else - { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index]/y[index]; + result[i] = x[i] / y[i]; } - } + }); } /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs index 85966372..003054bf 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Complex32.cs @@ -78,43 +78,23 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } else if (alpha.IsOne()) { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = y[i] + x[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = y[index] + x[index]; + result[i] = y[i] + x[i]; } - } + }); } else { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = y[i] + (alpha*x[i]); - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = y[index] + (alpha*x[index]); + result[i] = y[i] + (alpha * x[i]); } - } + }); } } @@ -143,23 +123,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } else { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, x.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = alpha*x[i]; - } - }); - } - else + CommonParallel.For(0, x.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = alpha*x[index]; + result[i] = alpha * x[i]; } - } + }); } } @@ -175,23 +145,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentNullException("x"); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, x.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i].Conjugate(); - } - }); - } - else + CommonParallel.For(0, x.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index].Conjugate(); + result[i] = x[i].Conjugate(); } - } + }); } /// @@ -260,23 +220,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i] + y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index] + y[index]; + result[i] = x[i] + y[i]; } - } + }); } /// @@ -311,23 +261,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i] - y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index] - y[index]; + result[i] = x[i] - y[i]; } - } + }); } /// @@ -362,23 +302,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i]*y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index]*y[index]; + result[i] = x[i] * y[i]; } - } + }); } /// @@ -413,23 +343,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) + CommonParallel.For(0, y.Length, 4096, (a, b) => { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i]/y[i]; - } - }); - } - else - { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index]/y[index]; + result[i] = x[i] / y[i]; } - } + }); } /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs index 8290e256..4d19b341 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Double.cs @@ -76,43 +76,23 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } else if (alpha == 1.0) { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = y[i] + x[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = y[index] + x[index]; + result[i] = y[i] + x[i]; } - } + }); } else { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = y[i] + (alpha*x[i]); - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = y[index] + (alpha*x[index]); + result[i] = y[i] + (alpha * x[i]); } - } + }); } } @@ -140,23 +120,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } else { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, x.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = alpha*x[i]; - } - }); - } - else + CommonParallel.For(0, x.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = alpha*x[index]; + result[i] = alpha * x[i]; } - } + }); } } @@ -244,23 +214,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) + CommonParallel.For(0, y.Length, 4096, (a, b) => { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i] + y[i]; - } - }); - } - else - { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index] + y[index]; + result[i] = x[i] + y[i]; } - } + }); } /// @@ -295,23 +255,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i] - y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index] - y[index]; + result[i] = x[i] - y[i]; } - } + }); } /// @@ -346,23 +296,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i]*y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index]*y[index]; + result[i] = x[i] * y[i]; } - } + }); } /// @@ -397,23 +337,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i]/y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index]/y[index]; + result[i] = x[i] / y[i]; } - } + }); } /// diff --git a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs index 78a122f6..024cca70 100644 --- a/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs +++ b/src/Numerics/Providers/LinearAlgebra/ManagedLinearAlgebraProvider.Single.cs @@ -76,43 +76,23 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } else if (alpha == 1.0) { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = y[i] + x[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = y[index] + x[index]; + result[i] = y[i] + x[i]; } - } + }); } else { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = y[i] + (alpha*x[i]); - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = y[index] + (alpha*x[index]); + result[i] = y[i] + (alpha * x[i]); } - } + }); } } @@ -140,23 +120,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra } else { - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, x.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = alpha*x[i]; - } - }); - } - else + CommonParallel.For(0, x.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = alpha*x[index]; + result[i] = alpha * x[i]; } - } + }); } } @@ -244,23 +214,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) + CommonParallel.For(0, y.Length, 4096, (a, b) => { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i] + y[i]; - } - }); - } - else - { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index] + y[index]; + result[i] = x[i] + y[i]; } - } + }); } /// @@ -295,23 +255,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i] - y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index] - y[index]; + result[i] = x[i] - y[i]; } - } + }); } /// @@ -346,23 +296,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i]*y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index]*y[index]; + result[i] = x[i] * y[i]; } - } + }); } /// @@ -397,23 +337,13 @@ namespace MathNet.Numerics.Providers.LinearAlgebra throw new ArgumentException(Resources.ArgumentVectorsSameLength); } - if (Control.ParallelizeOperation(x.Length)) - { - CommonParallel.For(0, y.Length, 4096, (a, b) => - { - for (int i = a; i < b; i++) - { - result[i] = x[i]/y[i]; - } - }); - } - else + CommonParallel.For(0, y.Length, 4096, (a, b) => { - for (var index = 0; index < x.Length; index++) + for (int i = a; i < b; i++) { - result[index] = x[index]/y[index]; + result[i] = x[i] / y[i]; } - } + }); } /// From abcb95d10291569f06b03a40cb4e7632c24ab7ff Mon Sep 17 00:00:00 2001 From: Thomas Ibel Date: Tue, 25 Feb 2014 19:26:45 +0100 Subject: [PATCH 7/7] add Control.TaskScheduler property --- src/Numerics/Control.cs | 7 +++++++ src/Numerics/Threading/CommonParallel.cs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs index 52dc2f8b..21bb583b 100644 --- a/src/Numerics/Control.cs +++ b/src/Numerics/Control.cs @@ -30,6 +30,7 @@ using MathNet.Numerics.Providers.LinearAlgebra; using System; +using System.Threading.Tasks; namespace MathNet.Numerics { @@ -64,6 +65,7 @@ namespace MathNet.Numerics _blockSize = 512; _parallelizeOrder = 64; _parallelizeElements = 300; + TaskScheduler = TaskScheduler.Default; // Linear Algebra Provider LinearAlgebraProvider = new ManagedLinearAlgebraProvider(); @@ -150,6 +152,11 @@ namespace MathNet.Numerics set { _numberOfThreads = Math.Max(1, Math.Min(1024, value)); } } + /// + /// Gets or sets the TaskScheduler used to schedule the worker tasks. + /// + public static TaskScheduler TaskScheduler { get; set; } + /// /// Gets or sets the the block size to use for /// the native linear algebra provider. diff --git a/src/Numerics/Threading/CommonParallel.cs b/src/Numerics/Threading/CommonParallel.cs index d8c12729..6e93d465 100644 --- a/src/Numerics/Threading/CommonParallel.cs +++ b/src/Numerics/Threading/CommonParallel.cs @@ -52,7 +52,7 @@ namespace MathNet.Numerics.Threading return new ParallelOptions { MaxDegreeOfParallelism = Control.NumberOfParallelWorkerThreads, - //TaskScheduler = Control.TaskScheduler, + TaskScheduler = Control.TaskScheduler, }; }