Beispiel #1
0
def roofline(name, project, scale, precision):
    pd.options.display.max_rows = 20

    project = advisor.open_project(str(project))
    data = project.load(advisor.SURVEY)
    rows = [{col: row[col] for col in row} for row in data.bottomup]
    roofs = data.get_roofs()

    df = pd.DataFrame(rows).replace('', np.nan)

    df.self_ai = df.self_ai.astype(float)
    df.self_gflops = df.self_gflops.astype(float)

    fig, ax = plt.subplots()
    key = lambda roof: roof.bandwidth if 'bandwidth' not in roof.name.lower() else 0
    max_compute_roof = max(roofs, key=key)
    max_compute_bandwidth = max_compute_roof.bandwidth / math.pow(10, 9)  # as GByte/s
    max_compute_bandwidth /= scale  # scale down as requested by the user

    key = lambda roof: roof.bandwidth if 'bandwidth' in roof.name.lower() else 0
    max_memory_roof = max(roofs, key=key)
    max_memory_bandwidth = max_memory_roof.bandwidth / math.pow(10, 9)  # as GByte/s
    max_memory_bandwidth /= scale  # scale down as requested by the user

    # Parameters to center the chart
    ai_min = 2**-5
    ai_max = 2**5
    gflops_min = 2**0
    width = ai_max

    for roof in roofs:
        # by default drawing multi-threaded roofs only
        if 'single-thread' not in roof.name:
            # memory roofs
            if 'bandwidth' in roof.name.lower():
                bandwidth = roof.bandwidth / math.pow(10, 9)  # as GByte/s
                bandwidth /= scale  # scale down as requested by the user
                # y = banwidth * x
                x1, x2 = 0, min(width, max_compute_bandwidth / bandwidth)
                y1, y2 = 0, x2 * bandwidth
                label = '{} {:.0f} GB/s'.format(roof.name, bandwidth)
                ax.plot([x1, x2], [y1, y2], '-', label=label)

            # compute roofs
            elif precision == 'all' or precision in roof.name:
                bandwidth = roof.bandwidth / math.pow(10, 9)  # as GFlOPS
                bandwidth /= scale  # scale down as requested by the user
                x1, x2 = max(bandwidth / max_memory_bandwidth, 0), width
                y1, y2 = bandwidth, bandwidth
                label = '{} {:.0f} GFLOPS'.format(roof.name, bandwidth)
                ax.plot([x1, x2], [y1, y2], '-', label=label)

    # drawing points using the same ax
    ax.set_xscale('log', basex=2)
    ax.xaxis.set_major_formatter(ScalarFormatter())
    ax.set_yscale('log', basey=2)
    ax.yaxis.set_major_formatter(ScalarFormatter())
    ax.plot(df.self_ai, df.self_gflops, 'o', color='black')

    # make sure axes start at 1
    ax.set_ylim(ymin=gflops_min)
    ax.set_xlim(xmin=ai_min, xmax=ai_max)

    ax.set_xlabel('Arithmetic intensity (FLOP/Byte)')
    ax.set_ylabel('Performance (GFLOPS)')

    plt.legend(loc='lower right', fancybox=True, prop={'size': 7})

    # saving the chart in PDF format
    plt.savefig('%s.pdf' % name)
Beispiel #2
0
def roofline(name, project, scale, precision, mode, th):
    pd.options.display.max_rows = 20

    log('Opening project...')
    project = advisor.open_project(str(project))

    if not project:
        err('Could not open project %s.' % project)
    log('Loading data...')

    data = project.load(advisor.SURVEY)
    rows = [{col: row[col] for col in row} for row in data.bottomup]
    roofs = data.get_roofs()

    full_df = pd.DataFrame(rows).replace('', np.nan)

    # Narrow down the columns to those of interest
    df = full_df[analysis_columns].copy()

    df.self_ai = df.self_ai.astype(float)
    df.self_gflops = df.self_gflops.astype(float)
    df.self_time = df.self_time.astype(float)

    # Add time weight column
    loop_total_time = df.self_time.sum()
    df['percent_weight'] = df.self_time / loop_total_time * 100

    fig, ax = plt.subplots()
    key = lambda roof: roof.bandwidth if 'bandwidth' not in roof.name.lower(
    ) else 0
    max_compute_roof = max(roofs, key=key)
    max_compute_bandwidth = max_compute_roof.bandwidth / math.pow(
        10, 9)  # as GByte/s
    max_compute_bandwidth /= scale  # scale down as requested by the user

    key = lambda roof: roof.bandwidth if 'bandwidth' in roof.name.lower(
    ) else 0
    max_memory_roof = max(roofs, key=key)
    max_memory_bandwidth = max_memory_roof.bandwidth / math.pow(
        10, 9)  # as GByte/s
    max_memory_bandwidth /= scale  # scale down as requested by the user

    # Parameters to center the chart
    ai_min = 2**-5
    ai_max = 2**5
    gflops_min = 2**0
    width = ai_max

    for roof in roofs:
        # by default drawing multi-threaded roofs only
        if 'single-thread' not in roof.name:
            # memory roofs
            if 'bandwidth' in roof.name.lower():
                bandwidth = roof.bandwidth / math.pow(10, 9)  # as GByte/s
                bandwidth /= scale  # scale down as requested by the user
                # y = bandwidth * x
                x1, x2 = 0, min(width, max_compute_bandwidth / bandwidth)
                y1, y2 = 0, x2 * bandwidth
                label = '{} {:.0f} GB/s'.format(roof.name, bandwidth)
                ax.plot([x1, x2], [y1, y2], '-', label=label)

            # compute roofs
            elif precision == 'all' or precision in roof.name:
                bandwidth = roof.bandwidth / math.pow(10, 9)  # as GFlOPS
                bandwidth /= scale  # scale down as requested by the user
                x1, x2 = max(bandwidth / max_memory_bandwidth, 0), width
                y1, y2 = bandwidth, bandwidth
                label = '{} {:.0f} GFLOPS'.format(roof.name, bandwidth)
                ax.plot([x1, x2], [y1, y2], '-', label=label)

    # drawing points using the same ax
    ax.set_xscale('log', base=2)
    ax.xaxis.set_major_formatter(ScalarFormatter())
    ax.set_yscale('log', base=2)
    ax.yaxis.set_major_formatter(ScalarFormatter())

    if mode == 'overview':
        # Only display the overall GFLOPS and arithmetic intensity of the program
        ax.plot(data.metrics.total_ai,
                data.metrics.total_gflops,
                'o',
                color='black')
    elif mode == 'top-loops':
        # Display the most costly loop followed by loops with same order of magnitude
        max_self_time = df.self_time.max()
        top_df = df[(max_self_time / df.self_time < 10)
                    & (max_self_time / df.self_time >= 1) &
                    (df.percent_weight >= th)]
        for _, row in top_df.iterrows():
            ax.plot(row.self_ai, row.self_gflops, 'o', color='black')
            label_x = row.self_ai + (row.self_ai + ai_max -
                                     2 * ai_min) * (2**0.005 - 1)
            label_y = row.self_gflops
            ax.text(label_x,
                    label_y,
                    'Time: %.2fs\n'
                    'Incidence: %.0f%%' % (row.self_time, row.percent_weight),
                    bbox={
                        'boxstyle': 'round',
                        'facecolor': 'white'
                    },
                    fontsize=8)

    # make sure axes start at 1
    ax.set_ylim(ymin=gflops_min)
    ax.set_xlim(xmin=ai_min, xmax=ai_max)

    ax.set_xlabel('Arithmetic intensity (FLOP/Byte)')
    ax.set_ylabel('Performance (GFLOPS)')

    legend = plt.legend(loc='center left',
                        bbox_to_anchor=(1, 0.5),
                        prop={'size': 7},
                        title='Rooflines')

    # saving the chart in PNG format
    plt.savefig('%s.png' % name,
                bbox_extra_artists=(legend, ),
                bbox_inches='tight')

    log('Figure saved as %s.png.' % name)
    print(
        'Import error: Python could not load advisor python library. Possible reasons:\n'
        '1. Python cannot resolve path to Advisor\'s pythonapi directory. '
        'To fix, either manually add path to the pythonapi directory into PYTHONPATH environment variable,'
        ' or use advixe-vars.* scripts to set up product environment variables automatically.\n'
        '2. Incompatible runtime versions used by advisor python library and other packages '
        '(such as matplotlib or pandas). To fix, either try to change import order or update other package '
        'version if possible.')
    sys.exit(1)

if len(sys.argv) < 2:
    print(
        'Usage: "python {} path_to_project_dir <num_cores>"'.format(__file__))
    sys.exit(2)

project = advisor.open_project(sys.argv[1])
data = project.load(advisor.SURVEY)
#take elapsed time from the topdown stack
tot_elapsed_time = float(next(data.topdown).total_elapsed_time)
print(tot_elapsed_time)

rows = [{col: row[col] for col in row} for row in data.bottomup]

#set number of cores (or number of threads)
num_cores = 1

if len(sys.argv) == 3:
    num_cores = int(sys.argv[2])

if num_cores == 1:
    roofs = data.get_roofs(1, advisor.RoofsStrategy.SINGLE_THREAD)
Beispiel #4
0
def advisor_to_json(name, project, scale, precision, mode, th):
    pd.options.display.max_rows = 20

    log('Opening project...')
    project = advisor.open_project(str(project))

    if not project:
        err('Could not open project %s.' % project)
    log('Loading data...')

    data = project.load(advisor.SURVEY)
    rows = [{col: row[col] for col in row} for row in data.bottomup]
    roofs = data.get_roofs()

    full_df = pd.DataFrame(rows).replace('', np.nan)

    # Narrow down the columns to those of interest
    df = full_df[analysis_columns].copy()

    df.self_ai = df.self_ai.astype(float)
    df.self_gflops = df.self_gflops.astype(float)
    df.self_time = df.self_time.astype(float)

    # Add time weight column
    loop_total_time = df.self_time.sum()
    df['percent_weight'] = df.self_time / loop_total_time * 100

    key = lambda roof: roof.bandwidth if 'bandwidth' not in roof.name.lower(
    ) else 0
    max_compute_roof = max(roofs, key=key)
    max_compute_bandwidth = max_compute_roof.bandwidth / math.pow(
        10, 9)  # as GByte/s
    max_compute_bandwidth /= scale  # scale down as requested by the user

    key = lambda roof: roof.bandwidth if 'bandwidth' in roof.name.lower(
    ) else 0
    max_memory_roof = max(roofs, key=key)
    max_memory_bandwidth = max_memory_roof.bandwidth / math.pow(
        10, 9)  # as GByte/s
    max_memory_bandwidth /= scale  # scale down as requested by the user

    # Parameters
    ai_max = 2**5
    width = ai_max

    # Declare the dictionary that will hold the JSON information
    roofline_data = {}

    # Declare the two types of rooflines dictionaries
    memory_roofs = []
    compute_roofs = []
    for roof in roofs:
        # by default drawing multi-threaded roofs only
        if 'single-thread' not in roof.name:
            # memory roofs
            if 'bandwidth' in roof.name.lower():
                bandwidth = roof.bandwidth / math.pow(10, 9)  # as GByte/s
                bandwidth /= scale  # scale down as requested by the user
                # y = bandwidth * x
                x1, x2 = 0, min(width, max_compute_bandwidth / bandwidth)
                y1, y2 = 0, x2 * bandwidth
                memory_roofs.append(((x1, x2), (y1, y2)))

            # compute roofs
            elif precision == 'all' or precision in roof.name:
                bandwidth = roof.bandwidth / math.pow(10, 9)  # as GFlOPS
                bandwidth /= scale  # scale down as requested by the user
                x1, x2 = max(bandwidth / max_memory_bandwidth, 0), width
                y1, y2 = bandwidth, bandwidth
                compute_roofs.append(((x1, x2), (y1, y2)))

    roofs = {'memory': memory_roofs, 'compute': compute_roofs}
    roofline_data['roofs'] = roofs

    if mode == 'overview' or mode == 'all':
        # Save the single point as the total ai and total gflops metric
        roofline_data['overview'] = {
            'total_ai': data.metrics.total_ai,
            'total_gflops': data.metrics.total_gflops
        }

    if mode == 'top-loops' or mode == 'all':
        # Save the most costly loop followed by loops with same order of magnitude
        max_self_time = df.self_time.max()
        top_df = df[(max_self_time / df.self_time < 10)
                    & (max_self_time / df.self_time >= 1) &
                    (df.percent_weight >= th)]
        top_loops_data = [{
            'ai': row.self_ai,
            'gflops': row.self_gflops,
            'time': row.self_time,
            'incidence': row.percent_weight
        } for _, row in top_df.iterrows()]
        roofline_data['top-loops'] = top_loops_data

    # Save the JSON file
    with open('%s.json' % name, 'w') as f:
        f.write(json.dumps(roofline_data))

    log('Figure saved as %s.json.' % name)
Beispiel #5
0
def roofline(name, project, scale, precision, mode, th):
    pd.options.display.max_rows = 20

    log('Opening project...')
    project = advisor.open_project(str(project))

    if not project:
        err('Could not open project %s.' % project)
    log('Loading data...')

    data = project.load(advisor.SURVEY)
    rows = [{col: row[col] for col in row} for row in data.bottomup]
    roofs = data.get_roofs()

    full_df = pd.DataFrame(rows).replace('', np.nan)

    # Narrow down the columns to those of interest
    try:
        df = full_df[analysis_columns].copy()
    except KeyError:
        err('Could not read data columns from profiling. Not enough data has been '
            'generated for the specified problem. Try rerunning with a bigger problem'
            )

    df.self_ai = df.self_ai.astype(float)
    df.self_gflops = df.self_gflops.astype(float)
    df.self_time = df.self_time.astype(float)

    # Add time weight column
    loop_total_time = df.self_time.sum()
    df['percent_weight'] = df.self_time / loop_total_time * 100

    fig, ax = plt.subplots()
    key = lambda roof: roof.bandwidth if 'bandwidth' not in roof.name.lower(
    ) else 0
    max_compute_roof = max(roofs, key=key)
    max_compute_bandwidth = max_compute_roof.bandwidth / math.pow(
        10, 9)  # as GByte/s
    max_compute_bandwidth /= scale  # scale down as requested by the user

    key = lambda roof: roof.bandwidth if 'bandwidth' in roof.name.lower(
    ) else 0
    max_memory_roof = max(roofs, key=key)
    max_memory_bandwidth = max_memory_roof.bandwidth / math.pow(
        10, 9)  # as GByte/s
    max_memory_bandwidth /= scale  # scale down as requested by the user

    # Parameters to center the chart
    ai_min = 2**-5
    ai_max = 2**5
    gflops_min = 2**0
    width = ai_max

    # Declare the dictionary that will hold the JSON information
    roofline_data = {}

    # Declare the two types of rooflines dictionaries
    memory_roofs = []
    compute_roofs = []

    for roof in roofs:
        # by default drawing multi-threaded roofs only
        if 'single-thread' not in roof.name:
            # memory roofs
            if 'bandwidth' in roof.name.lower():
                bandwidth = roof.bandwidth / math.pow(10, 9)  # as GByte/s
                bandwidth /= scale  # scale down as requested by the user
                # y = bandwidth * x
                x1, x2 = 0, min(width, max_compute_bandwidth / bandwidth)
                y1, y2 = 0, x2 * bandwidth
                label = '{} {:.0f} GB/s'.format(roof.name, bandwidth)
                ax.plot([x1, x2], [y1, y2], '-', label=label)
                memory_roofs.append(((x1, x2), (y1, y2)))

            # compute roofs
            elif precision == 'all' or precision in roof.name:
                bandwidth = roof.bandwidth / math.pow(10, 9)  # as GFlOPS
                bandwidth /= scale  # scale down as requested by the user
                x1, x2 = max(bandwidth / max_memory_bandwidth, 0), width
                y1, y2 = bandwidth, bandwidth
                label = '{} {:.0f} GFLOPS'.format(roof.name, bandwidth)
                ax.plot([x1, x2], [y1, y2], '-', label=label)
                compute_roofs.append(((x1, x2), (y1, y2)))

    roofs = {'memory': memory_roofs, 'compute': compute_roofs}
    roofline_data['roofs'] = roofs

    if mode == 'overview' or mode == 'all':
        # Save the single point as the total ai and total gflops metric
        roofline_data['overview'] = {
            'total_ai': data.metrics.total_ai,
            'total_gflops': data.metrics.total_gflops
        }

    # drawing points using the same ax
    ax.set_xscale('log', base=2)
    ax.xaxis.set_major_formatter(ScalarFormatter())
    ax.set_yscale('log', base=2)
    ax.yaxis.set_major_formatter(ScalarFormatter())

    if mode == 'overview':
        # Only display the overall GFLOPS and arithmetic intensity of the program
        ax.plot(data.metrics.total_ai,
                data.metrics.total_gflops,
                'o',
                color='black')
    elif mode == 'top-loops':
        # Display/save the most costly loop followed by loops with same order of magnitude
        max_self_time = df.self_time.max()
        top_df = df[(max_self_time / df.self_time < 10)
                    & (max_self_time / df.self_time >= 1) &
                    (df.percent_weight >= th)]
        for _, row in top_df.iterrows():
            ax.plot(row.self_ai, row.self_gflops, 'o', color='black')
            label_x = row.self_ai + (row.self_ai + ai_max -
                                     2 * ai_min) * (2**0.005 - 1)
            label_y = row.self_gflops
            ax.text(label_x,
                    label_y,
                    'Time: %.2fs\n'
                    'Incidence: %.0f%%' % (row.self_time, row.percent_weight),
                    bbox={
                        'boxstyle': 'round',
                        'facecolor': 'white'
                    },
                    fontsize=8)
        top_loops_data = [{
            'ai': row.self_ai,
            'gflops': row.self_gflops,
            'time': row.self_time,
            'incidence': row.percent_weight
        } for _, row in top_df.iterrows()]
        roofline_data['top-loops'] = top_loops_data
    elif mode == 'all':  # JSON dumping only
        max_self_time = df.self_time.max()
        top_df = df[(max_self_time / df.self_time < 10)
                    & (max_self_time / df.self_time >= 1) &
                    (df.percent_weight >= th)]
        top_loops_data = [{
            'ai': row.self_ai,
            'gflops': row.self_gflops,
            'time': row.self_time,
            'incidence': row.percent_weight
        } for _, row in top_df.iterrows()]
        roofline_data['top-loops'] = top_loops_data

    # make sure axes start at 1
    ax.set_ylim(ymin=gflops_min)
    ax.set_xlim(xmin=ai_min, xmax=ai_max)

    ax.set_xlabel('Arithmetic intensity (FLOP/Byte)')
    ax.set_ylabel('Performance (GFLOPS)')

    legend = plt.legend(loc='center left',
                        bbox_to_anchor=(1, 0.5),
                        prop={'size': 7},
                        title='Rooflines')

    # saving the chart in PNG format
    plt.savefig('%s.png' % name,
                bbox_extra_artists=(legend, ),
                bbox_inches='tight')
    figpath = os.path.realpath(__file__).split(os.path.basename(__file__))[0]
    log('Figure saved in %s%s.png.' % (figpath, name))

    # Save the JSON file
    with open('%s.json' % name, 'w') as f:
        f.write(json.dumps(roofline_data))

    log('JSON file saved as %s.json.' % name)
                    help="project-dir name")
args = parser.parse_args()

variables = [
    "self_ai",
    "self_gflops",
    "self_gflop",
    "self_time",
    "self_dram_gb",
    "self_dram_loaded_gb",
    "self_dram_stored_gb",
    "self_memory_gb",
    "self_loaded_gb",
    "self_stored_gb",
    "self_l2_gb",
    "self_l3_gb",
    "loop_name",
]

project = advisor.open_project(args.project_dir)
data = project.load(advisor.SURVEY)
rows = [{col: row[col] for col in row} for row in data.bottomup]
df = pd.DataFrame(rows).replace("", np.nan)

for var in variables:
    if "loop_name" not in var:
        df[var] = df[var].astype(float)

print(df[variables].dropna().sort_values(by=["self_dram_gb"],
                                         ascending=False).head(5))