aboutsummaryrefslogtreecommitdiffstats
path: root/host/tests/streaming_performance/parse_benchmark_rate.py
blob: e30c3e6aaef35188b3f09d14824b502e9514ee81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"""
Copyright 2019 Ettus Research, A National Instrument Brand

SPDX-License-Identifier: GPL-3.0-or-later

Helper script that parses the results of benchmark_rate and extracts numeric
values printed at the end of execution.
"""

import collections
import re
import csv

Results = collections.namedtuple(
    'Results',
    """
    num_rx_channels
    num_tx_channels
    rx_rate
    tx_rate
    received_samps
    dropped_samps
    overruns
    transmitted_samps
    tx_seq_errs
    rx_seq_errs
    underruns
    late_cmds
    tx_timeouts
    rx_timeouts
    """
)

def average(results):
    """
    Returns the average of a list of results.
    """
    results_as_lists = [list(r) for r in results]
    avg_vals = [sum(x)/len(results) for x in zip(*results_as_lists)]
    return Results(*avg_vals)

def min_vals(results):
    """
    Returns the minimum values of a list of results.
    """
    results_as_lists = [list(r) for r in results]
    min_vals = [min(x) for x in zip(*results_as_lists)]
    return Results(*min_vals)

def max_vals(results):
    """
    Returns the maximum values of a list of results.
    """
    results_as_lists = [list(r) for r in results]
    max_vals = [max(x) for x in zip(*results_as_lists)]
    return Results(*max_vals)

def non_zero_vals(results):
    """
    Returns the number of non-zero values from a list of results.
    """
    results_as_lists = [list(r) for r in results]
    results_as_lists = [[1 if x > 0 else 0 for x in y] for y in results_as_lists]
    non_zero_vals = [sum(x) for x in zip(*results_as_lists)]
    return Results(*non_zero_vals)

def parse(result_str):
    """
    Parses benchmark results and returns numerical values.
    """
    # Parse rx rate
    rx_rate = 0.0
    num_rx_channels = 0
    expr = "Testing receive rate ([0-9]+\.[0-9]+) Msps on (\d+) channels"
    match = re.search(expr, result_str)
    if match is not None:
        rx_rate = float(match.group(1)) * 1.0e6
        num_rx_channels = int(match.group(2))

    tx_rate = 0.0
    num_tx_channels = 0
    expr = "Testing transmit rate ([0-9]+\.[0-9]+) Msps on (\d+) channels"
    match = re.search(expr, result_str)
    if match is not None:
        tx_rate = float(match.group(1)) * 1.0e6
        num_tx_channels = int(match.group(2))

    # Parse results
    expr = "Benchmark rate summary:"
    expr += r"\s*Num received samples:\s*(\d+)"
    expr += r"\s*Num dropped samples:\s*(\d+)"
    expr += r"\s*Num overruns detected:\s*(\d+)"
    expr += r"\s*Num transmitted samples:\s*(\d+)"
    expr += r"\s*Num sequence errors \(Tx\):\s*(\d+)"
    expr += r"\s*Num sequence errors \(Rx\):\s*(\d+)"
    expr += r"\s*Num underruns detected:\s*(\d+)"
    expr += r"\s*Num late commands:\s*(\d+)"
    expr += r"\s*Num timeouts \(Tx\):\s*(\d+)"
    expr += r"\s*Num timeouts \(Rx\):\s*(\d+)"
    match = re.search(expr, result_str)
    if match:
        return Results(
            num_rx_channels   = num_rx_channels,
            num_tx_channels   = num_tx_channels,
            rx_rate           = rx_rate,
            tx_rate           = tx_rate,
            received_samps    = int(match.group(1)),
            dropped_samps     = int(match.group(2)),
            overruns          = int(match.group(3)),
            transmitted_samps = int(match.group(4)),
            tx_seq_errs       = int(match.group(5)),
            rx_seq_errs       = int(match.group(6)),
            underruns         = int(match.group(7)),
            late_cmds         = int(match.group(8)),
            tx_timeouts       = int(match.group(9)),
            rx_timeouts       = int(match.group(10))
        )
    else:
        return None

def write_benchmark_rate_csv(results, file_name):
    with open(file_name, 'w', newline='') as f:
        w = csv.writer(f)
        w.writerow(results[0]._fields)
        w.writerows(results)

if __name__ == "__main__":
    result_str = """
    [00:00:00.000376] Creating the usrp device with: addr=192.168.30.2, second_addr=192.168.40.2...
    [00:00:05.63100253] Testing receive rate 200.000000 Msps on 2 channels
    [00:00:05.73100253] Testing transmit rate 100.000000 Msps on 1 channels
    [00:00:15.113339078] Benchmark complete.

    Benchmark rate summary:
    Num received samples:     10000
    Num dropped samples:      200
    Num overruns detected:    10
    Num transmitted samples:  20000
    Num sequence errors (Tx): 5
    Num sequence errors (Rx): 6
    Num underruns detected:   20
    Num late commands:        2
    Num timeouts (Tx):        0
    Num timeouts (Rx):        100

    Done!
    """
    print("Parsing hardcoded string for testing only")
    print(parse(result_str))