xref: /XiangShan/scripts/top-down/draw.py (revision 03a1a638e54b0b04a4d6c88c5f5cbc92c20e76fb)
1import os.path as osp
2import numpy as np
3import matplotlib.pyplot as plt
4import pandas as pd
5import configs as cf
6
7
8def draw():
9    results = {
10        'XS': (cf.OUT_CSV, 'XS'),
11    }
12
13    configs = list(results.keys())
14
15    color_types = 10
16    cmap = plt.get_cmap('tab10')
17    color_index = np.arange(0, 1, 1.0 / color_types)
18    colors = [cmap(c) for c in color_index] * 3
19    hatches = [None] * color_types + ['//'] * color_types + ['|'] * color_types
20
21    n_conf = len(configs)
22    # Draw stacked bar chart for each simulator
23    width = 0.8 / n_conf
24    # set figure size:
25
26    fig, ax = plt.subplots()
27    fig.set_size_inches(8.0, 5.0)
28
29    x = None
30    have_set_label = False
31
32    dfs = [pd.read_csv(result[0], index_col=0)
33           for _, result in results.items()]
34    common_bmk = list(set.intersection(*[set(df.index) for df in dfs]))
35    dfs = [df.loc[common_bmk] for df in dfs]
36
37    rename = True
38    fine_grain_rename = False
39    renamed_dfs = []
40    for df in dfs:
41        to_drops = []
42        sorted_cols = []
43
44        def rename_with_map(df, rename_map):
45            for k in rename_map:
46                if rename_map[k] is not None:
47                    if rename_map[k].startswith('Merge'):
48                        merged = rename_map[k][5:]
49                        if merged not in df.columns:
50                            df[merged] = df[k]
51                            sorted_cols.append(merged)
52                        else:
53                            df[merged] += df[k]
54                    else:
55                        df[rename_map[k]] = df[k]
56                        sorted_cols.append(rename_map[k])
57
58                    to_drops.append(k)
59                else:
60                    sorted_cols.append(k)
61            df.drop(columns=to_drops, inplace=True)
62
63        # Merge df columns according to the rename map if value starting with 'Merge'
64        if rename:
65            if fine_grain_rename:
66                rename_with_map(df, cf.xs_fine_grain_rename_map)
67            else:
68                rename_with_map(df, cf.xs_coarse_rename_map)
69
70            icount = 20 * 10 ** 6
71            if 'BadSpecInst' in df.columns:
72                df['BadSpecInst'] += df['Base'] - icount
73            else:
74                df['BadSpecInst'] = df['Base'] - icount
75            df['Base'] = icount
76
77        df = df.astype(float)
78        renamed_dfs.append(df)
79
80    common_col = list(set.intersection(
81        *[set(df.columns) for df in renamed_dfs]))
82    unique_cols = set()
83    for df in renamed_dfs:
84        unique_col = set(df.columns) - set(common_col)
85        for col in unique_col:
86            unique_cols.add(col)
87    for df in renamed_dfs:
88        for col in unique_cols:
89            if col not in df.columns:
90                df[col] = 0.0
91        df.sort_index(axis=1, inplace=True)
92
93    put_to_front = ['Base', 'BadSpec']
94
95    tmp_df = renamed_dfs[0].sort_values(by='cpi', ascending=False)
96    bmk_sort = tmp_df.index.tolist()
97
98    for df in renamed_dfs:
99        df = df.loc[bmk_sort]
100        df = df[put_to_front +
101                [col for col in df.columns if col not in put_to_front]]
102        df = df.drop(columns=['cpi'])
103        for to_drop in ['ipc', 'cpi', 'Cycles', 'Insts', 'coverage']:
104            if to_drop in df.columns:
105                df = df.drop(columns=[to_drop])
106
107        # draw stacked bar chart
108        bottom = np.zeros(len(df))
109        highest = 0.0
110        if x is None:
111            x = np.arange(len(df), dtype=float)
112        for component, color, hatch in zip(df.columns, colors[:len(df.columns)], hatches[:len(df.columns)]):
113            if have_set_label:
114                label = None
115            else:
116                label = component
117            ax.bar(x, df[component], bottom=bottom,
118                   width=width, color=color, label=label, edgecolor='black', hatch=hatch)
119            highest = max((bottom + df[component]).max(), highest)
120            bottom += df[component]
121        x += width
122        have_set_label = True
123    # replace x tick labels with df.index with rotation
124    ax.set_xticks(x - width * len(results) / n_conf - 0.25)
125    ax.set_xticklabels(bmk_sort, rotation=90)
126    ax.tick_params(left=False, bottom=False)
127    ax.set_ylabel('Slots')
128    ax.set_xlabel('SPECCPU 2006 Benchmarks')
129
130    handles, labels = plt.gca().get_legend_handles_labels()
131    ax.legend(list(reversed(handles)), list(reversed(labels)), fancybox=True,
132              framealpha=0.3,
133              loc='best',
134              ncol=3,
135              )
136    if n_conf == 2:
137        ax.set_title(f'{configs[0]} <-- VS. --> {configs[1]}')
138
139    fig.savefig(osp.join('results', 'result.png'),
140                bbox_inches='tight', pad_inches=0.05, dpi=200)
141