Tracker.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package solver
  2. import (
  3. "strconv"
  4. "time"
  5. )
  6. // Keep track and output progress.
  7. // Calculate rates, display percentages, estimate the ETA till completion.
  8. func (solver *Solver) Tracker() {
  9. // Add time tracking
  10. defer solver.timeTrack(time.Now(), "Validated solutions")
  11. solver.Outp.Println("Validating solutions")
  12. // Determine if the main-loop is done
  13. var done bool
  14. // Tracking progress in percentages
  15. var percentage float32
  16. // Tracking progress in validated solutions
  17. var track int
  18. // Tracking the rate, starting point
  19. var rateStart uint64
  20. // Tracking the rate, difference between previous iterations
  21. var rateDiff uint64
  22. // Tracking duration
  23. var timerStart = time.Now()
  24. // Estimation how long it will take
  25. var est_fin string
  26. // Required to read memory usage
  27. // var memStats runtime.MemStats
  28. // While not needed for rateDiff anymore, it makes estimation calculations more accurate. ☹️
  29. time.Sleep(time.Second)
  30. // for solver.Iter != solver.counter { // Start for-loop
  31. for !done {
  32. // Determine how far we are.
  33. percentage = (float32(solver.counter.Load()) / (float32(solver.Iter) / 100))
  34. // Reset the loop
  35. rateDiff = solver.counter.Load() - rateStart
  36. if track <= int(percentage) || rateDiff == 0 { // Start if-statement
  37. // Make sure something happened, making rateStart the only reliable variable
  38. if solver.Iter == solver.counter.Load() {
  39. percentage = 100
  40. solver.counter.Store(solver.Iter)
  41. done = true
  42. }
  43. timer_elapsed := time.Since(timerStart)
  44. solver.rates = append(solver.rates, rateDiff)
  45. rate_avg := solver.calcAVG()
  46. // Estimate when this is finished
  47. if rateDiff == 0 {
  48. est_fin = "N/A"
  49. } else {
  50. duration_int := (solver.Iter - solver.counter.Load()) / rate_avg
  51. duration_string := strconv.Itoa(int(duration_int)) + "s"
  52. est, err := time.ParseDuration(duration_string)
  53. if err != nil {
  54. est_fin = "parse error"
  55. } else {
  56. est_fin = est.String()
  57. }
  58. }
  59. // Printing the progress
  60. solver.Outp.Println("Processing: " + strconv.Itoa(int(percentage)) + "% (" + strconv.FormatUint(solver.counter.Load(), 10) + "/" + strconv.Itoa(int(solver.Iter)) + "); Rate: " + strconv.FormatUint(rateDiff, 10) + "/sec for " + timer_elapsed.String() + "; Time left (est.): " + est_fin)
  61. solver.Controller.Rates = append(solver.Controller.Rates, rateDiff)
  62. // TODO: REMOVE
  63. // runtime.ReadMemStats(&memStats)
  64. // solver.Outp.Println("GoRoutines: " + strconv.Itoa(runtime.NumGoroutine()) + "; memStats.Sys (Bytes): " + humanize.Bytes(memStats.Sys) + "; memStats.Sys (iBytes): " + humanize.IBytes(memStats.Sys) + "; memStas.NumGC: " + strconv.Itoa(int(memStats.NumGC)) + ";")
  65. // After we are done printing, exit this for-loop
  66. if percentage == 100 {
  67. break
  68. }
  69. // Wrap up the loop or break
  70. if int(percentage) > track {
  71. track = int(percentage)
  72. } else {
  73. track = track + 1
  74. }
  75. timerStart = time.Now()
  76. }
  77. // Resert the rate counter
  78. rateStart = solver.counter.Load()
  79. // Sleep for a second
  80. if solver.Iter != solver.counter.Load() {
  81. time.Sleep(1 * time.Second)
  82. }
  83. } // End for-loop
  84. }