diff --git a/VectoConsole/Program.cs b/VectoConsole/Program.cs index 64ddb2f4503283ee3338aa7ef2135420bee889d3..6172449a69ea5186b5b1fb14962949a5e7991e47 100644 --- a/VectoConsole/Program.cs +++ b/VectoConsole/Program.cs @@ -14,14 +14,14 @@ using TUGraz.VectoCore.Models.Simulation.Impl; namespace VectoConsole { - internal static class Program - { - private static int NumLines; - private static int ProgessCounter { get; set; } + internal static class Program + { + private static int NumLines; + private static int ProgessCounter { get; set; } - private const string USAGE = @"Usage: vecto.exe [-h] [-v] FILE1.vecto [FILE2.vecto ...]"; + private const string USAGE = @"Usage: vecto.exe [-h] [-v] FILE1.vecto [FILE2.vecto ...]"; - private const string HELP = @" + private const string HELP = @" Commandline Interface for Vecto. Synopsis: @@ -50,173 +50,180 @@ Examples: vecto.exe -h "; - private static int Main(string[] args) - { - try { - // on -h display help and terminate. - if (args.Contains("-h")) { - ShowVersionInformation(); - Console.Write(HELP); - return 0; - } - - // on -v: activate verbose console logger - var logLevel = LogLevel.Fatal; - - // Fatal > Error > Warn > Info > Debug > Trace - var debugEnabled = false; - - if (args.Contains("-v")) { - // display errors, warnings - logLevel = LogLevel.Warn; - debugEnabled = true; - } else if (args.Contains("-vv")) { - // also display info - logLevel = LogLevel.Info; - debugEnabled = true; - } else if (args.Contains("-vvv")) { - // display debug messages - logLevel = LogLevel.Debug; - debugEnabled = true; - } else if (args.Contains("-vvvv")) { - // display everything! - logLevel = LogLevel.Trace; - debugEnabled = true; - } - - var config = LogManager.Configuration; - //config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("ConsoleLogger"))); - config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("LogFile"))); - LogManager.Configuration = config; - Trace.Listeners.Add(new ConsoleTraceListener(true)); - - if (args.Contains("-V") || debugEnabled) { - ShowVersionInformation(); - } - - args = args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-mod", "-eng", "-t" }).ToArray(); - - // if no other arguments given: display usage and terminate - if (!args.Any()) { - Console.Write(USAGE); - return 1; - } - - var stopWatch = new Stopwatch(); - var timings = new Dictionary<string, double>(); - - // process the file list and start simulation - var fileList = args; - - var sumFileName = Path.Combine(Path.GetDirectoryName(fileList.First()) ?? "", - Path.GetFileNameWithoutExtension(fileList.First()) + Constants.FileExtensions.SumFile); - var sumWriter = new SummaryFileWriter(sumFileName); - var jobContainer = new JobContainer(sumWriter); - - var mode = SimulatorFactory.FactoryMode.DeclarationMode; - if (args.Contains("-eng")) { - mode = SimulatorFactory.FactoryMode.EngineeringMode; - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine("Switching to Engineering Mode. Make sure the job-file is saved in engineering mode!"); - Console.ResetColor(); - } - - Console.WriteLine("Reading Job Files"); - stopWatch.Start(); - foreach (var file in fileList.Where(f => Path.GetExtension(f) == Constants.FileExtensions.VectoJobFile)) { - var runsFactory = new SimulatorFactory(mode, file); - if (args.Contains("-mod")) { - runsFactory.WriteModalResults = true; - } - jobContainer.AddRuns(runsFactory); - } - stopWatch.Stop(); - timings.Add("Reading input files", stopWatch.Elapsed.TotalMilliseconds); - stopWatch.Reset(); - - Console.WriteLine("Starting simulation runs"); - if (debugEnabled) { - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine("Debug-Output is enabled, executing simulation runs sequentially"); - Console.ResetColor(); - } - Console.WriteLine(); - stopWatch.Start(); - jobContainer.Execute(!debugEnabled); - - Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { - var isCtrlC = e.SpecialKey == ConsoleSpecialKey.ControlC; - var isCtrlBreak = e.SpecialKey == ConsoleSpecialKey.ControlBreak; - - if (isCtrlC) { - Console.WriteLine("Canceling simulation!"); - } - }; - - //var x = Console.CursorLeft; - while (!jobContainer.AllCompleted) { - PrintProgress(jobContainer.GetProgress()); - Thread.Sleep(250); - } - stopWatch.Stop(); - timings.Add("Simulation runs", stopWatch.Elapsed.TotalMilliseconds); - - PrintProgress(jobContainer.GetProgress(), args.Contains("-t")); - if (args.Contains("-t")) { - PrintTimings(timings); - } - } catch (Exception e) { - Console.Error.WriteLine(e.Message); - //Trace.TraceError(e.ToString()); - Console.ForegroundColor = ConsoleColor.Red; - Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)"); - Console.ResetColor(); - Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1; - } - return Environment.ExitCode; - } - - private static void ShowVersionInformation() - { - var vectodll = AssemblyName.GetAssemblyName("VectoCore.dll"); - Console.WriteLine("VectoConsole: {0}", Assembly.GetExecutingAssembly().GetName().Version); - Console.WriteLine("VectoCore: {0}", vectodll.Version); - } - - private static void PrintProgress(Dictionary<string, JobContainer.ProgressEntry> progessData, bool showTiming = true) - { - Console.SetCursorPosition(0, Console.CursorTop - NumLines); - NumLines = 0; - var sumProgress = 0.0; - foreach (var progressEntry in progessData) { - if (progressEntry.Value.Success) { - Console.ForegroundColor = ConsoleColor.Green; - } else if (progressEntry.Value.Error != null) { - Console.ForegroundColor = ConsoleColor.Red; - } - var timingString = ""; - if (showTiming && progressEntry.Value.ExecTime > 0) { - timingString = string.Format("{0,9:F2}s", progressEntry.Value.ExecTime / 1000.0); - } - Console.WriteLine("{0,-60} {1,8:P}{2}", progressEntry.Key, progressEntry.Value.Progress, timingString); - Console.ResetColor(); - sumProgress += progressEntry.Value.Progress; - NumLines++; - } - sumProgress /= NumLines; - var spinner = "/-\\|"[ProgessCounter++ % 4]; - var bar = new string('#', (int)(sumProgress * 100.0 / 2)); - Console.WriteLine(string.Format(" {2} [{1,-50}] [{0,7:P}]", sumProgress, bar, spinner)); - NumLines++; - } - - private static void PrintTimings(Dictionary<string, double> timings) - { - Console.WriteLine(); - Console.WriteLine("---- timing information ----"); - foreach (var timing in timings) { - Console.WriteLine("{0,-20}: {1:F2}s", timing.Key, timing.Value / 1000); - } - } - } + private static JobContainer jobContainer; + + private static int Main(string[] args) + { + try { + // on -h display help and terminate. + if (args.Contains("-h")) { + ShowVersionInformation(); + Console.Write(HELP); + return 0; + } + + // on -v: activate verbose console logger + var logLevel = LogLevel.Fatal; + + // Fatal > Error > Warn > Info > Debug > Trace + var debugEnabled = false; + + if (args.Contains("-v")) { + // display errors, warnings + logLevel = LogLevel.Warn; + debugEnabled = true; + } else if (args.Contains("-vv")) { + // also display info + logLevel = LogLevel.Info; + debugEnabled = true; + } else if (args.Contains("-vvv")) { + // display debug messages + logLevel = LogLevel.Debug; + debugEnabled = true; + } else if (args.Contains("-vvvv")) { + // display everything! + logLevel = LogLevel.Trace; + debugEnabled = true; + } + + var config = LogManager.Configuration; + //config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("ConsoleLogger"))); + config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("LogFile"))); + LogManager.Configuration = config; + Trace.Listeners.Add(new ConsoleTraceListener(true)); + + if (args.Contains("-V") || debugEnabled) { + ShowVersionInformation(); + } + + args = args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-mod", "-eng", "-t" }).ToArray(); + + // if no other arguments given: display usage and terminate + if (!args.Any()) { + Console.Write(USAGE); + return 1; + } + + var stopWatch = new Stopwatch(); + var timings = new Dictionary<string, double>(); + + // process the file list and start simulation + var fileList = args; + + var sumFileName = Path.Combine(Path.GetDirectoryName(fileList.First()) ?? "", + Path.GetFileNameWithoutExtension(fileList.First()) + Constants.FileExtensions.SumFile); + var sumWriter = new SummaryFileWriter(sumFileName); + jobContainer = new JobContainer(sumWriter); + + var mode = SimulatorFactory.FactoryMode.DeclarationMode; + if (args.Contains("-eng")) { + mode = SimulatorFactory.FactoryMode.EngineeringMode; + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine( + "Switching to Engineering Mode. Make sure the job-file is saved in engineering mode!"); + Console.ResetColor(); + } + + Console.WriteLine("Reading Job Files"); + stopWatch.Start(); + foreach (var file in fileList.Where(f => Path.GetExtension(f) == Constants.FileExtensions.VectoJobFile)) { + var runsFactory = new SimulatorFactory(mode, file); + if (args.Contains("-mod")) { + runsFactory.WriteModalResults = true; + } + jobContainer.AddRuns(runsFactory); + } + stopWatch.Stop(); + timings.Add("Reading input files", stopWatch.Elapsed.TotalMilliseconds); + stopWatch.Reset(); + + Console.WriteLine("Starting simulation runs"); + if (debugEnabled) { + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine("Debug-Output is enabled, executing simulation runs sequentially"); + Console.ResetColor(); + } + Console.WriteLine(); + stopWatch.Start(); + jobContainer.Execute(!debugEnabled); + + Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { + var isCtrlC = e.SpecialKey == ConsoleSpecialKey.ControlC; + var isCtrlBreak = e.SpecialKey == ConsoleSpecialKey.ControlBreak; + + if (!isCtrlC) { + return; + } + //Console.WriteLine("Canceling simulation!"); + e.Cancel = true; + Program.jobContainer.CancelCurrent(); + }; + + //var x = Console.CursorLeft; + while (!jobContainer.AllCompleted) { + PrintProgress(jobContainer.GetProgress()); + Thread.Sleep(250); + } + stopWatch.Stop(); + timings.Add("Simulation runs", stopWatch.Elapsed.TotalMilliseconds); + + PrintProgress(jobContainer.GetProgress(), args.Contains("-t")); + if (args.Contains("-t")) { + PrintTimings(timings); + } + } catch (Exception e) { + Console.Error.WriteLine(e.Message); + //Trace.TraceError(e.ToString()); + Console.ForegroundColor = ConsoleColor.Red; + Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)"); + Console.ResetColor(); + Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1; + } + return Environment.ExitCode; + } + + private static void ShowVersionInformation() + { + var vectodll = AssemblyName.GetAssemblyName("VectoCore.dll"); + Console.WriteLine("VectoConsole: {0}", Assembly.GetExecutingAssembly().GetName().Version); + Console.WriteLine("VectoCore: {0}", vectodll.Version); + } + + private static void PrintProgress(Dictionary<string, JobContainer.ProgressEntry> progessData, + bool showTiming = true) + { + Console.SetCursorPosition(0, Console.CursorTop - NumLines); + NumLines = 0; + var sumProgress = 0.0; + foreach (var progressEntry in progessData) { + if (progressEntry.Value.Success) { + Console.ForegroundColor = ConsoleColor.Green; + } else if (progressEntry.Value.Error != null) { + Console.ForegroundColor = ConsoleColor.Red; + } + var timingString = ""; + if (showTiming && progressEntry.Value.ExecTime > 0) { + timingString = string.Format("{0,9:F2}s", progressEntry.Value.ExecTime / 1000.0); + } + Console.WriteLine("{0,-60} {1,8:P}{2}", progressEntry.Key, progressEntry.Value.Progress, timingString); + Console.ResetColor(); + sumProgress += progressEntry.Value.Progress; + NumLines++; + } + sumProgress /= NumLines; + var spinner = "/-\\|"[ProgessCounter++ % 4]; + var bar = new string('#', (int)(sumProgress * 100.0 / 2)); + Console.WriteLine(string.Format(" {2} [{1,-50}] [{0,7:P}]", sumProgress, bar, spinner)); + NumLines++; + } + + private static void PrintTimings(Dictionary<string, double> timings) + { + Console.WriteLine(); + Console.WriteLine("---- timing information ----"); + foreach (var timing in timings) { + Console.WriteLine("{0,-20}: {1:F2}s", timing.Key, timing.Value / 1000); + } + } + } } \ No newline at end of file diff --git a/VectoCore/Models/Simulation/Impl/JobContainer.cs b/VectoCore/Models/Simulation/Impl/JobContainer.cs index cb123fd98a5a78cc31135374fa528b8f186ddc14..c144f885cb5072ff949212681c843aada6134a6a 100644 --- a/VectoCore/Models/Simulation/Impl/JobContainer.cs +++ b/VectoCore/Models/Simulation/Impl/JobContainer.cs @@ -8,182 +8,191 @@ using TUGraz.VectoCore.Models.Simulation.Data; namespace TUGraz.VectoCore.Models.Simulation.Impl { - /// <summary> - /// Container for simulation jobs. - /// </summary> - public class JobContainer : LoggingObject - { - internal readonly List<JobEntry> Runs = new List<JobEntry>(); - private readonly SummaryFileWriter _sumWriter; - - private static int _jobNumber; - - /// <summary> - /// Initializes a new empty instance of the <see cref="JobContainer"/> class. - /// </summary> - /// <param name="sumWriter">The sum writer.</param> - public JobContainer(SummaryFileWriter sumWriter) - { - _sumWriter = sumWriter; - } - - public void AddRun(IVectoRun run) - { - _jobNumber++; - Runs.Add(new JobEntry() { - Run = run, - Container = this, - }); - } - - public void AddRuns(IEnumerable<IVectoRun> runs) - { - _jobNumber++; - //Runs.AddRange(runs); - foreach (var run in runs) { - Runs.Add(new JobEntry() { - Run = run, - Container = this, - }); - } - } - - public void AddRuns(SimulatorFactory factory) - { - factory.SumWriter = _sumWriter; - factory.JobNumber = _jobNumber++; - AddRuns(factory.SimulationRuns()); - } - - /// <summary> - /// Execute all runs, waits until finished. - /// </summary> - public void Execute(bool multithreaded = true) - { - Log.Info("VectoRun started running. Executing Runs."); - - foreach (var job in Runs) { - job.Worker = new BackgroundWorker() { - WorkerSupportsCancellation = true, - WorkerReportsProgress = true, - }; - job.Worker.DoWork += job.DoWork; - job.Worker.ProgressChanged += job.ProgressChanged; - job.Worker.RunWorkerCompleted += job.RunWorkerCompleted; - if (multithreaded) { - job.Started = true; - job.Worker.RunWorkerAsync(); - } - } - if (!multithreaded) { - var entry = Runs.First(); - entry.Started = true; - entry.Worker.RunWorkerAsync(); - } - //Task.WaitAll(_runs.Select(r => Task.Factory.StartNew(r.Run)).ToArray()); - - _sumWriter.Finish(); - } - - public void Cancel() - { - foreach (var job in Runs) { - if (job.Worker != null && job.Worker.WorkerSupportsCancellation) { - job.Worker.CancelAsync(); - } - } - } - - private static AutoResetEvent resetEvent = new AutoResetEvent(false); - - public void WaitFinished() - { - resetEvent.WaitOne(); - } - - - private void JobCompleted(JobEntry jobEntry) - { - var next = Runs.FirstOrDefault(x => x.Started == false); - if (next != null) { - next.Started = true; - next.Worker.RunWorkerAsync(); - } - if (Runs.Count(x => x.Done == true) == Runs.Count()) { - _sumWriter.Finish(); - resetEvent.Set(); - } - } - - public Dictionary<string, ProgressEntry> GetProgress() - { - return Runs.ToDictionary(jobEntry => jobEntry.Run.Name, entry => new ProgressEntry() { - Progress = entry.Progress, - Done = entry.Done, - ExecTime = entry.ExecTime, - Success = entry.Success, - Canceled = entry.Canceled, - Error = entry.ExecException - }); - } - - public bool AllCompleted - { - get { return (Runs.Count(x => x.Done == true) == Runs.Count()); } - } - - public class ProgressEntry - { - public double Progress; - public double ExecTime; - public Exception Error; - public bool Canceled; - public bool Success; - public bool Done; - } - - internal class JobEntry : LoggingObject - { - public IVectoRun Run; - public JobContainer Container; - public double Progress; - public bool Done; - public bool Started; - public bool Success; - public bool Canceled; - public double ExecTime; - public Exception ExecException; - - public BackgroundWorker Worker; - - public void DoWork(object sender, DoWorkEventArgs e) - { - var stopWatch = new Stopwatch(); - stopWatch.Start(); - var worker = sender as BackgroundWorker; - try { - Run.Run(worker); - } catch (Exception ex) { - Log.Error(ex, "Error during simulation run!"); - ExecException = ex; - } - if (worker != null && worker.CancellationPending) { - e.Cancel = true; - Canceled = true; - } - stopWatch.Stop(); - Success = Run.FinishedWithoutErrors; - Done = true; - ExecTime = stopWatch.Elapsed.TotalMilliseconds; - Container.JobCompleted(this); - } - - public void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {} - - public void ProgressChanged(object sender, ProgressChangedEventArgs e) - { - Progress = e.ProgressPercentage / 10000.0; - } - } - } + /// <summary> + /// Container for simulation jobs. + /// </summary> + public class JobContainer : LoggingObject + { + internal readonly List<JobEntry> Runs = new List<JobEntry>(); + private readonly SummaryFileWriter _sumWriter; + + private static int _jobNumber; + + /// <summary> + /// Initializes a new empty instance of the <see cref="JobContainer"/> class. + /// </summary> + /// <param name="sumWriter">The sum writer.</param> + public JobContainer(SummaryFileWriter sumWriter) + { + _sumWriter = sumWriter; + } + + public void AddRun(IVectoRun run) + { + _jobNumber++; + Runs.Add(new JobEntry() { + Run = run, + Container = this, + }); + } + + public void AddRuns(IEnumerable<IVectoRun> runs) + { + _jobNumber++; + //Runs.AddRange(runs); + foreach (var run in runs) { + Runs.Add(new JobEntry() { + Run = run, + Container = this, + }); + } + } + + public void AddRuns(SimulatorFactory factory) + { + factory.SumWriter = _sumWriter; + factory.JobNumber = _jobNumber++; + AddRuns(factory.SimulationRuns()); + } + + /// <summary> + /// Execute all runs, waits until finished. + /// </summary> + public void Execute(bool multithreaded = true) + { + Log.Info("VectoRun started running. Executing Runs."); + + foreach (var job in Runs) { + job.Worker = new BackgroundWorker() { + WorkerSupportsCancellation = true, + WorkerReportsProgress = true, + }; + job.Worker.DoWork += job.DoWork; + job.Worker.ProgressChanged += job.ProgressChanged; + job.Worker.RunWorkerCompleted += job.RunWorkerCompleted; + if (multithreaded) { + job.Started = true; + job.Worker.RunWorkerAsync(); + } + } + if (!multithreaded) { + var entry = Runs.First(); + entry.Started = true; + entry.Worker.RunWorkerAsync(); + } + //Task.WaitAll(_runs.Select(r => Task.Factory.StartNew(r.Run)).ToArray()); + + _sumWriter.Finish(); + } + + public void Cancel() + { + foreach (var job in Runs) { + if (job.Worker != null && job.Worker.WorkerSupportsCancellation) { + job.Worker.CancelAsync(); + } + } + } + + public void CancelCurrent() + { + foreach (var job in Runs) { + if (job.Worker != null && job.Worker.IsBusy && job.Worker.WorkerSupportsCancellation) { + job.Worker.CancelAsync(); + } + } + } + + private static AutoResetEvent resetEvent = new AutoResetEvent(false); + + public void WaitFinished() + { + resetEvent.WaitOne(); + } + + + private void JobCompleted(JobEntry jobEntry) + { + var next = Runs.FirstOrDefault(x => x.Started == false); + if (next != null) { + next.Started = true; + next.Worker.RunWorkerAsync(); + } + if (Runs.Count(x => x.Done == true) == Runs.Count()) { + _sumWriter.Finish(); + resetEvent.Set(); + } + } + + public Dictionary<string, ProgressEntry> GetProgress() + { + return Runs.ToDictionary(jobEntry => jobEntry.Run.Name, entry => new ProgressEntry() { + Progress = entry.Progress, + Done = entry.Done, + ExecTime = entry.ExecTime, + Success = entry.Success, + Canceled = entry.Canceled, + Error = entry.ExecException + }); + } + + public bool AllCompleted + { + get { return (Runs.Count(x => x.Done == true) == Runs.Count()); } + } + + public class ProgressEntry + { + public double Progress; + public double ExecTime; + public Exception Error; + public bool Canceled; + public bool Success; + public bool Done; + } + + internal class JobEntry : LoggingObject + { + public IVectoRun Run; + public JobContainer Container; + public double Progress; + public bool Done; + public bool Started; + public bool Success; + public bool Canceled; + public double ExecTime; + public Exception ExecException; + + public BackgroundWorker Worker; + + public void DoWork(object sender, DoWorkEventArgs e) + { + var stopWatch = new Stopwatch(); + stopWatch.Start(); + var worker = sender as BackgroundWorker; + try { + Run.Run(worker); + } catch (Exception ex) { + Log.Error(ex, "Error during simulation run!"); + ExecException = ex; + } + if (worker != null && worker.CancellationPending) { + e.Cancel = true; + Canceled = true; + } + stopWatch.Stop(); + Success = Run.FinishedWithoutErrors; + Done = true; + ExecTime = stopWatch.Elapsed.TotalMilliseconds; + Container.JobCompleted(this); + } + + public void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {} + + public void ProgressChanged(object sender, ProgressChangedEventArgs e) + { + Progress = e.ProgressPercentage / 10000.0; + } + } + } } \ No newline at end of file