112269Sradhika.jagtap@arm.com# Copyright (c) 2017 ARM Limited
212269Sradhika.jagtap@arm.com# All rights reserved
312269Sradhika.jagtap@arm.com#
412269Sradhika.jagtap@arm.com# The license below extends only to copyright in the software and shall
512269Sradhika.jagtap@arm.com# not be construed as granting a license to any other intellectual
612269Sradhika.jagtap@arm.com# property including but not limited to intellectual property relating
712269Sradhika.jagtap@arm.com# to a hardware implementation of the functionality of the software
812269Sradhika.jagtap@arm.com# licensed hereunder.  You may use the software subject to the license
912269Sradhika.jagtap@arm.com# terms below provided that you ensure that this notice is replicated
1012269Sradhika.jagtap@arm.com# unmodified and in its entirety in all distributions of the software,
1112269Sradhika.jagtap@arm.com# modified or unmodified, in source code or in binary form.
1212269Sradhika.jagtap@arm.com#
1312269Sradhika.jagtap@arm.com# Redistribution and use in source and binary forms, with or without
1412269Sradhika.jagtap@arm.com# modification, are permitted provided that the following conditions are
1512269Sradhika.jagtap@arm.com# met: redistributions of source code must retain the above copyright
1612269Sradhika.jagtap@arm.com# notice, this list of conditions and the following disclaimer;
1712269Sradhika.jagtap@arm.com# redistributions in binary form must reproduce the above copyright
1812269Sradhika.jagtap@arm.com# notice, this list of conditions and the following disclaimer in the
1912269Sradhika.jagtap@arm.com# documentation and/or other materials provided with the distribution;
2012269Sradhika.jagtap@arm.com# neither the name of the copyright holders nor the names of its
2112269Sradhika.jagtap@arm.com# contributors may be used to endorse or promote products derived from
2212269Sradhika.jagtap@arm.com# this software without specific prior written permission.
2312269Sradhika.jagtap@arm.com#
2412269Sradhika.jagtap@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2512269Sradhika.jagtap@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2612269Sradhika.jagtap@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2712269Sradhika.jagtap@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2812269Sradhika.jagtap@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2912269Sradhika.jagtap@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3012269Sradhika.jagtap@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3112269Sradhika.jagtap@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3212269Sradhika.jagtap@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3312269Sradhika.jagtap@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3412269Sradhika.jagtap@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3512269Sradhika.jagtap@arm.com#
3612269Sradhika.jagtap@arm.com# Authors: Radhika Jagtap
3712269Sradhika.jagtap@arm.com
3812269Sradhika.jagtap@arm.comimport matplotlib
3912269Sradhika.jagtap@arm.commatplotlib.use('Agg')
4012269Sradhika.jagtap@arm.comimport matplotlib.pyplot as plt
4112269Sradhika.jagtap@arm.comfrom matplotlib.font_manager import FontProperties
4212269Sradhika.jagtap@arm.comimport numpy as np
4312269Sradhika.jagtap@arm.comimport os
4412269Sradhika.jagtap@arm.com
4512269Sradhika.jagtap@arm.com# global results dict
4612269Sradhika.jagtap@arm.comresults = {}
4712269Sradhika.jagtap@arm.comidleResults = {}
4812269Sradhika.jagtap@arm.com
4912269Sradhika.jagtap@arm.com# global vars for bank utilisation and seq_bytes values swept in the experiment
5012269Sradhika.jagtap@arm.combankUtilValues = []
5112269Sradhika.jagtap@arm.comseqBytesValues = []
5212269Sradhika.jagtap@arm.comdelayValues = []
5312269Sradhika.jagtap@arm.com
5412269Sradhika.jagtap@arm.com# settings for 3 values of bank util and 3 values of seq_bytes
5512269Sradhika.jagtap@arm.comstackHeight = 6.0
5612269Sradhika.jagtap@arm.comstackWidth = 18.0
5712269Sradhika.jagtap@arm.combarWidth = 0.5
5812269Sradhika.jagtap@arm.complotFontSize = 18
5912269Sradhika.jagtap@arm.com
6012269Sradhika.jagtap@arm.comStates = ['IDLE', 'ACT', 'REF', 'ACT_PDN', 'PRE_PDN', 'SREF']
6112269Sradhika.jagtap@arm.com
6212269Sradhika.jagtap@arm.comEnergyStates = ['ACT_E',
6312269Sradhika.jagtap@arm.com'PRE_E',
6412269Sradhika.jagtap@arm.com'READ_E',
6512269Sradhika.jagtap@arm.com'REF_E',
6612269Sradhika.jagtap@arm.com'ACT_BACK_E',
6712269Sradhika.jagtap@arm.com'PRE_BACK_E',
6812269Sradhika.jagtap@arm.com'ACT_PDN_E',
6912269Sradhika.jagtap@arm.com'PRE_PDN_E',
7012269Sradhika.jagtap@arm.com'SREF_E']
7112269Sradhika.jagtap@arm.com
7212269Sradhika.jagtap@arm.comStackColors = {
7312269Sradhika.jagtap@arm.com'IDLE' : 'black',       # time spent in states
7412269Sradhika.jagtap@arm.com'ACT' : 'lightskyblue',
7512269Sradhika.jagtap@arm.com'REF' : 'limegreen',
7612269Sradhika.jagtap@arm.com'ACT_PDN' : 'crimson',
7712269Sradhika.jagtap@arm.com'PRE_PDN' : 'orange',
7812269Sradhika.jagtap@arm.com'SREF' : 'gold',
7912269Sradhika.jagtap@arm.com'ACT_E' : 'lightskyblue',  # energy of states
8012269Sradhika.jagtap@arm.com'PRE_E' : 'black',
8112269Sradhika.jagtap@arm.com'READ_E' : 'white',
8212269Sradhika.jagtap@arm.com'REF_E' : 'limegreen',
8312269Sradhika.jagtap@arm.com'ACT_BACK_E' : 'lightgray',
8412269Sradhika.jagtap@arm.com'PRE_BACK_E' : 'gray',
8512269Sradhika.jagtap@arm.com'ACT_PDN_E' : 'crimson',
8612269Sradhika.jagtap@arm.com'PRE_PDN_E' : 'orange',
8712269Sradhika.jagtap@arm.com'SREF_E' : 'gold'
8812269Sradhika.jagtap@arm.com}
8912269Sradhika.jagtap@arm.com
9012269Sradhika.jagtap@arm.comStatToKey = {
9112269Sradhika.jagtap@arm.com'system.mem_ctrls_0.actEnergy'          : 'ACT_E',
9212269Sradhika.jagtap@arm.com'system.mem_ctrls_0.preEnergy'          : 'PRE_E',
9312269Sradhika.jagtap@arm.com'system.mem_ctrls_0.readEnergy'         : 'READ_E',
9412269Sradhika.jagtap@arm.com'system.mem_ctrls_0.refreshEnergy'      : 'REF_E',
9512269Sradhika.jagtap@arm.com'system.mem_ctrls_0.actBackEnergy'      : 'ACT_BACK_E',
9612269Sradhika.jagtap@arm.com'system.mem_ctrls_0.preBackEnergy'      : 'PRE_BACK_E',
9712269Sradhika.jagtap@arm.com'system.mem_ctrls_0.actPowerDownEnergy' : 'ACT_PDN_E',
9812269Sradhika.jagtap@arm.com'system.mem_ctrls_0.prePowerDownEnergy' : 'PRE_PDN_E',
9912269Sradhika.jagtap@arm.com'system.mem_ctrls_0.selfRefreshEnergy'  : 'SREF_E'
10012269Sradhika.jagtap@arm.com}
10112269Sradhika.jagtap@arm.com# Skipping write energy, the example script issues 100% reads by default
10212269Sradhika.jagtap@arm.com# 'system.mem_ctrls_0.writeEnergy' : "WRITE"
10312269Sradhika.jagtap@arm.com
10412269Sradhika.jagtap@arm.comdef plotLowPStates(plot_dir, stats_fname, bank_util_list, seqbytes_list,
10512269Sradhika.jagtap@arm.com                   delay_list):
10612269Sradhika.jagtap@arm.com    """
10712269Sradhika.jagtap@arm.com    plotLowPStates generates plots by parsing statistics output by the DRAM
10812269Sradhika.jagtap@arm.com    sweep simulation described in the the configs/dram/low_power_sweep.py
10912269Sradhika.jagtap@arm.com    script.
11012269Sradhika.jagtap@arm.com
11112269Sradhika.jagtap@arm.com    The function outputs eps format images for the following plots
11212269Sradhika.jagtap@arm.com    (1) time spent in the DRAM Power states as a stacked bar chart
11312269Sradhika.jagtap@arm.com    (2) energy consumed by the DRAM Power states as a stacked bar chart
11412269Sradhika.jagtap@arm.com    (3) idle plot for the last stats dump corresponding to an idle period
11512269Sradhika.jagtap@arm.com
11612269Sradhika.jagtap@arm.com    For all plots, the time and energy values of the first rank (i.e. rank0)
11712269Sradhika.jagtap@arm.com    are plotted because the way the script is written means stats across ranks
11812269Sradhika.jagtap@arm.com    are similar.
11912269Sradhika.jagtap@arm.com
12012269Sradhika.jagtap@arm.com    @param plot_dir: the dir to output the plots
12112269Sradhika.jagtap@arm.com    @param stats_fname: the stats file name of the low power sweep sim
12212269Sradhika.jagtap@arm.com    @param bank_util_list: list of bank utilisation values (e.g. [1, 4, 8])
12312269Sradhika.jagtap@arm.com    @param seqbytes_list: list of seq_bytes values (e.g. [64, 456, 512])
12412269Sradhika.jagtap@arm.com    @param delay_list: list of itt max multipliers (e.g. [1, 20, 200])
12512269Sradhika.jagtap@arm.com
12612269Sradhika.jagtap@arm.com    """
12712269Sradhika.jagtap@arm.com    stats_file = open(stats_fname, 'r')
12812269Sradhika.jagtap@arm.com
12912269Sradhika.jagtap@arm.com    global bankUtilValues
13012269Sradhika.jagtap@arm.com    bankUtilValues = bank_util_list
13112269Sradhika.jagtap@arm.com
13212269Sradhika.jagtap@arm.com    global seqBytesValues
13312269Sradhika.jagtap@arm.com    seqBytesValues = seqbytes_list
13412269Sradhika.jagtap@arm.com
13512269Sradhika.jagtap@arm.com    global delayValues
13612269Sradhika.jagtap@arm.com    delayValues = delay_list
13712269Sradhika.jagtap@arm.com    initResults()
13812269Sradhika.jagtap@arm.com
13912269Sradhika.jagtap@arm.com    # throw away the first two lines of the stats file
14012269Sradhika.jagtap@arm.com    stats_file.readline()
14112269Sradhika.jagtap@arm.com    stats_file.readline() # the 'Begin' line
14212269Sradhika.jagtap@arm.com
14312269Sradhika.jagtap@arm.com    #######################################
14412269Sradhika.jagtap@arm.com    # Parse stats file and gather results
14512269Sradhika.jagtap@arm.com    ########################################
14612269Sradhika.jagtap@arm.com
14712269Sradhika.jagtap@arm.com    for delay in delayValues:
14812269Sradhika.jagtap@arm.com        for bank_util in bankUtilValues:
14912269Sradhika.jagtap@arm.com            for seq_bytes in seqBytesValues:
15012269Sradhika.jagtap@arm.com
15112269Sradhika.jagtap@arm.com                for line in stats_file:
15212269Sradhika.jagtap@arm.com                    if 'Begin' in line:
15312269Sradhika.jagtap@arm.com                        break
15412269Sradhika.jagtap@arm.com
15512269Sradhika.jagtap@arm.com                    if len(line.strip()) == 0:
15612269Sradhika.jagtap@arm.com                        continue
15712269Sradhika.jagtap@arm.com
15812269Sradhika.jagtap@arm.com                    #### state time values ####
15912269Sradhika.jagtap@arm.com                    if 'system.mem_ctrls_0.memoryStateTime' in line:
16012269Sradhika.jagtap@arm.com                        # remove leading and trailing white spaces
16112269Sradhika.jagtap@arm.com                        line = line.strip()
16212269Sradhika.jagtap@arm.com                        # Example format:
16312269Sradhika.jagtap@arm.com                        # 'system.mem_ctrls_0.memoryStateTime::ACT    1000000'
16412269Sradhika.jagtap@arm.com                        statistic, stime = line.split()[0:2]
16512269Sradhika.jagtap@arm.com                        # Now grab the state, i.e. 'ACT'
16612269Sradhika.jagtap@arm.com                        state = statistic.split('::')[1]
16712269Sradhika.jagtap@arm.com                        # store the value of the stat in the results dict
16812269Sradhika.jagtap@arm.com                        results[delay][bank_util][seq_bytes][state] = \
16912269Sradhika.jagtap@arm.com                            int(stime)
17012269Sradhika.jagtap@arm.com                    #### state energy values ####
17112269Sradhika.jagtap@arm.com                    elif line.strip().split()[0] in StatToKey.keys():
17212269Sradhika.jagtap@arm.com                        # Example format:
17312269Sradhika.jagtap@arm.com                        # system.mem_ctrls_0.actEnergy                 35392980
17412269Sradhika.jagtap@arm.com                        statistic, e_val = line.strip().split()[0:2]
17512269Sradhika.jagtap@arm.com                        senergy = int(float(e_val))
17612269Sradhika.jagtap@arm.com                        state = StatToKey[statistic]
17712269Sradhika.jagtap@arm.com                        # store the value of the stat in the results dict
17812269Sradhika.jagtap@arm.com                        results[delay][bank_util][seq_bytes][state] = senergy
17912269Sradhika.jagtap@arm.com
18012269Sradhika.jagtap@arm.com    # To add last traffic gen idle period stats to the results dict
18112269Sradhika.jagtap@arm.com    for line in stats_file:
18212269Sradhika.jagtap@arm.com        if 'system.mem_ctrls_0.memoryStateTime' in line:
18312269Sradhika.jagtap@arm.com            line = line.strip() # remove leading and trailing white spaces
18412269Sradhika.jagtap@arm.com            # Example format:
18512269Sradhika.jagtap@arm.com            # 'system.mem_ctrls_0.memoryStateTime::ACT    1000000'
18612269Sradhika.jagtap@arm.com            statistic, stime = line.split()[0:2]
18712269Sradhika.jagtap@arm.com            # Now grab the state energy, .e.g 'ACT'
18812269Sradhika.jagtap@arm.com            state = statistic.split('::')[1]
18912269Sradhika.jagtap@arm.com            idleResults[state] = int(stime)
19012269Sradhika.jagtap@arm.com            if state == 'ACT_PDN':
19112269Sradhika.jagtap@arm.com                break
19212269Sradhika.jagtap@arm.com
19312269Sradhika.jagtap@arm.com    ########################################
19412269Sradhika.jagtap@arm.com    # Call plot functions
19512269Sradhika.jagtap@arm.com    ########################################
19612269Sradhika.jagtap@arm.com    # one plot per delay value
19712269Sradhika.jagtap@arm.com    for delay in delayValues:
19812269Sradhika.jagtap@arm.com        plot_path = plot_dir + delay + '-'
19912269Sradhika.jagtap@arm.com
20012269Sradhika.jagtap@arm.com        plotStackedStates(delay, States, 'IDLE', stateTimePlotName(plot_path),
20112269Sradhika.jagtap@arm.com                          'Time (ps) spent in a power state')
20212269Sradhika.jagtap@arm.com        plotStackedStates(delay, EnergyStates, 'ACT_E',
20312269Sradhika.jagtap@arm.com                          stateEnergyPlotName(plot_path),
20412269Sradhika.jagtap@arm.com                          'Energy (pJ) of a power state')
20512269Sradhika.jagtap@arm.com    plotIdle(plot_dir)
20612269Sradhika.jagtap@arm.com
20712269Sradhika.jagtap@arm.comdef plotIdle(plot_dir):
20812269Sradhika.jagtap@arm.com    """
20912269Sradhika.jagtap@arm.com    Create a bar chart for the time spent in power states during the idle phase
21012269Sradhika.jagtap@arm.com
21112269Sradhika.jagtap@arm.com    @param plot_dir: the dir to output the plots
21212269Sradhika.jagtap@arm.com    """
21312269Sradhika.jagtap@arm.com    fig, ax = plt.subplots()
21412269Sradhika.jagtap@arm.com    width = 0.35
21512269Sradhika.jagtap@arm.com    ind = np.arange(len(States))
21612269Sradhika.jagtap@arm.com    l1 = ax.bar(ind, map(lambda x : idleResults[x], States), width)
21712269Sradhika.jagtap@arm.com
21812269Sradhika.jagtap@arm.com    ax.xaxis.set_ticks(ind + width/2)
21912269Sradhika.jagtap@arm.com    ax.xaxis.set_ticklabels(States)
22012269Sradhika.jagtap@arm.com    ax.set_ylabel('Time (ps) spent in a power state')
22112269Sradhika.jagtap@arm.com    fig.suptitle("Idle 50 us")
22212269Sradhika.jagtap@arm.com
22312269Sradhika.jagtap@arm.com    print "saving plot:", idlePlotName(plot_dir)
22412269Sradhika.jagtap@arm.com    plt.savefig(idlePlotName(plot_dir), format='eps')
22512269Sradhika.jagtap@arm.com    plt.close(fig)
22612269Sradhika.jagtap@arm.com
22712269Sradhika.jagtap@arm.comdef plotStackedStates(delay, states_list, bottom_state, plot_name, ylabel_str):
22812269Sradhika.jagtap@arm.com    """
22912269Sradhika.jagtap@arm.com    Create a stacked bar chart for the list that is passed in as arg, which
23012269Sradhika.jagtap@arm.com    is either time spent or energy consumed in power states.
23112269Sradhika.jagtap@arm.com
23212269Sradhika.jagtap@arm.com    @param delay: one plot is output per delay value
23312269Sradhika.jagtap@arm.com    @param states_list: list of either time or energy state names
23412269Sradhika.jagtap@arm.com    @param bottom_state: the bottom-most component of the stacked bar
23512269Sradhika.jagtap@arm.com    @param plot_name: the file name of the image to write the plot to
23612269Sradhika.jagtap@arm.com    @param ylabel_str: Y-axis label depending on plotting time or energy
23712269Sradhika.jagtap@arm.com    """
23812269Sradhika.jagtap@arm.com    fig, ax = plt.subplots(1, len(bankUtilValues), sharey=True)
23912269Sradhika.jagtap@arm.com    fig.set_figheight(stackHeight)
24012269Sradhika.jagtap@arm.com    fig.set_figwidth(stackWidth)
24112269Sradhika.jagtap@arm.com    width = barWidth
24212269Sradhika.jagtap@arm.com    plt.rcParams.update({'font.size': plotFontSize})
24312269Sradhika.jagtap@arm.com
24412269Sradhika.jagtap@arm.com    # Get the number of seq_bytes values
24512269Sradhika.jagtap@arm.com    N = len(seqBytesValues)
24612269Sradhika.jagtap@arm.com    ind = np.arange(N)
24712269Sradhika.jagtap@arm.com
24812269Sradhika.jagtap@arm.com    for sub_idx, bank_util in enumerate(bankUtilValues):
24912269Sradhika.jagtap@arm.com
25012269Sradhika.jagtap@arm.com        l_states = {}
25112269Sradhika.jagtap@arm.com        p_states = {}
25212269Sradhika.jagtap@arm.com
25312269Sradhika.jagtap@arm.com        # Must have a bottom of the stack first
25412269Sradhika.jagtap@arm.com        state = bottom_state
25512269Sradhika.jagtap@arm.com
25612269Sradhika.jagtap@arm.com        l_states[state] = map(lambda x: results[delay][bank_util][x][state],
25712269Sradhika.jagtap@arm.com                              seqBytesValues)
25812269Sradhika.jagtap@arm.com        p_states[state] = ax[sub_idx].bar(ind, l_states[state], width,
25912269Sradhika.jagtap@arm.com                                          color=StackColors[state])
26012269Sradhika.jagtap@arm.com
26112269Sradhika.jagtap@arm.com        time_sum = l_states[state]
26212269Sradhika.jagtap@arm.com        for state in states_list[1:]:
26312269Sradhika.jagtap@arm.com            l_states[state] = map(lambda x:
26412269Sradhika.jagtap@arm.com                                  results[delay][bank_util][x][state],
26512269Sradhika.jagtap@arm.com                                  seqBytesValues)
26612269Sradhika.jagtap@arm.com            # Now add on top of the bottom = sum of values up until now
26712269Sradhika.jagtap@arm.com            p_states[state] = ax[sub_idx].bar(ind, l_states[state], width,
26812269Sradhika.jagtap@arm.com                                              color=StackColors[state],
26912269Sradhika.jagtap@arm.com                                              bottom=time_sum)
27012269Sradhika.jagtap@arm.com            # Now add the bit of the stack that we just ploted to the bottom
27112269Sradhika.jagtap@arm.com            # resulting in a new bottom for the next iteration
27212269Sradhika.jagtap@arm.com            time_sum = [prev_sum + new_s for prev_sum, new_s in \
27312269Sradhika.jagtap@arm.com                zip(time_sum, l_states[state])]
27412269Sradhika.jagtap@arm.com
27512269Sradhika.jagtap@arm.com        ax[sub_idx].set_title('Bank util %s' % bank_util)
27612269Sradhika.jagtap@arm.com        ax[sub_idx].xaxis.set_ticks(ind + width/2.)
27712269Sradhika.jagtap@arm.com        ax[sub_idx].xaxis.set_ticklabels(seqBytesValues, rotation=45)
27812269Sradhika.jagtap@arm.com        ax[sub_idx].set_xlabel('Seq. bytes')
27912269Sradhika.jagtap@arm.com        if bank_util == bankUtilValues[0]:
28012269Sradhika.jagtap@arm.com            ax[sub_idx].set_ylabel(ylabel_str)
28112269Sradhika.jagtap@arm.com
28212269Sradhika.jagtap@arm.com    myFontSize='small'
28312269Sradhika.jagtap@arm.com    fontP = FontProperties()
28412269Sradhika.jagtap@arm.com    fontP.set_size(myFontSize)
28512269Sradhika.jagtap@arm.com    fig.legend(map(lambda x: p_states[x], states_list), states_list,
28612269Sradhika.jagtap@arm.com               prop=fontP)
28712269Sradhika.jagtap@arm.com
28812269Sradhika.jagtap@arm.com    plt.savefig(plot_name,  format='eps', bbox_inches='tight')
28912269Sradhika.jagtap@arm.com    print "saving plot:", plot_name
29012269Sradhika.jagtap@arm.com    plt.close(fig)
29112269Sradhika.jagtap@arm.com
29212269Sradhika.jagtap@arm.com# These plat name functions are also called in the main script
29312269Sradhika.jagtap@arm.comdef idlePlotName(plot_dir):
29412269Sradhika.jagtap@arm.com    return (plot_dir + 'idle.eps')
29512269Sradhika.jagtap@arm.com
29612269Sradhika.jagtap@arm.comdef stateTimePlotName(plot_dir):
29712269Sradhika.jagtap@arm.com    return (plot_dir + 'state-time.eps')
29812269Sradhika.jagtap@arm.com
29912269Sradhika.jagtap@arm.comdef stateEnergyPlotName(plot_dir):
30012269Sradhika.jagtap@arm.com    return (plot_dir + 'state-energy.eps')
30112269Sradhika.jagtap@arm.com
30212269Sradhika.jagtap@arm.comdef initResults():
30312269Sradhika.jagtap@arm.com    for delay in delayValues:
30412269Sradhika.jagtap@arm.com        results[delay] = {}
30512269Sradhika.jagtap@arm.com        for bank_util in bankUtilValues:
30612269Sradhika.jagtap@arm.com            results[delay][bank_util] = {}
30712269Sradhika.jagtap@arm.com            for seq_bytes in seqBytesValues:
30812269Sradhika.jagtap@arm.com                results[delay][bank_util][seq_bytes] = {}
309