- Timestamp:
- 01/12/18 14:24:16 (7 years ago)
- Location:
- branches/GeneralizedQAP/HeuristicLab.Optimization
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GeneralizedQAP/HeuristicLab.Optimization
- Property svn:mergeinfo changed
-
branches/GeneralizedQAP/HeuristicLab.Optimization/3.3/MetaOptimizers/BatchRun.cs
r15603 r15605 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 242 242 if (ExecutionState == ExecutionState.Paused || ExecutionState == ExecutionState.Stopped) break; 243 243 Optimizer.Prepare(); 244 if (ExecutionState == ExecutionState.Paused || ExecutionState == ExecutionState.Stopped) break; 244 245 } 245 246 } … … 255 256 if (Optimizer.ExecutionState != ExecutionState.Started) return; 256 257 // a race-condition may occur when the optimizer has changed the state by itself in the meantime 257 try { Optimizer.Pause(); } catch (InvalidOperationException) { } 258 try { Optimizer.Pause(); } catch (InvalidOperationException) { } catch (NotSupportedException) { } 258 259 } 259 260 public void Stop() { -
branches/GeneralizedQAP/HeuristicLab.Optimization/3.3/MetaOptimizers/Experiment.cs
r15603 r15605 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 93 93 } 94 94 95 [Storable] 96 private int numberOfWorkers = 1; 97 public int NumberOfWorkers { 98 get { return numberOfWorkers; } 99 set { 100 if (value < 1) throw new ArgumentException("Number of Workers must not be lower than one."); 101 numberOfWorkers = value; 102 } 103 } 104 95 105 public IEnumerable<IOptimizer> NestedOptimizers { 96 106 get { … … 107 117 private bool experimentStarted = false; 108 118 private bool experimentStopped = false; 109 private readonly ManualResetEventSlim allOptimizerFinished = new ManualResetEventSlim(false); // this indicates that all started optimizers have been paused or stopped 119 120 // track already started optimizers (.StartAsync does not set the executionstate immediately) 121 // and to avoid restarting optimizers that were manually paused/stopped by the user 122 private readonly IDictionary<IOptimizer, Task> startedOptimizers = new Dictionary<IOptimizer, Task>(); 123 private IEnumerable<IOptimizer> StartableOptimizers { 124 get { 125 return Optimizers 126 .Where(x => x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused) 127 .Where(o => !startedOptimizers.ContainsKey(o)); // all startable optimizers that were not startet yet 128 } 129 } 110 130 111 131 public Experiment() … … 151 171 experimentStarted = original.experimentStarted; 152 172 experimentStopped = original.experimentStopped; 173 numberOfWorkers = original.numberOfWorkers; 153 174 Initialize(); 154 175 } … … 188 209 if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused)) 189 210 throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState)); 190 if (!Optimizers.Any(x => x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused)) return; 211 212 startedOptimizers.Clear(); 213 if (!StartableOptimizers.Any()) return; 191 214 192 215 experimentStarted = true; 193 216 experimentStopped = false; 194 allOptimizerFinished.Reset(); 195 IOptimizer optimizer; 196 while ((optimizer = Optimizers.FirstOrDefault(x => x.ExecutionState == ExecutionState.Prepared || x.ExecutionState == ExecutionState.Paused)) != null) { 197 // a race-condition may occur when the optimizer has changed the state by itself in the meantime 198 try { optimizer.Start(cancellationToken); } catch (InvalidOperationException) { } 199 if (ExecutionState == ExecutionState.Paused || ExecutionState == ExecutionState.Stopped) break; 200 } 201 allOptimizerFinished.Wait(); 217 218 using (var availableWorkers = new SemaphoreSlim(NumberOfWorkers, NumberOfWorkers)) { 219 while (StartableOptimizers.Any()) { 220 try { 221 availableWorkers.Wait(cancellationToken); 222 var optimizer = StartableOptimizers.FirstOrDefault(); 223 if (experimentStopped || !experimentStarted || optimizer == null) break; 224 225 var startedTask = optimizer.StartAsync(cancellationToken).ContinueWith(async t => { 226 availableWorkers.Release(); // is guaranteed to be not disposed yet because Task.WaitAll blocks before the end of the using 227 await t; // trigger a potential exception on the optimizerTask 228 }); 229 startedOptimizers.Add(optimizer, startedTask.Unwrap()); // unwrap task because lambda of .ContinueWith is async 230 } catch (InvalidOperationException) { } catch (OperationCanceledException) { } 231 } 232 233 Task.WaitAll(startedOptimizers.Values.ToArray()); // retrieve exeptions of the asyncrounously started optimizer 234 } 202 235 } 203 236 public async Task StartAsync() { await StartAsync(CancellationToken.None); } … … 214 247 foreach (IOptimizer optimizer in Optimizers.Where(x => x.ExecutionState == ExecutionState.Started)) { 215 248 // a race-condition may occur when the optimizer has changed the state by itself in the meantime 216 try { optimizer.Pause(); } catch (InvalidOperationException) { } 249 try { optimizer.Pause(); } catch (InvalidOperationException) { } catch (NotSupportedException) { } 217 250 } 218 251 } … … 249 282 public event EventHandler Prepared; 250 283 private void OnPrepared() { 284 if (ExecutionState == ExecutionState.Prepared) return; 251 285 ExecutionState = ExecutionState.Prepared; 252 286 EventHandler handler = Prepared; … … 255 289 public event EventHandler Started; 256 290 private void OnStarted() { 291 if (ExecutionState == ExecutionState.Started) return; 257 292 ExecutionState = ExecutionState.Started; 258 293 EventHandler handler = Started; … … 261 296 public event EventHandler Paused; 262 297 private void OnPaused() { 298 if (ExecutionState == ExecutionState.Paused) return; 263 299 ExecutionState = ExecutionState.Paused; 264 allOptimizerFinished.Set();265 300 EventHandler handler = Paused; 266 301 if (handler != null) handler(this, EventArgs.Empty); … … 268 303 public event EventHandler Stopped; 269 304 private void OnStopped() { 305 if (ExecutionState == ExecutionState.Stopped) return; 270 306 ExecutionState = ExecutionState.Stopped; 271 allOptimizerFinished.Set();272 307 EventHandler handler = Stopped; 273 308 if (handler != null) handler(this, EventArgs.Empty); … … 353 388 } 354 389 private void optimizer_Paused(object sender, EventArgs e) { 355 lock (locker) 356 if (Optimizers.All(x => x.ExecutionState != ExecutionState.Started)) OnPaused(); 390 UpdateExecutionState(); 357 391 } 358 392 private void optimizer_Prepared(object sender, EventArgs e) { 359 lock (locker) 360 if (Optimizers.All(x => x.ExecutionState == ExecutionState.Prepared)) OnPrepared(); 393 UpdateExecutionState(); 361 394 } 362 395 private void optimizer_Started(object sender, EventArgs e) { … … 365 398 } 366 399 private void optimizer_Stopped(object sender, EventArgs e) { 400 UpdateExecutionState(); 401 } 402 private void UpdateExecutionState() { 403 // Execution states of the Experiment are determined using the following _basic_ rules: 404 // if any Optimizer is Started => Experiment is Started (2. if) 405 // if any Optimizer is Paused => Experiment is Paused (3. if) 406 // if any Optimizer is Prepared => Experiment is Prepared (5. if) 407 // else (all Optimizer are Stopped) => Experiment is Stopped (6. if) 408 // Additional there are two extra rules: 409 // if the Experiment is running and there are still optimizers that can be started => keep the Experiment Running (1. if) 410 // if experiment-stop is pending: Stop Experiment even if there are still Prepared Optimizer (4. if) 411 367 412 lock (locker) { 368 if (experimentStopped) { 369 if (Optimizers.All(x => (x.ExecutionState == ExecutionState.Stopped) || (x.ExecutionState == ExecutionState.Prepared))) OnStopped(); 370 } else { 371 if (experimentStarted && Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused))) return; 372 else if (Optimizers.All(x => x.ExecutionState == ExecutionState.Stopped)) OnStopped(); 373 else if (Optimizers.Any(x => (x.ExecutionState == ExecutionState.Prepared) || (x.ExecutionState == ExecutionState.Paused)) && Optimizers.All(o => o.ExecutionState != ExecutionState.Started)) OnPaused(); 374 } 375 } 376 } 413 // 1. experiment is running & further startable optimizers are available => continue executing 414 if (experimentStarted && StartableOptimizers.Any()) 415 return; 416 417 // 2. any optimizer is running => continue executing 418 if (Optimizers.Any(x => x.ExecutionState == ExecutionState.Started)) 419 return; 420 421 experimentStarted = false; 422 // 3. any optimizer is paused => experiment paused 423 if (Optimizers.Any(x => x.ExecutionState == ExecutionState.Paused)) 424 OnPaused(); 425 426 // 4. stop pending & all optimizers either stopped or prepared => experiment stopped 427 else if (experimentStopped) 428 OnStopped(); 429 430 // 5. any optimizer prepared => experiment prepared 431 else if (Optimizers.Any(x => x.ExecutionState == ExecutionState.Prepared)) 432 OnPrepared(); 433 434 // 6. (else) all optimizers stopped 435 else 436 OnStopped(); 437 } 438 } 439 377 440 private void optimizer_Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) { 378 441 lock (runsLocker) { -
branches/GeneralizedQAP/HeuristicLab.Optimization/3.3/MetaOptimizers/TimeLimitRun.cs
r15603 r15605 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab.
Note: See TracChangeset
for help on using the changeset viewer.