GitLab will be upgraded on 30 Jan 2023 from 2.00 pm (AEDT) to 3.00 pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

mu.py 4.94 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python3
# Copyright 2017 The Australian National University
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

John Zhang's avatar
John Zhang committed
16
17
18
19
import subprocess as subproc
import os
from pathlib import Path

John Zhang's avatar
John Zhang committed
20
21
22
from mubench.lang import Language
from mubench import CALLBACKS_DIR
from mubench.exceptions import ExecutionFailure
23
from mubench.util import expandenv
John Zhang's avatar
John Zhang committed
24
25
26
27


class Mu(Language):
    name = 'mu'
Zixian Cai's avatar
PEP 8    
Zixian Cai committed
28
    src_ext = 'c'  # one or a folder of C files calling API to build the bundle
John Zhang's avatar
John Zhang committed
29
    compiled = True
Zixian Cai's avatar
PEP 8    
Zixian Cai committed
30
    default_exec = 'clang'  # assume presence of clang
31
    known_impls = ('holstein', 'zebu')
John Zhang's avatar
John Zhang committed
32
33

    @classmethod
John Zhang's avatar
John Zhang committed
34
    def check_lang(cls, lc):
35
36
37
        assert 'impl' in lc, "Mu impl not specified"
        assert lc['impl'] in cls.known_impls, 'invalid impl: %(impl)s' % lc
        return lc
John Zhang's avatar
John Zhang committed
38

39
    @classmethod
John Zhang's avatar
John Zhang committed
40
    def check_compiler(cls, cc, lc, task):
41
        impl = lc['impl']
John Zhang's avatar
John Zhang committed
42
        env = task.evn
43
44
45
46
47
48

        # check Mu impl environment variable
        v = 'MU_%s' % (impl.upper())
        assert v in env, '%s needs to be defined in environ.'

        mu_dir = Path(env[v])
John Zhang's avatar
John Zhang committed
49

50
51
        exe = cc.get('exec', cls.default_exec)
        cc['exec'] = expandenv(exe, env)
52

53
54
55
        # include dirs
        include_dirs = cc.get('include_dirs', [])
        include_dirs.append(CALLBACKS_DIR / cls.name)
56
57
58
        if impl == 'holstein':
            include_dirs.append(mu_dir / 'cbinding')
        elif impl == 'zebu':
59
            include_dirs.append(mu_dir / 'src' / 'vm' / 'api')
60
        cc['include_dirs'] = include_dirs
61

62
63
        # library dirs
        library_dirs = cc.get('library_dirs', [])
64
65
66
67
68
69
        libmu_dir = ''
        libname = ''
        if impl == 'holstein':
            libmu_dir = mu_dir / 'cbinding'
            libname = 'murefimpl2start'
        elif impl == 'zebu':
70
            libmu_dir = mu_dir / 'target' / env.get('ZEBU_BUILD', 'release')
71
            libname = 'mu'
72
73
74
75
76
77
78
79
80
        library_dirs.append(libmu_dir)
        cc['library_dirs'] = library_dirs
        cc.setdefault('libmu_link_name', libname)

        return cc

    @classmethod
    def check_runner(cls, rc, lc, env):
        if lc['impl'] == 'holstein':
81
82
83
84
            mu_holstein_dir = Path(env['MU_HOLSTEIN'])
            default_exec = mu_holstein_dir / 'tools' / 'runmu.sh'
            rc.setdefault('exec', default_exec)
            rc['exec'] = Path(expandenv(str(rc['exec']), env))
85
86
87
88
89
90
91
92

            holstein_default_flags = ['--uPtrHack=True']
            rc['flags'] = holstein_default_flags + rc.get('flags', [])
        return rc

    @classmethod
    def compile(cls, task):
        callback_dir = CALLBACKS_DIR / cls.name
93

John Zhang's avatar
John Zhang committed
94
95
        cc = task.compiler
        lc = task.lang
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110

        # First compile the build scripts
        cmd = []
        cmd.append(cc['exec'])

        # flags
        flags = []

        impl = lc['impl']
        flags.append('-DMU_IMPL_%s' % impl.upper())

        flags.extend(['-I%s' % d for d in cc['include_dirs']])
        flags.extend(['-L%s' % d for d in cc['library_dirs']])
        flags.append('-l%(libmu_link_name)s' % cc)

John Zhang's avatar
John Zhang committed
111
112
        target_dir = task.output_dir
        build_target = target_dir / task.resfile.name[:-2]
113
        flags.extend(['-o', str(build_target)])
John Zhang's avatar
John Zhang committed
114

115
        cmd.extend(flags)
John Zhang's avatar
John Zhang committed
116

John Zhang's avatar
John Zhang committed
117
        bm_src = task.resfile
118
119
120
        srcs = [
            callback_dir / 'build_callbacks.c',
            callback_dir / 'main.c',
121
            callback_dir / ('build_cb_%(name)s.c' % task.callback),
122
            bm_src
123
        ]
124
        cmd.extend(srcs)
John Zhang's avatar
John Zhang committed
125

John Zhang's avatar
John Zhang committed
126
        cls.run_in_subproc(cmd, task.env)
John Zhang's avatar
John Zhang committed
127

128
129
130
        assert build_target.exists()

        # Then run the build program to get the boot image
131
132
        if bm_src.name.startswith('build_'):
            target_name = '%s-%s-mu' % (bm_src.name[len('build_'):-2],
John Zhang's avatar
John Zhang committed
133
                                        task.callback['name'])
134
        else:
135
            target_name = 'bootimg-' + bm_src.name[:-2]
136
        target = target_dir / target_name
137
        cmd = [build_target]
John Zhang's avatar
John Zhang committed
138
        cmd.append(cc.get('vmarg', ""))
139
        cmd.append(target)
140

John Zhang's avatar
John Zhang committed
141
        cls.run_in_subproc(cmd, task.env)
142

John Zhang's avatar
John Zhang committed
143
        assert target.exists()
144
        return target
John Zhang's avatar
John Zhang committed
145
146

    @classmethod
147
    def run(cls, target, task):
148
        cmd = []
John Zhang's avatar
John Zhang committed
149
150
        rc = task.runner
        lc = task.lang
151

152
153
154
155
156
157
158
159
        if 'exec' in rc:
            cmd.append(rc['exec'])
            cmd.extend(rc.get('flags', []))

        if lc['impl'] == 'holstein':
            cmd.extend(rc['flags'])

        cmd.append(target)
John Zhang's avatar
John Zhang committed
160
161

        # first argument: callback param
John Zhang's avatar
John Zhang committed
162
        cmd.append(task.callback['param'])
John Zhang's avatar
John Zhang committed
163

John Zhang's avatar
John Zhang committed
164
        cmd.extend(task.benchmark['args'])
John Zhang's avatar
John Zhang committed
165

John Zhang's avatar
John Zhang committed
166
        return cls.run_in_subproc(cmd, task.env)