feat(scheduler-sim-decision-trace): capture shortfall and limit rows from the satisfaction check
Task 2.2: each checked row carries name, flags, value type, total, in-use, reserved, requested and met (same comparison as unsatisfy_()); limit rows resolve through the scope's matched limits and never count as shortfalls; the cluster-wide check keeps every row, a host only unmet rows, which set its shortfall/limit verdict. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
90d417bb1b
commit
258267fa48
6 changed files with 977 additions and 38 deletions
|
|
@ -157,8 +157,7 @@ typedef struct {
|
|||
* Entry types (design.md "Logical Data Model"). Every stored entry renders
|
||||
* as exactly one line in the budgeted sections (requirement, cluster-wide
|
||||
* check, plan and host), so the number of stored entries is the number of
|
||||
* budgeted lines. The check rows and host rows are added by the task that
|
||||
* captures them (TraceCapture).
|
||||
* budgeted lines.
|
||||
*/
|
||||
typedef enum {
|
||||
SCHED_TRACE_E_RESREQ_BEGIN = 0, /* requirement named by the path */
|
||||
|
|
@ -184,6 +183,8 @@ typedef enum {
|
|||
SCHED_TRACE_E_POS_SUMMARY, /* summary level: the position end with
|
||||
* its verdict counts (5.9) */
|
||||
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_NTYPES
|
||||
} sched_trace_entry_type_t;
|
||||
|
||||
|
|
@ -222,6 +223,32 @@ typedef struct {
|
|||
const char* scope; /* arena copy */
|
||||
} sched_trace_limit_ref_t;
|
||||
|
||||
/*
|
||||
* One row of the satisfaction check (resource.c unsatisfy_()): one
|
||||
* requested resource compared against its total. `met` is the check's own
|
||||
* verdict, !(total < inuse + reserved + requested). A row whose resource
|
||||
* has XCE_RESF_LIMIT is a limit row: `limit`, `scope` and `limited_res`
|
||||
* name the limit, the scope instance it applies to ("u=..,q=..,p=..", with
|
||||
* ",h=<host>" or "h=<host>" appended in a host scope) and the resource it
|
||||
* limits (NULL when no matched limit names it). Every other row is a
|
||||
* resource row, its limit fields NULL. Stored strings are arena copies.
|
||||
*/
|
||||
typedef struct {
|
||||
const char* res; /* resource name; NULL when the index is unknown */
|
||||
int idx; /* resource index */
|
||||
int flags; /* XCE_RESF_* */
|
||||
int valtype;
|
||||
float total;
|
||||
float inuse;
|
||||
float reserved; /* provisionally reserved by earlier parts of
|
||||
* this job's evaluation (uncommitted) */
|
||||
float requested;
|
||||
bool met;
|
||||
const char* limit; /* limit rows only */
|
||||
const char* scope; /* limit rows only */
|
||||
const char* limited_res; /* limit rows only; NULL: unknown */
|
||||
} sched_trace_row_t;
|
||||
|
||||
/* One requested resource of a single requirement or member (3.2). */
|
||||
typedef struct {
|
||||
const char* name; /* arena copy */
|
||||
|
|
@ -335,6 +362,7 @@ typedef struct sched_trace_entry_s {
|
|||
sched_trace_limit_tally_t* limits; /* hits per limit, in the
|
||||
* order first hit */
|
||||
} pos_summary;
|
||||
sched_trace_row_t row; /* CHECK_ROW, HOST_ROW */
|
||||
struct { /* ROLLBACK: consecutive released hosts, in call order */
|
||||
int nhosts;
|
||||
int cap;
|
||||
|
|
@ -404,6 +432,13 @@ struct xce_sched_trace_rec_s {
|
|||
bool scan_err_set;
|
||||
unsigned host_row_verdicts; /* SHORTFALL/LIMIT from the current host's
|
||||
* unmet rows (set by the row capture) */
|
||||
bool check_open; /* between check_begin and check_end */
|
||||
/* the current host's unmet rows (full level), held in builder memory
|
||||
* (malloc'd, strings strdup'd) until its verdict line is stored, then
|
||||
* stored after it; dropped when the host scope ends any other way */
|
||||
sched_trace_row_t* host_rows;
|
||||
int host_nrows;
|
||||
int host_rows_cap;
|
||||
/* plans of the current requirement's search (reset by resreq_begin
|
||||
* and after search_end) */
|
||||
int scope_tried;
|
||||
|
|
@ -564,6 +599,17 @@ extern void sched_trace_host_verdict(xce_sched_trace_rec_t* rec,
|
|||
extern void sched_trace_host_limit_hit(xce_sched_trace_rec_t* rec,
|
||||
const char* limit, const char* scope);
|
||||
|
||||
/*
|
||||
* One satisfaction check row (2.2), copied. In a host scope (between
|
||||
* host_begin and host_verdict) it is a HOST_ROW, held until the host's
|
||||
* verdict line and stored right after it, one level deeper; at summary
|
||||
* level it is not stored at all. Otherwise it is a CHECK_ROW, stored now.
|
||||
* Which rows to keep, and the host verdict bits they set, are the caller's
|
||||
* (TraceCapture's) decision.
|
||||
*/
|
||||
extern void sched_trace_row(xce_sched_trace_rec_t* rec,
|
||||
const sched_trace_row_t* row);
|
||||
|
||||
/* One host whose claim a failed plan released. Consecutive calls merge
|
||||
* into one ROLLBACK entry, "released hosts: n01, n02" (5.8). */
|
||||
extern void sched_trace_rollback_host(xce_sched_trace_rec_t* rec,
|
||||
|
|
@ -602,6 +648,27 @@ extern void sched_trace_capture_selection(xce_sched_trace_rec_t* rec,
|
|||
extern void sched_trace_capture_glimits(xce_sched_trace_rec_t* rec,
|
||||
const xce_sched_obj_t* obj);
|
||||
|
||||
/*
|
||||
* The satisfaction check's rows (4.1, 4.2, 5.4, 5.5), called from
|
||||
* resource.c unsatisfy_() with its inputs: `nres` rows of resource index,
|
||||
* total, in-use and requested, and the dense uncommitted vector keyed by
|
||||
* resource index. Each row's resource is resolved through core->resmgr.
|
||||
* A limit row (XCE_RESF_LIMIT) is resolved to its limit through the
|
||||
* scope's matched limits: obj->glimits in the cluster-wide check scope,
|
||||
* obj->hlimits[w->idx] in a host scope; without a match, the limit name
|
||||
* and scope come from the resource's own name. The cluster-wide scope
|
||||
* keeps every row. A host scope keeps only unmet rows: an unmet resource
|
||||
* row sets the host's SHORTFALL verdict, an unmet limit row its LIMIT
|
||||
* verdict (via sched_trace_host_limit_hit), never SHORTFALL. Outside both
|
||||
* scopes nothing is recorded. `core` is only read.
|
||||
*/
|
||||
extern void sched_trace_check_rows(xce_sched_trace_rec_t* rec,
|
||||
xce_sched_core_t* core, int nres,
|
||||
const int* idxs, const float* total,
|
||||
const float* inuse,
|
||||
const xvec_t* uncomitted,
|
||||
const float* wanted);
|
||||
|
||||
/* A failed compound attempt's reasons (3.5), from its pend-reason set before
|
||||
* the scheduler replaces obj->reason: one ATTEMPT_REASONS entry with a
|
||||
* count per pend-reason code (main reason, host and resource reasons, in
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue