add cluster and subcluster information to compareplot

This commit is contained in:
Christoph Kluge 2025-05-06 18:08:35 +02:00
parent aed2bd48fc
commit 4419df8d1b
6 changed files with 135 additions and 2 deletions

View File

@ -174,6 +174,8 @@ type JobStats {
jobId: Int!
startTime: Int!
duration: Int!
cluster: String!
subCluster: String!
numNodes: Int!
numHWThreads: Int
numAccelerators: Int

View File

@ -171,6 +171,7 @@ type ComplexityRoot struct {
}
JobStats struct {
Cluster func(childComplexity int) int
Duration func(childComplexity int) int
JobID func(childComplexity int) int
NumAccelerators func(childComplexity int) int
@ -178,6 +179,7 @@ type ComplexityRoot struct {
NumNodes func(childComplexity int) int
StartTime func(childComplexity int) int
Stats func(childComplexity int) int
SubCluster func(childComplexity int) int
}
JobsStatistics struct {
@ -945,6 +947,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.JobResultList.Offset(childComplexity), true
case "JobStats.cluster":
if e.complexity.JobStats.Cluster == nil {
break
}
return e.complexity.JobStats.Cluster(childComplexity), true
case "JobStats.duration":
if e.complexity.JobStats.Duration == nil {
break
@ -994,6 +1003,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.JobStats.Stats(childComplexity), true
case "JobStats.subCluster":
if e.complexity.JobStats.SubCluster == nil {
break
}
return e.complexity.JobStats.SubCluster(childComplexity), true
case "JobsStatistics.histDuration":
if e.complexity.JobsStatistics.HistDuration == nil {
break
@ -2323,6 +2339,8 @@ type JobStats {
jobId: Int!
startTime: Int!
duration: Int!
cluster: String!
subCluster: String!
numNodes: Int!
numHWThreads: Int
numAccelerators: Int
@ -7533,6 +7551,94 @@ func (ec *executionContext) fieldContext_JobStats_duration(_ context.Context, fi
return fc, nil
}
func (ec *executionContext) _JobStats_cluster(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_JobStats_cluster(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.Cluster, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_JobStats_cluster(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "JobStats",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _JobStats_subCluster(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_JobStats_subCluster(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SubCluster, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_JobStats_subCluster(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "JobStats",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _JobStats_numNodes(ctx context.Context, field graphql.CollectedField, obj *model.JobStats) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_JobStats_numNodes(ctx, field)
if err != nil {
@ -11460,6 +11566,10 @@ func (ec *executionContext) fieldContext_Query_jobsMetricStats(ctx context.Conte
return ec.fieldContext_JobStats_startTime(ctx, field)
case "duration":
return ec.fieldContext_JobStats_duration(ctx, field)
case "cluster":
return ec.fieldContext_JobStats_cluster(ctx, field)
case "subCluster":
return ec.fieldContext_JobStats_subCluster(ctx, field)
case "numNodes":
return ec.fieldContext_JobStats_numNodes(ctx, field)
case "numHWThreads":
@ -17806,6 +17916,16 @@ func (ec *executionContext) _JobStats(ctx context.Context, sel ast.SelectionSet,
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "cluster":
out.Values[i] = ec._JobStats_cluster(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "subCluster":
out.Values[i] = ec._JobStats_subCluster(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "numNodes":
out.Values[i] = ec._JobStats_numNodes(ctx, field, obj)
if out.Values[i] == graphql.Null {

View File

@ -100,6 +100,8 @@ type JobStats struct {
JobID int `json:"jobId"`
StartTime int `json:"startTime"`
Duration int `json:"duration"`
Cluster string `json:"cluster"`
SubCluster string `json:"subCluster"`
NumNodes int `json:"numNodes"`
NumHWThreads *int `json:"numHWThreads,omitempty"`
NumAccelerators *int `json:"numAccelerators,omitempty"`

View File

@ -621,6 +621,8 @@ func (r *queryResolver) JobsMetricStats(ctx context.Context, filter []*model.Job
JobID: int(job.JobID),
StartTime: int(job.StartTime.Unix()),
Duration: int(job.Duration),
Cluster: job.Cluster,
SubCluster: job.SubCluster,
NumNodes: int(job.NumNodes),
NumHWThreads: &numThreadsInt,
NumAccelerators: &numAccsInt,

View File

@ -41,6 +41,7 @@
let filter = [...filterBuffer];
let comparePlotData = {};
let jobIds = [];
let jobClusters = [];
/*uPlot*/
let plotSync = uPlot.sync("compareJobsView");
@ -54,6 +55,8 @@
jobId
startTime
duration
cluster
subCluster
numNodes
numHWThreads
numAccelerators
@ -130,8 +133,9 @@
if (jobs) {
let plotIndex = 0
jobs.forEach((j) => {
// Collect JobIDs for X-Ticks
// Collect JobIDs & Clusters for X-Ticks and Legend
jobIds.push(j.jobId)
jobClusters.push(`${j.cluster} ${j.subCluster}`)
// Resources
comparePlotData['resources'].data[0].push(plotIndex)
comparePlotData['resources'].data[1].push(j.startTime)
@ -203,6 +207,7 @@
title={'Compare Resources'}
xlabel="JobIDs"
xticks={jobIds}
xinfo={jobClusters}
ylabel={'Resource Counts'}
data={comparePlotData['resources'].data}
{plotSync}
@ -217,6 +222,7 @@
title={`Compare Metric '${m}'`}
xlabel="JobIDs"
xticks={jobIds}
xinfo={jobClusters}
ylabel={m}
metric={m}
yunit={comparePlotData[m].unit}

View File

@ -24,6 +24,7 @@
export let data = null;
export let xlabel = "";
export let xticks = [];
export let xinfo = [];
export let ylabel = "";
export let yunit = "";
export let title = "";
@ -102,7 +103,7 @@
label: "JobID",
scale: "x",
value: (u, ts, sidx, didx) => {
return xticks[didx];
return `${xticks[didx]} | ${xinfo[didx]}`;
},
},
{