Free cookie consent management tool by TermsFeed Policy Generator

source: branches/WebJobManager/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs @ 13847

Last change on this file since 13847 was 13656, checked in by ascheibe, 9 years ago

#2582 created branch for Hive Web Job Manager

File size: 18.3 KB
RevLine 
[3226]1#region License Information
2/* HeuristicLab
[12012]3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[3226]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
[4533]23using System.Collections.Generic;
[3226]24using System.Drawing;
[3716]25using HeuristicLab.Collections;
[3265]26using HeuristicLab.Common;
[3226]27using HeuristicLab.Core;
[3716]28using HeuristicLab.Data;
[3226]29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Optimization {
[8194]32  internal enum BatchRunAction { None, Prepare, Start, Pause, Stop };
33
[3226]34  /// <summary>
[5300]35  /// A run in which an optimizer is executed a given number of times.
[3226]36  /// </summary>
[5300]37  [Item("Batch Run", "A run in which an optimizer is executed a given number of times.")]
[12504]38  [Creatable(CreatableAttribute.Categories.TestingAndAnalysis, Priority = 110)]
[3226]39  [StorableClass]
[4419]40  public sealed class BatchRun : NamedItem, IOptimizer, IStorableContent {
41    public string Filename { get; set; }
42
[13656]43    public static new Image StaticItemImage
44    {
45      get { return new Bitmap(25, 25); }
[7201]46    }
[13656]47    public override Image ItemImage
48    {
49      get
50      {
[6534]51        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPrepared;
52        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStarted;
53        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPaused;
54        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStopped;
[7201]55        else return base.ItemImage;
[3351]56      }
[3226]57    }
58
[3265]59    [Storable]
60    private ExecutionState executionState;
[13656]61    public ExecutionState ExecutionState
62    {
[3265]63      get { return executionState; }
[13656]64      private set
65      {
[3265]66        if (executionState != value) {
67          executionState = value;
68          OnExecutionStateChanged();
[3351]69          OnItemImageChanged();
[3265]70        }
71      }
72    }
73
74    [Storable]
75    private TimeSpan executionTime;
[13656]76    public TimeSpan ExecutionTime
77    {
78      get
79      {
[5300]80        if ((Optimizer != null) && (Optimizer.ExecutionState != ExecutionState.Stopped))
81          return executionTime + Optimizer.ExecutionTime;
[3265]82        else
83          return executionTime;
84      }
[13656]85      private set
86      {
[3265]87        executionTime = value;
88        OnExecutionTimeChanged();
89      }
90    }
91
[3280]92    [Storable]
[8149]93    private TimeSpan runsExecutionTime;
94
95    [Storable]
[5300]96    private IOptimizer optimizer;
[13656]97    public IOptimizer Optimizer
98    {
[5300]99      get { return optimizer; }
[13656]100      set
101      {
[5300]102        if (optimizer != value) {
103          if (optimizer != null) {
104            DeregisterOptimizerEvents();
105            IEnumerable<IRun> runs = optimizer.Runs;
106            optimizer = null; //necessary to avoid removing the runs from the old optimizer
[4115]107            Runs.RemoveRange(runs);
108          }
[5300]109          optimizer = value;
110          if (optimizer != null) {
111            RegisterOptimizerEvents();
112            Runs.AddRange(optimizer.Runs);
[4115]113          }
[5300]114          OnOptimizerChanged();
[3716]115          Prepare();
[3226]116        }
117      }
118    }
[5300]119    // BackwardsCompatibility3.3
120    #region Backwards compatible code (remove with 3.4)
[5409]121    [Storable(AllowOneWay = true)]
[13656]122    private IAlgorithm algorithm
123    {
[5300]124      set { optimizer = value; }
125    }
126    #endregion
[3226]127
128    [Storable]
129    private int repetitions;
[13656]130    public int Repetitions
131    {
[3226]132      get { return repetitions; }
[13656]133      set
134      {
[3226]135        if (repetitions != value) {
136          repetitions = value;
137          OnRepetitionsChanged();
[5300]138          if ((Optimizer != null) && (Optimizer.ExecutionState == ExecutionState.Stopped))
[3275]139            Prepare();
[3226]140        }
141      }
142    }
[3716]143    [Storable]
144    private int repetitionsCounter;
[13656]145    public int RepetitionsCounter
146    {
[8668]147      get { return repetitionsCounter; }
[13656]148      private set
149      {
[8668]150        if (value != repetitionsCounter) {
151          repetitionsCounter = value;
152          OnRepetitionsCounterChanged();
153        }
154      }
155    }
[3226]156
157    [Storable]
[3260]158    private RunCollection runs;
[13656]159    public RunCollection Runs
160    {
[3260]161      get { return runs; }
[13656]162      private set
163      {
[3716]164        if (value == null) throw new ArgumentNullException();
165        if (runs != value) {
166          if (runs != null) DeregisterRunsEvents();
167          runs = value;
168          if (runs != null) RegisterRunsEvents();
169        }
170      }
[3226]171    }
172
[13656]173    public IEnumerable<IOptimizer> NestedOptimizers
174    {
175      get
176      {
[5419]177        if (Optimizer == null) yield break;
178
179        yield return Optimizer;
180        foreach (IOptimizer opt in Optimizer.NestedOptimizers)
181          yield return opt;
182      }
183    }
184
[8194]185    private BatchRunAction batchRunAction = BatchRunAction.None;
[3226]186
187    public BatchRun()
188      : base() {
[3280]189      name = ItemName;
190      description = ItemDescription;
[3265]191      executionState = ExecutionState.Stopped;
192      executionTime = TimeSpan.Zero;
[8149]193      runsExecutionTime = TimeSpan.Zero;
[3226]194      repetitions = 10;
[3716]195      repetitionsCounter = 0;
[8975]196      Runs = new RunCollection { OptimizerName = Name };
[3226]197    }
[3280]198    public BatchRun(string name)
199      : base(name) {
200      description = ItemDescription;
[3265]201      executionState = ExecutionState.Stopped;
202      executionTime = TimeSpan.Zero;
[8149]203      runsExecutionTime = TimeSpan.Zero;
[3226]204      repetitions = 10;
[3716]205      repetitionsCounter = 0;
[8975]206      Runs = new RunCollection { OptimizerName = Name };
[3226]207    }
[3280]208    public BatchRun(string name, string description)
209      : base(name, description) {
[3265]210      executionState = ExecutionState.Stopped;
211      executionTime = TimeSpan.Zero;
[8149]212      runsExecutionTime = TimeSpan.Zero;
[3226]213      repetitions = 10;
[3716]214      repetitionsCounter = 0;
[8975]215      Runs = new RunCollection { OptimizerName = Name };
[3226]216    }
[3280]217    [StorableConstructor]
[6767]218    private BatchRun(bool deserializing) : base(deserializing) { }
[3280]219    [StorableHook(HookType.AfterDeserialization)]
[4722]220    private void AfterDeserialization() {
221      Initialize();
[3280]222    }
223
[4722]224    private BatchRun(BatchRun original, Cloner cloner)
225      : base(original, cloner) {
226      executionState = original.executionState;
227      executionTime = original.executionTime;
[8149]228      runsExecutionTime = original.runsExecutionTime;
[5300]229      optimizer = cloner.Clone(original.optimizer);
[4722]230      repetitions = original.repetitions;
231      repetitionsCounter = original.repetitionsCounter;
232      runs = cloner.Clone(original.runs);
[8194]233      batchRunAction = original.batchRunAction;
[4722]234      Initialize();
235    }
[3226]236    public override IDeepCloneable Clone(Cloner cloner) {
[3280]237      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
[4722]238      return new BatchRun(this, cloner);
[3226]239    }
240
[4722]241    private void Initialize() {
[5300]242      if (optimizer != null) RegisterOptimizerEvents();
[4722]243      if (runs != null) RegisterRunsEvents();
244    }
245
[3226]246    public void Prepare() {
[3275]247      Prepare(false);
[3226]248    }
[3275]249    public void Prepare(bool clearRuns) {
[3265]250      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
251        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
[5300]252      if (Optimizer != null) {
[8149]253        ExecutionTime = TimeSpan.Zero;
[8668]254        RepetitionsCounter = 0;
[3716]255        if (clearRuns) runs.Clear();
[8194]256        batchRunAction = BatchRunAction.Prepare;
257        // a race-condition may occur when the optimizer has changed the state by itself in the meantime
[12504]258        try { Optimizer.Prepare(clearRuns); }
259        catch (InvalidOperationException) { }
[6471]260      } else {
261        ExecutionState = ExecutionState.Stopped;
[3261]262      }
[3226]263    }
[3265]264    public void Start() {
265      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
266        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
[6767]267      if (Optimizer == null) return;
[8194]268      batchRunAction = BatchRunAction.Start;
[6816]269      if (Optimizer.ExecutionState == ExecutionState.Stopped) Optimizer.Prepare();
[8194]270      // a race-condition may occur when the optimizer has changed the state by itself in the meantime
[12504]271      try { Optimizer.Start(); }
272      catch (InvalidOperationException) { }
[3265]273    }
274    public void Pause() {
275      if (ExecutionState != ExecutionState.Started)
276        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
[6767]277      if (Optimizer == null) return;
[8194]278      batchRunAction = BatchRunAction.Pause;
[6767]279      if (Optimizer.ExecutionState != ExecutionState.Started) return;
[8194]280      // a race-condition may occur when the optimizer has changed the state by itself in the meantime
[12504]281      try { Optimizer.Pause(); }
282      catch (InvalidOperationException) { }
[3265]283    }
[3226]284    public void Stop() {
[3265]285      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
286        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
[6767]287      if (Optimizer == null) return;
[8194]288      batchRunAction = BatchRunAction.Stop;
[8190]289      if (Optimizer.ExecutionState != ExecutionState.Started && Optimizer.ExecutionState != ExecutionState.Paused) {
290        OnStopped();
291        return;
292      }
[8194]293      // a race-condition may occur when the optimizer has changed the state by itself in the meantime
[12504]294      try { Optimizer.Stop(); }
295      catch (InvalidOperationException) { }
[3226]296    }
297
298    #region Events
[8738]299    protected override void OnNameChanged() {
300      base.OnNameChanged();
[8975]301      runs.OptimizerName = Name;
[8738]302    }
303
[3265]304    public event EventHandler ExecutionStateChanged;
305    private void OnExecutionStateChanged() {
306      EventHandler handler = ExecutionStateChanged;
307      if (handler != null) handler(this, EventArgs.Empty);
308    }
309    public event EventHandler ExecutionTimeChanged;
310    private void OnExecutionTimeChanged() {
311      EventHandler handler = ExecutionTimeChanged;
312      if (handler != null) handler(this, EventArgs.Empty);
313    }
[5300]314    public event EventHandler OptimizerChanged;
315    private void OnOptimizerChanged() {
316      EventHandler handler = OptimizerChanged;
[3265]317      if (handler != null) handler(this, EventArgs.Empty);
[3226]318    }
319    public event EventHandler RepetitionsChanged;
320    private void OnRepetitionsChanged() {
[3265]321      EventHandler handler = RepetitionsChanged;
322      if (handler != null) handler(this, EventArgs.Empty);
[3226]323    }
[8668]324    public event EventHandler RepetetionsCounterChanged;
325    private void OnRepetitionsCounterChanged() {
326      EventHandler handler = RepetetionsCounterChanged;
327      if (handler != null) handler(this, EventArgs.Empty);
328    }
[3226]329    public event EventHandler Prepared;
330    private void OnPrepared() {
[8194]331      batchRunAction = BatchRunAction.None;
[3265]332      ExecutionState = ExecutionState.Prepared;
333      EventHandler handler = Prepared;
334      if (handler != null) handler(this, EventArgs.Empty);
[3226]335    }
336    public event EventHandler Started;
337    private void OnStarted() {
[8194]338      // no reset of BatchRunAction.Started, because we need to differ which of the two was started by the user
[3265]339      ExecutionState = ExecutionState.Started;
340      EventHandler handler = Started;
341      if (handler != null) handler(this, EventArgs.Empty);
[3226]342    }
[3265]343    public event EventHandler Paused;
344    private void OnPaused() {
[8194]345      batchRunAction = BatchRunAction.None;
[3265]346      ExecutionState = ExecutionState.Paused;
347      EventHandler handler = Paused;
348      if (handler != null) handler(this, EventArgs.Empty);
349    }
[3226]350    public event EventHandler Stopped;
351    private void OnStopped() {
[8194]352      batchRunAction = BatchRunAction.None;
[3265]353      ExecutionState = ExecutionState.Stopped;
354      EventHandler handler = Stopped;
355      if (handler != null) handler(this, EventArgs.Empty);
[3226]356    }
[3265]357    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
[3226]358    private void OnExceptionOccurred(Exception exception) {
[3265]359      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
360      if (handler != null) handler(this, new EventArgs<Exception>(exception));
[3226]361    }
362
[5300]363    private void RegisterOptimizerEvents() {
364      optimizer.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Optimizer_ExceptionOccurred);
365      optimizer.ExecutionTimeChanged += new EventHandler(Optimizer_ExecutionTimeChanged);
366      optimizer.Paused += new EventHandler(Optimizer_Paused);
367      optimizer.Prepared += new EventHandler(Optimizer_Prepared);
368      optimizer.Started += new EventHandler(Optimizer_Started);
369      optimizer.Stopped += new EventHandler(Optimizer_Stopped);
370      optimizer.Runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_CollectionReset);
371      optimizer.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsAdded);
372      optimizer.Runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsRemoved);
[3261]373    }
[5300]374    private void DeregisterOptimizerEvents() {
375      optimizer.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Optimizer_ExceptionOccurred);
376      optimizer.ExecutionTimeChanged -= new EventHandler(Optimizer_ExecutionTimeChanged);
377      optimizer.Paused -= new EventHandler(Optimizer_Paused);
378      optimizer.Prepared -= new EventHandler(Optimizer_Prepared);
379      optimizer.Started -= new EventHandler(Optimizer_Started);
380      optimizer.Stopped -= new EventHandler(Optimizer_Stopped);
381      optimizer.Runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_CollectionReset);
382      optimizer.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsAdded);
383      optimizer.Runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsRemoved);
[3226]384    }
[5300]385    private void Optimizer_ExceptionOccurred(object sender, EventArgs<Exception> e) {
[3261]386      OnExceptionOccurred(e.Value);
[3226]387    }
[5300]388    private void Optimizer_ExecutionTimeChanged(object sender, EventArgs e) {
[3265]389      OnExecutionTimeChanged();
390    }
[5300]391    private void Optimizer_Paused(object sender, EventArgs e) {
[6767]392      if (ExecutionState == ExecutionState.Started) {
393        OnPaused();
394      }
[3265]395    }
[5300]396    private void Optimizer_Prepared(object sender, EventArgs e) {
[8194]397      if (batchRunAction == BatchRunAction.Prepare || ExecutionState == ExecutionState.Stopped) {
[8150]398        ExecutionTime = TimeSpan.Zero;
399        runsExecutionTime = TimeSpan.Zero;
[8668]400        RepetitionsCounter = 0;
[3276]401        OnPrepared();
[6767]402      }
[3265]403    }
[5300]404    private void Optimizer_Started(object sender, EventArgs e) {
[3276]405      if (ExecutionState != ExecutionState.Started)
406        OnStarted();
[3261]407    }
[5300]408    private void Optimizer_Stopped(object sender, EventArgs e) {
[8668]409      RepetitionsCounter++;
[8149]410      ExecutionTime += runsExecutionTime;
411      runsExecutionTime = TimeSpan.Zero;
[3265]412
[8194]413      if (batchRunAction == BatchRunAction.Stop) OnStopped();
[6767]414      else if (repetitionsCounter >= repetitions) OnStopped();
[8194]415      else if (batchRunAction == BatchRunAction.Pause) OnPaused();
416      else if (batchRunAction == BatchRunAction.Start) {
[5300]417        Optimizer.Prepare();
418        Optimizer.Start();
[8189]419      } else if (executionState == ExecutionState.Started) {
420        // if the batch run hasn't been started but the inner optimizer was run then pause
421        OnPaused();
[6767]422      } else OnStopped();
[3226]423    }
[5300]424    private void Optimizer_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
[3275]425      Runs.RemoveRange(e.OldItems);
426      Runs.AddRange(e.Items);
427    }
[5300]428    private void Optimizer_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
[3275]429      Runs.AddRange(e.Items);
430    }
[5300]431    private void Optimizer_Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
[3275]432      Runs.RemoveRange(e.Items);
433    }
[3716]434
435    private void RegisterRunsEvents() {
436      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
[4115]437      runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
[3716]438      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
439    }
[4115]440
[3716]441    private void DeregisterRunsEvents() {
442      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
[4115]443      runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
[3716]444      runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
445    }
446    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
[5300]447      if (Optimizer != null) Optimizer.Runs.RemoveRange(e.OldItems);
[3716]448      foreach (IRun run in e.Items) {
449        IItem item;
450        run.Results.TryGetValue("Execution Time", out item);
451        TimeSpanValue executionTime = item as TimeSpanValue;
452        if (executionTime != null) ExecutionTime += executionTime.Value;
453      }
454    }
[4115]455    private void Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
456      foreach (IRun run in e.Items) {
457        IItem item;
458        run.Results.TryGetValue("Execution Time", out item);
459        TimeSpanValue executionTime = item as TimeSpanValue;
[8149]460        if (executionTime != null) {
461          if (Optimizer.ExecutionState == ExecutionState.Started)
462            runsExecutionTime += executionTime.Value;
463          else
464            ExecutionTime += executionTime.Value;
465        }
[4115]466      }
467    }
[3716]468    private void Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
[5300]469      if (Optimizer != null) Optimizer.Runs.RemoveRange(e.Items);
[3716]470    }
[3226]471    #endregion
472  }
473}
Note: See TracBrowser for help on using the repository browser.