예제 #1
0
        private static IEnumerable <Labeled <Action <ParVerifier, ParallelQuery <int> > > > HardQueries()
        {
            yield return(Labeled.Label <Action <ParVerifier, ParallelQuery <int> > >("Select+Where+TakeWhile+ToArray",
                                                                                     (verifier, query) => query.Select(x => verifier.Verify(x)).Where(x => true).TakeWhile((x, i) => true).ToArray()));

            yield return(Labeled.Label <Action <ParVerifier, ParallelQuery <int> > >("Select+Where+TakeWhile+foreach",
                                                                                     (verifier, query) => query.Select(x => verifier.Verify(x)).Where(x => true).TakeWhile((x, i) => true).Enumerate()));

            yield return(Labeled.Label <Action <ParVerifier, ParallelQuery <int> > >("Where+Select+ElementAt",
                                                                                     (verifier, query) => query.Where(x => true).Select(x => verifier.Verify(x)).ElementAt(8)));

            yield return(Labeled.Label <Action <ParVerifier, ParallelQuery <int> > >("Where+Select+foreach",
                                                                                     (verifier, query) => query.Where(x => true).Select(x => verifier.Verify(x)).Enumerate()));
        }
예제 #2
0
        /// <summary>
        /// Get a a combination of partitioned data sources, degree of parallelism, expected resulting dop,
        /// query to execute on the data source, and mode of execution.
        /// </summary>
        /// <param name="dop">A set of the desired degrees of parallelism to be employed.</param>
        /// <returns>Entries for test data.
        /// The first element is the Labeled{ParallelQuery{int}} data source,
        /// the second is the desired dop,
        /// the third is the expected resulting dop,
        /// the fourth is the query to execute on the data source,
        /// and the fifth is the execution mode.</returns>
        public static IEnumerable <object[]> WithExecutionModeQueryData(int[] dops)
        {
            foreach (int dop in dops)
            {
                // Use data sources that have a fixed set of elements in each partition (no load balancing between the partitions).
                // PLINQ will assign a Task to each partition, and no other task will process that partition. As a result, we can
                // verify that we get a known number of tasks doing the processing. (This doesn't guarantee that such tasks are
                // running in parallel, but it's "good enough".  If PLINQ's implementation is ever changed to proactively exit
                // tasks and spawn replicas to continue the processing, ala Parallel.For*, this test will need to be updated.)
                int count             = 3 * dop; // 3 chosen arbitrarily as a small value; any positive value will do
                var partitionedRanges = new Labeled <ParallelQuery <int> >[]
                {
                    Labeled.Label("ParallelEnumerable.Range", ParallelEnumerable.Range(0, count)),
                    Labeled.Label("Partitioner.Create", Partitioner.Create(UnorderedSources.GetRangeArray(0, count), loadBalance: false).AsParallel())
                };

                // For each source and mode, get both unordered and ordered queries that should easily parallelize for all execution modes
                foreach (ParallelExecutionMode mode in new[] { ParallelExecutionMode.Default, ParallelExecutionMode.ForceParallelism })
                {
                    foreach (Labeled <ParallelQuery <int> > source in partitionedRanges)
                    {
                        foreach (var query in EasyUnorderedQueries(count))
                        {
                            yield return new object[] { source, dop, dop, query, mode }
                        }
                        ;

                        foreach (var query in EasyOrderedQueries(count))
                        {
                            yield return new object[] { source.Order(), dop, dop, query, mode }
                        }
                        ;
                    }
                }

                // For each source, get queries that are difficult to parallelize and thus only do so with ForceParallelism.
                foreach (Labeled <ParallelQuery <int> > source in partitionedRanges)
                {
                    foreach (var query in HardQueries(count))
                    {
                        yield return(new object[] { source, dop, dop, query, ParallelExecutionMode.ForceParallelism }); // should parallelize, thus expected DOP of > 1

                        yield return(new object[] { source, dop, 1, query, ParallelExecutionMode.Default });            // won't parallelize, thus expected DOP of 1
                    }
                }
            }
        }
예제 #3
0
 public static IEnumerable <object[]> AggregateExceptionData(int[] counts)
 {
     foreach (object[] results in UnorderedSources.Ranges(counts.Cast <int>()))
     {
         Labeled <ParallelQuery <int> > query = (Labeled <ParallelQuery <int> >)results[0];
         if (query.ToString().StartsWith("Partitioner"))
         {
             yield return(new object[] { Labeled.Label(query.ToString(), Partitioner.Create(UnorderedSources.GetRangeArray(0, (int)results[1]), false).AsParallel()), results[1] });
         }
         else if (query.ToString().StartsWith("Enumerable.Range"))
         {
             yield return(new object[] { Labeled.Label(query.ToString(), new StrictPartitioner <int>(Partitioner.Create(Enumerable.Range(0, (int)results[1]), EnumerablePartitionerOptions.None), (int)results[1]).AsParallel()), results[1] });
         }
         else
         {
             yield return(results);
         }
     }
 }
예제 #4
0
        private static IEnumerable <Labeled <ParallelQuery <int> > > LabeledRanges(int start, int count)
        {
            yield return(Labeled.Label("ParallelEnumerable.Range", ParallelEnumerable.Range(start, count)));

            yield return(Labeled.Label("Enumerable.Range", Enumerable.Range(start, count).AsParallel()));

            int[] rangeArray = GetRangeArray(start, count);
            yield return(Labeled.Label("Array", rangeArray.AsParallel()));

            if (count < AdditionalTypeLimit + 1)
            {
                yield return(Labeled.Label("Partitioner", Partitioner.Create(rangeArray).AsParallel()));

                IList <int> rangeList = rangeArray.ToList();
                yield return(Labeled.Label("List", rangeList.AsParallel()));

                yield return(Labeled.Label("ReadOnlyCollection", new ReadOnlyCollection <int>(rangeList).AsParallel()));
            }
        }
예제 #5
0
 public static IEnumerable <object[]> NotLoadBalancedDegreeData(object[] counts, object[] degrees)
 {
     foreach (object[] results in DegreeData(counts, degrees))
     {
         Labeled <ParallelQuery <int> > query = (Labeled <ParallelQuery <int> >)results[0];
         if (query.ToString().StartsWith("Partitioner"))
         {
             yield return(new object[] { Labeled.Label(query.ToString(), Partitioner.Create(UnorderedSources.GetRangeArray(0, (int)results[1]), false).AsParallel()), results[1], results[2] });
         }
         else if (query.ToString().StartsWith("Enumerable.Range"))
         {
             yield return(new object[] { Labeled.Label(query.ToString(), new StrictPartitioner <int>(Partitioner.Create(Enumerable.Range(0, (int)results[1]), EnumerablePartitionerOptions.NoBuffering), (int)results[1]).AsParallel()), results[1], results[2] });
         }
         else
         {
             yield return(results);
         }
     }
 }
예제 #6
0
 private static IEnumerable <Labeled <Action <UsedTaskTracker, ParallelQuery <int> > > > EasyOrderedQueries(int count)
 {
     yield return(Labeled.Label <Action <UsedTaskTracker, ParallelQuery <int> > >("Where+Select+Concat(AsOrdered+Where)+ToList",
                                                                                  (verifier, query) => query.Where(x => true).Select(x => verifier.AddCurrent(x)).Concat(Enumerable.Range(0, count).AsParallel().AsOrdered().Where(x => true)).ToList()));
 }
예제 #7
0
 private static IEnumerable <Labeled <Action <ParVerifier, ParallelQuery <int> > > > EasyOrderedQueries()
 {
     yield return(Labeled.Label <Action <ParVerifier, ParallelQuery <int> > >("Where+Select+Concat(AsOrdered+Where)+ToList",
                                                                              (verifier, query) => query.Where(x => true).Select(x => verifier.Verify(x)).Concat(Enumerable.Range(0, 1000).AsParallel().AsOrdered().Where(x => true)).ToList()));
 }
예제 #8
0
 // Return an enumerable which throws on first MoveNext.
 // Useful for testing promptness of cancellation.
 public static IEnumerable <object[]> ThrowOnFirstEnumeration()
 {
     yield return(new object[] { Labeled.Label("ThrowOnFirstEnumeration", Enumerables <int> .ThrowOnEnumeration().AsParallel()), 8 });
 }