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

WIP: Release GIL around C functions #391

Open
wants to merge 8 commits into
base: branch-0.13
Choose a base branch
from

Conversation

jakirkham
Copy link
Member

Fixes #251

Mark C functions as nogil. Adjust the Cython C-level callbacks to not require the GIL (though acquire it internally as needed). Make sure to release the GIL before calling UCX C functions.

@jakirkham jakirkham requested a review from a team as a code owner January 14, 2020 22:35
These functions should be safe to use without the Python GIL as they are
not creating or destroying Python objects. So mark them as such.

Note: This does **not** actually release the GIL. We still have to do
that ourselves. However this allows us to use these in code sections
where we have already released the GIL. We can also continue to use them
when we have the GIL as well.
Cython already infers these are `object` type given the assignment type.
So these definitions can be dropped without any loss in affect. This
will make it easier to move the assignment into the GIL block later.
As these functions are effectively called from `nogil` contexts now
given the C functions calling them are `nogil`, make them `nogil` as
well, but acquire the GIL internally for the parts of the function that
require it. Namely when the Python callback is run and its results are
added to the asyncio Future.
Go ahead and release the GIL before calling UCX functions. They should
not be creating, destroying, or modifying any Python objects. Once any
of our callbacks are called that do need to manipulate Python objects,
we make sure to reacquire the GIL anyways.
As this is the type expected by the C level functions that we call later
when using `port`, go ahead and coerce it to `uint16_t` in advance.
This should make it easier to release the GIL later on.
@pentschev
Copy link
Member

This PR looks correct to me, but I don't have much experience on working with the GIL, so I'll leave the review for this to someone with more experience, perhaps @quasiben or @madsbk .

int(<uintptr_t><void*>a.ucp_worker),
func,
a.guarantee_msg_order
with gil:
Copy link
Member

Choose a reason for hiding this comment

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

This needs to be with the gil ?

Copy link
Member

Choose a reason for hiding this comment

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

Oh , any call back needs to be with the gil, correct ?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's right.

_send_cb)
cdef ucp_send_callback_t _send_cb
cdef ucs_status_ptr_t status
with nogil:
Copy link
Member

Choose a reason for hiding this comment

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

Should this be with the gil since it's a callback executed by C ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Our Cython callbacks are acquiring the GIL before they call into Python. So we need to be sure to release the GIL beforehand.

@jakirkham
Copy link
Member Author

FWIW this still needs a bit more work. There are other places we could potentially benefit from releasing the GIL.

@quasiben
Copy link
Member

@jakirkham is there a good test for testing GIL release ?

@jakirkham
Copy link
Member Author

We can call PyGILState_Check to verify it is released. Though I may not be totally understanding. What did you have in mind?

@quasiben
Copy link
Member

i didn't know about PyGILState_Check that seems like a good check. Is it easy to add a test with that ? I was considering more complicated tasks around threading...

@jakirkham
Copy link
Member Author

I suppose we could add some asserts in the code. Is that what you have in mind?

@quasiben
Copy link
Member

Yeah, I at not very familiar with adding in GIL release so I am mostly speaking out of ignorance. I checked the Pandas source and I don't think they test GIL release though they do have calls to PyGILState_Ensure in the code. So maybe an assert would be good.

@quasiben
Copy link
Member

There is a merge conflict. Once this is resolved we should be good to merge

@jakirkham
Copy link
Member Author

There is a merge conflict

Yeah saw that. Will fix in a bit.

Once this is resolved we should be good to merge

Yeah we should probably hold off merging until we are releasing the GIL in more places. Will take a look at this tomorrow.

@jakirkham jakirkham changed the base branch from branch-0.12 to branch-0.13 January 25, 2020 02:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

Releasing the GIL
3 participants