def main(log_dir: pathlib.Path):
    (log_dir / "graphs").mkdir(parents=True, exist_ok=True)

    results = parse_cr(log_dir)

    XYs = {
        hostname: [(cr.response.iterations, cr.response.duration)
                   for cr in result.challenge_responses]
        for (hostname, result) in results.items()
    }

    iterations = [
        cr.response.iterations for (hostname, result) in results.items()
        for cr in result.challenge_responses
    ]
    durations = [
        cr.response.duration for (hostname, result) in results.items()
        for cr in result.challenge_responses
    ]
    print_mean_ci("iterations", iterations)
    print_mean_ci("durations", durations)

    fig = plt.figure()
    ax = fig.gca()

    for (hostname, XY) in sorted(XYs.items(), key=lambda x: x[0]):
        X, Y = zip(*XY)
        ax.scatter(X, Y, label=hostname)

    ax.set_xlabel('Iterations')
    ax.set_ylabel('Time Taken (secs)')

    ax.legend()

    savefig(fig, log_dir / "graphs" / "cr_iterations_vs_timetaken.pdf")

    fig = plt.figure()
    ax = fig.gca()

    Xs = []
    labels = []

    for (hostname, XY) in sorted(XYs.items(), key=lambda x: x[0]):
        X, Y = zip(*XY)
        Xs.append(X)
        labels.append(hostname)

    ax.boxplot(Xs)
    ax.set_xticklabels(labels)

    ax.set_xlabel('Resource Rich Nodes')
    ax.set_ylabel('Iterations')

    savefig(fig, log_dir / "graphs" / "cr_iterations_boxplot.pdf")
예제 #2
0
def main(log_dir: pathlib.Path, tx_ymax: Optional[float],
         rx_ymax: Optional[float]):
    (log_dir / "graphs").mkdir(parents=True, exist_ok=True)

    results = parse(log_dir, quiet=True)

    XYs_tx = {
        hostname: [(name, [
            datetime.fromtimestamp(float(value.sniff_timestamp))
            for value in values
        ], [packet_length(value) for value in values])
                   for (name, values) in result.tx.items()]
        for (hostname, result) in results.items()
    }

    XYs_rx = {
        hostname: [(name, [
            datetime.fromtimestamp(float(value.sniff_timestamp))
            for value in values
        ], [packet_length(value) for value in values])
                   for (name, values) in result.rx.items()]
        for (hostname, result) in results.items()
    }

    to_graph = {
        ("tx", tx_ymax): XYs_tx,
        ("rx", rx_ymax): XYs_rx,
    }

    bin_width = timedelta(minutes=6)

    min_time = min(r.min_snift_time for r in results.values())
    max_time = min(r.max_snift_time for r in results.values())

    min_time = datetime.fromtimestamp(min_time)
    max_time = datetime.fromtimestamp(max_time)

    bins = [min_time]
    while bins[-1] + bin_width < max_time:
        bins.append(bins[-1] + bin_width)
    bins.append(max_time)

    # Make the colors the same between rx and tx graphs
    kinds1 = {
        name
        for nvs in XYs_tx.values() for (name, times, lengths) in nvs
    }
    kinds2 = {
        name
        for nvs in XYs_rx.values() for (name, times, lengths) in nvs
    }

    kinds = kinds1 | kinds2

    ckind = {
        kind: plt.cm.get_cmap('tab20')(i)
        for i, kind in enumerate(sorted(kinds))
    }

    for ((name, ymax), XYs) in to_graph.items():

        for (hostname, metric_values) in XYs.items():

            fig = plt.figure()
            ax = fig.gca()

            labels, values, weights = zip(
                *sorted(metric_values, key=lambda x: x[0]))

            colors = [ckind[label] for label in labels]

            ax.hist(values,
                    bins=bins,
                    histtype='bar',
                    stacked=True,
                    label=labels,
                    weights=weights,
                    color=colors,
                    rwidth=1)

            ax.set_xlabel('Time')
            ax.set_ylabel(
                f'Message Length (bytes) {"Sent" if name == "tx" else "Received"} During Window'
            )

            ax.set_ylim(0, ymax)

            ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

            ax.legend(ncol=3,
                      loc="center",
                      fontsize="small",
                      bbox_to_anchor=(0.5, 1.125))

            savefig(fig, log_dir / "graphs" / f"{name}-by-type-{hostname}.pdf")

    # Table of the percentage of bytes in each category
    hostnames = sorted(set(XYs_tx.keys()) | set(XYs_rx.keys()))

    for hostname in hostnames:
        #print(hostname)

        log_file = log_dir / "graphs" / f"{hostname}-messages.tex"

        with open(log_file, "w") as f:
            print("\\begin{table}[t]", file=f)
            print("\\centering", file=f)
            print(
                "\\begin{tabular}{l S[table-format=6] S[table-format=3.1] S[table-format=6] S[table-format=3.1]}",
                file=f)
            print("    \\toprule", file=f)
            print(
                "    ~ & \\multicolumn{2}{c}{Tx} & \\multicolumn{2}{c}{Rx} \\\\",
                file=f)
            print(
                "    Category & {(\\si{\\byte})} & {(\\%)} & {(\\si{\\byte})} & {(\\%)} \\\\",
                file=f)
            print("    \\midrule", file=f)

            XY_tx = XYs_tx.get(hostname, [])
            XY_rx = XYs_rx.get(hostname, [])

            XY_tx = {name: sum(lengths) for (name, dates, lengths) in XY_tx}
            total_tx = sum(XY_tx.values())

            XY_rx = {name: sum(lengths) for (name, dates, lengths) in XY_rx}
            total_rx = sum(XY_rx.values())

            names = sorted(set(XY_tx.keys()) | set(XY_rx.keys()))

            for name in names:
                print(
                    f"{name} & {XY_tx.get(name, 0)} & {round(100*XY_tx.get(name, 0)/total_tx,1)} & {XY_rx.get(name, 0)} & {round(100*XY_rx.get(name, 0)/total_rx,1)} \\\\",
                    file=f)
            print("\\midrule", file=f)
            print(f"Total & {total_tx} & 100 & {total_rx} & 100 \\\\", file=f)

            print("\\bottomrule", file=f)
            print("\\end{tabular}", file=f)
            print(f"\\caption{{Message tx and rx for {hostname}}}", file=f)
            #print("\\label{tab:ram-flash-usage}", file=f)
            print("\\end{table}", file=f)
def main(log_dir: pathlib.Path,
         throw_on_error: bool = True,
         with_error_bars: bool = False):
    (log_dir / "graphs").mkdir(parents=True, exist_ok=True)

    results = parse(log_dir, throw_on_error=throw_on_error)

    capabilities = {
        value.cr.capability
        for result in results.values() for value in result.throughput_updates
    }

    targets = {
        value.edge_id
        for result in results.values() for value in result.throughput_updates
    }

    CXYs = {(capability, direction):
            {(hostname, target): [(value.time, value.cr.throughput)
                                  for value in result.throughput_updates
                                  if value.edge_id == target
                                  if value.cr.capability == capability
                                  if value.cr.direction == direction]
             for (hostname, result) in results.items() for target in targets}
            for capability in capabilities
            for direction in ThroughputDirection}

    # TODO: Draw some bar graphs of which nodes tasks were submitted to

    for ((capability, direction), XYs) in CXYs.items():
        fig = plt.figure()
        ax = fig.gca()

        for (label, XY) in sorted(XYs.items(), key=lambda x: x[0]):
            hostname, target = label

            if not XY:
                print(f"Skipping {label}")
                continue

            X, Y = zip(*XY)
            ax.plot(
                X,
                Y,
                label=
                f"{hostname_to_name(hostname)} eval {eui64_to_name(target)} dir {direction}"
            )

        ax.set_xlabel('Time')
        ax.set_ylabel('Throughput (bytes/sec)')

        ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

        ax.legend(ncol=3,
                  fontsize="small",
                  loc="center",
                  bbox_to_anchor=(0.5, 1.075))

        savefig(
            fig,
            f"{log_dir}/graphs/throughput_vs_time_{capability}_{direction}.pdf"
        )

    CXYs = {(capability, direction):
            {(hostname, target): [(value.time, value.tm_to.mean.mean,
                                   math.sqrt(value.tm_to.mean.var))
                                  for value in result.throughput_updates
                                  if value.edge_id == target
                                  if value.cr.capability == capability
                                  if value.cr.direction == direction]
             for (hostname, result) in results.items() for target in targets}
            for capability in capabilities
            for direction in ThroughputDirection}

    # TODO: Draw some bar graphs of which nodes tasks were submitted to

    for ((capability, direction), XYs) in CXYs.items():
        fig = plt.figure()
        ax = fig.gca()

        for (label, XY) in sorted(XYs.items(), key=lambda x: x[0]):
            hostname, target = label

            if not XY:
                print(f"Skipping {label}")
                continue

            X, Y, E = zip(*XY)

            if with_error_bars:
                ax.errorbar(
                    X,
                    Y,
                    yerr=E,
                    label=
                    f"{hostname_to_name(hostname)} eval {eui64_to_name(target)} dir {direction}"
                )
            else:
                ax.plot(
                    X,
                    Y,
                    label=
                    f"{hostname_to_name(hostname)} eval {eui64_to_name(target)} dir {direction}"
                )

        ax.set_xlabel('Time')
        ax.set_ylabel('Throughput (bytes/sec)')

        ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

        ax.legend(ncol=3,
                  fontsize="small",
                  loc="center",
                  bbox_to_anchor=(0.5, 1.075))

        savefig(
            fig,
            f"{log_dir}/graphs/ave_throughput_vs_time_{capability}_{direction}.pdf"
        )

    CXYs = {(capability, direction):
            {(hostname, target): [(value.time, value.tm_to.ewma.mean,
                                   math.sqrt(value.tm_to.ewma.var))
                                  for value in result.throughput_updates
                                  if value.edge_id == target
                                  if value.cr.capability == capability
                                  if value.cr.direction == direction]
             for (hostname, result) in results.items() for target in targets}
            for capability in capabilities
            for direction in ThroughputDirection}

    # TODO: Draw some bar graphs of which nodes tasks were submitted to

    for ((capability, direction), XYs) in CXYs.items():
        fig = plt.figure()
        ax = fig.gca()

        for (label, XY) in sorted(XYs.items(), key=lambda x: x[0]):
            hostname, target = label

            if not XY:
                print(f"Skipping {label}")
                continue

            X, Y, E = zip(*XY)

            if with_error_bars:
                ax.errorbar(
                    X,
                    Y,
                    yerr=E,
                    label=
                    f"{hostname_to_name(hostname)} eval {eui64_to_name(target)} dir {direction}"
                )
            else:
                ax.plot(
                    X,
                    Y,
                    label=
                    f"{hostname_to_name(hostname)} eval {eui64_to_name(target)} dir {direction}"
                )

        ax.set_xlabel('Time')
        ax.set_ylabel('Throughput (bytes/sec)')

        ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

        ax.legend(ncol=3,
                  fontsize="small",
                  loc="center",
                  bbox_to_anchor=(0.5, 1.075))

        savefig(
            fig,
            f"{log_dir}/graphs/ewma_throughput_vs_time_{capability}_{direction}.pdf"
        )
def main(log_dir: pathlib.Path):
    (log_dir / "graphs").mkdir(parents=True, exist_ok=True)

    results = parse_cr(log_dir)

    edge_labels = {
        up.edge_id
        for result in results.values() for up in result.tm_updates
    }

    # Show how the epoch changes over time
    XYs = {(hostname, eui64_to_name(edge_label)): [(up.time, up.tm_to.epoch)
                                                   for up in result.tm_updates
                                                   if up.edge_id == edge_label]
           for (hostname, result) in results.items()
           for edge_label in edge_labels}

    fig = plt.figure()
    ax = fig.gca()

    for (hostname, XY) in sorted(XYs.items(), key=lambda x: x[0]):
        X, Y = zip(*XY)
        ax.step(X, Y, label=f"{hostname[0]} evaluating {hostname[1]}")

    ax.set_xlabel('Time')
    ax.set_ylabel('Epoch Number')

    ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

    ax.legend()

    savefig(fig, log_dir / "graphs" / "cr_time_vs_epoch.pdf")

    # Show when the edge nodes were thought to be good or not
    event_types = {(hostname, eui64_to_name(edge_label)):
                   [(up.time, not up.tm_to.bad) for up in result.tm_updates
                    if up.edge_id == edge_label]
                   for (hostname, result) in results.items()
                   for edge_label in edge_labels}

    event_cause = {(hostname, eui64_to_name(edge_label)):
                   [(up.time, up.cr.kind) for up in result.tm_updates
                    if up.edge_id == edge_label if not up.cr.good
                    if up.tm_to.bad]
                   for (hostname, result) in results.items()
                   for edge_label in edge_labels}

    #pprint(event_cause)

    fig = plt.figure()
    ax = fig.gca()

    y = 0
    yticks = []
    ytick_labels = []

    cxs = defaultdict(list)
    cys = defaultdict(list)

    for (hostname, XY) in sorted(event_types.items(), key=lambda x: x[0]):
        true_list, false_list = squash_true_false_seq(XY)

        ax.broken_barh(true_list, (y, 0.9), color="lightgreen")
        ax.broken_barh(false_list, (y, 0.9), color="grey")

        # Record the causes of these changes
        causes = event_cause[hostname]
        for (ctime, cevent) in causes:
            cxs[cevent].append(ctime)
            cys[cevent].append(y + 0.45)

        yticks.append(y)
        ytick_labels.append(f"{hostname[0]}\neval {hostname[1]}")
        y += 1

    for cevent in sorted(cxs):
        (shape, colour) = ChallengeResponseType_to_shape_and_color(cevent)

        ax.scatter(cxs[cevent],
                   cys[cevent],
                   label=latex_escape(cevent),
                   c=colour,
                   marker=shape)

    ax.set_yticks([x + 0.45 for x in yticks])
    ax.set_yticklabels(ytick_labels)

    ax.set_xlabel('Time')
    ax.set_ylabel('Status')

    ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

    ax.legend()

    savefig(fig, log_dir / "graphs" / "cr_time_vs_good.pdf")
def main(log_dir: pathlib.Path):
    (log_dir / "graphs").mkdir(parents=True, exist_ok=True)

    results = parse_cr(log_dir)
    pyterm_results = parse_pyterm(log_dir)

    print([r.behaviour_changes for r in results.values()])

    if all(len(r.behaviour_changes) == 0 for r in results.values()):
        print("This graph type does not make sense for this result")
        return

    earliest = min(t for r in results.values()
                   for (t, v) in r.behaviour_changes)
    latest = max(t for r in results.values() for (t, v) in r.behaviour_changes)

    # Find the latest time a task was submitted
    # Some times we might not have much behaviour changing to go on
    latest_task = max(t.time for r in pyterm_results.values() for t in r.tasks)

    latest = max(latest, latest_task)

    # Stacked bar graph showing how many tasks were offloaded to each node
    # over the time periods in which no changes occur

    # Create a graph showing when tasks where offloaded to nodes and that node was bad

    # Need to create some data ranges for well-behaved nodes, as they don't say when they are being bad
    event_types = {
        hostname_to_name(hostname):
        result.behaviour_changes + [(latest, result.behaviour_changes[-1][1])]
        if result.behaviour_changes else [(earliest, True), (latest, True)]
        for (hostname, result) in results.items()
    }

    # Calculate bins, need to include left edge of first bin and right edge of last bin
    bins = [t for (t, v) in event_types['rr6']]

    targets = {
        task.target
        for result in pyterm_results.values() for task in result.tasks
    }

    data = {
        target: [
            task.time for result in pyterm_results.values()
            for task in result.tasks if task.target == target
        ]
        for target in targets
    }

    fig = plt.figure()
    ax = fig.gca()

    y = 0
    yticks = []
    ytick_labels = []

    for (hostname, XY) in sorted(event_types.items(), key=lambda x: x[0]):
        true_list, false_list = squash_true_false_seq(XY)

        ax.broken_barh(true_list, (y, 0.9), color="lightgreen")
        ax.broken_barh(false_list, (y, 0.9), color="grey")

        yticks.append(y)
        ytick_labels.append(f"{hostname}")
        y += 1

    ax2 = ax.twinx()
    hlabels, hdata = zip(*list(sorted(data.items(), key=lambda x: x[0])))
    hlabels = [ip_to_name(l) for l in hlabels]
    ax2.hist(hdata,
             bins,
             stacked=True,
             histtype='bar',
             label=hlabels,
             rwidth=0.4)

    ax.set_yticks([x + 0.45 for x in yticks])
    ax.set_yticklabels(ytick_labels)

    ax.set_xlabel('Time')
    ax.set_ylabel('Status')

    ax2.set_ylabel("Number of tasks submitted")

    ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

    ax2.legend()

    savefig(fig, log_dir / "graphs" / "cr_offload_vs_behaviour.pdf")
예제 #6
0
def main(log_dir: pathlib.Path):
    (log_dir / "graphs").mkdir(parents=True, exist_ok=True)

    results = parse_cr(log_dir)
    pyterm_results = parse_pyterm(log_dir)

    print([r.behaviour_changes for r in results.values()])

    earliest = min(t for r in results.values() for (t, v) in r.behaviour_changes)
    latest = max(t for r in results.values() for (t, v) in r.behaviour_changes)

    # Find the latest time a task was submitted
    # Some times we might not have much behaviour changing to go on
    latest_task = max(t.time for r in pyterm_results.values() for t in r.tasks)

    latest = max(latest, latest_task)

    # Create a graph showing when tasks where offloaded to nodes and that node was bad

    # Need to create some data ranges for well-behaved nodes, as they don't say when they are being bad
    actual = {
        hostname_to_name(hostname): result.behaviour_changes + [(latest, result.behaviour_changes[-1][1])] if result.behaviour_changes else [(earliest, True), (latest, True)]
        for (hostname, result) in results.items()
    }

    edge_labels = {up.edge_id for result in pyterm_results.values() for up in result.tm_updates}
    belived = {
        (hostname, eui64_to_name(edge_label)): [
            (up.time, not up.tm_to.bad)
            for up in result.tm_updates
            if up.edge_id == edge_label
        ]
        for (hostname, result) in pyterm_results.items()
        for edge_label in edge_labels
    }

    # Translate believed into whether the belief was correct or not
    correct = {
        (wsn, edge): belief_correct(results, actual[edge])
        for ((wsn, edge), results) in belived.items()
    }

    targets = {task.target for result in pyterm_results.values() for task in result.tasks}

    data = {
        target: [
            task.time
            for result in pyterm_results.values()
            for task in result.tasks
            if task.target == target
        ]
        for target in targets
    }

    fig = plt.figure()
    ax = fig.gca()

    y = 0
    yticks = []
    ytick_labels = []

    legend = True

    x = plt.cm.get_cmap('tab10')

    # new tab10
    """tp_colour = "#59a14f"
    tn_colour = "#4e79a7"
    fp_colour = "#b07aa1"
    fn_colour = "#9c755f"
    u_colour = "#bab0ac"""

    tp_colour = x(2)
    tn_colour = x(0)
    fp_colour = x(4)
    fn_colour = x(5)
    u_colour = x(7)

    summaries = {}

    for (hostname, XY) in sorted(correct.items(), key=lambda x: x[0]):
        result = squash_generic_seq(XY, ("TP", "TN", "FP", "FN", None))

        summary = {k: sum(v[1].total_seconds() for v in vv) for (k, vv) in result.items() if k is not None}
        summary_total = sum(summary.values())
        summary_pc = {k: round(v/summary_total, 2) for (k, v) in summary.items()}
        print(hostname, summary_pc)

        summaries[hostname] = f"\\ConfusionMatrix{{{summary_pc['TP']}}}{{{summary_pc['TN']}}}{{{summary_pc['FP']}}}{{{summary_pc['FN']}}}"

        ax.broken_barh(result["TP"], (y,0.9), color=tp_colour, label="TP" if legend else None)
        ax.broken_barh(result["TN"], (y,0.9), color=tn_colour, label="TN" if legend else None)
        ax.broken_barh(result["FP"], (y,0.9), color=fp_colour, label="FP" if legend else None)
        ax.broken_barh(result["FN"], (y,0.9), color=fn_colour, label="FN" if legend else None)
        #ax.broken_barh(result[None], (y,0.9), color=u_colour, label="U" if legend else None)

        yticks.append(y)
        ytick_labels.append(f"{hostname[0]}\\newline eval {hostname[1]}")
        y += 1

        legend = False

    ax.set_yticks([x+0.45 for x in yticks])
    ax.set_yticklabels(ytick_labels)

    ax.set_xlabel('Time')
    ax.set_ylabel('Status')

    ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

    ax.legend()

    savefig(fig, log_dir / "graphs" / "cr_correctly_evaluated.pdf")


    print("\\begin{table}[H]")
    wsns = list(sorted({k[0] for k in summaries.keys()}))
    rrs = list(sorted({k[1] for k in summaries.keys()}))

    print("\\centering")
    print("\\begin{tabular}{l c c c}")

    print(" & ".join(['~'] + wsns) + "\\\\")

    for rr in rrs:
        print(rr)
        for wsn in wsns:
            summary = summaries[(wsn, rr)]

            print("&", summary)
        print("\\\\")

    print("\\end{tabular}")
    print("\\end{table}")
def main(log_dir: pathlib.Path, ax2_ymax: float, throw_on_error: bool = True):
    (log_dir / "graphs").mkdir(parents=True, exist_ok=True)

    results = parse(log_dir, throw_on_error=throw_on_error)

    capabilities = {
        value.capability
        for result in results.values() for value in result.trust_choose.values
    }

    targets = {
        value.target
        for result in results.values() for value in result.trust_choose.values
    }

    CXYs = {
        capability:
        {(hostname, target): [(value.time, value.value)
                              for value in result.trust_choose.values
                              if value.target == target
                              if value.capability == capability]
         for (hostname, result) in results.items() for target in targets}
        for capability in capabilities
    }

    CHs = {
        capability: {(f"{hostname} eval {eui64_to_name(target)}"): [
            task.time for task in result.tasks
            if isinstance(task.details, capability_to_task[capability])
            if ip_to_name(task.target) == eui64_to_name(target)
        ]
                     for (hostname, result) in results.items()
                     for target in targets}
        for capability in capabilities
    }

    # TODO: Draw some bar graphs of which nodes tasks were submitted to

    for (capability, XYs) in CXYs.items():
        fig = plt.figure()
        ax = fig.gca()

        Hs = CHs[capability]

        print(capability)
        pprint(Hs)

        labels, hs = zip(*list(sorted(Hs.items(), key=lambda x: x[0])))

        ax2 = ax.twinx()
        ax2.hist(hs, bins=None, histtype='bar', label=labels, rwidth=0.6)

        for (label, XY) in sorted(XYs.items(), key=lambda x: x[0]):
            hostname, target = label

            X, Y = zip(*XY)
            ax.plot(X, Y, label=f"{hostname} eval {eui64_to_name(target)}")

        ax.set_xlabel('Time')
        ax.set_ylabel('Trust Value (lines)')
        ax2.set_ylabel('Number of tasks submitted (bars)')

        ax.set_ylim(0, 1)
        ax2.set_ylim(0, ax2_ymax)

        ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

        ax.legend(ncol=3,
                  fontsize="small",
                  loc="center",
                  bbox_to_anchor=(0.5, 1.075))

        savefig(
            fig,
            f"{log_dir}/graphs/banded_trust_value_vs_time_{capability}.pdf")
def main(log_dir: pathlib.Path, throw_on_error: bool = True):
    (log_dir / "graphs").mkdir(parents=True, exist_ok=True)

    results = parse(log_dir, throw_on_error=throw_on_error)

    targets = {
        value.edge_id
        for result in results.values() for value in result.tm_updates
        if isinstance(value.cr, LastPing)
    }

    XYs = {(hostname, target):
           [(value.time, value.tm_to.ping - value.tm_from.ping)
            for value in result.tm_updates if isinstance(value.cr, LastPing)
            if value.edge_id == target]
           for (hostname, result) in results.items() for target in targets}

    fig = plt.figure()
    ax = fig.gca()

    for (label, XY) in sorted(XYs.items(), key=lambda x: x[0]):
        hostname, target = label

        if not XY:
            print(f"Skipping {label}")
            continue

        X, Y = zip(*XY)
        ax.plot(
            X,
            Y,
            label=f"{hostname_to_name(hostname)} eval {eui64_to_name(target)}")

    ax.set_xlabel('Time')
    ax.set_ylabel('Time between pings (ms)')

    ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))

    ax.legend(ncol=3,
              fontsize="small",
              loc="center",
              bbox_to_anchor=(0.5, 1.075))

    savefig(fig, f"{log_dir}/graphs/time_between_pings.pdf")

    fig = plt.figure()
    ax = fig.gca()

    Xs = []
    labels = []

    for (label, XY) in sorted(XYs.items(), key=lambda x: x[0]):
        hostname, target = label

        if not XY:
            print(f"Skipping {label}")
            continue

        _, Y = zip(*XY)

        Xs.append(Y)
        labels.append(
            f"{hostname_to_name(hostname)} eval {eui64_to_name(target)}")

    ax.hist(Xs, stacked=True)

    ax.set_xlabel('Time between pings (ms)')
    ax.set_ylabel('Count')

    savefig(fig, f"{log_dir}/graphs/time_between_pings_hist.pdf")

    fig = plt.figure()
    ax = fig.gca()

    Xs = []
    labels = []

    for (label, XY) in sorted(XYs.items(), key=lambda x: x[0]):
        hostname, target = label

        if not XY:
            print(f"Skipping {label}")
            continue

        _, Y = zip(*XY)

        Xs.append(Y)
        labels.append(
            f"{hostname_to_name(hostname)} eval {eui64_to_name(target)}")

    ax.boxplot(Xs, labels=labels)

    ax.set_xlabel('Target')
    ax.set_ylabel('Time between pings (ms)')

    ax.set_xticklabels(labels, rotation=45)

    savefig(fig, f"{log_dir}/graphs/time_between_pings_boxplot.pdf")
예제 #9
0
def main(log_dir: pathlib.Path):
    (log_dir / "graphs").mkdir(parents=True, exist_ok=True)

    results = profile_pyterm(log_dir)

    XYs = {
        hostname: [(cr.length, cr.seconds) for cr in result.stats_sha256]
        for (hostname, result) in results.items()
    }

    fig = plt.figure()
    ax = fig.gca()

    for (hostname, XY) in sorted(XYs.items(), key=lambda x: x[0]):
        X, Y = zip(*XY)
        ax.scatter(X, Y, label=hostname)

    ax.set_xlabel('Message Length')
    ax.set_ylabel('Time Taken (secs)')

    ax.legend()

    savefig(fig, log_dir / "graphs" / "crypto_perf_sha256_scatter.pdf")

    fig = plt.figure()
    ax = fig.gca()

    Ys = []
    labels = []

    for (hostname, result) in sorted(XYs.items(), key=lambda x: x[0]):
        X, Y = zip(*XY)
        Ys.append(Y)
        labels.append(hostname)

    ax.boxplot(Ys)
    ax.set_xticklabels(labels)

    ax.set_xlabel('Resource Rich Nodes')
    ax.set_ylabel('Time Taken (secs)')

    savefig(fig, log_dir / "graphs" / "crypto_perf_sha256_box.pdf")

    def round_down(x: float, a: float) -> float:
        return math.floor(x / a) * a

    def round_up(x: float, a: float) -> float:
        return math.ceil(x / a) * a

    names = {
        "stats_sha256_u": 1e-5,
        "stats_sha256_n": 1e-7,
        "stats_ecdh": 1e-3,
        "stats_sign": 1e-3,
        "stats_verify": 1e-3,
        "stats_encrypt_u": 1e-3,
        "stats_encrypt_n": 1e-3,
        "stats_decrypt_u": 1e-3,
        "stats_decrypt_n": 1e-3,
    }

    for (name, bin_width) in names.items():
        fig = plt.figure()
        ax = fig.gca()

        labels = []
        hs = []

        hmin, hmax = float("+inf"), float("-inf")

        for (hostname, result) in sorted(results.items(), key=lambda x: x[0]):
            labels.append(hostname)

            h = getattr(result, name)

            hs.append(h)

            hmin = min(hmin, min(h))
            hmax = max(hmax, max(h))

        hmin = round_down(hmin, bin_width)
        hmax = round_up(hmax, bin_width)

        bins = np.arange(hmin, hmax, bin_width)

        ax.hist(hs, bins=bins, stacked=True, label=labels)

        if name == "stats_sha256_n":
            ax.set_xlim(0, 2e-6)

        ax.legend()
        ax.set_xlabel('Time Taken (secs)')
        ax.set_ylabel('Count')

        savefig(fig, log_dir / "graphs" / f"crypto_perf_{name}_hist.pdf")