#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; } } } }