[pypy-svn] r35875 - in pypy/dist/pypy/objspace: cclp cclp/constraint test
auc at codespeak.net
auc at codespeak.net
Tue Dec 19 10:40:37 CET 2006
Author: auc
Date: Tue Dec 19 10:40:32 2006
New Revision: 35875
Modified:
pypy/dist/pypy/objspace/cclp/constraint/domain.py
pypy/dist/pypy/objspace/cclp/scheduler.py
pypy/dist/pypy/objspace/cclp/space.py
pypy/dist/pypy/objspace/cclp/thunk.py
pypy/dist/pypy/objspace/cclp/types.py
pypy/dist/pypy/objspace/test/test_logicobjspace.py
Log:
current state of the (non-cloning) cloning stuff, better error checking bits wrt applevel
Modified: pypy/dist/pypy/objspace/cclp/constraint/domain.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/constraint/domain.py (original)
+++ pypy/dist/pypy/objspace/cclp/constraint/domain.py Tue Dec 19 10:40:32 2006
@@ -138,8 +138,6 @@
def intersection(space, w_fd1, w_fd2):
- assert isinstance(w_fd1, W_FiniteDomain)
- assert isinstance(w_fd2, W_FiniteDomain)
return space.intersection(w_fd1, w_fd2)
app_intersection = gateway.interp2app(intersection)
Modified: pypy/dist/pypy/objspace/cclp/scheduler.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/scheduler.py (original)
+++ pypy/dist/pypy/objspace/cclp/scheduler.py Tue Dec 19 10:40:32 2006
@@ -41,11 +41,18 @@
group._prev = l
group._next = r
+
def schedule(self):
+ running = self._head
to_be_run = self._select_next()
assert isinstance(to_be_run, W_ThreadGroupScheduler), "type error"
#w(".. SWITCHING (spaces)", str(id(get_current_cspace(self.space))), "=>", str(id(to_be_run)))
self._switch_count += 1
+ if to_be_run != running:
+ if running._pool is not None:
+ running.goodbye()
+ if to_be_run._pool is not None:
+ to_be_run.hello()
to_be_run.schedule()
def _select_next(self):
@@ -230,10 +237,12 @@
#-- Thread Group scheduler --------------------------------------
+
class W_ThreadGroupScheduler(baseobjspace.Wrappable):
def __init__(self, space):
self.space = space
+ self._pool = None
self._switch_count = 0
self._traced = {} # thread -> vars
self.thread_count = 1
@@ -259,6 +268,18 @@
thread._prev = l
thread._next = r
+ def hello(self):
+ self._pool.hello_local_pool()
+
+ def goodbye(self):
+ self._pool.goodbye_local_pool()
+
+ def register_var(self, var):
+ space = self.space
+ raise OperationError(space.w_AssertionError,
+ space.wrap('You cannot create a constraint variable '
+ 'in the top-level computation space.'))
+
def is_blocked(self):
return self.thread_count == self.blocked_count
Modified: pypy/dist/pypy/objspace/cclp/space.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/space.py (original)
+++ pypy/dist/pypy/objspace/cclp/space.py Tue Dec 19 10:40:32 2006
@@ -15,13 +15,11 @@
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_AbstractDistributor
+ W_CVar, W_AbstractDomain, W_AbstractDistributor, Pool
from pypy.objspace.cclp.interp_var import interp_bind, interp_free
from pypy.objspace.cclp.constraint.distributor import distribute
from pypy.objspace.cclp.scheduler import W_ThreadGroupScheduler
-from pypy.rlib.rgc import gc_swap_pool, gc_clone
-
def newspace(space, w_callable, __args__):
"application level creation of a new computation space"
args = __args__.normalize()
@@ -39,81 +37,66 @@
def choose(space, w_n):
- assert isinstance(w_n, W_IntObject)
+ if not isinstance(w_n, W_IntObject):
+ raise OperationError(space.w_TypeError,
+ space.wrap('Choose only accepts an integer.'))
n = space.int_w(w_n)
+ # XXX sanity check for 1 <= n <= last_choice
cspace = get_current_cspace(space)
- if cspace is not None:
- assert isinstance(cspace, W_CSpace)
- try:
- return cspace.choose(w_n.intval)
- except ConsistencyError:
- raise OperationError(space.w_ConsistencyError,
- space.wrap("the space is failed"))
- raise OperationError(space.w_RuntimeError,
- space.wrap("choose is forbidden from the top-level space"))
+ if not isinstance(cspace, W_CSpace):
+ raise OperationError(space.w_TypeError,
+ space.wrap('Choose does not work from within '
+ 'the top-level computatoin space.'))
+ try:
+ return cspace.choose(n)
+ except ConsistencyError:
+ raise OperationError(space.w_ConsistencyError,
+ space.wrap("the space is failed"))
app_choose = gateway.interp2app(choose)
-
from pypy.objspace.cclp.constraint import constraint
def tell(space, w_constraint):
- assert isinstance(w_constraint, constraint.W_AbstractConstraint)
+ if not isinstance(w_constraint, constraint.W_AbstractConstraint):
+ raise OperationError(space.w_TypeError,
+ space.wrap('Tell only accepts object of '
+ '(sub-)types Constraint.'))
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(W_ThreadGroupScheduler):
- local_pool = None
def __init__(self, space, dist_thread):
W_ThreadGroupScheduler.__init__(self, space)
dist_thread._cspace = self
self._init_head(dist_thread)
self._next = self._prev = self
+ self._pool = Pool(self)
sched.uler.add_new_group(self)
-
self.distributor = None # dist instance != thread
- self._container = None # thread that 'contains' us
# choice mgmt
self._choice = newvar(space)
self._committed = newvar(space)
# status, merging
self._solution = newvar(space)
- self._finished = newvar(space)
self._failed = False
+ self._merged = False
+ self._finished = newvar(space)
# constraint store ...
self._store = {} # name -> var
- if not we_are_translated():
- self._constraints = []
def register_var(self, cvar):
self._store[cvar.name] = cvar
def w_clone(self):
- if we_are_translated():
- w("<> cloning the space")
- if self.local_pool is None:
- self.local_pool = gc_swap_pool(gc_swap_pool(None))
- new_cspace, new_cspace.local_pool = gc_clone(self, self.local_pool)
- w("<> add cloned cspace to new group")
- assert isinstance(new_cspace, W_CSpace)
- new_cspace._next = new_cspace._prev = new_cspace
- sched.uler.add_new_group(new_cspace)
- w("<> returning clone ")
- return new_cspace
- else:
- raise NotImplementedError
-
+ clone = self._pool.clone()
+ return self.space.wrap(clone.cspace)
def w_ask(self):
+ if not interp_free(self._finished):
+ raise OperationError(self.space.w_RuntimeError,
+ self.space.wrap("space is finished"))
self.wait_stable()
self.space.wait(self._choice)
choice = self._choice.w_bound_to
@@ -123,6 +106,9 @@
return choice
def choose(self, n):
+ if not interp_free(self._finished):
+ raise OperationError(self.space.w_RuntimeError,
+ self.space.wrap("space is finished"))
# solver probably asks
assert n > 1
self.wait_stable()
@@ -138,6 +124,9 @@
return committed
def w_commit(self, w_n):
+ if not interp_free(self._finished):
+ raise OperationError(self.space.w_RuntimeError,
+ self.space.wrap("space is finished"))
assert isinstance(w_n, W_IntObject)
n = w_n.intval
assert interp_free(self._committed)
@@ -152,9 +141,6 @@
w_coro._cspace = self
thunk = PropagatorThunk(space, w_constraint, w_coro)
w_coro.bind(thunk)
- if not we_are_translated():
- w("PROPAGATOR in thread", str(id(w_coro)))
- self._constraints.append(w_constraint)
self.add_new_thread(w_coro)
def fail(self):
@@ -167,6 +153,10 @@
def w_merge(self):
# let's bind the solution variables
+ if self._merged:
+ raise OperationError(self.space.w_RuntimeError,
+ self.space.wrap("space is already merged"))
+ self._merged = True
sol = self._solution.w_bound_to
if isinstance(sol, W_ListObject):
self._bind_solution_variables(sol.wrappeditems)
@@ -191,10 +181,7 @@
def contains_cvar(lst):
- for elt in lst:
- if isinstance(elt, W_CVar):
- return True
- return False
+ return isinstance(lst[0], W_CVar)
W_CSpace.typedef = typedef.TypeDef("W_CSpace",
Modified: pypy/dist/pypy/objspace/cclp/thunk.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/thunk.py (original)
+++ pypy/dist/pypy/objspace/cclp/thunk.py Tue Dec 19 10:40:32 2006
@@ -108,7 +108,7 @@
outcome = sol.w_bound_to
if not (isinstance(outcome, W_ListObject) or \
isinstance(outcome, W_TupleObject)):
- w("WARNING: return value type of the script was not a list or tuple, we fail ...")
+ w("WARNING: return value type of the script was not a list or tuple, we fail the space.")
cspace.fail()
return
assert interp_free(cspace._choice)
Modified: pypy/dist/pypy/objspace/cclp/types.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/types.py (original)
+++ pypy/dist/pypy/objspace/cclp/types.py Tue Dec 19 10:40:32 2006
@@ -2,6 +2,10 @@
from pypy.interpreter.error import OperationError
from pypy.objspace.cclp.misc import w, AppCoroutine, get_current_cspace
+from pypy.objspace.cclp.global_state import sched
+
+from pypy.rlib.rgc import gc_swap_pool, gc_clone
+from pypy.rlib.objectmodel import we_are_translated
W_Root = baseobjspace.W_Root
@@ -42,11 +46,7 @@
self.w_dom = w_dom
self.name = space.str_w(w_name)
self.w_nam = w_name
- cspace = get_current_cspace(space)
- if cspace is None:
- w("-- WARNING : you are instanciating a constraint var in the top-level space")
- else:
- cspace.register_var(self)
+ get_current_cspace(space).register_var(self)
def copy(self, space):
return W_CVar(space, self.w_dom.copy(), self.w_nam)
@@ -124,6 +124,49 @@
W_AbstractDistributor.typedef = typedef.TypeDef("W_AbstractDistributor")
+#-- Pool --------------------------------------------------
+
+class Pool:
+ local_pool = None
+
+ def __init__(self, cspace=None):
+ self.cspace = cspace
+
+ def hello_local_pool(self):
+ if we_are_translated():
+ w('hello_local_pool')
+ self.saved_pool = gc_swap_pool(self.local_pool)
+
+ def goodbye_local_pool(self):
+ if we_are_translated():
+ w('goodbye_local_pool')
+ self.local_pool = gc_swap_pool(self.saved_pool)
+ self.saved_pool = None
+
+ def clone(self):
+ copy = Pool()
+ self.clone_into(copy)
+ return copy
+
+ def clone_into(self, copy, extradata=None):
+ # blindly copied from interp_clonable
+ # all we need is love, after all ...
+ if not we_are_translated():
+ raise NotImplementedError
+ # cannot gc_clone() directly self, because it is not in its own
+ # local_pool. Moreover, it has a __del__, which cloning doesn't
+ # support properly at the moment.
+ # the hello/goodbye pair has two purposes: it forces
+ # self.local_pool to be computed even if it was None up to now,
+ # and it puts the 'data' tuple in the correct pool to be cloned.
+ self.hello_local_pool()
+ data = (self.cspace, extradata)
+ self.goodbye_local_pool()
+ # clone!
+ data, copy.local_pool = gc_clone(data, self.local_pool)
+ copy.cspace, extradata = data
+ return extradata
+
#-- Misc ---------------------------------------------------
Modified: pypy/dist/pypy/objspace/test/test_logicobjspace.py
==============================================================================
--- pypy/dist/pypy/objspace/test/test_logicobjspace.py (original)
+++ pypy/dist/pypy/objspace/test/test_logicobjspace.py Tue Dec 19 10:40:32 2006
@@ -764,6 +764,7 @@
break
if status:
unify(Sol, spc.merge())
+ raises(AssertionError, spc.merge)
else:
unify(Sol, False)
More information about the Pypy-commit
mailing list