Skip to content
New issue

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

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

Already on GitHub? # to your account

Support pickling of Basic objects #377

Merged
merged 8 commits into from
Dec 2, 2021
Merged

Conversation

isuruf
Copy link
Member

@isuruf isuruf commented Nov 27, 2021

No description provided.

@isuruf isuruf requested a review from a team November 27, 2021 07:10
@isuruf
Copy link
Member Author

isuruf commented Nov 28, 2021

This should be ready for a review. Failing test is a network issue.

Copy link
Contributor

@certik certik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks good to me.

@rikardn
Copy link
Contributor

rikardn commented Nov 29, 2021

This is super useful!

@bocklund
Copy link

bocklund commented Dec 1, 2021

In pycalphad, we used to subclass sympy Symbol objects and later extend them with some special behaviors. When switching to SymEngine, we are finding that using the subclassed objects in expressions don't survive a round trip through pickle without getting clobbered and changed to Symbol objects.

Self-contained example:

import pickle
from symengine import Add, Symbol

class StateVariable(Symbol):
    def __init__(self, name):
        super().__init__(name.upper())

    def __reduce__(self):
        return self.__class__, (self.name,)

T = StateVariable('T')

loaded_T = pickle.loads(pickle.dumps(T))
assert isinstance(loaded_T, StateVariable), f"Got type {type(loaded_T)}" # passes

loaded_Add_T = list(pickle.loads(pickle.dumps(Add(T, 1))).free_symbols)[0]
assert isinstance(loaded_Add_T, StateVariable), f"Got type {type(loaded_Add_T)}" # fails
AssertionError                            Traceback (most recent call last)
<ipython-input-1-ff0882030409> in <module>
     15
     16 loaded_Add_T = list(pickle.loads(pickle.dumps(Add(T, 1))).free_symbols)[0]
---> 17 assert isinstance(loaded_Add_T, StateVariable), f"Got type {type(loaded_Add_T)}" # fails

AssertionError: Got type <class 'symengine.lib.symengine_wrapper.Symbol'>

Are there any changes here or in our code that we can make to have our subclasses survive a round trip through pickle in expressions?

@bocklund
Copy link

bocklund commented Dec 1, 2021

Thank you, @isuruf! The changes here and upstream in SymEngine work well and solve our problem.

@certik
Copy link
Contributor

certik commented Dec 1, 2021

Thanks @isuruf for all the work.

Thanks @bocklund for using SymEngine. I am very happy it works for you.

@isuruf isuruf merged commit cfb4f4b into symengine:master Dec 2, 2021
@isuruf isuruf deleted the pickling branch December 2, 2021 01:56
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants