Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Cloudpickle #5643

Merged
merged 5 commits into from
Sep 10, 2019
Merged

Conversation

richardliaw
Copy link
Contributor

Why are these changes needed?

cc @suquark

Related issue number

Checks

@robertnishihara
Copy link
Collaborator

One of the main reasons for doing this is that the current version of cloudpickle that we vendor does not properly serialize keyword only arguments in functions.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Ray-PRB/16813/
Test FAILed.

@suquark
Copy link
Member

suquark commented Sep 6, 2019

jenkins, retest this please

@richardliaw
Copy link
Contributor Author

richardliaw commented Sep 6, 2019 via email

@pcmoritz
Copy link
Contributor

pcmoritz commented Sep 6, 2019

Jenkins retest this please

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Ray-PRB/16825/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Ray-PRB/16827/
Test FAILed.

@suquark
Copy link
Member

suquark commented Sep 6, 2019

Here's one easy patch to the original cloudpickle:

cloudpipe/cloudpickle@b9dc17f

    def save_codeobject(self, obj):
        """
        Save a code object
        """
        if PY3:  # pragma: no branch
            if hasattr(obj, "co_posonlyargcount"):  # pragma: no branch
                args = (
                    obj.co_argcount, obj.co_posonlyargcount,
                    obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
                    obj.co_flags, obj.co_code, obj.co_consts, obj.co_names,
                    obj.co_varnames, obj.co_filename, obj.co_name,
                    obj.co_firstlineno, obj.co_lnotab, obj.co_freevars,
                    obj.co_cellvars
                )
            else:
                args = (
                    obj.co_argcount, obj.co_kwonlyargcount, obj.co_nlocals,
                    obj.co_stacksize, obj.co_flags, obj.co_code, obj.co_consts,
                    obj.co_names, obj.co_varnames, obj.co_filename,
                    obj.co_name, obj.co_firstlineno, obj.co_lnotab,
                    obj.co_freevars, obj.co_cellvars
                )
        else:
            args = (
                obj.co_argcount, obj.co_nlocals, obj.co_stacksize, obj.co_flags, obj.co_code,
                obj.co_consts, obj.co_names, obj.co_varnames, obj.co_filename, obj.co_name,
                obj.co_firstlineno, obj.co_lnotab, obj.co_freevars, obj.co_cellvars
            )
        self.save_reduce(types.CodeType, args, obj=obj)

@richardliaw
Copy link
Contributor Author

@suquark we should update the cloudpickle entirely rather than monkey patch it.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Ray-PRB/16884/
Test FAILed.

@AmplabJenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Ray-PRB/16887/
Test PASSed.

@pcmoritz
Copy link
Contributor

pcmoritz commented Sep 8, 2019

@ericl Do you foresee anything else breaking? It's important to merge this so @suquark can move forward with #5611

@robertnishihara
Copy link
Collaborator

Thanks @richardliaw, I think we should merge it and try it out. This behavior of reusing existing classes instead of creating a new one seems dangerous to me (e.g., this means that mutations to the class will affect the deserialized object, right?).

@suquark doesn't cloudpickle have an option to turn off this behavior?

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Ray-PRB/16894/
Test FAILed.

@AmplabJenkins
Copy link

Test FAILed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Ray-PRB/16895/
Test FAILed.

@richardliaw
Copy link
Contributor Author

jenkins retest this please

@robertnishihara
Copy link
Collaborator

@richardliaw just to clarify, you are saying that cloudpickle's behavior has changed between the previous version and this one, right?

@richardliaw
Copy link
Contributor Author

Yeah

@AmplabJenkins
Copy link

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/Ray-PRB/16910/
Test PASSed.

@pcmoritz pcmoritz merged commit 0010f54 into ray-project:master Sep 10, 2019
@pcmoritz pcmoritz deleted the cloudpickleupdate branch September 10, 2019 00:17
@suquark
Copy link
Member

suquark commented Sep 10, 2019

@robertnishihara I don't think cloudpickle has such options. This is essential for cloudpickle to work correctly with dynamic class between remote processes.

For example,

def main():
    def DynamicClass:
        pass

    @ray.remote
    def remote_function():
        return DynamicClass()

    # register a serializer (assume broadcast to all workers)
    cloudpickle.dispatch[DynamicClass] = ....

    ray.get(remote_function.remote())

In this case, if cloudpickle doesn't keep the existing dynamic class, then when it serializes the DynamicClass() object (the return value of the remote function), it will try to look up the dispatch table for the correct serializer. However, the returned object's class has been changed, because after DynamicClass itself was serialized and deserialized, Python will not think it is the original type (because types are compared by their pointers), even in this case their qualname and content match. With a different type, the correct serializer will not likely to be triggered. So cloudpickle creates a class_tracker_id for each dynamic class, and will reuse the class for instances of dynamic classes.

Pyarrow also did in the same ways but with class_id. So the risk could be low.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants