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)); } }
/// <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())); } } }