Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit d0cf304b authored by aumgn's avatar aumgn
Browse files

[src] Add visualizations

parent 0928953c
library('tidyverse')
library('ggthemr')
light_theme <- ggthemr('flat', set_theme = FALSE)
dark_theme <- ggthemr('flat dark', set_theme = FALSE)
args = commandArgs(trailingOnly=TRUE)
if (length(args) != 1) {
stop("Exactly one argument required (csv input)", call.=FALSE)
}
migrations <- read_csv(args[1], col_names = TRUE) %>%
filter(Trigger %in% c('NLB', 'SLB', 'ILB', 'WA', 'WLB')) %>%
group_by(Orig, Dest) %>%
summarize(Count = n()) %>%
ungroup()
cpus_x_breaks <- seq(0, 63)
cpus_y_breaks <- seq(0, 63)
png('migrations_matrix.png', width = 940, height = 900)
ggplot(migrations, aes(x = Dest, y = Orig)) +
geom_tile(aes(fill = Count)) +
scale_x_continuous(breaks = cpus_x_breaks, position = 'top', expand = c(0, 0)) +
scale_y_continuous(breaks = cpus_y_breaks, trans = "reverse", expand = c(0, 0)) +
scale_fill_distiller(palette = "Spectral") +
xlab("Destination CPU") +
ylab("Origin CPU") +
theme(
line = element_blank(),
plot.margin = unit(c(0.2, 0.2, 0.2, 0.2), 'cm'),
legend.text = element_blank()
)
# -*- coding: utf-8 -*-
import os
import sys
import getopt
sys.path.append(os.environ['PERF_EXEC_PATH'] + \
'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
from perf_trace_context import *
from Core import *
import csv
TRIGGER_SLB = 0x0001
TRIGGER_NLB = 0x0002
TRIGGER_ILB = 0x0004
TRIGGER_WLB = 0x0008
TRIGGER_WAFF = 0x0010
TRIGGER_FLB = 0x0020
TRIGGER_ELB = 0x0040
TRIGGER_RT = 0x0080
TRIGGER_DL = 0x0100
TRIGGER_NB = 0x0200
TRIGGER_CA = 0x0400
TRIGGER_HP = 0x0800
TRIGGER_OTH = 0x1000
TRIGGER_EXIT = 0x8000
TRIGGER_SYMBOLS = {
TRIGGER_SLB : 'SLB',
TRIGGER_NLB : 'NLB',
TRIGGER_ILB : 'ILB',
TRIGGER_WLB : 'WLB',
TRIGGER_WAFF : 'WAFF',
TRIGGER_FLB : 'FLB',
TRIGGER_ELB : 'ELB',
TRIGGER_RT : 'RT',
TRIGGER_DL : 'DL',
TRIGGER_NB : 'NB',
TRIGGER_CA : 'CA',
TRIGGER_HP : 'HP',
TRIGGER_OTH : 'OTH',
TRIGGER_EXIT : 'EXIT'
}
data = None
class GlobalData:
def __init__(self):
if len(sys.argv) != 5:
print("Invalid number of arguments expected 4, got {}".format(len(sys.argv) - 1))
print("perf script ... <comm> <exec> <migrations-output> <rq-sizes-output>")
exit(15)
self.comm = sys.argv[1]
self.exec_comm = sys.argv[2]
self.last_secs = 0
self.rq_start = [None] * 64
self.rq_sizes = [0] * 64
try:
self.migrations_file = open(sys.argv[3], 'w')
self.rq_sizes_file = open(sys.argv[4], 'w')
except:
exit(10)
self.migrations_writer = csv.writer(self.migrations_file)
self.migrations_writer.writerow(['Time', 'Comm', 'Pid', 'Orig', 'Dest', 'Trigger'])
self.rq_sizes_writer = csv.writer(self.rq_sizes_file)
self.rq_sizes_writer.writerow(['Start', 'End', 'Cpu', 'Size'])
def perf_clean_up_comm(self, comm, trigger):
# Perf python lib seems to mess up the translation of the comm
# fields leaving them with some sort of trailing 0 followed by trash
for i, c in enumerate(comm):
if c == 0:
comm = comm[:i]
break
if comm == self.exec_comm and trigger == TRIGGER_ELB:
comm = self.comm
return comm
def perf_timestamp_format(self, secs, nsecs):
return "{}.{}".format(secs, nsecs)
def process(self, secs, nsecs, comm, pid, trigger, orig_cpu, dest_cpu):
comm = self.perf_clean_up_comm(comm, trigger)
now = self.perf_timestamp_format(secs, nsecs)
if trigger != TRIGGER_EXIT:
self.migrations_writer.writerow([
now, comm, pid, orig_cpu, dest_cpu, TRIGGER_SYMBOLS.get(trigger)
])
if comm != self.comm:
return
if self.last_secs < secs:
self.last_secs = secs + 1
if trigger not in (TRIGGER_ELB, TRIGGER_FLB):
start = self.rq_start[orig_cpu]
orig_was = self.rq_sizes[orig_cpu]
orig_now = orig_was - 1
self.rq_start[orig_cpu] = now
self.rq_sizes[orig_cpu] = orig_now
if orig_was > 0:
self.rq_sizes_writer.writerow([start, now, orig_cpu, orig_was])
if trigger != TRIGGER_EXIT:
self.migrations_writer.writerow([now, comm, pid, orig_cpu, dest_cpu,
TRIGGER_SYMBOLS.get(trigger)])
start = self.rq_start[dest_cpu]
dest_was = self.rq_sizes[dest_cpu]
dest_now = dest_was + 1
self.rq_start[dest_cpu] = now
self.rq_sizes[dest_cpu] = dest_now
if dest_was > 0:
self.rq_sizes_writer.writerow([start, now, dest_cpu, dest_was])
def trace_begin():
global data
data = GlobalData()
def trace_end():
for cpu in range(64):
data.process(data.last_secs, 0, data.comm, 0, TRIGGER_EXIT, cpu, -1)
data.migrations_file.close()
data.rq_sizes_file.close()
def sched__sched_thread_placement(event_name, context, common_cpu,
common_secs, common_nsecs, common_pid, common_comm,
common_callchain, comm, pid, orig_cpu, dest_cpu,
exec_cpu, trigger, level, task_load):
data.process(common_secs, common_nsecs, comm, pid, trigger, orig_cpu, dest_cpu)
def sched__sched_process_exit(event_name, context, common_cpu,
common_secs, common_nsecs, common_pid, common_comm,
common_callchain, comm, pid, prio):
data.process(common_secs, common_nsecs, comm, pid, TRIGGER_EXIT, common_cpu, -1)
library('tidyverse')
library('scales')
library('ggthemr')
light_theme <- ggthemr('flat', set_theme = FALSE)
dark_theme <- ggthemr('flat dark', set_theme = FALSE)
args = commandArgs(trailingOnly=TRUE)
if (length(args) < 2) {
stop("Three arguments required (comm, migrations.csv rq-sizes filenames)", call.=FALSE)
}
comm = args[1]
migrations <- read_csv(args[2], col_names = TRUE) %>%
filter(Comm == comm)
rq_sizes <- read_csv(args[3], col_names = TRUE)
if (length(args) == 4) {
time_start <- as.numeric(args[4])
time_end <- as.numeric(args[5])
} else {
time_start <- min(migrations$Time, rq_sizes$Start, rq_sizes$End)
time_end <- max(migrations$Time, rq_sizes$Start, rq_sizes$End)
}
time_offset <- (time_end - time_start) / 500
time_breaks <- seq(time_start, time_end, length.out = 8)
cpus_breaks <- seq(0, 63)
trigger_colors <- c(
FLB = '#9B58B5', ELB = '#8F44AD',
SLB = '#1BBC9B', NLB = '#1BBC9B', ILB = '#2DCC70', WLB = '#27AE61',
WAFF = '#F39C11',
NB = '#8F44AD',
RT = '#34495E', DL = '#2D3E50' ,
CA = '#7E8C8D', HP = '#95A5A5' , OTH = '#BEC3C7'
)
png('sched_timeline.png', width = 1600, height = 900)
ggplot(rq_sizes, aes(y = Cpu)) +
geom_rect(aes(
xmin = Start,
xmax = End,
ymin = Cpu,
ymax = Cpu + 1,
fill = Size
)) +
scale_x_continuous(breaks = time_breaks) +
scale_y_continuous(breaks = cpus_breaks, trans = "reverse", expand = c(0, 0)) +
coord_cartesian(xlim = c(time_start, time_end)) +
scale_fill_distiller(palette = "Spectral") +
geom_segment(data = migrations, aes(
x = Time - time_offset,
xend = Time + time_offset,
y = Orig + 0.5,
yend = Dest + 0.5,
color = Trigger
)) +
scale_color_manual(values = trigger_colors) +
xlab("Time") +
ylab("CPUs") +
light_theme$theme +
theme(
line = element_blank(),
plot.margin = unit(c(0.2, 0.2, 0.2, 0.2), 'cm')
)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment