public void Execute(VectorExecutionOptions options)
        {
            var codeBuilder = new CUDACodeBuilder();
            var block       = _builder.ToBlock();

            codeBuilder.GenerateCode(block);
        }
        public void OptionPricingTest()
        {
            var location = StorageLocation.Host;

            var a     = new NArray(location, Enumerable.Range(0, 10).Select(i => (double)i).ToArray());
            var b     = new NArray(location, Enumerable.Range(0, 10).Select(i => (double)i * 2).ToArray());
            var c     = 5 - b;
            var check = c.First();

            IntelMathKernelLibrary.SetAccuracyMode(VMLAccuracy.LowAccuracy);
            IntelMathKernelLibrary.SetSequential();
            using (var randomStream = new RandomNumberStream(location, RandomNumberGeneratorType.MRG32K3A, 111))
            {
                var normalDistribution = new Normal(randomStream, 0, 1);

                var vectorOptions = new VectorExecutionOptions()
                {
                    MultipleThreads = true
                };

                var watch = new Stopwatch();

                watch.Start();
                var optionPrices = Value(normalDistribution);
                Console.WriteLine(String.Format("Start-up: {0}ms", watch.ElapsedMilliseconds));

                randomStream.Reset();

                watch.Restart();
                optionPrices = Value(normalDistribution);
                Console.WriteLine(String.Format("Threaded, deferred 1: {0}ms", watch.ElapsedMilliseconds));

                randomStream.Reset();

                watch.Restart();
                var optionPricesDeferred = Value(normalDistribution);
                Console.WriteLine(String.Format("Threaded, deferred 2: {0}ms", watch.ElapsedMilliseconds)); watch.Restart();

                Console.WriteLine(TestHelpers.AgreesAbsoluteString(optionPrices, optionPricesDeferred));
            }
        }
예제 #3
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");
            }
        }
        public void Evaluate(VectorExecutionOptions options,
                             NArray[] outputs,
                             NArray dependentVariable, IList <NArray> independentVariables, ExecutionTimer timer, StringBuilder expressionsOut = null,
                             Aggregator aggregator = Aggregator.ElementwiseAdd)
        {
            if (aggregator != Aggregator.ElementwiseAdd)
            {
                throw new NotImplementedException();
            }

            var dependentVariableExpression    = _builder.GetParameter <double>(dependentVariable);
            var independentVariableExpressions = independentVariables.Select(v => _builder.GetParameter <double>(v)).ToArray();

            // and important special case
            // this can only occur if the dependent variable is a scalar that does not depend on any independent variables
            if (dependentVariableExpression.Index == -1)
            {
                var scalarValue = (dependentVariableExpression as ReferencingVectorParameterExpression <double>).ScalarValue;
                outputs[0].Add(scalarValue);
                // all derivatives remains zero
                return;
            }

            _builder.UpdateLocalsNumbering();

            timer.MarkEvaluateSetupComplete();

            // differentiate, extending the block as necessary
            IList <Expression> derivativeExpressions;

            AlgorithmicDifferentiator.Differentiate(_builder, out derivativeExpressions,
                                                    dependentVariableExpression, independentVariableExpressions);

            timer.MarkDifferentationComplete();

            // arrange output storage
            var outputIndices = new int[1 + independentVariables.Count];

            for (int i = 0; i < independentVariables.Count + 1; ++i)
            {
                var referencingExpression = (i > 0) ? derivativeExpressions[i - 1] as ReferencingVectorParameterExpression <double>
                    : dependentVariableExpression as ReferencingVectorParameterExpression <double>;
                if (referencingExpression.IsScalar) // common case: constant derivative (especially zero)
                {
                    outputs[i].Add(referencingExpression.ScalarValue);
                    outputIndices[i] = int.MaxValue;
                    // TODO if storage passed in, update here in case of non-zero constant?
                }
                else // not a scalar so we will need storage
                {
                    outputIndices[i] = referencingExpression.Index;
                    if (outputs[i].IsScalar)
                    {
                        // we increase the storage, copying the scalar value
                        outputs[i] = new NArray(new VectorAccelerator.NArrayStorage.ManagedStorage <double>(_builder.VectorLength, 1, outputs[i].First()));
                    }
                }
            }

            timer.MarkStorageSetupComplete();

            // run
            VectorBlockExpressionRunner.RunNonCompiling(_builder, Provider(StorageLocation.Host),
                                                        new VectorExecutionOptions(), outputs, outputIndices, aggregator, timer);

            timer.MarkExecuteComplete();

            if (expressionsOut != null)
            {
                var block = _builder.ToBlock();
                expressionsOut.AppendLine("Result in expression "
                                          + dependentVariableExpression.ToString());

                if (derivativeExpressions != null && derivativeExpressions.Any())
                {
                    expressionsOut.AppendLine("Derivatives in expressions " + String.Join(", ",
                                                                                          derivativeExpressions.Select(e => e.ToString())));
                }
                foreach (var item in block.Operations)
                {
                    var display = item.ToString();
                    expressionsOut.AppendLine(new string(display.ToArray()));
                }
            }
        }