Blame test/draw_plots.py

Packit 345191
#
Packit 345191
#  Copyright (C) 2016 - 2018 Intel Corporation.
Packit 345191
#  All rights reserved.
Packit 345191
#
Packit 345191
#  Redistribution and use in source and binary forms, with or without
Packit 345191
#  modification, are permitted provided that the following conditions are met:
Packit 345191
#  1. Redistributions of source code must retain the above copyright notice(s),
Packit 345191
#     this list of conditions and the following disclaimer.
Packit 345191
#  2. Redistributions in binary form must reproduce the above copyright notice(s),
Packit 345191
#     this list of conditions and the following disclaimer in the documentation
Packit 345191
#     and/or other materials provided with the distribution.
Packit 345191
#
Packit 345191
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
Packit 345191
#  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
Packit 345191
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
Packit 345191
#  EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit 345191
#  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 345191
#  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit 345191
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit 345191
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
Packit 345191
#  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
Packit 345191
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 345191
#
Packit 345191
Packit 345191
from mpl_toolkits.mplot3d import Axes3D
Packit 345191
import matplotlib.pyplot as plt
Packit 345191
import numpy as np
Packit 345191
import numpy.ma as ma
Packit 345191
import os
Packit 345191
from shutil import rmtree
Packit 345191
Packit 345191
files = ('alloctest_hbw.txt', 'alloctest_glibc.txt', 'alloctest_tbb.txt', 'alloctest_pmem.txt')
Packit 345191
legend = ('avg hbw', 'avg glibc', 'avg tbb', 'avg pmem', 'first operation')
Packit 345191
colors = ('red', 'green', 'blue', 'black')
Packit 345191
first_operation_color = 'yellow'
Packit 345191
Packit 345191
threads_values = ('1', '2', '4', '8', '16', '18', '36')
Packit 345191
Packit 345191
small_sizes_values = ('1', '4', '16')
Packit 345191
medium_sizes_values = ('64', '256')
Packit 345191
big_sizes_values = ('1024', '4096', '16384')
Packit 345191
sizes_values = (small_sizes_values, medium_sizes_values, big_sizes_values)
Packit 345191
sizes_display = ('small', 'medium', 'big')
Packit 345191
Packit 345191
operations = ('Allocation', 'Free', 'Total')
Packit 345191
Packit 345191
iterations = 1000
Packit 345191
output_directory = './plots/'
Packit 345191
Packit 345191
threads_index      = np.arange(len(threads_values))
Packit 345191
small_sizes_index  = np.arange(len(small_sizes_values))
Packit 345191
medium_sizes_index = np.arange(len(medium_sizes_values))
Packit 345191
big_sizes_index    = np.arange(len(big_sizes_values))
Packit 345191
sizes_index = (small_sizes_index, medium_sizes_index, big_sizes_index)
Packit 345191
Packit 345191
# 3D and 2D plots needs different width, so that bars do not cover each other in 3D
Packit 345191
bar_width_2D = 0.2
Packit 345191
bar_width_3D = 0.1
Packit 345191
Packit 345191
# return times (total, allocation, free, first allocation, first free) as columns 2 - 6
Packit 345191
def return_times(entry):
Packit 345191
    return entry[:,2], entry[:,3], entry[:,4], entry[:,5], entry[:,6]
Packit 345191
Packit 345191
# initialize axis with labels, ticks and values
Packit 345191
def init_axis(fig, suptitle, subplot_projection, x_label, x_ticks, x_values, y_label, y_ticks, y_values, z_label):
Packit 345191
    assert fig is not None
Packit 345191
    fig.clf()
Packit 345191
    fig.suptitle(suptitle)
Packit 345191
    if subplot_projection:
Packit 345191
        ax = fig.add_subplot(111, projection=subplot_projection)
Packit 345191
    else:
Packit 345191
        ax = fig.add_subplot(111)
Packit 345191
    assert ax is not None
Packit 345191
    if x_label:
Packit 345191
        ax.set_xlabel(x_label)
Packit 345191
        if x_ticks is not None and x_values is not None:
Packit 345191
            ax.set_xticks(x_ticks)
Packit 345191
            ax.set_xticklabels(x_values)
Packit 345191
    if y_label:
Packit 345191
        ax.set_ylabel(y_label)
Packit 345191
        if y_ticks is not None and y_values is not None:
Packit 345191
            ax.set_yticks(y_ticks)
Packit 345191
            ax.set_yticklabels(y_values)
Packit 345191
    if z_label:
Packit 345191
        ax.set_zlabel(z_label)
Packit 345191
    return ax
Packit 345191
Packit 345191
def draw_bar(ax, show_first_operation, x, y, time, init_time, draw_color):
Packit 345191
    assert ax is not None
Packit 345191
    if y is None:
Packit 345191
        if show_first_operation is True:
Packit 345191
            mask_time = ma.where(time>=init_time)
Packit 345191
            mask_init_time = ma.where(init_time>=time)
Packit 345191
            ax.bar(x[mask_time], time[mask_time], width=bar_width, color=draw_color)
Packit 345191
            ax.bar(x, init_time, width=bar_width, color=first_operation_color)
Packit 345191
            ax.bar(x[mask_init_time], time[mask_init_time], width=bar_width, color=draw_color)
Packit 345191
        else:
Packit 345191
            ax.bar(x, time, width=bar_width, color=draw_color)
Packit 345191
    else:
Packit 345191
        if show_first_operation is True:
Packit 345191
            mask_time = ma.where(time>=init_time)
Packit 345191
            mask_init_time = ma.where(init_time>=time)
Packit 345191
            ax.bar(x[mask_time], (time - init_time)[mask_time], y[mask_time], bottom=init_time[mask_time], zdir='y', width=bar_width, color=draw_color)
Packit 345191
            ax.bar(x[mask_init_time], (init_time - time)[mask_init_time], y[mask_init_time], bottom=time[mask_init_time], zdir='y', width=bar_width, color=first_operation_color)
Packit 345191
            ax.bar(x[mask_init_time], time[mask_init_time], y[mask_init_time], zdir='y', width=bar_width, color=draw_color)
Packit 345191
            ax.bar(x[mask_time], init_time[mask_time], y[mask_time], zdir='y', width=bar_width, color=first_operation_color)
Packit 345191
        else:
Packit 345191
            ax.bar(x, time, y, zdir='y', width=bar_width, color=draw_color)
Packit 345191
Packit 345191
def save_plot(show_first_operation, subfolder, filename):
Packit 345191
    if show_first_operation:
Packit 345191
        path = os.path.join(output_directory, "with_first_operation")
Packit 345191
    else:
Packit 345191
        path = os.path.join(output_directory, "without_first_operation")
Packit 345191
    if subfolder:
Packit 345191
        path = os.path.join(path, subfolder)
Packit 345191
    if not os.path.exists(path):
Packit 345191
        os.mkdir(path)
Packit 345191
    plt.savefig(os.path.join(path, filename))
Packit 345191
    print "Saved file %s" % filename
Packit 345191
Packit 345191
def load_data_from_files():
Packit 345191
    data = []
Packit 345191
    # load all files into data
Packit 345191
    for f in files:
Packit 345191
        assert os.path.isfile(f) is True
Packit 345191
        data.append(np.loadtxt(f, comments='#'))
Packit 345191
    return data
Packit 345191
Packit 345191
def set_bar_width_and_offsets(requested_width):
Packit 345191
    bar_width = requested_width
Packit 345191
    offsets = (0, bar_width, 2*bar_width, 3*bar_width)
Packit 345191
    return bar_width, offsets
Packit 345191
Packit 345191
if os.path.exists(output_directory):
Packit 345191
    rmtree(output_directory)
Packit 345191
os.mkdir(output_directory)
Packit 345191
Packit 345191
data = load_data_from_files()
Packit 345191
Packit 345191
fig = plt.figure()
Packit 345191
Packit 345191
########################################
Packit 345191
# Draw 3D plots (time, sizes, threads) #
Packit 345191
########################################
Packit 345191
Packit 345191
bar_width, offsets = set_bar_width_and_offsets(bar_width_3D)
Packit 345191
Packit 345191
# for each size range (small, medium, big)
Packit 345191
for size_values, size_index, size_display in zip(sizes_values, sizes_index, sizes_display):
Packit 345191
    # show plots with and without first operation
Packit 345191
    for show_first_operation in (True, False):
Packit 345191
        # for each operation (allocation, free, total)
Packit 345191
        for operation in operations:
Packit 345191
            # add bar_width to each element of size_index
Packit 345191
            ax = init_axis(fig, "%s time of %s sizes (%s iterations)" % (operation, size_display, iterations), '3d',
Packit 345191
                           'size [kB]', size_index + (bar_width,) * len(size_index), size_values,
Packit 345191
                           'threads', threads_index, threads_values,
Packit 345191
                           'time [ms]')
Packit 345191
            legend_data = []
Packit 345191
            # for each allocator (hbw, glibc, tbb, pmem)
Packit 345191
            for entry, offset, draw_color in zip(data, offsets, colors):
Packit 345191
                # remove all rows where column 1 (size) is not in size_values (current size range)
Packit 345191
                entry = entry[np.in1d(entry[:,1], np.array(size_values).astype(np.int))]
Packit 345191
                # convert column 0 (threads values) to thread index
Packit 345191
                threads_col = np.array([threads_values.index(str(n)) for n in map(int, entry[:,0])])
Packit 345191
                # convert column 1 (sizes values) to size index
Packit 345191
                size_col = [size_values.index(str(n)) for n in map(int, entry[:,1])]
Packit 345191
                # add offset to size index so that bars display near each other
Packit 345191
                size_col = np.array(size_col) + offset
Packit 345191
                total_time_col, alloc_time_col, free_time_col, first_alloc_time_col, first_free_time_col = return_times(entry)
Packit 345191
                if operation == 'Allocation':
Packit 345191
                    draw_bar(ax, show_first_operation, size_col, threads_col, alloc_time_col, first_alloc_time_col, draw_color)
Packit 345191
                elif operation == 'Free':
Packit 345191
                    draw_bar(ax, show_first_operation, size_col, threads_col, free_time_col, first_free_time_col, draw_color)
Packit 345191
                elif operation == 'Total':
Packit 345191
                    draw_bar(ax, show_first_operation, size_col, threads_col, total_time_col, first_alloc_time_col+first_free_time_col, draw_color)
Packit 345191
                legend_data.append(plt.Rectangle((0, 0), 1, 1, fc=draw_color))
Packit 345191
            if show_first_operation is True:
Packit 345191
                legend_data.append(plt.Rectangle((0, 0), 1, 1, fc=first_operation_color))
Packit 345191
            ax.legend(legend_data,legend,loc='best')
Packit 345191
            plt.grid()
Packit 345191
            save_plot(show_first_operation, None, "%s_time_of_%s_sizes_%s_iterations.png" % (operation, size_display, iterations))
Packit 345191
Packit 345191
################################################
Packit 345191
# Draw 2D plots (time, sizes, constant thread) #
Packit 345191
################################################
Packit 345191
Packit 345191
bar_width, offsets = set_bar_width_and_offsets(bar_width_2D)
Packit 345191
Packit 345191
# for each size range (small, medium, big)
Packit 345191
for size_values, size_index, size_display in zip(sizes_values, sizes_index, sizes_display):
Packit 345191
    # show plots with and without first operation
Packit 345191
    for show_first_operation in (True, False):
Packit 345191
        for thread in threads_values:
Packit 345191
            # for each operation (allocation, free, total)
Packit 345191
            for operation in operations:
Packit 345191
                # add bar_width to each element of size_index
Packit 345191
                ax = init_axis(fig, "%s time of %s sizes with %s threads (%s operations)" % (operation, size_display, thread, iterations), None,
Packit 345191
                               'size [kB]', size_index + (bar_width,) * len(size_index), size_values,
Packit 345191
                               'time [ms]', None, None,
Packit 345191
                               None)
Packit 345191
                legend_data = []
Packit 345191
                # for each allocator (hbw, glibc, tbb, pmem)
Packit 345191
                for entry, offset, draw_color in zip(data, offsets, colors):
Packit 345191
                    # remove all rows where column 1 (size) is not in size_values (current size range)
Packit 345191
                    entry = entry[np.in1d(entry[:,1], np.array(size_values).astype(np.int))]
Packit 345191
                    # remove all rows where column 0 (threads) is not equal to currently analyzed thread value
Packit 345191
                    entry = entry[entry[:,0] == int(thread)]
Packit 345191
                    # convert column 0 (threads values) to thread index
Packit 345191
                    threads_col = np.array([threads_values.index(str(n)) for n in map(int, entry[:,0])])
Packit 345191
                    # convert column 1 (size values) to size index
Packit 345191
                    size_col = [size_values.index(str(n)) for n in map(int, entry[:,1])]
Packit 345191
                    # add offset to size index so that bars display near each other
Packit 345191
                    size_col = np.array(size_col) + offset
Packit 345191
                    total_time_col, alloc_time_col, free_time_col, first_alloc_time_col, first_free_time_col = return_times(entry)
Packit 345191
                    if operation == 'Allocation':
Packit 345191
                        draw_bar(ax, show_first_operation, size_col, None, alloc_time_col, first_alloc_time_col, draw_color)
Packit 345191
                    elif operation == 'Free':
Packit 345191
                        draw_bar(ax, show_first_operation, size_col, None, free_time_col, first_free_time_col, draw_color)
Packit 345191
                    elif operation == 'Total':
Packit 345191
                        draw_bar(ax, show_first_operation, size_col, None, total_time_col, first_alloc_time_col+first_free_time_col, draw_color)
Packit 345191
                    legend_data.append(plt.Rectangle((0, 0), 1, 1, fc=draw_color))
Packit 345191
                if show_first_operation is True:
Packit 345191
                    legend_data.append(plt.Rectangle((0, 0), 1, 1, fc=first_operation_color))
Packit 345191
                ax.legend(legend_data,legend,loc='best')
Packit 345191
                plt.grid()
Packit 345191
                save_plot(show_first_operation, "constant_thread", "%s_time_of_%s_sizes_with_%s_threads_%s_iterations.png" % (operation, size_display, thread, iterations))
Packit 345191
Packit 345191
################################################
Packit 345191
# Draw 2D plots (time, threads, constant size) #
Packit 345191
################################################
Packit 345191
Packit 345191
# for each size range (small, medium, big)
Packit 345191
for size_values, size_index, size_display in zip(sizes_values, sizes_index, sizes_display):
Packit 345191
    # show plots with and without first operation
Packit 345191
    for show_first_operation in (True, False):
Packit 345191
        for size in size_values:
Packit 345191
            # for each operation (allocation, free, total)
Packit 345191
            for operation in operations:
Packit 345191
                # add bar_width to each element of threads_index
Packit 345191
                ax = init_axis(fig, "%s time of %s kB (%s operations)" % (operation, size, iterations), None,
Packit 345191
                               'threads', threads_index + (bar_width,) * len(threads_index), threads_values,
Packit 345191
                               'time [ms]', None, None,
Packit 345191
                               None)
Packit 345191
                legend_data = []
Packit 345191
                # for each allocator (hbw, glibc, tbb, pmem)
Packit 345191
                for entry, offset, draw_color in zip(data, offsets, colors):
Packit 345191
                    # remove all rows where column 1 (size) is not in size_values (current size range)
Packit 345191
                    entry = entry[np.in1d(entry[:,1], np.array(size_values).astype(np.int))]
Packit 345191
                    # remove all rows where column 1 (size) is not equal to currently analyzed size value
Packit 345191
                    entry = entry[entry[:,1] == int(size)]
Packit 345191
                    # convert column 0 (threads values) to thread index
Packit 345191
                    threads_col = np.array([threads_values.index(str(n)) for n in map(int, entry[:,0])])
Packit 345191
                    # add offset to thread index so that bars display near each other
Packit 345191
                    threads_col = np.array(threads_col) + offset
Packit 345191
                    # convert column 1 (size values) to size index
Packit 345191
                    size_col = [size_values.index(str(n)) for n in map(int, entry[:,1])]
Packit 345191
                    total_time_col, alloc_time_col, free_time_col, first_alloc_time_col, first_free_time_col = return_times(entry)
Packit 345191
                    if operation == 'Allocation':
Packit 345191
                        draw_bar(ax, show_first_operation, threads_col, None, alloc_time_col, first_alloc_time_col, draw_color)
Packit 345191
                    elif operation == 'Free':
Packit 345191
                        draw_bar(ax, show_first_operation, threads_col, None, free_time_col, first_free_time_col, draw_color)
Packit 345191
                    elif operation == 'Total':
Packit 345191
                        draw_bar(ax, show_first_operation, threads_col, None, total_time_col, first_alloc_time_col+first_free_time_col, draw_color)
Packit 345191
                    legend_data.append(plt.Rectangle((0, 0), 1, 1, fc=draw_color))
Packit 345191
                if show_first_operation is True:
Packit 345191
                    legend_data.append(plt.Rectangle((0, 0), 1, 1, fc=first_operation_color))
Packit 345191
                ax.legend(legend_data,legend,loc='best')
Packit 345191
                plt.grid()
Packit 345191
                save_plot(show_first_operation, "constant_size", "%s_time_of_%s_kB_%s_operations.png" % (operation, size, iterations))