summaryrefslogtreecommitdiff
blob: 8e6940f304ff92135e6c50f58a12e01c170d6157 (plain)
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
import os, shlex, numpy as np, subprocess as sp
from os.path import realpath, exists as pexists, join as pjoin
from random import randint

import basemodule
import benchconfig as cfg
from benchutils import mkdir
from benchprint import Print
import benchchilds

inputsdir = pjoin(cfg.testsdir, 'metis-input')
mkdir(inputsdir)

avail_graph = ['pmetis-8', 'kmetis-8', 'pmetis-64', 'kmetis-64']
avail_mesh = []
avail_matrix = []

class Module(basemodule.BaseModule):
    
    #classmethod
    def _initialize(cls):
        cls.avail = avail_graph + avail_mesh + avail_matrix
    
    def _parse_args(self, args):
        tests = []
        
        # Parse arguments
        for i in args:
            if i in self.avail:
                tests.append(i)
            else:
                raise Exception("Argument not recognized: " + i)
                
        if len(tests) == 0:
            # If not test provided, perform all
            self.tests = self.avail
        else:
            # Sort tests
            self.tests = [i for i in self.avail if i in tests]
    
    @staticmethod
    def get_impls(*args, **kwargs):
        return ('metis',)
        
    def instructionsFor(self, impl):
        Print("Nothing to do")
    
    def save_results(self, results):
        basemodule.BaseModule.save_results(self, results, 'loglog', 'Seconds')
    
    def getTest(self, root, impl, testdir, logdir):
        t = MetisTest(root, testdir, logdir, self.tests)
        return t
    

class MetisTest:
    sizes = None
    
    def __init__(self, root, testdir, logdir, tests):
        self.root = root
        self.testdir = testdir
        self.logdir = logdir
        self.tests = tests
        mkdir(logdir)
        mkdir(testdir)
        
    @classmethod
    def _getSizes(cls):
        if cls.sizes is None:
            cls.sizes = [int(i) for i in np.logspace(3, 6, 100)]
        return cls.sizes
    
    def _generateFiles(self):
        Print("Generating input files...")
        # Graph
        if len([i for i in self.tests if i in avail_graph]) != 0:
            for size in self._getSizes():
                fname = pjoin(inputsdir, 'input_%i.graph' % size)
                if not pexists(fname):
                    writeGraph(size, fname)
        Print("Done")
                    
        
    def run_test(self, changes={}):
        self._generateFiles()
        result = {}
        
        for t in [i for i in self.tests if i in avail_graph]:
            Print('Doing ' + t)
            Print.down()
            res = []
            
            for s,size in enumerate(self._getSizes(), 1):
                inputfile = pjoin(inputsdir, 'input_%i.graph' % size)
                
                # Setting environment
                env = os.environ.copy()
                envpath = env.has_key('PATH') and env['PATH'] or ''
                env['PATH'] = ':'.join([pjoin(self.root, p) for p in \
                  ('bin', 'usr/bin')]) + ':' + envpath
                envlib = env.has_key('LD_LIBARY_PATH') and \
                  env['LD_LIBARY_PATH'] or ''
                env['LD_LIBRARY_PATH'] = ':'.join([pjoin(self.root,p) for p in \
                  ('usr/lib', 'usr/lib64', 'usr/lib32')]) + ':' + envlib
                  
                # Get executable
                exe, parts = t.split('-')
                exe = pjoin(self.root, 'usr/bin', exe)
                
                # Check dynamic linking
                logf = file(pjoin(self.logdir, 'ldd.log'), 'w')
                p = sp.Popen(\
                  ['ldd', '-v', exe], stdout=logf, stderr=sp.STDOUT, env=env
                )
                p.wait()
                
                # Execute
                logname = pjoin(self.logdir, t + '_%i.log' % size)
                cmd = [exe, inputfile, parts]
                pr = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.STDOUT, env=env)
                benchchilds.append(pr)
                lines = pr.communicate()[0].split('\n')
                
                # Interpret output
                for i,line in enumerate(lines):
                    if line[:18] == "Timing Information":
                        begin_timing = i+1
                        break
                    
                lines = [i[:-1] for i in lines[begin_timing+1:]]
                for l in lines:
                    if l.strip()[:13] == "Partitioning:":
                        time = float(shlex.split(l)[1])
                        break
                res.append((size,time))
                Print("size: %6i    %2.3f sec.  (%i/%i)" % (size, time, s, 100))
            
            Print.up()
            
            # Write sizes / times to result file
            resfname = pjoin(self.testdir, t+'.dat')
            resfs = file(resfname, 'w')
            for i in res:
                print >> resfs, i[0], i[1]
            resfs.close()
            result[t] = resfname
        return result
            
            
def writeGraph(size, filename):
    edges = [[] for i in xrange(size)]
    nedges = 0
    for e1 in xrange(len(edges)):
        n = 0
        tot = randint(1, min(size / 4, 5))
        while n < tot:
            e2 = randint(0, size - 1)
            if e2 not in edges[e1] and e1 != e2:
                edges[e1].append(e2)
                edges[e2].append(e1)
                n += 1
                nedges += 1
    fs = file(filename, 'w')
    print >> fs, size, nedges
    for s in edges:
        print >> fs, ' '.join([str(i+1) for i in s])
    fs.close()