aboutsummaryrefslogtreecommitdiffstats
path: root/tests/power/PowerMeasure.py
blob: 83b177bc618d6776c035be4b23dd330d654b10f3 (plain) (blame)
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/env python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.


# ---------Power measurement ------------------------------#
# This script will run the servo with the given benchmark and
# get the power usage using Powermetrics. Results will be put
# in sperate files with that name.
# Do not forget to run the script in servo/tests/power folder
# --------------------------------------------------------#

from __future__ import print_function, unicode_literals

import os
from os import path
import time
import argparse

# ------------------------PowerCollector----------------------------#
# Collecting all the power data and put them into files


TOP_DIR = path.join("..", "..")


def PowerCollector(OutputDir, Benchmarks, LayoutThreads, Renderer):
    print("Running the power collector")
    power_dir = path.join(OutputDir, "power")
    time_dir = path.join(OutputDir, "time")
    etc_dir = path.join(OutputDir, "etc")
    for d in [power_dir, time_dir, etc_dir]:
        os.mkdir(d)
    SleepTime = 20
    GuardTime = 0.5
    powerTiming = 1
    ExperimentNum = 21
    for ExpNum in range(1, ExperimentNum):
        for layoutT in range(1, LayoutThreads + 1):
            print("  layoutT=%d ExpNum=%d" % (layoutT, ExpNum))
            PowerFiles = path.join(
                power_dir, "power-Layout%d-set%d.csv" % (layoutT, ExpNum))
            TimeFiles = path.join(
                time_dir, "time-Layout%d-set%d.csv" % (layoutT, ExpNum))
            ServoCmd = "(time ../../target/release/servo -x -y %d %s %s) 2> %s" % \
                       (layoutT, Renderer, Benchmarks, TimeFiles)
            Metrics = path.join(
                etc_dir, "metrics-Layout%d-set%d-css.csv" % (layoutT, ExpNum))
            cmd = "(sudo powermetrics -i %d | " \
                  "grep \"energy\\|elapsed\\|servo\" > %s &_) 2> %s" % \
                  (powerTiming, PowerFiles, Metrics)
            time.sleep(SleepTime)
            os.system(cmd)
            time.sleep(GuardTime)
            os.system(ServoCmd)
            time.sleep(GuardTime)
            os.system('sudo pkill -9 powermetrics')
            time.sleep(SleepTime)

# -------------------PowerParser ---------------------------------#
# Parsing collected power by PowerCollector fucntion


def PowerParser(OutputDir, LayoutThreads):
    print("Running the PowerParser")
    ExperimentNum = 21
    ResultTable = OutputDir + "ResultTable.csv"
    ResultFile = open(ResultTable, "w")
    ResultFile.write("LayoutThreads, MeanPower, MaxPower , MinPower, MeanTime , MaxTime, "
                     "MinTime  \n")

    for layoutT in range(1, LayoutThreads + 1):
        MaxTime = 0
        MinTime = 1000000
        MaxPower = 0
        MinPower = 1000000
        TotalPower = 0
        TotalTime = 0
        TimeGen = 0
        PowerGen = 0
        for ExpNum in range(1, ExperimentNum):
            print("  layoutT=%d ExpNum=%d" % (layoutT, ExpNum))
            Files = path.join(
                OutputDir, "power", "power-Layout%d-set%d.csv" %
                (layoutT, ExpNum))
            NewFile = path.join(OutputDir, "power", "Servo-Layout%d-set%d.csv" %
                                (layoutT, ExpNum))
            File = open(Files, 'r')
            PowerFile = open(NewFile, 'w')
            TimeFiles = path.join(OutputDir, "time", "time-Layout%d-set%d.csv" %
                                  (layoutT, ExpNum))
            # ----Putting the power the power and its time into a table---- #

            for line in File:
                words = line.split()
                if words[0] == "***":
                    insertingWord = words[10][1:-2] + " "
                elif words[0] == "Intel":
                    insertingWord += words[7][:-1]
                    insertingWord += "\n"
                    PowerFile.write(insertingWord)
            File.close()
            PowerFile.close()

            # ---------------geting the total power of experiments-------- #

            TempFile = open(NewFile, 'r')
            Power = 0
            for line in TempFile:
                words2 = line.split()
                Power += float(words2[0]) * float(words2[1])
            TotalPower = float(Power / 1000.0)
            if TotalPower > MaxPower:
                MaxPower = TotalPower
            if TotalPower < MinPower:
                MinPower = TotalPower

            # -------------getting the total time of execution---------- #

            TempFile2 = open(TimeFiles, "r")
            for line in TempFile2:
                words3 = line.split()
                if line != "\n" and words3[0] == "real":
                    TotalTime = (float(words3[1][0]) * 60) + \
                        float(words3[1][2:-1])
            if TotalTime > MaxTime:
                MaxTime = TotalTime
            if TotalTime < MinTime:
                MinTime = TotalTime
            TimeGen = TimeGen + TotalTime
            PowerGen = PowerGen + TotalPower

        TotalPower = PowerGen / float(ExperimentNum - 1)
        TotalTime = TimeGen / float(ExperimentNum - 1)
        ResultFile.write(str(layoutT) + " , " + str(TotalPower) + " , "
                         + str(MaxPower) + " , " + str(MinPower) + " , "
                         + str(TotalTime) + " , " + str(MaxTime) + " , "
                         + str(MinTime) + "\n")
    ResultFile.close()
    Opener = ResultFile = open(ResultTable, "r")
    for line in Opener:
        print(line)

    print("Also you can find all the numbers for Power "
          "and Performance in : ", ResultTable)


# ----------------------------------------------------#
def main():
    LayoutThreads = 8  # Maximum number of threads considered for Layout
    Benchmarks = path.join(TOP_DIR, "tests", "html", "perf-rainbow.html")
    OutputDir = "Experiments"
    os.mkdir(OutputDir)
    Renderer = ""

    # Parsing the input of the script
    parser = argparse.ArgumentParser(description="Measuring \
        power and performance of your Servo runs")
    parser.add_argument("-b", "--benchmark", help="Gets the \
        benchmark, for example \"-B perf-rainbow.html\"")
    parser.add_argument("-c", "--CPU", help="Rendering with \
        CPU instead of  GPU, for example -C")
    parser.add_argument("-l", "--LayoutThreads", help="Specify \
        the maximum number of threads for layout, for example \" -L 5\"")
    parser.add_argument("-o", "--Output", help="Specify \
        the output directory")

    args = parser.parse_args()
    if args.benchmark:
        Benchmarks = args.benchmark
    if args.CPU:
        Renderer = "-c"
    if args.LayoutThreads:
        LayoutThreads = int(args.LayoutThreads)
    if args.Output:
        OutputDir = args.Output

    PowerCollector(OutputDir, Benchmarks, LayoutThreads, Renderer)
    PowerParser(OutputDir, LayoutThreads)


if __name__ == "__main__":
    main()