yum/vfft
git clone https://git.yummers.dev/yum/vfft
b279c5c
master
1#!/usr/bin/env -S uv run --script 2# 3# /// script 4# requires-python = ">=3.12" 5# dependencies = ["matplotlib", "PySide6"] 6# /// 7 8import argparse 9import csv 10import matplotlib 11matplotlib .use ("QtAgg" ) 12import matplotlib .pyplot as plt 13from pathlib import Path 14 15def parse_args (): 16parser = argparse .ArgumentParser (description = "Plot three CSV columns." ) 17parser .add_argument ("csv_path" ,help = "Path to the CSV file" ) 18parser .add_argument ("--x" ,default = 0 ,help = "Column for the x axis" ) 19parser .add_argument ("--y0" ,default = 1 ,help = "Column 0 for the y axis" ) 20parser .add_argument ("--y1" ,default = 2 ,help = "Column 1 for the y axis" ) 21parser .add_argument ("--save" ,action = "store_true" ,help = "Save the chart instead of displaying it" ) 22args = parser .parse_args () 23return args 24 25def to_ns (datum ): 26if datum .endswith (" ns" ): 27return float (datum [:- 3 ]) 28if datum .endswith (" us" ): 29return float (datum [:- 3 ])* 1000 30if datum .endswith (" ms" ): 31return float (datum [:- 3 ])* 1000 * 1000 32# Assume it's already in ns 33return float (datum ) 34 35def get_basic_save_path (args ): 36return Path (args .csv_path ).with_suffix (".png" ) 37 38def get_ratio_save_path (args ): 39path = Path (args .csv_path ) 40stem = path .stem 41return Path (args .csv_path ).with_stem (stem + "_ratio" ).with_suffix (".png" ) 42 43def parse_data (args ): 44data = ([], [], []) 45with open (args .csv_path ,newline = "" ,encoding = "utf-8" )as file : 46reader = (row for row in csv .reader (file )) 47header = next (reader ) 48 49for row in reader : 50x = float (row [args .x ]) 51y0 = to_ns (row [args .y0 ]) 52y1 = to_ns (row [args .y1 ]) 53 54data [0 ].append (x ) 55data [1 ].append (y0 ) 56data [2 ].append (y1 ) 57 58return data 59 60def plot_basic (args ,data ): 61x ,y0 ,y1 = data 62fig ,ax = plt .subplots () 63ax .plot (x ,y0 ,marker = "o" ,label = "rustfft" ) 64ax .plot (x ,y1 ,marker = "o" ,label = "vfft" ) 65ax .set (xlabel = "Input length" ,ylabel = "Time (ns)" ) 66ax .legend () 67ax .grid (True ,alpha = 0.3 ) 68fig .tight_layout () 69 70if args .save : 71fig .savefig (get_basic_save_path (args ),dpi = 150 ) 72else : 73plt .show () 74 75def plot_ratio (args ,data ): 76x ,y0 ,y1 = data 77ratio = [x1 / x0 for x0 ,x1 in zip (y0 ,y1 ) ] 78fig ,ax = plt .subplots () 79ax .plot (x ,ratio ,marker = "o" ,label = "vfft / rustfft" ) 80ax .set_xlim (left = 0 ) 81ax .set_ylim (bottom = 0 ) 82ax .axhline (y = 1 ,color = "red" ,linestyle = "--" ) 83ax .set (xlabel = "Input length" ,ylabel = "Execution time ratio (vfft / rustfft)" ) 84ax .legend () 85ax .grid (True ,alpha = 0.3 ) 86fig .tight_layout () 87 88if args .save : 89fig .savefig (get_ratio_save_path (args ),dpi = 150 ) 90else : 91plt .show () 92 93def print_stats (data ): 94x ,y0 ,y1 = data 95 96num_wins = 0 97for x0 ,x1 in zip (y0 ,y1 ): 98if x1 < x0 : 99num_wins += 1 100 101f"num trials: { len ( x ) } " ) 102f"num wins: { num_wins } " ) 103f"win rate: { num_wins / len ( x ) } " ) 104 105def main (): 106args = parse_args () 107data = parse_data (args ) 108plot_basic (args ,data ) 109plot_ratio (args ,data ) 110print_stats (data ) 111 112 113if __name__ == "__main__" : 114main () 115