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 5.81 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.env
43
44
45
46
47

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

John Zhang's avatar
John Zhang committed
48
        mudir = 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
        if impl == 'holstein':
John Zhang's avatar
John Zhang committed
57
            include_dirs.append(mudir / 'cbinding')
58
        elif impl == 'zebu':
John Zhang's avatar
John Zhang committed
59
            include_dirs.append(mudir / 'src' / 'vm' / 'api')
60
        cc['include_dirs'] = include_dirs
61

62
63
        # library dirs
        library_dirs = cc.get('library_dirs', [])
64
65
66
        libmu_dir = ''
        libname = ''
        if impl == 'holstein':
John Zhang's avatar
John Zhang committed
67
            libmu_dir = mudir / 'cbinding'
68
69
            libname = 'murefimpl2start'
        elif impl == 'zebu':
John Zhang's avatar
John Zhang committed
70
            libmu_dir = mudir / 'target' / env.get('ZEBU_BUILD', 'release')
71
            libname = 'mu'
72
73
74
75
        library_dirs.append(libmu_dir)
        cc['library_dirs'] = library_dirs
        cc.setdefault('libmu_link_name', libname)

John Zhang's avatar
John Zhang committed
76
        # vmarg
John Zhang's avatar
John Zhang committed
77
78
79
        def set_default_args(defl_d, vmargs):
            # include default args if not specified, otherwise use custom-defined value
            for key, val in defl_d.items():
80
                if not key in vmargs:
John Zhang's avatar
John Zhang committed
81
82
83
84
                    vmargs.append('%(key)s=%(val)s' % locals())
            return vmargs

        vmargs = list(map(lambda a: expandenv(a, task.env), cc.get('vmargs', [])))
85
        libcb = task.taskset.callback['dylib']
John Zhang's avatar
John Zhang committed
86
87
        if lc['impl'] == 'holstein':
            separators = '\n'
88
89
90
            default_args = {
                'extraLibs': str(libcb)
            }
John Zhang's avatar
John Zhang committed
91
92
93
94
        else:   # zebu
            separators = ' '
            emit_dir = task.output_dir / ('%s_%s-emit' % (task.taskset.name, task.name))
            default_args = {
95
96
97
                '--aot-emit-dir': str(emit_dir),
                '--bootimage-external-libpath': str(libcb.parent),
                '--bootimage-external-lib': "cb_%(name)s" % task.callback   # libcb_%(name)s.so/dylib
John Zhang's avatar
John Zhang committed
98
            }
99
        vmarg_s = separators.join(set_default_args(default_args, vmargs))
100
101
        if lc['impl'] == 'zebu':
            vmarg_s = 'init_mu ' + vmarg_s
John Zhang's avatar
John Zhang committed
102
        cc['vmarg_s'] = vmarg_s
103
104
105
        return cc

    @classmethod
106
107
    def check_runner(cls, rc, lc, task):
        env = task.env
108
        if lc['impl'] == 'holstein':
109
110
111
112
            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))
113

114
115
116
            holstein_default_flags = [
                '--uPtrHack=True',
                '--extraLibs=%s' % task.taskset.callback['dylib']]
117
118
119
120
121
122
            rc['flags'] = holstein_default_flags + rc.get('flags', [])
        return rc

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

John Zhang's avatar
John Zhang committed
124
125
        cc = task.compiler
        lc = task.lang
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

        # 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)

141
142
        target = cls.get_default_target(task)
        build_target = target.with_name('build_' + target.name)
143
        flags.extend(['-o', str(build_target)])
John Zhang's avatar
John Zhang committed
144

145
        cmd.extend(flags)
John Zhang's avatar
John Zhang committed
146

147
        bm_src = task.srcfile
148
149
150
        srcs = [
            callback_dir / 'build_callbacks.c',
            callback_dir / 'main.c',
151
            bm_src
152
        ]
153
        cmd.extend(srcs)
John Zhang's avatar
John Zhang committed
154

John Zhang's avatar
John Zhang committed
155
        cls.run_in_subproc(cmd, task.env)
John Zhang's avatar
John Zhang committed
156

157
158
159
        assert build_target.exists()

        # Then run the build program to get the boot image
160

161
        cmd = [build_target]
John Zhang's avatar
John Zhang committed
162
        cmd.append(cc['vmarg_s'])
163
        cmd.append(target.absolute())
164

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

John Zhang's avatar
John Zhang committed
167
        assert target.exists()
168
        return target
John Zhang's avatar
John Zhang committed
169
170

    @classmethod
171
    def run(cls, target, task):
172
        cmd = []
John Zhang's avatar
John Zhang committed
173
174
        rc = task.runner
        lc = task.lang
175

176
        if lc['impl'] == 'holstein':
177
178
179
180
            cmd.append(rc['exec'])
            cmd.extend(rc.get('flags', []))

        cmd.append(target)
John Zhang's avatar
John Zhang committed
181
182

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

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

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