예제 #1
0
 internal static SimDataOutput Create(
     Simulation simulation,
     SimInput serieInput,
     NumDataTable serie,
     OutputOrigin outputOrigin,
     DateTime acquiredOn,
     bool persist
     ) =>
예제 #2
0
 public SimConfig(string title, string?description, DateTime importedOn, SimCode code, SimInput input, SimOutput output)
 {
     _title       = title;
     _description = description;
     _importedOn  = importedOn;
     _simCode     = code;
     _simInput    = input;
     _simOutput   = output;
 }
예제 #3
0
        private static async Task <Arr <SimInput> > EvaluateNonScalarsAsync(
            SimInput seriesInput,
            SimInput defaultInput,
            ServerLicense serverLicense,
            CancellationToken cancellationToken
            )
        {
            var nonScalarParameters = seriesInput.SimParameters.Filter(p =>
            {
                var parameter       = defaultInput.SimParameters.GetParameter(p.Name);
                var isNonScalarEdit = p.Value != parameter.Value && IsNaN(p.Scalar);
                return(isNonScalarEdit);
            });

            if (nonScalarParameters.IsEmpty)
            {
                return(Array(seriesInput));
            }

            RequireTrue(serverLicense.IsCurrent);

            var client = await serverLicense.GetRClientAsync(cancellationToken);

            var evaluationTasks = nonScalarParameters
                                  .Map(async p => new
            {
                Parameter  = p,
                Evaluation = await client.EvaluateNumDataAsync(p.Value, cancellationToken)
            });

            var evaluations = (await Task.WhenAll(evaluationTasks)).ToArr();

            var invalid = evaluations.Filter(a => a.Evaluation.Length != 1);

            if (!invalid.IsEmpty)
            {
                throw new InvalidOperationException(
                          "Parameter values failed to produce single-column output: " +
                          Join(", ", invalid.Map(e => e.Parameter.Name))
                          );
            }

            var singleColumns = evaluations
                                .Map(e => new { e.Parameter, Sequence = e.Evaluation[0].Data });
            var nParameters       = singleColumns.Count;
            var maxSequenceLength = singleColumns.Max(a => a.Sequence.Count);
            var serieInputs       = Range(0, maxSequenceLength).Map(i =>
            {
                var parameters = singleColumns.Map(
                    a => a.Parameter.With(a.Sequence[i % a.Sequence.Count])
                    );
                return(seriesInput.With(parameters));
            });

            return(serieInputs.ToArr());
        }
예제 #4
0
        private OutputRequest FulfilRequest(Simulation simulation, SimInput serieInput)
        {
            Log.Debug($"{nameof(SimData)} retrieving output");

            var serie = simulation.LoadData(serieInput);

            _outputs.TryAdd(
                (serieInput.Hash, simulation),
                SimDataOutput.Create(simulation, serieInput, serie, OutputOrigin.Storage, DateTime.UtcNow, false)
                );

            return(OutputRequest.Create(serieInput, Array(serieInput)));
        }
예제 #5
0
 private SimDataOutput(
     Simulation simulation,
     SimInput serieInput,
     NumDataTable serie,
     OutputOrigin outputOrigin,
     DateTime acquiredOn,
     bool persist,
     DateTime persistedOn
     )
 {
     Simulation   = simulation;
     SerieInput   = serieInput;
     Serie        = serie;
     OutputOrigin = outputOrigin;
     AcquiredOn   = acquiredOn;
     Persist      = persist;
     PersistedOn  = persistedOn;
 }
예제 #6
0
        private async Task <OutputRequest> FulfilRequestAsync(
            Simulation simulation,
            SimInput seriesInput,
            ServerLicense serverLicense,
            bool persist,
            CancellationToken cancellationToken)
        {
            var serieInputs = await EvaluateNonScalarsAsync(
                seriesInput,
                simulation.SimConfig.SimInput,
                serverLicense,
                cancellationToken
                );

            Log.Debug($"Evaluating non-scalar parameter values produced n={serieInputs.Count} series");

            var useExec = simulation.SimConfig.SimCode.Exec.IsAString();

            async Task <(SimInput SerieInput, NumDataTable Serie, bool Persist, OutputOrigin OutputOrigin)> AcquireSerieDataAsync(SimInput serieInput)
            {
                if (simulation.HasData(serieInput))
                {
                    Log.Debug($"{nameof(SimData)} retrieving data");
                    var retrieved = simulation.LoadData(serieInput);
                    return(serieInput, retrieved, false, OutputOrigin.Storage);
                }

                Log.Debug($"{nameof(SimData)} generating data");

                var          serieConfig = simulation.SimConfig.With(serieInput);
                NumDataTable serie;

                var stopWatch = Stopwatch.StartNew();

                if (simulation.IsRSimulation())
                {
                    var client = await serverLicense.GetRClientAsync(cancellationToken);

                    if (useExec)
                    {
                        var pathToCodeFile = simulation.PathToCodeFile;
                        RequireFile(pathToCodeFile);
                        await client.RunExecAsync(pathToCodeFile, serieConfig, cancellationToken);

                        serie = await client.TabulateExecOutputAsync(serieConfig, cancellationToken);
                    }
                    else
                    {
                        var pathToCodeFile = simulation.PopulateTemplate(serieConfig.SimInput.SimParameters);
                        await client.SourceFileAsync(pathToCodeFile, cancellationToken);

                        serie = await client.TabulateTmplOutputAsync(serieConfig, cancellationToken);
                    }
                }
                else
                {
                    var mcsimExecutor = serverLicense.GetMCSimExecutor(simulation);
                    var numDataTable  = mcsimExecutor.Execute(serieConfig.SimInput.SimParameters);
                    RequireNotNull(numDataTable, "MCSim execution failed");
                    serie = numDataTable;
                }

                stopWatch.Stop();
                var msElapsed = 1000L * stopWatch.ElapsedTicks / Stopwatch.Frequency;

                lock (_syncLock)
                {
                    if (!_executionIntervals.TryGetValue(simulation, out SimExecutionInterval? executionInterval))
                    {
                        executionInterval = new SimExecutionInterval(simulation);
                        executionInterval.Load();
                        _executionIntervals.Add(simulation, executionInterval);
                    }

                    executionInterval.AddInterval(msElapsed);
                }

                return(serieInput, serie, persist, OutputOrigin.Generation);
            }

            var outputs = (await Task.WhenAll(serieInputs.Map(AcquireSerieDataAsync))).ToArr();

            var outputsRequiringPersistence = outputs
                                              .Filter(t =>
            {
                var didAdd = _outputs.TryAdd(
                    (t.SerieInput.Hash, simulation),
                    SimDataOutput.Create(simulation, t.SerieInput, t.Serie, t.OutputOrigin, DateTime.UtcNow, t.Persist)
                    );

                return(didAdd && t.Persist);
            });

            if (!outputsRequiringPersistence.IsEmpty)
            {
                _mreDataService.Set();
            }

            return(OutputRequest.Create(
                       seriesInput,
                       outputs.Map(t => t.SerieInput)
                       ));
        }
예제 #7
0
 public SimConfig With(SimInput SimInput = default) =>
예제 #8
0
 public static OutputRequest Create(SimInput seriesInput, bool persist) =>
 new OutputRequest(seriesInput, Either <Exception, Arr <SimInput> > .Bottom, persist);
예제 #9
0
 private OutputRequest(SimInput seriesInput, Either <Exception, Arr <SimInput> > serieInputs, bool persist)
 {
     SeriesInput = seriesInput;
     SerieInputs = serieInputs;
     Persist     = persist;
 }
예제 #10
0
 public static OutputRequest Create(SimInput seriesInput, Arr <SimInput> serieInputs) =>
 new OutputRequest(seriesInput, Right <Exception, Arr <SimInput> >(serieInputs), false);
예제 #11
0
 public static OutputRequest Create(SimInput seriesInput, Exception exception) =>
 new OutputRequest(seriesInput, Left(exception), false);