charmplusplus / charm4py

Parallel Programming with Python and Charm++
https://charm4py.readthedocs.io
Apache License 2.0
290 stars 21 forks source link

Crash with co-routine suspension within charm.iwait #198

Open ZwFink opened 3 years ago

ZwFink commented 3 years ago

Currently, charm.iwait assumes that the body of code that executes for each iteratively-received object does not suspend. If suspension does happen and the next object is received while the code executing within the body of the loop is suspended, the program will crash. This is illustrated in the following block of code:

from charm4py import Chare, Channel, charm, Future, Group, coro

class A(Chare):
    def __init__(self):
        self.partnerProxy = self.thisProxy[not self.thisIndex]
        self.channels = [Channel(self, self.partnerProxy),
                         Channel(self, self.partnerProxy)]

    @coro
    def run(self):
        if self.thisIndex == 0:
            my_ch = self.channels[0]
            self.partner_fut = my_ch.recv()
            my_ch.send(4)
            self.channels[1].send(4)
            self.partner_fut(4)
        else:
            my_fut = Future()
            partner_ch = self.channels[0]
            partner_ch.send(my_fut)
            for ch in charm.iwait(self.channels):
                recvd = ch.recv()

                # this greenlet pauses here and resumes here when
                # the second partner channel is ready to receive
                result = my_fut.get()
                print(recvd, result)

def main(args):
    assert charm.numPes() == 2
    chares = Group(A)
    chares.run()

charm.start(main)

This code will crash with the following (truncated) error message:

    result = my_fut.get()
  File "/home/zane/charm4py/charm4py/threads.py", line 51, in get
    return self.values[0]
  Fatal error on PE 1> TypeError: '_Channel' object is not subscriptable

This error happens because the greenlet that suspends when my_fut.get() is called is awakened when the next channel in self.channels is ready to receive and is yielded by charm.iwait.