Skip to content

Commit d6cbf78

Browse files
committed
Downsampling seems to work, upsampling not yet
1 parent c9abaf1 commit d6cbf78

File tree

2 files changed

+65
-29
lines changed

2 files changed

+65
-29
lines changed

tools/bitme.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,8 +1634,10 @@ def main():
16341634
Values.CFLOBVDD_fork_level = args.use_CFLOBVDD[0] if len(args.use_CFLOBVDD) > 0 else 0
16351635
Values.CFLOBVDD_swap_level = args.use_CFLOBVDD[1] if len(args.use_CFLOBVDD) > 1 else Values.CFLOBVDD_fork_level
16361636
Values.CFLOBVDD_level = args.use_CFLOBVDD[2] if len(args.use_CFLOBVDD) > 2 else Values.CFLOBVDD_swap_level
1637-
assert 0 <= Values.CFLOBVDD_fork_level <= Values.CFLOBVDD_swap_level <= Values.CFLOBVDD_level, \
1638-
f"invalid fork level {Values.CFLOBVDD_fork_level} or swap level {Values.CFLOBVDD_swap_level} for level {Values.CFLOBVDD_level}"
1637+
assert 0 <= Values.CFLOBVDD_swap_level <= Values.CFLOBVDD_level, \
1638+
f"invalid swap level {Values.CFLOBVDD_swap_level} for level {Values.CFLOBVDD_level}"
1639+
assert 0 <= Values.CFLOBVDD_fork_level <= Values.CFLOBVDD_level, \
1640+
f"invalid fork level {Values.CFLOBVDD_fork_level} for level {Values.CFLOBVDD_level}"
16391641

16401642
level = max(Values.CFLOBVDD_level, Values.CFLOBVDD_swap_level, Values.CFLOBVDD_fork_level,
16411643
ceil(log2(len(Variable.bvdd_input))) if Variable.bvdd_input else 0)

tools/cflobvdd.py

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,12 @@ def representative():
236236
assert BV_Dont_Care_Grouping.representatives.is_consistent()
237237
return BV_Dont_Care_Grouping.representatives
238238

239+
def downsample(self):
240+
if self.is_downsample_cached():
241+
return self.get_cached_downsample()
242+
243+
return BV_No_Distinction_Proto.downsample(self)
244+
239245
def pair_product(self, g2, inorder = True):
240246
assert isinstance(g2, BV_Grouping)
241247

@@ -311,8 +317,8 @@ class BV_Fork_Grouping(BV_Grouping):
311317

312318
def __init__(self, level, swap_level, fork_level, number_of_exits, bvdd):
313319
super().__init__(level, number_of_exits)
314-
assert 0 <= swap_level <= level
315-
assert 0 <= fork_level <= level
320+
assert 0 <= swap_level
321+
assert 0 <= fork_level
316322
self.swap_level = swap_level
317323
self.fork_level = fork_level
318324
self.bvdd = bvdd
@@ -364,11 +370,10 @@ def representative(self):
364370
BV_Fork_Grouping.representatives[self] = self
365371
return BV_Fork_Grouping.representatives[self]
366372

367-
def projection_proto(level, input_i):
368-
# TODO: assert level == 0 and input_i == 0
369-
assert 0 <= input_i < 2**level
370-
bvdd = BVDD.BVDD.projection_proto(input_i)
371-
return BV_Fork_Grouping(level, level, level,
373+
def projection_proto(level, swap_level, fork_level):
374+
assert level == 0
375+
bvdd = BVDD.BVDD.projection_proto(0)
376+
return BV_Fork_Grouping(level, swap_level, fork_level,
372377
bvdd.number_of_exits(), bvdd).representative()
373378

374379
def upsample(self):
@@ -377,14 +382,18 @@ def upsample(self):
377382
if self.is_upsample_cached():
378383
return self.get_cached_upsample()
379384

380-
g_a_bvdd, g_b_bvdds, g_b_return_tuples, _ = self.bvdd.upsample(2**(self.level - 1) - 1)
385+
g_a_bvdd, _, g_b_bvdds, g_b_return_tuples = self.bvdd.upsample(self.level)
381386

382387
# TODO: enable different input orderings
383388
g = BV_Internal_Grouping(self.level, self.swap_level, self.fork_level, True,
384389
len(g_b_return_tuples))
385390

386-
g.a_connection = BV_Fork_Grouping(self.level - 1, self.swap_level, self.fork_level,
387-
g_a_bvdd.number_of_exits(), g_a_bvdd).representative()
391+
if g_a_bvdd.is_constant():
392+
g.a_connection = BV_No_Distinction_Proto.representative(self.level - 1,
393+
self.swap_level, self.fork_level)
394+
else:
395+
g.a_connection = BV_Fork_Grouping(self.level - 1, self.swap_level, self.fork_level,
396+
g_a_bvdd.number_of_exits(), g_a_bvdd).representative()
388397

389398
assert g.a_connection.number_of_exits == len(g_b_bvdds)
390399

@@ -393,15 +402,28 @@ def upsample(self):
393402
g.b_connections = {}
394403

395404
for g_b_i in g_b_bvdds:
396-
g_b = BV_Fork_Grouping(self.level - 1, self.swap_level, self.fork_level,
397-
g_b_bvdds[g_b_i].number_of_exits(), g_b_bvdds[g_b_i]).representative()
405+
if g_b_bvdds[g_b_i].is_constant():
406+
g_b = BV_No_Distinction_Proto.representative(self.level - 1,
407+
self.swap_level, self.fork_level)
408+
else:
409+
g_b = BV_Fork_Grouping(self.level - 1, self.swap_level, self.fork_level,
410+
g_b_bvdds[g_b_i].number_of_exits(), g_b_bvdds[g_b_i]).representative()
398411
g.b_connections[g_b_i] = g_b
399412

400413
assert g_b.number_of_exits == len(g_b_return_tuples[g_b_i])
401414

402415
g.b_return_tuples = g_b_return_tuples
403416

404-
return self.cache_upsample(g.representative())
417+
if g.a_connection.is_no_distinction_proto():
418+
print(self)
419+
420+
if (g.a_connection.is_no_distinction_proto() and
421+
g.number_of_b_connections == 1 and
422+
g.b_connections[1].is_no_distinction_proto()):
423+
return self.cache_upsample(BV_No_Distinction_Proto.representative(self.level,
424+
self.swap_level, self.fork_level))
425+
else:
426+
return self.cache_upsample(g.representative())
405427

406428
def downsample(self):
407429
assert self.level <= self.fork_level
@@ -502,7 +524,8 @@ def reduce(self, reduction_tuple):
502524
assert self.level == self.fork_level
503525

504526
if bvdd.is_constant():
505-
g = No_Distinction_Proto.representative(self.level, self.swap_level, self.fork_level)
527+
g = No_Distinction_Proto.representative(self.level,
528+
self.swap_level, self.fork_level)
506529
else:
507530
g = BV_Fork_Grouping(self.level, self.swap_level, self.fork_level,
508531
reduction_length, bvdd).representative()
@@ -540,7 +563,8 @@ class BV_Internal_Grouping(BV_Grouping):
540563
def __init__(self, level, swap_level, fork_level, a2b, number_of_exits = 0):
541564
assert level > 0
542565
super().__init__(level, number_of_exits)
543-
assert 0 <= fork_level <= swap_level <= level
566+
assert 0 <= swap_level
567+
assert 0 <= fork_level
544568
self.swap_level = swap_level
545569
self.fork_level = fork_level
546570
self.a2b = a2b
@@ -668,8 +692,8 @@ def representative(self):
668692
def projection_proto(level, swap_level, fork_level, input_i):
669693
# generalizing CFLOBDD projection to generational CFLOBVDD projection
670694
assert 0 <= input_i < 2**level
671-
if level == fork_level:
672-
return BV_Fork_Grouping.projection_proto(level, input_i)
695+
if level == 0:
696+
return BV_Fork_Grouping.projection_proto(level, swap_level, fork_level)
673697
else:
674698
g = BV_Internal_Grouping(level, swap_level, fork_level, True)
675699

@@ -836,10 +860,8 @@ def pair_product(self, g2):
836860

837861
if g1.level <= g1.fork_level:
838862
# g1 and g2 are downsampled in original order (decompressing)
839-
pass
840-
# TODO:
841-
#g, pt_ans = g1.downsample().pair_product(g2.downsample())
842-
#return g1_orig.cache_pair_product(g2_orig, g, pt_ans)
863+
g, pt_ans = g1.downsample().pair_product(g2.downsample())
864+
return g1_orig.cache_pair_product(g2_orig, g, pt_ans)
843865

844866
g = BV_Internal_Grouping(g1.level, g1.swap_level, g1.fork_level, g1.a2b)
845867

@@ -957,10 +979,8 @@ def triple_product(self, g2, g3):
957979

958980
if g1.level <= g1.fork_level:
959981
# g1, g2, g3 are downsampled in original order (decompressing)
960-
pass
961-
# TODO:
962-
#g, tt_ans = g1.downsample().triple_product(g2.downsample(), g3.downsample())
963-
#return g1_orig.cache_triple_product(g2_orig, g3_orig, g, tt_ans)
982+
g, tt_ans = g1.downsample().triple_product(g2.downsample(), g3.downsample())
983+
return g1_orig.cache_triple_product(g2_orig, g3_orig, g, tt_ans)
964984

965985
g = BV_Internal_Grouping(g1.level, g1.swap_level, g1.fork_level, g1.a2b)
966986

@@ -1099,7 +1119,8 @@ class BV_No_Distinction_Proto(BV_Internal_Grouping):
10991119

11001120
def __init__(self, level, swap_level, fork_level):
11011121
assert level > 0
1102-
assert 0 <= fork_level <= swap_level <= level
1122+
assert 0 <= swap_level
1123+
assert 0 <= fork_level
11031124
super().__init__(level, swap_level, fork_level, True, 1)
11041125

11051126
def representative(level, swap_level, fork_level):
@@ -1130,6 +1151,16 @@ def swap(self):
11301151
assert self.level > self.swap_level
11311152
return self
11321153

1154+
def downsample(self):
1155+
assert self.level <= self.fork_level
1156+
1157+
if self.is_downsample_cached():
1158+
return self.get_cached_downsample()
1159+
1160+
return self.cache_downsample(BV_Fork_Grouping(self.level,
1161+
self.swap_level, self.fork_level,
1162+
1, BVDD.BVDD.constant(1)).representative())
1163+
11331164
def pair_product(self, g2, inorder = True):
11341165
assert isinstance(g2, BV_Grouping)
11351166

@@ -1320,6 +1351,8 @@ def is_always_true(self):
13201351
return self.number_of_distinct_outputs() == 1 and True in self.outputs.values()
13211352

13221353
def constant(level, swap_level, fork_level, output = 0):
1354+
assert 0 <= swap_level <= level
1355+
assert 0 <= fork_level <= level
13231356
with CFLOBVDD.max_level_lock:
13241357
CFLOBVDD.max_level = max(CFLOBVDD.max_level, level)
13251358
return CFLOBVDD.representative(
@@ -1358,7 +1391,8 @@ def unary_apply_and_reduce(self, op, number_of_output_bits):
13581391
number_of_output_bits)
13591392

13601393
def projection(level, swap_level, fork_level, input_i, reorder = False):
1361-
assert 0 <= fork_level <= swap_level <= level
1394+
assert 0 <= swap_level <= level
1395+
assert 0 <= fork_level <= level
13621396
assert 0 <= input_i < 2**level
13631397
with CFLOBVDD.max_level_lock:
13641398
CFLOBVDD.max_level = max(CFLOBVDD.max_level, level)

0 commit comments

Comments
 (0)