/// <summary>
        /// Evaluates the map operation
        /// </summary>
        /// <param name="vm">Current state of virtual machine</param>
        /// <returns>An ArrayValue containing new values</returns>
        public override HeronValue Eval(VM vm)
        {
            SeqValue sv = vm.Eval(list) as SeqValue;

            if (sv == null)
            {
                throw new Exception("Expected list: " + list.ToString());
            }

            // internal structure for indexing lists
            IInternalIndexable ii = sv.GetIndexable();

            if (ii.InternalCount() == 0)
            {
                return(sv);
            }

            // Array of values used for output of map operations
            HeronValue[] output = new HeronValue[ii.InternalCount()];

            // Create a parallel options object to limit parallelism
            ParallelOptions po = new ParallelOptions();

            po.MaxDegreeOfParallelism = Config.maxThreads;

            // Create a partitioner
            var partitioner = Partitioner.Create(0, ii.InternalCount());

            Parallel.ForEach(
                // Breaks the for loop up into sub-ranges
                partitioner,
                // Parellel options
                po,
                // Initialization of thread-local variables
                () =>
            {
                LoopParams lp = new LoopParams();
                lp.op         = new OptimizationParams();
                lp.acc        = lp.op.AddNewAccessor(name);
                lp.vm         = vm.Fork();
                lp.expr       = yield.Optimize(lp.op);
                return(lp);
            },
                // Loop body
                (Tuple <int, int> range, ParallelLoopState state, LoopParams lp) =>
            {
                for (int i = range.Item1; i < range.Item2; ++i)
                {
                    lp.acc.Set(ii.InternalAt(i));
                    output[i] = lp.vm.Eval(lp.expr);
                }
                return(lp);
            },
                // Finalization function
                (LoopParams lp) => { }
                );

            return(new ArrayValue(output, sv.GetElementType()));
        }
Exemple #2
0
        public override HeronValue Eval(VM vm)
        {
            SeqValue sv = vm.Eval(list) as SeqValue;

            if (sv == null)
            {
                throw new Exception("Expected list: " + list.ToString());
            }

            // internal structure for indexing lists
            IInternalIndexable ii = sv.GetIndexable();

            if (ii.InternalCount() == 0)
            {
                return(sv);
            }

            bool[] bools = new bool[ii.InternalCount()];

            ParallelOptions po = new ParallelOptions();

            po.MaxDegreeOfParallelism = Config.maxThreads;

            var p = Partitioner.Create(0, ii.InternalCount());

            Parallel.ForEach(
                p,
                po,
                () =>
            {
                LoopParams lp = new LoopParams();
                lp.op         = new OptimizationParams();
                lp.acc        = lp.op.AddNewAccessor(name);
                lp.vm         = vm.Fork();
                lp.expr       = predicate.Optimize(lp.op);
                return(lp);
            },
                (Tuple <int, int> range, ParallelLoopState state, LoopParams lp) =>
            {
                for (int i = range.Item1; i < range.Item2; ++i)
                {
                    lp.acc.Set(ii.InternalAt(i));
                    bools[i] = lp.vm.Eval(lp.expr).ToBool();
                }
                return(lp);
            },
                (LoopParams lp) => { }
                );

            List <HeronValue> r = new List <HeronValue>(ii.InternalCount());

            for (int i = 0; i < ii.InternalCount(); ++i)
            {
                if (bools[i])
                {
                    r.Add(ii.InternalAt(i));
                }
            }
            r.Capacity = r.Count;
            return(new ListValue(r, sv.GetElementType()));
        }
        public override HeronValue Eval(VM vm)
        {
            SeqValue sv = vm.Eval(list) as SeqValue;

            if (sv == null)
            {
                throw new Exception("Expected list: " + list.ToString());
            }

            // internal structure for indexing lists
            IInternalIndexable ii = sv.GetIndexable();

            if (ii.InternalCount() < 2)
            {
                return(sv);
            }

            HeronValue[]    output = new HeronValue[ii.InternalCount()];
            ParallelOptions po     = new ParallelOptions();

            po.MaxDegreeOfParallelism = Config.maxThreads;
            var p = Partitioner.Create(1, ii.InternalCount());

            HeronValue result     = ii.InternalAt(0);
            object     resultLock = new Object();

            Parallel.ForEach(
                p,
                po,
                () =>
            {
                LoopParams lp = new LoopParams();
                lp.op         = new OptimizationParams();
                lp.acc        = lp.op.AddNewAccessor(a);
                lp.acc2       = lp.op.AddNewAccessor(b);
                lp.vm         = vm.Fork();
                lp.expr       = yield.Optimize(lp.op);
                return(lp);
            },
                (Tuple <int, int> range, ParallelLoopState state, LoopParams lp) =>
            {
                if (range.Item1 == range.Item2)
                {
                    return(lp);
                }

                lp.acc.Set(ii.InternalAt(range.Item1));

                for (int i = range.Item1 + 1; i < range.Item2; ++i)
                {
                    lp.acc2.Set(ii.InternalAt(i));
                    lp.acc.Set(lp.vm.Eval(lp.expr));
                }

                // Update the result
                lock (resultLock)
                {
                    lp.acc2.Set(result);
                    result = lp.vm.Eval(lp.expr);
                }

                return(lp);
            },
                (LoopParams lp) => { }
                );

            return(new ArrayValue(new HeronValue[] { result }, sv.GetElementType()));
        }