def construct_short_name_for_file(filename, affinity_dir):
    try:
        my_tokens = SFP.parseYAMLFileName(filename)

        # parse affinity information, because it contains timestamps
        try:
            parse_affinity_data(affinity_path=affinity_dir, tokens=my_tokens)

            short_name = str(my_tokens['num_nodes']) + 'x' + \
                         str(my_tokens['procs_per_node']) + 'x' + \
                         str(my_tokens['cores_per_proc']) + 'x' + \
                         str(my_tokens['threads_per_core'])

            short_name += '_' + pd.to_datetime(
                my_tokens['timestamp']).strftime('%b-%Y')
        except:
            short_name = 'A'

        return short_name
    except:
        pass

    # attempt try using the filenames
    try:
        short_name = os.path.basename(filename).split('_')[0]
        return short_name
    except:
        return 'A'
def parse_affinity_data(affinity_path, tokens):
    affinity_filename = '{path}/{name}'.format(
        path=affinity_path, name=SFP.build_affinity_filename(my_tokens))

    my_file_lookup = Path(affinity_filename)
    try:
        affinity_file_abs = my_file_lookup.resolve()
    except:
        print('Missing Affinity File: {}'.format(affinity_filename))
        return

    #if ~my_file.is_file():
    #  print('Missing Affinity File: {}'.format(affinity_filename))
    #  print(my_file.stat())
    #  return
    file_lines = file_len(affinity_file_abs)

    # 0,64,64,0,"nid02623","5-11-2017 21:02:30.900965",0,0|68|136|204
    expected_lines = tokens['num_nodes'] \
                   * tokens['procs_per_node'] \
                   * tokens['cores_per_proc'] \
                   * tokens['threads_per_core'] \
                   + 1
    if expected_lines != file_lines:
        import re

        print('{fname}: has {num} lines, expected {exp}'.format(
            fname=affinity_filename, num=file_lines, exp=expected_lines))
        #line_re = r'\d+,\d+,\d+,\d+,"\w+","[0-9- :.]+",\d+,\d+|\d+|\d+|\d\d\d'
        hostnames = 'unknown'
        timestamp = 'unknown'

    else:
        # use pandas to read the CSV
        df = pd.read_csv(affinity_file_abs,
                         parse_dates=True,
                         skipinitialspace=True,
                         low_memory=False)

        hostnames = ','.join(df['hostname'].unique())
        timestamp = df['Timestamp'].max()

    tokens['nodes'] = hostnames
    tokens['timestamp'] = timestamp
Ejemplo n.º 3
0
def parse_teuchos_timers_from_log_file(YAML_filename, relative_log_dir):
    import os

    # parse the YAML filename
    my_tokens = SFP.parseYAMLFileName(YAML_filename)

    # weakscaling_openmp_Laplace3D-246x246x246_decomp-1x64x1x1_knl-quad-cache-onyx.log-ok
    logfile_fmt_str = 'weakscaling_{lexecspace_name}_' \
                      '{problem_type}-{problem_nx}x{problem_ny}x{problem_nz}_' \
                      'decomp-{num_nodes}x{procs_per_node}x{cores_per_proc}x{threads_per_core}_' \
                      '*.log-ok'
    # construct the log file's name
    logfile_name = logfile_fmt_str.format(**my_tokens)

    # form an absolute path
    log_dir = os.path.dirname(
        os.path.realpath(YAML_filename)) + '/' + relative_log_dir
    print('log_dir: ', os.path.dirname(os.path.realpath(YAML_filename)),
          'relative: ', relative_log_dir)
    logfile_path = log_dir + '/' + logfile_name
    print(logfile_path)
    # glob the variable parts of the log name
    logfiles = glob.glob(logfile_path)
    print(logfiles)
    # we should find a single logfile
    if len(logfiles) != 1:
        print(
            'Searched for logfiles, but found more than one. Move the similar log file away.'
        )
        print('log files found: ', len(logfiles))
        for log in logfiles:
            print(log)
        exit(-1)

    # parse the timer names from the log file
    return gather_timer_name_sets_from_logfile(logfiles[0])
Ejemplo n.º 4
0
def load_dataset(dataset_name):
    print('Reading {}'.format(dataset_name))
    # write the total dataset out, index=False, because we do not drop it above
    dataset = pd.read_csv(dataset_name, low_memory=False)

    print('Read csv complete')

    integral_columns = SFP.getIndexColumns(execspace_name='OpenMP')
    non_integral_names = [
        'Timer Name', 'problem_type', 'solver_name', 'solver_attributes',
        'prec_name', 'prec_attributes', 'execspace_name',
        'execspace_attributes'
    ]

    # set the index, verify it, and sort
    dataset.set_index(keys=SFP.getIndexColumns(execspace_name='OpenMP'),
                      drop=False,
                      inplace=True,
                      verify_integrity=True)
    print('Verified index')

    # optionally restrict the data processed
    # Elasticity data is incomplete.
    restriction_query = '(problem_type != \"Elasticity3D\") & ' \
                        '(num_nodes >= {min_num_nodes}) & ' \
                        '(num_nodes <= {max_num_nodes}) & ' \
                        '(prec_attributes != \"-no-repartition\")' \
                        ''.format(min_num_nodes=MIN_NUM_NODES,
                                  max_num_nodes=MAX_NUM_NODES)

    dataset = dataset.query(restriction_query)
    print('Restricted dataset')

    dataset.fillna(value='None', inplace=True)

    # sort
    # dataset.sort_values(inplace=True,
    #                     by=SFP.getIndexColumns(execspace_name='OpenMP'))
    dataset.sort_index(inplace=True)
    print('Sorted')

    # remove the timers the driver adds
    driver_dataset = dataset[dataset['Timer Name'].isin([
        '0 - Total Time', '1 - Reseting Linear System',
        '2 - Adjusting Nullspace for BlockSize',
        '3 - Constructing Preconditioner', '4 - Constructing Solver',
        '5 - Solve'
    ])]
    print('Gathered driver timers')

    # remove the timers the driver adds
    dataset = dataset[~dataset['Timer Name'].isin([
        '0 - Total Time', '1 - Reseting Linear System',
        '2 - Adjusting Nullspace for BlockSize',
        '3 - Constructing Preconditioner', '4 - Constructing Solver',
        '5 - Solve'
    ])]
    print('Removed driver timers')

    # reindex
    # set the index, verify it, and sort
    dataset.set_index(keys=SFP.getIndexColumns(execspace_name='OpenMP'),
                      drop=False,
                      inplace=True,
                      verify_integrity=True)
    driver_dataset.set_index(keys=SFP.getIndexColumns(execspace_name='OpenMP'),
                             drop=False,
                             inplace=True,
                             verify_integrity=True)
    print('Rebuilt truncated index')

    return dataset, driver_dataset
Ejemplo n.º 5
0
    # enforce all plots use the same num_nodes. E.g., the axes will be consistent
    my_nodes = np.array(list(map(int, dataset['num_nodes'].unique())))
    my_num_nodes = dataset['num_nodes'].nunique()
    #
    my_ticks = np.arange(start=1, stop=my_num_nodes + 1, step=1, dtype=int)
    max_num_nodes = np.max(my_nodes)

    expected_data_points = my_num_nodes
    print(my_nodes)

    # groups = dataset.groupby(['Experiment', 'problem_type', 'Timer Name', 'procs_per_node', 'cores_per_proc'])
    # timer_name_index = 2
    # there is a bug in Pandas. GroupBy cannot handle groupby keys that are none or nan.
    # For now, use Experiment, because it encapsulates the possible 'nan' keys

    omp_groupby_columns = SFP.getMasterGroupBy(execspace_name='OpenMP',
                                               scaling_type='strong')
    print(omp_groupby_columns)
    timer_name_index = omp_groupby_columns.index('Timer Name')
    groups = dataset.groupby(omp_groupby_columns)

    spmv_group_by = SFP.getMasterGroupBy(execspace_name='OpenMP',
                                         scaling_type='strong')
    # uncomment these, and you will get the fastest SpMV over all decomps
    # spmv_group_by.remove('procs_per_node')
    # spmv_group_by.remove('cores_per_proc')
    spmv_group_by.remove('solver_name')
    spmv_group_by.remove('solver_attributes')
    spmv_group_by.remove('prec_name')
    spmv_group_by.remove('prec_attributes')

    # mini index
def main():
    # Process input
    options = docopt(__doc__)

    comparable_files = options['--comparable']
    baseline_file = options['--baseline']
    bl_affinity_dir = options['--bl_affinity_dir']
    comparable_affinity_dir = options['--comparable_affinity_dir']
    output_csv = options['--output_csv']
    remove_string = options['--remove_string']
    averaging = options['--average']
    write_percent_total = options['--write_percent_total']
    total_time_key = options['--total_time_key']
    total_time_key = ''

    DO_PERCENT_TOTAL = write_percent_total
    NUKE_SPARC_NUMBERS = True

    if remove_string == '':
        remove_string = None

    if total_time_key == '':
        total_time_key = None
        DO_PERCENT_TOTAL = False

    ignored_labels = [
        '0 - Total Time', '1 - Reseting Linear System',
        '2 - Adjusting Nullspace for BlockSize',
        '3 - Constructing Preconditioner', '4 - Constructing Solver',
        '5 - Solve'
    ]

    print(options)

    # we allow globs on the file names, but it should return a single file
    if '*' in baseline_file:
        baseline_files = glob.glob(baseline_file)
        if len(baseline_files) != 1:
            print(
                'Error locating a baseline file. Globbed the filename, but obtained multiple files.'
            )
            print(baseline_file)
            print(baseline_files)
        baseline_file = baseline_files[0]

    print('baseline_file: {baseline}\n'
          'comparable_files: {comparable}\n'
          'average: {avg}\n'
          'remove_string: {suffix}\n'
          'output_csv: {output}\n'
          'total_time_key: {total_time_key}'.format(
              baseline=baseline_file,
              avg=averaging,
              output=output_csv,
              suffix=remove_string,
              comparable=comparable_files,
              total_time_key=total_time_key))

    if isinstance(comparable_files, str):
        if '*' in comparable_files:
            print('Globbing comparison files')
            comparable_files = glob.glob(comparable_files)
        else:
            comparable_files = [comparable_files]

    print(comparable_files)

    bl_yaml = load_yaml(baseline_file)

    TTU.remove_timer_string(bl_yaml, string=remove_string)

    my_tokens = {}
    try:
        my_tokens = SFP.parseYAMLFileName(baseline_file)
    except:
        pass

    baseline_df = TTU.construct_dataframe(bl_yaml)
    baseline_df = remove_sparc_label_numbers(baseline_df)

    baseline_df.to_csv('baseline_df-a.csv', index_label='Original Timer')
    baseline_df = TTU.demange_muelu_timer_names_df(baseline_df)
    baseline_df.to_csv('baseline_df.csv', index_label='Demangled Timer')

    # remove ignored timers
    baseline_df = baseline_df.drop(ignored_labels, errors='ignore')

    # perform averaging
    do_averaging(averaging=averaging, df=baseline_df, my_tokens=my_tokens)

    # compute the percentage of total time
    if DO_PERCENT_TOTAL:
        add_percent_total(total_time_key=total_time_key, df=baseline_df)

    # track the global set of timer labels
    unified_timer_names = set(baseline_df.index)

    # construct a short name for this data
    comparable_file_mapping = {}

    construct_short_names(comparable_files=comparable_files,
                          comparable_file_mapping=comparable_file_mapping,
                          relative_affinity_dir=comparable_affinity_dir)

    baseline_short_name = construct_short_names(
        comparable_files=baseline_file, relative_affinity_dir=bl_affinity_dir)

    print(comparable_file_mapping)
    for short_name in sorted(comparable_file_mapping.keys()):
        comparable_file = comparable_file_mapping[short_name]

        # we need the tokens, because they contain num_steps, which is
        # an averaging option, since call counts is not appropriate in all cases
        my_tokens = {}
        try:
            my_tokens = SFP.parseYAMLFileName(comparable_file)
            rebuilt_filename = SFP.rebuild_source_filename(my_tokens)

            if rebuilt_filename == os.path.basename(comparable_file):
                print("Rebuild OK: {} == {}".format(rebuilt_filename,
                                                    comparable_file))
            else:
                print("Rebuild FAIL: {} != {}".format(rebuilt_filename,
                                                      comparable_file))
                exit(-1)
        except:
            pass

        # load the YAML data
        comparable_yaml = load_yaml(comparable_file)

        # remove a string from the timer labels (_kokkos)
        TTU.remove_timer_string(comparable_yaml, string=remove_string)

        # construct the dataframe
        comparable_df = TTU.construct_dataframe(comparable_yaml)

        comparable_df.to_csv('comparable_df-a.csv',
                             index_label='Original Timer')
        comparable_df = remove_sparc_label_numbers(comparable_df)
        comparable_df.to_csv('comparable_df.csv',
                             index_label='Demangled Timer')

        # drop the unwanted timers
        comparable_df = comparable_df.drop(ignored_labels, errors='ignore')

        # add new timers to the global set of parsed timers (required, because we do not always have the same
        # set of timers)
        unified_timer_names = unified_timer_names.union(
            set(comparable_df.index))

        # update the dataframe of baseline to use this new index
        baseline_df = baseline_df.reindex(list(unified_timer_names))

        # update the comparable datafrae
        comparable_df = comparable_df.reindex(list(unified_timer_names))

        # apply any averaging to the timers
        do_averaging(averaging=averaging,
                     df=comparable_df,
                     my_tokens=my_tokens)

        # optionally, compute the perct total time
        if DO_PERCENT_TOTAL:
            add_percent_total(total_time_key=total_time_key, df=comparable_df)

        # merge the new timer data into the baseline dataframe using columns "Foo_shortname"
        baseline_df = pd.merge(baseline_df,
                               comparable_df,
                               left_index=True,
                               right_index=True,
                               how='outer',
                               suffixes=('', '_' + short_name))

    baseline_df.to_csv('happy.csv', index=True)
    #baseline_df = baseline_df.dropna(subset=['Timer Name'])
    baseline_df = baseline_df.dropna()
    baseline_df.to_csv('happy-d.csv', index=True)
    timer_types = ['minT', 'maxT', 'meanT', 'meanCT']
    for timer_type in timer_types:
        output_columns = ['Timer Name', timer_type]

        if DO_PERCENT_TOTAL:
            output_columns.append('perc_{timer}'.format(timer=timer_type))

        lookup_column = ''

        for short_name in sorted(comparable_file_mapping.keys()):
            lookup_column = '{timer}_{short_name}'.format(
                timer=timer_type, short_name=short_name)

            speedup_column = '{timer}_speedup_{short_name}'.format(
                timer=timer_type, short_name=short_name)
            baseline_df[speedup_column] = baseline_df[
                timer_type] / baseline_df[lookup_column]

            # round the speedup  ?
            baseline_df[speedup_column] = pd.Series(
                [round(val, 3) for val in baseline_df[speedup_column]],
                index=baseline_df.index)

            output_columns.append(lookup_column)
            output_columns.append(speedup_column)

            if DO_PERCENT_TOTAL:
                output_columns.append('perc_{timer}_{short_name}'.format(
                    timer=timer_type, short_name=short_name))
                print(output_columns)
            if total_time_key is not None:
                output_columns.append('total_time_{timer}_{short_name}'.format(
                    timer=timer_type, short_name=short_name))

        fname = '{timer}_comparison'.format(timer=timer_type)
        if averaging != 'none':
            fname += '_averaged_by_{avg}'.format(avg=averaging)

        # slice this data off and rank/sort
        data_slice = baseline_df[output_columns]

        data_slice.to_csv('{fname}.csv'.format(fname=fname),
                          index=False,
                          columns=output_columns)

        df_to_markdown(data_slice[output_columns])

        # data_slice.to_csv('{fname}.csv'.format(fname=fname),
        #                    index_label='Timer Name',
        #                    index=True,
        #                    columns=output_columns)

    for short_name in sorted(comparable_file_mapping.keys()):
        comparable_file = comparable_file_mapping[short_name]
        print('{short_name}: {file}'.format(short_name=short_name,
                                            file=comparable_file))
Ejemplo n.º 7
0
  if len(input_files) == 1:
    input_files = glob.glob(input_files[0])
    # Impose sorted order (similar to bash "sort -n"
    input_files = sorted(input_files, key=string_split_by_numbers)

  #df_cols = ['Experiment', 'Problem', 'Timer Name', 'num_nodes', 'procs_per_node', 'cores_per_proc', 'threads_per_core',
  #           'Num Threads', 'Max Aggregate Time']
  dataset = pd.DataFrame()
  df_idx = -1
  future_index = ['Experiment', 'Timer Name']

  for input_file in input_files:
    with open(input_file) as data_file:
      yaml_data = yaml.safe_load(data_file)

    my_tokens = SFP.parseYAMLFileName(input_file)
    rebuilt_filename = SFP.rebuild_source_filename(my_tokens)

    if rebuilt_filename == os.path.basename(input_file):
      print("Rebuild OK: {} == {}".format(rebuilt_filename, input_file))
    else:
      print("Rebuild FAILK: {} != {}".format(rebuilt_filename, input_file))
      exit(-1)

    print(my_tokens)

    experiment_id = "{solver_name}{solver_attributes}_{prec_name}{prec_attributes}".format(**my_tokens)

    timer_data = construct_dataframe(yaml_data, list(my_tokens.keys()))

    for key, value in my_tokens.items():
          'output-csv: {output}\n'
          'affinity-dir: {affinity}\n'.format(affinity=affinity_dir,
                                              output=output_csv,
                                              input=input_files))

    SCALING_TYPE = 'weak'

    if isinstance(input_files, str) and '*' in input_files:
        print('Globbing')
        input_files = glob.glob(input_files)
    else:
        input_files = [input_files]

    dataset = pd.DataFrame()
    df_idx = -1
    future_index = SFP.getIndexColumns(execspace_name='OpenMP')

    for input_file in input_files:
        with open(input_file) as data_file:
            yaml_data = yaml.safe_load(data_file)

        my_tokens = SFP.parseYAMLFileName(input_file)
        rebuilt_filename = SFP.rebuild_source_filename(my_tokens)

        if rebuilt_filename == os.path.basename(input_file):
            print("Rebuild OK: {} == {}".format(rebuilt_filename, input_file))
        else:
            print("Rebuild FAIL: {} != {}".format(rebuilt_filename,
                                                  input_file))
            exit(-1)
Ejemplo n.º 9
0
                            'procs_per_node', 'cores_per_proc',
                            'threads_per_core', 'num_nodes', 'cuda_device_name'
                        ])

    groups = dataset.groupby([
        'Experiment', 'problem_type', 'procs_per_node', 'cores_per_proc',
        'threads_per_core', 'Timer Name'
    ])
    for name, group in groups:
        if name[5] in [
                '0 - Total Time', '1 - Reseting Linear System',
                '4 - Constructing Solver', '5 - Solve'
        ]:
            continue

        my_tokens = SFP.getTokensFromDataFrameGroupBy(group)
        simple_fname = SFP.getScalingFilename(my_tokens, weak=True)
        simple_title = SFP.getScalingTitle(my_tokens, weak=True)

        # the number of HT combos we have
        num_cuda_arch = group['cuda_device_name'].nunique()

        fig_size = 5
        ax = []
        sec_ax = []
        fig = plt.figure()
        fig.set_size_inches(fig_size * num_cuda_arch, fig_size * 1.30)

        my_nodes = np.array(list(map(int, group['num_nodes'].unique())))
        max_num_nodes = np.max(my_nodes)
        procs_per_node = int(group['procs_per_node'].max())
Ejemplo n.º 10
0
def main():
    # Process input
    from docopt import DocoptExit
    #  try:
    options = docopt(__doc__)
    #  except DocoptExit:
    #    print(__doc__)
    #    exit(0)

    comparable_files = options['--comparable']
    baseline_file = options['--baseline']
    bl_affinity_dir = options['--bl_affinity_dir']
    #    print(__doc__)
    #    exit(0)

    comparable_files = options['--comparable']
    baseline_file = options['--baseline']
    bl_affinity_dir = options['--bl_affinity_dir']
    comparable_affinity_dir = options['--comparable_affinity_dir']
    bl_log_dir = options['--bl_log_dir']
    comparable_log_dir = options['--comparable_log_dir']
    output_csv = options['--output_csv']
    remove_string = options['--remove_string']
    averaging = options['--average']
    write_percent_total = options['--write_percent_total']
    muelu_prof = options['--muelu_prof']
    total_time_key = options['--total_time_key']
    total_time_key = ''

    DO_MUELU_COMP = muelu_prof
    DO_PERCENT_TOTAL = write_percent_total

    if remove_string == '':
        remove_string = None

    if total_time_key == '':
        total_time_key = None
        DO_PERCENT_TOTAL = False

    ignored_labels = [
        '0 - Total Time', '1 - Reseting Linear System',
        '2 - Adjusting Nullspace for BlockSize',
        '3 - Constructing Preconditioner', '4 - Constructing Solver',
        '5 - Solve'
    ]

    print(options)

    baseline_file = glob.glob(baseline_file)[0]

    print('baseline_file: {baseline}\n'
          'comparable_files: {comparable}\n'
          'average: {avg}\n'
          'remove_string: {suffix}\n'
          'output_csv: {output}\n'
          'total_time_key: {total_time_key}'.format(
              baseline=baseline_file,
              avg=averaging,
              output=output_csv,
              suffix=remove_string,
              comparable=comparable_files,
              total_time_key=total_time_key))

    if isinstance(comparable_files, str) and '*' in comparable_files:
        print('Globbing')
        comparable_files = glob.glob(comparable_files)
    else:
        comparable_files = [comparable_files]

    print(comparable_files)

    sets = parse_teuchos_timers_from_log_file(YAML_filename=baseline_file,
                                              relative_log_dir=bl_log_dir)
    bl_yaml = load_yaml(baseline_file)
    num_missing = reconcile_timer_set_and_YAML(
        timer_list=bl_yaml['Timer names'], sets=sets)

    print('Missing Labels: ', num_missing)

    # print('---------------------------------------------------------------------')
    # import pprint
    # pprint.PrettyPrinter(indent=4).pprint(bl_yaml)
    # print('---------------------------------------------------------------------', )

    remove_timer_string(bl_yaml, string=remove_string)

    my_tokens = SFP.parseYAMLFileName(baseline_file)
    baseline_df = construct_dataframe(bl_yaml)

    baseline_df.to_csv('baseline_df-a.csv', index_label='Original Timer')
    baseline_df = demangeDF_TimerNames(baseline_df)
    baseline_df.to_csv('baseline_df.csv', index_label='Demangled Timer')

    # remove ignored timers
    baseline_df = baseline_df.drop(ignored_labels, errors='ignore')

    # perform averaging
    do_averaging(averaging=averaging, df=baseline_df, my_tokens=my_tokens)

    # compute the percentage of total time
    if DO_PERCENT_TOTAL:
        add_percent_total(total_time_key=total_time_key, df=baseline_df)

    # this will drastically reduce the number of timer labels
    if DO_MUELU_COMP:
        baseline_df = annotate_muelu_dataframe(df=baseline_df,
                                               total_time_key=total_time_key)

    # track the global set of timer labels
    unified_timer_names = set(baseline_df.index)

    # construct a short name for this data
    comparable_file_mapping = {}

    construct_short_names(comparable_files=comparable_files,
                          comparable_file_mapping=comparable_file_mapping,
                          relative_affinity_dir=comparable_affinity_dir)

    baseline_short_name = construct_short_names(
        comparable_files=baseline_file, relative_affinity_dir=bl_affinity_dir)

    for short_name in sorted(comparable_file_mapping.keys()):
        comparable_file = comparable_file_mapping[short_name]

        # we need the tokens, because they contain num_steps, which is
        # an averaging option, since call counts is not appropriate in all cases
        my_tokens = SFP.parseYAMLFileName(comparable_file)
        rebuilt_filename = SFP.rebuild_source_filename(my_tokens)

        if rebuilt_filename == os.path.basename(comparable_file):
            print("Rebuild OK: {} == {}".format(rebuilt_filename,
                                                comparable_file))
        else:
            print("Rebuild FAIL: {} != {}".format(rebuilt_filename,
                                                  comparable_file))
            exit(-1)

        # load the YAML data
        comparable_yaml = load_yaml(comparable_file)

        # remove a string from the timer labels (_kokkos)
        remove_timer_string(comparable_yaml, string=remove_string)

        sets = parse_teuchos_timers_from_log_file(
            YAML_filename=comparable_file, relative_log_dir=comparable_log_dir)
        num_missing = reconcile_timer_set_and_YAML(
            timer_list=comparable_yaml['Timer names'], sets=sets)

        print('Missing Labels: ', num_missing)
        # construct the dataframe
        comparable_df = construct_dataframe(comparable_yaml)

        comparable_df.to_csv('comparable_df-a.csv',
                             index_label='Original Timer')
        comparable_df = demangeDF_TimerNames(comparable_df)
        comparable_df.to_csv('comparable_df.csv',
                             index_label='Demangled Timer')

        # print('---------------------------------------------------------------------')
        # import pprint
        # pprint.PrettyPrinter(indent=4).pprint(comparable_yaml)
        # print('---------------------------------------------------------------------', )

        # drop the unwanted timers
        comparable_df = comparable_df.drop(ignored_labels, errors='ignore')

        if DO_MUELU_COMP:
            comparable_df = annotate_muelu_dataframe(
                df=comparable_df, total_time_key=total_time_key)

        # add new timers to the global set of parsed timers (required, because we do not always have the same
        # set of timers)
        unified_timer_names = unified_timer_names.union(
            set(comparable_df.index))

        # update the dataframe of baseline to use this new index
        baseline_df = baseline_df.reindex(list(unified_timer_names))

        # update the comparable datafrae
        comparable_df = comparable_df.reindex(list(unified_timer_names))

        # apply any averaging to the timers
        do_averaging(averaging=averaging,
                     df=comparable_df,
                     my_tokens=my_tokens)

        # optionally, compute the perct total time
        if DO_PERCENT_TOTAL:
            add_percent_total(total_time_key=total_time_key, df=comparable_df)

        # merge the new timer data into the baseline dataframe using columns "Foo_shortname"
        baseline_df = pd.merge(baseline_df,
                               comparable_df,
                               left_index=True,
                               right_index=True,
                               how='outer',
                               suffixes=('', '_' + short_name))

    baseline_df.to_csv('happy.csv')
    timer_types = ['minT', 'maxT', 'meanT', 'meanCT']
    for timer_type in timer_types:
        output_columns = [timer_type]

        if DO_PERCENT_TOTAL:
            output_columns.append('perc_{timer}'.format(timer=timer_type))

        lookup_column = ''

        for short_name in sorted(comparable_file_mapping.keys()):
            comparable_file = comparable_file_mapping[short_name]
            lookup_column = '{timer}_{short_name}'.format(
                timer=timer_type, short_name=short_name)

            speedup_column = '{timer}_speedup_{short_name}'.format(
                timer=timer_type, short_name=short_name)
            baseline_df[speedup_column] = baseline_df[
                timer_type] / baseline_df[lookup_column]

            # round the speedup  ?
            baseline_df[speedup_column] = pd.Series(
                [round(val, 3) for val in baseline_df[speedup_column]],
                index=baseline_df.index)

            output_columns.append(lookup_column)
            output_columns.append(speedup_column)

            if DO_PERCENT_TOTAL:
                output_columns.append('perc_{timer}_{short_name}'.format(
                    timer=timer_type, short_name=short_name))
                print(output_columns)
            if total_time_key is not None:
                output_columns.append('total_time_{timer}_{short_name}'.format(
                    timer=timer_type, short_name=short_name))

        fname = '{timer}_comparison'.format(timer=timer_type)
        if averaging != 'none':
            fname += '_averaged_by_{avg}'.format(avg=averaging)

        # slice this data off and rank/sort
        data_slice = baseline_df[output_columns]
        data_slice = add_running_total_and_rank(data_slice,
                                                column_name=timer_type,
                                                prefix_label='bl_')

        if DO_MUELU_COMP:
            data_slice = add_running_total_and_rank(data_slice,
                                                    column_name=lookup_column,
                                                    prefix_label='')
            # data_slice = data_slice.sort_values(by=[lookup_column], ascending=True)
            # data_slice['running'] = data_slice[lookup_column].cumsum()
            data_slice[
                'rank_delta'] = data_slice['rank'] - data_slice['bl_rank']
            output_columns.append('running')
            output_columns.append('rank')
            output_columns.append('rank_delta')
            data_slice['Timer Name'] = data_slice.index.values
            output_columns = ['Timer Name'] + output_columns

            data_slice = data_slice[data_slice['running'].notnull()]
            data_slice = data_slice.reset_index(drop=True)
            data_slice = data_slice.sort_index(ascending=True).reset_index()
            data_slice = data_slice.rename(
                columns={timer_type: baseline_short_name})
            output_columns[output_columns.index(
                timer_type)] = baseline_short_name

            output_columns.remove('rank')
            output_columns.remove('rank_delta')
            output_columns = ['rank', 'rank_delta'] + output_columns

        data_slice.to_csv('{fname}.csv'.format(fname=fname),
                          index=False,
                          columns=output_columns)

        df_to_markdown(data_slice[output_columns])

        # data_slice.to_csv('{fname}.csv'.format(fname=fname),
        #                    index_label='Timer Name',
        #                    index=True,
        #                    columns=output_columns)

    for short_name in sorted(comparable_file_mapping.keys()):
        comparable_file = comparable_file_mapping[short_name]
        print('{short_name}: {file}'.format(short_name=short_name,
                                            file=comparable_file))
Ejemplo n.º 11
0
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import ScalingFilenameParser as SFP

MIN_NUM_NODES = 1
MAX_NUM_NODES = 512

if __name__ == '__main__':
    # write the total dataset out, index=False, because we do not drop it above
    dataset = pd.read_csv('analysis.csv', low_memory=False)

    dataset.set_index(keys=SFP.getIndexColumns(execspace_name='OpenMP'),
                      drop=False,
                      inplace=True,
                      verify_integrity=True)

    dataset.sort_values(inplace=True,
                        by=SFP.getIndexColumns(execspace_name='OpenMP'))

    restriction_query = '(problem_type != \"Elasticity3D\") & ' \
                        '(solver_name == \"Constructor\") & ' \
                        '(num_nodes >= {min_num_nodes}) & ' \
                        '(num_nodes <= {max_num_nodes})' \
                        ''.format(min_num_nodes=MIN_NUM_NODES,
                                  max_num_nodes=MAX_NUM_NODES)

    dataset = dataset.query(restriction_query)

    # enforce all plots use the same num_nodes. E.g., the axes will be consistent