Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization/3.3/OrchestratedAlgorithmNode.cs @ 14624

Last change on this file since 14624 was 14624, checked in by mkommend, 7 years ago

#2205: Refactored messages in orchestrated algorithm node.

File size: 8.3 KB
RevLine 
[14610]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2017 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;
[14586]23using System.Collections.Generic;
24using System.Linq;
25using System.Threading;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Core.Networks;
29using HeuristicLab.Data;
30using HeuristicLab.Operators;
31using HeuristicLab.Optimization;
32using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
33
34namespace HeuristicLab.Networks.IntegratedOptimization {
35  [Item("OrchestratedAlgorithmNode", "A node of a network which contains a HeuristicLab algorithm and can be orchestrated by an orchestrator.")]
36  [StorableClass]
37  public class OrchestratedAlgorithmNode : AlgorithmNode {
38    #region Constants
39    private const string OrchestrationPortName = "OrchestrationPort";
40    private const string EvaluationPortName = "EvaluationPort";
41    #endregion
42
43    private bool sendResultMessage = true;
44
45    #region Ports
[14598]46    public IMessagePort OrchestrationPort {
47      get { return (IMessagePort)Ports[OrchestrationPortName]; }
[14586]48    }
[14598]49    public IMessagePort EvaluationPort {
50      get { return (IMessagePort)Ports[EvaluationPortName]; }
[14586]51    }
52    #endregion
53
54    [Storable]
55    private IHookOperator evalHook;
56    public IHookOperator EvalHook {
57      get { return evalHook; }
58      set {
59        if (evalHook == value) return;
60        evalHook = value;
61        evalHook.Port = EvaluationPort;
62      }
63    }
64
65    [StorableConstructor]
66    protected OrchestratedAlgorithmNode(bool deserializing) : base(deserializing) { }
[14624]67    protected OrchestratedAlgorithmNode(OrchestratedAlgorithmNode original, Cloner cloner)
68      : base(original, cloner) {
[14586]69      EvalHook = cloner.Clone(original.EvalHook);
[14598]70      RegisterEvents();
[14586]71    }
72    public OrchestratedAlgorithmNode() : this("OrchestratedAlgorithmNode") { }
[14624]73    public OrchestratedAlgorithmNode(string name)
74      : base(name) {
[14598]75      var orchestrationPort = new MessagePort(OrchestrationPortName);
[14586]76      Ports.Add(orchestrationPort);
77
[14598]78      var evaluationPort = new MessagePort(EvaluationPortName);
[14586]79      Ports.Add(evaluationPort);
[14598]80
81      RegisterEvents();
[14586]82    }
83
84    public override IDeepCloneable Clone(Cloner cloner) {
85      return new OrchestratedAlgorithmNode(this, cloner);
86    }
87
88    [StorableHook(HookType.AfterDeserialization)]
89    private void AfterDeserialization() {
[14598]90      RegisterEvents();
91    }
92
93    private void RegisterEvents() {
[14586]94      OrchestrationPort.MessageReceived += OrchestrationPort_MessageReceived;
95    }
96
97    #region Port Events
98    private void OrchestrationPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
[14624]99      var message = e.Value;
100      var orchestrationMessage = ((EnumValue<OrchestrationMessage>)message["OrchestrationMessage"]).Value;
[14586]101
[14598]102      #region Prepare
[14624]103      if (orchestrationMessage.HasFlag(OrchestrationMessage.Prepare)) {
[14598]104        switch (Algorithm.ExecutionState) {
105          case ExecutionState.Prepared:
106          case ExecutionState.Paused:
107          case ExecutionState.Stopped:
108            IMessageValue problemMsgVal;
109            if (e.Value.Values.TryGetValue("Problem", out problemMsgVal)) {
110              var prob = (IHeuristicOptimizationProblem)problemMsgVal.Value.Clone();
[14586]111
[14624]112              if (orchestrationMessage.HasFlag(OrchestrationMessage.SetEvalHook)) {
[14598]113                var instEval = prob.Evaluator as InstrumentedOperator;
114                if (instEval != null && EvalHook != null) instEval.AfterExecutionOperators.Add(EvalHook);
115              }
[14586]116
[14598]117              IParameter analyzerParameter = null;
118              IMultiAnalyzer multiAnalyzer = null;
119              var checkedStates = new Dictionary<Type, bool>();
120              if (Algorithm.Parameters.TryGetValue("Analyzer", out analyzerParameter)) {
121                multiAnalyzer = analyzerParameter.ActualValue as IMultiAnalyzer;
122                foreach (var item in multiAnalyzer.Operators)
123                  checkedStates.Add(item.GetType(), multiAnalyzer.Operators.ItemChecked(item));
124              }
[14586]125
[14598]126              Algorithm.Problem = prob;
[14586]127
[14598]128              if (multiAnalyzer != null) {
129                if (Algorithm.Parameters.TryGetValue("Analyzer", out analyzerParameter)) {
130                  multiAnalyzer = analyzerParameter.ActualValue as IMultiAnalyzer;
131                  if (multiAnalyzer != null && checkedStates.Any()) {
132                    foreach (var analyzer in multiAnalyzer.Operators) {
133                      bool checkedState;
[14601]134                      if (!checkedStates.TryGetValue(analyzer.GetType(), out checkedState))
135                        checkedState = analyzer.EnabledByDefault;
[14598]136                      multiAnalyzer.Operators.SetItemCheckedState(analyzer, checkedState);
137                    }
138                  }
139                }
140              }
141
[14624]142              Algorithm.Prepare(orchestrationMessage.HasFlag(OrchestrationMessage.ClearRuns));
[14586]143            }
[14598]144            break;
[14586]145        }
146      }
[14598]147      #endregion
[14586]148
[14598]149      #region Start
[14624]150      if (orchestrationMessage.HasFlag(OrchestrationMessage.Start)) {
[14598]151        switch (Algorithm.ExecutionState) {
152          case ExecutionState.Prepared:
153          case ExecutionState.Paused:
154            var trigger = new ManualResetEvent(false);
155            Exception ex = null;
[14586]156
[14598]157            EventHandler onStopped = null;
158            EventHandler<EventArgs<Exception>> onExceptionOccurred = null;
159            Algorithm.Stopped += onStopped = (src, args) => {
160              Algorithm.Stopped -= onStopped;
161              Algorithm.ExceptionOccurred -= onExceptionOccurred;
162              trigger.Set();
163            };
164            Algorithm.ExceptionOccurred += onExceptionOccurred = (src, args) => {
165              Algorithm.Stopped -= onStopped;
166              Algorithm.ExceptionOccurred -= onExceptionOccurred;
167              ex = args.Value;
168              trigger.Set();
169            };
170
171            Algorithm.Start();
172            trigger.WaitOne();
173
174            if (ex != null) throw ex;
175
176            if (sendResultMessage) {
[14624]177              message["Results"] = (ResultCollection)Algorithm.Results.Clone();
[14598]178              var msg = OrchestrationPort.PrepareMessage();
179              msg["Results"] = (ResultCollection)Algorithm.Results.Clone();
180              OrchestrationPort.SendMessage(msg);
181            } else sendResultMessage = true;
182            break;
183        }
[14586]184      }
[14598]185      #endregion
[14586]186
[14598]187      #region Pause
[14624]188      if (orchestrationMessage.HasFlag(OrchestrationMessage.Pause)) {
[14598]189        if (Algorithm.ExecutionState == ExecutionState.Started) {
190          sendResultMessage = false;
191          try {
192            Algorithm.Pause();
[14624]193          }
194          catch (InvalidOperationException) {
[14598]195            // ExecutionState might have changed since we accepted the message
196          }
197        }
[14586]198      }
[14598]199      #endregion
[14586]200
[14598]201      #region Stop
[14624]202      if (orchestrationMessage.HasFlag(OrchestrationMessage.Stop)) {
[14598]203        switch (Algorithm.ExecutionState) {
204          case ExecutionState.Started:
205          case ExecutionState.Paused:
206            try {
207              Algorithm.Stop();
[14624]208            }
209            catch (InvalidOperationException) {
[14598]210              // ExecutionState might have changed since we accepted the message
[14624]211            }
212            catch (NullReferenceException) {
[14598]213              // BasicAlgorithm might have stopped since we accepted the message
214              // CancellationTokenSource is null in this case
215            }
216            break;
217        }
[14586]218      }
[14598]219      #endregion
[14586]220    }
221    #endregion
222  }
223}
Note: See TracBrowser for help on using the repository browser.