1##########################################################################
2# Copyright (c) 2009, 2010, 2011, ETH Zurich.
3# All rights reserved.
4#
5# This file is distributed under the terms in the attached LICENSE file.
6# If you do not find this file, copies can be found by writing to:
7# ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8##########################################################################
9
10import re
11import debug, tests
12from common import TestCommon, TimeoutError
13from results import RowResults
14from results import RawResults
15
16@tests.add_test
17class PhaseChangeTest(TestCommon):
18    ''' Scheduler phase change latency benchmark '''
19    name = "phasechange"
20
21    def get_build_targets(self, build, machine):
22        targets = super(PhaseChangeTest, self).get_build_targets(build, machine)
23        targets.append("%s/sbin/phases_bench" % (machine.get_bootarch()))
24        return targets
25
26    def get_finish_string(self):
27        return "client done."
28
29    def run(self, build, machine, testdir):
30        ncores = machine.get_ncores()
31        for i in [2**x for x in range(0,ncores + 1) if 2 ** x <= ncores]:
32            debug.log('running %s on %d/%d cores' % (self.name, i, ncores))
33            modules = self.get_modules(build, machine)
34            modules.add_module("phases_bench", [i])
35            self.boot(machine, modules)
36            for line in self.collect_data(machine):
37                yield line
38
39    def process_data(self, testdir, rawiter):
40        results = RawResults('threads')
41        data = []
42        for line in rawiter:
43            m = re.match("duration \d+: (\d+)", line)
44            if m:
45                data.append(int(m.group(1)))
46                continue
47
48            m = re.match("number of threads: (\d+)", line)
49            if m:
50                results.add_group(m.group(1), data)
51                data = []
52
53        return results
54
55# Run every benchmark for 10 seconds (specified in ms)
56PHASESCALE_TIMEOUT = 10000
57
58@tests.add_test
59class PhaseScaleTest(TestCommon):
60    ''' Scheduler phase change scalability benchmark '''
61    name = "phasechange_scale"
62
63    def get_build_targets(self, build, machine):
64        targets = super(PhaseScaleTest, self).get_build_targets(build, machine)
65        targets.append("%s/sbin/phases_scale_bench" % (machine.get_bootarch()))
66        return targets
67
68    def get_finish_string(self):
69        return "client done."
70
71    def run(self, build, machine, testdir):
72        ncores = machine.get_ncores()
73        for delay in [0, 1, 5, 10, 25, 50, 100, 250, 500]:
74            for i in range(2, ncores + 1):
75                debug.log('running %s on %d/%d cores, delay %d' % (self.name, i, ncores, delay))
76                modules = self.get_modules(build, machine)
77                modules.add_module("phases_scale_bench", [i, delay, PHASESCALE_TIMEOUT])
78                self.boot(machine, modules)
79                for line in self.collect_data(machine):
80                    yield line
81
82    def process_data(self, testdir, rawiter):
83        results = RowResults(['threads', 'delay', 'slowdown'])
84        process_sum = 0
85        sums = []
86        baseline = []
87
88        for line in rawiter:
89            m = re.match("workcnt (\d+): (\d+)", line)
90            if m:
91                if int(m.group(1)) != 0:
92                    process_sum += int(m.group(2))
93                continue
94
95            m = re.match("number of threads: (\d+), delay: (\d+)", line)
96            if m:
97                sums.append([m.group(1), m.group(2), process_sum])
98                if int(m.group(2)) == 0:
99                    baseline.append([m.group(1), process_sum])
100                process_sum = 0
101
102        for sum in sums:
103            for [t,p] in baseline:
104                if t == sum[0]:
105                    basesum = p
106                    break
107
108            procsum = float(sum[2]) / float(basesum)
109            results.add_row([sum[0], sum[1], procsum])
110
111        return results
112