You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I came across this problem while trying to add a test for recursive remote functions. I think the problem occurs because our testing paradigm requires defining remote functions inside of regular functions.
Defining a remote function inside a regular function works.
deff():
@ray.remote([int], [int])defg(x):
returnxreturnray.get(g(0))
f() # prints 0
Defining a recursive remote function works.
@ray.remote([int], [int])deffactorial(n):
ifn==0:
return1returnn*ray.get(factorial(n-1))
ray.get(factorial(2)) # prints 2
Calling a recursive remote function from another remote function works.
@ray.remote([int], [int])defgetfactorial(n):
returnray.get(factorial(n))
ray.get(getfactorial(2)) # prints 2
However, defining a recursive remote function inside of a regular function seems to note work.
This is quite an interesting issue that in fact has nothing to do with pickling itself, but merely the timing of when we are trying to pickle the function.
The issue is that we need fact to be fully defined at the point where remote is called, but in fact, it turns out that this is impossible because Python has not yet finished constructing the closure of fact at that point! (i.e., while it does have a Cell object whose contents are supposed to be func, its contents have not yet been set at the point where we try to pickle it.)
Here's an illustration to show what I mean:
def annotated(func):
global closure
closure = func.__closure__[0]
print closure # <cell at 0x0000000004027108: empty>
return func
def getfact():
@annotated
def fact(n): return n * fact(n - 1) if n else 1
return fact
getfact()(3)
print closure # <cell at 0x0000000004027108: function object at 0x00000000046E5438>
The only solution that i can see? You won't like it, but it's the same thing I've said multiple times in the past -- annotations should merely annotate; they shouldn't have side effects like sending the function to the scheduler. The actual remote definition should occur along with the call itself, and furthermore, the definition and the call should probably be packaged into the same message, not separate messages -- because a separate definition and call doesn't make sense when you consider that different calls might be using the "same" function with a different closure, and they need to work correctly.
I was originally going to close the issue as invalid since this isn't a pickling bug. However, it is a bug, so I'm leaving it open and assigning it back to you so you can finally make remote wait until the invocation. ;)
I came across this problem while trying to add a test for recursive remote functions. I think the problem occurs because our testing paradigm requires defining remote functions inside of regular functions.
Defining a remote function inside a regular function works.
Defining a recursive remote function works.
Calling a recursive remote function from another remote function works.
However, defining a recursive remote function inside of a regular function seems to note work.
Calling
getfact()
fails withThe text was updated successfully, but these errors were encountered: