Changeset 15573


Ignore:
Timestamp:
01/03/18 07:16:03 (12 months ago)
Author:
jkarder
Message:

#2822: merged r15408:15409, r15452 and r15560 into stable

Location:
stable
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • stable

  • stable/HeuristicLab.Optimization

  • stable/HeuristicLab.Optimization.Views

  • stable/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs

    r14186 r15573  
    4747      this.tabControl = new HeuristicLab.MainForm.WindowsForms.DragOverTabControl();
    4848      this.optimizersTabPage = new System.Windows.Forms.TabPage();
     49      this.experimentTreeView = new HeuristicLab.Optimization.Views.ExperimentTreeView();
    4950      this.runsTabPage = new System.Windows.Forms.TabPage();
    5051      this.runsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
    51       this.experimentTreeView = new HeuristicLab.Optimization.Views.ExperimentTreeView();
     52      this.workersNumericUpDown = new System.Windows.Forms.NumericUpDown();
     53      this.workersLabel = new System.Windows.Forms.Label();
    5254      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
    5355      this.tabControl.SuspendLayout();
    5456      this.optimizersTabPage.SuspendLayout();
    5557      this.runsTabPage.SuspendLayout();
     58      ((System.ComponentModel.ISupportInitialize)(this.workersNumericUpDown)).BeginInit();
    5659      this.SuspendLayout();
    5760      //
     
    119122      this.optimizersTabPage.Text = "Optimizers";
    120123      this.optimizersTabPage.UseVisualStyleBackColor = true;
     124      //
     125      // experimentTreeView
     126      //
     127      this.experimentTreeView.Caption = "Experiment View";
     128      this.experimentTreeView.Content = null;
     129      this.experimentTreeView.Dock = System.Windows.Forms.DockStyle.Fill;
     130      this.experimentTreeView.Location = new System.Drawing.Point(3, 3);
     131      this.experimentTreeView.Name = "experimentTreeView";
     132      this.experimentTreeView.ReadOnly = false;
     133      this.experimentTreeView.Size = new System.Drawing.Size(665, 395);
     134      this.experimentTreeView.TabIndex = 0;
    121135      //
    122136      // runsTabPage
     
    147161      this.runsViewHost.ViewType = null;
    148162      //
    149       // experimentTreeView
    150       //
    151       this.experimentTreeView.Caption = "Experiment View";
    152       this.experimentTreeView.Content = null;
    153       this.experimentTreeView.Dock = System.Windows.Forms.DockStyle.Fill;
    154       this.experimentTreeView.Location = new System.Drawing.Point(3, 3);
    155       this.experimentTreeView.Name = "experimentTreeView";
    156       this.experimentTreeView.ReadOnly = false;
    157       this.experimentTreeView.Size = new System.Drawing.Size(665, 395);
    158       this.experimentTreeView.TabIndex = 0;
     163      // workersNumericUpDown
     164      //
     165      this.workersNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
     166      this.workersNumericUpDown.Location = new System.Drawing.Point(193, 461);
     167      this.workersNumericUpDown.Minimum = new decimal(new int[] {
     168            1,
     169            0,
     170            0,
     171            0});
     172      this.workersNumericUpDown.Name = "workersNumericUpDown";
     173      this.workersNumericUpDown.Size = new System.Drawing.Size(59, 20);
     174      this.workersNumericUpDown.TabIndex = 16;
     175      this.workersNumericUpDown.Value = new decimal(new int[] {
     176            1,
     177            0,
     178            0,
     179            0});
     180      this.workersNumericUpDown.ValueChanged += new System.EventHandler(this.workersNumericUpDown_ValueChanged);
     181      //
     182      // workersLabel
     183      //
     184      this.workersLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
     185      this.workersLabel.AutoSize = true;
     186      this.workersLabel.Location = new System.Drawing.Point(140, 464);
     187      this.workersLabel.Name = "workersLabel";
     188      this.workersLabel.Size = new System.Drawing.Size(53, 13);
     189      this.workersLabel.TabIndex = 17;
     190      this.workersLabel.Text = "Workers: ";
    159191      //
    160192      // ExperimentView
    161193      //
    162       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    163194      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
     195      this.Controls.Add(this.workersLabel);
     196      this.Controls.Add(this.workersNumericUpDown);
    164197      this.Controls.Add(this.tabControl);
    165198      this.Name = "ExperimentView";
     
    175208      this.Controls.SetChildIndex(this.nameLabel, 0);
    176209      this.Controls.SetChildIndex(this.nameTextBox, 0);
     210      this.Controls.SetChildIndex(this.workersNumericUpDown, 0);
     211      this.Controls.SetChildIndex(this.workersLabel, 0);
    177212      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
    178213      this.tabControl.ResumeLayout(false);
    179214      this.optimizersTabPage.ResumeLayout(false);
    180215      this.runsTabPage.ResumeLayout(false);
     216      ((System.ComponentModel.ISupportInitialize)(this.workersNumericUpDown)).EndInit();
    181217      this.ResumeLayout(false);
    182218      this.PerformLayout();
     
    190226    private HeuristicLab.MainForm.WindowsForms.ViewHost runsViewHost;
    191227    private ExperimentTreeView experimentTreeView;
    192 
     228    private System.Windows.Forms.NumericUpDown workersNumericUpDown;
     229    private System.Windows.Forms.Label workersLabel;
    193230  }
    194231}
  • stable/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs

    r14186 r15573  
    2020#endregion
    2121
     22using System;
    2223using System.Linq;
    2324using System.Windows.Forms;
     
    4344        experimentTreeView.Content = null;
    4445        runsViewHost.Content = null;
     46        workersNumericUpDown.Value = 1;
    4547      } else {
    4648        experimentTreeView.Content = Content;
    4749        runsViewHost.Content = Content.Runs;
     50        workersNumericUpDown.Value = Content.NumberOfWorkers;
    4851      }
    4952    }
     
    5356      experimentTreeView.Enabled = Content != null;
    5457      runsViewHost.Enabled = Content != null;
     58      workersNumericUpDown.Enabled = Content != null && Content.ExecutionState != ExecutionState.Started;
    5559    }
    5660
     
    6670      base.OnClosed(e);
    6771    }
     72
     73    protected override void Content_ExecutionStateChanged(object sender, EventArgs e) {
     74      base.Content_ExecutionStateChanged(sender, e);
     75      workersNumericUpDown.Enabled = Content.ExecutionState != ExecutionState.Started;
     76    }
     77
     78    #region Events
     79    private void workersNumericUpDown_ValueChanged(object sender, System.EventArgs e) {
     80      if (Content != null)
     81        Content.NumberOfWorkers = (int)workersNumericUpDown.Value;
     82    }
     83    #endregion
    6884  }
    6985}
  • stable/HeuristicLab.Optimization/3.3/Algorithms/BasicAlgorithm.cs

    r15384 r15573  
    2121
    2222using System;
    23 using System.Linq;
    2423using System.Threading;
    2524using HeuristicLab.Common;
     
    8079      try {
    8180        Run((object)cancellationTokenSource.Token);
    82       }
    83       catch (OperationCanceledException) {
    84       }
    85       catch (AggregateException ae) {
     81      } catch (OperationCanceledException) {
     82      } catch (AggregateException ae) {
    8683        ae.FlattenAndHandle(new[] { typeof(OperationCanceledException) }, e => OnExceptionOccurred(e));
    87       }
    88       catch (Exception e) {
     84      } catch (Exception e) {
    8985        OnExceptionOccurred(e);
    9086      }
     
    104100      base.Pause();
    105101      pausePending = true;
    106       CancellationTokenSource.Cancel();
     102      if (CancellationTokenSource != null) CancellationTokenSource.Cancel();
    107103    }
    108104
     
    112108      base.Stop();
    113109      if (ExecutionState == ExecutionState.Paused) OnStopped();
    114       else CancellationTokenSource.Cancel();
     110      else if (CancellationTokenSource != null) CancellationTokenSource.Cancel();
    115111    }
    116112
     
    127123        initialized = true;
    128124        Run(cancellationToken);
    129       }
    130       finally {
     125      } finally {
    131126        timer.Elapsed -= new System.Timers.ElapsedEventHandler(timer_Elapsed);
    132127        timer.Stop();
  • stable/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs

    r15292 r15573  
    258258        if (ExecutionState == ExecutionState.Paused || ExecutionState == ExecutionState.Stopped) break;
    259259        Optimizer.Prepare();
     260        if (ExecutionState == ExecutionState.Paused || ExecutionState == ExecutionState.Stopped) break;
    260261      }
    261262    }
     
    271272      if (Optimizer.ExecutionState != ExecutionState.Started) return;
    272273      // a race-condition may occur when the optimizer has changed the state by itself in the meantime
    273       try { Optimizer.Pause(); } catch (InvalidOperationException) { }
     274      try { Optimizer.Pause(); } catch (InvalidOperationException) { } catch (NotSupportedException) { }
    274275    }
    275276    public void Stop() {
  • stable/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs

    r15382 r15573  
    9797    }
    9898
     99    [Storable]
     100    private int numberOfWorkers = 1;
     101    public int NumberOfWorkers {
     102      get { return numberOfWorkers; }
     103      set {
     104        if (value < 1) throw new ArgumentException("Number of Workers must not be lower than one.");
     105        numberOfWorkers = value;
     106      }
     107    }
     108
    99109    public IEnumerable<IOptimizer> NestedOptimizers {
    100110      get {
     
    111121    private bool experimentStarted = false;
    112122    private bool experimentStopped = false;
    113     private readonly ManualResetEventSlim allOptimizerFinished = new ManualResetEventSlim(false); // this indicates that all started optimizers have been paused or stopped
     123
     124    // track already started optimizers (.StartAsync does not set the executionstate immediately)
     125    // and to avoid restarting optimizers that were manually paused/stopped by the user
     126    private readonly IDictionary<IOptimizer, Task> startedOptimizers = new Dictionary<IOptimizer, Task>();
     127    private IEnumerable<IOptimizer> StartableOptimizers {
     128      get {
     129        return Optimizers
     130          .Where(x => x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused)
     131          .Where(o => !startedOptimizers.ContainsKey(o));  // all startable optimizers that were not startet yet
     132      }
     133    }
    114134
    115135    public Experiment()
     
    155175      experimentStarted = original.experimentStarted;
    156176      experimentStopped = original.experimentStopped;
     177      numberOfWorkers = original.numberOfWorkers;
    157178      Initialize();
    158179    }
     
    192213      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
    193214        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
    194       if (!Optimizers.Any(x => x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused)) return;
     215
     216      startedOptimizers.Clear();
     217      if (!StartableOptimizers.Any()) return;
    195218
    196219      experimentStarted = true;
    197220      experimentStopped = false;
    198       allOptimizerFinished.Reset();
    199       IOptimizer optimizer;
    200       while ((optimizer = Optimizers.FirstOrDefault(x => x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused)) != null) {
    201         // a race-condition may occur when the optimizer has changed the state by itself in the meantime
    202         try { optimizer.Start(cancellationToken); } catch (InvalidOperationException) { }
    203         if (ExecutionState == ExecutionState.Paused || ExecutionState == ExecutionState.Stopped) break;
    204       }
    205       allOptimizerFinished.Wait();
     221
     222      using (var availableWorkers = new SemaphoreSlim(NumberOfWorkers, NumberOfWorkers)) {
     223        while (StartableOptimizers.Any()) {
     224          try {
     225            availableWorkers.Wait(cancellationToken);
     226            var optimizer = StartableOptimizers.FirstOrDefault();
     227            if (experimentStopped || !experimentStarted || optimizer == null) break;
     228
     229            var startedTask = optimizer.StartAsync(cancellationToken).ContinueWith(async t => {
     230              availableWorkers.Release(); // is guaranteed to be not disposed yet because Task.WaitAll blocks before the end of the using
     231              await t; // trigger a potential exception on the optimizerTask
     232            });
     233            startedOptimizers.Add(optimizer, startedTask.Unwrap()); // unwrap task because lambda of .ContinueWith is async
     234          } catch (InvalidOperationException) { } catch (OperationCanceledException) { }
     235        }
     236
     237        Task.WaitAll(startedOptimizers.Values.ToArray()); // retrieve exeptions of the asyncrounously started optimizer
     238      }
    206239    }
    207240    public async Task StartAsync() { await StartAsync(CancellationToken.None); }
     
    218251      foreach (IOptimizer optimizer in Optimizers.Where(x => x.ExecutionState == ExecutionState.Started)) {
    219252        // a race-condition may occur when the optimizer has changed the state by itself in the meantime
    220         try { optimizer.Pause(); } catch (InvalidOperationException) { }
     253        try { optimizer.Pause(); } catch (InvalidOperationException) { } catch (NotSupportedException) { }
    221254      }
    222255    }
     
    256289    public event EventHandler Prepared;
    257290    private void OnPrepared() {
     291      if (ExecutionState == ExecutionState.Prepared) return;
    258292      ExecutionState = ExecutionState.Prepared;
    259293      EventHandler handler = Prepared;
     
    262296    public event EventHandler Started;
    263297    private void OnStarted() {
     298      if (ExecutionState == ExecutionState.Started) return;
    264299      ExecutionState = ExecutionState.Started;
    265300      EventHandler handler = Started;
     
    268303    public event EventHandler Paused;
    269304    private void OnPaused() {
     305      if (ExecutionState == ExecutionState.Paused) return;
    270306      ExecutionState = ExecutionState.Paused;
    271       allOptimizerFinished.Set();
    272307      EventHandler handler = Paused;
    273308      if (handler != null) handler(this, EventArgs.Empty);
     
    275310    public event EventHandler Stopped;
    276311    private void OnStopped() {
     312      if (ExecutionState == ExecutionState.Stopped) return;
    277313      ExecutionState = ExecutionState.Stopped;
    278       allOptimizerFinished.Set();
    279314      EventHandler handler = Stopped;
    280315      if (handler != null) handler(this, EventArgs.Empty);
     
    372407    }
    373408    private void optimizer_Paused(object sender, EventArgs e) {
    374       lock (locker)
    375         if (Optimizers.All(x => x.ExecutionState != ExecutionState.Started)) OnPaused();
     409      UpdateExecutionState();
    376410    }
    377411    private void optimizer_Prepared(object sender, EventArgs e) {
    378       lock (locker)
    379         if (Optimizers.All(x => x.ExecutionState == ExecutionState.Prepared)) OnPrepared();
     412      UpdateExecutionState();
    380413    }
    381414    private void optimizer_Started(object sender, EventArgs e) {
     
    384417    }
    385418    private void optimizer_Stopped(object sender, EventArgs e) {
     419      UpdateExecutionState();
     420    }
     421    private void UpdateExecutionState() {
     422      // Execution states of the Experiment are determined using the following _basic_ rules:
     423      //   if any Optimizer is Started      => Experiment is Started  (2. if)
     424      //   if any Optimizer is Paused       => Experiment is Paused   (3. if)
     425      //   if any Optimizer is Prepared     => Experiment is Prepared (5. if)
     426      //   else (all Optimizer are Stopped) => Experiment is Stopped  (6. if)
     427      // Additional there are two extra rules:
     428      //   if the Experiment is running and there are still optimizers that can be started => keep the Experiment Running (1. if)
     429      //   if experiment-stop is pending: Stop Experiment even if there are still Prepared Optimizer               (4. if)
     430
    386431      lock (locker) {
    387         if (experimentStopped) {
    388           if (Optimizers.All(x => (x.ExecutionState == ExecutionState.Stopped) || (x.ExecutionState == ExecutionState.Prepared))) OnStopped();
    389         } else {
    390           if (experimentStarted && Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused))) return;
    391           else if (Optimizers.All(x => x.ExecutionState == ExecutionState.Stopped)) OnStopped();
    392           else if (Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused)) && Optimizers.All(o => o.ExecutionState != ExecutionState.Started)) OnPaused();
    393         }
    394       }
    395     }
     432        // 1. experiment is running & further startable optimizers are available => continue executing
     433        if (experimentStarted && StartableOptimizers.Any())
     434          return;
     435
     436        // 2. any optimizer is running => continue executing
     437        if (Optimizers.Any(x => x.ExecutionState == ExecutionState.Started))
     438          return;
     439
     440        experimentStarted = false;
     441        // 3. any optimizer is paused => experiment paused
     442        if (Optimizers.Any(x => x.ExecutionState == ExecutionState.Paused))
     443          OnPaused();
     444
     445        // 4. stop pending & all optimizers either stopped or prepared => experiment stopped
     446        else if (experimentStopped)
     447          OnStopped();
     448
     449        // 5. any optimizer prepared => experiment prepared
     450        else if (Optimizers.Any(x => x.ExecutionState == ExecutionState.Prepared))
     451          OnPrepared();
     452
     453        // 6. (else) all optimizers stopped
     454        else
     455          OnStopped();
     456      }
     457    }
     458
    396459    private void optimizer_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
    397460      lock (runsLocker) {
Note: See TracChangeset for help on using the changeset viewer.