@@ -333,16 +333,40 @@ impl SchedulerState {
333333 // }
334334
335335 fn try_start_multinode_tasks ( & mut self , core : & mut Core ) {
336+ let mut selected_workers = Vec :: new ( ) ;
336337 loop {
337338 // "while let" not used because of lifetime problems
338- let ( mn_queue, task_map, worker_map) = core. multi_node_queue_split_mut ( ) ;
339+ let ( mn_queue, task_map, worker_map, worker_groups ) = core. multi_node_queue_split_mut ( ) ;
339340 if let Some ( ( task_id, _) ) = mn_queue. queue . peek ( ) {
340341 let task_id = * task_id;
341342 let task = task_map. get_task_mut ( task_id) ;
342343 let n_nodes = task. configuration . resources . n_nodes ( ) as usize ;
343344 assert ! ( n_nodes > 0 ) ;
344345
345- if worker_map. len ( ) < n_nodes {
346+ let mut found = false ;
347+ let mut big_enough = false ;
348+ ' outer: for group in worker_groups. values ( ) {
349+ if group. size ( ) < n_nodes {
350+ continue ;
351+ }
352+ big_enough = true ;
353+ selected_workers. clear ( ) ;
354+ for worker_id in group. worker_ids ( ) {
355+ let worker = worker_map. get_worker ( worker_id) ;
356+ if worker. is_free ( ) {
357+ selected_workers. push ( worker_id) ;
358+ }
359+ if selected_workers. len ( ) == n_nodes {
360+ found = true ;
361+ break ' outer;
362+ }
363+ }
364+ }
365+ if found {
366+ mn_queue. queue . pop ( ) ;
367+ self . assign_multinode ( worker_map, task, std:: mem:: take ( & mut selected_workers) ) ;
368+ continue ;
369+ } else if !big_enough {
346370 log:: debug!(
347371 "Multi-node task {} put into sleep. (n_nodes={}, workers={})" ,
348372 task_id,
@@ -352,23 +376,6 @@ impl SchedulerState {
352376 mn_queue. queue . pop ( ) ;
353377 core. add_sleeping_mn_task ( task_id) ;
354378 continue ;
355- }
356-
357- let mut selected_workers = Vec :: new ( ) ;
358- let mut found = false ;
359- for worker in worker_map. values ( ) {
360- if worker. is_free ( ) {
361- selected_workers. push ( worker. id ) ;
362- }
363- if selected_workers. len ( ) == n_nodes {
364- found = true ;
365- break ;
366- }
367- }
368- if found {
369- mn_queue. queue . pop ( ) ;
370- self . assign_multinode ( worker_map, task, selected_workers) ;
371- continue ;
372379 } else {
373380 return ;
374381 }
@@ -391,13 +398,13 @@ impl SchedulerState {
391398 compute_b_level_metric( core. task_map_mut( ) )
392399 } ) ;
393400
394- let ( multi_node_queue, task_map, _) = core. multi_node_queue_split_mut ( ) ;
401+ let ( multi_node_queue, task_map, _, _ ) = core. multi_node_queue_split_mut ( ) ;
395402 multi_node_queue. recompute_priorities ( task_map) ;
396403 }
397404
398405 let multi_node_ready_tasks = core. take_multi_node_ready_to_assign ( ) ;
399406 if !multi_node_ready_tasks. is_empty ( ) {
400- let ( multi_node_queue, task_map, _) = core. multi_node_queue_split_mut ( ) ;
407+ let ( multi_node_queue, task_map, _, _ ) = core. multi_node_queue_split_mut ( ) ;
401408 for task_id in multi_node_ready_tasks {
402409 if let Some ( task) = task_map. find_task ( task_id) {
403410 multi_node_queue. add_task ( task)
0 commit comments