Skip to content

Commit c0b307f

Browse files
authored
Merge pull request #222 from alwilson/toposort_random_stability
Make list solve_order predictable
2 parents 5f79289 + 46b44a8 commit c0b307f

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

src/vsc/model/rand_info_builder.py

+8-9
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,14 @@ def build(
133133
if f in builder._order_m.keys():
134134
rs_deps[f] = builder._order_m[f]
135135

136-
if len(rs_deps) > 0:
137-
rs.rand_order_l = []
138-
for fs in list(toposort(rs_deps)):
139-
field_l = []
140-
for fi in fs:
141-
if fi in rs.fields():
142-
field_l.append(fi)
143-
if len(field_l) > 0:
144-
rs.rand_order_l.append(field_l)
136+
if len(rs_deps) > 0:
137+
rs.rand_order_l = []
138+
# Random stability warning: toposort uses sets and is unordered
139+
for fs in list(toposort(rs_deps)):
140+
# Add fields in predictable randset order
141+
field_l = [fi for fi in rs.fields() if fi in fs]
142+
if len(field_l) > 0:
143+
rs.rand_order_l.append(field_l)
145144

146145
# It's important to maintain a fixed order for the
147146
# unconstrained fields, since this affects their

ve/unit/test_constraint_solve_order.py

+39
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,42 @@ def loop_c(self):
323323
self.assertNotEqual(0, num_of_nested_loop_hist[1])
324324
self.assertNotEqual(0, num_of_nested_loop_hist[2])
325325

326+
327+
def test_toposort_random_stability(self):
328+
@vsc.randobj
329+
class my_s(object):
330+
331+
def __init__(self):
332+
self.a = vsc.rand_bit_t(8)
333+
self.list_0 = vsc.rand_list_t(vsc.rand_bit_t(8), 10)
334+
self.list_1 = vsc.rand_list_t(vsc.rand_bit_t(8), 10)
335+
336+
@vsc.constraint
337+
def a_and_lists_c(self):
338+
# Excercise rand_order/toposort on lists
339+
vsc.solve_order(self.a, self.list_0)
340+
vsc.solve_order(self.list_0, self.list_1)
341+
342+
# Make lists unique to better detect ordering differences
343+
vsc.unique(self.list_0)
344+
vsc.unique(self.list_1)
345+
346+
# Tie all variables into single randset
347+
self.a > 10
348+
self.a < 20
349+
with vsc.foreach(self.list_0) as it:
350+
it < self.a
351+
with vsc.foreach(self.list_1) as it:
352+
it < self.a
353+
354+
first = my_s()
355+
first.set_randstate(vsc.RandState.mkFromSeed(0))
356+
first.randomize()
357+
358+
for _ in range(20):
359+
repeat = my_s()
360+
repeat.set_randstate(vsc.RandState.mkFromSeed(0))
361+
repeat.randomize()
362+
self.assertEqual(first.a, repeat.a, "Mismatch on a")
363+
self.assertListEqual(list(first.list_0), list(repeat.list_0), "Mismatch on list_0")
364+
self.assertListEqual(list(first.list_1), list(repeat.list_1), "Mismatch on list_1")

0 commit comments

Comments
 (0)