def test_asymmetric_absorb(): class Info(object): def __init__(self, obj): self.values = [obj] def absorb(self, other): self.values += other.values uf = UnionFind(Info) uf.union(2, 3) uf.union(1, 2) assert uf[1].values == uf[2].values == uf[3].values == [1, 2, 3]
def memo(funcdesc, arglist_s): from rpython.annotator.model import SomePBC, SomeImpossibleValue, SomeBool from rpython.annotator.model import unionof # call the function now, and collect possible results argvalues = [] for s in arglist_s: if s.is_constant(): values = [s.const] elif isinstance(s, SomePBC): values = [] assert not s.can_be_None, "memo call: cannot mix None and PBCs" for desc in s.descriptions: if desc.pyobj is None: raise annmodel.AnnotatorError( "memo call with a class or PBC that has no " "corresponding Python object (%r)" % (desc,)) values.append(desc.pyobj) elif isinstance(s, SomeImpossibleValue): return s # we will probably get more possible args later elif isinstance(s, SomeBool): values = [False, True] else: raise annmodel.AnnotatorError("memo call: argument must be a class " "or a frozen PBC, got %r" % (s,)) argvalues.append(values) # the list of all possible tuples of arguments to give to the memo function possiblevalues = cartesian_product(argvalues) # a MemoTable factory -- one MemoTable per family of arguments that can # be called together, merged via a UnionFind. bookkeeper = funcdesc.bookkeeper try: memotables = bookkeeper.all_specializations[funcdesc] except KeyError: func = funcdesc.pyobj if func is None: raise annmodel.AnnotatorError("memo call: no Python function object" "to call (%r)" % (funcdesc,)) def compute_one_result(args): value = func(*args) memotable = MemoTable(funcdesc, args, value) memotable.register_finish() return memotable memotables = UnionFind(compute_one_result) bookkeeper.all_specializations[funcdesc] = memotables # merge the MemoTables for the individual argument combinations firstvalues = possiblevalues.next() _, _, memotable = memotables.find(firstvalues) for values in possiblevalues: _, _, memotable = memotables.union(firstvalues, values) if memotable.graph is not None: return memotable.graph # if already computed else: # otherwise, for now, return the union of each possible result return unionof(*[bookkeeper.immutablevalue(v) for v in memotable.table.values()])
def test_cleanup(): state = [] class ReferencedByExternalState(object): def __init__(self, obj): state.append(self) self.obj = obj def absorb(self, other): state.remove(other) uf = UnionFind(ReferencedByExternalState) uf.find(1) for i in xrange(1, 10, 2): uf.union(i, 1) uf.find(2) for i in xrange(2, 20, 2): uf.union(i, 2) assert len(state) == 2 # we have exactly 2 partitions
def memo(funcdesc, args_s): # call the function now, and collect possible results # the list of all possible tuples of arguments to give to the memo function possiblevalues = cartesian_product([all_values(s_arg) for s_arg in args_s]) # a MemoTable factory -- one MemoTable per family of arguments that can # be called together, merged via a UnionFind. bookkeeper = funcdesc.bookkeeper try: memotables = bookkeeper.all_specializations[funcdesc] except KeyError: func = funcdesc.pyobj if func is None: raise annmodel.AnnotatorError( "memo call: no Python function object" "to call (%r)" % (funcdesc, )) def compute_one_result(args): value = func(*args) memotable = MemoTable(funcdesc, args, value) memotable.register_finish() return memotable memotables = UnionFind(compute_one_result) bookkeeper.all_specializations[funcdesc] = memotables # merge the MemoTables for the individual argument combinations firstvalues = possiblevalues.next() _, _, memotable = memotables.find(firstvalues) for values in possiblevalues: _, _, memotable = memotables.union(firstvalues, values) if memotable.graph is not None: return memotable.graph # if already computed else: # otherwise, for now, return the union of each possible result return unionof( *[bookkeeper.immutablevalue(v) for v in memotable.table.values()])
def memo(funcdesc, args_s): # call the function now, and collect possible results # the list of all possible tuples of arguments to give to the memo function possiblevalues = cartesian_product([all_values(s_arg) for s_arg in args_s]) # a MemoTable factory -- one MemoTable per family of arguments that can # be called together, merged via a UnionFind. bookkeeper = funcdesc.bookkeeper try: memotables = bookkeeper.all_specializations[funcdesc] except KeyError: func = funcdesc.pyobj if func is None: raise annmodel.AnnotatorError("memo call: no Python function object" "to call (%r)" % (funcdesc,)) def compute_one_result(args): value = func(*args) memotable = MemoTable(funcdesc, args, value) memotable.register_finish() return memotable memotables = UnionFind(compute_one_result) bookkeeper.all_specializations[funcdesc] = memotables # merge the MemoTables for the individual argument combinations firstvalues = possiblevalues.next() _, _, memotable = memotables.find(firstvalues) for values in possiblevalues: _, _, memotable = memotables.union(firstvalues, values) if memotable.graph is not None: return memotable.graph # if already computed else: # otherwise, for now, return the union of each possible result return unionof(*[bookkeeper.immutablevalue(v) for v in memotable.table.values()])
def memo(funcdesc, arglist_s): from rpython.annotator.model import SomePBC, SomeImpossibleValue, SomeBool from rpython.annotator.model import unionof # call the function now, and collect possible results argvalues = [] for s in arglist_s: if s.is_constant(): values = [s.const] elif isinstance(s, SomePBC): values = [] assert not s.can_be_None, "memo call: cannot mix None and PBCs" for desc in s.descriptions: if desc.pyobj is None: raise annmodel.AnnotatorError( "memo call with a class or PBC that has no " "corresponding Python object (%r)" % (desc, )) values.append(desc.pyobj) elif isinstance(s, SomeImpossibleValue): return s # we will probably get more possible args later elif isinstance(s, SomeBool): values = [False, True] else: raise annmodel.AnnotatorError( "memo call: argument must be a class " "or a frozen PBC, got %r" % (s, )) argvalues.append(values) # the list of all possible tuples of arguments to give to the memo function possiblevalues = cartesian_product(argvalues) # a MemoTable factory -- one MemoTable per family of arguments that can # be called together, merged via a UnionFind. bookkeeper = funcdesc.bookkeeper try: memotables = bookkeeper.all_specializations[funcdesc] except KeyError: func = funcdesc.pyobj if func is None: raise annmodel.AnnotatorError( "memo call: no Python function object" "to call (%r)" % (funcdesc, )) def compute_one_result(args): value = func(*args) memotable = MemoTable(funcdesc, args, value) memotable.register_finish() return memotable memotables = UnionFind(compute_one_result) bookkeeper.all_specializations[funcdesc] = memotables # merge the MemoTables for the individual argument combinations firstvalues = possiblevalues.next() _, _, memotable = memotables.find(firstvalues) for values in possiblevalues: _, _, memotable = memotables.union(firstvalues, values) if memotable.graph is not None: return memotable.graph # if already computed else: # otherwise, for now, return the union of each possible result return unionof( *[bookkeeper.immutablevalue(v) for v in memotable.table.values()])