charm4py icon indicating copy to clipboard operation
charm4py copied to clipboard

Crash with co-routine suspension within charm.iwait

Open ZwFink opened this issue 3 years ago • 0 comments

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.

ZwFink avatar Mar 15 '21 19:03 ZwFink