1 # Copyright (c) 2017 ARM Limited
4 # The license below extends only to copyright in the software and shall
5 # not be construed as granting a license to any other intellectual
6 # property including but not limited to intellectual property relating
7 # to a hardware implementation of the functionality of the software
8 # licensed hereunder. You may use the software subject to the license
9 # terms below provided that you ensure that this notice is replicated
10 # unmodified and in its entirety in all distributions of the software,
11 # modified or unmodified, in source code or in binary form.
13 # Redistribution and use in source and binary forms, with or without
14 # modification, are permitted provided that the following conditions are
15 # met: redistributions of source code must retain the above copyright
16 # notice, this list of conditions and the following disclaimer;
17 # redistributions in binary form must reproduce the above copyright
18 # notice, this list of conditions and the following disclaimer in the
19 # documentation and/or other materials provided with the distribution;
20 # neither the name of the copyright holders nor the names of its
21 # contributors may be used to endorse or promote products derived from
22 # this software without specific prior written permission.
24 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 # Authors: Radhika Jagtap
40 import matplotlib
.pyplot
as plt
41 from matplotlib
.font_manager
import FontProperties
49 # global vars for bank utilisation and seq_bytes values swept in the experiment
54 # settings for 3 values of bank util and 3 values of seq_bytes
60 States
= ['IDLE', 'ACT', 'REF', 'ACT_PDN', 'PRE_PDN', 'SREF']
62 EnergyStates
= ['ACT_E',
73 'IDLE' : 'black', # time spent in states
74 'ACT' : 'lightskyblue',
76 'ACT_PDN' : 'crimson',
79 'ACT_E' : 'lightskyblue', # energy of states
82 'REF_E' : 'limegreen',
83 'ACT_BACK_E' : 'lightgray',
84 'PRE_BACK_E' : 'gray',
85 'ACT_PDN_E' : 'crimson',
86 'PRE_PDN_E' : 'orange',
91 'system.mem_ctrls_0.actEnergy' : 'ACT_E',
92 'system.mem_ctrls_0.preEnergy' : 'PRE_E',
93 'system.mem_ctrls_0.readEnergy' : 'READ_E',
94 'system.mem_ctrls_0.refreshEnergy' : 'REF_E',
95 'system.mem_ctrls_0.actBackEnergy' : 'ACT_BACK_E',
96 'system.mem_ctrls_0.preBackEnergy' : 'PRE_BACK_E',
97 'system.mem_ctrls_0.actPowerDownEnergy' : 'ACT_PDN_E',
98 'system.mem_ctrls_0.prePowerDownEnergy' : 'PRE_PDN_E',
99 'system.mem_ctrls_0.selfRefreshEnergy' : 'SREF_E'
101 # Skipping write energy, the example script issues 100% reads by default
102 # 'system.mem_ctrls_0.writeEnergy' : "WRITE"
104 def plotLowPStates(plot_dir
, stats_fname
, bank_util_list
, seqbytes_list
,
107 plotLowPStates generates plots by parsing statistics output by the DRAM
108 sweep simulation described in the the configs/dram/low_power_sweep.py
111 The function outputs eps format images for the following plots
112 (1) time spent in the DRAM Power states as a stacked bar chart
113 (2) energy consumed by the DRAM Power states as a stacked bar chart
114 (3) idle plot for the last stats dump corresponding to an idle period
116 For all plots, the time and energy values of the first rank (i.e. rank0)
117 are plotted because the way the script is written means stats across ranks
120 @param plot_dir: the dir to output the plots
121 @param stats_fname: the stats file name of the low power sweep sim
122 @param bank_util_list: list of bank utilisation values (e.g. [1, 4, 8])
123 @param seqbytes_list: list of seq_bytes values (e.g. [64, 456, 512])
124 @param delay_list: list of itt max multipliers (e.g. [1, 20, 200])
127 stats_file
= open(stats_fname
, 'r')
129 global bankUtilValues
130 bankUtilValues
= bank_util_list
132 global seqBytesValues
133 seqBytesValues
= seqbytes_list
136 delayValues
= delay_list
139 # throw away the first two lines of the stats file
140 stats_file
.readline()
141 stats_file
.readline() # the 'Begin' line
143 #######################################
144 # Parse stats file and gather results
145 ########################################
147 for delay
in delayValues
:
148 for bank_util
in bankUtilValues
:
149 for seq_bytes
in seqBytesValues
:
151 for line
in stats_file
:
155 if len(line
.strip()) == 0:
158 #### state time values ####
159 if 'system.mem_ctrls_0.memoryStateTime' in line
:
160 # remove leading and trailing white spaces
163 # 'system.mem_ctrls_0.memoryStateTime::ACT 1000000'
164 statistic
, stime
= line
.split()[0:2]
165 # Now grab the state, i.e. 'ACT'
166 state
= statistic
.split('::')[1]
167 # store the value of the stat in the results dict
168 results
[delay
][bank_util
][seq_bytes
][state
] = \
170 #### state energy values ####
171 elif line
.strip().split()[0] in StatToKey
.keys():
173 # system.mem_ctrls_0.actEnergy 35392980
174 statistic
, e_val
= line
.strip().split()[0:2]
175 senergy
= int(float(e_val
))
176 state
= StatToKey
[statistic
]
177 # store the value of the stat in the results dict
178 results
[delay
][bank_util
][seq_bytes
][state
] = senergy
180 # To add last traffic gen idle period stats to the results dict
181 for line
in stats_file
:
182 if 'system.mem_ctrls_0.memoryStateTime' in line
:
183 line
= line
.strip() # remove leading and trailing white spaces
185 # 'system.mem_ctrls_0.memoryStateTime::ACT 1000000'
186 statistic
, stime
= line
.split()[0:2]
187 # Now grab the state energy, .e.g 'ACT'
188 state
= statistic
.split('::')[1]
189 idleResults
[state
] = int(stime
)
190 if state
== 'ACT_PDN':
193 ########################################
194 # Call plot functions
195 ########################################
196 # one plot per delay value
197 for delay
in delayValues
:
198 plot_path
= plot_dir
+ delay
+ '-'
200 plotStackedStates(delay
, States
, 'IDLE', stateTimePlotName(plot_path
),
201 'Time (ps) spent in a power state')
202 plotStackedStates(delay
, EnergyStates
, 'ACT_E',
203 stateEnergyPlotName(plot_path
),
204 'Energy (pJ) of a power state')
207 def plotIdle(plot_dir
):
209 Create a bar chart for the time spent in power states during the idle phase
211 @param plot_dir: the dir to output the plots
213 fig
, ax
= plt
.subplots()
215 ind
= np
.arange(len(States
))
216 l1
= ax
.bar(ind
, map(lambda x
: idleResults
[x
], States
), width
)
218 ax
.xaxis
.set_ticks(ind
+ width
/2)
219 ax
.xaxis
.set_ticklabels(States
)
220 ax
.set_ylabel('Time (ps) spent in a power state')
221 fig
.suptitle("Idle 50 us")
223 print "saving plot:", idlePlotName(plot_dir
)
224 plt
.savefig(idlePlotName(plot_dir
), format
='eps')
227 def plotStackedStates(delay
, states_list
, bottom_state
, plot_name
, ylabel_str
):
229 Create a stacked bar chart for the list that is passed in as arg, which
230 is either time spent or energy consumed in power states.
232 @param delay: one plot is output per delay value
233 @param states_list: list of either time or energy state names
234 @param bottom_state: the bottom-most component of the stacked bar
235 @param plot_name: the file name of the image to write the plot to
236 @param ylabel_str: Y-axis label depending on plotting time or energy
238 fig
, ax
= plt
.subplots(1, len(bankUtilValues
), sharey
=True)
239 fig
.set_figheight(stackHeight
)
240 fig
.set_figwidth(stackWidth
)
242 plt
.rcParams
.update({'font.size': plotFontSize
})
244 # Get the number of seq_bytes values
245 N
= len(seqBytesValues
)
248 for sub_idx
, bank_util
in enumerate(bankUtilValues
):
253 # Must have a bottom of the stack first
256 l_states
[state
] = map(lambda x
: results
[delay
][bank_util
][x
][state
],
258 p_states
[state
] = ax
[sub_idx
].bar(ind
, l_states
[state
], width
,
259 color
=StackColors
[state
])
261 time_sum
= l_states
[state
]
262 for state
in states_list
[1:]:
263 l_states
[state
] = map(lambda x
:
264 results
[delay
][bank_util
][x
][state
],
266 # Now add on top of the bottom = sum of values up until now
267 p_states
[state
] = ax
[sub_idx
].bar(ind
, l_states
[state
], width
,
268 color
=StackColors
[state
],
270 # Now add the bit of the stack that we just ploted to the bottom
271 # resulting in a new bottom for the next iteration
272 time_sum
= [prev_sum
+ new_s
for prev_sum
, new_s
in \
273 zip(time_sum
, l_states
[state
])]
275 ax
[sub_idx
].set_title('Bank util %s' % bank_util
)
276 ax
[sub_idx
].xaxis
.set_ticks(ind
+ width
/2.)
277 ax
[sub_idx
].xaxis
.set_ticklabels(seqBytesValues
, rotation
=45)
278 ax
[sub_idx
].set_xlabel('Seq. bytes')
279 if bank_util
== bankUtilValues
[0]:
280 ax
[sub_idx
].set_ylabel(ylabel_str
)
283 fontP
= FontProperties()
284 fontP
.set_size(myFontSize
)
285 fig
.legend(map(lambda x
: p_states
[x
], states_list
), states_list
,
288 plt
.savefig(plot_name
, format
='eps', bbox_inches
='tight')
289 print "saving plot:", plot_name
292 # These plat name functions are also called in the main script
293 def idlePlotName(plot_dir
):
294 return (plot_dir
+ 'idle.eps')
296 def stateTimePlotName(plot_dir
):
297 return (plot_dir
+ 'state-time.eps')
299 def stateEnergyPlotName(plot_dir
):
300 return (plot_dir
+ 'state-energy.eps')
303 for delay
in delayValues
:
305 for bank_util
in bankUtilValues
:
306 results
[delay
][bank_util
] = {}
307 for seq_bytes
in seqBytesValues
:
308 results
[delay
][bank_util
][seq_bytes
] = {}