[pypy-svn] r33120 - in pypy/dist/pypy/objspace: . cclp cclp/constraint
auc at codespeak.net
auc at codespeak.net
Tue Oct 10 17:54:23 CEST 2006
Author: auc
Date: Tue Oct 10 17:54:01 2006
New Revision: 33120
Modified:
pypy/dist/pypy/objspace/cclp/constraint/constraint.py
pypy/dist/pypy/objspace/cclp/constraint/distributor.py
pypy/dist/pypy/objspace/cclp/constraint/variable.py
pypy/dist/pypy/objspace/cclp/interp_var.py
pypy/dist/pypy/objspace/cclp/scheduler.py
pypy/dist/pypy/objspace/cclp/space.py
pypy/dist/pypy/objspace/cclp/thread.py
pypy/dist/pypy/objspace/cclp/thunk.py
pypy/dist/pypy/objspace/cclp/variable.py
pypy/dist/pypy/objspace/logic.py
Log:
interpreted clone (for constraint problems), removal of many debug prints -- probably not translatable right now
Modified: pypy/dist/pypy/objspace/cclp/constraint/constraint.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/constraint/constraint.py (original)
+++ pypy/dist/pypy/objspace/cclp/constraint/constraint.py Tue Oct 10 17:54:01 2006
@@ -1,3 +1,4 @@
+from pypy.rpython.objectmodel import we_are_translated
from pypy.interpreter.error import OperationError
from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter import baseobjspace, typedef, gateway
@@ -43,8 +44,7 @@
def w_revise(self):
return self._space.newbool(self.revise())
-
-
+
W_AbstractConstraint.typedef = typedef.TypeDef(
"W_AbstractConstraint",
W_Constraint.typedef,
@@ -92,6 +92,14 @@
# self.filter_func is a function taking keyword arguments and returning a boolean
self.filter_func = self._space.make_filter(w_variables, w_formula)
+ def copy(self):
+ if we_are_translated():
+ raise NotImplementedError
+ else:
+ newvars = [var.copy(self._space) for var in self._variables]
+ const = W_Expression(self._space, self._space.newlist(newvars), self._space.wrap(self.formula))
+ return const
+
def _init_result_cache(self):
"""key = (variable,value), value = [has_success,has_failure]"""
result_cache = self._space.newdict()
@@ -229,6 +237,14 @@
# worst case complexity
#self.__cost = len(w_variables.wrappeditems) * (len(w_variables.wrappeditems) - 1) / 2
+ def copy(self):
+ if we_are_translated():
+ raise NotImplementedError
+ else:
+ newvars = [var.copy(self._space) for var in self._variables]
+ const = W_AllDistinct(self._space, self._space.newlist(newvars))
+ return const
+
def revise(self):
_spc = self._space
Modified: pypy/dist/pypy/objspace/cclp/constraint/distributor.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/constraint/distributor.py (original)
+++ pypy/dist/pypy/objspace/cclp/constraint/distributor.py Tue Oct 10 17:54:01 2006
@@ -14,18 +14,18 @@
assert isinstance(w_strategy, W_StringObject)
strat = space.str_w(w_strategy)
cspace = get_current_cspace(space)
+ dist = None
if strat == 'dichotomy':
- cspace.distributor = make_split_distributor(space, space.newint(2))
+ dist = make_split_distributor(space, space.newint(2))
else:
raise OperationError(space.w_RuntimeError,
space.wrap("please pick a strategy in (naive, dichotomy)"))
- dist = cspace.distributor
+ cspace.distributor = dist
# constraint distributor thread main loop
while dist.distributable():
choice = cspace.choose(dist.fanout())
dist.w_distribute(choice)
-
app_distribute = interp2app(distribute)
Modified: pypy/dist/pypy/objspace/cclp/constraint/variable.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/constraint/variable.py (original)
+++ pypy/dist/pypy/objspace/cclp/constraint/variable.py Tue Oct 10 17:54:01 2006
@@ -16,7 +16,7 @@
assert isinstance(w_name, W_StringObject)
w_dom = W_FiniteDomain(space, w_values)
w_var = W_CVar(space, w_dom, w_name)
- w("CVAR", str(w_var))
+ #w("CVAR", str(w_var))
return w_var
app_domain = gateway.interp2app(domain)
Modified: pypy/dist/pypy/objspace/cclp/interp_var.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/interp_var.py (original)
+++ pypy/dist/pypy/objspace/cclp/interp_var.py Tue Oct 10 17:54:01 2006
@@ -40,7 +40,7 @@
def interp_assign_aliases(w_var, w_val):
- w(" :assign")
+ #w(" :assign")
assert isinstance(w_var, W_Var)
w_curr = w_var
while 1:
@@ -54,10 +54,10 @@
# switch to next
w_curr = w_next
_assign_entailed(w_var, w_val)
- w(" :assigned")
+ #w(" :assigned")
def _assign_entailed(w_var, w_val):
- w(" :assign entailed")
+ #w(" :assign entailed")
for var in w_var.entails:
assert isinstance(var, W_Var)
if interp_free(var):
Modified: pypy/dist/pypy/objspace/cclp/scheduler.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/scheduler.py (original)
+++ pypy/dist/pypy/objspace/cclp/scheduler.py Tue Oct 10 17:54:01 2006
@@ -16,13 +16,13 @@
self.space = space
self._main = ClonableCoroutine.w_getcurrent(space)
assert isinstance(self._main, ClonableCoroutine)
+ self._switch_count = 0
self._init_head(self._main)
self._blocked = {} # thread set
# variables suspension lists
self._blocked_on = {} # var -> threads
self._blocked_byneed = {} # var -> threads
self._asking = {} # thread -> cspace
- self._switch_count = 0
# more accounting
self._per_space_live_threads = {} # space -> nb runnable threads
self._traced = {} # thread -> vars
@@ -69,7 +69,7 @@
self.dec_live_thread_count(cspace)
self.schedule()
self.inc_live_thread_count(cspace)
- else: # or we ask() from outside
+ else: # or we ask(), or clone() from outside
self.schedule()
#-- cspace -> thread_count helpers
@@ -93,7 +93,7 @@
def schedule(self):
to_be_run = self._select_next()
assert isinstance(to_be_run, ClonableCoroutine)
- w(".. SWITCHING", str(id(ClonableCoroutine.w_getcurrent(self.space))), "=>", str(id(to_be_run)))
+ #w(".. SWITCHING", str(id(ClonableCoroutine.w_getcurrent(self.space))), "=>", str(id(to_be_run)))
self._switch_count += 1
to_be_run.w_switch()
@@ -104,7 +104,7 @@
if to_be_run == curr:
w(".. PASS")
return
- w(".. SWITCHING", str(id(curr)), "=>", str(id(to_be_run)))
+ #w(".. SWITCHING", str(id(curr)), "=>", str(id(to_be_run)))
self._switch_count += 1
to_be_run.w_switch()
@@ -133,7 +133,7 @@
sched.uler._main = sched.uler._head = self._head
w(".. SCHEDULER reinitialized")
raise OperationError(self.space.w_AllBlockedError,
- self.space.wrap("can't schedule, possible deadlock in sight"))
+ self.space.wrap("can't schedule, probable deadlock in sight"))
self._head = to_be_run
return to_be_run
@@ -153,7 +153,8 @@
try:
del self._traced[thread]
except KeyError:
- w(".. removing non-traced thread")
+ pass
+ #w(".. removing non-traced thread")
l = thread._prev
r = thread._next
l._next = r
@@ -172,7 +173,7 @@
del self._per_space_live_threads[cspace]
def add_to_blocked_on(self, w_var, thread):
- w(".. we BLOCK thread", str(id(thread)), "on var", str(w_var))
+ #w(".. we BLOCK thread", str(id(thread)), "on var", str(w_var))
assert isinstance(w_var, W_Var)
assert isinstance(thread, ClonableCoroutine)
assert thread not in self._blocked
@@ -188,13 +189,13 @@
self.dec_live_thread_count(thread._cspace)
def unblock_on(self, w_var):
- v(".. we UNBLOCK threads dependants of var", str(w_var))
+ #v(".. we UNBLOCK threads dependants of var", str(w_var))
assert isinstance(w_var, W_Var)
blocked = []
if w_var in self._blocked_on:
blocked = self._blocked_on[w_var]
del self._blocked_on[w_var]
- w(str([id(thr) for thr in blocked]))
+ #w(str([id(thr) for thr in blocked]))
for thr in blocked:
del self._blocked[thr]
# cspace accounting
@@ -202,7 +203,7 @@
self.inc_live_thread_count(thr._cspace)
def add_to_blocked_byneed(self, w_var, thread):
- w(".. we BLOCK BYNEED thread", str(id(thread)), "on var", str(w_var))
+ #w(".. we BLOCK BYNEED thread", str(id(thread)), "on var", str(w_var))
assert isinstance(w_var, W_Var)
assert isinstance(thread, ClonableCoroutine)
if w_var in self._blocked_byneed:
@@ -217,7 +218,7 @@
self.dec_live_thread_count(thread._cspace)
def unblock_byneed_on(self, w_var):
- v(".. we UNBLOCK BYNEED dependants of var", str(w_var))
+ #v(".. we UNBLOCK BYNEED dependants of var", str(w_var))
assert isinstance(w_var, W_Var)
blocked = []
for w_alias in aliases(self.space, w_var):
@@ -225,7 +226,7 @@
blocked += self._blocked_byneed[w_alias]
del self._blocked_byneed[w_alias]
w_alias.needed = True
- w(str([id(thr) for thr in blocked]))
+ #w(str([id(thr) for thr in blocked]))
for thr in blocked:
del self._blocked[thr]
# cspace accounting
@@ -238,14 +239,14 @@
def trace_vars(self, thread, lvars):
assert isinstance(thread, ClonableCoroutine)
assert isinstance(lvars, list)
- w(".. TRACING logic vars.", str(lvars), "for", str(id(thread)))
+ #w(".. TRACING logic vars.", str(lvars), "for", str(id(thread)))
#assert not self._traced.has_key(thread) doesn't translate
self._traced[thread] = lvars
def dirty_traced_vars(self, thread, failed_value):
assert isinstance(thread, ClonableCoroutine)
assert isinstance(failed_value, W_FailedValue)
- w(".. DIRTYING traced vars")
+ #w(".. DIRTYING traced vars")
for w_var in self._traced[thread]:
if self.space.is_true(self.space.is_free(w_var)):
self.space.bind(w_var, failed_value)
Modified: pypy/dist/pypy/objspace/cclp/space.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/space.py (original)
+++ pypy/dist/pypy/objspace/cclp/space.py Tue Oct 10 17:54:01 2006
@@ -1,7 +1,7 @@
from pypy.rpython.objectmodel import we_are_translated
from pypy.interpreter import baseobjspace, gateway, argument, typedef
from pypy.interpreter.function import Function
-from pypy.interpreter.eval import Code
+from pypy.interpreter.pycode import PyCode
from pypy.interpreter.error import OperationError
@@ -13,9 +13,9 @@
from pypy.objspace.cclp.global_state import sched
from pypy.objspace.cclp.variable import newvar
from pypy.objspace.cclp.types import ConsistencyError, Solution, W_Var, \
- W_CVar, W_AbstractDomain
+ W_CVar, W_AbstractDomain, W_AbstractDistributor
from pypy.objspace.cclp.interp_var import interp_bind, interp_free
-
+from pypy.objspace.cclp.constraint.distributor import distribute
def newspace(space, w_callable, __args__):
args = __args__.normalize()
@@ -61,12 +61,20 @@
get_current_cspace(space).tell(w_constraint)
app_tell = gateway.interp2app(tell)
+if not we_are_translated():
+ def fresh_distributor(space, w_dist):
+ cspace = w_dist._cspace
+ while w_dist.distributable():
+ choice = cspace.choose(w_dist.fanout())
+ w_dist.w_distribute(choice)
+ app_fresh_distributor = gateway.interp2app(fresh_distributor)
class W_CSpace(baseobjspace.Wrappable):
def __init__(self, space):
self.space = space # the object space ;-)
self.distributor = None
+ self.threads = []
# choice mgmt
self._choice = newvar(space)
self._committed = newvar(space)
@@ -84,7 +92,6 @@
def clone(self):
if not we_are_translated():
- print "<-CLONE !! -----------------------------------------------------------------------"
# build fresh cspace & distributor thread
thread = ClonableCoroutine(self.space)
new_cspace = W_CSpace(self.space)
@@ -93,34 +100,39 @@
old_dist = self.distributor
new_dist = old_dist.__class__(self.space, old_dist._fanout)
new_dist._cspace = new_cspace
- # new distributor thunk
- thunk = CSpaceThunk(self.space,
- Function(self.space, Code('nocode')),
- argument.Arguments([]),
- thread)
- thread.bind(thunk)
- sched.uler.add_new_thread(thread)
+ new_cspace.distributor = new_dist
# copy the store
for var in self._store.values():
new_cspace.register_var(var.copy(self.space))
+ # new distributor thunk & thread
+ f = Function(self.space,
+ app_fresh_distributor._code,
+ self.space.newdict())
+ thunk = CSpaceThunk(self.space, f,
+ argument.Arguments(self.space, [new_dist]),
+ thread)
+ thread.bind(thunk)
+ sched.uler.add_new_thread(thread)
# rebuild propagators
new_cspace._last_choice = self._last_choice
new_cspace._solution = newvar(self.space)
- self.space.unify(new_cspace._solution, self.space.newlist(self._store.values()))
- try:
- for const in self._constraints:
- new_cspace.tell(const)
- # other attrs
- #if hasattr(self, '_last_choice'):
-
- except Exception, e:
- print "DUH ?"
- import traceback
- traceback.print_exc()
+ # copy solution variables
+ self.space.unify(new_cspace._solution,
+ self.space.newlist([var.copy(self.space)
+ for var in self._store.values()]))
+ # constraints
+ for const in self._constraints:
+ ccopy = const.copy()
+ new_cspace.tell(ccopy)
+ sched.uler.wait_stable(new_cspace)
return new_cspace
else:
+ # need to copy distributor & propagator threads???
+ # but, where are we going to find them ?
raise NotImplementedError
-
+ #new_cspace = W_CSpace(self.space)
+ #for th in self.threads:
+ # new_cspace.threads.append(th.clone())
def w_ask(self):
sched.uler.wait_stable(self)
@@ -171,13 +183,12 @@
self._store = {}
def w_merge(self):
- self._store = {}
# let's bind the solution variables
sol = self._solution.w_bound_to
if isinstance(sol, W_ListObject):
- bind_solution_variables(sol.wrappeditems)
+ self._bind_solution_variables(sol.wrappeditems)
elif isinstance(sol, W_TupleObject):
- bind_solution_variables(sol.wrappeditems)
+ self._bind_solution_variables(sol.wrappeditems)
return self._solution
def __ne__(self, other):
@@ -186,14 +197,15 @@
return True
-def bind_solution_variables(solution):
- if contains_cvar(solution): # was a constraint script
- for var in solution:
- assert isinstance(var, W_CVar)
- dom = var.w_dom
- assert isinstance(dom, W_AbstractDomain)
- assert dom.size() == 1
- interp_bind(var, dom.get_values()[0])
+ def _bind_solution_variables(self, solution):
+ if contains_cvar(solution): # was a constraint script
+ for var in solution:
+ assert isinstance(var, W_CVar)
+ realvar = self._store[var.name]
+ dom = realvar.w_dom
+ assert isinstance(dom, W_AbstractDomain)
+ assert dom.size() == 1
+ interp_bind(var, dom.get_values()[0])
def contains_cvar(lst):
Modified: pypy/dist/pypy/objspace/cclp/thread.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/thread.py (original)
+++ pypy/dist/pypy/objspace/cclp/thread.py Tue Oct 10 17:54:01 2006
@@ -13,11 +13,7 @@
"""returns a future result"""
#XXX we could be much more lazy wrt coro creation
args = __args__.normalize()
- # coro init
coro = ClonableCoroutine(space)
- # computation space is the same as in the parent
- #coro.cspace = ClonableCoroutine.w_getcurrent(space).cspace
- # feed the coro
w_Future = W_Future(space)
thunk = FutureThunk(space, w_callable, args, w_Future, coro)
coro.bind(thunk)
@@ -35,10 +31,7 @@
def stacklet(space, w_callable, __args__):
"""returns a coroutine object"""
args = __args__.normalize()
- # coro init
coro = ClonableCoroutine(space)
- # computation space is the same as in the parent
- #coro.cspace = ClonableCoroutine.w_getcurrent(space).cspace
thunk = ProcedureThunk(space, w_callable, args, coro)
coro.bind(thunk)
coro._cspace = get_current_cspace(space)
Modified: pypy/dist/pypy/objspace/cclp/thunk.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/thunk.py (original)
+++ pypy/dist/pypy/objspace/cclp/thunk.py Tue Oct 10 17:54:01 2006
@@ -15,7 +15,7 @@
def logic_args(args):
"returns logic vars found in unpacked normalized args"
assert isinstance(args, tuple)
- pos = args[0]
+ pos = args[0] or [] # pos is not an empty tuple but None
kwa = args[1]
pos_l = [arg for arg in pos
if isinstance(arg, W_Var)]
@@ -80,7 +80,7 @@
self._coro = coro
def call(self):
- w("-- initial thunk CALL in", str(id(self._coro)))
+ w("-- initial DISTRIBUTOR thunk CALL in", str(id(self._coro)))
sched.uler.trace_vars(self._coro, logic_args(self.args.unpack()))
cspace = self._coro._cspace
space = self.space
@@ -98,7 +98,8 @@
w("-- clean EXIT of DISTRIBUTOR (success)", str(id(self._coro)))
sol = cspace._solution
assert isinstance(sol, W_Var)
- interp_bind(sol, self.costate.w_tempval)
+ if interp_free(sol): # returning from a constraint/logic script
+ interp_bind(sol, self.costate.w_tempval)
outcome = sol.w_bound_to
if not (isinstance(outcome, W_ListObject) or \
isinstance(outcome, W_TupleObject)):
@@ -107,6 +108,7 @@
return
assert interp_free(cspace._choice)
interp_bind(cspace._choice, self.space.newint(1))
+ assert sched.uler._per_space_live_threads[cspace] == 0, "there are still threads living in this space"
finally:
interp_bind(cspace._finished, self.space.w_True)
sched.uler.remove_thread(self._coro)
Modified: pypy/dist/pypy/objspace/cclp/variable.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/variable.py (original)
+++ pypy/dist/pypy/objspace/cclp/variable.py Tue Oct 10 17:54:01 2006
@@ -27,7 +27,7 @@
return w_obj
def wait__Var(space, w_var):
- w("###:wait", str(id(ClonableCoroutine.w_getcurrent(space))))
+ #w("###:wait", str(id(ClonableCoroutine.w_getcurrent(space))))
if space.is_true(space.is_free(w_var)):
sched.uler.unblock_byneed_on(w_var)
sched.uler.add_to_blocked_on(w_var, ClonableCoroutine.w_getcurrent(space))
@@ -239,7 +239,7 @@
def entail__Var_Var(space, w_v1, w_v2):
- w(" :entail Var Var")
+ #w(" :entail Var Var")
if space.is_true(space.is_bound(w_v1)):
if space.is_true(space.is_bound(w_v2)):
return unify(space,
@@ -260,7 +260,7 @@
return space.w_None
def _assign_aliases(space, w_var, w_val):
- w(" :assign")
+ #w(" :assign")
assert isinstance(w_var, W_Var)
#assert isinstance(w_val, W_Root)
w_curr = w_var
@@ -275,11 +275,11 @@
# switch to next
w_curr = w_next
_assign_entailed(space, w_var, w_val)
- w(" :assigned")
+ #w(" :assigned")
return space.w_None
def _assign_entailed(space, w_var, w_val):
- w(" :assign entailed")
+ #w(" :assign entailed")
for var in w_var.entails:
if space.is_true(space.is_free(var)):
_assign_aliases(space, var, w_val)
@@ -299,7 +299,7 @@
user must ensure freeness of both vars"""
assert isinstance(w_v1, W_Var)
assert isinstance(w_v2, W_Var)
- w(" :alias", str(id(w_v1)), str(id(w_v2)))
+ #w(" :alias", str(id(w_v1)), str(id(w_v2)))
if space.is_true(space.is_nb_(w_v1, w_v2)):
return space.w_None
if space.is_true(is_aliased(space, w_v1)):
@@ -316,7 +316,7 @@
def _add_to_aliases(space, w_v1, w_v2):
assert isinstance(w_v1, W_Var)
assert isinstance(w_v2, W_Var)
- w(" :add to aliases")
+ #w(" :add to aliases")
w_tail = w_v1.w_bound_to
w_v1.w_bound_to = w_v2
w_v2.w_bound_to = w_tail
@@ -325,7 +325,7 @@
def _merge_aliases(space, w_v1, w_v2):
assert isinstance(w_v1, W_Var)
assert isinstance(w_v2, W_Var)
- w(" :merge aliases")
+ #w(" :merge aliases")
w_tail1 = get_ring_tail(space, w_v1)
w_tail2 = get_ring_tail(space, w_v2)
w_tail1.w_bound_to = w_v2
Modified: pypy/dist/pypy/objspace/logic.py
==============================================================================
--- pypy/dist/pypy/objspace/logic.py (original)
+++ pypy/dist/pypy/objspace/logic.py Tue Oct 10 17:54:01 2006
@@ -95,15 +95,15 @@
def eq(w_obj1, w_obj2):
assert isinstance(w_obj1, W_Root)
assert isinstance(w_obj2, W_Root)
- w("#> check identity")
+ #w("#> check identity")
if space.is_true(space.is_nb_(w_obj1, w_obj2)):
return space.newbool(True)
- w("#> check aliasing")
+ #w("#> check aliasing")
if space.is_true(space.is_free(w_obj1)):
if space.is_true(space.is_free(w_obj2)):
if space.is_true(alias_of(space, w_obj1, w_obj2)):
return space.newbool(True) # and just go on ...
- w("#> using parent eq")
+ #w("#> using parent eq")
return parentfn(wait(space, w_obj1), wait(space, w_obj2))
return eq
More information about the Pypy-commit
mailing list