# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # STM 32H743 FIR Filter performance
# This notebook shows FIR Filter performance on the STM32H743 for various block sizes, number of channels, and number of taps.  
#
# Source code is at https://github.com/ccrome/jupyter_notebooks/tree/master/stm32_fir_filter_test
#
# ## ************************************************
# ## If you just want to browse the data, Just hit Cell->Run All and scroll to the bottom
# ## ************************************************
#

from ipywidgets import interact
from bokeh.io import curdoc, push_notebook, show, output_notebook
from bokeh.layouts import row, column
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, Range1d
from bokeh.models.widgets import Slider, TextInput
output_notebook()

import pandas as pd
import matplotlib.pyplot as plt
# %matplotlib inline

# +
clock_speed = 400e6
def load_data(fn):
    data_f32 = pd.read_csv(fn, dtype={'type':str})
    data_f32 = data_f32.rename(columns=lambda x: x.strip())
    data_f32['time'] = data_f32['time_ns']/1e9
    data_f32['cycles'] = clock_speed * data_f32['time']
    data_f32['calculations'] = data_f32['channels'] * data_f32['blocksize'] * data_f32['ntaps']
    data_f32['cycles_per_calc'] = data_f32['cycles']/data_f32['calculations']
    data_f32['ns'] = data_f32['calculations']/data_f32['time']
    return data_f32

def get_data_chan_taps(data, dtype, nchan, ntaps):
    return  data.loc[(data['type']     == dtype) &
                 (data['channels'] == nchan) &
                 (data['ntaps']    == ntaps)]
    return r

def get_min_max(d, col, dtype=None):
    if dtype is None:
        return d.describe()[col]['min'], d.describe()[col]['max']
    else:
        return dtype(d.describe()[col]['min']), dtype(d.describe()[col]['max'])



# -

data = load_data("fir_filter.csv")


# +
def get_data_from(data, dtype, nchan, ntaps):
    df = get_data_chan_taps(data, dtype, nchan, ntaps)
    arr = df.loc[:, ['blocksize', 'cycles_per_calc']].to_numpy()
    blocksize = arr[:, 0]
    cycles_per_mac = arr[:, 1]
    return blocksize, cycles_per_mac

def plot_data_bokeh(dtypes, data, nchan, ntapss, ylimit=None):
    for dtype in dtypes:
        for ntaps in ntapss:
            df = get_data_chan_taps(data, dtype, nchan, ntaps)
            x = df['blocksize']
            y = df['cycles_per_calc']
            plot(df['blocksize'], df['cycles_per_calc'], "*-", label=f"t={dtype}, ch={nchan}, t={ntaps}")
    xlabel("blocksize")
    ylabel("cycles/calc")
    if ylimit is not None:
        ylim(ylimit[0], ylimit[1])
    title(f"cycles/MAC, float32 FIR filter, channels={nchan}")
    legend()
    show()

#source = ColumnDataSource(data=dict(x=x, y=y))



# +
def update_data(taps, channels, dtype):
    blocksizes, cycles = get_data_from(data, dtype, nchan=channels, ntaps=taps)
    source.data = dict(x=blocksizes, y=cycles)
    push_notebook()



bs_min, bs_max = get_min_max(data, 'blocksize', int)
ch_min, ch_max = get_min_max(data, 'channels', int)
tp_min, tp_max = get_min_max(data, 'ntaps', int)


#bs_slider = Slider(start = bs_min, end = bs_max, value = bs_min, step = 1, title="Block Size")
ch = 16
taps = 100
blocksizes, cycles = get_data_from(data, "f32", nchan=ch, ntaps=taps)


source = ColumnDataSource(data=dict(x=blocksizes, y=cycles))
plot = figure (plot_width=500, plot_height=300, x_range=[0, bs_max+1], y_range=[0, 10])
plot.xaxis.axis_label="Block Size"
plot.yaxis.axis_label="CPU Cycles/MAC"
plot.line('x', 'y', source=source, line_width=3, line_alpha = 0.6)
layout = row(plot)
handle = show(layout, notebook_handle=True)

i = interact (update_data, 
              taps=(tp_min, tp_max), 
              channels=(ch_min, ch_max),
              #types=[("f32", 1), ("q31", 2), ("q31f", 3), ("q15", 4), ("q15f", 5)],
              dtype=["f32", "q31", "q31f", "q15", "q15f"],
             ) 


StarcoderdataJupyterScriptsDedupFiltered