Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization/3.3/OrchestratedAlgorithmNode.cs

Last change on this file was 14635, checked in by jkarder, 8 years ago

#2205: worked on optimization networks

  • created default parameters for orchestration and evaluation ports
  • adapted FeatureSelectionNetwork
File size: 9.4 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      Ports.Add(CreateOrchestrationPort<IProblem>(OrchestrationPortName));
76      Ports.Add(CreateEvaluationPort<IItem>(EvaluationPortName, "Solution", "Quality"));
77
78      RegisterEvents();
79    }
80
81    public override IDeepCloneable Clone(Cloner cloner) {
82      return new OrchestratedAlgorithmNode(this, cloner);
83    }
84
85    [StorableHook(HookType.AfterDeserialization)]
86    private void AfterDeserialization() {
87      RegisterEvents();
88    }
89
90    private void RegisterEvents() {
91      OrchestrationPort.MessageReceived += OrchestrationPort_MessageReceived;
92    }
93
94    protected IMessagePort CreateOrchestrationPort<T>(string portName) where T : class, IProblem {
95      var orchestrationPort = new MessagePort(portName);
96      orchestrationPort.Parameters.Add(new PortParameter<EnumValue<OrchestrationMessage>>("OrchestrationMessage") {
97        Type = PortParameterType.Input
98      });
99      orchestrationPort.Parameters.Add(new PortParameter<T>("Problem") {
100        Type = PortParameterType.Input
101      });
102      orchestrationPort.Parameters.Add(new PortParameter<ResultCollection>("Results") {
103        Type = PortParameterType.Output
104      });
105      return orchestrationPort;
106    }
107
108    protected IMessagePort CreateEvaluationPort<T>(string portName, string solutionName, string qualityName) where T : class, IItem {
109      var evaluationPort = new MessagePort(portName);
110      evaluationPort.Parameters.Add(new PortParameter<T>(solutionName) {
111        Type = PortParameterType.Output
112      });
113      evaluationPort.Parameters.Add(new PortParameter<DoubleValue>(qualityName) {
114        Type = PortParameterType.Input | PortParameterType.Output
115      });
116      return evaluationPort;
117    }
118
119    #region Port Events
120    private void OrchestrationPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
121      var requestMessage = e.Value;
122      var messageFlags = ((EnumValue<OrchestrationMessage>)requestMessage["OrchestrationMessage"]).Value;
123
124      #region Prepare
125      if (messageFlags.HasFlag(OrchestrationMessage.Prepare)) {
126        switch (Algorithm.ExecutionState) {
127          case ExecutionState.Prepared:
128          case ExecutionState.Paused:
129          case ExecutionState.Stopped:
130            var problem = (IProblem)requestMessage["Problem"];
131            if (problem != null) {
132              problem = (IProblem)problem.Clone();
133
134              var heuristicOptimizationProblem = problem as IHeuristicOptimizationProblem;
135              if (heuristicOptimizationProblem != null && messageFlags.HasFlag(OrchestrationMessage.SetEvalHook)) {
136                var instEval = heuristicOptimizationProblem.Evaluator as InstrumentedOperator;
137                if (instEval != null && EvalHook != null) instEval.AfterExecutionOperators.Add(EvalHook);
138              }
139
140              IParameter analyzerParameter = null;
141              IMultiAnalyzer multiAnalyzer = null;
142              var checkedStates = new Dictionary<Type, bool>();
143              if (Algorithm.Parameters.TryGetValue("Analyzer", out analyzerParameter)) {
144                multiAnalyzer = analyzerParameter.ActualValue as IMultiAnalyzer;
145                foreach (var item in multiAnalyzer.Operators)
146                  checkedStates.Add(item.GetType(), multiAnalyzer.Operators.ItemChecked(item));
147              }
148
149              Algorithm.Problem = problem;
150
151              if (multiAnalyzer != null) {
152                if (Algorithm.Parameters.TryGetValue("Analyzer", out analyzerParameter)) {
153                  multiAnalyzer = analyzerParameter.ActualValue as IMultiAnalyzer;
154                  if (multiAnalyzer != null && checkedStates.Any()) {
155                    foreach (var analyzer in multiAnalyzer.Operators) {
156                      bool checkedState;
157                      if (!checkedStates.TryGetValue(analyzer.GetType(), out checkedState))
158                        checkedState = analyzer.EnabledByDefault;
159                      multiAnalyzer.Operators.SetItemCheckedState(analyzer, checkedState);
160                    }
161                  }
162                }
163              }
164            }
165
166
167            Algorithm.Prepare(messageFlags.HasFlag(OrchestrationMessage.ClearRuns));
168            break;
169        }
170      }
171      #endregion
172
173      #region Start
174      if (messageFlags.HasFlag(OrchestrationMessage.Start)) {
175        switch (Algorithm.ExecutionState) {
176          case ExecutionState.Prepared:
177          case ExecutionState.Paused:
178            var trigger = new ManualResetEvent(false);
179            Exception ex = null;
180
181            EventHandler onStopped = null;
182            EventHandler<EventArgs<Exception>> onExceptionOccurred = null;
183            Algorithm.Stopped += onStopped = (src, args) => {
184              Algorithm.Stopped -= onStopped;
185              Algorithm.ExceptionOccurred -= onExceptionOccurred;
186              trigger.Set();
187            };
188            Algorithm.ExceptionOccurred += onExceptionOccurred = (src, args) => {
189              Algorithm.Stopped -= onStopped;
190              Algorithm.ExceptionOccurred -= onExceptionOccurred;
191              ex = args.Value;
192              trigger.Set();
193            };
194
195            Algorithm.Start();
196            trigger.WaitOne();
197
198            if (ex != null) throw ex;
199
200            if (sendResultMessage) {
201              requestMessage["Results"] = (ResultCollection)Algorithm.Results.Clone();
202              var responseMessage = OrchestrationPort.PrepareMessage();
203              responseMessage["Results"] = (ResultCollection)Algorithm.Results.Clone();
204              OrchestrationPort.SendMessage(responseMessage);
205            } else sendResultMessage = true;
206            break;
207        }
208      }
209      #endregion
210
211      #region Pause
212      if (messageFlags.HasFlag(OrchestrationMessage.Pause)) {
213        if (Algorithm.ExecutionState == ExecutionState.Started) {
214          sendResultMessage = false;
215          try {
216            Algorithm.Pause();
217          } catch (InvalidOperationException) {
218            // ExecutionState might have changed since we accepted the message
219          }
220        }
221      }
222      #endregion
223
224      #region Stop
225      if (messageFlags.HasFlag(OrchestrationMessage.Stop)) {
226        switch (Algorithm.ExecutionState) {
227          case ExecutionState.Started:
228          case ExecutionState.Paused:
229            try {
230              Algorithm.Stop();
231            } catch (InvalidOperationException) {
232              // ExecutionState might have changed since we accepted the message
233            } catch (NullReferenceException) {
234              // BasicAlgorithm might have stopped since we accepted the message
235              // CancellationTokenSource is null in this case
236            }
237            break;
238        }
239      }
240      #endregion
241    }
242    #endregion
243  }
244}
Note: See TracBrowser for help on using the repository browser.