113540Sandrea.mondelli@ucf.edu#!/usr/bin/env python2.7
212269Sradhika.jagtap@arm.com
312269Sradhika.jagtap@arm.com# Copyright (c) 2015 ARM Limited
412269Sradhika.jagtap@arm.com# All rights reserved
512269Sradhika.jagtap@arm.com#
612269Sradhika.jagtap@arm.com# The license below extends only to copyright in the software and shall
712269Sradhika.jagtap@arm.com# not be construed as granting a license to any other intellectual
812269Sradhika.jagtap@arm.com# property including but not limited to intellectual property relating
912269Sradhika.jagtap@arm.com# to a hardware implementation of the functionality of the software
1012269Sradhika.jagtap@arm.com# licensed hereunder.  You may use the software subject to the license
1112269Sradhika.jagtap@arm.com# terms below provided that you ensure that this notice is replicated
1212269Sradhika.jagtap@arm.com# unmodified and in its entirety in all distributions of the software,
1312269Sradhika.jagtap@arm.com# modified or unmodified, in source code or in binary form.
1412269Sradhika.jagtap@arm.com#
1512269Sradhika.jagtap@arm.com# Redistribution and use in source and binary forms, with or without
1612269Sradhika.jagtap@arm.com# modification, are permitted provided that the following conditions are
1712269Sradhika.jagtap@arm.com# met: redistributions of source code must retain the above copyright
1812269Sradhika.jagtap@arm.com# notice, this list of conditions and the following disclaimer;
1912269Sradhika.jagtap@arm.com# redistributions in binary form must reproduce the above copyright
2012269Sradhika.jagtap@arm.com# notice, this list of conditions and the following disclaimer in the
2112269Sradhika.jagtap@arm.com# documentation and/or other materials provided with the distribution;
2212269Sradhika.jagtap@arm.com# neither the name of the copyright holders nor the names of its
2312269Sradhika.jagtap@arm.com# contributors may be used to endorse or promote products derived from
2412269Sradhika.jagtap@arm.com# this software without specific prior written permission.
2512269Sradhika.jagtap@arm.com#
2612269Sradhika.jagtap@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2712269Sradhika.jagtap@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2812269Sradhika.jagtap@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2912269Sradhika.jagtap@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3012269Sradhika.jagtap@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3112269Sradhika.jagtap@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3212269Sradhika.jagtap@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3312269Sradhika.jagtap@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3412269Sradhika.jagtap@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3512269Sradhika.jagtap@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3612269Sradhika.jagtap@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3712269Sradhika.jagtap@arm.com#
3812269Sradhika.jagtap@arm.com# Authors: Andreas Hansson
3912269Sradhika.jagtap@arm.com
4012269Sradhika.jagtap@arm.comtry:
4112269Sradhika.jagtap@arm.com    import matplotlib.pyplot as plt
4212269Sradhika.jagtap@arm.com    import matplotlib as mpl
4312269Sradhika.jagtap@arm.com    import numpy as np
4412269Sradhika.jagtap@arm.comexcept ImportError:
4512269Sradhika.jagtap@arm.com    print "Failed to import matplotlib and numpy"
4612269Sradhika.jagtap@arm.com    exit(-1)
4712269Sradhika.jagtap@arm.com
4812269Sradhika.jagtap@arm.comimport sys
4912269Sradhika.jagtap@arm.comimport re
5012269Sradhika.jagtap@arm.com
5112269Sradhika.jagtap@arm.com# This script is intended to post process and plot the output from
5212269Sradhika.jagtap@arm.com# running configs/dram/lat_mem_rd.py, as such it parses the simout and
5312269Sradhika.jagtap@arm.com# stats.txt to get the relevant data points.
5412269Sradhika.jagtap@arm.comdef main():
5512269Sradhika.jagtap@arm.com
5612269Sradhika.jagtap@arm.com    if len(sys.argv) != 2:
5712269Sradhika.jagtap@arm.com        print "Usage: ", sys.argv[0], "<simout directory>"
5812269Sradhika.jagtap@arm.com        exit(-1)
5912269Sradhika.jagtap@arm.com
6012269Sradhika.jagtap@arm.com    try:
6112269Sradhika.jagtap@arm.com        stats = open(sys.argv[1] + '/stats.txt', 'r')
6212269Sradhika.jagtap@arm.com    except IOError:
6312269Sradhika.jagtap@arm.com        print "Failed to open ", sys.argv[1] + '/stats.txt', " for reading"
6412269Sradhika.jagtap@arm.com        exit(-1)
6512269Sradhika.jagtap@arm.com
6612269Sradhika.jagtap@arm.com    try:
6712269Sradhika.jagtap@arm.com        simout = open(sys.argv[1] + '/simout', 'r')
6812269Sradhika.jagtap@arm.com    except IOError:
6912269Sradhika.jagtap@arm.com        print "Failed to open ", sys.argv[1] + '/simout', " for reading"
7012269Sradhika.jagtap@arm.com        exit(-1)
7112269Sradhika.jagtap@arm.com
7212269Sradhika.jagtap@arm.com    # Get the address ranges
7312269Sradhika.jagtap@arm.com    got_ranges = False
7412269Sradhika.jagtap@arm.com    ranges = []
7512269Sradhika.jagtap@arm.com
7612269Sradhika.jagtap@arm.com    iterations = 1
7712269Sradhika.jagtap@arm.com
7812269Sradhika.jagtap@arm.com    for line in simout:
7912269Sradhika.jagtap@arm.com        if got_ranges:
8012269Sradhika.jagtap@arm.com            ranges.append(int(line) / 1024)
8112269Sradhika.jagtap@arm.com
8212269Sradhika.jagtap@arm.com        match = re.match("lat_mem_rd with (\d+) iterations, ranges:.*", line)
8312269Sradhika.jagtap@arm.com        if match:
8412269Sradhika.jagtap@arm.com            got_ranges = True
8512269Sradhika.jagtap@arm.com            iterations = int(match.groups(0)[0])
8612269Sradhika.jagtap@arm.com
8712269Sradhika.jagtap@arm.com    simout.close()
8812269Sradhika.jagtap@arm.com
8912269Sradhika.jagtap@arm.com    if not got_ranges:
9012269Sradhika.jagtap@arm.com        print "Failed to get address ranges, ensure simout is up-to-date"
9112269Sradhika.jagtap@arm.com        exit(-1)
9212269Sradhika.jagtap@arm.com
9312269Sradhika.jagtap@arm.com    # Now parse the stats
9412269Sradhika.jagtap@arm.com    raw_rd_lat = []
9512269Sradhika.jagtap@arm.com
9612269Sradhika.jagtap@arm.com    for line in stats:
9712269Sradhika.jagtap@arm.com        match = re.match(".*readLatencyHist::mean\s+(.+)\s+#.*", line)
9812269Sradhika.jagtap@arm.com        if match:
9912269Sradhika.jagtap@arm.com            raw_rd_lat.append(float(match.groups(0)[0]) / 1000)
10012269Sradhika.jagtap@arm.com    stats.close()
10112269Sradhika.jagtap@arm.com
10212269Sradhika.jagtap@arm.com    # The stats also contain the warming, so filter the latency stats
10312269Sradhika.jagtap@arm.com    i = 0
10412269Sradhika.jagtap@arm.com    filtered_rd_lat = []
10512269Sradhika.jagtap@arm.com    for l in raw_rd_lat:
10612269Sradhika.jagtap@arm.com        if i % (iterations + 1) == 0:
10712269Sradhika.jagtap@arm.com            pass
10812269Sradhika.jagtap@arm.com        else:
10912269Sradhika.jagtap@arm.com            filtered_rd_lat.append(l)
11012269Sradhika.jagtap@arm.com        i = i + 1
11112269Sradhika.jagtap@arm.com
11212269Sradhika.jagtap@arm.com    # Next we need to take care of the iterations
11312269Sradhika.jagtap@arm.com    rd_lat = []
11412269Sradhika.jagtap@arm.com    for i in range(iterations):
11512269Sradhika.jagtap@arm.com        rd_lat.append(filtered_rd_lat[i::iterations])
11612269Sradhika.jagtap@arm.com
11712269Sradhika.jagtap@arm.com    final_rd_lat = map(lambda p: min(p), zip(*rd_lat))
11812269Sradhika.jagtap@arm.com
11912269Sradhika.jagtap@arm.com    # Sanity check
12012269Sradhika.jagtap@arm.com    if not (len(ranges) == len(final_rd_lat)):
12112269Sradhika.jagtap@arm.com        print "Address ranges (%d) and read latency (%d) do not match" % \
12212269Sradhika.jagtap@arm.com            (len(ranges), len(final_rd_lat))
12312269Sradhika.jagtap@arm.com        exit(-1)
12412269Sradhika.jagtap@arm.com
12512269Sradhika.jagtap@arm.com    for (r, l) in zip(ranges, final_rd_lat):
12612269Sradhika.jagtap@arm.com        print r, round(l, 2)
12712269Sradhika.jagtap@arm.com
12812269Sradhika.jagtap@arm.com    # lazy version to check if an integer is a power of two
12912269Sradhika.jagtap@arm.com    def is_pow2(num):
13012269Sradhika.jagtap@arm.com        return num != 0 and ((num & (num - 1)) == 0)
13112269Sradhika.jagtap@arm.com
13212269Sradhika.jagtap@arm.com    plt.semilogx(ranges, final_rd_lat)
13312269Sradhika.jagtap@arm.com
13412269Sradhika.jagtap@arm.com    # create human readable labels
13512269Sradhika.jagtap@arm.com    xticks_locations = [r for r in ranges if is_pow2(r)]
13612269Sradhika.jagtap@arm.com    xticks_labels = []
13712269Sradhika.jagtap@arm.com    for x in xticks_locations:
13812269Sradhika.jagtap@arm.com        if x < 1024:
13912269Sradhika.jagtap@arm.com            xticks_labels.append('%d kB' % x)
14012269Sradhika.jagtap@arm.com        else:
14112269Sradhika.jagtap@arm.com            xticks_labels.append('%d MB' % (x / 1024))
14212269Sradhika.jagtap@arm.com    plt.xticks(xticks_locations, xticks_labels, rotation=-45)
14312269Sradhika.jagtap@arm.com
14412269Sradhika.jagtap@arm.com    plt.minorticks_off()
14512269Sradhika.jagtap@arm.com    plt.xlim((xticks_locations[0], xticks_locations[-1]))
14612269Sradhika.jagtap@arm.com    plt.ylabel("Latency (ns)")
14712269Sradhika.jagtap@arm.com    plt.grid(True)
14812269Sradhika.jagtap@arm.com    plt.show()
14912269Sradhika.jagtap@arm.com
15012269Sradhika.jagtap@arm.comif __name__ == "__main__":
15112269Sradhika.jagtap@arm.com    main()
152