Changeset 15204


Ignore:
Timestamp:
07/11/17 21:58:59 (10 days ago)
Author:
jkarder
Message:

#2258: worked on execution of cross-validation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/Async/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs

    r15190 r15204  
    4040  [StorableClass]
    4141  public sealed class CrossValidation : ParameterizedNamedItem, IAlgorithm, IStorableContent {
    42     private SemaphoreSlim ticket;
    43     private ManualResetEventSlim signal;
     42    private SemaphoreSlim availableWorkers; // limits the number of concurrent algorithm executions
     43    private ManualResetEventSlim allAlgorithmsFinished; // this indicates that all started algorithms have been paused or stopped
    4444
    4545    public CrossValidation()
     
    311311
    312312      OnStarted();
    313       ticket = new SemaphoreSlim(NumberOfWorkers.Value);
    314       signal = new ManualResetEventSlim(false);
     313      availableWorkers = new SemaphoreSlim(NumberOfWorkers.Value, NumberOfWorkers.Value);
     314      allAlgorithmsFinished = new ManualResetEventSlim(false);
    315315
    316316      //start prepared or paused cloned algorithms
    317317      foreach (IAlgorithm clonedAlgorithm in clonedAlgorithms) {
    318         if (pausePending || stopPending) break;
     318        if (pausePending || stopPending || ExecutionState != ExecutionState.Started) break;
    319319        if (clonedAlgorithm.ExecutionState == ExecutionState.Prepared ||
    320320            clonedAlgorithm.ExecutionState == ExecutionState.Paused) {
    321           ticket.Wait();
     321          availableWorkers.Wait();
    322322          lock (locker) {
    323             if (pausePending || stopPending) break;
     323            if (pausePending || stopPending || ExecutionState != ExecutionState.Started) break;
    324324            clonedAlgorithm.StartAsync(cancellationToken);
    325325          }
     
    327327      }
    328328
    329       signal.Wait();
    330       if (pausePending) OnPaused();
    331       else OnStopped();
     329      allAlgorithmsFinished.Wait();
    332330    }
    333331
     
    343341      if (!pausePending) {
    344342        pausePending = true;
    345         var toPause = clonedAlgorithms.Where(x => x.ExecutionState == ExecutionState.Started);
    346         if (toPause.Any()) {
     343        lock (locker) {
     344          var toPause = clonedAlgorithms.Where(x => x.ExecutionState == ExecutionState.Started);
    347345          foreach (var optimizer in toPause) {
    348346            // a race-condition may occur when the optimizer has changed the state by itself in the meantime
     
    350348          }
    351349        }
    352         if (ExecutionState != ExecutionState.Paused) OnPaused();
    353350      }
    354351    }
     
    361358      if (!stopPending) {
    362359        stopPending = true;
    363         var toStop = clonedAlgorithms.Where(x => x.ExecutionState == ExecutionState.Started || x.ExecutionState == ExecutionState.Paused);
    364         if (toStop.Any()) {
     360        lock (locker) {
     361          var toStop = clonedAlgorithms.Where(x => x.ExecutionState == ExecutionState.Started || x.ExecutionState == ExecutionState.Paused);
    365362          foreach (var optimizer in toStop) {
    366363            // a race-condition may occur when the optimizer has changed the state by itself in the meantime
     
    368365          }
    369366        }
    370         if (ExecutionState != ExecutionState.Stopped) OnStopped();
    371367      }
    372368    }
     
    656652    }
    657653    private void ClonedAlgorithm_ExceptionOccurred(object sender, EventArgs<Exception> e) {
     654      Pause();
    658655      OnExceptionOccurred(e.Value);
    659656    }
     
    674671    private void ClonedAlgorithm_Paused(object sender, EventArgs e) {
    675672      lock (locker) {
    676         if (ExecutionState != ExecutionState.Paused) {
    677           if (clonedAlgorithms.All(alg => alg.ExecutionState != ExecutionState.Started)) {
    678             pausePending = true;
    679             signal.Set();
    680             ticket.Release();
    681           }
     673        availableWorkers.Release();
     674        if (clonedAlgorithms.All(alg => alg.ExecutionState != ExecutionState.Started)) {
     675          OnPaused();
     676          allAlgorithmsFinished.Set();
    682677        }
    683678      }
     
    686681    private void ClonedAlgorithm_Stopped(object sender, EventArgs e) {
    687682      lock (locker) {
    688         if (ExecutionState != ExecutionState.Stopped) {
    689           if (clonedAlgorithms.All(alg => alg.ExecutionState == ExecutionState.Stopped || stopPending && alg.ExecutionState == ExecutionState.Prepared)) {
    690             stopPending = true;
    691             signal.Set();
    692           }
    693           ticket.Release();
     683        // if the algorithm was in paused state, its worker has already been released
     684        if (availableWorkers.CurrentCount < NumberOfWorkers.Value)
     685          availableWorkers.Release();
     686        if (clonedAlgorithms.All(alg => alg.ExecutionState == ExecutionState.Stopped)) {
     687          OnStopped();
     688          allAlgorithmsFinished.Set();
     689        } else if (stopPending && clonedAlgorithms.All(alg => alg.ExecutionState == ExecutionState.Prepared || alg.ExecutionState == ExecutionState.Stopped)) {
     690          OnStopped();
     691          allAlgorithmsFinished.Set();
    694692        }
    695693      }
Note: See TracChangeset for help on using the changeset viewer.