1""" 2Copyright 2019 Ettus Research, A National Instrument Brand 3 4SPDX-License-Identifier: GPL-3.0-or-later 5 6Helper script that parses the results of benchmark_rate and extracts numeric 7values printed at the end of execution. 8""" 9 10import collections 11import re 12import csv 13 14Results = collections.namedtuple( 15 'Results', 16 """ 17 num_rx_channels 18 num_tx_channels 19 rx_rate 20 tx_rate 21 received_samps 22 dropped_samps 23 overruns 24 transmitted_samps 25 tx_seq_errs 26 rx_seq_errs 27 underruns 28 late_cmds 29 tx_timeouts 30 rx_timeouts 31 """ 32) 33 34def average(results): 35 """ 36 Returns the average of a list of results. 37 """ 38 results_as_lists = [list(r) for r in results] 39 avg_vals = [sum(x)/len(results) for x in zip(*results_as_lists)] 40 return Results(*avg_vals) 41 42def min_vals(results): 43 """ 44 Returns the minimum values of a list of results. 45 """ 46 results_as_lists = [list(r) for r in results] 47 min_vals = [min(x) for x in zip(*results_as_lists)] 48 return Results(*min_vals) 49 50def max_vals(results): 51 """ 52 Returns the maximum values of a list of results. 53 """ 54 results_as_lists = [list(r) for r in results] 55 max_vals = [max(x) for x in zip(*results_as_lists)] 56 return Results(*max_vals) 57 58def non_zero_vals(results): 59 """ 60 Returns the number of non-zero values from a list of results. 61 """ 62 results_as_lists = [list(r) for r in results] 63 results_as_lists = [[1 if x > 0 else 0 for x in y] for y in results_as_lists] 64 non_zero_vals = [sum(x) for x in zip(*results_as_lists)] 65 return Results(*non_zero_vals) 66 67def parse(result_str): 68 """ 69 Parses benchmark results and returns numerical values. 70 """ 71 # Parse rx rate 72 rx_rate = 0.0 73 num_rx_channels = 0 74 expr = "Testing receive rate ([0-9]+\.[0-9]+) Msps on (\d+) channels" 75 match = re.search(expr, result_str) 76 if match is not None: 77 rx_rate = float(match.group(1)) * 1.0e6 78 num_rx_channels = int(match.group(2)) 79 80 tx_rate = 0.0 81 num_tx_channels = 0 82 expr = "Testing transmit rate ([0-9]+\.[0-9]+) Msps on (\d+) channels" 83 match = re.search(expr, result_str) 84 if match is not None: 85 tx_rate = float(match.group(1)) * 1.0e6 86 num_tx_channels = int(match.group(2)) 87 88 # Parse results 89 expr = "Benchmark rate summary:" 90 expr += r"\s*Num received samples:\s*(\d+)" 91 expr += r"\s*Num dropped samples:\s*(\d+)" 92 expr += r"\s*Num overruns detected:\s*(\d+)" 93 expr += r"\s*Num transmitted samples:\s*(\d+)" 94 expr += r"\s*Num sequence errors \(Tx\):\s*(\d+)" 95 expr += r"\s*Num sequence errors \(Rx\):\s*(\d+)" 96 expr += r"\s*Num underruns detected:\s*(\d+)" 97 expr += r"\s*Num late commands:\s*(\d+)" 98 expr += r"\s*Num timeouts \(Tx\):\s*(\d+)" 99 expr += r"\s*Num timeouts \(Rx\):\s*(\d+)" 100 match = re.search(expr, result_str) 101 if match: 102 return Results( 103 num_rx_channels = num_rx_channels, 104 num_tx_channels = num_tx_channels, 105 rx_rate = rx_rate, 106 tx_rate = tx_rate, 107 received_samps = int(match.group(1)), 108 dropped_samps = int(match.group(2)), 109 overruns = int(match.group(3)), 110 transmitted_samps = int(match.group(4)), 111 tx_seq_errs = int(match.group(5)), 112 rx_seq_errs = int(match.group(6)), 113 underruns = int(match.group(7)), 114 late_cmds = int(match.group(8)), 115 tx_timeouts = int(match.group(9)), 116 rx_timeouts = int(match.group(10)) 117 ) 118 else: 119 return None 120 121def write_benchmark_rate_csv(results, file_name): 122 with open(file_name, 'w', newline='') as f: 123 w = csv.writer(f) 124 w.writerow(results[0]._fields) 125 w.writerows(results) 126 127if __name__ == "__main__": 128 result_str = """ 129 [00:00:00.000376] Creating the usrp device with: addr=192.168.30.2, second_addr=192.168.40.2... 130 [00:00:05.63100253] Testing receive rate 200.000000 Msps on 2 channels 131 [00:00:05.73100253] Testing transmit rate 100.000000 Msps on 1 channels 132 [00:00:15.113339078] Benchmark complete. 133 134 Benchmark rate summary: 135 Num received samples: 10000 136 Num dropped samples: 200 137 Num overruns detected: 10 138 Num transmitted samples: 20000 139 Num sequence errors (Tx): 5 140 Num sequence errors (Rx): 6 141 Num underruns detected: 20 142 Num late commands: 2 143 Num timeouts (Tx): 0 144 Num timeouts (Rx): 100 145 146 Done! 147 """ 148 print("Parsing hardcoded string for testing only") 149 print(parse(result_str)) 150