author | Fabian Huch <huch@in.tum.de> |
Fri, 03 Nov 2023 10:03:05 +0100 | |
changeset 78884 | 0233d5a5a4ca |
parent 78851 | db37cae970a6 |
child 78888 | 95bbf9a576b3 |
permissions | -rw-r--r-- |
78845
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
1 |
/* Title: Pure/Tools/build_schedule.scala |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
2 |
Author: Fabian Huch, TU Muenchen |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
3 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
4 |
Build schedule generated by Heuristic methods, allowing for more efficient builds. |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
5 |
*/ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
6 |
package isabelle |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
7 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
8 |
|
78846 | 9 |
import Host.Node_Info |
78845
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
10 |
import scala.annotation.tailrec |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
11 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
12 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
13 |
object Build_Schedule { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
14 |
val engine_name = "build_schedule" |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
15 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
16 |
object Config { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
17 |
def from_job(job: Build_Process.Job): Config = Config(job.name, job.node_info) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
18 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
19 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
20 |
case class Config(job_name: String, node_info: Node_Info) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
21 |
def job_of(start_time: Time): Build_Process.Job = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
22 |
Build_Process.Job(job_name, "", "", node_info, Date(start_time), None) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
23 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
24 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
25 |
/* organized historic timing information (extracted from build logs) */ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
26 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
27 |
case class Timing_Entry(job_name: String, hostname: String, threads: Int, elapsed: Time) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
28 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
29 |
class Timing_Data private(data: List[Timing_Entry], val host_infos: Host_Infos) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
30 |
require(data.nonEmpty) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
31 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
32 |
def speedup(time: Time, factor: Double): Time = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
33 |
Time.ms((time.ms * factor).toLong) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
34 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
35 |
def is_empty = data.isEmpty |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
36 |
def size = data.length |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
37 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
38 |
private lazy val by_job = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
39 |
data.groupBy(_.job_name).view.mapValues(new Timing_Data(_, host_infos)).toMap |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
40 |
private lazy val by_threads = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
41 |
data.groupBy(_.threads).view.mapValues(new Timing_Data(_, host_infos)).toMap |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
42 |
private lazy val by_hostname = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
43 |
data.groupBy(_.hostname).view.mapValues(new Timing_Data(_, host_infos)).toMap |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
44 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
45 |
def mean_time: Time = Timing_Data.mean_time(data.map(_.elapsed)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
46 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
47 |
private def best_entry: Timing_Entry = data.minBy(_.elapsed.ms) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
48 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
49 |
def best_threads(job_name: String): Option[Int] = by_job.get(job_name).map(_.best_entry.threads) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
50 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
51 |
def best_time(job_name: String): Time = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
52 |
by_job.get(job_name).map(_.best_entry.elapsed).getOrElse( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
53 |
estimate_config(Config(job_name, Node_Info(best_entry.hostname, None, Nil)))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
54 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
55 |
private def hostname_factor(from: String, to: String): Double = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
56 |
host_infos.host_factor(host_infos.the_host(from), host_infos.the_host(to)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
57 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
58 |
def approximate_threads(threads: Int): Option[Time] = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
59 |
val approximations = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
60 |
by_job.values.filter(_.size > 1).map { data => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
61 |
val (ref_hostname, x0) = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
62 |
data.by_hostname.toList.flatMap((hostname, data) => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
63 |
data.by_threads.keys.map(hostname -> _)).minBy((_, n) => Math.abs(n - threads)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
64 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
65 |
def unify_hosts(data: Timing_Data): List[Time] = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
66 |
data.by_hostname.toList.map((hostname, data) => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
67 |
speedup(data.mean_time, hostname_factor(hostname, ref_hostname))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
68 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
69 |
val entries = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
70 |
data.by_threads.toList.map((threads, data) => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
71 |
threads -> Timing_Data.median_time(unify_hosts(data))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
72 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
73 |
val y0 = data.by_hostname(ref_hostname).by_threads(x0).mean_time |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
74 |
val (x1, y1_data) = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
75 |
data.by_hostname(ref_hostname).by_threads.toList.minBy((n, _) => Math.abs(n - threads)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
76 |
val y1 = y1_data.mean_time |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
77 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
78 |
val a = (y1.ms - y0.ms).toDouble / (x1 - x0) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
79 |
val b = y0.ms - a * x0 |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
80 |
Time.ms((a * threads + b).toLong) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
81 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
82 |
if (approximations.isEmpty) None else Some(Timing_Data.mean_time(approximations)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
83 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
84 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
85 |
def threads_factor(divided: Int, divisor: Int): Double = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
86 |
(approximate_threads(divided), approximate_threads(divisor)) match { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
87 |
case (Some(dividend), Some(divisor)) => dividend.ms.toDouble / divisor.ms |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
88 |
case _ => divided.toDouble / divisor |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
89 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
90 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
91 |
def estimate_config(config: Config): Time = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
92 |
by_job.get(config.job_name) match { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
93 |
case None => mean_time |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
94 |
case Some(data) => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
95 |
val hostname = config.node_info.hostname |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
96 |
val threads = host_infos.num_threads(config.node_info) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
97 |
data.by_threads.get(threads) match { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
98 |
case None => // interpolate threads |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
99 |
data.by_hostname.get(hostname).flatMap( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
100 |
_.approximate_threads(threads)).getOrElse { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
101 |
// per machine, try to approximate config for threads |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
102 |
val approximated = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
103 |
data.by_hostname.toList.flatMap((hostname1, data) => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
104 |
data.approximate_threads(threads).map(time => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
105 |
speedup(time, hostname_factor(hostname1, hostname)))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
106 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
107 |
if (approximated.nonEmpty) Timing_Data.mean_time(approximated) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
108 |
else { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
109 |
// no machine where config can be approximated |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
110 |
data.approximate_threads(threads).getOrElse { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
111 |
// only single data point, use global curve to approximate |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
112 |
val global_factor = threads_factor(data.by_threads.keys.head, threads) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
113 |
speedup(data.by_threads.values.head.mean_time, global_factor) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
114 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
115 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
116 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
117 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
118 |
case Some(data) => // time for job/thread exists, interpolate machine |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
119 |
data.by_hostname.get(hostname).map(_.mean_time).getOrElse { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
120 |
Timing_Data.median_time( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
121 |
data.by_hostname.toList.map((hostname1, data) => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
122 |
speedup(data.mean_time, hostname_factor(hostname1, hostname)))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
123 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
124 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
125 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
126 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
127 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
128 |
object Timing_Data { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
129 |
def median_time(obs: List[Time]): Time = obs.sortBy(_.ms).drop(obs.length / 2).head |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
130 |
def mean_time(obs: Iterable[Time]): Time = Time.ms(obs.map(_.ms).sum / obs.size) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
131 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
132 |
private val dummy_entries = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
133 |
List( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
134 |
Timing_Entry("dummy", "dummy", 1, Time.minutes(5)), |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
135 |
Timing_Entry("dummy", "dummy", 8, Time.minutes(1))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
136 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
137 |
def dummy: Timing_Data = new Timing_Data(dummy_entries, Host_Infos.dummy) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
138 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
139 |
def make( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
140 |
host_infos: Host_Infos, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
141 |
build_history: List[(Build_Log.Meta_Info, Build_Log.Build_Info)], |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
142 |
): Timing_Data = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
143 |
val hosts = host_infos.hosts |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
144 |
val measurements = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
145 |
for { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
146 |
(meta_info, build_info) <- build_history |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
147 |
build_host <- meta_info.get(Build_Log.Prop.build_host).toList |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
148 |
(job_name, session_info) <- build_info.sessions.toList |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
149 |
hostname = session_info.hostname.getOrElse(build_host) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
150 |
host <- hosts.find(_.info.hostname == build_host).toList |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
151 |
threads = session_info.threads.getOrElse(host.info.num_cpus) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
152 |
} yield (job_name, hostname, threads) -> session_info.timing.elapsed |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
153 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
154 |
val entries = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
155 |
if (measurements.isEmpty) dummy_entries |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
156 |
else |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
157 |
measurements.groupMap(_._1)(_._2).toList.map { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
158 |
case ((job_name, hostname, threads), timings) => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
159 |
Timing_Entry(job_name, hostname, threads, median_time(timings)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
160 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
161 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
162 |
new Timing_Data(entries, host_infos) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
163 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
164 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
165 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
166 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
167 |
/* host information */ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
168 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
169 |
case class Host(info: isabelle.Host.Info, build: Build_Cluster.Host) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
170 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
171 |
object Host_Infos { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
172 |
def dummy: Host_Infos = |
78846 | 173 |
new Host_Infos( |
174 |
List(Host(isabelle.Host.Info("dummy", Nil, 8, Some(1.0)), Build_Cluster.Host("dummy")))) |
|
78845
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
175 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
176 |
def apply(build_hosts: List[Build_Cluster.Host], db: SQL.Database): Host_Infos = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
177 |
def get_host(build_host: Build_Cluster.Host): Host = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
178 |
val info = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
179 |
isabelle.Host.read_info(db, build_host.name).getOrElse( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
180 |
error("No benchmark for " + quote(build_host.name))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
181 |
Host(info, build_host) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
182 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
183 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
184 |
new Host_Infos(build_hosts.map(get_host)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
185 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
186 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
187 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
188 |
class Host_Infos private(val hosts: List[Host]) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
189 |
private val by_hostname = hosts.map(host => host.info.hostname -> host).toMap |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
190 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
191 |
def host_factor(from: Host, to: Host): Double = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
192 |
from.info.benchmark_score.get / to.info.benchmark_score.get |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
193 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
194 |
val host_speeds: Ordering[Host] = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
195 |
Ordering.fromLessThan((host1, host2) => host_factor(host1, host2) > 1) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
196 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
197 |
def the_host(hostname: String): Host = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
198 |
by_hostname.getOrElse(hostname, error("Unknown host " + quote(hostname))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
199 |
def the_host(node_info: Node_Info): Host = the_host(node_info.hostname) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
200 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
201 |
def num_threads(node_info: Node_Info): Int = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
202 |
if (node_info.rel_cpus.nonEmpty) node_info.rel_cpus.length |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
203 |
else the_host(node_info).info.num_cpus |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
204 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
205 |
def available(state: Build_Process.State): Resources = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
206 |
val allocated = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
207 |
state.running.values.map(_.node_info).groupMapReduce(the_host)(List(_))(_ ::: _) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
208 |
Resources(this, allocated) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
209 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
210 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
211 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
212 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
213 |
/* offline tracking of resource allocations */ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
214 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
215 |
case class Resources( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
216 |
host_infos: Host_Infos, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
217 |
allocated_nodes: Map[Host, List[Node_Info]] |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
218 |
) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
219 |
val unused_hosts: List[Host] = host_infos.hosts.filter(allocated(_).isEmpty) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
220 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
221 |
def allocated(host: Host): List[Node_Info] = allocated_nodes.getOrElse(host, Nil) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
222 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
223 |
def allocate(node: Node_Info): Resources = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
224 |
val host = host_infos.the_host(node) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
225 |
copy(allocated_nodes = allocated_nodes + (host -> (node :: allocated(host)))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
226 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
227 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
228 |
def try_allocate_tasks( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
229 |
hosts: List[Host], |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
230 |
tasks: List[(Build_Process.Task, Int)] |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
231 |
): (List[Config], Resources) = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
232 |
tasks match { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
233 |
case Nil => (Nil, this) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
234 |
case (task, threads) :: tasks => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
235 |
val (config, resources) = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
236 |
hosts.find(available(_, threads)) match { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
237 |
case Some(host) => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
238 |
val node_info = next_node(host, threads) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
239 |
(Some(Config(task.name, node_info)), allocate(node_info)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
240 |
case None => (None, this) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
241 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
242 |
val (configs, resources1) = resources.try_allocate_tasks(hosts, tasks) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
243 |
(configs ++ config, resources1) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
244 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
245 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
246 |
def next_node(host: Host, threads: Int): Node_Info = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
247 |
val numa_node_num_cpus = host.info.num_cpus / (host.info.numa_nodes.length max 1) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
248 |
def explicit_cpus(node_info: Node_Info): List[Int] = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
249 |
if (node_info.rel_cpus.nonEmpty) node_info.rel_cpus else (0 until numa_node_num_cpus).toList |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
250 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
251 |
val used_nodes = allocated(host).groupMapReduce(_.numa_node)(explicit_cpus)(_ ::: _) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
252 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
253 |
val available_nodes = host.info.numa_nodes |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
254 |
val numa_node = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
255 |
if (!host.build.numa) None |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
256 |
else available_nodes.sortBy(n => used_nodes.getOrElse(Some(n), Nil).length).headOption |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
257 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
258 |
val used_cpus = used_nodes.getOrElse(numa_node, Nil).toSet |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
259 |
val available_cpus = (0 until numa_node_num_cpus).filterNot(used_cpus.contains).toList |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
260 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
261 |
val rel_cpus = if (available_cpus.length >= threads) available_cpus.take(threads) else Nil |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
262 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
263 |
Node_Info(host.info.hostname, numa_node, rel_cpus) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
264 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
265 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
266 |
def available(host: Host, threads: Int): Boolean = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
267 |
val used = allocated(host) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
268 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
269 |
if (used.length >= host.build.jobs) false |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
270 |
else { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
271 |
if (host.info.numa_nodes.length <= 1) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
272 |
used.map(host_infos.num_threads).sum + threads <= host.info.num_cpus |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
273 |
else { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
274 |
def node_threads(n: Int): Int = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
275 |
used.filter(_.numa_node.contains(n)).map(host_infos.num_threads).sum |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
276 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
277 |
host.info.numa_nodes.exists( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
278 |
node_threads(_) + threads <= host.info.num_cpus / host.info.numa_nodes.length) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
279 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
280 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
281 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
282 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
283 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
284 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
285 |
/* schedule generation */ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
286 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
287 |
case class State(build_state: Build_Process.State, current_time: Time) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
288 |
def start(config: Config): State = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
289 |
copy(build_state = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
290 |
build_state.copy(running = build_state.running + |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
291 |
(config.job_name -> config.job_of(current_time)))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
292 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
293 |
def step(timing_data: Timing_Data): State = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
294 |
val remaining = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
295 |
build_state.running.values.toList.map { job => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
296 |
val elapsed = current_time - job.start_date.time |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
297 |
val predicted = timing_data.estimate_config(Config.from_job(job)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
298 |
val remaining = if (elapsed > predicted) Time.zero else predicted - elapsed |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
299 |
job -> remaining |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
300 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
301 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
302 |
if (remaining.isEmpty) error("Schedule step without running sessions") |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
303 |
else { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
304 |
val (job, elapsed) = remaining.minBy(_._2.ms) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
305 |
State(build_state.remove_running(job.name).remove_pending(job.name), current_time + elapsed) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
306 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
307 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
308 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
309 |
def finished: Boolean = build_state.pending.isEmpty && build_state.running.isEmpty |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
310 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
311 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
312 |
abstract class Scheduler { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
313 |
def ready_jobs(state: Build_Process.State): Build_Process.State.Pending = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
314 |
state.pending.filter(entry => entry.is_ready && !state.is_running(entry.name)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
315 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
316 |
def next(timing: Timing_Data, state: Build_Process.State): List[Config] |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
317 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
318 |
def build_duration(timing_data: Timing_Data, build_state: Build_Process.State): Time = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
319 |
@tailrec |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
320 |
def simulate(state: State): State = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
321 |
if (state.finished) state |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
322 |
else { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
323 |
val state1 = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
324 |
next(timing_data, state.build_state).foldLeft(state)(_.start(_)).step(timing_data) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
325 |
simulate(state1) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
326 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
327 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
328 |
val start = Time.now() |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
329 |
simulate(State(build_state, start)).current_time - start |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
330 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
331 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
332 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
333 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
334 |
/* heuristics */ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
335 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
336 |
class Timing_Heuristic(threshold: Time) extends Scheduler { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
337 |
def next(timing_data: Timing_Data, state: Build_Process.State): List[Config] = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
338 |
val host_infos = timing_data.host_infos |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
339 |
val resources = host_infos.available(state) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
340 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
341 |
def best_threads(task: Build_Process.Task): Int = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
342 |
timing_data.best_threads(task.name).getOrElse( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
343 |
host_infos.hosts.map(_.info.num_cpus).max min 8) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
344 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
345 |
val ready = ready_jobs(state) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
346 |
val free = resources.unused_hosts |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
347 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
348 |
if (ready.length <= free.length) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
349 |
resources.try_allocate_tasks(free, ready.map(task => task -> best_threads(task)))._1 |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
350 |
else { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
351 |
val pending_tasks = state.pending.map(_.name).toSet |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
352 |
val graph = state.sessions.graph.restrict(pending_tasks) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
353 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
354 |
val accumulated_time = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
355 |
graph.node_depth(timing_data.best_time(_).ms).filter((name, _) => graph.is_maximal(name)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
356 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
357 |
val path_time = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
358 |
accumulated_time.flatMap((name, ms) => graph.all_preds(List(name)).map(_ -> ms)).toMap |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
359 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
360 |
def is_critical(task: String): Boolean = path_time(task) > threshold.ms |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
361 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
362 |
val (critical, other) = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
363 |
ready.sortBy(task => path_time(task.name)).partition(task => is_critical(task.name)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
364 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
365 |
val critical_graph = graph.restrict(is_critical) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
366 |
def parallel_paths(node: String): Int = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
367 |
critical_graph.imm_succs(node).map(suc => parallel_paths(suc) max 1).sum max 1 |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
368 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
369 |
val (critical_hosts, other_hosts) = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
370 |
host_infos.hosts.sorted(host_infos.host_speeds).reverse.splitAt( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
371 |
critical.map(_.name).map(parallel_paths).sum) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
372 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
373 |
val (configs1, resources1) = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
374 |
resources.try_allocate_tasks(critical_hosts, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
375 |
critical.map(task => task -> best_threads(task))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
376 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
377 |
val (configs2, _) = resources1.try_allocate_tasks(other_hosts, other.map(_ -> 1)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
378 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
379 |
configs1 ::: configs2 |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
380 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
381 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
382 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
383 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
384 |
class Meta_Heuristic(schedulers: List[Scheduler]) extends Scheduler { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
385 |
require(schedulers.nonEmpty) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
386 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
387 |
def next(timing_data: Timing_Data, state: Build_Process.State): List[Config] = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
388 |
val (best, _) = schedulers.map(h => h -> h.build_duration(timing_data, state)).minBy(_._2.ms) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
389 |
best.next(timing_data, state) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
390 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
391 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
392 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
393 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
394 |
/* process for scheduled build */ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
395 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
396 |
class Scheduled_Build_Process( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
397 |
scheduler: Scheduler, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
398 |
build_context: Build.Context, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
399 |
build_progress: Progress, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
400 |
server: SSH.Server, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
401 |
) extends Build_Process(build_context, build_progress, server) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
402 |
protected val start_date = Date.now() |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
403 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
404 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
405 |
/* global resources with common close() operation */ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
406 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
407 |
private final lazy val _log_store: Build_Log.Store = Build_Log.store(build_options) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
408 |
private final lazy val _log_database: SQL.Database = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
409 |
try { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
410 |
val db = _log_store.open_database(server = this.server) |
78851 | 411 |
_log_store.init_database(db) |
78845
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
412 |
db |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
413 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
414 |
catch { case exn: Throwable => close(); throw exn } |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
415 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
416 |
override def close(): Unit = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
417 |
super.close() |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
418 |
Option(_log_database).foreach(_.close()) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
419 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
420 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
421 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
422 |
/* previous results via build log */ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
423 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
424 |
override def open_build_cluster(): Build_Cluster = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
425 |
val build_cluster = super.open_build_cluster() |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
426 |
build_cluster.init() |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
427 |
if (build_context.master && build_context.max_jobs > 0) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
428 |
val benchmark_options = build_options.string("build_hostname") = hostname |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
429 |
Benchmark.benchmark(benchmark_options, progress) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
430 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
431 |
build_cluster.benchmark() |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
432 |
build_cluster |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
433 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
434 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
435 |
private val timing_data: Timing_Data = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
436 |
val cluster_hosts: List[Build_Cluster.Host] = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
437 |
if (build_context.max_jobs == 0) build_context.build_hosts |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
438 |
else { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
439 |
val local_build_host = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
440 |
Build_Cluster.Host( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
441 |
hostname, jobs = build_context.max_jobs, numa = build_context.numa_shuffling) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
442 |
local_build_host :: build_context.build_hosts |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
443 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
444 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
445 |
val host_infos = Host_Infos(cluster_hosts, _host_database) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
446 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
447 |
val build_history = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
448 |
for { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
449 |
log_name <- _log_database.execute_query_statement( |
78849 | 450 |
Build_Log.private_data.meta_info_table.select(List(Build_Log.private_data.log_name)), |
451 |
List.from[String], res => res.string(Build_Log.private_data.log_name)) |
|
78845
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
452 |
meta_info <- _log_store.read_meta_info(_log_database, log_name) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
453 |
build_info = _log_store.read_build_info(_log_database, log_name) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
454 |
} yield (meta_info, build_info) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
455 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
456 |
Timing_Data.make(host_infos, build_history) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
457 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
458 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
459 |
def write_build_log(results: Build.Results, state: Build_Process.State.Results): Unit = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
460 |
val sessions = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
461 |
for { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
462 |
(session_name, result) <- state.toList |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
463 |
if !result.current |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
464 |
} yield { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
465 |
val info = build_context.sessions_structure(session_name) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
466 |
val entry = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
467 |
if (!results.cancelled(session_name)) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
468 |
val status = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
469 |
if (result.ok) Build_Log.Session_Status.finished |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
470 |
else Build_Log.Session_Status.failed |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
471 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
472 |
Build_Log.Session_Entry( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
473 |
chapter = info.chapter, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
474 |
groups = info.groups, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
475 |
hostname = Some(result.node_info.hostname), |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
476 |
threads = Some(timing_data.host_infos.num_threads(result.node_info)), |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
477 |
timing = result.process_result.timing, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
478 |
sources = Some(result.output_shasum.digest.toString), |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
479 |
status = Some(status)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
480 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
481 |
else |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
482 |
Build_Log.Session_Entry( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
483 |
chapter = info.chapter, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
484 |
groups = info.groups, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
485 |
status = Some(Build_Log.Session_Status.cancelled)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
486 |
session_name -> entry |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
487 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
488 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
489 |
val settings = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
490 |
Build_Log.Settings.all_settings.map(_.name).map(name => |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
491 |
name -> Isabelle_System.getenv(name)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
492 |
val props = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
493 |
List( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
494 |
Build_Log.Prop.build_id.name -> build_context.build_uuid, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
495 |
Build_Log.Prop.build_engine.name -> build_context.engine.name, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
496 |
Build_Log.Prop.build_host.name -> hostname, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
497 |
Build_Log.Prop.build_start.name -> Build_Log.print_date(start_date)) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
498 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
499 |
val meta_info = Build_Log.Meta_Info(props, settings) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
500 |
val build_info = Build_Log.Build_Info(sessions.toMap) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
501 |
val log_name = Build_Log.log_filename(engine = engine_name, date = start_date) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
502 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
503 |
_log_store.update_sessions(_log_database, log_name.file_name, build_info) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
504 |
_log_store.update_meta_info(_log_database, log_name.file_name, meta_info) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
505 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
506 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
507 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
508 |
/* build process */ |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
509 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
510 |
case class Cache(state: Build_Process.State, configs: List[Config], estimate: Date) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
511 |
def is_current(state: Build_Process.State): Boolean = this.state == state |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
512 |
def is_current_estimate(estimate: Date): Boolean = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
513 |
this.estimate.time - estimate.time >= Time.seconds(1) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
514 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
515 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
516 |
private var cache = Cache(Build_Process.State(), Nil, Date.now()) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
517 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
518 |
override def next_node_info(state: Build_Process.State, session_name: String): Node_Info = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
519 |
val configs = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
520 |
if (cache.is_current(state)) cache.configs |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
521 |
else scheduler.next(timing_data, state) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
522 |
configs.find(_.job_name == session_name).get.node_info |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
523 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
524 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
525 |
override def next_jobs(state: Build_Process.State): List[String] = |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
526 |
if (cache.is_current(state)) cache.configs.map(_.job_name) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
527 |
else { |
78884 | 528 |
val start = Time.now() |
78845
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
529 |
val next = scheduler.next(timing_data, state) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
530 |
val estimate = Date(Time.now() + scheduler.build_duration(timing_data, state)) |
78884 | 531 |
val elapsed = Time.now() - start |
532 |
||
533 |
val timing_msg = if (elapsed.is_relevant) " (in " + elapsed.message + ")" else "" |
|
534 |
progress.echo_if(build_context.master && !cache.is_current_estimate(estimate), |
|
535 |
"Estimated completion: " + estimate + timing_msg) |
|
78845
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
536 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
537 |
val configs = next.filter(_.node_info.hostname == hostname) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
538 |
cache = Cache(state, configs, estimate) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
539 |
configs.map(_.job_name) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
540 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
541 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
542 |
override def run(): Build.Results = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
543 |
val results = super.run() |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
544 |
if (build_context.master) write_build_log(results, snapshot().results) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
545 |
results |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
546 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
547 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
548 |
|
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
549 |
class Engine extends Build.Engine(engine_name) { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
550 |
override def open_build_process( |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
551 |
context: Build.Context, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
552 |
progress: Progress, |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
553 |
server: SSH.Server |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
554 |
): Build_Process = { |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
555 |
val heuristics = List(5, 10, 20).map(minutes => Timing_Heuristic(Time.minutes(minutes))) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
556 |
val scheduler = new Meta_Heuristic(heuristics) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
557 |
new Scheduled_Build_Process(scheduler, context, progress, server) |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
558 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
559 |
} |
ff96d94957cb
add module for faster scheduled builds;
Fabian Huch <huch@in.tum.de>
parents:
diff
changeset
|
560 |
} |