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
|
#!/usr/bin/env python3
import json
import kconfiglib
import logging
import os
import sys
import numpy as np
numeric_level = getattr(logging, "DEBUG", None)
if not isinstance(numeric_level, int):
print(f"Invalid log level: {loglevel}", file=sys.stderr)
sys.exit(1)
logging.basicConfig(level=numeric_level)
kconfig_path = "/tmp/multipass/Kconfig"
configs_base = "/tmp/multipass-model"
kconf = kconfiglib.Kconfig(kconfig_path)
symbols = sorted(
map(
lambda sym: sym.name,
filter(
lambda sym: kconfiglib.TYPE_TO_STR[sym.type] == "bool", kconf.syms.values()
),
)
)
config_vector = tuple(map(lambda sym: kconf.syms[sym].tri_value == 2, symbols))
with open("kconfigmodel.json", "r") as f:
data = json.load(f)
assert symbols == data["symbols"]
model = data["model"]
kconf.load_config(sys.argv[1])
class DTreeLeaf:
def __init__(self, value, stddev):
self.value = value
self.stddev = stddev
def __repr__(self):
return f"<DTreeLeaf({self.value}, {self.stddev})>"
def model(self, kconf):
return self.value
class DTreeNode:
def __init__(self, symbol, false_child=None, true_child=None):
self.symbol = symbol
self.false_child = false_child
self.true_child = true_child
def set_false_child(self, child_node):
self.false_child = child_node
def set_true_child(self, child_node):
self.true_child = child_node
def __repr__(self):
return f"<DTreeNode({self.false_child}, {self.true_child})>"
def model(self, kconf):
if kconf.syms[self.symbol].tri_value == 2 and self.true_child:
return self.true_child.model(kconf)
elif kconf.syms[self.symbol].tri_value == 0 and self.false_child:
return self.false_child.model(kconf)
return None
def load_model(tree):
if tree is None:
return None
if "value" in tree:
return DTreeLeaf(tree["value"], tree["stddev"])
return DTreeNode(
tree["symbol"], load_model(tree["false"]), load_model(tree["true"])
)
root = load_model(model)
def vector_diff(v1, v2):
return sum(map(lambda i: int(v1[i] != v2[i]), range(len(v1))))
current_model = root.model(kconf)
print(f"Model result: {current_model}")
for symbol in symbols:
kconf_sym = kconf.syms[symbol]
if kconf_sym.tri_value == 0 and 2 in kconf_sym.assignable:
kconf_sym.set_value(2)
new_vector = tuple(map(lambda sym: kconf.syms[sym].tri_value == 2, symbols))
num_changes = vector_diff(config_vector, new_vector)
model_diff = root.model(kconf) - current_model
print(
f"Setting {symbol:30s} to y changes {num_changes:2d} symbols, model change: {model_diff:+5.0f}"
)
elif kconf_sym.tri_value == 2 and 0 in kconf_sym.assignable:
kconf_sym.set_value(0)
new_vector = tuple(map(lambda sym: kconf.syms[sym].tri_value == 2, symbols))
num_changes = vector_diff(config_vector, new_vector)
model_diff = root.model(kconf) - current_model
print(
f"Setting {symbol:30s} to n changes {num_changes:2d} symbols, model change: {model_diff:+5.0f}"
)
kconf.load_config(sys.argv[1])
|