diff --git a/charm4py/charm.py b/charm4py/charm.py index 47a9b1f4..e14e977f 100644 --- a/charm4py/charm.py +++ b/charm4py/charm.py @@ -1158,9 +1158,9 @@ def notify_future_deletion(self, store_id, depth): # if yes, remove it fut = charm.threadMgr.borrowed_futures[(store_id, depth)] refcount = ctypes.c_long.from_address(id(fut)).value - #print(store_id, "on pe", charm.myPe(), "depth", depth, "ref count =", refcount) + # print(store_id, "on pe", charm.myPe(), "depth", depth, "ref count =", refcount) if (fut.parent == None and refcount == 3) or (fut.parent != None and refcount == 2): - #print("Real deletion of", store_id, "from", charm.myPe()) + # print("Real deletion of", store_id, "from", charm.myPe()) if fut.parent == None: charm.threadMgr.futures.pop(fut.fid) charm.threadMgr.borrowed_futures.pop((store_id, depth)) diff --git a/charm4py/threads.py b/charm4py/threads.py index 3c6f0547..fc888e00 100644 --- a/charm4py/threads.py +++ b/charm4py/threads.py @@ -163,7 +163,13 @@ def __getstate__(self): # keep track of how many PEs this future is being sent to self.num_borrowers += 1 if self.store: - charm.threadMgr.borrowed_futures[(self.store_id, self.borrow_depth)] = self + # print("Getting state for id", self.store_id, "at borrow depth", self.borrow_depth, "num borrowers", self.num_borrowers, "on pe", charm.myPe()) + #in the case where one pe has 2 instances of futures with matching store ids and borrow depths + if (self.store_id, self.borrow_depth) in charm.threadMgr.borrowed_futures: + if charm.threadMgr.borrowed_futures[(self.store_id, self.borrow_depth)] is not self: + charm.threadMgr.borrowed_futures[(self.store_id, self.borrow_depth)].num_borrowers += 1 + else: + charm.threadMgr.borrowed_futures[(self.store_id, self.borrow_depth)] = self return (self.fid, self.src, self.store, self.borrow_depth, charm.myPe()) def __setstate__(self, state): @@ -173,6 +179,7 @@ def __setstate__(self, state): self.store_id = (self.src << 32) + self.fid else: self.store_id = 0 + # print("Setting state for id", self.store_id, "on pe", charm.myPe(), "at depth", self.borrow_depth) self._requested = False self.num_borrowers = 0 @@ -180,11 +187,11 @@ def __del__(self): if self.store: if self.parent == None and self.num_borrowers == 0: # This is the owner, delete the object from the object store - #print("Deleting owner", self.store_id) + # print("Deleting owner", self.store_id) self.delete_object() else: # this is a borrower, notify its parent of the deletion - #print("Deleting", self.store_id, "from", charm.myPe(), "sending notify to", self.parent) + # print("Deleting", self.store_id, "from", charm.myPe(), "sending notify to", self.parent, "at depth", self.borrow_depth) charm.thisProxy[self.parent].notify_future_deletion(self.store_id, self.borrow_depth - 1) diff --git a/docs/pool.rst b/docs/pool.rst index c37d9344..d76e8185 100644 --- a/docs/pool.rst +++ b/docs/pool.rst @@ -17,7 +17,8 @@ or creating more processes than processors. ``charm.pool`` is experimental, the API and performance (especially at large scales) is still subject to - change. + change. Additionally, do not include any Future objects in the iterable provided + to map or map_async, unless you set is_ray to True. .. note:: diff --git a/examples/pool/pool_fibonacci.py b/examples/pool/pool_fibonacci.py index f0153439..bbc81e47 100644 --- a/examples/pool/pool_fibonacci.py +++ b/examples/pool/pool_fibonacci.py @@ -9,6 +9,9 @@ def fib(n): return sum(charm.pool.map(fib, [n-1, n-2])) def main(args): + if(charm.numPes()==1): + print("Error: Run with more than one PE (exiting). For documentation on using pools, see: https://charm4py.readthedocs.io/en/latest/pool.html") + exit() print('fibonacci(13)=', fib(13)) exit() diff --git a/examples/pool/pool_simple.py b/examples/pool/pool_simple.py index 0adc7dd4..ba546628 100644 --- a/examples/pool/pool_simple.py +++ b/examples/pool/pool_simple.py @@ -9,8 +9,11 @@ def twice(x): def main(args): ray.init() - results = charm.pool.map_async(square, [4], chunksize=1, multi_future=True) - results_twice = charm.pool.map_async(twice, results, chunksize=1, multi_future=True) + if(charm.numPes()==1): + print("Error: Run with more than one PE (exiting). For documentation on using pools, see: https://charm4py.readthedocs.io/en/latest/pool.html") + exit() + results = charm.pool.map_async(square, [4], chunksize=1, multi_future=True, is_ray=True) + results_twice = charm.pool.map_async(twice, results, chunksize=1, multi_future=True, is_ray=True) for x in results_twice: print(x.get())