public void ThrowOnDuplicateId()
        {
            var job = new ParallelJob(new ConsoleLogProvider())
                      .AddTask("a", () => { });

            TestUtility.ShouldFail <InvalidOperationException>(() => job.AddTask("a", () => { }), "has already been added");
        }
        public void UnresolvableDependencies()
        {
            var result = new ConcurrentQueue <string>();

            var job = new ParallelJob(new ConsoleLogProvider())
                      .AddTask("a", () => result.Enqueue("a"), new[] { "c", "d", "e" })
                      .AddTask("b", () => result.Enqueue("b"), new[] { "c", "d", "e" })
                      .AddTask("c", () => result.Enqueue("c"), new[] { "d", "e" })
                      .AddTask("d", () => result.Enqueue("d"), new[] { "a" })
                      .AddTask("e", () => result.Enqueue("e"));

            TestUtility.ShouldFail <InvalidOperationException>(() => job.RunAllTasks(), "Unable to resolve required task dependencies");
            Assert.AreEqual("e", string.Concat(result));
        }
Пример #3
0
    // Start is called before the first frame update
    void Start()
    {
        SimpleJob simpleJob = new SimpleJob
        {
            number = myNumber,
            data   = myData,
        };

        ParallelJob parallelJob = new ParallelJob
        {
            number = myNumber,
            data   = myData,
        };

        TransformJob transformJob = new TransformJob
        {
            number    = myNumber,
            data      = myData,
            deltaTime = Time.deltaTime,
        };

        simpleJobHandle    = simpleJob.Schedule();
        parallelJobHandle  = parallelJob.Schedule(myData.Length, 32, simpleJobHandle);
        transformJobHandle = transformJob.Schedule(transformAccessArray, parallelJobHandle);

        // dependency like a->b->c...

        JobHandle.ScheduleBatchedJobs();

        simpleJobHandle.Complete();
        parallelJobHandle.Complete();
        transformJobHandle.Complete();

        if (simpleJobHandle.IsCompleted)
        {
            Debug.Log("simple job result " + simpleJob.data[0]);
        }

        if (parallelJobHandle.IsCompleted)
        {
            for (int i = 0; i < myData.Length; ++i)
            {
                Debug.Log("parallel job result " + parallelJob.data[i]);
            }
        }
        myData.Dispose();
        transformAccessArray.Dispose();
    }
        public void SimpleDependency()
        {
            var result = new ConcurrentQueue <string>();

            var job = new ParallelJob(new ConsoleLogProvider())
                      .AddTask("a", () =>
            {
                Task.Delay(50).Wait();
                result.Enqueue("a");
            })
                      .AddTask("b", () => result.Enqueue("b"), new [] { "a" })
                      .AddTask("c", () => result.Enqueue("c"));

            job.RunAllTasks();
            Assert.AreEqual("cab", string.Concat(result));
        }
        public void ComplexDependencies()
        {
            var result = new ConcurrentQueue <string>();

            var job = new ParallelJob(new ConsoleLogProvider())
                      .AddTask("a", () => result.Enqueue("a"), new[] { "c", "d", "e" })
                      .AddTask("b", () => result.Enqueue("b"), new[] { "c", "d", "e" })
                      .AddTask("c", () => result.Enqueue("c"), new[] { "d", "e" })
                      .AddTask("d", () => result.Enqueue("d"), new[] { "e" })
                      .AddTask("e", () => result.Enqueue("e"));

            job.RunAllTasks();
            var sequence = string.Concat(result);

            Assert.IsTrue(sequence == "edcab" || sequence == "edcba");
        }
Пример #6
0
    public void FindPrimesInAGeneratedSample()
    {
        results.text = ("\n Starting...");
        //start a stopper to benchmark
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();

        NativeArray <int> input = new NativeArray <int>(inputSize, Allocator.TempJob);
        //store data how many prime numbers we found -> make an array element for each thread to avoid racing (multiple threads trying to write the same element can cause trouble)
        NativeArray <int> numberOfFoundPrimes = new NativeArray <int>(numberOfThreads, Allocator.TempJob);

        //initialize the sample
        for (int i = 0; i < inputSize; i++)
        {
            input[i] = UnityEngine.Random.Range(0, 10);
        }
        jobData             = new ParallelJob();
        jobData.input       = input;
        jobData.nthreads    = numberOfThreads;
        jobData.inputSize   = inputSize;
        jobData.foundPrimes = numberOfFoundPrimes;

        //pass to scheduler - divide the input interval with the threads so we get (thread number) of chunks and we can calculate thread id's in the Execute method
        //(roughly the same as static scheduling)
        handle = jobData.Schedule(inputSize, inputSize / numberOfThreads);

        //waiting for all threads to finish
        handle.Complete();

        //summarize the total prime numbers we found on each thread
        int totalFoundPrimes = 0;

        for (int i = 0; i < numberOfThreads; i++)
        {
            totalFoundPrimes += jobData.foundPrimes[i];
        }

        //stop our stopper
        sw.Stop();
        results.text += ("\n Done! Elapsed time: " + sw.ElapsedMilliseconds / 1000f + "\n Found: " + totalFoundPrimes);

        // disposal of nativearrays
        input.Dispose();
        numberOfFoundPrimes.Dispose();
    }
        private void RunDemo()
        {
            ParallelJob parallelJob = new ParallelJob
            {
                Number = m_MyNumber,
                Data   = m_MyData
            };

            m_ParallelJobHandle = parallelJob.Schedule(m_MyData.Length, 32);

            JobHandle.ScheduleBatchedJobs();
            m_ParallelJobHandle.Complete();
            if (m_ParallelJobHandle.IsCompleted)
            {
                for (int i = 0; i < m_MyData.Length; i++)
                {
                    Debug.Log(parallelJob.Data[i]);
                }
                FreeMemoryData();
            }
        }
Пример #8
0
    static void TestJob()
    {
        var j1 = new Job((job) =>
        {
            Debug.Log("j1");
            job.Success();
        });
        var j2 = new Job((job) =>
        {
            Debug.Log("j2");
            job.Success();
        });
        var j3 = new Job((job) =>
        {
            Debug.Log("j3");
            job.Fail();
        });
        var j4 = new Job((job) =>
        {
            Debug.Log("j4");
            job.Success();
        });
        var parallel = new ParallelJob();

        parallel.AddChild(j1);
        parallel.AddChild(j2);
        parallel.AddChild(j3);
        parallel.AddChild(j4);
        parallel.Run((job) =>
        {
            Debug.Log("parallel success");
        }, (Job) =>
        {
            var children = (Job as ParallelJob)?.m_ErrorChildren;
            Debug.Log("parallel error");
        }, (job) =>
        {
            Debug.Log("parallel progress:" + job.Progress);
        });
    }
        public void StopOnException()
        {
            var result = new ConcurrentQueue <string>();

            var job = new ParallelJob(new ConsoleLogProvider())
                      .AddTask("a", () =>
            {
                Task.Delay(50).Wait();
                result.Enqueue("a");
            })
                      .AddTask("b", () =>
            {
                result.Enqueue("b");
                throw new InvalidOperationException("Test exception");
            })
                      .AddTask("c", () => result.Enqueue("c"), new[] { "a" });


            var e = TestUtility.ShouldFail <InvalidOperationException>(() => job.RunAllTasks(), "Test exception");

            Assert.AreEqual("ab", string.Concat(result.OrderBy(a => a)));
        }
Пример #10
0
        public void CorrectlyCancels()
        {
            var lockAStart    = new SemaphoreSlim(0, 1);
            var lockAFinished = new SemaphoreSlim(0, 1);
            var lockBFinished = new SemaphoreSlim(0, 1);

            var result = new ConcurrentQueue <string>();
            var job    = new ParallelJob(new ConsoleLogProvider())
                         .AddTask("a", () =>
            {
                lockAStart.Wait();
                result.Enqueue("a");
                lockAFinished.Release();
            })
                         .AddTask("b", () =>
            {
                result.Enqueue("b");
                lockBFinished.Release();
            })
                         .AddTask("c", () => result.Enqueue("c"), new[] { "a" });

            var cancellationTokenSource = new CancellationTokenSource();
            var task = Task.Run(() => job.RunAllTasks(0, cancellationTokenSource.Token));

            lockBFinished.Wait(); // Wait for "b" to finish.
            cancellationTokenSource.Cancel();
            var e = TestUtility.ShouldFail <AggregateException>(() => task.Wait());

            Assert.IsTrue(e.InnerException is OperationCanceledException);

            // Only "b" should be completed. "a" is waiting for lock, "c" i waiting for "a".
            Assert.AreEqual("b", TestUtility.Dump(result));
            lockAStart.Release(); // Allow "a" to run now.

            // "a" is expected to complete also, since it has been started prior to cancellation.
            lockAFinished.Wait(); // Wait for "a" to finish.
            Thread.Sleep(50);     // Wait a little longer, but "c" should still not start, because it had not started prior to cancellation.
            Assert.AreEqual("b, a", TestUtility.Dump(result));
        }
Пример #11
0
        public void CorrectlyCancels()
        {
            var lockAStart    = new SemaphoreSlim(0, 1);
            var lockAFinished = new SemaphoreSlim(0, 1);
            var lockBFinished = new SemaphoreSlim(0, 1);

            var result = new ConcurrentQueue <string>();
            var job    = new ParallelJob(new ConsoleLogProvider())
                         .AddTask("a", () =>
            {
                result.Enqueue("a1");
                lockAStart.Wait();
                result.Enqueue("a2");
                lockAFinished.Release();
            })
                         .AddTask("b", () =>
            {
                result.Enqueue("b");
                lockBFinished.Release();
            })
                         .AddTask("c", () => result.Enqueue("c"), new[] { "a" });

            var cancellationTokenSource = new CancellationTokenSource();
            var task = Task.Run(() => job.RunAllTasks(0, cancellationTokenSource.Token));

            lockBFinished.Wait(); // Wait for "b" to finish.
            cancellationTokenSource.Cancel();
            var e = TestUtility.ShouldFail <AggregateException>(() => task.Wait());

            Assert.IsTrue(e.InnerException is OperationCanceledException);

            // only b completes immediately after cancellation
            Assert.AreEqual("a1b", string.Concat(result));
            lockAStart.Release(); // Allow "a" to run now.

            // a should complete also, since it has been started prior to cancellation
            lockAFinished.Wait(); // Wait for "a" to finish.
            Assert.AreEqual("a1ba2", string.Concat(result));
        }
Пример #12
0
        private ParallelJob PrepareGeneratorsJob(IList <IGenerator> generators)
        {
            var allDependencies   = ResolveDependencies(generators);
            var validDependencies = FilterInvalidDependencies(generators, allDependencies);

            var job = new ParallelJob(_logProvider);

            foreach (var generator in generators)
            {
                var generatorName = GetGeneratorName(generator);
                validDependencies.TryGetValue(generatorName, out var generatorDependencies);

                job.AddTask(generatorName, () =>
                {
                    _logger.Info(() => $"Starting {generatorName}.");
                    var sw = Stopwatch.StartNew();
                    generator.Generate();
                    _performanceLogger.Write(sw, () => $"{generatorName} completed.");
                }, generatorDependencies ?? new List <string>());
            }

            return(job);
        }
Пример #13
0
    private void runDemo()
    {
        ParallelJob parallelJob = new ParallelJob {
            number = myNumber,
            data   = myData
        };

        myParallelJobHandle = parallelJob.Schedule(myData.Length, 32);

        JobHandle.ScheduleBatchedJobs();

        myParallelJobHandle.Complete();

        if (myParallelJobHandle.IsCompleted)
        {
            for (int i = 0; i < myData.Length; i++)
            {
                Debug.Log(parallelJob.data[i]);
            }

            freeMemoryData();
        }
    }
Пример #14
0
    // Update is called once per frame
    void Update()
    {
        if (useThread)
        {
            ParallelJob tempParallelJob = new ParallelJob()
            {
                deltaTime = Time.deltaTime
            };
            NativeArray <float3> eulerAngles = new NativeArray <float3>(goList.Count, Allocator.TempJob);
            for (int i = 0; i < goList.Count; ++i)
            {
                eulerAngles[i] = goList[i].transform.eulerAngles;
            }
            tempParallelJob.eulerAngles = eulerAngles;
            JobHandle jobHandle = tempParallelJob.Schedule(goList.Count, 10);
            jobHandle.Complete();
            for (int i = 0; i < goList.Count; ++i)
            {
                goList[i].transform.eulerAngles = eulerAngles[i];
            }

            eulerAngles.Dispose();
        }
        else
        {
            foreach (var item in goList)
            {
                item.transform.eulerAngles += new Vector3(0, 30 * Time.deltaTime, 0);

                for (int i = 0; i < 1000; ++i)
                {
                    float result = math.exp10(math.sqrt(5 * 6));
                }
            }
        }
    }
Пример #15
0
    // Start is called before the first frame update
    void Start()
    {
        ParallelJob parallelJob = new ParallelJob
        {
            number = myNumber,
            data   = myData,
        };

        parallelJobHandle = parallelJob.Schedule(myData.Length, 32);

        JobHandle.ScheduleBatchedJobs();

        parallelJobHandle.Complete();

        if (parallelJobHandle.IsCompleted)
        {
            for (int i = 0; i < myData.Length; ++i)
            {
                Debug.Log(parallelJob.data[i]);
            }
        }

        myData.Dispose();
    }