Exemplo n.º 1
0
        /// <summary>
        /// Here we execute the expression, but without attempting to compile it.
        /// The performance gain comes only from reducing the amount of memory allocation required, not
        /// from compiling an optimised kernel.
        /// </summary>
        /// <param name="block"></param>
        /// <param name="provider"></param>
        /// <param name="vectorOptions"></param>
        public static void RunNonCompiling(BlockExpressionBuilder _builder,
                                           LinearAlgebraProvider provider, VectorExecutionOptions vectorOptions,
                                           NArray[] outputs, int[] outputsIndices, Aggregator aggregator, ExecutionTimer timer)
        {
            var block = _builder.ToBlock();

            if (block.Operations.Count == 0)
            {
                return;
            }

            // we will cycle through arrays in order of increasing index
            var getter = new OutputGetter <double>(outputs, outputsIndices);

            int chunksLength   = _builder.VectorLength; //5000;
            var arrayPoolStack = ExecutionContext.ArrayPool.GetStack(chunksLength);

            int length = (block.ArgumentParameters.First() as ReferencingVectorParameterExpression <double>)
                         .Array.Length;

            int chunkCount = length / chunksLength;

            if (length % chunksLength != 0)
            {
                chunkCount++;
            }

            List <NArray <double> >[] localsToFree; // the storage that can be freed up after each operation is complete
            AssignNArrayStorage <double>(block, chunkCount, chunksLength, length, out localsToFree);
            // for integer support, add here

            var options = new ParallelOptions();

            if (!vectorOptions.MultipleThreads)
            {
                options.MaxDegreeOfParallelism = 1;
            }

            timer.MarkExecutionTemporaryStorageAllocationComplete();

            // can multi-thread here, but better to do so at higher level
            //Parallel.For(0, chunkCount, options, (i) =>
            for (int i = 0; i < chunkCount; ++i)
            {
                int startIndex   = i * chunksLength;
                int vectorLength = Math.Min(chunksLength, length - startIndex);
                for (int j = 0; j < block.Operations.Count; ++j)
                {
                    var operation = block.Operations[j];
                    if (operation.Type == typeof(NArray))
                    {
                        var newOperation = _builder.SimplifyOperation(operation); // deal with any expressions containing scalars that can be simplified
                        ExecuteSingleVectorOperation <double>(newOperation, provider,
                                                              arrayPoolStack, localsToFree[j],
                                                              getter, aggregator,
                                                              vectorLength,
                                                              i, startIndex, timer);
                    }
                }
            }
            ;

            if (!arrayPoolStack.StackCountEqualsCreated)
            {
                throw new Exception("not all storage arrays created returned to stack");
            }
        }