TinyverseGP 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- __init__.py +0 -0
- benchmark/__init__.py +0 -0
- benchmark/benchmark.py +23 -0
- benchmark/logic_synthesis/__init__.py +0 -0
- benchmark/logic_synthesis/blif_parser/__init__.py +0 -0
- benchmark/logic_synthesis/blif_parser/blif.py +330 -0
- benchmark/logic_synthesis/boolean_benchmark_tools/__init__.py +0 -0
- benchmark/logic_synthesis/boolean_benchmark_tools/benchmark_evaluator.py +54 -0
- benchmark/logic_synthesis/boolean_benchmark_tools/benchmark_reader.py +475 -0
- benchmark/logic_synthesis/ls_benchmark.py +46 -0
- benchmark/logic_synthesis/lsbench/__init__.py +0 -0
- benchmark/logic_synthesis/lsbench/lsbench.py +309 -0
- benchmark/policy_search/__init__.py +0 -0
- benchmark/policy_search/pl_benchmark.py +120 -0
- benchmark/policy_search/plbench/plbench.py +152 -0
- benchmark/policy_search/policy_evaluation.py +76 -0
- benchmark/program_synthesis/leetcode/happy_number.py +147 -0
- benchmark/program_synthesis/leetcode/palindrome_number.py +65 -0
- benchmark/program_synthesis/leetcode/power_of_three.py +45 -0
- benchmark/program_synthesis/leetcode/power_of_two.py +54 -0
- benchmark/program_synthesis/leetcode/ugly_number.py +66 -0
- benchmark/program_synthesis/ps_benchmark.py +53 -0
- benchmark/symbolic_regression/__init__.py +0 -0
- benchmark/symbolic_regression/sr_benchmark.py +99 -0
- benchmark/symbolic_regression/srbench.py +159 -0
- gp/__init__.py +1 -0
- gp/functions.py +135 -0
- gp/loss.py +127 -0
- gp/problem.py +278 -0
- gp/tiny_3ge.py +631 -0
- gp/tiny_cgp.py +700 -0
- gp/tiny_ge.py +472 -0
- gp/tiny_lgp.py +459 -0
- gp/tiny_tgp.py +521 -0
- gp/tinyverse.py +614 -0
- gp/types.py +7 -0
- gp/util.py +18 -0
- hpo/__init__.py +0 -0
- hpo/hpo.py +157 -0
- hpo/hpo_3ge_model.py +102 -0
- hpo/hpo_model.py +160 -0
- llm/__init__.py +0 -0
- llm/llm.py +67 -0
- llm/tiny_llm.py +349 -0
- nn/__init__.py +0 -0
- nn/nn.py +92 -0
- nn/tiny_ff.py +41 -0
- tinyversegp-0.0.1.dist-info/METADATA +218 -0
- tinyversegp-0.0.1.dist-info/RECORD +52 -0
- tinyversegp-0.0.1.dist-info/WHEEL +5 -0
- tinyversegp-0.0.1.dist-info/licenses/LICENSE +674 -0
- tinyversegp-0.0.1.dist-info/top_level.txt +6 -0
__init__.py
ADDED
|
File without changes
|
benchmark/__init__.py
ADDED
|
File without changes
|
benchmark/benchmark.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class Benchmark(ABC):
|
|
7
|
+
"""
|
|
8
|
+
Abstract base class for the representation of benchmarks.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
@abstractmethod
|
|
12
|
+
def generate(self, args: any):
|
|
13
|
+
"""
|
|
14
|
+
Generator function that creates the benchmark with respect to the
|
|
15
|
+
problem type.
|
|
16
|
+
"""
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
class BenchmarkSuite(Benchmark):
|
|
20
|
+
|
|
21
|
+
@abstractmethod
|
|
22
|
+
def bench(self, args: any):
|
|
23
|
+
pass
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
class BlifFile:
|
|
2
|
+
"""BLIF file parser"""
|
|
3
|
+
|
|
4
|
+
def __init__(self, known_gates=None):
|
|
5
|
+
self.known_gates = []
|
|
6
|
+
for i in range(len(known_gates)):
|
|
7
|
+
g = known_gates[i]
|
|
8
|
+
if g is None:
|
|
9
|
+
g = "-null-"
|
|
10
|
+
self.known_gates.append(g)
|
|
11
|
+
self.initialize_()
|
|
12
|
+
|
|
13
|
+
def parse(self, blif_or_file: str) -> tuple:
|
|
14
|
+
"""
|
|
15
|
+
Parses a BLIF file and returns the number of inputs, outputs and gates.
|
|
16
|
+
The parsed data is stored in the object and can be accessed using the eachGate, eachInput and eachOutput methods.
|
|
17
|
+
|
|
18
|
+
:param blif_or_file: A string containing the BLIF data or a file object
|
|
19
|
+
:return: A tuple containing the number of inputs, outputs and gates
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
if isinstance(blif_or_file, str):
|
|
23
|
+
data = blif_or_file
|
|
24
|
+
assert ".model" in data, "The BLIF file must contain a model."
|
|
25
|
+
else:
|
|
26
|
+
data = blif_or_file.read()
|
|
27
|
+
|
|
28
|
+
self.initialize_()
|
|
29
|
+
|
|
30
|
+
lbuf = ""
|
|
31
|
+
# NOTE: T.S. Disabled unused code
|
|
32
|
+
# lineid = 0
|
|
33
|
+
for line in data.splitlines():
|
|
34
|
+
line = line.strip()
|
|
35
|
+
if not line:
|
|
36
|
+
continue
|
|
37
|
+
if line.endswith("\\"):
|
|
38
|
+
lbuf += line[:-1]
|
|
39
|
+
continue
|
|
40
|
+
if lbuf:
|
|
41
|
+
line = lbuf + line
|
|
42
|
+
lbuf = ""
|
|
43
|
+
line = line.split("#", 1)[0]
|
|
44
|
+
if not line:
|
|
45
|
+
continue
|
|
46
|
+
if line.startswith("."):
|
|
47
|
+
# param
|
|
48
|
+
wordlist = line[1:].split()
|
|
49
|
+
pid, args = wordlist[0], wordlist[1:]
|
|
50
|
+
|
|
51
|
+
if self.tableSpec is not None:
|
|
52
|
+
self._identifyGate()
|
|
53
|
+
|
|
54
|
+
if pid == "names":
|
|
55
|
+
self.tableSpec = args
|
|
56
|
+
if len(args) > 3:
|
|
57
|
+
raise Exception(
|
|
58
|
+
'Invalid number of inputs (1, 2 or 3 input gates are supported only) "%s"'
|
|
59
|
+
% line
|
|
60
|
+
)
|
|
61
|
+
elif pid == "inputs":
|
|
62
|
+
self.inputs = args
|
|
63
|
+
elif pid == "outputs":
|
|
64
|
+
self.outputs = args
|
|
65
|
+
elif pid == "model":
|
|
66
|
+
pass
|
|
67
|
+
elif pid == "end":
|
|
68
|
+
break
|
|
69
|
+
elif pid.startswith("default"):
|
|
70
|
+
pass
|
|
71
|
+
elif pid == "gate":
|
|
72
|
+
args[0] = args[0].upper()
|
|
73
|
+
if args[0] in self.name_conversion:
|
|
74
|
+
args[0] = self.name_conversion[args[0]]
|
|
75
|
+
if args[0] in self.known_gates:
|
|
76
|
+
gtype = self.known_gates.index(args[0])
|
|
77
|
+
elif (args[0] == "ZERO") and ("XOR2" in self.known_gates):
|
|
78
|
+
# constant zero using XOR
|
|
79
|
+
gtype = self.known_gates.index("XOR2")
|
|
80
|
+
elif (args[0] == "ONE") and ("XNOR2" in self.known_gates):
|
|
81
|
+
# constant 1 using XNOR
|
|
82
|
+
gtype = self.known_gates.index("XNOR2")
|
|
83
|
+
else:
|
|
84
|
+
raise Exception(
|
|
85
|
+
'Unknown gate "%s". Supported gate names: %s'
|
|
86
|
+
% (args[0], ",".join(self.known_gates))
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
pin_map = {}
|
|
90
|
+
for a in args[1:]:
|
|
91
|
+
pin_name, map = [b.strip() for b in a.split("=")]
|
|
92
|
+
pin_map[pin_name.upper()] = map
|
|
93
|
+
|
|
94
|
+
if len(pin_map) > 3:
|
|
95
|
+
raise Exception(
|
|
96
|
+
'Invalid number of inputs (1,2 or 3 input gates are supported only) "%s"'
|
|
97
|
+
% line
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
if "B" not in pin_map:
|
|
101
|
+
pin_map["B"] = None
|
|
102
|
+
if "A" not in pin_map:
|
|
103
|
+
pin_map["A"] = None
|
|
104
|
+
|
|
105
|
+
self.gatelist[pin_map["O"]] = BlifGate(
|
|
106
|
+
pin_map["O"], pin_map["A"], pin_map["B"], gtype
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
else:
|
|
110
|
+
raise Exception('Unknown command ".%s"' % pid)
|
|
111
|
+
|
|
112
|
+
elif self.tableSpec is not None:
|
|
113
|
+
line = line.split()
|
|
114
|
+
if len(line) == 1:
|
|
115
|
+
if line[0] == "0":
|
|
116
|
+
self.tableFunc = 0
|
|
117
|
+
else:
|
|
118
|
+
self.tableFunc = 1
|
|
119
|
+
self.tableData.append((line[0]))
|
|
120
|
+
else:
|
|
121
|
+
|
|
122
|
+
if (line[1] != "1") and (line[1] != "0"):
|
|
123
|
+
raise Exception(
|
|
124
|
+
"Invalid BLIF data: %s. Right side should contain 0 for OFF-set or 1 for ON-set"
|
|
125
|
+
% " ".join(line)
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# First data line, initialize tableFunc
|
|
129
|
+
if self.tableFunc is None:
|
|
130
|
+
if line[1] == "0": # OFF-set
|
|
131
|
+
self.tableFunc = (1 << 2 ** (len(self.tableSpec) - 1)) - 1
|
|
132
|
+
else: # ON-set
|
|
133
|
+
self.tableFunc = 0
|
|
134
|
+
|
|
135
|
+
vals = expand(line[0])
|
|
136
|
+
for v in vals:
|
|
137
|
+
self.tableData.append((v, line[1]))
|
|
138
|
+
|
|
139
|
+
expval = 0
|
|
140
|
+
for v in vals:
|
|
141
|
+
# print v, int(v,2)
|
|
142
|
+
expval |= 1 << int(v, 2)
|
|
143
|
+
|
|
144
|
+
if line[1] == "0": # OFF-set
|
|
145
|
+
expval = expval ^ ((1 << 2 ** (len(self.tableSpec) - 1)) - 1)
|
|
146
|
+
self.tableFunc &= expval
|
|
147
|
+
else: # ON-set
|
|
148
|
+
self.tableFunc |= expval
|
|
149
|
+
|
|
150
|
+
else:
|
|
151
|
+
raise Exception("Invalid BLIF data: %s" % line)
|
|
152
|
+
|
|
153
|
+
if self.tableSpec is not None:
|
|
154
|
+
self._identifyGate()
|
|
155
|
+
|
|
156
|
+
# Topological sort of gatelist
|
|
157
|
+
# NOTE: T.S. Disabled unused code
|
|
158
|
+
# remaining = {key: idx for idx, key in enumerate(self.gatelist.keys())}
|
|
159
|
+
g2lev = {}
|
|
160
|
+
for i in self.inputs:
|
|
161
|
+
g2lev[i] = 0
|
|
162
|
+
|
|
163
|
+
def prop(g):
|
|
164
|
+
if g in g2lev:
|
|
165
|
+
return g2lev[g]
|
|
166
|
+
ina = self.gatelist[g].ina
|
|
167
|
+
ina = prop(ina) if (ina is not None) else 0
|
|
168
|
+
inb = self.gatelist[g].inb
|
|
169
|
+
inb = prop(inb) if (inb is not None) else 0
|
|
170
|
+
g2lev[g] = max(ina, inb) + 1
|
|
171
|
+
return g2lev[g]
|
|
172
|
+
|
|
173
|
+
for o in self.outputs:
|
|
174
|
+
prop(o)
|
|
175
|
+
|
|
176
|
+
g2lev = sorted(g2lev.items(), key=lambda x: x[1])
|
|
177
|
+
self.toposorted = [g for g, lev in g2lev if g not in self.inputs]
|
|
178
|
+
|
|
179
|
+
return len(self.inputs), len(self.outputs), len(self.gatelist)
|
|
180
|
+
|
|
181
|
+
def eachGate(self):
|
|
182
|
+
"""Returns an iterator over the gates"""
|
|
183
|
+
for g in self.toposorted:
|
|
184
|
+
yield self.gatelist[g]
|
|
185
|
+
|
|
186
|
+
def eachInput(self):
|
|
187
|
+
"""Returns an iterator over the inputs"""
|
|
188
|
+
for i in self.inputs:
|
|
189
|
+
yield i
|
|
190
|
+
|
|
191
|
+
def eachOutput(self):
|
|
192
|
+
"""Returns an iterator over the outputs"""
|
|
193
|
+
for o in self.outputs:
|
|
194
|
+
yield o
|
|
195
|
+
|
|
196
|
+
def initialize_(self):
|
|
197
|
+
self.outputs = []
|
|
198
|
+
self.inputs = []
|
|
199
|
+
self.gatelist = {}
|
|
200
|
+
self.toposorted = []
|
|
201
|
+
self.tableSpec = None
|
|
202
|
+
self.tableData = []
|
|
203
|
+
self.tableFunc = None
|
|
204
|
+
self.result = None
|
|
205
|
+
self.name_conversion = {
|
|
206
|
+
"INV1": "INVA",
|
|
207
|
+
"INV": "INVA",
|
|
208
|
+
"NOR": "NOR2",
|
|
209
|
+
"OR": "OR2",
|
|
210
|
+
"AND": "AND2",
|
|
211
|
+
"NAND": "NAND2",
|
|
212
|
+
"XNOR": "XNOR2",
|
|
213
|
+
"XOR": "XOR2",
|
|
214
|
+
"XORA": "XOR2",
|
|
215
|
+
"XORA2": "XOR2",
|
|
216
|
+
"XORB2": "XOR2",
|
|
217
|
+
"XNORA": "XNOR2",
|
|
218
|
+
"XNORA2": "XNOR2",
|
|
219
|
+
"XNORB2": "XNOR2",
|
|
220
|
+
"BUF": "IDA",
|
|
221
|
+
"BUF1": "IDA",
|
|
222
|
+
"WIRE": "IDA",
|
|
223
|
+
"ZERO0": "ZERO",
|
|
224
|
+
"ONE0": "ONE",
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
def _identifyGate(self):
|
|
228
|
+
if self.tableSpec is None:
|
|
229
|
+
if len(self.tableData):
|
|
230
|
+
raise Exception("Internal error")
|
|
231
|
+
return
|
|
232
|
+
|
|
233
|
+
if len(self.tableSpec) == 1:
|
|
234
|
+
if self.tableFunc is None:
|
|
235
|
+
self.tableFunc = 0
|
|
236
|
+
|
|
237
|
+
# const 0 = XOR2, const 1 = XNOR2
|
|
238
|
+
func2gate = {0: "XOR2", 1: "XNOR2"}
|
|
239
|
+
try:
|
|
240
|
+
gtype = self.known_gates.index(func2gate[self.tableFunc])
|
|
241
|
+
except Exception:
|
|
242
|
+
raise Exception(
|
|
243
|
+
"Unknown constant. Truth table: %s Index: %d"
|
|
244
|
+
% (str(self.tableData), self.tableFunc)
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
self.gatelist[self.tableSpec[0]] = BlifGate(
|
|
248
|
+
self.tableSpec[0], None, None, gtype
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
elif len(self.tableSpec) == 2:
|
|
252
|
+
# 1-input, 1-output
|
|
253
|
+
func2gate = {1: "INVA", 2: "IDA"}
|
|
254
|
+
try:
|
|
255
|
+
gtype = self.known_gates.index(func2gate[self.tableFunc])
|
|
256
|
+
except Exception:
|
|
257
|
+
raise Exception(
|
|
258
|
+
"Unknown 1-input gate. Truth table: %s Index: %d"
|
|
259
|
+
% (
|
|
260
|
+
",".join(["%s:%s" % (a, b) for a, b in self.tableData]),
|
|
261
|
+
self.tableFunc,
|
|
262
|
+
)
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
self.gatelist[self.tableSpec[1]] = BlifGate(
|
|
266
|
+
self.tableSpec[1], self.tableSpec[0], None, gtype
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
else:
|
|
270
|
+
# 2-inputs, 1-output
|
|
271
|
+
func2gate = {
|
|
272
|
+
1: "NOR2",
|
|
273
|
+
6: "XOR2",
|
|
274
|
+
7: "NAND2",
|
|
275
|
+
8: "AND2",
|
|
276
|
+
14: "OR2",
|
|
277
|
+
9: "XNOR2",
|
|
278
|
+
2: "AND2NOTA",
|
|
279
|
+
4: "AND2NOTB",
|
|
280
|
+
11: "OR2NOTA",
|
|
281
|
+
13: "OR2NOTB",
|
|
282
|
+
}
|
|
283
|
+
try:
|
|
284
|
+
gtype = self.known_gates.index(func2gate[self.tableFunc])
|
|
285
|
+
except Exception:
|
|
286
|
+
raise Exception(
|
|
287
|
+
"Unknown 2-input gate. Truth table: {%s} Function index: %d"
|
|
288
|
+
% (
|
|
289
|
+
",".join(["%s:%s" % (a, b) for a, b in self.tableData]),
|
|
290
|
+
self.tableFunc,
|
|
291
|
+
)
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
self.gatelist[self.tableSpec[2]] = BlifGate(
|
|
295
|
+
self.tableSpec[2], self.tableSpec[0], self.tableSpec[1], gtype
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
self.tableSpec = None
|
|
299
|
+
self.tableData = []
|
|
300
|
+
self.tableFunc = None
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
class BlifGate:
|
|
304
|
+
def __init__(self, name, ina, inb, fun):
|
|
305
|
+
self.name = name
|
|
306
|
+
self.ina = ina
|
|
307
|
+
self.inb = inb
|
|
308
|
+
self.fun = fun
|
|
309
|
+
self.lev = None
|
|
310
|
+
self.levidx = None
|
|
311
|
+
|
|
312
|
+
def arity(self):
|
|
313
|
+
return 0 + (self.ina is not None) + (self.inb is not None)
|
|
314
|
+
|
|
315
|
+
def __repr__(self):
|
|
316
|
+
return "Gate<%s>(%s,%s)" % (self.fun, self.ina, self.inb)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def expand(inp):
|
|
320
|
+
i = inp.find("-")
|
|
321
|
+
res = []
|
|
322
|
+
if i > -1:
|
|
323
|
+
s1 = inp[0:i]
|
|
324
|
+
s2 = inp[i + 1 :]
|
|
325
|
+
res.extend(expand(s1 + "0" + s2))
|
|
326
|
+
res.extend(expand(s1 + "1" + s2))
|
|
327
|
+
else:
|
|
328
|
+
res.append(inp)
|
|
329
|
+
|
|
330
|
+
return res
|
|
File without changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Provides an evaluator that can be used for the evalution of the benchmarks of the
|
|
3
|
+
General Boolean Function Benchmark Suite (GBFS):
|
|
4
|
+
https://dl.acm.org/doi/abs/10.1145/3594805.3607131
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BenchmarkEvaluator:
|
|
9
|
+
"""Evaluator class that evaluates compressed and uncompressed output pairs
|
|
10
|
+
by calculating the the hamming distance."""
|
|
11
|
+
|
|
12
|
+
def evaluate(
|
|
13
|
+
self, x: list, y: list, compressed: bool = False, bit_length: int = None
|
|
14
|
+
) -> int:
|
|
15
|
+
"""
|
|
16
|
+
Triggers the evaluation with the Hamming distance. Distinguishes between compressed and uncompressed
|
|
17
|
+
output pairs of a candidate program/model and the real output values of a truth table that are passed to the function.
|
|
18
|
+
"""
|
|
19
|
+
if len(x) != len(y):
|
|
20
|
+
raise ValueError("Dimensions do not match.")
|
|
21
|
+
|
|
22
|
+
if not compressed:
|
|
23
|
+
return self.hamming_distance(x, y)
|
|
24
|
+
else:
|
|
25
|
+
return self.hamming_distance(
|
|
26
|
+
x, y, compressed=compressed, bit_length=bit_length
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def hamming_distance(
|
|
30
|
+
self, x: list, y: list, compressed: bool = False, bit_length: int = None
|
|
31
|
+
) -> int:
|
|
32
|
+
"""
|
|
33
|
+
Calculates the hamming distance which is defined as
|
|
34
|
+
the number of different bits between x and y.
|
|
35
|
+
|
|
36
|
+
:param x: list with output values from the candidate model or program
|
|
37
|
+
:param y: list with real output values
|
|
38
|
+
:compressed: status of truthtable (compressed or uncompressed)
|
|
39
|
+
:bit_length: number of bits for each chunk of an uncompressed truth table
|
|
40
|
+
"""
|
|
41
|
+
dist = 0
|
|
42
|
+
if compressed:
|
|
43
|
+
for xi, yi in zip(x, y):
|
|
44
|
+
# Bitwise XOR the chunks to identify dissimilar bits
|
|
45
|
+
cmp = xi ^ yi
|
|
46
|
+
for i in range(bit_length):
|
|
47
|
+
# Sum up the number of 1s then
|
|
48
|
+
dist += cmp & 1
|
|
49
|
+
cmp = cmp >> 1
|
|
50
|
+
else:
|
|
51
|
+
for xi, yi in zip(x, y):
|
|
52
|
+
if xi != yi:
|
|
53
|
+
dist += 1
|
|
54
|
+
return dist
|