Пример #1
0
def check_pandas_or_run(sim,
                        dataframe,
                        sim_sweep_csv,
                        batch_size=1,
                        config_file='./conf.ini'):
    ld = {}
    ld['N'] = sim.accelerator.N
    ld['M'] = sim.accelerator.M
    ld['Max Precision (bits)'] = sim.accelerator.pmax
    ld['Min Precision (bits)'] = sim.accelerator.pmin
    ld['Bandwidth (bits/cycle)'] = sim.accelerator.mem_if_width
    ld['WBUF Size (bits)'] = sim.accelerator.sram['wgt']
    ld['OBUF Size (bits)'] = sim.accelerator.sram['out']
    ld['IBUF Size (bits)'] = sim.accelerator.sram['act']
    ld['Batch size'] = batch_size

    results = lookup_pandas_dataframe(dataframe, ld)

    if len(results) == 0:
        sweep_obj = SimulatorSweep(sim_sweep_csv, config_file)
        dataframe = sweep_obj.sweep(sim, list_batch=[batch_size])
        dataframe.to_csv(sim_sweep_csv, index=False)
        return lookup_pandas_dataframe(dataframe, ld)
    else:
        return results
Пример #2
0
    def plot(self, outputFileName, dataframe, x_plot, y_plot, bar_plot, x_plot_list=None, y_plot_list=None, bar_list=None, lookup_dict=None, add_geomean=False, baseline=None):

        stacked = isinstance(y_plot, list) and len(y_plot) > 1
        if not stacked:
            y_plot = [y_plot]

        self.log.info('Plotting BarChart to file: {}'.format(outputFileName))
        self.log.info('bar_plot: {}'.format(bar_plot))
        self.log.info('x-axis: {}'.format(x_plot))
        self.log.info('y-axis: {}'.format(y_plot))

        assert bar_list is not None, 'Expected list of bar_plot'
        num_bar_plot = len(bar_list)

        if x_plot_list is None:
            x_plot_list = list(dataframe[x_plot].unique())

        if add_geomean:
            # Add an additional 'Gmean'
            x_plot_list.append('Gmean')

        if stacked:
            num_colors = len(y_plot)
        else:
            num_colors = num_bar_plot

        if self.COLOR is None or len(self.COLOR) != num_colors:
            self.COLOR = []
            diff = (self.COLOR_MAX - self.COLOR_MIN) / (num_colors - 1)
            for i in range(num_colors):
                self.COLOR.append(tuple(self.COLOR_MAX - i * diff))
            self.log.info('Using colors: {}'.format(self.COLOR))

        with PdfPages(outputFileName) as pdf:

            fig, ax = plt.subplots(figsize=(self.FIG_WIDTH, self.FIG_HEIGHT))

            num_benchmarks = len(x_plot_list)
            N = num_benchmarks
            ind = np.arange(N)

            legendLocation = []
            rectsList = []

            xbegin = np.arange(N)

            self.BAR_WIDTH = 1. / (num_bar_plot * (1+self.BAR_GAP) + self.BAR_LEFT_MARGIN)

            if lookup_dict is None:
                default_lookup = {}
            else:
                default_lookup = lookup_dict
            default_lookup[bar_plot] = bar_list[0]
            left_margin = float(self.BAR_LEFT_MARGIN * self.BAR_WIDTH)

            edgecolors = ['black'] * num_benchmarks

            for i in range(0, num_bar_plot):
                bottom = np.zeros(num_benchmarks)
                for _y in range(len(y_plot)):
                    _y_plot = y_plot[_y]

                    if lookup_dict is None:
                        data_lookup = {}
                        base_lookup = {}
                    else:
                        data_lookup = lookup_dict
                        base_lookup = {}

                    dataLine = []
                    data_lookup[bar_plot] = bar_list[i]
                    for j in range(num_benchmarks - add_geomean):
                        data_lookup[x_plot] = x_plot_list[j]
                        data_row = lookup_pandas_dataframe(dataframe, data_lookup)
                        
                        dataLine.append(float(data_row[_y_plot]))

                    if baseline is None:
                        baseLine = [1]*len(dataLine)
                    else:
                        base_lookup[bar_plot] = baseline
                        baseLine = []
                        for j in range(num_benchmarks - add_geomean):
                            base_lookup[x_plot] = x_plot_list[j]
                            base_row = lookup_pandas_dataframe(dataframe, base_lookup)
                            baseLine.append(float(base_row[_y_plot]))
                        assert len(baseLine) == len(dataLine)
                    dataLine = [x/y for x,y in zip(dataLine, baseLine)]

                    if add_geomean:
                        dataLine.append(gmean(dataLine))

                    if stacked:
                        color = self.COLOR[_y]
                    else:
                        color = self.COLOR[i]

                    if self.LOG_SCALE == False:
                        rects = ax.bar(ind + left_margin, dataLine, self.BAR_WIDTH, color=color, bottom=bottom, edgecolor=edgecolors)
                    else:
                        rects = ax.bar(ind + left_margin, dataLine, self.BAR_WIDTH, log=1, color=color, bottom=bottom, edgecolor=edgecolors)

                    legendLocation.append(rects[0])
                    rectsList.append(rects)

                    if stacked:
                        bottom += dataLine
                left_margin += self.BAR_WIDTH + self.BAR_GAP

            if self.LOG_SCALE == True:
                ax.set_yscale('log', nonposy='clip')
            ax.set_xlim(0, len(x_plot_list))
            ax.set_ylim(self.YAXIS_MIN, self.YAXIS_MAX)

            if stacked:
                num_minor_ticks = len(x_plot_list) * len(bar_plot)
                num_major_ticks = len(x_plot_list)
                minor_ticks = []
                minor_ind = []
                for i in range(len(x_plot_list)):
                    offset = self.BAR_LEFT_MARGIN * self.BAR_WIDTH + i
                    for j in range(len(bar_list)):
                        minor_ticks.append(bar_list[j])
                        minor_ind.append(offset)
                        offset += self.BAR_WIDTH + self.BAR_GAP
                ax.set_xticks(minor_ind, minor=True)
                ax.set_xticklabels(minor_ticks, rotation=self.XAXIS_LABEL_ROTATE, minor=True)
                ax.set_xticks(ind+0.5, minor=False)
                ax.set_xticklabels(x_plot_list, rotation=self.XAXIS_LABEL_ROTATE, minor=False)
                ax.tick_params(axis='x', which='major', direction='out', length=0)

                # vertical alignment of xtick labels
                va = [ -0.10 for i in range(len(x_plot_list))]
                for t, y in zip( ax.get_xticklabels( ), va ):
                        t.set_y( y )
            else:
                ax.set_xticks(ind+0.5, minor=False)
                ax.set_xticklabels(x_plot_list, rotation=self.XAXIS_LABEL_ROTATE)

            ax.spines['top'].set_visible(False)
            ax.spines['right'].set_visible(False)

            fig.subplots_adjust(top=self.TOP_MARGIN)
            if self.BENCH_NEWLINE == True:
                fig.subplots_adjust(bottom=self.BOTTOM_MARGIN)
            else:
                fig.subplots_adjust(bottom=self.BOTTOM_MARGIN * 0.5)
            fig.subplots_adjust(left=self.LEFT_MARGIN)
            fig.subplots_adjust(right=self.RIGHT_MARGIN)

            if self.ISRATES == True:
                formatter = FuncFormatter(self.to_percent)
                ax.yaxis.set_major_formatter(formatter)
            elif self.ISTIMES == True:
                formatter = FuncFormatter(self.to_times2)
                ax.yaxis.set_major_formatter(formatter)
            else:
                formatter = FuncFormatter(self.to_text)
                ax.yaxis.set_major_formatter(formatter)

            if self.yaxis != '':
                ax.set_ylabel(self.yaxis, fontsize=self.AXIS_TITLE_FONTSIZE, labelpad=5.0)
            if self.xaxis != '':
                ax.set_xlabel(self.xaxis, fontsize=self.AXIS_TITLE_FONTSIZE, labelpad=20.0)

            # for i in range(0, len(x_plot_list)):
            #     loc = (1.0 / len(x_plot_list)) * (i + 0.5)
            #     space4line = 0.075
            #     if self.BENCH_NEWLINE == True:
            #         space4text = space4line * 2
            #     else:
            #         space4text = space4line
            #     ax.text(loc, -space4text, x_plot_list[i], horizontalalignment='center', fontsize=self.XAXIS_FONTSIZE,
            #             transform=ax.transAxes, rotation=self.XAXIS_LABEL_ROTATE)

            # is stacked, show the stacks as legends; otherwise show the bars as legend
            if stacked:
                legend_list = y_plot
            else:
                legend_list = bar_list
            if self.MV_LEGEND_OUTSIDE_X != 0.0 or self.MV_LEGEND_OUTSIDE_Y != 1.0:
                ax.legend(tuple(legendLocation), legend_list, loc=self.LEGEND_LOCATION, fontsize=self.LEGEND_FONTSIZE, borderpad=0.2,
                          borderaxespad=0.3, labelspacing=0.05, ncol=self.LEGEND_NCOLUMN,
                          bbox_to_anchor=(self.MV_LEGEND_OUTSIDE_X, self.MV_LEGEND_OUTSIDE_Y))
            else:
                ax.legend(tuple(legendLocation), legend_list, loc=self.LEGEND_LOCATION, fontsize=self.LEGEND_FONTSIZE, borderpad=0.2,
                          borderaxespad=0.3, labelspacing=0.05, ncol=self.LEGEND_NCOLUMN)

            length = len(rectsList)
            for i in range(0, length):
                rects = rectsList[i]
                self.autolabel(ax, rects)

            ax.set_axisbelow(True)

            for tick in ax.get_yaxis().get_major_ticks():
                tick.set_pad(self.YAXIS_PAD)
                tick.label1 = tick._get_text1()

            if x_plot_list[len(x_plot_list) - 1] == '\sf{Gmean}' or x_plot_list[len(x_plot_list) - 1] == 'Gmean' or x_plot_list[len(x_plot_list) - 1] == 'Avg' or x_plot_list[len(x_plot_list) - 1] == 'Average':
                plt.axvline(x=len(x_plot_list) - 1, c="black", lw=1.2)

            # plt.axhline(y=1.0, c="black", lw=2)

            pdf.savefig(fig, bbox_inches='tight', pad_inches=0.02)
Пример #3
0
    def get_energy_cost(self):

        if self.energy_costs is not None:
            return self.energy_costs

        frequency = self.accelerator.frequency
        ##################################################
        N = self.accelerator.N
        M = self.accelerator.M
        pmax = self.accelerator.pmax
        pmin = self.accelerator.pmin
        wbuf_size = self.accelerator.sram['wgt'] * 8
        ibuf_size = self.accelerator.sram['act'] * 8
        obuf_size = self.accelerator.sram['out'] * 8
        wbuf_bank = N * M
        ibuf_bank = N
        obuf_bank = M
        wbuf_bits = (pmax * pmax / pmin)
        ibuf_bits = (pmax * pmax / pmin)
        obuf_bits = 32
        wbuf_word = ceil_a_by_b(wbuf_size, wbuf_bank * wbuf_bits)
        ibuf_word = ceil_a_by_b(ibuf_size, ibuf_bank * ibuf_bits)
        obuf_word = ceil_a_by_b(obuf_size, obuf_bank * obuf_bits)
        wbuf_bank_size = wbuf_word * wbuf_bits
        ibuf_bank_size = ibuf_word * ibuf_bits
        obuf_bank_size = obuf_word * obuf_bits

        assert wbuf_bank_size * wbuf_bank == wbuf_size
        assert ibuf_bank_size * ibuf_bank == ibuf_size
        assert obuf_bank_size * obuf_bank == obuf_size

        ##################################################
        cfg_dict = {
            'size (bytes)': wbuf_bank_size / 8.,
            'block size (bytes)': wbuf_bits / 8.,
            'read-write port': 0
        }
        wbuf_data = self.sram_obj.get_data_clean(cfg_dict)
        wbuf_read_energy = float(wbuf_data['read_energy_nJ']) / wbuf_bits
        wbuf_write_energy = float(wbuf_data['write_energy_nJ']) / wbuf_bits
        wbuf_leak_power = float(wbuf_data['leak_power_mW']) * wbuf_bank
        wbuf_area = float(wbuf_data['area_mm^2']) * wbuf_bank

        self.logger.debug('WBUF :')
        self.logger.debug(
            '\tBanks                       : {0:>8}'.format(wbuf_bank))
        self.logger.debug(
            '\tBitWidth                    : {0:>8} bits'.format(wbuf_bits))
        self.logger.debug(
            '\tWords                       : {0:>8}'.format(wbuf_word))
        self.logger.debug(
            '\tTotal Size                  : {0:>8} kBytes'.format(wbuf_size /
                                                                   8. / 1024.))
        self.logger.debug(
            '\tTotal Area                  : {0:>8.2f} mm^2'.format(wbuf_area))
        self.logger.debug(
            '\tLeak Energy (per clock)     : {0:>8.4f} mWatt'.format(
                wbuf_leak_power))
        self.logger.debug(
            '\tRead Energy                 : {0:>8.4f} pJ/bit'.format(
                wbuf_read_energy * 1.e3))
        self.logger.debug(
            '\tWrite Energy                : {0:>8.4f} pJ/bit'.format(
                wbuf_write_energy * 1.e3))
        ##################################################
        cfg_dict = {
            'size (bytes)': ibuf_bank_size / 8.,
            'block size (bytes)': ibuf_bits / 8.,
            'read-write port': 0
        }
        ibuf_data = self.sram_obj.get_data_clean(cfg_dict)
        ibuf_read_energy = float(ibuf_data['read_energy_nJ']) / ibuf_bits
        ibuf_write_energy = float(ibuf_data['write_energy_nJ']) / ibuf_bits
        ibuf_leak_power = float(ibuf_data['leak_power_mW']) * ibuf_bank
        ibuf_area = float(ibuf_data['area_mm^2']) * ibuf_bank

        self.logger.debug('IBUF :')
        self.logger.debug(
            '\tBanks                       : {0:>8}'.format(ibuf_bank))
        self.logger.debug(
            '\tBitWidth                    : {0:>8} bits'.format(ibuf_bits))
        self.logger.debug(
            '\tWords                       : {0:>8}'.format(ibuf_word))
        self.logger.debug(
            '\tTotal Size                  : {0:>8} kBytes'.format(ibuf_size /
                                                                   8. / 1024.))
        self.logger.debug(
            '\tTotal Area                  : {0:>8.2f} mm^2'.format(ibuf_area))
        self.logger.debug(
            '\tLeak Energy (per clock)     : {0:>8.4f} mWatt'.format(
                ibuf_leak_power))
        self.logger.debug(
            '\tRead Energy                 : {0:>8.4f} pJ/bit'.format(
                ibuf_read_energy * 1.e3))
        self.logger.debug(
            '\tWrite Energy                : {0:>8.4f} pJ/bit'.format(
                ibuf_write_energy * 1.e3))
        ##################################################
        cfg_dict = {
            'size (bytes)': obuf_bank_size / 8.,
            'block size (bytes)': obuf_bits / 8.,
            'read-write port': 1
        }
        obuf_data = self.sram_obj.get_data_clean(cfg_dict)
        obuf_read_energy = float(obuf_data['read_energy_nJ']) / obuf_bits
        obuf_write_energy = float(obuf_data['write_energy_nJ']) / obuf_bits
        obuf_leak_power = float(obuf_data['leak_power_mW']) * obuf_bank
        obuf_area = float(obuf_data['area_mm^2']) * obuf_bank

        self.logger.debug('OBUF :')
        self.logger.debug(
            '\tBanks                       : {0:>8}'.format(obuf_bank))
        self.logger.debug(
            '\tBitWidth                    : {0:>8} bits'.format(obuf_bits))
        self.logger.debug(
            '\tWords                       : {0:>8}'.format(obuf_word))
        self.logger.debug(
            '\tTotal Size                  : {0:>8} kBytes'.format(obuf_size /
                                                                   8. / 1024.))
        self.logger.debug(
            '\tTotal Area                  : {0:>8.2f} mm^2'.format(obuf_area))
        self.logger.debug(
            '\tLeak Energy (per clock)     : {0:>8.4f} mWatt'.format(
                obuf_leak_power))
        self.logger.debug(
            '\tRead Energy                 : {0:>8.4f} pJ/bit'.format(
                obuf_read_energy * 1.e3))
        self.logger.debug(
            '\tWrite Energy                : {0:>8.4f} pJ/bit'.format(
                obuf_write_energy * 1.e3))
        ##################################################
        # Get stats for systolic array
        core_csv = os.path.join('./results', 'systolic_array_synth.csv')
        core_synth_data = pandas.read_csv(core_csv)

        lookup_dict = {}
        lookup_dict['Max Precision (bits)'] = pmax
        lookup_dict['Min Precision (bits)'] = pmin
        lookup_dict['N'] = N
        lookup_dict['M'] = M
        core_data = lookup_pandas_dataframe(core_synth_data, lookup_dict)
        if len(core_data) == 0:
            lookup_dict['N'] = 4
            lookup_dict['M'] = 4
            core_data = lookup_pandas_dataframe(core_synth_data, lookup_dict)
            assert len(core_data) == 1
            core_area = float(core_data['Area (um^2)']) * 1.e-6 * (N * M) / 16.
            core_dyn_power = float(
                core_data['Dynamic Power (nW)']) * (N * M) / 16.
            core_dyn_energy = core_dyn_power / float(core_data['Frequency'])
            core_leak_power = float(
                core_data['Leakage Power (nW)']) * (N * M) / 16.
            core_leak_energy = core_leak_power / float(core_data['Frequency'])
        else:
            core_area = float(core_data['Area (um^2)']) * 1.e-6
            core_dyn_power = float(core_data['Dynamic Power (nW)'])
            core_dyn_energy = core_dyn_power / float(core_data['Frequency'])
            core_leak_power = float(core_data['Leakage Power (nW)'])
            core_leak_energy = core_leak_power / float(core_data['Frequency'])
        self.logger.debug('Core :')
        self.logger.debug(
            '\tDimensions              : {0}x{1}-systolic array'.format(N, M))
        self.logger.debug('\tMax-Precision           : {}'.format(pmax))
        self.logger.debug('\tMin-Precision           : {}'.format(pmin))
        self.logger.debug(
            '\tLeak power              : {} (nW)'.format(core_leak_energy))
        self.logger.debug(
            '\tDynamic Energy (nJ)     : {}'.format(core_dyn_energy))
        self.logger.debug('\tArea (mm^2)             : {}'.format(core_area))
        ##################################################

        energy_tuple = EnergyTuple(core_dyn_energy, wbuf_read_energy,
                                   wbuf_write_energy, ibuf_read_energy,
                                   ibuf_write_energy, obuf_read_energy,
                                   obuf_write_energy)

        return energy_tuple
Пример #4
0
    def sweep(self,
              sim_obj,
              list_n=None,
              list_m=None,
              list_pmax=None,
              list_pmin=None,
              list_bw=None,
              list_bench=None,
              list_wbuf=None,
              list_ibuf=None,
              list_obuf=None,
              list_batch=None):
        """
        Sweep the parameters of the accelerator
        """

        if list_n is None:
            list_n = [sim_obj.accelerator.N]
        if list_m is None:
            list_m = [sim_obj.accelerator.M]

        if list_pmax is None:
            list_pmax = [sim_obj.accelerator.pmax]
        if list_pmin is None:
            list_pmin = [sim_obj.accelerator.pmin]

        if list_bw is None:
            list_bw = [sim_obj.accelerator.mem_if_width]

        if list_bench is None:
            list_bench = benchmarks.benchlist

        if list_wbuf is None:
            list_wbuf = [sim_obj.accelerator.sram['wgt']]
        if list_ibuf is None:
            list_ibuf = [sim_obj.accelerator.sram['act']]
        if list_obuf is None:
            list_obuf = [sim_obj.accelerator.sram['out']]

        if list_batch is None:
            list_batch = [1]

        data_line = []
        for batch_size in list_batch:
            for n in list_n:
                for m in list_m:
                    # self.logger.info('N x M = {} x {}'.format(n, m))
                    for pmax in list_pmax:
                        for pmin in list_pmin:
                            if pmin > pmax:
                                continue
                            for wbuf in list_wbuf:
                                for ibuf in list_ibuf:
                                    for obuf in list_obuf:
                                        for bw in list_bw:
                                            sim_obj.accelerator.N = n
                                            sim_obj.accelerator.M = m
                                            sim_obj.accelerator.pmax = pmax
                                            sim_obj.accelerator.pmin = pmin
                                            sim_obj.accelerator.mem_if_width = bw
                                            sim_obj.accelerator.sram[
                                                'wgt'] = wbuf
                                            sim_obj.accelerator.sram[
                                                'out'] = obuf
                                            sim_obj.accelerator.sram[
                                                'act'] = ibuf
                                            for b in list_bench:
                                                lookup_dict = {}
                                                lookup_dict['N'] = n
                                                lookup_dict['M'] = m
                                                lookup_dict[
                                                    'Max Precision (bits)'] = pmax
                                                lookup_dict[
                                                    'Min Precision (bits)'] = pmin
                                                lookup_dict['Network'] = b
                                                lookup_dict[
                                                    'Bandwidth (bits/cycle)'] = sim_obj.accelerator.mem_if_width
                                                lookup_dict[
                                                    'WBUF Size (bits)'] = wbuf
                                                lookup_dict[
                                                    'OBUF Size (bits)'] = obuf
                                                lookup_dict[
                                                    'IBUF Size (bits)'] = ibuf
                                                lookup_dict[
                                                    'Batch size'] = batch_size
                                                results = lookup_pandas_dataframe(
                                                    self.sweep_df, lookup_dict)
                                                nn = benchmarks.get_bench_nn(
                                                    b, WRPN=True)
                                                if len(results) == 0:
                                                    self.logger.info(
                                                        'Simulating Benchmark: {}'
                                                        .format(b))
                                                    self.logger.info(
                                                        'N x M = {} x {}'.
                                                        format(n, m))
                                                    self.logger.info(
                                                        'Max Precision (bits): {}'
                                                        .format(pmax))
                                                    self.logger.info(
                                                        'Min Precision (bits): {}'
                                                        .format(pmin))
                                                    self.logger.info(
                                                        'Batch size: {}'.
                                                        format(batch_size))
                                                    self.logger.info(
                                                        'Bandwidth (bits/cycle): {}'
                                                        .format(bw))
                                                    stats = benchmarks.get_bench_numbers(
                                                        nn, sim_obj,
                                                        batch_size)
                                                    for layer in stats:
                                                        cycles = stats[
                                                            layer].total_cycles
                                                        reads = stats[
                                                            layer].reads
                                                        writes = stats[
                                                            layer].writes
                                                        stalls = stats[
                                                            layer].mem_stall_cycles
                                                        data_line.append((
                                                            n, m, pmax, pmin,
                                                            b, layer, cycles,
                                                            stalls,
                                                            reads['wgt'],
                                                            writes['wgt'],
                                                            reads['out'],
                                                            writes['out'],
                                                            reads['act'],
                                                            writes['act'],
                                                            reads['dram'],
                                                            writes['dram'],
                                                            sim_obj.accelerator
                                                            .mem_if_width,
                                                            wbuf, obuf, ibuf,
                                                            batch_size))
                                            if len(data_line) > 0:
                                                if os.path.exists(
                                                        self.csv_filename):
                                                    self.sweep_df = pandas.read_csv(
                                                        self.csv_filename)
                                                else:
                                                    self.sweep_df = pandas.DataFrame(
                                                        columns=self.columns)
                                                self.sweep_df = self.sweep_df.append(
                                                    pandas.DataFrame(
                                                        data_line,
                                                        columns=self.columns))
                                                self.sweep_df.to_csv(
                                                    self.csv_filename,
                                                    index=False)
                                                data_line = []
        return self.sweep_df