source: branches/MPI/HeuristicLab.MPIAlgorithmRunner/3.3/Program.cs @ 7544

Last change on this file since 7544 was 7544, checked in by svonolfe, 8 years ago

Improved performance, added MPISolutionsCreator (#1542)

File size: 8.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 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.Text;
26using HeuristicLab.Optimization;
27using HeuristicLab.Persistence.Default.Xml;
28using System.Threading;
29using Microsoft.Hpc.Scheduler;
30using System.Net;
31using System.ServiceModel;
32using HeuristicLab.Operators.MPISupport;
33using HeuristicLab.Core;
34using System.Diagnostics;
35
36namespace HeuristicLab.MPIAlgorithmRunner {
37  class Program {
38    EventWaitHandle waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
39
40    static void Main(string[] args) {
41      if (args.Length == 2) {
42        string fileName = args[0];
43        string resultName = args[1];
44
45        using (new MPI.Environment(ref args)) {
46          if (MPI.Communicator.world.Rank != 0) {
47            Program p = new Program();
48            p.StartAlgorithm(fileName, resultName + MPI.Communicator.world.Rank + ".hl");
49          }
50        }
51      } else {
52        using (new MPI.Environment(ref args)) {
53          int clients = MPI.Communicator.world.Group.Size - 1;
54          Console.WriteLine("Clients: " + clients);
55
56          MPI.Communicator communicator = MPI.Communicator.world.Clone() as MPI.Communicator;
57
58          if (communicator.Rank == 0) {
59            ServiceHost service = AlgorithmBroker.StartService(communicator);
60            AlgorithmBroker broker = (service.SingletonInstance as AlgorithmBroker);
61
62            string address = GetAddress(service);
63            SetJobStatus(address);
64
65            bool[] finished = new bool[clients];
66            int finishedCount = 0;
67
68            while (finishedCount != clients) {
69              ItemList<ResultCollection> results = new ItemList<ResultCollection>();
70
71              for (int i = 0; i < clients; i++) {
72                if (!finished[i]) {
73                  int client = i + 1;
74                  ResultCollection result = communicator.Receive<MPITransportWrapper<ResultCollection>>(client, 1).InnerItem;
75
76                  Console.WriteLine("Received result " + result);
77
78                  if (results.Count != clients) {
79                    results.Add(result);
80                  } else {
81                    results[i] = result;
82                  }
83
84                  Console.WriteLine("Probing...");
85                  if (communicator.ImmediateProbe(client, 2) != null) {
86                    finished[i] = true;
87                    finishedCount++;
88                  }
89                }
90              }
91
92              Console.WriteLine("Update results");
93              lock (broker.resultLocker)
94                broker.Results = results;
95            }
96
97            lock (broker.ExitWaitHandle) {
98              broker.Terminated = true;
99            }
100
101            broker.ExitWaitHandle.WaitOne();
102            Console.WriteLine("Finished.");
103            Thread.Sleep(1000);
104            service.Close();
105          } else {
106              Program p = new Program();
107              p.StartAlgorithm(communicator);
108          }
109        }
110      }       
111    }
112
113    private static void SetJobStatus(string address) {
114      Console.WriteLine("Started service... at " + address);
115
116      // Discover the job's context from the environment
117      String headNodeName = System.Environment.GetEnvironmentVariable("CCP_SCHEDULER");
118      int jobId = System.Convert.ToInt32(System.Environment.GetEnvironmentVariable("CCP_JOBID"));
119
120      Console.WriteLine(jobId + "@" + headNodeName);
121
122      // Connect to the head node and get the job
123      IScheduler scheduler = new Scheduler();
124      scheduler.Connect(headNodeName);
125      ISchedulerJob job = scheduler.OpenJob(jobId);
126
127      job.SetCustomProperty("address", address);
128
129      job.Commit();
130    }
131
132    private static string GetAddress(ServiceHost service) {
133      IPHostEntry IPHost = Dns.GetHostByName(Dns.GetHostName());
134      string address = "net.tcp://" + IPHost.AddressList[0].ToString() + ":" + service.ChannelDispatchers[0].Listener.Uri.Port + "/AlgorithmBroker";
135
136      return address;
137    }
138
139    public void StartAlgorithm(MPI.Communicator communicator) {
140      IAlgorithm alg = communicator.Receive<MPITransportWrapper<IAlgorithm>>(0, 0).InnerItem;
141      int updateInterval = communicator.Receive<int>(0, 1);
142
143      Console.WriteLine("Starting algorithm...");
144
145      alg.Prepare(true);
146      waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
147      alg.Started += new EventHandler(alg_Started);
148      alg.Start();
149
150      waitHandle.WaitOne();
151
152      alg.Started -= new EventHandler(alg_Started);
153
154      while (alg.ExecutionState != ExecutionState.Stopped) {
155        Console.WriteLine("Pausing alg...");
156        alg.Pause();
157
158        while (alg.ExecutionState == ExecutionState.Started) {
159          Thread.Sleep(100);
160        }
161
162        communicator.Send<MPITransportWrapper<ResultCollection>>(
163          new MPITransportWrapper<ResultCollection>(alg.Results), 0, 1);
164
165        Console.WriteLine("Sending update...");
166
167        Console.WriteLine("Resuming alg...");
168        if (alg.ExecutionState == ExecutionState.Paused)
169          alg.Start();
170        Thread.Sleep(updateInterval);
171      }
172
173      communicator.Send<int>(communicator.Rank, 0, 2);
174      communicator.Send<MPITransportWrapper<ResultCollection>>(
175          new MPITransportWrapper<ResultCollection>(alg.Results), 0, 1);
176    }
177
178    void alg_Started(object sender, EventArgs e) {
179      waitHandle.Set();
180    }
181
182    public void StartAlgorithm(string fileName, string resultName) {
183      IAlgorithm alg = XmlParser.Deserialize<HeuristicLab.Optimization.IAlgorithm>(fileName);
184
185      alg.Stopped += new EventHandler(algorithm_Stopped);
186      waitHandle.Reset();
187
188      alg.Prepare(true);
189      alg.Start();
190      Console.WriteLine("ALG STARTED");
191      Stopwatch sw = new Stopwatch();
192      sw.Start();
193
194     /* Thread.Sleep(10000);     
195      Thread t = new Thread(delegate() {
196        while (true) {
197          if (alg.ExecutionState == Core.ExecutionState.Started) {
198            alg.Pause();
199
200            while (alg.ExecutionState == Core.ExecutionState.Started)
201              Thread.Sleep(100);
202
203            if (alg.Results.ContainsKey("Best valid Solution Distance")) {
204              Console.WriteLine("BestDistance: " + alg.Results["Best valid Solution Distance"].Value.ToString());
205            }
206
207            if (alg.Results.ContainsKey("Best valid Solution Vehicles")) {
208              Console.WriteLine("BestVehicles: " + alg.Results["Best valid Solution Vehicles"].Value.ToString());
209            }
210
211            XmlGenerator.Serialize(alg, resultName);
212            alg.Start();
213          }
214
215          Thread.Sleep(300000);
216        }
217      });
218      t.IsBackground = true;
219      t.Start();*/
220
221      waitHandle.WaitOne();
222
223      Console.WriteLine("ALG STOPPED");
224      sw.Stop();
225      Console.WriteLine("TIME: " + sw.ElapsedMilliseconds + "ms");
226
227      if (alg.Results.ContainsKey("Best valid Solution Distance") && alg.Results.ContainsKey("Best valid Solution Vehicles")) {
228        Console.WriteLine("BestDistance: " + alg.Results["Best valid Solution Distance"].Value.ToString() + ", " + 
229                          "BestVehicles: " + alg.Results["Best valid Solution Vehicles"].Value.ToString());
230      }
231
232      XmlGenerator.Serialize(alg, resultName);
233    }
234
235    void algorithm_Stopped(object sender, EventArgs e) {
236      waitHandle.Set(); 
237    }
238  }
239}
Note: See TracBrowser for help on using the repository browser.