-
Notifications
You must be signed in to change notification settings - Fork 532
[WIP] Lightweight implementation of InterfaceResult
#2805
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
Conversation
This PR replaces the good old ``Bunch``. ``Bunch`` has been moved to the module ``nipype.utils.misc``, although it is still loadable from ``nipype.interfaces.base``.
One caveat is that this is not better on Python 2.7: >>> from nipype.interfaces.base.support import InterfaceRuntime
>>> from nipype.interfaces.base import Bunch
>>> from pympler import asizeof
>>> rt = InterfaceRuntime(cmdline='/bin/echo', cwd='/home/oesteban', stdout='some text that is actually somewhat longer than other parameters')
>>> asizeof.asizeof(rt)
736
>>> rt2 = Bunch(cmdline='/bin/echo', cwd='/home/oesteban', stdout='some text that is actually somewhat longer than other parameters')
>>> asizeof.asizeof(rt2)
688 The difference is about 10% (half as much as before), and we can always patch the InterfaceRuntime object to be a Bunch for Python 2. EDIT: the difference goes away with bigger objects: >>> from nipype.interfaces.base.support import InterfaceRuntime
>>> from nipype.interfaces.base import Bunch
>>> from pympler import asizeof
>>> rt = InterfaceRuntime(cmdline='/bin/echo', cwd='/home/oesteban', stdout='some text that is actually somewhat longer than other parameters', stderr='onemore')
>>> asizeof.asizeof(rt)
784
>>> rt2 = Bunch(cmdline='/bin/echo', cwd='/home/oesteban', stdout='some text that is actually somewhat longer than other parameters', stderr='onemore')
>>> asizeof.asizeof(rt2)
784 and >>> from nipype.interfaces.base.support import InterfaceRuntime
>>> from nipype.interfaces.base import Bunch
>>> from pympler import asizeof
>>> rt = InterfaceRuntime(cmdline='/bin/echo', cwd='/home/oesteban', stdout='some text that is actually somewhat longer than other parameters', stderr='onemore', returncode=0)
>>> asizeof.asizeof(rt)
808
>>> rt2 = Bunch(cmdline='/bin/echo', cwd='/home/oesteban', stdout='some text that is actually somewhat longer than other parameters', stderr='onemore', returncode=0)
>>> asizeof.asizeof(rt2)
856 And, in python 3.7, things start to be very different: >>> from nipype.interfaces.base.support import InterfaceRuntime
>>> from nipype.interfaces.base import Bunch
>>> from pympler import asizeof
>>> rt = InterfaceRuntime(cmdline='/bin/echo', cwd='/home/oesteban', stdout='some text that is actually somewhat longer than other parameters', stderr='onemore', returncode=0)
>>> asizeof.asizeof(rt)
552
>>> rt2 = Bunch(cmdline='/bin/echo', cwd='/home/oesteban', stdout='some text that is actually somewhat longer than other parameters', stderr='onemore', returncode=0)
>>> asizeof.asizeof(rt2)
784 |
Codecov Report
@@ Coverage Diff @@
## master #2805 +/- ##
==========================================
- Coverage 67.52% 64.14% -3.39%
==========================================
Files 341 340 -1
Lines 43312 43274 -38
Branches 5371 5369 -2
==========================================
- Hits 29248 27758 -1490
- Misses 13363 14444 +1081
- Partials 701 1072 +371
Continue to review full report at Codecov.
|
InterfaceResult
InterfaceResult
nipype/interfaces/base/support.py
Outdated
>>> pickleds = pickle.dumps(rt) | ||
>>> newrt = pickle.loads(pickleds) | ||
>>> newrt | ||
Bunch(cmdline='/bin/echo', cwd='/scratch/workflow', returncode=0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Bunch
and not InterfaceRuntime
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is for backwards compatibility. If I change Bunch I'm afraid I'll need to update all the tests. But I can make that extra mile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would much prefer repr
to accurately reflect the class name. Sorry that it's a lot of work...
""" | ||
__slots__ = ['interface', 'runtime', 'inputs', 'outputs', 'provenance'] | ||
version = __version__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the goal of the version
attribute was to invalidate results loaded from an incompatible format, not record the nipype version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MMM so this is why we had 2.0 here? was that the pickle protocol version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@satra Perhaps you can clarify? I interpreted as the InterfaceResult
API version.
def __setstate__(self, state): | ||
"""Necessary for un-pickling""" | ||
for key in self.__class__.__slots__: | ||
setattr(self, key, state.get(key, None)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should you check that state.get('version') == self.version
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throw a warning at least would be appropriate. Since I was trying to do a minimal proof of concept, I passed. But yes, I'll include the warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warning added 👍
78fed19
to
dd6351a
Compare
InterfaceResult
InterfaceResult
Do not merge yet, still under testing. |
Hi, just a reminder that the 1.1.8 release is targeted for January 28. Please let us know if you'd like to try to finish this up for that release. |
We can push this one to 1.1.9 |
@oesteban Just a bump to note that the merge window closes next Friday, Feb 22. |
I'm going to close this one for now. I am confident this is a good direction, but I need to mull over the details of the implementation. I'll reopen when ready. |
I'm going to mark it orphaned. Let's start a new PR when you're ready. |
This pull request is "orphaned," which means it has been deemed to be abandoned by its original author. Orphaned pull requests have not been rejected, and we hope that if a user sees one that will meet their needs with a little work, that they will fork it and open a new pull request (or, in the case of the original author, reopen the original PR). We ask that all adopted PRs be updated to merge or rebase the current master. If you would like to adopt a PR and need help getting started, any of a number of contributors will be happy to help. |
Summary
(Ref #2776)
This PR replaces the good old
Bunch
.Bunch
has been moved to the modulenipype.utils.misc
, although it is still loadable fromnipype.interfaces.base
.The memory fingerprint of runtime objects improve by some 20%, not that we will see a huge difference but it justifies itself as an optimization:
**
pympler
measures the whole size of the data structure, including the full tree of references.List of changes proposed in this PR (pull-request)
nipype.interfaces.base.support.InterfaceRuntime
object with a reduce memory footprint that the previousBunch
.Bunch
has been moved tonipype.utils.misc
and some unused code has been removed.Acknowledgment