-
Notifications
You must be signed in to change notification settings - Fork 189
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
Faster pycall. Adds pycall! #492
Conversation
src/PyCall.jl
Outdated
|
||
""" | ||
Low-level version of `pycall(o, ...)` that always returns `PyObject`. | ||
""" | ||
function _pycall(o::Union{PyObject,PyPtr}, args...; kwargs...) | ||
function _pycall_legacy(o::Union{PyObject,PyPtr}, args...; kwargs...) |
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.
This is just here for the benchmark comparison, the whole function, and the pycall_legacy
methods below, need to be removed before merging.
6122bcd
to
b6db3b1
Compare
Anything else you need doing for this (and other open PRs)? Test failures on Windows here to do with importing NumPy, not sure what to do for those? 0.7 failures seem unrelated. |
worked out why it was benchmarking slightly slower than the closure version. I think the struct version is clearer.
@stevengj any news here? Should I bother trying to rebase #487 (again) yet? Or wait a bit for more 0.7 related changes? Seems this and the others don't have merge conflicts (so I rebased them). Apologies if the file rearranging made this or the others harder to review. I can revert if needed I suppose. |
Looks like this is breaking nightly? |
Hmm, I can't replicate the nightly errors locally, both w julia on the commit that travis used edit: with python3 on mac |
Attempt to fix 0.7 issue
Ok, pushed a fix. There's a seemingly unrelated error in the Conda Mac build on 0.6, but the rest of the travis builds are good. Most of the Windows builds are complaining about numpy not being installed - anything I can do about those? |
Don't rely on numpy features in the tests, or only test the numpy aspects if |
I've changed the tests to not use NumPy anymore. However, for #487's most of the tests need numpy, so I'll just not run those if |
It's false in the beginning because numpy is loaded lazily, but it should be true after other array tests execute. However, you can also do |
Codecov Report
@@ Coverage Diff @@
## master #492 +/- ##
==========================================
- Coverage 65.5% 65.17% -0.33%
==========================================
Files 18 19 +1
Lines 1487 1522 +35
==========================================
+ Hits 974 992 +18
- Misses 513 530 +17
Continue to review full report at Codecov.
|
src/pyfncall.jl
Outdated
(`pyargsptr`). Sets `ret.o` to the result of the call, and returns `ret::PyObject`. | ||
""" | ||
function _pycall!(ret::PyObject, o::Union{PyObject,PyPtr}, args, | ||
nargs::Int=length(args), kw::Union{Ptr{Nothing}, PyObject}=C_NULL) |
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.
Shouldn't this be a PyPtr
rather than Ptr{Nothing}
?
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.
No that's for the C_NULL
when there aren't any kwargs. But good - that nudged me to add some tests for the kwargs case.
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.
Ptr{Nothing}
is an implementation detail; it's best to use Ptr{Cvoid}
(Base in 0.7, available from Compat in 0.6)
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.
ta
"Everyone" happy with this? Should I remove the |
Oh and btw re
I thought I was checking late in the tests, but perhaps not, it's fine now. |
Yes, go ahead and remove |
Speeds up pycalls. For functions with 1-7 arguments it reduces the overhead of calling the function from Julia by about 10-40x
Adds
pycall!(ret, o, ...)
to avoid allocating a PyObject for the return value each time the function is called.One query: I'm not 100% about the
const pyarg_tuples = PyPtr[]
, and growing it when functions have more arguments. Maybe we should just initialise it to a certain size (32 arguments?), check forisassigned(pyarg_tuples, nargs+1)
, and if not assigned, create the tuple, and grow thepyarg_tuples
vector if someone requires more than the 32 arg default.For reasons that I'll need to track down over the weekend, one of the tuples that we use for passing args, is ending up with a refcount of 2, which is not allowed when setting an item, since tuples are supposed to be immutable (but when there's only one ref, setting an item is allowed):https://github.com/python/cpython/blob/23ab5ee667a9b29014f6f7f01797c611f63ff743/Objects/tupleobject.c#L166so this is WIP until I solve that.
Happens after the@pydef type Doubler
, see the@test_broken
in runtests. Any ideas appreciated.Creating new builtin exceptions increment the refcount of the arguments tuple passed to it. The Doubler class in that test was subclassing
AssertionError
and instantiating triggered this. Handled this situation (callees incrementing the refcount of args tuple) now.to-do:
and possibly some others about.(there was another minor bug in the test for having the only reference to the (empty) arguments tuple)Benchmark results (Mean times for different arities)