Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bc4cb69

Browse files
committed
Satifisfied conditions are also included in the explanation
1 parent a4c6251 commit bc4cb69

3 files changed

Lines changed: 194 additions & 76 deletions

File tree

crates/hyperqueue/src/client/output/cli.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,21 +1074,24 @@ impl Output for CliOutput {
10741074
.color(colored::Color::Red)
10751075
)
10761076
}
1077-
let mut runnable_worker_ids = explanation
1077+
let runnable_worker_ids = explanation
10781078
.workers
10791079
.iter()
1080-
.filter_map(|w| w.is_enabled().then(|| w.worker_id.as_num()))
1080+
.filter(|&w| w.is_enabled())
1081+
.map(|w| w.worker_id.as_num())
10811082
.collect_vec();
10821083
if runnable_worker_ids.is_empty() {
10831084
println!(
10841085
"There is {} where the task can run.",
10851086
"no worker".color(colored::Color::Red)
10861087
);
10871088
} else {
1089+
let count = runnable_worker_ids.len();
10881090
let ids = IntArray::from_sorted_ids(runnable_worker_ids.into_iter());
10891091
println!(
1090-
"The task can run on {} workers: {}",
1091-
ids.id_count().to_string().color(colored::Color::Green),
1092+
"The task can run on {} {}: {}",
1093+
count.to_string().color(colored::Color::Green),
1094+
pluralize("worker", count),
10921095
ids.to_string().color(colored::Color::Green)
10931096
);
10941097
}
@@ -1124,7 +1127,13 @@ impl Output for CliOutput {
11241127
header.push("".cell());
11251128
header.push("".cell());
11261129
}
1127-
header.push(i.cell());
1130+
header.push(i.cell().foreground_color(
1131+
if variant.iter().any(|v| v.is_blocking()) {
1132+
Some(Color::Red)
1133+
} else {
1134+
None
1135+
},
1136+
));
11281137
header.push(rtype.join("\n").cell());
11291138
header.push(provs.join("\n").cell());
11301139
header.push(rqs.join("\n").cell());
@@ -1665,18 +1674,27 @@ fn resources_summary(resources: &ResourceDescriptor, multiline: bool) -> String
16651674
fn explanation_item_to_strings(
16661675
item: &TaskExplainItem,
16671676
) -> (ColoredString, ColoredString, ColoredString) {
1677+
let request_color = if item.is_blocking() {
1678+
colored::Color::Red
1679+
} else {
1680+
colored::Color::Green
1681+
};
16681682
match item {
16691683
TaskExplainItem::Time {
16701684
min_time,
16711685
remaining_time,
16721686
} => (
16731687
"time".color(colored::Color::Magenta),
1674-
human_duration(chrono::Duration::from_std(*remaining_time).unwrap())
1675-
.to_string()
1676-
.color(colored::Color::Yellow),
1688+
if let Some(time) = remaining_time {
1689+
human_duration(chrono::Duration::from_std(*time).unwrap())
1690+
.to_string()
1691+
.color(colored::Color::Yellow)
1692+
} else {
1693+
"unknown".color(colored::Color::Yellow)
1694+
},
16771695
human_duration(chrono::Duration::from_std(*min_time).unwrap())
16781696
.to_string()
1679-
.color(colored::Color::Red),
1697+
.color(request_color),
16801698
),
16811699
TaskExplainItem::Resources {
16821700
resource,
@@ -1685,15 +1703,15 @@ fn explanation_item_to_strings(
16851703
} => (
16861704
resource.color(colored::Color::Cyan),
16871705
format!("{}", worker_amount).color(colored::Color::Yellow),
1688-
format!("{}", request_amount).color(colored::Color::Red),
1706+
format!("{}", request_amount).color(request_color),
16891707
),
16901708
TaskExplainItem::WorkerGroup {
16911709
n_nodes,
16921710
group_size,
16931711
} => (
16941712
"nodes".color(colored::Color::Magenta),
16951713
format!("group size {}", group_size).color(colored::Color::Yellow),
1696-
format!("{}", n_nodes).color(colored::Color::Red),
1714+
format!("{}", n_nodes).color(request_color),
16971715
),
16981716
}
16991717
}

crates/tako/src/internal/server/explain.rs

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@ impl TaskExplanationForWorker {
2323
pub fn n_enabled_variants(&self) -> u32 {
2424
self.variants
2525
.iter()
26-
.map(|v| if v.is_empty() { 1 } else { 0 })
26+
.map(|v| {
27+
if v.iter().any(|item| item.is_blocking()) {
28+
0
29+
} else {
30+
1
31+
}
32+
})
2733
.sum()
2834
}
2935

@@ -40,7 +46,7 @@ impl TaskExplanationForWorker {
4046
pub enum TaskExplainItem {
4147
Time {
4248
min_time: Duration,
43-
remaining_time: Duration,
49+
remaining_time: Option<Duration>,
4450
},
4551
Resources {
4652
resource: String,
@@ -53,6 +59,30 @@ pub enum TaskExplainItem {
5359
},
5460
}
5561

62+
impl TaskExplainItem {
63+
pub fn is_blocking(&self) -> bool {
64+
match self {
65+
TaskExplainItem::Time {
66+
min_time,
67+
remaining_time: Some(remaining_time),
68+
} => min_time > remaining_time,
69+
TaskExplainItem::Time {
70+
min_time: _,
71+
remaining_time: None,
72+
} => false,
73+
TaskExplainItem::Resources {
74+
resource: _,
75+
request_amount,
76+
worker_amount,
77+
} => request_amount > worker_amount,
78+
TaskExplainItem::WorkerGroup {
79+
n_nodes,
80+
group_size,
81+
} => n_nodes > group_size,
82+
}
83+
}
84+
}
85+
5686
pub fn task_explain_init(task: &Task) -> TaskExplanation {
5787
TaskExplanation {
5888
n_task_deps: task.task_deps.len() as u32,
@@ -80,35 +110,29 @@ pub fn task_explain_for_worker(
80110
.iter()
81111
.map(|rq| {
82112
let mut result = Vec::new();
83-
if let Some(remaining_time) = worker.remaining_time(now) {
84-
if rq.min_time() > remaining_time {
85-
result.push(TaskExplainItem::Time {
86-
min_time: rq.min_time(),
87-
remaining_time,
88-
});
89-
}
113+
if !rq.min_time().is_zero() {
114+
result.push(TaskExplainItem::Time {
115+
min_time: rq.min_time(),
116+
remaining_time: worker.remaining_time(now),
117+
});
90118
}
91119
if rq.is_multi_node() {
92-
if rq.n_nodes() > worker_group.size() as NumOfNodes {
93-
result.push(TaskExplainItem::WorkerGroup {
94-
n_nodes: rq.n_nodes(),
95-
group_size: worker_group.size() as NumOfNodes,
96-
})
97-
}
120+
result.push(TaskExplainItem::WorkerGroup {
121+
n_nodes: rq.n_nodes(),
122+
group_size: worker_group.size() as NumOfNodes,
123+
})
98124
} else {
99125
for entry in rq.entries() {
100126
let request_amount = entry.request.min_amount();
101127
let worker_amount = worker.resources.get(entry.resource_id);
102-
if request_amount > worker_amount {
103-
result.push(TaskExplainItem::Resources {
104-
resource: resource_map
105-
.get_name(entry.resource_id)
106-
.unwrap()
107-
.to_string(),
108-
request_amount,
109-
worker_amount,
110-
})
111-
}
128+
result.push(TaskExplainItem::Resources {
129+
resource: resource_map
130+
.get_name(entry.resource_id)
131+
.unwrap()
132+
.to_string(),
133+
request_amount,
134+
worker_amount,
135+
})
112136
}
113137
}
114138
result
@@ -157,32 +181,37 @@ mod tests {
157181
let task = TaskBuilder::new(task_id).build();
158182
let r = explain(&task, &worker1, now);
159183
assert_eq!(r.variants.len(), 1);
160-
assert!(r.variants[0].is_empty());
184+
assert_eq!(r.variants[0].len(), 1);
185+
assert_eq!(r.n_enabled_variants(), 1);
161186

162187
let task = TaskBuilder::new(task_id).time_request(20_000).build();
163188
let r = explain(&task, &worker1, now);
164189
assert_eq!(r.variants.len(), 1);
165-
assert!(r.variants[0].is_empty());
190+
assert_eq!(r.variants[0].len(), 2);
191+
assert_eq!(r.n_enabled_variants(), 1);
166192

167193
let r = explain(&task, &worker2, now);
168194
assert_eq!(r.variants.len(), 1);
169-
assert!(r.variants[0].is_empty());
195+
assert_eq!(r.variants[0].len(), 2);
196+
assert_eq!(r.n_enabled_variants(), 1);
170197

171198
let now2 = now + Duration::from_secs(21_000);
172199
let r = explain(&task, &worker1, now2);
173200
assert_eq!(r.variants.len(), 1);
174-
assert!(r.variants[0].is_empty());
201+
assert_eq!(r.variants[0].len(), 2);
202+
assert_eq!(r.n_enabled_variants(), 1);
175203

176204
let r = explain(&task, &worker2, now2);
177205
assert_eq!(r.variants.len(), 1);
178-
assert_eq!(r.variants[0].len(), 1);
206+
assert_eq!(r.variants[0].len(), 2);
179207
assert!(matches!(
180208
r.variants[0][0],
181209
TaskExplainItem::Time {
182210
min_time,
183211
remaining_time,
184-
} if min_time == Duration::from_secs(20_000) && remaining_time == Duration::from_secs(19_000)
212+
} if min_time == Duration::from_secs(20_000) && remaining_time == Some(Duration::from_secs(19_000))
185213
));
214+
assert_eq!(r.n_enabled_variants(), 0);
186215

187216
let task = TaskBuilder::new(task_id)
188217
.time_request(20_000)
@@ -191,13 +220,14 @@ mod tests {
191220
.build();
192221
let r = explain(&task, &worker2, now);
193222
assert_eq!(r.variants.len(), 1);
194-
assert_eq!(r.variants[0].len(), 1);
223+
assert_eq!(r.variants[0].len(), 3);
195224
assert!(matches!(
196-
&r.variants[0][0],
225+
&r.variants[0][1],
197226
TaskExplainItem::Resources {
198227
resource, request_amount, worker_amount
199228
} if resource == "cpus" && *request_amount == ResourceAmount::new_units(30) && *worker_amount == ResourceAmount::new_units(10)
200229
));
230+
assert_eq!(r.n_enabled_variants(), 0);
201231

202232
let task = TaskBuilder::new(task_id)
203233
.time_request(30_000)
@@ -210,13 +240,13 @@ mod tests {
210240
let r = explain(&task, &worker2, now2);
211241
assert_eq!(r.variants.len(), 2);
212242
assert_eq!(r.variants[0].len(), 3);
213-
assert_eq!(r.variants[1].len(), 1);
243+
assert_eq!(r.variants[1].len(), 2);
214244
assert!(matches!(
215245
r.variants[0][0],
216246
TaskExplainItem::Time {
217247
min_time,
218248
remaining_time,
219-
} if min_time == Duration::from_secs(30_000) && remaining_time == Duration::from_secs(19_000)
249+
} if min_time == Duration::from_secs(30_000) && remaining_time == Some(Duration::from_secs(19_000))
220250
));
221251
assert!(matches!(
222252
&r.variants[0][1],
@@ -231,7 +261,7 @@ mod tests {
231261
} if resource == "gpus" && *request_amount == ResourceAmount::new_units(8) && *worker_amount == ResourceAmount::new_units(4)
232262
));
233263
assert!(matches!(
234-
&r.variants[1][0],
264+
&r.variants[1][1],
235265
TaskExplainItem::Resources {
236266
resource, request_amount, worker_amount
237267
} if resource == "gpus" && *request_amount == ResourceAmount::new_units(32) && *worker_amount == ResourceAmount::new_units(4)
@@ -254,7 +284,8 @@ mod tests {
254284
let group = WorkerGroup::new(wset);
255285
let r = task_explain_for_worker(&resource_map, &task, &worker, &group, now);
256286
assert_eq!(r.variants.len(), 1);
257-
assert!(r.variants[0].is_empty());
287+
assert_eq!(r.variants[0].len(), 1);
288+
assert_eq!(r.n_enabled_variants(), 1);
258289

259290
let mut wset = Set::new();
260291
wset.insert(WorkerId::new(1));
@@ -270,5 +301,6 @@ mod tests {
270301
group_size: 2
271302
}
272303
));
304+
assert_eq!(r.n_enabled_variants(), 0);
273305
}
274306
}

0 commit comments

Comments
 (0)