diff --git a/pycdfpp/buffers.hpp b/pycdfpp/buffers.hpp index 186d9f7..33e32ea 100644 --- a/pycdfpp/buffers.hpp +++ b/pycdfpp/buffers.hpp @@ -96,9 +96,13 @@ template [[nodiscard]] py::array make_array(Variable& variable, py::object& obj) { // static_assert(data_t != CDF_Types::CDF_CHAR and data_t != CDF_Types::CDF_UCHAR); - return py::array_t>(shape_ssize_t(variable), - strides>(variable), variable.get>().data(), - obj); + from_cdf_type_t* ptr = nullptr; + { + py::gil_scoped_release release; + ptr = variable.get>().data(); + } + return py::array_t>( + shape_ssize_t(variable), strides>(variable), ptr, obj); } template @@ -155,9 +159,14 @@ template [[nodiscard]] py::buffer_info impl_make_buffer(cdf::Variable& var) { using U = cdf::from_cdf_type_t; + char* ptr = nullptr; + { + py::gil_scoped_release release; + ptr = var.bytes_ptr(); + } if constexpr ((T == CDF_Types::CDF_CHAR) or (T == CDF_Types::CDF_UCHAR)) { - return py::buffer_info(var.bytes_ptr(), /* Pointer to buffer */ + return py::buffer_info(ptr, /* Pointer to buffer */ var.shape().back(), /* Size of one scalar */ fmt::format("{}s", var.shape().back()), static_cast(std::size(var.shape()) - 1), /* Number of dimensions */ @@ -165,7 +174,7 @@ template } else { - return py::buffer_info(var.bytes_ptr(), /* Pointer to buffer */ + return py::buffer_info(ptr, /* Pointer to buffer */ sizeof(U), /* Size of one scalar */ py::format_descriptor::format(), static_cast(std::size(var.shape())), /* Number of dimensions */ @@ -177,7 +186,7 @@ template [[nodiscard]] py::object make_str_array(py::object& obj) { py::module_ np = py::module_::import("numpy"); - if constexpr(encode_strings) + if constexpr (encode_strings) { return np.attr("char").attr("decode")(py::memoryview(obj)); } @@ -185,7 +194,6 @@ template { return np.attr("array")(py::memoryview(obj)); } - } } diff --git a/pycdfpp/cdf.hpp b/pycdfpp/cdf.hpp index 72b4bfd..59bf031 100644 --- a/pycdfpp/cdf.hpp +++ b/pycdfpp/cdf.hpp @@ -160,6 +160,7 @@ void def_cdf_loading_functions(T& mod) [](py::bytes& buffer, bool iso_8859_1_to_utf8) { py::buffer_info info(py::buffer(buffer).request()); + py::gil_scoped_release release; return io::load(static_cast(info.ptr), static_cast(info.size), iso_8859_1_to_utf8); }, @@ -172,6 +173,7 @@ void def_cdf_loading_functions(T& mod) py::buffer_info info(buffer.request()); if (info.ndim != 1) throw std::runtime_error("Incompatible buffer dimension!"); + py::gil_scoped_release release; return io::load(static_cast(info.ptr), info.shape[0], iso_8859_1_to_utf8, true); }, py::arg("buffer"), py::arg("iso_8859_1_to_utf8") = false, py::return_value_policy::move, @@ -180,7 +182,10 @@ void def_cdf_loading_functions(T& mod) mod.def( "load", [](const char* fname, bool iso_8859_1_to_utf8, bool lazy_load) - { return io::load(std::string { fname }, iso_8859_1_to_utf8, lazy_load); }, + { + py::gil_scoped_release release; + return io::load(std::string { fname }, iso_8859_1_to_utf8, lazy_load); + }, py::arg("fname"), py::arg("iso_8859_1_to_utf8") = false, py::arg("lazy_load") = true, py::return_value_policy::move); } @@ -196,14 +201,28 @@ void def_cdf_saving_functions(T& mod) mod.def( "save", - [](const CDF& cdf, const char* fname) { return io::save(cdf, std::string { fname }); }, + [](const CDF& cdf, const char* fname) + { + py::gil_scoped_release release; + return io::save(cdf, std::string { fname }); + }, py::arg("cdf"), py::arg("fname")); py::class_(mod, "_cdf_bytes", py::buffer_protocol()) - .def_buffer([](cdf_bytes& b) -> py::buffer_info - { return py::buffer_info(b.data.data(), std::size(b.data), true); }); + .def_buffer( + [](cdf_bytes& b) -> py::buffer_info + { + py::gil_scoped_release release; + return py::buffer_info(b.data.data(), std::size(b.data), true); + }); mod.def( - "save", [](const CDF& cdf) { return cdf_bytes { io::save(cdf) }; }, py::arg("cdf")); + "save", + [](const CDF& cdf) + { + py::gil_scoped_release release; + return cdf_bytes { io::save(cdf) }; + }, + py::arg("cdf")); }