def show_core_locality(df, task_re, label): df = df[df['event'] == 'sched__sched_switch'] df = df[df['task_name'].str.match(task_re)] # aggregate all the per core tasks (e.g. swapper/0 -> swapper) df['task_name'] = df['task_name'].str.replace(r'/.*$', '') # group by task name gb = df.groupby('task_name') task_list = gb.groups p = figure(plot_width=1000, plot_height=800, **title_style) p.xaxis.axis_label = 'time (usecs)' p.yaxis.axis_label = 'core' p.legend.orientation = "bottom_right" p.xaxis.axis_label_text_font_size = "10pt" p.yaxis.axis_label_text_font_size = "10pt" p.title = "Core locality (%s)" % (label) color_list = cycle_colors(task_list) for task, color in zip(task_list, color_list): dfe = gb.get_group(task) # add 1 column to contain the starting time for each run period dfe['start'] = dfe['usecs'] - dfe['duration'] tid = dfe['pid'].iloc[0] count = len(dfe) legend_text = '%s:%d (%d)' % (task, tid, count) # draw end of runs p.circle('usecs', 'cpu', source=ColumnDataSource(dfe), size=get_disc_size(count) + 2, color=color, alpha=0.3, legend=legend_text) # draw segments to show the entire runs p.segment('start', 'cpu', 'usecs', 'cpu', line_width=5, line_color=color, source=ColumnDataSource(dfe)) # specify how to output the plot(s) output_html(p, 'coreloc', task_re)
def show_core_locality(df, task_re, label): df = df[df['event'] == 'sched__sched_switch'] df = df[df['task_name'].str.match(task_re)] # aggregate all the per core tasks (e.g. swapper/0 -> swapper) df['task_name'] = df['task_name'].str.replace(r'/.*$', '') # group by task name gb = df.groupby('task_name') task_list = gb.groups p = figure(plot_width=1000, plot_height=800, **title_style) p.xaxis.axis_label = 'time (usecs)' p.yaxis.axis_label = 'core' p.legend.orientation = "bottom_right" p.xaxis.axis_label_text_font_size = "10pt" p.yaxis.axis_label_text_font_size = "10pt" p.title = "Core locality (%s)" % (label) color_list = cycle_colors(task_list) for task, color in zip(task_list, color_list): dfe = gb.get_group(task) # add 1 column to contain the starting time for each run period dfe['start'] = dfe['usecs'] - dfe['duration'] tid = dfe['pid'].iloc[0] count = len(dfe) legend_text = '%s:%d (%d)' % (task, tid, count) # draw end of runs p.circle('usecs', 'cpu', source=ColumnDataSource(dfe), size=get_disc_size(count) + 2, color=color, alpha=0.3, legend=legend_text) # draw segments to show the entire runs p.segment('start', 'cpu', 'usecs', 'cpu', line_width=5, line_color=color, source=ColumnDataSource(dfe)) # specify how to output the plot(s) output_html('coreloc', task_re) # display the figure show(p)
def show_sw_kvm_heatmap(df, task_re, label, show_ctx_switches, show_kvm): gb = get_groupby(df, task_re) chart_list = [] # these are the 2 main events to show for kvm events legend_map_kvm = { 'kvm_exit': (BLUE, 'vcpu running (y=vcpu run time)', False), 'kvm_entry': (ORANGE, 'vcpu not running (y=kvm+sleep time)', False) } # context switch events legend_map_ctx_sw = { 'sched__sched_stat_sleep': (RED, 'wakeup from sleep (y=sleep time)', True), 'sched__sched_switch': (GREEN, 'switched out from cpu (y=run time)', True) } if show_kvm and show_ctx_switches: legend_map = dict(legend_map_kvm.items() + legend_map_ctx_sw.items()) title = "Scheduler and KVM events" prefix = 'swkvm' elif show_kvm: legend_map = legend_map_kvm title = "KVM events" prefix = 'kvm' else: legend_map = legend_map_ctx_sw title = "Scheduler events" prefix = 'sw' width = 1000 height = 800 show_legend = True nb_charts = len(gb.groups) if nb_charts == 0: print 'No selection matching: ' + task_re return if nb_charts > 1: width /= 2 height /= 2 tstyle = grid_title_style else: tstyle = title_style task_list = gb.groups.keys() task_list.sort() show_legend = True duration_max = usecs_max = -1 duration_min = usecs_min = sys.maxint event_list = legend_map.keys() event_list.sort() for task in task_list: p = figure(plot_width=width, plot_height=height, y_axis_type="log", **tstyle) p.xaxis.axis_label = 'time (usecs)' p.yaxis.axis_label = 'duration (usecs)' p.legend.orientation = "bottom_right" p.xaxis.axis_label_text_font_size = "10pt" p.yaxis.axis_label_text_font_size = "10pt" if label: p.title = "%s for %s (%s)" % (title, task, label) label = None else: p.title = task p.ygrid.minor_grid_line_color = 'navy' p.ygrid.minor_grid_line_alpha = 0.1 accumulated_time = {} total_time = 0 dfg = gb.get_group(task) # remove any row with zero duration as it confuses the chart library dfg = dfg[dfg['duration'] > 0] for event in event_list: dfe = dfg[dfg.event == event] duration_min = min(duration_min, dfe['duration'].min()) duration_max = max(duration_max, dfe['duration'].max()) usecs_min = min(usecs_min, dfe['usecs'].min()) usecs_max = max(usecs_max, dfe['usecs'].max()) count = len(dfe) color, legend_text, cx_sw = legend_map[event] if show_legend: legend_text = '%s (%d)' % (legend_text, count) elif color == GREEN: legend_text = '(%d)' % (count) else: legend_text = None # there is bug in bokeh when there are too many circles to draw, nothing is visible if len(dfe) > 50000: dfe = dfe[:50000] print 'Series for %s display truncated to 50000 events' % (event) if cx_sw: draw_shape = p.circle size = get_disc_size(count) else: draw_shape = p.diamond size = get_disc_size(count) + 4 draw_shape('usecs', 'duration', source=ColumnDataSource(dfe), size=size, color=color, alpha=0.3, legend=legend_text) event_duration = dfe['duration'].sum() accumulated_time[event] = event_duration total_time += event_duration chart_list.append(p) show_legend = False shared_x_range = Range1d(usecs_min, usecs_max) shared_y_range = Range1d(duration_min, duration_max) for p in chart_list: p.x_range = shared_x_range p.y_range = shared_y_range # specify how to output the plot(s) output_html(prefix, task_re) # display the figure if len(chart_list) == 1: show(chart_list[0]) else: # split the list into an array of rows with 2 charts per row gp = gridplot(split_list(chart_list, 2)) show(gp)
def show_sw_kvm_heatmap(df, task_re, label, show_ctx_switches, show_kvm): gb = get_groupby(df, task_re) chart_list = [] # these are the 2 main events to show for kvm events legend_map_kvm = { 'kvm_exit': (BLUE, 'vcpu running (y=vcpu run time)', False), 'kvm_entry': (ORANGE, 'vcpu not running (y=kvm+sleep time)', False) } # context switch events legend_map_ctx_sw = { 'sched__sched_stat_sleep': (RED, 'wakeup from sleep (y=sleep time)', True), 'sched__sched_switch': (GREEN, 'switched out from cpu (y=run time)', True) } if show_kvm and show_ctx_switches: legend_map = dict(legend_map_kvm.items() + legend_map_ctx_sw.items()) title = "Scheduler and KVM events" prefix = 'swkvm' elif show_kvm: legend_map = legend_map_kvm title = "KVM events" prefix = 'kvm' else: legend_map = legend_map_ctx_sw title = "Scheduler events" prefix = 'sw' width = 1000 height = 800 show_legend = True nb_charts = len(gb.groups) if nb_charts == 0: print 'No selection matching: ' + task_re return if nb_charts > 1: width /= 2 height /= 2 tstyle = grid_title_style else: tstyle = title_style task_list = gb.groups.keys() task_list.sort() show_legend = True duration_max = usecs_max = -1 duration_min = usecs_min = sys.maxint event_list = legend_map.keys() event_list.sort() for task in task_list: p = figure(plot_width=width, plot_height=height, y_axis_type="log", **tstyle) p.xaxis.axis_label = 'time (usecs)' p.yaxis.axis_label = 'duration (usecs)' p.legend.orientation = "bottom_right" p.xaxis.axis_label_text_font_size = "10pt" p.yaxis.axis_label_text_font_size = "10pt" if label: p.title = "%s for %s (%s)" % (title, task, label) label = None else: p.title = task p.ygrid.minor_grid_line_color = 'navy' p.ygrid.minor_grid_line_alpha = 0.1 accumulated_time = {} total_time = 0 dfg = gb.get_group(task) # remove any row with zero duration as it confuses the chart library dfg = dfg[dfg['duration'] > 0] for event in event_list: dfe = dfg[dfg.event == event] duration_min = min(duration_min, dfe['duration'].min()) duration_max = max(duration_max, dfe['duration'].max()) usecs_min = min(usecs_min, dfe['usecs'].min()) usecs_max = max(usecs_max, dfe['usecs'].max()) count = len(dfe) color, legend_text, cx_sw = legend_map[event] if show_legend: legend_text = '%s (%d)' % (legend_text, count) elif color == GREEN: legend_text = '(%d)' % (count) else: legend_text = None # there is bug in bokeh when there are too many circles to draw, nothing is visible if len(dfe) > 50000: dfe = dfe[:50000] print 'Series for %s display truncated to 50000 events' % (event) if cx_sw: draw_shape = p.circle size = get_disc_size(count) else: draw_shape = p.diamond size = get_disc_size(count) + 4 draw_shape('usecs', 'duration', source=ColumnDataSource(dfe), size=size, color=color, alpha=0.3, legend=legend_text) event_duration = dfe['duration'].sum() accumulated_time[event] = event_duration total_time += event_duration chart_list.append(p) show_legend = False shared_x_range = Range1d(usecs_min, usecs_max) shared_y_range = Range1d(duration_min, duration_max) for p in chart_list: p.x_range = shared_x_range p.y_range = shared_y_range # specify how to output the plot(s) # display the figure if len(chart_list) == 1: output_html(chart_list[0], prefix, task_re) else: # split the list into an array of rows with 2 charts per row gp = gridplot(split_list(chart_list, 2)) output_html(gp, prefix, task_re)