Skip to content

Commit

Permalink
Add jobs flags + run fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
Lars T Hansen committed Jan 14, 2025
1 parent 0f30c8b commit 1a4574a
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 25 deletions.
84 changes: 84 additions & 0 deletions code/sonalyze/cmd/jobs/jobs-table.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,48 @@ var jobsFormatters = map[string]Formatter[*jobSummary]{
},
Help: "(DurationValue) Total GPU time of the job across all cards",
},
"SomeGpu": {
Fmt: func(d *jobSummary, ctx PrintMods) string {
return FormatBool(d.computedFlags&kUsesGpu != 0, ctx)
},
Help: "(bool) True iff process was seen to use some GPU",
},
"NoGpu": {
Fmt: func(d *jobSummary, ctx PrintMods) string {
return FormatBool(d.computedFlags&kDoesNotUseGpu != 0, ctx)
},
Help: "(bool) True iff process was seen to use no GPU",
},
"Running": {
Fmt: func(d *jobSummary, ctx PrintMods) string {
return FormatBool(d.computedFlags&kIsLiveAtEnd != 0, ctx)
},
Help: "(bool) True iff process appears to still be running at end of time window",
},
"Completed": {
Fmt: func(d *jobSummary, ctx PrintMods) string {
return FormatBool(d.computedFlags&kIsNotLiveAtEnd != 0, ctx)
},
Help: "(bool) True iff process appears not to be running at end of time window",
},
"Zombie": {
Fmt: func(d *jobSummary, ctx PrintMods) string {
return FormatBool(d.computedFlags&kIsZombie != 0, ctx)
},
Help: "(bool) True iff the process looks like a zombie",
},
"Primordial": {
Fmt: func(d *jobSummary, ctx PrintMods) string {
return FormatBool(d.computedFlags&kIsLiveAtStart != 0, ctx)
},
Help: "(bool) True iff the process appears to have been alive at the start of the time window",
},
"BornLater": {
Fmt: func(d *jobSummary, ctx PrintMods) string {
return FormatBool(d.computedFlags&kIsNotLiveAtStart != 0, ctx)
},
Help: "(bool) True iff the process appears not to have been alive at the start of the time window",
},
"Submit": {
Fmt: func(d *jobSummary, ctx PrintMods) string {
if d.sacctInfo != nil {
Expand Down Expand Up @@ -654,6 +696,48 @@ var jobsPredicates = map[string]Predicate[*jobSummary]{
return cmp.Compare(d.GpuTime, v.(DurationValue))
},
},
"SomeGpu": Predicate[*jobSummary]{
Convert: CvtString2Bool,
Compare: func(d *jobSummary, v any) int {
return CompareBool(d.computedFlags&kUsesGpu != 0, v.(bool))
},
},
"NoGpu": Predicate[*jobSummary]{
Convert: CvtString2Bool,
Compare: func(d *jobSummary, v any) int {
return CompareBool(d.computedFlags&kDoesNotUseGpu != 0, v.(bool))
},
},
"Running": Predicate[*jobSummary]{
Convert: CvtString2Bool,
Compare: func(d *jobSummary, v any) int {
return CompareBool(d.computedFlags&kIsLiveAtEnd != 0, v.(bool))
},
},
"Completed": Predicate[*jobSummary]{
Convert: CvtString2Bool,
Compare: func(d *jobSummary, v any) int {
return CompareBool(d.computedFlags&kIsNotLiveAtEnd != 0, v.(bool))
},
},
"Zombie": Predicate[*jobSummary]{
Convert: CvtString2Bool,
Compare: func(d *jobSummary, v any) int {
return CompareBool(d.computedFlags&kIsZombie != 0, v.(bool))
},
},
"Primordial": Predicate[*jobSummary]{
Convert: CvtString2Bool,
Compare: func(d *jobSummary, v any) int {
return CompareBool(d.computedFlags&kIsLiveAtStart != 0, v.(bool))
},
},
"BornLater": Predicate[*jobSummary]{
Convert: CvtString2Bool,
Compare: func(d *jobSummary, v any) int {
return CompareBool(d.computedFlags&kIsNotLiveAtStart != 0, v.(bool))
},
},
"Submit": Predicate[*jobSummary]{
Convert: CvtString2DateTimeValue,
Compare: func(d *jobSummary, v any) int {
Expand Down
26 changes: 25 additions & 1 deletion code/sonalyze/cmd/jobs/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,29 @@ FIELDS *jobSummary
CpuTime DurationValue desc:"Total CPU time of the job across all cores" alias:"cputime"
GpuTime DurationValue desc:"Total GPU time of the job across all cards" alias:"gputime"
# The expressions extracting bit flags happen to work but this is very brittle and depends
# on internals of the table generation logic. Essentially, the "field" has a constraint that
# when appended to "<something>." it yields a valid expression of the right type, and these
# partial expressions have that form. And it works in Go only because the operator precedence
# is right; in C it would not work. A more principled solution is to not use "field" but to
# introduce a "compute" attribute that takes an expression with a free variable eg "_object"
# that would be bound to the object in question.
SomeGpu bool desc:"True iff process was seen to use some GPU" \
field:"computedFlags & kUsesGpu != 0"
NoGpu bool desc:"True iff process was seen to use no GPU" \
field:"computedFlags & kDoesNotUseGpu != 0"
Running bool desc:"True iff process appears to still be running at end of time window" \
field:"computedFlags & kIsLiveAtEnd != 0"
Completed bool desc:"True iff process appears not to be running at end of time window" \
field:"computedFlags & kIsNotLiveAtEnd != 0"
Zombie bool desc:"True iff the process looks like a zombie" \
field:"computedFlags & kIsZombie != 0"
Primordial bool desc:"True iff the process appears to have been alive at the start of the time window" \
field:"computedFlags & kIsLiveAtStart != 0"
BornLater bool desc:"True iff the process appears not to have been alive at the start of the time window" \
field:"computedFlags & kIsNotLiveAtStart != 0"
# NOTE! The slurm fields (via *sacctInfo) are checked for in perform.go. We can add more slurm
# fields here but if so they must also be added there.
Expand Down Expand Up @@ -147,7 +170,8 @@ ALIASES
GpuAvgPct,GpuPeakPct,RelativeGpuAvgPct,RelativeGpuPeakPct,OccupiedRelativeGpuAvgPct,\
OccupiedRelativeGpuPeakPct,GpuMemAvgGB,GpuMemPeakGB,RelativeGpuMemAvgPct,\
RelativeGpuMemPeakPct,OccupiedRelativeGpuMemAvgPct,OccupiedRelativeGpuMemPeakPct,Gpus,GpuFail,\
Cmd,Host,Now,Now/sec,Classification,CpuTime/sec,CpuTime,GpuTime/sec,GpuTime
Cmd,Host,Now,Now/sec,Classification,CpuTime/sec,CpuTime,GpuTime/sec,GpuTime,\
SomeGpu,NoGpu,Running,Completed,Zombie,Primordial,BornLater
Std JobAndMark,User,Duration,Host
Cpu CpuAvgPct,CpuPeakPct
RelativeCpu RelativeCpuAvgPct,RelativeCpuPeakPct
Expand Down
2 changes: 1 addition & 1 deletion code/sonalyze/table/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ func CvtString2DurationValue(s string) (any, error) {
if m[7] != "" {
minutes, _ = strconv.Atoi(m[8])
}
return (((int64(weeks)*7+int64(days))*24+int64(hours))*60 + int64(minutes))*60, nil
return (((int64(weeks)*7+int64(days))*24+int64(hours))*60 + int64(minutes)) * 60, nil
}

func CvtString2U32Duration(s string) (any, error) {
Expand Down
43 changes: 20 additions & 23 deletions code/sonalyze/table/data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,20 @@ func TestDataFormatting(t *testing.T) {
}

if s := FormatUstr(StringToUstr("hello"), 0); s != "hello" {
t.Fatalf("Ustr %s", s);
t.Fatalf("Ustr %s", s)
}
if s := FormatUstr(UstrEmpty, PrintModNoDefaults); s != "*skip*" {
t.Fatalf("Ustr %s", s);
t.Fatalf("Ustr %s", s)
}

if s := FormatUstrMax30(StringToUstr("supercalifragilisticexpialidocious"), PrintModFixed);
s != "supercalifragilisticexpialidoc" {
t.Fatalf("UstrMax30 %s", s);
if s := FormatUstrMax30(StringToUstr("supercalifragilisticexpialidocious"), PrintModFixed); s != "supercalifragilisticexpialidoc" {
t.Fatalf("UstrMax30 %s", s)
}
if s := FormatUstrMax30(StringToUstr("supercalifragilisticexpialidocious"), 0);
s != "supercalifragilisticexpialidocious" {
t.Fatalf("UstrMax30 %s", s);
if s := FormatUstrMax30(StringToUstr("supercalifragilisticexpialidocious"), 0); s != "supercalifragilisticexpialidocious" {
t.Fatalf("UstrMax30 %s", s)
}
if s := FormatUstrMax30(UstrEmpty, PrintModNoDefaults); s != "*skip*" {
t.Fatalf("UstrMax30 %s", s);
t.Fatalf("UstrMax30 %s", s)
}

if s := FormatInt64(int64(123456), 0); s != "123456" {
Expand Down Expand Up @@ -144,14 +142,14 @@ func TestDataFormatting(t *testing.T) {
t.Fatalf("String %s", s)
}

if s := FormatStrings([]string{"a","b","c"}, 0); s != "a,b,c" {
t.Fatalf("Strings %s", s);
if s := FormatStrings([]string{"a", "b", "c"}, 0); s != "a,b,c" {
t.Fatalf("Strings %s", s)
}
if s := FormatStrings([]string{}, PrintModNoDefaults); s != "*skip*" {
t.Fatalf("Strings %s", s);
t.Fatalf("Strings %s", s)
}
if s := FormatStrings(nil, PrintModNoDefaults); s != "*skip*" {
t.Fatalf("Strings %s", s);
t.Fatalf("Strings %s", s)
}

set, _ := gpuset.NewGpuSet("1,3")
Expand Down Expand Up @@ -347,7 +345,7 @@ func TestCvt2Strings(t *testing.T) {
same(t, xs, []string{"a"})
xs, err = CvtString2Strings("a,b,c,d")
check(t, err)
same(t, xs, []string{"a","b","c","d"})
same(t, xs, []string{"a", "b", "c", "d"})
}

func TestCvt2GpuSet(t *testing.T) {
Expand All @@ -357,18 +355,18 @@ func TestCvt2GpuSet(t *testing.T) {

xs, err := CvtString2GpuSet("none")
check(t, err)
same(t, xs, gpuset.EmptyGpuSet());
same(t, xs, gpuset.EmptyGpuSet())

xs, err = CvtString2GpuSet("unknown")
check(t, err)
same(t, xs, gpuset.UnknownGpuSet());
same(t, xs, gpuset.UnknownGpuSet())

xs, err = CvtString2GpuSet("1,2,3")
check(t, err)
s := gpuset.EmptyGpuSet()
s, err = gpuset.Adjoin(s, 1, 2, 3)
check(t, err)
same(t, xs, s);
same(t, xs, s)
}

func TestCvt2Misc(t *testing.T) {
Expand Down Expand Up @@ -449,22 +447,21 @@ func TestCvt2Misc(t *testing.T) {
func TestCvt2DurationValue(t *testing.T) {
x, err := CvtString2DurationValue("1h")
check(t, err)
same(t, x, int64(3600));
same(t, x, int64(3600))

x, err = CvtString2DurationValue("1h2m")
check(t, err)
same(t, x, int64(3600 + 120));
same(t, x, int64(3600+120))

x, err = CvtString2DurationValue("2d")
check(t, err)
same(t, x, int64(3600 * 24 * 2))
same(t, x, int64(3600*24*2))

x, err = CvtString2DurationValue("3w")
check(t, err)
same(t, x, int64(3600 * 24 * 7 * 3))
same(t, x, int64(3600*24*7*3))

x, err = CvtString2U32Duration("1h")
check(t, err)
same(t, x, uint32(3600));
same(t, x, uint32(3600))
}

0 comments on commit 1a4574a

Please sign in to comment.