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
Line 
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;
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
46    public IMessagePort OrchestrationPort {
47      get { return (IMessagePort)Ports[OrchestrationPortName]; }
48    }
49    public IMessagePort EvaluationPort {
50      get { return (IMessagePort)Ports[EvaluationPortName]; }
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) { }
67    protected OrchestratedAlgorithmNode(OrchestratedAlgorithmNode original, Cloner cloner)
68      : base(original, cloner) {
69      EvalHook = cloner.Clone(original.EvalHook);
70      RegisterEvents();
71    }
72    public OrchestratedAlgorithmNode() : this("OrchestratedAlgorithmNode") { }
73    public OrchestratedAlgorithmNode(string name)
74      : base(name) {
75      var orchestrationPort = new MessagePort(OrchestrationPortName);
76      Ports.Add(orchestrationPort);
77
78      var evaluationPort = new MessagePort(EvaluationPortName);
79      Ports.Add(evaluationPort);
80
81      RegisterEvents();
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() {
90      RegisterEvents();
91    }
92
93    private void RegisterEvents() {
94      OrchestrationPort.MessageReceived += OrchestrationPort_MessageReceived;
95    }
96
97    #region Port Events
98    private void OrchestrationPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
99      var message = e.Value;
100      var orchestrationMessage = ((EnumValue<OrchestrationMessage>)message["OrchestrationMessage"]).Value;
101
102      #region Prepare
103      if (orchestrationMessage.HasFlag(OrchestrationMessage.Prepare)) {
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();
111
112              if (orchestrationMessage.HasFlag(OrchestrationMessage.SetEvalHook)) {
113                var instEval = prob.Evaluator as InstrumentedOperator;
114                if (instEval != null && EvalHook != null) instEval.AfterExecutionOperators.Add(EvalHook);
115              }
116
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              }
125
126              Algorithm.Problem = prob;
127
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;
134                      if (!checkedStates.TryGetValue(analyzer.GetType(), out checkedState))
135                        checkedState = analyzer.EnabledByDefault;
136                      multiAnalyzer.Operators.SetItemCheckedState(analyzer, checkedState);
137                    }
138                  }
139                }
140              }
141
142              Algorithm.Prepare(orchestrationMessage.HasFlag(OrchestrationMessage.ClearRuns));
143            }
144            break;
145        }
146      }
147      #endregion
148
149      #region Start
150      if (orchestrationMessage.HasFlag(OrchestrationMessage.Start)) {
151        switch (Algorithm.ExecutionState) {
152          case ExecutionState.Prepared:
153          case ExecutionState.Paused:
154            var trigger = new ManualResetEvent(false);
155            Exception ex = null;
156
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) {
177              message["Results"] = (ResultCollection)Algorithm.Results.Clone();
178              var msg = OrchestrationPort.PrepareMessage();
179              msg["Results"] = (ResultCollection)Algorithm.Results.Clone();
180              OrchestrationPort.SendMessage(msg);
181            } else sendResultMessage = true;
182            break;
183        }
184      }
185      #endregion
186
187      #region Pause
188      if (orchestrationMessage.HasFlag(OrchestrationMessage.Pause)) {
189        if (Algorithm.ExecutionState == ExecutionState.Started) {
190          sendResultMessage = false;
191          try {
192            Algorithm.Pause();
193          }
194          catch (InvalidOperationException) {
195            // ExecutionState might have changed since we accepted the message
196          }
197        }
198      }
199      #endregion
200
201      #region Stop
202      if (orchestrationMessage.HasFlag(OrchestrationMessage.Stop)) {
203        switch (Algorithm.ExecutionState) {
204          case ExecutionState.Started:
205          case ExecutionState.Paused:
206            try {
207              Algorithm.Stop();
208            }
209            catch (InvalidOperationException) {
210              // ExecutionState might have changed since we accepted the message
211            }
212            catch (NullReferenceException) {
213              // BasicAlgorithm might have stopped since we accepted the message
214              // CancellationTokenSource is null in this case
215            }
216            break;
217        }
218      }
219      #endregion
220    }
221    #endregion
222  }
223}
Note: See TracBrowser for help on using the repository browser.