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

Add PythonFutureTask #46

Merged
merged 27 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c624e35
Add C++-backed `ucxx::python::PythonFutureTask`
pentschev May 5, 2023
1d10a54
Add `PythonFutureTask` example
pentschev May 5, 2023
dfb1f6e
Add Python examples include directory to CMake
pentschev May 5, 2023
ebf0120
Merge remote-tracking branch 'upstream/branch-0.35' into python-futur…
pentschev Oct 26, 2023
6552c96
Fix linting
pentschev Oct 26, 2023
86609ac
Fix include
pentschev Oct 27, 2023
70f64df
Update `CODEOWNERS` with new CMake file
pentschev Oct 27, 2023
0ce583f
Add Python future with asyncio event loop
pentschev Oct 27, 2023
5272bb9
Add C++ future -> Python future notifier example to CI
pentschev Oct 30, 2023
6c06dc1
Merge remote-tracking branch 'upstream/branch-0.35' into python-futur…
pentschev Oct 31, 2023
fadc96b
Merge remote-tracking branch 'upstream/branch-0.35' into python-futur…
pentschev Nov 2, 2023
32b800c
Update test to match latest cuDF changes
pentschev Nov 9, 2023
e621984
Clarify GIL requirement in `PythonFutureTask` constructor
pentschev Nov 13, 2023
d71faa3
Fix error handlers
pentschev Nov 13, 2023
e4b928d
Move `PythonFutureTask` implementation details
pentschev Nov 13, 2023
24989fe
Use `PythonFutureTask` move constructor instead of pointers
pentschev Nov 13, 2023
9a7491f
Mark Python future C functions as `noexcept`
pentschev Nov 13, 2023
1e68b19
Remove explicit `ucxx::python::PythonFutureTask` destructor
pentschev Nov 13, 2023
f6a8c29
Merge remote-tracking branch 'upstream/branch-0.36' into python-futur…
pentschev Nov 22, 2023
514627d
Remove unnecessary `_readyPool`
pentschev Nov 22, 2023
72eb539
Add a garbage collector for `PythonFutureTask`s
pentschev Nov 27, 2023
6e63140
Collect `PythonFutureTask`s during `~ApplicationThread`
pentschev Nov 27, 2023
7e0ad1b
Hold the mutex during `~PythonFutureTaskCollector()`
pentschev Nov 27, 2023
161e015
Merge remote-tracking branch 'upstream/branch-0.36' into python-futur…
pentschev Nov 29, 2023
e55efdd
Remove unnecessary CMake rpath entry
pentschev Nov 30, 2023
25cb66c
Merge remote-tracking branch 'origin/python-future-task' into python-…
pentschev Nov 30, 2023
8439f95
Removed unnecessary CMake `ASSOCIATED_TARGETS`
pentschev Nov 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
#cpp code owners
cpp/ @rapidsai/ucxx-cpp-codeowners
cpp/ @rapidsai/ucxx-cpp-codeowners

#python code owners
python/ @rapidsai/ucxx-python-codeowners
python/ @rapidsai/ucxx-python-codeowners

#cmake code owners
cpp/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
cpp/python/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
cpp/examples/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
cpp/benchmarks/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
cpp/tests/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
python/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
python/ucxx/_lib/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
fetch_rapids.cmake @rapidsai/ucxx-cmake-codeowners
**/cmake/ @rapidsai/ucxx-cmake-codeowners
cpp/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
cpp/python/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
cpp/examples/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
cpp/benchmarks/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
cpp/tests/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
python/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
python/ucxx/examples/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
python/ucxx/_lib/CMakeLists.txt @rapidsai/ucxx-cmake-codeowners
fetch_rapids.cmake @rapidsai/ucxx-cmake-codeowners
**/cmake/ @rapidsai/ucxx-cmake-codeowners

#build/ops code owners
.github/ @rapidsai/ops-codeowners
ci/ @rapidsai/ops-codeowners
conda/ @rapidsai/ops-codeowners
.github/ @rapidsai/ops-codeowners
ci/ @rapidsai/ops-codeowners
conda/ @rapidsai/ops-codeowners
3 changes: 3 additions & 0 deletions ci/test_python.sh
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,6 @@ run_distributed_ucxx_tests thread 0 0
run_distributed_ucxx_tests thread 0 1
run_distributed_ucxx_tests thread 1 0
run_distributed_ucxx_tests thread 1 1

rapids-logger "C++ future -> Python future notifier example"
python -m ucxx.examples.python_future_task_example
1 change: 1 addition & 0 deletions cpp/python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ add_library(
src/future.cpp
src/notifier.cpp
src/python_future.cpp
src/python_future_task_collector.cpp
src/worker.cpp
)

Expand Down
1 change: 1 addition & 0 deletions cpp/python/include/ucxx/python/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
#include <ucxx/python/exception.h>
#include <ucxx/python/notifier.h>
#include <ucxx/python/python_future.h>
#include <ucxx/python/python_future_task_collector.h>
#include <ucxx/python/worker.h>
3 changes: 3 additions & 0 deletions cpp/python/include/ucxx/python/constructors.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ namespace python {

std::shared_ptr<::ucxx::Future> createFuture(std::shared_ptr<::ucxx::Notifier> notifier);

std::shared_ptr<::ucxx::Future> createFutureWithEventLoop(
PyObject* asyncioEventLoop, std::shared_ptr<::ucxx::Notifier> notifier);

std::shared_ptr<::ucxx::Notifier> createNotifier();

std::shared_ptr<::ucxx::Worker> createWorker(std::shared_ptr<ucxx::Context> context,
Expand Down
60 changes: 57 additions & 3 deletions cpp/python/include/ucxx/python/future.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace python {
*
* @returns The Python asyncio future object.
*/
PyObject* create_python_future();
PyObject* create_python_future() noexcept;

/**
* @brief Set the result of a Python future.
Expand All @@ -37,7 +37,7 @@ PyObject* create_python_future();
*
* @returns The result of the call to `_asyncio.Future.set_result()`.
*/
PyObject* future_set_result(PyObject* future, PyObject* value);
PyObject* future_set_result(PyObject* future, PyObject* value) noexcept;

/**
* @brief Set the exception of a Python future.
Expand All @@ -53,7 +53,61 @@ PyObject* future_set_result(PyObject* future, PyObject* value);
*
* @returns The result of the call to `_asyncio.Future.set_result()`.
*/
PyObject* future_set_exception(PyObject* future, PyObject* exception, const char* message);
PyObject* future_set_exception(PyObject* future, PyObject* exception, const char* message) noexcept;

/**
* @brief Create a Python asyncio future with associated event loop.
*
* Create Python asyncio future associated with the event loop passed via the `event_loop`
* argument, effectively equal to calling `loop.create_future()` directly in Python.
*
* Note that this call will take the Python GIL and requires that the current thread have
* an asynchronous event loop set.
*
* @param[in] event_loop the Python asyncio event loop to which the future will belong to.
*
* @returns The Python asyncio future object.
*/
PyObject* create_python_future_with_event_loop(PyObject* event_loop) noexcept;

/**
* @brief Set the result of a Python future with associated event loop.
*
* Schedule setting the result of a Python future in the given event loop using the
* threadsafe method `event_loop.call_soon_threadsafe`. The event loop given must be the
* same specified when creating the future object with `create_python_future`.
*
* Note that this may be called from any thread and will take the Python GIL to run.
*
* @param[in] future Python object containing the `_asyncio.Future` object.
* @param[in] value Python object containing an arbitrary value to set the future result
* to.
*
* @returns The result of the call to `_asyncio.Future.set_result()`.
*/
PyObject* future_set_result_with_event_loop(PyObject* event_loop,
PyObject* future,
PyObject* value) noexcept;

/**
* @brief Set the exception of a Python future with associated event loop.
*
* Schedule setting an exception of a Python future in the given event loop using the
* threadsafe method `event_loop.call_soon_threadsafe`. The event loop given must be the
* same specified when creating the future object with `create_python_future`.
*
* Note that this may be called from any thread and will take the Python GIL to run.
*
* @param[in] future Python object containing the `_asyncio.Future` object.
* @param[in] exception a Python exception derived of the `Exception` class.
* @param[in] message human-readable error message for the exception.
*
* @returns The result of the call to `_asyncio.Future.set_result()`.
*/
PyObject* future_set_exception_with_event_loop(PyObject* event_loop,
PyObject* future,
PyObject* exception,
const char* message) noexcept;

} // namespace python

Expand Down
25 changes: 23 additions & 2 deletions cpp/python/include/ucxx/python/python_future.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ namespace python {

class Future : public ::ucxx::Future {
private:
PyObject* _handle{create_python_future()}; ///< The handle to the Python future
PyObject* _asyncioEventLoop{nullptr}; ///< The asyncio event loop the Python future belongs to.
PyObject* _handle{nullptr}; ///< The handle to the Python future

/**
* @brief Construct a future that may be notified from a notifier thread.
Expand All @@ -32,9 +33,12 @@ class Future : public ::ucxx::Future {
* This class may also be used to set the result or exception from any thread, but that
* currently requires explicitly taking the GIL before calling `set()`.
*
* @param[in] asyncioEventLoop pointer to a valid Python object containing the event loop
* that the application is using, to which the future will
* belong to.
* @param[in] notifier notifier object running on a separate thread.
*/
explicit Future(std::shared_ptr<::ucxx::Notifier> notifier);
explicit Future(PyObject* asyncioEventLoop, std::shared_ptr<::ucxx::Notifier> notifier);

public:
Future() = delete;
Expand All @@ -56,6 +60,23 @@ class Future : public ::ucxx::Future {
*/
friend std::shared_ptr<::ucxx::Future> createFuture(std::shared_ptr<::ucxx::Notifier> notifier);

/**
* @brief Constructor of `shared_ptr<ucxx::python::Future>`.
*
* The constructor for a `shared_ptr<ucxx::python::Future>` object. The default
* constructor is made private to ensure all UCXX objects are shared pointers and correct
* lifetime management.
*
* @param[in] asyncioEventLoop pointer to a valid Python object containing the event loop
* that the application is using, to which the future will
* belong to.
* @param[in] notifier notifier object running on a separate thread.
*
* @returns The `shared_ptr<ucxx::python::Worker>` object
*/
friend std::shared_ptr<::ucxx::Future> createFutureWithEventLoop(
PyObject* asyncioEventLoop, std::shared_ptr<::ucxx::Notifier> notifier);

/**
* @brief Virtual destructor.
*
Expand Down
Loading