From 10c41fd1f4711568c1bc93cb93f120840e011d01 Mon Sep 17 00:00:00 2001 From: Jonathan Kenyon Date: Tue, 11 Aug 2020 09:34:30 +0200 Subject: [PATCH 1/5] Add code to drop the GIL. Demostrate usefulness on reads/writes. --- src/guards.h | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ src/pytable.cc | 63 +++++---------------------- 2 files changed, 125 insertions(+), 53 deletions(-) create mode 100644 src/guards.h diff --git a/src/guards.h b/src/guards.h new file mode 100644 index 00000000..2c39b861 --- /dev/null +++ b/src/guards.h @@ -0,0 +1,115 @@ +#include + +#include +#include +#include +#include +#include +#include + +namespace details { + +/// @brief Functor that will invoke a function while holding a guard. +/// Upon returning from the function, the guard is released. +template +class guarded_function +{ +public: + + typedef typename boost::function_types::result_type::type + result_type; + + template + guarded_function(Fn fn) + : fn_(fn) + {} + + template + result_type operator()(Args... args) + { + Guard g; + return fn_(args...); + } + +private: + boost::function fn_; +}; + +/// @brief Provides signature type. +template +struct mpl_signature +{ + typedef typename boost::function_types::components::type type; +}; + +// Support boost::function. +template +struct mpl_signature >: + public mpl_signature +{}; + +/// @brief Create a callable object with guards. +template +boost::python::object with_aux(Fn fn, const Policy& policy) +{ + // Obtain the components of the Fn. This will decompose non-member + // and member functions into an mpl sequence. + // R (*)(A1) => R, A1 + // R (C::*)(A1) => R, C*, A1 + typedef typename mpl_signature::type mpl_signature_type; + + // Synthesize the components into a function type. This process + // causes member functions to require the instance argument. + // This is necessary because member functions will be explicitly + // provided the 'self' argument. + // R, A1 => R (*)(A1) + // R, C*, A1 => R (*)(C*, A1) + typedef typename boost::function_types::function_type< + mpl_signature_type>::type signature_type; + + // Create a callable boost::python::object that delegates to the + // guarded_function. + return boost::python::make_function( + guarded_function(fn), + policy, mpl_signature_type()); +} + +} // namespace details + +/// @brief Create a callable object with guards. +template +boost::python::object with(const Fn& fn, const Policy& policy) +{ + return details::with_aux(fn, policy); +} + +/// @brief Create a callable object with guards. +template +boost::python::object with(const Fn& fn) +{ + return with(fn, boost::python::default_call_policies()); +} + +/// @brief Guard that will unlock the GIL upon construction, and +/// reacquire it upon destruction. +struct no_gil +{ +public: + no_gil() { state_ = PyEval_SaveThread(); } + ~no_gil() { PyEval_RestoreThread(state_); } +private: + PyThreadState* state_; +}; + +/// @brief Guard that prints to std::cout. +struct echo_guard +{ + echo_guard() { std::cout << "echo_guard()" << std::endl; } + ~echo_guard() { std::cout << "~echo_guard()" << std::endl; } +}; diff --git a/src/pytable.cc b/src/pytable.cc index 5c292254..9787c286 100755 --- a/src/pytable.cc +++ b/src/pytable.cc @@ -33,6 +33,7 @@ #include #include +#include "guards.h" using namespace boost::python; @@ -139,59 +140,15 @@ namespace casacore { namespace python { .def ("_iscelldefined", &TableProxy::cellContentsDefined, (boost::python::arg("columnname"), boost::python::arg("rownr"))) - .def ("_getcell", &TableProxy::getCell, - (boost::python::arg("columnname"), - boost::python::arg("rownr"))) - .def ("_getcellvh", &TableProxy::getCellVH, - (boost::python::arg("columnname"), - boost::python::arg("rownr"), - boost::python::arg("value"))) - .def ("_getcellslice", &TableProxy::getCellSliceIP, - (boost::python::arg("columnname"), - boost::python::arg("rownr"), - boost::python::arg("blc"), - boost::python::arg("trc"), - boost::python::arg("inc"))) - .def ("_getcellslicevh", &TableProxy::getCellSliceVHIP, - (boost::python::arg("columnname"), - boost::python::arg("rownr"), - boost::python::arg("blc"), - boost::python::arg("trc"), - boost::python::arg("inc"), - boost::python::arg("value"))) - .def ("_getcol", &TableProxy::getColumn, - (boost::python::arg("columnname"), - boost::python::arg("startrow"), - boost::python::arg("nrow"), - boost::python::arg("rowincr"))) - .def ("_getcolvh", &TableProxy::getColumnVH, - (boost::python::arg("columnname"), - boost::python::arg("startrow"), - boost::python::arg("nrow"), - boost::python::arg("rowincr"), - boost::python::arg("value"))) - .def ("_getvarcol", &TableProxy::getVarColumn, - (boost::python::arg("columnname"), - boost::python::arg("startrow"), - boost::python::arg("nrow"), - boost::python::arg("rowincr"))) - .def ("_getcolslice", &TableProxy::getColumnSliceIP, - (boost::python::arg("columnname"), - boost::python::arg("blc"), - boost::python::arg("trc"), - boost::python::arg("inc"), - boost::python::arg("startrow"), - boost::python::arg("nrow"), - boost::python::arg("rowincr"))) - .def ("_getcolslicevh", &TableProxy::getColumnSliceVHIP, - (boost::python::arg("columnname"), - boost::python::arg("blc"), - boost::python::arg("trc"), - boost::python::arg("inc"), - boost::python::arg("startrow"), - boost::python::arg("nrow"), - boost::python::arg("rowincr"), - boost::python::arg("value"))) + .def ("_getcell", with(&TableProxy::getCell)) + .def ("_getcellvh", with(&TableProxy::getCellVH)) + .def ("_getcellslice", with(&TableProxy::getCellSliceIP)) + .def ("_getcellslicevh", with(&TableProxy::getCellSliceVHIP)) + .def ("_getcol", with(&TableProxy::getColumn)) + .def ("_getcolvh", with(&TableProxy::getColumnVH)) + .def ("_getvarcol", with(&TableProxy::getVarColumn)) + .def ("_getcolslice", with(&TableProxy::getColumnSliceIP)) + .def ("_getcolslicevh", with(&TableProxy::getColumnSliceVHIP)) .def ("_putcell", &TableProxy::putCell, (boost::python::arg("columnname"), boost::python::arg("rownr"), From e5c1954115f08cf4c4468bd5514b44616e76e95d Mon Sep 17 00:00:00 2001 From: Jonathan Kenyon Date: Mon, 12 Oct 2020 09:12:07 +0200 Subject: [PATCH 2/5] Include writes. --- src/pytable.cc | 37 +++++-------------------------------- 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/src/pytable.cc b/src/pytable.cc index 9787c286..bdacfb7d 100755 --- a/src/pytable.cc +++ b/src/pytable.cc @@ -149,38 +149,11 @@ namespace casacore { namespace python { .def ("_getvarcol", with(&TableProxy::getVarColumn)) .def ("_getcolslice", with(&TableProxy::getColumnSliceIP)) .def ("_getcolslicevh", with(&TableProxy::getColumnSliceVHIP)) - .def ("_putcell", &TableProxy::putCell, - (boost::python::arg("columnname"), - boost::python::arg("rownr"), - boost::python::arg("value"))) - .def ("_putcellslice", &TableProxy::putCellSliceIP, - (boost::python::arg("columnname"), - boost::python::arg("rownr"), - boost::python::arg("value"), - boost::python::arg("blc"), - boost::python::arg("trc"), - boost::python::arg("inc"))) - .def ("_putcol", &TableProxy::putColumn, - (boost::python::arg("columnname"), - boost::python::arg("startrow"), - boost::python::arg("nrow"), - boost::python::arg("rowincr"), - boost::python::arg("value"))) - .def ("_putvarcol", &TableProxy::putVarColumn, - (boost::python::arg("columnname"), - boost::python::arg("startrow"), - boost::python::arg("nrow"), - boost::python::arg("rowincr"), - boost::python::arg("value"))) - .def ("_putcolslice", &TableProxy::putColumnSliceIP, - (boost::python::arg("columnname"), - boost::python::arg("value"), - boost::python::arg("blc"), - boost::python::arg("trc"), - boost::python::arg("inc"), - boost::python::arg("startrow"), - boost::python::arg("nrow"), - boost::python::arg("rowincr"))) + .def ("_putcell", with(&TableProxy::putCell)) + .def ("_putcellslice", with(&TableProxy::putCellSliceIP)) + .def ("_putcol", with(&TableProxy::putColumn)) + .def ("_putvarcol", with(&TableProxy::putVarColumn)) + .def ("_putcolslice", with(&TableProxy::putColumnSliceIP)) .def ("_getcolshapestring", &TableProxy::getColumnShapeString, (boost::python::arg("columnname"), boost::python::arg("startrow"), From d2f518b56c275dab0da2f088a0dcf7082cf3a5be Mon Sep 17 00:00:00 2001 From: JSKenyon Date: Mon, 28 Feb 2022 11:23:53 +0200 Subject: [PATCH 3/5] Patch. --- README.rst | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index ed277546..ca5a409a 100644 --- a/README.rst +++ b/README.rst @@ -76,6 +76,7 @@ On ubuntu you can install these with:: this:: CFLAGS="-std=c++11 \ + -lpthread \ -I/usr/local/Cellar/boost/1.68.0/include/ \ -I/usr/local/include/ \ -L/usr/local/Cellar/boost/1.68.0/lib \ diff --git a/setup.py b/setup.py index def6ec52..52dc2c1f 100755 --- a/setup.py +++ b/setup.py @@ -233,7 +233,7 @@ def get_extensions(): library_dirs=library_dirs, include_dirs=include_dirs, # Since casacore 3.0.0 we have to be C++11 - extra_compile_args=['-std=c++11'])) + extra_compile_args=['-std=c++11', '-lpthread'])) return extensions From 2268b9f3d3279b44a8f5a90266825f6109b7dbe4 Mon Sep 17 00:00:00 2001 From: JSKenyon Date: Mon, 28 Feb 2022 11:26:17 +0200 Subject: [PATCH 4/5] Patch. --- src/tables.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tables.cc b/src/tables.cc index 37fb8dde..83bcc2f7 100755 --- a/src/tables.cc +++ b/src/tables.cc @@ -32,15 +32,18 @@ #include #include #include +#include #include #include #include #include +#include BOOST_PYTHON_MODULE(_tables) { + casacore::python::registerNotThreadSafeException(); casacore::python::register_convert_excp(); casacore::python::register_convert_basicdata(); casacore::python::register_convert_casa_valueholder(); From 56c6f30691d3d748ed7d2fb18f469e576bab0bac Mon Sep 17 00:00:00 2001 From: JSKenyon Date: Mon, 28 Feb 2022 11:27:45 +0200 Subject: [PATCH 5/5] Fix pep8. --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 52dc2c1f..90f6dd11 100755 --- a/setup.py +++ b/setup.py @@ -233,7 +233,8 @@ def get_extensions(): library_dirs=library_dirs, include_dirs=include_dirs, # Since casacore 3.0.0 we have to be C++11 - extra_compile_args=['-std=c++11', '-lpthread'])) + extra_compile_args=['-std=c++11', + '-lpthread'])) return extensions