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
|
#!/bin/sh
set -ex
wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2
tar xjf busybox-1.35.0.tar.bz2
rm busybox-1.35.0.tar.bz2
# Generate Config.in files
( cd busybox-1.35.0 ; make gen_build_files )
git clone --recursive https://ess.cs.uos.de/git/software/dfatool.git
dfatool/bin/kconfig-expand-includes busybox-1.35.0/Config.in > busybox-1.35.0/Kconfig
cat > busybox-1.35.0/nfpkeys.json <<__EOF__
{"ELF": {"Size": {"unit": "B", "description": "Binary Size", "minimize": true}, "RAM": {"unit": "B", "description": "static RAM", "minimize": true}}}
__EOF__
cat > busybox-1.35.0/Makefile.local << __EOF__
.PHONY: nfpkeys
nfpkeys:
@cat nfpkeys.json
.PHONY: nfpvalues
nfpvalues:
@scripts/nfpvalues.py size _ data,bss
__EOF__
cat > busybox-1.35.0/scripts/nfpvalues.py << __EOF__
#!/usr/bin/env python3
import json
import re
import subprocess
import sys
def main(size_executable, rom_sections, ram_sections):
rom_sections = rom_sections.split(",")
ram_sections = ram_sections.split(",")
status = subprocess.run(
[size_executable, "-A", "busybox"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
section_size = dict()
for line in status.stdout.split("\n"):
match = re.match("[.](\S+)\s+(\d+)", line)
if match:
section = match.group(1)
size = int(match.group(2))
section_size[section] = size
status = subprocess.run(
["stat", "-c", "%s", "busybox"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
binary_size = int(status.stdout)
total = {
"Size": binary_size,
"RAM": sum(map(lambda section: section_size[section], ram_sections)),
}
output = {"ELF": total}
print(json.dumps(output))
if __name__ == "__main__":
main(*sys.argv[1:])
__EOF__
chmod 755 busybox-1.35.0/scripts/nfpvalues.py
set +ex
cat <<__EOF__
busybox has been prepared for dfatool data acquisition for NFP model generation.
Example usage with random sampling (10,000 samples)
> mkdir data
> cd data
> ../dfatool/bin/explore-kconfig.py --random 10000 ../busybox-1.35.0
Alternatively, you can run multiple build processes in parallel.
> for i in {1..10}; do rsync -a busybox-1.35.0/ busybox-build-\${i}/ ; done
> mkdir data
> cd data
> for i in {1..10}; do ../dfatool/bin/explore-kconfig.py --random 1000 ../busybox-build-\${i} & done
Once everything is done, you have various options for generating a kconfig-webconf performance model.
To do so, call bin/analyze-kconfig.py from the data directory.
For example, to generate a CART:
> DFATOOL_DTREE_SKLEARN_CART=1 DFATOOL_PARAM_CATEGORIAL_TO_SCALAR=1 DFATOOL_KCONF_IGNORE_STRING=1 DFATOOL_KCONF_WITH_CHOICE_NODES=0 ~/var/ess/aemr/dfatool/bin/analyze-kconfig.py --force-tree --skip-param-stats --export-webconf /tmp/busybox-cart.json ../busybox-1.35.0/Kconfig .
By adding the option "--cross-validation kfold:10", you can determine the model prediction error.
__EOF__
|