fix(scheduler): place a task-range job with the largest count that fits (bug-1931)
The parjob plan generator split only maxTasks, so a job submitted with a task range (minTasks < maxTasks) pended until all maxTasks tasks fit, even when minTasks did (a tasks 2..5 job pended on a host with 2 free slots). The runner now handles a task range in sched_alloc_range_(): it probes minTasks first and pends after that one search when it does not fit; otherwise it places maxTasks when that fits, or binary-searches for the largest count that fits and places it. Fitting is monotone in the count for balanced plans, so the search is exact for today's plan shapes. ctx->ntasks carries the count; parjob's job-level pass scales per-task shared wants and global limits to it, and the generator gets the request with its task count fixed to it. Fixed counts keep the old path. The decision trace shows each count tried (task count N (minimum) / (maximum), placing N tasks) and releases a fitting probe's hosts. Test fixtures that used minTasks = 1 as filler for an N-task job are now fixed-count. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7cdf25e001
commit
e3b87d28f3
19 changed files with 726 additions and 32 deletions
|
|
@ -189,6 +189,7 @@ typedef enum {
|
|||
SCHED_TRACE_E_ROLLBACK, /* released hosts, merged (5.8) */
|
||||
SCHED_TRACE_E_CHECK_ROW, /* cluster-wide check row (4.1, 4.2) */
|
||||
SCHED_TRACE_E_HOST_ROW, /* unmet row under a host (5.4, 5.5) */
|
||||
SCHED_TRACE_E_TASK_COUNT, /* task-range count tried (bug-1931) */
|
||||
SCHED_TRACE_E_NTYPES
|
||||
} sched_trace_entry_type_t;
|
||||
|
||||
|
|
@ -292,7 +293,7 @@ typedef struct sched_trace_entry_s {
|
|||
int rc; /* > 0 satisfied, 0 not, < 0 error */
|
||||
int not_tried_after; /* members after this one, not tried */
|
||||
} resreq_end;
|
||||
struct { /* ALT_SKIPPED, ALT_RESULT (i == 0: none chosen) */
|
||||
struct { /* ALT_SKIPPED, ALT_RESULT (i == 0: none chosen), TASK_COUNT */
|
||||
int i;
|
||||
int n;
|
||||
} alt;
|
||||
|
|
@ -626,6 +627,8 @@ extern void sched_trace_check_begin(xce_sched_trace_rec_t* rec,
|
|||
const xce_sched_obj_t* obj);
|
||||
extern void sched_trace_check_end(xce_sched_trace_rec_t* rec, int rc,
|
||||
bool plans_follow);
|
||||
/* bug-1931: count n next; kind 1 minimum, 2 maximum, 3 placing, else 0 */
|
||||
extern void sched_trace_task_count(xce_sched_trace_rec_t* rec, int n, int kind);
|
||||
|
||||
/* No plan generated for the current requirement, and why (4.7). Counts
|
||||
* the requirement under "no plan generated" (9.3), once: a search end
|
||||
|
|
|
|||
|
|
@ -189,6 +189,10 @@ typedef struct {
|
|||
xce_primary_resreq_t* primary;
|
||||
int nhosts;
|
||||
int nslots;
|
||||
/* bug-1931: the task count a task-range attempt (minTasks < maxTasks)
|
||||
* is trying, set by the runner before the job-level prepare pass; 0
|
||||
* (sched_ctx_init()/sched_ctx_set_primary()) means primary->maxTasks. */
|
||||
int ntasks;
|
||||
struct {
|
||||
xvec_t* shared;
|
||||
zarray_t hosts;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue