feat(scheduler-sim-decision-trace): capture decision outcomes and reconstructed dispatches
Task 2.3: dispatch rows with limit charges listed separately and resolved through the job's matched limits (raw-number fallback), pend reason set deep-copied, 50 hosts in detail with the rest aggregated, and RECONSTRUCTED records holding the dispatch outcome. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
79c5a0cbda
commit
8efe142bad
4 changed files with 1269 additions and 68 deletions
|
|
@ -371,6 +371,68 @@ typedef struct sched_trace_entry_s {
|
|||
} u;
|
||||
} sched_trace_entry_t;
|
||||
|
||||
/*
|
||||
* Decision outcome (6.1-6.4, 9.4), filled by TraceCapture and rendered
|
||||
* outside the line budget. All pointers point into the record's arena.
|
||||
*/
|
||||
typedef enum {
|
||||
SCHED_TRACE_OUTCOME_NONE = 0,
|
||||
SCHED_TRACE_OUTCOME_DISPATCH,
|
||||
SCHED_TRACE_OUTCOME_PEND
|
||||
} sched_trace_outcome_kind_t;
|
||||
|
||||
/* One allocated amount: a resource row, or a limit charge (6.3: a charge is
|
||||
* never a resource row). A charge names its limit and scope instance (a
|
||||
* host charge has "h=<host>" appended); `limited_res` is the resource the
|
||||
* limit limits, NULL when no matched limit names the charge, in which case
|
||||
* the amount is a raw number. In an aggregate the scope has no host part. */
|
||||
typedef struct {
|
||||
const char* res; /* allocated resource name (a charge: the vres name;
|
||||
* NULL in a limit aggregate) */
|
||||
double value; /* amount, or the total in an aggregate */
|
||||
const char* limit; /* charges only */
|
||||
const char* scope; /* charges only */
|
||||
const char* limited_res; /* charges only; NULL: unknown (raw number) */
|
||||
} sched_trace_alloc_row_t;
|
||||
|
||||
/* One allocated host kept in detail (6.1), in allocation order. */
|
||||
typedef struct {
|
||||
const char* host;
|
||||
int nres;
|
||||
sched_trace_alloc_row_t* res;
|
||||
int ncharges;
|
||||
sched_trace_alloc_row_t* charges;
|
||||
} sched_trace_host_out_t;
|
||||
|
||||
/* Dispatch outcome: the first XCE_TRACE_OUTCOME_HOSTS hosts in detail, the
|
||||
* job's shared rows and charges (6.2), and the omitted hosts' totals per
|
||||
* resource (limits excluded) and per limit, in the order first seen (9.4). */
|
||||
typedef struct {
|
||||
int nhosts; /* kept in detail */
|
||||
sched_trace_host_out_t* hosts;
|
||||
int nshared;
|
||||
sched_trace_alloc_row_t* shared;
|
||||
int nshared_charges;
|
||||
sched_trace_alloc_row_t* shared_charges;
|
||||
int omitted_hosts;
|
||||
int nagg_res;
|
||||
sched_trace_alloc_row_t* agg_res;
|
||||
int nagg_charges;
|
||||
sched_trace_alloc_row_t* agg_charges;
|
||||
} sched_trace_dispatch_out_t;
|
||||
|
||||
/* Pend outcome (6.4): a copy of the decision's pend-reason set holding the
|
||||
* main reason, every entry that names no host and every entry of the first
|
||||
* XCE_TRACE_OUTCOME_HOSTS distinct hosts, in source order (equal to the
|
||||
* source under job_preason_eq() when no host was omitted). Entries of the
|
||||
* hosts after them are counted per pend-reason code (9.4). */
|
||||
typedef struct {
|
||||
xce_job_preason_t* reasons; /* NULL: the decision had none */
|
||||
int omitted_hosts;
|
||||
int ncodes;
|
||||
sched_trace_reason_count_t* omitted_codes; /* first-seen order */
|
||||
} sched_trace_pend_out_t;
|
||||
|
||||
/* One arena chunk; the record frees the whole chain at once. */
|
||||
typedef struct sched_trace_chunk_s {
|
||||
struct sched_trace_chunk_s* next;
|
||||
|
|
@ -416,6 +478,11 @@ struct xce_sched_trace_rec_s {
|
|||
|
||||
sched_trace_counters_t counters;
|
||||
|
||||
/* outcome (6.x, 9.4), outside the line budget */
|
||||
sched_trace_outcome_kind_t outcome;
|
||||
sched_trace_dispatch_out_t dispatch; /* outcome DISPATCH */
|
||||
sched_trace_pend_out_t pend; /* outcome PEND */
|
||||
|
||||
/* stored entries, in the order made; at most line_bound of them */
|
||||
sched_trace_entry_t* entries;
|
||||
sched_trace_entry_t* entries_tail;
|
||||
|
|
@ -677,4 +744,37 @@ extern void sched_trace_check_rows(xce_sched_trace_rec_t* rec,
|
|||
extern void sched_trace_capture_attempt_reasons(xce_sched_trace_rec_t* rec,
|
||||
const xce_pendreason_t* reason);
|
||||
|
||||
/*
|
||||
* A dispatch decision's allocation as the record's outcome (6.1-6.3, 9.4).
|
||||
* Each row is a limit charge when its resource, found by name in
|
||||
* core->resmgr, has XCE_RESF_LIMIT, or, when the name is not registered,
|
||||
* when it starts with "limit=". A charge is resolved by vres name through
|
||||
* the job's matched limits: obj->glimits for shared rows,
|
||||
* obj->hlimits[w->idx] for a host's rows (w found by host name in
|
||||
* core->workers); unresolved, its name and scope are parsed from the
|
||||
* resource name and its limited resource is unknown. NULL obj: nothing
|
||||
* resolves. A NULL alloc stores an empty dispatch. `core` is only read.
|
||||
*/
|
||||
extern void sched_trace_capture_dispatch(xce_sched_trace_rec_t* rec,
|
||||
xce_sched_core_t* core,
|
||||
const xce_sched_obj_t* obj,
|
||||
const xce_job_alloc_t* alloc);
|
||||
|
||||
/* A pend decision's pend-reason set as the record's outcome (6.4, 9.4). */
|
||||
extern void sched_trace_capture_pend(xce_sched_trace_rec_t* rec,
|
||||
const xce_pendreason_t* reason);
|
||||
|
||||
/*
|
||||
* A RECONSTRUCTED record (2.5) for a dispatch the simulator rebuilt from a
|
||||
* recorded allocation, built on the sim thread: the header from `ctl` and
|
||||
* `allocs` as its dispatch outcome, captured as above (`obj` is the job's
|
||||
* schedobj, NULL when it has none). NULL when ctl is NULL or the record
|
||||
* cannot be allocated.
|
||||
*/
|
||||
extern xce_sched_trace_rec_t*
|
||||
sched_trace_rec_reconstructed(const xce_sched_trace_ctl_t* ctl,
|
||||
xce_sched_core_t* core, uint64_t jobid,
|
||||
const xce_sched_obj_t* obj,
|
||||
const xce_job_alloc_t* allocs);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue