Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/28/16 13:08:54 (9 years ago)
Author:
abeham
Message:

#2457: added file system based cache of runs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem.Common/3.3/KnowledgeCenter.cs

    r13804 r13809  
    3939using System.Threading;
    4040using System.Threading.Tasks;
     41using Algorithm = HeuristicLab.Clients.OKB.Administration.Algorithm;
     42using Problem = HeuristicLab.Clients.OKB.Administration.Problem;
    4143using RunCreationClient = HeuristicLab.Clients.OKB.RunCreation.RunCreationClient;
    4244using SingleObjectiveOKBProblem = HeuristicLab.Clients.OKB.RunCreation.SingleObjectiveOKBProblem;
     
    414416
    415417        problemId2ProblemInstanceMapping.Clear();
    416         progress.Status = "Downloading problem instances...";
     418        progress.Status = "Downloading algorithm and problem instances...";
    417419        progress.ProgressValue = 0;
     420
    418421        int[] p = { 0 };
    419422        ProblemInstances.UpdateOfRunsInProgress = true;
    420423        ProblemInstances.Clear();
    421         var characteristics = new HashSet<string>();
    422         var totalProblems = adminClient.Problems.Count(x => x.ProblemClassId == probClassId);
    423         Parallel.ForEach(adminClient.Problems.Where(x => x.ProblemClassId == probClassId), new ParallelOptions { MaxDegreeOfParallelism = 8 }, (pInst) => {
    424           var charas = new List<string>();
    425           IRun probRun = null;
    426           var data = Clients.OKB.Administration.AdministrationClient.GetProblemData(pInst.Id);
    427           if (data != null) {
    428             using (var stream = new MemoryStream(data)) {
    429               try {
    430                 var prob = (IProblem)XmlParser.Deserialize<IContent>(stream);
    431                 probRun = new Run() { Name = prob.Name };
    432                 prob.CollectParameterValues(probRun.Parameters);
    433                 probRun.Parameters["Problem Name"] = new StringValue(prob.Name);
    434                 probRun.Parameters["Problem Type"] = new StringValue(prob.GetType().Name);
    435                 foreach (var v in RunCreationClient.Instance.GetCharacteristicValues(pInst.Id)) {
    436                   probRun.Results.Add("Characteristic." + v.Name, RunCreationClient.Instance.ConvertToItem(v));
    437                   charas.Add("Characteristic." + v.Name);
    438                 }
    439               } catch { }
    440               stream.Close();
    441             }
    442             if (probRun != null) {
    443               lock (characteristics) {
    444                 problemId2ProblemInstanceMapping.Add(pInst.Id, probRun);
    445                 ProblemInstances.Add(probRun);
    446                 progress.Status = string.Format("Downloaded problem {0} (okb-id: {1})....", pInst.Name, pInst.Id);
    447                 p[0]++;
    448                 progress.ProgressValue = p[0] / (double)totalProblems;
    449                 foreach (var c in charas) characteristics.Add(c);
    450               }
    451             }
    452           }
    453         });
    454        
    455424        algorithmId2AlgorithmInstanceMapping.Clear();
    456425        algorithmId2RunMapping.Clear();
    457426        algorithmInstances.Clear();
    458         progress.Status = "Downloading algorithm instances...";
    459         progress.ProgressValue = 0;
    460         p[0] = 0;
    461         Parallel.ForEach(adminClient.Algorithms, new ParallelOptions { MaxDegreeOfParallelism = 8 }, (algInst) => {
    462           IAlgorithm alg = null;
    463           var data = Clients.OKB.Administration.AdministrationClient.GetAlgorithmData(algInst.Id);
    464           if (data != null) {
    465             using (var stream = new MemoryStream(data)) {
    466               try {
    467                 alg = (IAlgorithm)XmlParser.Deserialize<IContent>(stream);
    468               } catch { }
    469               stream.Close();
    470             }
    471             if (alg != null) {
    472               lock (algorithmId2AlgorithmInstanceMapping) {
    473                 algorithmInstances.Add(alg);
    474                 algorithmId2AlgorithmInstanceMapping.Add(algInst.Id, alg);
    475                 progress.Status = string.Format("Downloaded algorithm {0} (okb-id: {1})...", algInst.Name, algInst.Id);
    476                 p[0]++;
    477                 progress.ProgressValue = p[0] / (double)adminClient.Algorithms.Count;
    478               }
    479             }
     427
     428        var characteristics = new HashSet<string>();
     429        var totalProblems = adminClient.Problems.Count(x => x.ProblemClassId == probClassId);
     430        var totalAlgorithms = adminClient.Algorithms.Count;
     431        var problems = adminClient.Problems.Where(x => x.ProblemClassId == probClassId);
     432        var algorithms = adminClient.Algorithms;
     433        var combined = problems.Cast<object>().Concat(algorithms.Cast<object>()).Shuffle(new MersenneTwister());
     434        Parallel.ForEach(combined, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, (inst) => {
     435          var pInst = inst as Clients.OKB.Administration.Problem;
     436          if (pInst != null) DownloadProblemInstance(progress, pInst, p, totalProblems + totalAlgorithms, characteristics);
     437          else {
     438            var aInst = inst as Clients.OKB.Administration.Algorithm;
     439            DownloadAlgorithmInstance(progress, aInst, p, totalProblems + totalAlgorithms);
    480440          }
    481441        });
     
    490450       
    491451        var runList = new List<IRun>();
    492         var runIds = queryClient.GetRunIds(problemClassFilter).ToList();
     452        var runIds = LoadRunsFromCache(queryClient.GetRunIds(problemClassFilter), runList, progress);
    493453        var batches = runIds.Select((v, i) => new { Idx = i, Val = v }).GroupBy(x => x.Idx / 500, x => x.Val);
    494         Parallel.ForEach(batches.Select(x => x.ToList()), new ParallelOptions { MaxDegreeOfParallelism = 4 }, (batch) => {
     454        Parallel.ForEach(batches.Select(x => x.ToList()), new ParallelOptions { MaxDegreeOfParallelism = Math.Min(Environment.ProcessorCount, 4) },
     455          (batch) => {
    495456          var okbRuns = queryClient.GetRunsWithValues(batch, true, interestingValues);
    496           var hlRuns = okbRuns.AsParallel().Select(x => new { AlgorithmId = x.Algorithm.Id, Run = queryClient.ConvertToOptimizationRun(x) }).ToList();
     457          var hlRuns = okbRuns.AsParallel().Select(x => new { AlgorithmId = x.Algorithm.Id, RunId = x.Id, Run = queryClient.ConvertToOptimizationRun(x) }).ToList();
    497458          lock (runList) {
     459            var toCache = new List<Tuple<long, long, IRun>>();
    498460            foreach (var r in hlRuns) {
    499461              algorithmId2RunMapping.Add(r.AlgorithmId, r.Run);
    500462              runList.Add(r.Run);
    501             }
     463              toCache.Add(Tuple.Create(r.AlgorithmId, r.RunId, r.Run));
     464            }
     465            SaveToCache(toCache);
    502466            progress.Status = string.Format("Downloaded runs {0} to {1} of {2}...", p[0], p[0] + batch.Count, count);
    503467            p[0] += batch.Count;
     
    558522      } finally { progress.Finish(); ProblemInstances.UpdateOfRunsInProgress = false; }
    559523      UpdateInstanceProjection(ProblemInstances.ResultNames.Where(x => x.StartsWith("Characteristic.")).ToArray());
     524    }
     525
     526    private void DownloadAlgorithmInstance(IProgress progress, Algorithm algInst, int[] p, int total) {
     527      IAlgorithm alg = null;
     528      var data = Clients.OKB.Administration.AdministrationClient.GetAlgorithmData(algInst.Id);
     529      if (data != null) {
     530        using (var stream = new MemoryStream(data)) {
     531          try {
     532            alg = (IAlgorithm)XmlParser.Deserialize<IContent>(stream);
     533          } catch { }
     534          stream.Close();
     535        }
     536        if (alg != null) {
     537          lock (progress) {
     538            algorithmInstances.Add(alg);
     539            algorithmId2AlgorithmInstanceMapping.Add(algInst.Id, alg);
     540            progress.Status = string.Format("Downloaded algorithm {0} (okb-id: {1})...", algInst.Name, algInst.Id);
     541            p[0]++;
     542            progress.ProgressValue = p[0] / (double)total;
     543          }
     544        }
     545      }
     546    }
     547
     548    private void DownloadProblemInstance(IProgress progress, Problem pInst, int[] p, int totalProblems, HashSet<string> characteristics) {
     549      var charas = new List<string>();
     550      IRun probRun = null;
     551      var data = Clients.OKB.Administration.AdministrationClient.GetProblemData(pInst.Id);
     552      if (data != null) {
     553        using (var stream = new MemoryStream(data)) {
     554          try {
     555            var prob = (IProblem)XmlParser.Deserialize<IContent>(stream);
     556            probRun = new Run() {Name = prob.Name};
     557            prob.CollectParameterValues(probRun.Parameters);
     558            probRun.Parameters["Problem Name"] = new StringValue(prob.Name);
     559            probRun.Parameters["Problem Type"] = new StringValue(prob.GetType().Name);
     560            foreach (var v in RunCreationClient.Instance.GetCharacteristicValues(pInst.Id)) {
     561              probRun.Results.Add("Characteristic." + v.Name, RunCreationClient.Instance.ConvertToItem(v));
     562              charas.Add("Characteristic." + v.Name);
     563            }
     564          } catch { }
     565          stream.Close();
     566        }
     567        if (probRun != null) {
     568          lock (progress) {
     569            problemId2ProblemInstanceMapping.Add(pInst.Id, probRun);
     570            ProblemInstances.Add(probRun);
     571            progress.Status = string.Format("Downloaded problem {0} (okb-id: {1})....", pInst.Name, pInst.Id);
     572            p[0]++;
     573            progress.ProgressValue = p[0] / (double)totalProblems;
     574            foreach (var c in charas) characteristics.Add(c);
     575          }
     576        }
     577      }
     578    }
     579
     580    private List<long> LoadRunsFromCache(IEnumerable<long> runIds, List<IRun> runList, IProgress progress) {
     581      var hashSet = new HashSet<long>(runIds);
     582      var total = hashSet.Count;
     583      try {
     584        var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "HeuristicLab.OKB", "cache", "runs");
     585        Parallel.ForEach(Directory.EnumerateDirectories(path).Select((d, i) => new { Index = i, Directory = d }).GroupBy(x => x.Index / 100), new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
     586          (folderGroup) => {
     587          var localRunList = new List<Tuple<long, long, IRun>>();
     588          foreach (var runPath in folderGroup.Select(x => x.Directory)) {
     589            long runId;
     590            var runFolder = new DirectoryInfo(runPath).Name;
     591            if (!long.TryParse(runFolder, out runId) || !hashSet.Contains(runId)) continue;
     592            var runFilePath = Directory.EnumerateFiles(runPath).Single();
     593            var runFileName = Path.GetFileNameWithoutExtension(runFilePath);
     594            long algId;
     595            if (!long.TryParse(runFileName, out algId)) continue;
     596            IRun run = null;
     597            try {
     598              using (var file = File.OpenRead(runFilePath))
     599                run = XmlParser.Deserialize<IRun>(file);
     600            } catch {
     601              File.Delete(runFilePath);
     602              Directory.Delete(runPath);
     603            }
     604            if (run != null) localRunList.Add(Tuple.Create(algId, runId, run));
     605          }
     606          lock (runList) {
     607            foreach (var r in localRunList) {
     608              hashSet.Remove(r.Item2);
     609              algorithmId2RunMapping.Add(r.Item1, r.Item3);
     610              runList.Add(r.Item3);
     611            }
     612            progress.Status = string.Format("Retrieved {0} of {1} from cache", runList.Count, total);
     613            progress.ProgressValue = (double)runList.Count / total;
     614          }
     615        });
     616      } catch { }
     617      return hashSet.ToList();
     618    }
     619
     620    private void SaveToCache(IEnumerable<Tuple<long, long, IRun>> runs) {
     621      try {
     622        var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "HeuristicLab.OKB", "cache", "runs");
     623        if (!Directory.Exists(path)) Directory.CreateDirectory(path);
     624        foreach (var r in runs) {
     625          var runPath = Path.Combine(path, r.Item2.ToString());
     626          if (!Directory.Exists(runPath)) Directory.CreateDirectory(runPath);
     627          using (var file = File.Open(Path.Combine(runPath, r.Item1.ToString()), FileMode.Create, FileAccess.ReadWrite)) {
     628            XmlGenerator.Serialize(r.Item3, file);
     629          }
     630        }
     631      } catch { }
    560632    }
    561633
Note: See TracChangeset for help on using the changeset viewer.