summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/images/python-pgo-image.bb
blob: e16cd524864d0653406858769c89b0a4ea88292d (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
SUMMARY = "Minimal image for doing Python profiling (for PGO)"

IMAGE_FEATURES += "ssh-server-dropbear"
IMAGE_INSTALL = "packagegroup-core-boot"
IMAGE_INSTALL += "python-profile-opt python-profile-opt-tests python-profile-opt-tools"
IMAGE_INSTALL += "python-profile-opt3 python-profile-opt3-tests"

LICENSE = "MIT"

inherit core-image

PYTHON_PROFILE_DIR ?= "${TMPDIR}/work-shared/${MACHINE}/python/pgo-data"
PROFILE_DATA_WORKDIR = "${WORKDIR}/profile-data"
#PYTHON_PROFILE_TASK_DEFAULT = "-m test.regrtest --pgo -w -x test_asyncore test_gdb test_multiprocessing test_subprocess"
## Exclude tests that are segfaulting on qemux86 target
#PYTHON_PROFILE_TASK_DEFAULT += "test_bytes test_str test_string test_tuple test_unicode test_userstring test_xmlrpc"
## Exclude tests that are failing on qemux86
#PYTHON_PROFILE_TASK_DEFAULT += "test_StringIO test_builtin test_calendar test_cmath test_ctypes test_distutils test_exceptions test_getargs test_gzip test_json test_math test_shutil test_socket test_sqlite test_sysconfig test_traceback test_warnings"
## Exclude tests that are taking very long on qemux86
#PYTHON_PROFILE_TASK_DEFAULT += "test_io test_lib2to3 test_itertools"
PYTHON_PROFILE_TASK_DEFAULT = "/opt/share/doc/python-profile-opt/Tools/pybench/pybench.py -n 2 --with-gc --with-syscheck"
PYTHON_PROFILE_TASK ?= "${PYTHON_PROFILE_TASK_DEFAULT}"

PYTHON3_PROFILE_DIR ?= "${TMPDIR}/work-shared/${MACHINE}/python3/pgo-data"
PYTHON3_PROFILE_TASK_DEFAULT = "-m test.regrtest --pgo -w -x test_asyncore test_gdb test_multiprocessing_fork test_multiprocessing_forkserver test_multiprocessing_main_handling test_multiprocessing_spawn test_subprocess"
# Exclude tests that are failing on qemux86
PYTHON3_PROFILE_TASK_DEFAULT += "test_builtin test_cmath test_concurrent_futures test_difflib test_distutils test_float test_format test_math test_optparse test_shutil test_statistics test_types test_unicode"
# Exclude tests that are taking very long on qemux86
PYTHON3_PROFILE_TASK_DEFAULT += "test_lib2to3 test_buffer test_pickle test_io test_threading test_asyncio test_urllib2_localnet test_itertools test_tuple test_trace test_tarfile test_unicodedata test_decimal"
PYTHON3_PROFILE_TASK_DEFAULT += "test_long test_zipfile test_deque test_descr test_email test_venv test_bytes test_compileall test_ast test_multibytecodec"

PYTHON3_PROFILE_TASK ?= "${PYTHON3_PROFILE_TASK_DEFAULT}"

# We need these because we're utilizing the runtime test helpers from oeqa
TEST_TARGET ?= "qemu"
TEST_QEMUBOOT_TIMEOUT ?= "1000"
TEST_LOG_DIR ?= "${WORKDIR}/qemulogs"
FIND_ROOTFS = "1"

def run_profile(d, profile_bin, profile_task, tgt_in_dir, host_out_dir):
    from oeqa.targetcontrol import get_target_controller
    from oe.utils import getstatusoutput

    target = get_target_controller(d)
    target.deploy()
    try:
        # Boot target
        bootparams = None
        if d.getVar('VIRTUAL-RUNTIME_init_manager', True) == 'systemd':
            bootparams = 'systemd.log_level=debug systemd.log_target=console'
        target.start(extra_bootparams=bootparams)

        # Run profile task
        ret, output = target.run(profile_bin + ' ' + profile_task, timeout=7200)
        if ret:
            bb.fatal("Failed to run profile task on target: %s" % output)
        ret, output = target.run('tar czf pgo-data.tgz -C %s .' % tgt_in_dir)
        if ret:
            bb.fatal("Failed to archive profile data on target: %s" % output)

        # Retrieve and unpack profile data
        target.copy_from('/home/root/pgo-data.tgz', host_out_dir)

        profile_tarball = os.path.join(host_out_dir, 'pgo-data.tgz')
        ret, output = getstatusoutput('tar xf %s -C %s' % (profile_tarball, host_out_dir))
        os.unlink(profile_tarball)
        if ret:
            bb.fatal("Failed to unpack python profile data: %s" % output)
    finally:
        target.stop()


# Profile task for Python2
python do_profile() {
    outdir = os.path.join(d.getVar("PROFILE_DATA_WORKDIR", True), 'python')
    run_profile(d, 'LD_LIBRARY_PATH=/opt/lib /opt/bin/python',
                d.getVar('PYTHON_PROFILE_TASK', True),
                '/home/root/python-pgo-profiles/',
                outdir)
    # Exclude files causing problems in cross-profiling
    excludes = [os.path.join(outdir, 'Modules', 'posixmodule.gcda')]
    for path in excludes:
        if os.path.exists(path):
            os.unlink(path)
}

addtask profile after do_build
do_profile[depends] += "qemu-native:do_populate_sysroot qemu-helper-native:do_populate_sysroot"
do_profile[cleandirs] = "${PROFILE_DATA_WORKDIR}/python"

python do_profile_setscene () {
    sstate_setscene(d)
}

SSTATETASKS += "do_profile"
do_profile[sstate-inputdirs] = "${PROFILE_DATA_WORKDIR}/python"
do_profile[sstate-outputdirs] = "${PYTHON_PROFILE_DIR}"
addtask do_profile_setscene


# Profile task for Python3
python do_profile3() {
    run_profile(d, 'LD_LIBRARY_PATH=/opt/lib /opt/bin/python3',
                d.getVar('PYTHON3_PROFILE_TASK', True),
                '/home/root/python3-pgo-profiles/',
                os.path.join(d.getVar("PROFILE_DATA_WORKDIR", True), 'python3'))
}

addtask profile3 after do_build
do_profile3[depends] += "qemu-native:do_populate_sysroot qemu-helper-native:do_populate_sysroot"
do_profile3[cleandirs] = "${PROFILE_DATA_WORKDIR}/python3"

python do_profile3_setscene () {
    sstate_setscene(d)
}

SSTATETASKS += "do_profile3"
do_profile3[sstate-inputdirs] = "${PROFILE_DATA_WORKDIR}/python3"
do_profile3[sstate-outputdirs] = "${PYTHON3_PROFILE_DIR}"
addtask do_profile3_setscene