#region License Information
/* HeuristicLab
* Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Hive.JobBase;
using HeuristicLab.Optimization;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
namespace HeuristicLab.Hive.Experiment.Jobs {
[StorableClass]
public class OptimizerJob : IJob {
[Storable]
protected IOptimizer optimizer;
public IOptimizer Optimizer {
get { return optimizer; }
set {
if (value != optimizer) {
if (optimizer != null) {
DeregisterEvents();
}
optimizer = value;
if (optimizer != null) {
RegisterEvents();
}
OnOptimizerChanged();
}
}
}
[Storable]
protected ILog log;
public ILog Log {
get { return log; }
}
[Storable]
protected bool computeInParallel;
public bool ComputeInParallel {
get { return computeInParallel; }
set {
if (computeInParallel != value) {
computeInParallel = value;
OnComputeInParallelChanged();
}
}
}
[Storable]
private int indexInParentOptimizerList = -1;
public int IndexInParentOptimizerList {
get { return indexInParentOptimizerList; }
set { this.indexInParentOptimizerList = value; }
}
[Storable]
private bool collectChildJobs;
public bool CollectChildJobs {
get { return collectChildJobs; }
set { collectChildJobs = value; }
}
public OptimizerJob() {
this.log = new Log();
}
public OptimizerJob(IOptimizer optimizer)
: this() {
this.optimizer = optimizer;
if (optimizer is Optimization.Experiment) {
this.ComputeInParallel = true;
} else if (optimizer is Optimization.BatchRun) {
this.ComputeInParallel = false;
} else {
this.ComputeInParallel = false;
}
}
[StorableHook(HookType.AfterDeserialization)]
protected virtual void AfterDeserialization() {
RegisterEvents();
}
///
/// Casts the Optimizer to an Experiment. Returns null if cast was not successfull.
///
public Optimization.Experiment OptimizerAsExperiment {
get { return Optimizer as Optimization.Experiment; }
}
///
/// Casts the Optimizer to an BatchRun. Returns null if cast was not successfull.
///
public Optimization.BatchRun OptimizerAsBatchRun {
get { return Optimizer as Optimization.BatchRun; }
}
#region IJob Members
public virtual ExecutionState ExecutionState {
get { return optimizer.ExecutionState; }
}
public TimeSpan ExecutionTime {
get { return optimizer.ExecutionTime; }
}
public virtual void Run() {
throw new NotSupportedException();
}
public virtual void Prepare() {
optimizer.Prepare();
}
public virtual void Start() {
if ((optimizer is Optimization.Experiment && OptimizerAsExperiment.Optimizers.Count == 0) || // experiment would not fire OnStopped if it has 0 optimizers
(optimizer is Optimization.BatchRun && OptimizerAsBatchRun.Algorithm == null)) { // batchrun would not fire OnStopped if algorithm == null
OnJobStopped();
} else {
optimizer.Start();
}
}
public virtual void Stop() {
optimizer.Stop();
}
public virtual void Resume(IEnumerable childJobs) {
OnJobStopped();
}
public event EventHandler JobStopped;
protected virtual void OnJobStopped() {
EventHandler handler = JobStopped;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler JobFailed;
protected virtual void OnJobFailed(EventArgs e) {
EventHandler handler = JobFailed;
if (handler != null) handler(this, e);
}
public event EventHandler> NewChildJob;
protected virtual void OnNewChildJob(IJob job) {
EventHandler> handler = NewChildJob;
if (handler != null) handler(this, new EventArgs(job));
}
public event EventHandler WaitForChildJobs;
protected virtual void OnWaitForChildJobs() {
EventHandler handler = WaitForChildJobs;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler DeleteChildJobs;
protected virtual void OnDeleteChildJobs() {
EventHandler handler = DeleteChildJobs;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler ComputeInParallelChanged;
protected virtual void OnComputeInParallelChanged() {
EventHandler handler = ComputeInParallelChanged;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler OptimizerChanged;
protected virtual void OnOptimizerChanged() {
EventHandler handler = OptimizerChanged;
if (handler != null) handler(this, EventArgs.Empty);
}
#endregion
#region Events
protected virtual void RegisterEvents() {
optimizer.Stopped += new EventHandler(optimizer_Stopped);
optimizer.ExceptionOccurred += new EventHandler>(optimizer_ExceptionOccurred);
optimizer.DescriptionChanged += this.DescriptionChanged;
optimizer.FilenameChanged += this.FilenameChanged;
optimizer.ItemImageChanged += this.ItemImageChanged;
optimizer.NameChanged += this.NameChanged;
optimizer.NameChanging += this.NameChanging;
optimizer.ToStringChanged += this.ToStringChanged;
}
protected virtual void DeregisterEvents() {
optimizer.Stopped -= new EventHandler(optimizer_Stopped);
optimizer.ExceptionOccurred -= new EventHandler>(optimizer_ExceptionOccurred);
optimizer.DescriptionChanged -= this.DescriptionChanged;
optimizer.FilenameChanged -= this.FilenameChanged;
optimizer.ItemImageChanged -= this.ItemImageChanged;
optimizer.NameChanged -= this.NameChanged;
optimizer.NameChanging -= this.NameChanging;
optimizer.ToStringChanged -= this.ToStringChanged;
}
protected virtual void optimizer_ExceptionOccurred(object sender, Common.EventArgs e) {
OnJobFailed(e);
}
protected virtual void optimizer_Stopped(object sender, EventArgs e) {
OnJobStopped();
}
#endregion
#region INamedItem Members
public bool CanChangeDescription {
get { return optimizer.CanChangeDescription; }
}
public bool CanChangeName {
get { return optimizer.CanChangeName; }
}
public string Description {
get { return optimizer.Description; }
set { optimizer.Description = value; }
}
public event EventHandler DescriptionChanged;
public string Name {
get { return optimizer.Name; }
set { optimizer.Name = value; }
}
public event EventHandler NameChanged;
public event EventHandler> NameChanging;
#endregion
#region IItem Members
public string ItemDescription {
get { return optimizer.ItemDescription; }
}
public System.Drawing.Image ItemImage {
get { return optimizer.ItemImage; }
}
public event EventHandler ItemImageChanged;
public string ItemName {
get { return optimizer.ItemName; }
}
public Version ItemVersion {
get { return optimizer.ItemVersion; }
}
public event EventHandler ToStringChanged;
#endregion
#region IStorableContent Members
public string Filename {
get;
set;
}
public event EventHandler FilenameChanged;
#endregion
#region IDeepCloneable Members
public Common.IDeepCloneable Clone(Cloner cloner) {
OptimizerJob clone = (OptimizerJob)Activator.CreateInstance(this.GetType());
cloner.RegisterClonedObject(this, clone);
clone.Optimizer = (IOptimizer)cloner.Clone(this.Optimizer);
clone.log = (ILog)cloner.Clone(this.Log);
clone.ComputeInParallel = this.ComputeInParallel;
clone.IndexInParentOptimizerList = this.IndexInParentOptimizerList;
clone.CollectChildJobs = this.CollectChildJobs;
clone.RegisterEvents();
return clone;
}
#endregion
#region ICloneable Members
public object Clone() {
return Clone(new Cloner());
}
#endregion
///
/// Gets the string representation of the current instance in the format: Name: [null|Value].
///
/// The current instance as a string.
public override string ToString() {
return Name;
}
public virtual bool IsParallelizable {
get { return this.Optimizer is Optimization.Experiment || this.Optimizer is BatchRun; }
}
}
}