Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Optimization/3.3/BatchRun.cs @ 5300

Last change on this file since 5300 was 5300, checked in by swagner, 13 years ago

Enabled batch runs to deal with optimizers (#1378)

File size: 15.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
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;
23using System.Collections.Generic;
24using System.Drawing;
25using HeuristicLab.Collections;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Data;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Optimization {
32  /// <summary>
33  /// A run in which an optimizer is executed a given number of times.
34  /// </summary>
35  [Item("Batch Run", "A run in which an optimizer is executed a given number of times.")]
36  [Creatable("Testing & Analysis")]
37  [StorableClass]
38  public sealed class BatchRun : NamedItem, IOptimizer, IStorableContent {
39    public string Filename { get; set; }
40
41    public override Image ItemImage {
42      get {
43        if (ExecutionState == ExecutionState.Prepared) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePrepared;
44        else if (ExecutionState == ExecutionState.Started) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStarted;
45        else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutablePaused;
46        else if (ExecutionState == ExecutionState.Stopped) return HeuristicLab.Common.Resources.VSImageLibrary.ExecutableStopped;
47        else return HeuristicLab.Common.Resources.VSImageLibrary.Event;
48      }
49    }
50
51    [Storable]
52    private ExecutionState executionState;
53    public ExecutionState ExecutionState {
54      get { return executionState; }
55      private set {
56        if (executionState != value) {
57          executionState = value;
58          OnExecutionStateChanged();
59          OnItemImageChanged();
60        }
61      }
62    }
63
64    [Storable]
65    private TimeSpan executionTime;
66    public TimeSpan ExecutionTime {
67      get {
68        if ((Optimizer != null) && (Optimizer.ExecutionState != ExecutionState.Stopped))
69          return executionTime + Optimizer.ExecutionTime;
70        else
71          return executionTime;
72      }
73      private set {
74        executionTime = value;
75        OnExecutionTimeChanged();
76      }
77    }
78
79    [Storable]
80    private IOptimizer optimizer;
81    public IOptimizer Optimizer {
82      get { return optimizer; }
83      set {
84        if (optimizer != value) {
85          if (optimizer != null) {
86            DeregisterOptimizerEvents();
87            IEnumerable<IRun> runs = optimizer.Runs;
88            optimizer = null; //necessary to avoid removing the runs from the old optimizer
89            Runs.RemoveRange(runs);
90          }
91          optimizer = value;
92          if (optimizer != null) {
93            RegisterOptimizerEvents();
94            Runs.AddRange(optimizer.Runs);
95          }
96          OnOptimizerChanged();
97          Prepare();
98        }
99      }
100    }
101    // BackwardsCompatibility3.3
102    #region Backwards compatible code (remove with 3.4)
103    [Storable]
104    private IAlgorithm algorithm {
105      get { return null; }
106      set { optimizer = value; }
107    }
108    #endregion
109
110    [Storable]
111    private int repetitions;
112    public int Repetitions {
113      get { return repetitions; }
114      set {
115        if (repetitions != value) {
116          repetitions = value;
117          OnRepetitionsChanged();
118          if ((Optimizer != null) && (Optimizer.ExecutionState == ExecutionState.Stopped))
119            Prepare();
120        }
121      }
122    }
123    [Storable]
124    private int repetitionsCounter;
125
126    [Storable]
127    private RunCollection runs;
128    public RunCollection Runs {
129      get { return runs; }
130      private set {
131        if (value == null) throw new ArgumentNullException();
132        if (runs != value) {
133          if (runs != null) DeregisterRunsEvents();
134          runs = value;
135          if (runs != null) RegisterRunsEvents();
136        }
137      }
138    }
139
140    private bool stopPending;
141
142    public BatchRun()
143      : base() {
144      name = ItemName;
145      description = ItemDescription;
146      executionState = ExecutionState.Stopped;
147      executionTime = TimeSpan.Zero;
148      repetitions = 10;
149      repetitionsCounter = 0;
150      Runs = new RunCollection();
151      stopPending = false;
152    }
153    public BatchRun(string name)
154      : base(name) {
155      description = ItemDescription;
156      executionState = ExecutionState.Stopped;
157      executionTime = TimeSpan.Zero;
158      repetitions = 10;
159      repetitionsCounter = 0;
160      Runs = new RunCollection();
161      stopPending = false;
162    }
163    public BatchRun(string name, string description)
164      : base(name, description) {
165      executionState = ExecutionState.Stopped;
166      executionTime = TimeSpan.Zero;
167      repetitions = 10;
168      repetitionsCounter = 0;
169      Runs = new RunCollection();
170      stopPending = false;
171    }
172    [StorableConstructor]
173    private BatchRun(bool deserializing)
174      : base(deserializing) {
175      stopPending = false;
176    }
177    [StorableHook(HookType.AfterDeserialization)]
178    private void AfterDeserialization() {
179      Initialize();
180    }
181
182    private BatchRun(BatchRun original, Cloner cloner)
183      : base(original, cloner) {
184      executionState = original.executionState;
185      executionTime = original.executionTime;
186      optimizer = cloner.Clone(original.optimizer);
187      repetitions = original.repetitions;
188      repetitionsCounter = original.repetitionsCounter;
189      runs = cloner.Clone(original.runs);
190      stopPending = original.stopPending;
191      Initialize();
192    }
193    public override IDeepCloneable Clone(Cloner cloner) {
194      if (ExecutionState == ExecutionState.Started) throw new InvalidOperationException(string.Format("Clone not allowed in execution state \"{0}\".", ExecutionState));
195      return new BatchRun(this, cloner);
196    }
197
198    private void Initialize() {
199      if (optimizer != null) RegisterOptimizerEvents();
200      if (runs != null) RegisterRunsEvents();
201    }
202
203    public void Prepare() {
204      Prepare(false);
205    }
206    public void Prepare(bool clearRuns) {
207      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
208        throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
209      if (Optimizer != null) {
210        repetitionsCounter = 0;
211        if (clearRuns) runs.Clear();
212        Optimizer.Prepare(clearRuns);
213      }
214    }
215    public void Start() {
216      if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
217        throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
218      if (Optimizer != null) Optimizer.Start();
219    }
220    public void Pause() {
221      if (ExecutionState != ExecutionState.Started)
222        throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
223      if ((Optimizer != null) && (Optimizer.ExecutionState == ExecutionState.Started))
224        Optimizer.Pause();
225    }
226    public void Stop() {
227      if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
228        throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
229      stopPending = true;
230      if ((Optimizer != null) &&
231          ((Optimizer.ExecutionState == ExecutionState.Started) || (Optimizer.ExecutionState == ExecutionState.Paused)))
232        Optimizer.Stop();
233    }
234
235    #region Events
236    public event EventHandler ExecutionStateChanged;
237    private void OnExecutionStateChanged() {
238      EventHandler handler = ExecutionStateChanged;
239      if (handler != null) handler(this, EventArgs.Empty);
240    }
241    public event EventHandler ExecutionTimeChanged;
242    private void OnExecutionTimeChanged() {
243      EventHandler handler = ExecutionTimeChanged;
244      if (handler != null) handler(this, EventArgs.Empty);
245    }
246    public event EventHandler OptimizerChanged;
247    private void OnOptimizerChanged() {
248      EventHandler handler = OptimizerChanged;
249      if (handler != null) handler(this, EventArgs.Empty);
250    }
251    public event EventHandler RepetitionsChanged;
252    private void OnRepetitionsChanged() {
253      EventHandler handler = RepetitionsChanged;
254      if (handler != null) handler(this, EventArgs.Empty);
255    }
256    public event EventHandler Prepared;
257    private void OnPrepared() {
258      ExecutionState = ExecutionState.Prepared;
259      EventHandler handler = Prepared;
260      if (handler != null) handler(this, EventArgs.Empty);
261    }
262    public event EventHandler Started;
263    private void OnStarted() {
264      ExecutionState = ExecutionState.Started;
265      EventHandler handler = Started;
266      if (handler != null) handler(this, EventArgs.Empty);
267    }
268    public event EventHandler Paused;
269    private void OnPaused() {
270      ExecutionState = ExecutionState.Paused;
271      EventHandler handler = Paused;
272      if (handler != null) handler(this, EventArgs.Empty);
273    }
274    public event EventHandler Stopped;
275    private void OnStopped() {
276      ExecutionState = ExecutionState.Stopped;
277      EventHandler handler = Stopped;
278      if (handler != null) handler(this, EventArgs.Empty);
279    }
280    public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
281    private void OnExceptionOccurred(Exception exception) {
282      EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
283      if (handler != null) handler(this, new EventArgs<Exception>(exception));
284    }
285
286    private void RegisterOptimizerEvents() {
287      optimizer.ExceptionOccurred += new EventHandler<EventArgs<Exception>>(Optimizer_ExceptionOccurred);
288      optimizer.ExecutionTimeChanged += new EventHandler(Optimizer_ExecutionTimeChanged);
289      optimizer.Paused += new EventHandler(Optimizer_Paused);
290      optimizer.Prepared += new EventHandler(Optimizer_Prepared);
291      optimizer.Started += new EventHandler(Optimizer_Started);
292      optimizer.Stopped += new EventHandler(Optimizer_Stopped);
293      optimizer.Runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_CollectionReset);
294      optimizer.Runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsAdded);
295      optimizer.Runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsRemoved);
296    }
297    private void DeregisterOptimizerEvents() {
298      optimizer.ExceptionOccurred -= new EventHandler<EventArgs<Exception>>(Optimizer_ExceptionOccurred);
299      optimizer.ExecutionTimeChanged -= new EventHandler(Optimizer_ExecutionTimeChanged);
300      optimizer.Paused -= new EventHandler(Optimizer_Paused);
301      optimizer.Prepared -= new EventHandler(Optimizer_Prepared);
302      optimizer.Started -= new EventHandler(Optimizer_Started);
303      optimizer.Stopped -= new EventHandler(Optimizer_Stopped);
304      optimizer.Runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_CollectionReset);
305      optimizer.Runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsAdded);
306      optimizer.Runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Optimizer_Runs_ItemsRemoved);
307    }
308    private void Optimizer_ExceptionOccurred(object sender, EventArgs<Exception> e) {
309      OnExceptionOccurred(e.Value);
310    }
311    private void Optimizer_ExecutionTimeChanged(object sender, EventArgs e) {
312      OnExecutionTimeChanged();
313    }
314    private void Optimizer_Paused(object sender, EventArgs e) {
315      OnPaused();
316    }
317    private void Optimizer_Prepared(object sender, EventArgs e) {
318      if ((ExecutionState == ExecutionState.Paused) || (ExecutionState == ExecutionState.Stopped))
319        OnPrepared();
320    }
321    private void Optimizer_Started(object sender, EventArgs e) {
322      stopPending = false;
323      if (ExecutionState != ExecutionState.Started)
324        OnStarted();
325    }
326    private void Optimizer_Stopped(object sender, EventArgs e) {
327      repetitionsCounter++;
328
329      if (!stopPending && (repetitionsCounter < repetitions)) {
330        Optimizer.Prepare();
331        Optimizer.Start();
332      } else {
333        OnStopped();
334      }
335    }
336    private void Optimizer_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
337      Runs.RemoveRange(e.OldItems);
338      Runs.AddRange(e.Items);
339    }
340    private void Optimizer_Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
341      Runs.AddRange(e.Items);
342    }
343    private void Optimizer_Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
344      Runs.RemoveRange(e.Items);
345    }
346
347    private void RegisterRunsEvents() {
348      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
349      runs.ItemsAdded += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
350      runs.ItemsRemoved += new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
351    }
352
353    private void DeregisterRunsEvents() {
354      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
355      runs.ItemsAdded -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsAdded);
356      runs.ItemsRemoved -= new CollectionItemsChangedEventHandler<IRun>(Runs_ItemsRemoved);
357    }
358    private void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
359      foreach (IRun run in e.OldItems) {
360        IItem item;
361        run.Results.TryGetValue("Execution Time", out item);
362        TimeSpanValue executionTime = item as TimeSpanValue;
363        if (executionTime != null) ExecutionTime -= executionTime.Value;
364      }
365      if (Optimizer != null) Optimizer.Runs.RemoveRange(e.OldItems);
366      foreach (IRun run in e.Items) {
367        IItem item;
368        run.Results.TryGetValue("Execution Time", out item);
369        TimeSpanValue executionTime = item as TimeSpanValue;
370        if (executionTime != null) ExecutionTime += executionTime.Value;
371      }
372    }
373    private void Runs_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
374      foreach (IRun run in e.Items) {
375        IItem item;
376        run.Results.TryGetValue("Execution Time", out item);
377        TimeSpanValue executionTime = item as TimeSpanValue;
378        if (executionTime != null) ExecutionTime += executionTime.Value;
379      }
380    }
381    private void Runs_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
382      foreach (IRun run in e.Items) {
383        IItem item;
384        run.Results.TryGetValue("Execution Time", out item);
385        TimeSpanValue executionTime = item as TimeSpanValue;
386        if (executionTime != null) ExecutionTime -= executionTime.Value;
387      }
388      if (Optimizer != null) Optimizer.Runs.RemoveRange(e.Items);
389    }
390    #endregion
391  }
392}
Note: See TracBrowser for help on using the repository browser.