From 7b191c91f9906ee0ff763d8c55c0880445a0bb20 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Mon, 22 Nov 2021 16:08:29 -0600 Subject: [PATCH 1/9] Family of make_Sycl*( Ref ) functions This is needed in order to be able to write pybind11 casters directly mapping sycl classes to `dpctl.Sycl*` classes for SyclContext, SyclQueue, SyclDevice and SyclEvent classes. --- dpctl/_sycl_context.pyx | 9 +++++++++ dpctl/_sycl_device.pyx | 9 +++++++++ dpctl/_sycl_event.pyx | 9 +++++++++ dpctl/_sycl_queue.pyx | 9 +++++++++ 4 files changed, 36 insertions(+) diff --git a/dpctl/_sycl_context.pyx b/dpctl/_sycl_context.pyx index 404f27c99b..0499a21c06 100644 --- a/dpctl/_sycl_context.pyx +++ b/dpctl/_sycl_context.pyx @@ -485,3 +485,12 @@ cdef api DPCTLSyclContextRef get_context_ref(SyclContext ctx): :class:`dpctl.SyclContext` instance. """ return ctx.get_context_ref() + + +cdef api SyclContext make_SyclContext(DPCTLSyclContextRef CRef): + """ + C-API function to create :class:`dpctl.SyclContext` instance + from the given opaque context reference. + """ + cdef DPCTLSyclContextRef copied_CRef = DPCTLContext_Copy(CRef) + return SyclContext._create(copied_CRef) diff --git a/dpctl/_sycl_device.pyx b/dpctl/_sycl_device.pyx index 70302e9937..c32575b1ae 100644 --- a/dpctl/_sycl_device.pyx +++ b/dpctl/_sycl_device.pyx @@ -1136,3 +1136,12 @@ cdef api DPCTLSyclDeviceRef get_device_ref(SyclDevice dev): :class:`dpctl.SyclDevice` instance. """ return dev.get_device_ref() + + +cdef api SyclDevice make_SyclDevice(DPCTLSyclDeviceRef DRef): + """ + C-API function to create :class:`dpctl.SyclDevice` instance + from the given opaque device reference. + """ + cdef DPCTLSyclDeviceRef copied_DRef = DPCTLDevice_Copy(DRef) + return SyclDevice._create(copied_DRef) diff --git a/dpctl/_sycl_event.pyx b/dpctl/_sycl_event.pyx index f78e19c326..1d02450775 100644 --- a/dpctl/_sycl_event.pyx +++ b/dpctl/_sycl_event.pyx @@ -64,6 +64,15 @@ cdef api DPCTLSyclEventRef get_event_ref(SyclEvent ev): return ev.get_event_ref() +cdef api SyclEvent make_SyclEvent(DPCTLSyclEventRef ERef): + """ + C-API function to create :class:`dpctl.SyclEvent` + instance from opaque sycl event reference. + """ + cdef DPCTLSyclEventRef copied_ERef = DPCTLEvent_Copy(ERef) + return SyclEvent._create(copied_ERef) + + cdef void _event_capsule_deleter(object o): cdef DPCTLSyclEventRef ERef = NULL if pycapsule.PyCapsule_IsValid(o, "SyclEventRef"): diff --git a/dpctl/_sycl_queue.pyx b/dpctl/_sycl_queue.pyx index 1091bbd765..614b7b2ae8 100644 --- a/dpctl/_sycl_queue.pyx +++ b/dpctl/_sycl_queue.pyx @@ -1007,3 +1007,12 @@ cdef api DPCTLSyclQueueRef get_queue_ref(SyclQueue q): :class:`dpctl.SyclQueue` instance. """ return q.get_queue_ref() + + +cdef api SyclQueue make_SyclQueue(DPCTLSyclQueueRef QRef): + """ + C-API function to create :class:`dpctl.SyclQueue` instance + from the given opaque queue reference. + """ + cdef DPCTLSyclQueueRef copied_QRef = DPCTLQueue_Copy(QRef) + return SyclQueue._create(copied_QRef) From 3691cfb7ad12670d2d6e4420b4f3b349f937d73c Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 23 Nov 2021 12:13:14 -0600 Subject: [PATCH 2/9] Reorg of dpctl/include folder 1. `dpctl/include` folder that is being installed in the site-packages/dpctl changes layout. It now has the structure dpctl/ include/ syclinterface/ *.h # all files that used to be in dpctl/include are moving here syclinterface.h dpctl_capi.h dpctl4pybind11.hpp _backend.pxd was modified to include syclinterface/ into path of header files from which we are importing build_backend.py was modified to copy install/include into dpctl/include/syclinterface instead of dpctl/include, and steps were added to also copy newly added dpctl/apis/include/* files into dpctl/include/ 2. Now, to work with syclinterface, one only needs `#include "syclinterface.h"` assuming `-I$(python -c "import dpctl; print(dpctl.get_include())")` is used 3. To work with `dpctl` objects using Python C-API one needs ``#include "dpctl_capi.h"`` where objects, types and C-API functions are declared. 4. To work with pybind11, one needs ``#include "dpctl4pybind11.hpp"`` where type casters are defined to map betwen ``sycl::queue`` and `dpctl.SyclQueue`, and correspondingly for ``sycl::device``, ``sycl::context`` and ``sycl::event``. Modifications to examples are forthcoming _backend.pxd should use syclinterface/ to reference .h files --- dpctl/_backend.pxd | 34 ++++----- dpctl/apis/include/dpctl4pybind11.hpp | 100 ++++++++++++++++++++++++++ dpctl/apis/include/dpctl_capi.h | 55 ++++++++++++++ dpctl/apis/include/syclinterface.h | 44 ++++++++++++ scripts/build_backend.py | 8 ++- setup.py | 2 +- 6 files changed, 224 insertions(+), 19 deletions(-) create mode 100644 dpctl/apis/include/dpctl4pybind11.hpp create mode 100644 dpctl/apis/include/dpctl_capi.h create mode 100644 dpctl/apis/include/syclinterface.h diff --git a/dpctl/_backend.pxd b/dpctl/_backend.pxd index 8a74222b06..ab4af7d136 100644 --- a/dpctl/_backend.pxd +++ b/dpctl/_backend.pxd @@ -25,15 +25,15 @@ from libc.stdint cimport int64_t, uint32_t from libcpp cimport bool -cdef extern from "dpctl_error_handler_type.h": +cdef extern from "syclinterface/dpctl_error_handler_type.h": ctypedef void error_handler_callback(int err_code) -cdef extern from "dpctl_utils.h": +cdef extern from "syclinterface/dpctl_utils.h": cdef void DPCTLCString_Delete(const char *str) cdef void DPCTLSize_t_Array_Delete(size_t *arr) -cdef extern from "dpctl_sycl_enum_types.h": +cdef extern from "syclinterface/dpctl_sycl_enum_types.h": ctypedef enum _backend_type 'DPCTLSyclBackendType': _ALL_BACKENDS 'DPCTL_ALL_BACKENDS' _CUDA 'DPCTL_CUDA' @@ -111,7 +111,7 @@ cdef extern from "dpctl_sycl_enum_types.h": _COMPLETE 'DPCTL_COMPLETE' -cdef extern from "dpctl_sycl_types.h": +cdef extern from "syclinterface/dpctl_sycl_types.h": cdef struct DPCTLOpaqueSyclContext cdef struct DPCTLOpaqueSyclDevice cdef struct DPCTLOpaqueSyclDeviceSelector @@ -133,12 +133,12 @@ cdef extern from "dpctl_sycl_types.h": ctypedef DPCTLOpaqueSyclUSM *DPCTLSyclUSMRef -cdef extern from "dpctl_sycl_device_manager.h": +cdef extern from "syclinterface/dpctl_sycl_device_manager.h": cdef struct DPCTLDeviceVector ctypedef DPCTLDeviceVector *DPCTLDeviceVectorRef -cdef extern from "dpctl_sycl_device_interface.h": +cdef extern from "syclinterface/dpctl_sycl_device_interface.h": cdef bool DPCTLDevice_AreEq(const DPCTLSyclDeviceRef DRef1, const DPCTLSyclDeviceRef DRef2) cdef DPCTLSyclDeviceRef DPCTLDevice_Copy(const DPCTLSyclDeviceRef DRef) @@ -192,7 +192,7 @@ cdef extern from "dpctl_sycl_device_interface.h": cdef DPCTLSyclDeviceRef DPCTLDevice_GetParentDevice(const DPCTLSyclDeviceRef DRef) -cdef extern from "dpctl_sycl_device_manager.h": +cdef extern from "syclinterface/dpctl_sycl_device_manager.h": cdef DPCTLDeviceVectorRef DPCTLDeviceVector_CreateFromArray( size_t nelems, DPCTLSyclDeviceRef *elems) @@ -213,7 +213,7 @@ cdef extern from "dpctl_sycl_device_manager.h": cdef int64_t DPCTLDeviceMgr_GetRelativeId(const DPCTLSyclDeviceRef DRef) -cdef extern from "dpctl_sycl_device_selector_interface.h": +cdef extern from "syclinterface/dpctl_sycl_device_selector_interface.h": DPCTLSyclDeviceSelectorRef DPCTLAcceleratorSelector_Create() DPCTLSyclDeviceSelectorRef DPCTLDefaultSelector_Create() DPCTLSyclDeviceSelectorRef DPCTLCPUSelector_Create() @@ -224,7 +224,7 @@ cdef extern from "dpctl_sycl_device_selector_interface.h": int DPCTLDeviceSelector_Score(DPCTLSyclDeviceSelectorRef, DPCTLSyclDeviceRef) -cdef extern from "dpctl_sycl_event_interface.h": +cdef extern from "syclinterface/dpctl_sycl_event_interface.h": cdef DPCTLSyclEventRef DPCTLEvent_Create() cdef DPCTLSyclEventRef DPCTLEvent_Copy(const DPCTLSyclEventRef ERef) cdef void DPCTLEvent_Wait(DPCTLSyclEventRef ERef) @@ -246,13 +246,13 @@ cdef extern from "dpctl_sycl_event_interface.h": cdef size_t DPCTLEvent_GetProfilingInfoEnd(DPCTLSyclEventRef ERef) -cdef extern from "dpctl_sycl_kernel_interface.h": +cdef extern from "syclinterface/dpctl_sycl_kernel_interface.h": cdef const char* DPCTLKernel_GetFunctionName(const DPCTLSyclKernelRef KRef) cdef size_t DPCTLKernel_GetNumArgs(const DPCTLSyclKernelRef KRef) cdef void DPCTLKernel_Delete(DPCTLSyclKernelRef KRef) -cdef extern from "dpctl_sycl_platform_manager.h": +cdef extern from "syclinterface/dpctl_sycl_platform_manager.h": cdef struct DPCTLPlatformVector ctypedef DPCTLPlatformVector *DPCTLPlatformVectorRef @@ -265,7 +265,7 @@ cdef extern from "dpctl_sycl_platform_manager.h": cdef void DPCTLPlatformMgr_PrintInfo(const DPCTLSyclPlatformRef, size_t) -cdef extern from "dpctl_sycl_platform_interface.h": +cdef extern from "syclinterface/dpctl_sycl_platform_interface.h": cdef DPCTLSyclPlatformRef DPCTLPlatform_Copy(const DPCTLSyclPlatformRef) cdef DPCTLSyclPlatformRef DPCTLPlatform_Create() cdef DPCTLSyclPlatformRef DPCTLPlatform_CreateFromSelector( @@ -278,7 +278,7 @@ cdef extern from "dpctl_sycl_platform_interface.h": cdef DPCTLPlatformVectorRef DPCTLPlatform_GetPlatforms() -cdef extern from "dpctl_sycl_context_interface.h": +cdef extern from "syclinterface/dpctl_sycl_context_interface.h": cdef DPCTLSyclContextRef DPCTLContext_Create( const DPCTLSyclDeviceRef DRef, error_handler_callback *handler, @@ -299,7 +299,7 @@ cdef extern from "dpctl_sycl_context_interface.h": cdef void DPCTLContext_Delete(DPCTLSyclContextRef CtxRef) -cdef extern from "dpctl_sycl_program_interface.h": +cdef extern from "syclinterface/dpctl_sycl_program_interface.h": cdef DPCTLSyclProgramRef DPCTLProgram_CreateFromSpirv( const DPCTLSyclContextRef Ctx, const void *IL, @@ -317,7 +317,7 @@ cdef extern from "dpctl_sycl_program_interface.h": cdef void DPCTLProgram_Delete(DPCTLSyclProgramRef PRef) -cdef extern from "dpctl_sycl_queue_interface.h": +cdef extern from "syclinterface/dpctl_sycl_queue_interface.h": cdef bool DPCTLQueue_AreEq(const DPCTLSyclQueueRef QRef1, const DPCTLSyclQueueRef QRef2) cdef DPCTLSyclQueueRef DPCTLQueue_Create( @@ -381,7 +381,7 @@ cdef extern from "dpctl_sycl_queue_interface.h": cdef bool DPCTLQueue_HasEnableProfiling(const DPCTLSyclQueueRef QRef) -cdef extern from "dpctl_sycl_queue_manager.h": +cdef extern from "syclinterface/dpctl_sycl_queue_manager.h": cdef DPCTLSyclQueueRef DPCTLQueueMgr_GetCurrentQueue() cdef bool DPCTLQueueMgr_GlobalQueueIsCurrent() cdef bool DPCTLQueueMgr_IsCurrentQueue(const DPCTLSyclQueueRef QRef) @@ -391,7 +391,7 @@ cdef extern from "dpctl_sycl_queue_manager.h": cdef size_t DPCTLQueueMgr_GetQueueStackSize() -cdef extern from "dpctl_sycl_usm_interface.h": +cdef extern from "syclinterface/dpctl_sycl_usm_interface.h": cdef DPCTLSyclUSMRef DPCTLmalloc_shared( size_t size, DPCTLSyclQueueRef QRef) diff --git a/dpctl/apis/include/dpctl4pybind11.hpp b/dpctl/apis/include/dpctl4pybind11.hpp new file mode 100644 index 0000000000..2d9775365d --- /dev/null +++ b/dpctl/apis/include/dpctl4pybind11.hpp @@ -0,0 +1,100 @@ +//===----------- dpctl4pybind11.h - Headers for type pybind11 casters -*-C-*- +//===// +// +// Data Parallel Control (dpctl) +// +// Copyright 2020-2021 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file defines imports for dcptl's Python C-API +//===----------------------------------------------------------------------===// + +#pragma once + +#include "dpctl_capi.h" +#include +#include + +namespace py = pybind11; + +namespace pybind11 +{ +namespace detail +{ +template <> struct type_caster +{ +public: + PYBIND11_TYPE_CASTER(sycl::queue, _("dpctl.SyclQueue")); + + bool load(handle src, bool) + { + PyObject *source = src.ptr(); + if (PyObject_TypeCheck(source, &PySyclQueueType)) { + DPCTLSyclQueueRef QRef = + get_queue_ref(reinterpret_cast(source)); + sycl::queue *q = reinterpret_cast(QRef); + value = *q; + return true; + } + else { + throw std::runtime_error( + "Input is of unexpected type, expected egapi.Example"); + } + } + + static handle cast(sycl::queue src, return_value_policy, handle) + { + auto tmp = make_SyclQueue(reinterpret_cast(&src)); + return handle(reinterpret_cast(tmp)); + } +}; +} // namespace detail +} // namespace pybind11 + +namespace pybind11 +{ +namespace detail +{ +template <> struct type_caster +{ +public: + PYBIND11_TYPE_CASTER(sycl::device, _("dpctl.SyclDevice")); + + bool load(handle src, bool) + { + PyObject *source = src.ptr(); + if (PyObject_TypeCheck(source, &PySyclDeviceType)) { + DPCTLSyclDeviceRef DRef = + get_device_ref(reinterpret_cast(source)); + sycl::device *d = reinterpret_cast(DRef); + value = *d; + return true; + } + else { + throw std::runtime_error( + "Input is of unexpected type, expected egapi.Example"); + } + } + + static handle cast(sycl::device src, return_value_policy, handle) + { + auto tmp = make_SyclDevice(reinterpret_cast(&src)); + return handle(reinterpret_cast(tmp)); + } +}; +} // namespace detail +} // namespace pybind11 diff --git a/dpctl/apis/include/dpctl_capi.h b/dpctl/apis/include/dpctl_capi.h new file mode 100644 index 0000000000..0a484bcff7 --- /dev/null +++ b/dpctl/apis/include/dpctl_capi.h @@ -0,0 +1,55 @@ +//===----------- dpctl_capi.h - Headers for dpctl's C-API -*-C-*- ===// +// +// Data Parallel Control (dpctl) +// +// Copyright 2020-2021 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file defines imports for dcptl's Python C-API +//===----------------------------------------------------------------------===// + +#pragma once + +// clang-format off +// Ordering of includes is important here. dpctl_sycl_types defines types +// used by dpctl's Python C-API headers. +#include "syclinterface/dpctl_sycl_types.h" +#include "../_sycl_device.h" +#include "../_sycl_device_api.h" +#include "../_sycl_context.h" +#include "../_sycl_context_api.h" +#include "../_sycl_event.h" +#include "../_sycl_event_api.h" +#include "../_sycl_queue.h" +#include "../_sycl_queue_api.h" +// clang-format on + +/* + * Function to import dpctl and make C-API functions available. + * C functions can use dpctl's C-API functions without linking to + * shared objects defining this symbols, if they call `import_dpctl()` + * prior to using those symbols. + */ +void import_dpctl(void) +{ + import_dpctl___sycl_device(); + import_dpctl___sycl_context(); + import_dpctl___sycl_event(); + import_dpctl___sycl_queue(); + + return; +} diff --git a/dpctl/apis/include/syclinterface.h b/dpctl/apis/include/syclinterface.h new file mode 100644 index 0000000000..04ab1cfbbb --- /dev/null +++ b/dpctl/apis/include/syclinterface.h @@ -0,0 +1,44 @@ +//=== syclinterace.h - single include header for libsyclinterface -*-C-*- ===// +// +// Data Parallel Control (dpctl) +// +// Copyright 2020-2021 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file includes all the headers of syclinterface/ +//===----------------------------------------------------------------------===// + +#pragma once + +// clang-format off +#include "syclinterface/dpctl_sycl_types.h" +#include "syclinterface/dpctl_sycl_enum_types.h" +#include "syclinterface/dpctl_service.h" +#include "syclinterface/dpctl_vector.h" +#include "syclinterface/dpctl_utils.h" +#include "syclinterface/dpctl_sycl_device_selector_interface.h" +#include "syclinterface/dpctl_sycl_context_interface.h" +#include "syclinterface/dpctl_sycl_device_interface.h" +#include "syclinterface/dpctl_sycl_event_interface.h" +#include "syclinterface/dpctl_sycl_platform_interface.h" +#include "syclinterface/dpctl_sycl_queue_interface.h" +#include "syclinterface/dpctl_sycl_usm_interface.h" + +#include "syclinterface/dpctl_sycl_device_manager.h" +#include "syclinterface/dpctl_sycl_platform_manager.h" +#include "syclinterface/dpctl_sycl_queue_manager.h" +// clang-format on diff --git a/scripts/build_backend.py b/scripts/build_backend.py index 0ee4e8799a..d188dfb8b3 100644 --- a/scripts/build_backend.py +++ b/scripts/build_backend.py @@ -213,9 +213,15 @@ def build_backend( shutil.rmtree(include_dir) shutil.copytree( - os.path.join(dpctl_dir, "libsyclinterface", "include"), include_dir + os.path.join(dpctl_dir, "libsyclinterface", "include"), + os.path.join(include_dir, "syclinterface"), ) + for file in glob.glob( + os.path.join(dpctl_dir, "dpctl", "apis", "include", "*.h*") + ): + shutil.copy(file, include_dir) + if __name__ == "__main__": build_backend() diff --git a/setup.py b/setup.py index c690c9ca28..b624ae473a 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ # to build_ext command _coverage = False dpctl_sycl_interface_lib = "dpctl" -dpctl_sycl_interface_include = r"dpctl/include" +dpctl_sycl_interface_include = os.path.join("dpctl", "include") # Get long description with open("README.md", "r", encoding="utf-8") as file: From ca3ee4d2ec29a7c1c474c5152970fd5f17d48fcf Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 23 Nov 2021 13:14:04 -0600 Subject: [PATCH 3/9] Streamlined pybind11 examples using dpctl4pybind11.hpp --- .../_usm_alloc_example.cpp | 25 +-- .../pybind11/use_dpctl_syclqueue/_example.cpp | 105 ++++++++++++ .../pybind11/use_dpctl_syclqueue/example.py | 2 +- .../use_dpctl_syclqueue/pybind11_example.cpp | 159 ------------------ .../pybind11/use_dpctl_syclqueue/setup.py | 4 +- 5 files changed, 113 insertions(+), 182 deletions(-) create mode 100644 examples/pybind11/use_dpctl_syclqueue/_example.cpp delete mode 100644 examples/pybind11/use_dpctl_syclqueue/pybind11_example.cpp diff --git a/examples/pybind11/external_usm_allocation/_usm_alloc_example.cpp b/examples/pybind11/external_usm_allocation/_usm_alloc_example.cpp index 7a4e846f6d..30216dac55 100644 --- a/examples/pybind11/external_usm_allocation/_usm_alloc_example.cpp +++ b/examples/pybind11/external_usm_allocation/_usm_alloc_example.cpp @@ -33,12 +33,7 @@ //===----------------------------------------------------------------------===// #include -// clang-format off -#include "dpctl_sycl_types.h" -#include "../_sycl_queue.h" -#include "../_sycl_queue_api.h" -// clang-format on - +#include "dpctl4pybind11.hpp" #include "pybind11/pybind11.h" #include "pybind11/stl.h" @@ -87,19 +82,9 @@ struct DMatrix vec_t vec_; }; -DMatrix create_matrix(py::object queue, size_t n, size_t m) +DMatrix create_matrix(sycl::queue &q, size_t n, size_t m) { - PyObject *queue_ptr = queue.ptr(); - if (PyObject_TypeCheck(queue_ptr, &PySyclQueueType)) { - DPCTLSyclQueueRef QRef = - get_queue_ref(reinterpret_cast(queue_ptr)); - sycl::queue *q = reinterpret_cast(QRef); - - return DMatrix(*q, n, m); - } - else { - throw std::runtime_error("expected dpctl.SyclQueue as argument"); - } + return DMatrix(q, n, m); } py::dict construct_sua_iface(DMatrix &m) @@ -149,8 +134,8 @@ py::list tolist(DMatrix &m) PYBIND11_MODULE(external_usm_alloc, m) { - // Import the dpctl._sycl_queue extension - import_dpctl___sycl_queue(); + // Import the dpctl extensions + import_dpctl(); py::class_ dm(m, "DMatrix"); dm.def(py::init(&create_matrix), diff --git a/examples/pybind11/use_dpctl_syclqueue/_example.cpp b/examples/pybind11/use_dpctl_syclqueue/_example.cpp new file mode 100644 index 0000000000..7b26a35858 --- /dev/null +++ b/examples/pybind11/use_dpctl_syclqueue/_example.cpp @@ -0,0 +1,105 @@ +//==- pybind11_example.cpp - Example of Pybind11 extension working with -===// +// dpctl Python objects. +// +// Data Parallel Control (dpctl) +// +// Copyright 2020-2021 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements Pybind11-generated extension exposing functions that +/// take dpctl Python objects, such as dpctl.SyclQueue, dpctl.SyclDevice as +/// arguments. +/// +//===----------------------------------------------------------------------===// + +#include "dpctl4pybind11.hpp" +#include +#include +#include +#include + +namespace py = pybind11; + +uint64_t get_device_global_mem_size(sycl::device &d) +{ + return d.get_info(); +} + +uint64_t get_device_local_mem_size(sycl::device &d) +{ + return d.get_info(); +} + +py::array_t +offloaded_array_mod(sycl::queue &q, + py::array_t array, + int64_t mod) +{ + py::buffer_info arg_pybuf = array.request(); + if (arg_pybuf.ndim != 1) { + throw std::runtime_error("Expecting a vector"); + } + if (mod <= 0) { + throw std::runtime_error("Modulus must be non-negative"); + } + + size_t n = arg_pybuf.size; + + auto res = py::array_t(n); + py::buffer_info res_pybuf = res.request(); + + int64_t *a = static_cast(arg_pybuf.ptr); + int64_t *r = static_cast(res_pybuf.ptr); + + { + const sycl::property_list props = { + sycl::property::buffer::use_host_ptr()}; + sycl::buffer a_buf(a, sycl::range<1>(n), props); + sycl::buffer r_buf(r, sycl::range<1>(n), props); + + q.submit([&](sycl::handler &cgh) { + sycl::accessor a_acc(a_buf, cgh, sycl::read_only); + sycl::accessor r_acc(r_buf, cgh, sycl::write_only, sycl::no_init); + + cgh.parallel_for(sycl::range<1>(n), [=](sycl::id<1> idx) { + r_acc[idx] = a_acc[idx] % mod; + }); + }).wait_and_throw(); + } + + return res; +} + +PYBIND11_MODULE(use_queue_device_ext, m) +{ + // Import the dpctl extensions + import_dpctl(); + m.def( + "get_max_compute_units", + [=](sycl::queue &q) -> size_t { + return q.get_device() + .get_info(); + }, + "Computes max_compute_units property of the device underlying given " + "dpctl.SyclQueue"); + m.def("get_device_global_mem_size", &get_device_global_mem_size, + "Computes amount of global memory of the given dpctl.SyclDevice"); + m.def("get_device_local_mem_size", &get_device_local_mem_size, + "Computes amount of local memory of the given dpctl.SyclDevice"); + m.def("offloaded_array_mod", &offloaded_array_mod, + "Compute offloaded modular reduction of integer-valued NumPy array"); +} diff --git a/examples/pybind11/use_dpctl_syclqueue/example.py b/examples/pybind11/use_dpctl_syclqueue/example.py index 4c53bfafe2..1980ca82d3 100644 --- a/examples/pybind11/use_dpctl_syclqueue/example.py +++ b/examples/pybind11/use_dpctl_syclqueue/example.py @@ -17,7 +17,7 @@ # coding: utf-8 import numpy as np -import pybind11_example as eg +import use_queue_device_ext as eg import dpctl diff --git a/examples/pybind11/use_dpctl_syclqueue/pybind11_example.cpp b/examples/pybind11/use_dpctl_syclqueue/pybind11_example.cpp deleted file mode 100644 index ed22daec2a..0000000000 --- a/examples/pybind11/use_dpctl_syclqueue/pybind11_example.cpp +++ /dev/null @@ -1,159 +0,0 @@ -//==- pybind11_example.cpp - Example of Pybind11 extension working with -===// -// dpctl Python objects. -// -// Data Parallel Control (dpctl) -// -// Copyright 2020-2021 Intel Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file implements Pybind11-generated extension exposing functions that -/// take dpctl Python objects, such as dpctl.SyclQueue, dpctl.SyclDevice as -/// arguments. -/// -//===----------------------------------------------------------------------===// - -#include -#include -#include -#include - -// clang-format off -// Ordering of includes is important here. dpctl_sycl_types defines types -// used by dpctl's Python C-API headers. -#include "dpctl_sycl_types.h" -#include "../_sycl_queue.h" -#include "../_sycl_queue_api.h" -#include "../_sycl_device.h" -#include "../_sycl_device_api.h" -// clang-format on - -namespace py = pybind11; - -size_t get_max_compute_units(py::object queue) -{ - PyObject *queue_ptr = queue.ptr(); - if (PyObject_TypeCheck(queue_ptr, &PySyclQueueType)) { - DPCTLSyclQueueRef QRef = - get_queue_ref(reinterpret_cast(queue_ptr)); - sycl::queue *q = reinterpret_cast(QRef); - - return q->get_device() - .get_info(); - } - else { - throw std::runtime_error("expected dpctl.SyclQueue as argument"); - } -} - -uint64_t get_device_global_mem_size(py::object device) -{ - PyObject *device_pycapi = device.ptr(); - if (PyObject_TypeCheck(device_pycapi, &PySyclDeviceType)) { - DPCTLSyclDeviceRef DRef = get_device_ref( - reinterpret_cast(device_pycapi)); - sycl::device *d_ptr = reinterpret_cast(DRef); - return d_ptr->get_info(); - } - else { - throw std::runtime_error("expected dpctl.SyclDevice as argument"); - } -} - -uint64_t get_device_local_mem_size(py::object device) -{ - PyObject *device_pycapi = device.ptr(); - if (PyObject_TypeCheck(device_pycapi, &PySyclDeviceType)) { - DPCTLSyclDeviceRef DRef = get_device_ref( - reinterpret_cast(device_pycapi)); - sycl::device *d_ptr = reinterpret_cast(DRef); - return d_ptr->get_info(); - } - else { - throw std::runtime_error("expected dpctl.SyclDevice as argument"); - } -} - -py::array_t -offloaded_array_mod(py::object queue, - py::array_t array, - int64_t mod) -{ - sycl::queue *q_ptr; - - PyObject *queue_pycapi = queue.ptr(); - if (PyObject_TypeCheck(queue_pycapi, &PySyclQueueType)) { - DPCTLSyclQueueRef QRef = - get_queue_ref(reinterpret_cast(queue_pycapi)); - q_ptr = reinterpret_cast(QRef); - } - else { - throw std::runtime_error("expected dpctl.SyclQueue as argument"); - } - - py::buffer_info arg_pybuf = array.request(); - if (arg_pybuf.ndim != 1) { - throw std::runtime_error("Expecting a vector"); - } - if (mod <= 0) { - throw std::runtime_error("Modulus must be non-negative"); - } - - size_t n = arg_pybuf.size; - - auto res = py::array_t(n); - py::buffer_info res_pybuf = res.request(); - - int64_t *a = static_cast(arg_pybuf.ptr); - int64_t *r = static_cast(res_pybuf.ptr); - - { - const sycl::property_list props = { - sycl::property::buffer::use_host_ptr()}; - sycl::buffer a_buf(a, sycl::range<1>(n), props); - sycl::buffer r_buf(r, sycl::range<1>(n), props); - - q_ptr - ->submit([&](sycl::handler &cgh) { - sycl::accessor a_acc(a_buf, cgh, sycl::read_only); - sycl::accessor r_acc(r_buf, cgh, sycl::write_only, - sycl::no_init); - - cgh.parallel_for(sycl::range<1>(n), [=](sycl::id<1> idx) { - r_acc[idx] = a_acc[idx] % mod; - }); - }) - .wait_and_throw(); - } - - return res; -} - -PYBIND11_MODULE(pybind11_example, m) -{ - // Import the dpctl._sycl_queue, dpctl._sycl_device extensions - import_dpctl___sycl_device(); - import_dpctl___sycl_queue(); - m.def("get_max_compute_units", &get_max_compute_units, - "Computes max_compute_units property of the device underlying given " - "dpctl.SyclQueue"); - m.def("get_device_global_mem_size", &get_device_global_mem_size, - "Computes amount of global memory of the given dpctl.SyclDevice"); - m.def("get_device_local_mem_size", &get_device_local_mem_size, - "Computes amount of local memory of the given dpctl.SyclDevice"); - m.def("offloaded_array_mod", &offloaded_array_mod, - "Compute offloaded modular reduction of integer-valued NumPy array"); -} diff --git a/examples/pybind11/use_dpctl_syclqueue/setup.py b/examples/pybind11/use_dpctl_syclqueue/setup.py index 4569c99029..34eeebe38c 100644 --- a/examples/pybind11/use_dpctl_syclqueue/setup.py +++ b/examples/pybind11/use_dpctl_syclqueue/setup.py @@ -21,8 +21,8 @@ exts = [ Pybind11Extension( - "pybind11_example", - ["./pybind11_example.cpp"], + "use_queue_device_ext", + ["./_example.cpp"], include_dirs=[dpctl.get_include()], extra_compile_args=["-fPIC"], extra_link_args=["-fPIC"], From fd35965c1bed704e33d086be5f91bd3c8a588ab1 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 23 Nov 2021 13:43:14 -0600 Subject: [PATCH 4/9] Changed include of dpctl_sycl_types.h to include of syclinterface.h --- examples/cython/sycl_buffer/use_sycl_buffer.cpp | 2 +- examples/cython/sycl_buffer/use_sycl_buffer.h | 2 +- examples/cython/usm_memory/sycl_blackscholes.cpp | 2 +- examples/cython/usm_memory/sycl_blackscholes.hpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/cython/sycl_buffer/use_sycl_buffer.cpp b/examples/cython/sycl_buffer/use_sycl_buffer.cpp index 57b28de1fb..afbc814aa9 100644 --- a/examples/cython/sycl_buffer/use_sycl_buffer.cpp +++ b/examples/cython/sycl_buffer/use_sycl_buffer.cpp @@ -28,7 +28,7 @@ //===----------------------------------------------------------------------===// #include "use_sycl_buffer.h" -#include "dpctl_sycl_types.h" +#include "syclinterface.h" #include #include diff --git a/examples/cython/sycl_buffer/use_sycl_buffer.h b/examples/cython/sycl_buffer/use_sycl_buffer.h index 66bfe756bc..9697f81fd2 100644 --- a/examples/cython/sycl_buffer/use_sycl_buffer.h +++ b/examples/cython/sycl_buffer/use_sycl_buffer.h @@ -1,4 +1,4 @@ -#include "dpctl_sycl_types.h" +#include "syclinterface.h" #include extern int c_columnwise_total(DPCTLSyclQueueRef q, diff --git a/examples/cython/usm_memory/sycl_blackscholes.cpp b/examples/cython/usm_memory/sycl_blackscholes.cpp index 67406345b6..87c1c517ce 100644 --- a/examples/cython/usm_memory/sycl_blackscholes.cpp +++ b/examples/cython/usm_memory/sycl_blackscholes.cpp @@ -27,7 +27,7 @@ //===----------------------------------------------------------------------===// #include "sycl_blackscholes.hpp" -#include "dpctl_sycl_types.h" +#include "syclinterface.h" #include #include #include diff --git a/examples/cython/usm_memory/sycl_blackscholes.hpp b/examples/cython/usm_memory/sycl_blackscholes.hpp index 02181e2756..e61b9b47f6 100644 --- a/examples/cython/usm_memory/sycl_blackscholes.hpp +++ b/examples/cython/usm_memory/sycl_blackscholes.hpp @@ -24,7 +24,7 @@ /// //===----------------------------------------------------------------------===// -#include "dpctl_sycl_types.h" +#include "syclinterface.h" #include template From 3b18c73e0ba39754d500c3fdf035604fde618c63 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 23 Nov 2021 14:03:21 -0600 Subject: [PATCH 5/9] Make sure to include dpctl4pybind11.hpp in the manifest --- MANIFEST.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 5ce66287a8..604da428cc 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,6 @@ include versioneer.py recursive-include dpctl/include *.h -recursive-include dpctl/tensor/include * +include dpctl/include/dpctl4pybind11.hpp recursive-include dpctl *.pxd include dpctl/_sycl_context.h include dpctl/_sycl_context_api.h @@ -14,5 +14,6 @@ include dpctl/memory/_memory.h include dpctl/memory/_memory_api.h include dpctl/tensor/_usmarray.h include dpctl/tensor/_usmarray_api.h +recursive-include dpctl/tensor/include * include dpctl/tests/input_files/* include dpctl/tests/*.pyx From 5f040b5554929e4ea15882a604bd972fe30e4f29 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 23 Nov 2021 14:52:48 -0600 Subject: [PATCH 6/9] Added tests to make_Sycl* C-API functions --- dpctl/tests/test_sycl_context.py | 24 ++++++++++++++++- dpctl/tests/test_sycl_device.py | 45 ++++++++++++++++++++++++++++++++ dpctl/tests/test_sycl_event.py | 24 ++++++++++++++++- dpctl/tests/test_sycl_queue.py | 24 +++++++++++++++-- 4 files changed, 113 insertions(+), 4 deletions(-) diff --git a/dpctl/tests/test_sycl_context.py b/dpctl/tests/test_sycl_context.py index 99d72c14eb..1b67d1f4f3 100644 --- a/dpctl/tests/test_sycl_context.py +++ b/dpctl/tests/test_sycl_context.py @@ -190,7 +190,7 @@ def test_context_repr(): assert type(ctx.__repr__()) is str -def test_cpython_api(): +def test_cpython_api_get_context_ref(): import ctypes import sys @@ -213,6 +213,28 @@ def test_cpython_api(): assert r1 == r2 +def test_cpython_api_make_SyclContext(): + import ctypes + import sys + + ctx = dpctl.SyclContext() + mod = sys.modules[ctx.__class__.__module__] + # get capsule storign make_SyclContext function ptr + make_ctx_fn_cap = mod.__pyx_capi__["make_SyclContext"] + # construct Python callable to invoke "make_SyclContext" + cap_ptr_fn = ctypes.pythonapi.PyCapsule_GetPointer + cap_ptr_fn.restype = ctypes.c_void_p + cap_ptr_fn.argtypes = [ctypes.py_object, ctypes.c_char_p] + make_ctx_fn_ptr = cap_ptr_fn( + make_ctx_fn_cap, b"struct PySyclContextObject *(DPCTLSyclContextRef)" + ) + callable_maker = ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p) + make_ctx_fn = callable_maker(make_ctx_fn_ptr) + + ctx2 = make_ctx_fn(ctx.addressof_ref()) + assert ctx == ctx2 + + def test_invalid_capsule(): cap = create_invalid_capsule() with pytest.raises(ValueError): diff --git a/dpctl/tests/test_sycl_device.py b/dpctl/tests/test_sycl_device.py index 5b3f30c89d..329444ac90 100644 --- a/dpctl/tests/test_sycl_device.py +++ b/dpctl/tests/test_sycl_device.py @@ -729,3 +729,48 @@ def test_handle_no_device(): dpctl.select_device_with_aspects(["gpu", "cpu"]) with pytest.raises(ValueError): dpctl.select_device_with_aspects("cpu", excluded_aspects="cpu") + + +def test_cpython_api_get_device_ref(): + import ctypes + import sys + + d = dpctl.SyclDevice() + mod = sys.modules[d.__class__.__module__] + # get capsule storign get_device_ref function ptr + d_ref_fn_cap = mod.__pyx_capi__["get_device_ref"] + # construct Python callable to invoke "get_device_ref" + cap_ptr_fn = ctypes.pythonapi.PyCapsule_GetPointer + cap_ptr_fn.restype = ctypes.c_void_p + cap_ptr_fn.argtypes = [ctypes.py_object, ctypes.c_char_p] + d_ref_fn_ptr = cap_ptr_fn( + d_ref_fn_cap, b"DPCTLSyclDeviceRef (struct PySyclDeviceObject *)" + ) + callable_maker = ctypes.PYFUNCTYPE(ctypes.c_void_p, ctypes.py_object) + get_device_ref_fn = callable_maker(d_ref_fn_ptr) + + r2 = d.addressof_ref() + r1 = get_device_ref_fn(d) + assert r1 == r2 + + +def test_cpython_api_make_SyclDevice(): + import ctypes + import sys + + d = dpctl.SyclDevice() + mod = sys.modules[d.__class__.__module__] + # get capsule storign make_SyclContext function ptr + make_d_fn_cap = mod.__pyx_capi__["make_SyclDevice"] + # construct Python callable to invoke "make_SyclDevice" + cap_ptr_fn = ctypes.pythonapi.PyCapsule_GetPointer + cap_ptr_fn.restype = ctypes.c_void_p + cap_ptr_fn.argtypes = [ctypes.py_object, ctypes.c_char_p] + make_d_fn_ptr = cap_ptr_fn( + make_d_fn_cap, b"struct PySyclDeviceObject *(DPCTLSyclDeviceRef)" + ) + callable_maker = ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p) + make_d_fn = callable_maker(make_d_fn_ptr) + + d2 = make_d_fn(d.addressof_ref()) + assert d == d2 diff --git a/dpctl/tests/test_sycl_event.py b/dpctl/tests/test_sycl_event.py index 24c4aa4b75..12c48e48c7 100644 --- a/dpctl/tests/test_sycl_event.py +++ b/dpctl/tests/test_sycl_event.py @@ -234,7 +234,7 @@ def test_addressof_ref(): assert type(ref) is int -def test_cpython_api(): +def test_cpython_api_get_event_ref(): import ctypes import sys @@ -255,3 +255,25 @@ def test_cpython_api(): r2 = ev.addressof_ref() r1 = get_event_ref_fn(ev) assert r1 == r2 + + +def test_cpython_api_make_SyclEvent(): + import ctypes + import sys + + ev = dpctl.SyclEvent() + mod = sys.modules[ev.__class__.__module__] + # get capsule storing make_SyclEvent function ptr + make_e_fn_cap = mod.__pyx_capi__["make_SyclEvent"] + # construct Python callable to invoke "make_SyclDevice" + cap_ptr_fn = ctypes.pythonapi.PyCapsule_GetPointer + cap_ptr_fn.restype = ctypes.c_void_p + cap_ptr_fn.argtypes = [ctypes.py_object, ctypes.c_char_p] + make_e_fn_ptr = cap_ptr_fn( + make_e_fn_cap, b"struct PySyclEventObject *(DPCTLSyclEventRef)" + ) + callable_maker = ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p) + make_e_fn = callable_maker(make_e_fn_ptr) + + ev2 = make_e_fn(ev.addressof_ref()) + assert type(ev) == type(ev2) diff --git a/dpctl/tests/test_sycl_queue.py b/dpctl/tests/test_sycl_queue.py index 0f36c319b2..6ad2571968 100644 --- a/dpctl/tests/test_sycl_queue.py +++ b/dpctl/tests/test_sycl_queue.py @@ -469,10 +469,10 @@ def test_queue_capsule(): assert q2 != [] # compare with other types -def test_cpython_api(): +def test_cpython_api_get_queue_ref(): q = dpctl.SyclQueue() mod = sys.modules[q.__class__.__module__] - # get capsule storign get_context_ref function ptr + # get capsule storign get_queue_ref function ptr q_ref_fn_cap = mod.__pyx_capi__["get_queue_ref"] # construct Python callable to invoke "get_queue_ref" cap_ptr_fn = ctypes.pythonapi.PyCapsule_GetPointer @@ -489,6 +489,26 @@ def test_cpython_api(): assert r1 == r2 +def test_cpython_api_make_SyclQueue(): + q = dpctl.SyclQueue() + mod = sys.modules[q.__class__.__module__] + # get capsule storing make_SyclQueue function ptr + make_SyclQueue_fn_cap = mod.__pyx_capi__["make_SyclQueue"] + # construct Python callable to invoke "make_SyclQueue" + cap_ptr_fn = ctypes.pythonapi.PyCapsule_GetPointer + cap_ptr_fn.restype = ctypes.c_void_p + cap_ptr_fn.argtypes = [ctypes.py_object, ctypes.c_char_p] + make_SyclQueue_fn_ptr = cap_ptr_fn( + make_SyclQueue_fn_cap, b"struct PySyclQueueObject *(DPCTLSyclQueueRef)" + ) + callable_maker = ctypes.PYFUNCTYPE(ctypes.py_object, ctypes.c_void_p) + make_SyclQueue_fn = callable_maker(make_SyclQueue_fn_ptr) + + q2 = make_SyclQueue_fn(q.addressof_ref()) + assert q.sycl_device == q2.sycl_device + assert q.sycl_context == q2.sycl_context + + def test_constructor_many_arg(): with pytest.raises(TypeError): dpctl.SyclQueue(None, None, None, None) From 0e38e21047920bd401e5d51efa922a3c68093065 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 23 Nov 2021 14:59:47 -0600 Subject: [PATCH 7/9] Added documenting C++ comment Fixed runtime_error verbiage. --- dpctl/apis/include/dpctl4pybind11.hpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dpctl/apis/include/dpctl4pybind11.hpp b/dpctl/apis/include/dpctl4pybind11.hpp index 2d9775365d..b959c66c59 100644 --- a/dpctl/apis/include/dpctl4pybind11.hpp +++ b/dpctl/apis/include/dpctl4pybind11.hpp @@ -35,6 +35,11 @@ namespace pybind11 { namespace detail { + +/* This type caster associates ``sycl::queue`` C++ class with + * :class:`dpctl.SyclQueue` for the purposes of generation of + * Python bindings by pybind11. + */ template <> struct type_caster { public: @@ -52,7 +57,7 @@ template <> struct type_caster } else { throw std::runtime_error( - "Input is of unexpected type, expected egapi.Example"); + "Input is of unexpected type, expected dpctl.SyclQueue"); } } @@ -69,6 +74,10 @@ namespace pybind11 { namespace detail { +/* This type caster associates ``sycl::device`` C++ class with + * :class:`dpctl.SyclDevice` for the purposes of generation of + * Python bindings by pybind11. + */ template <> struct type_caster { public: @@ -86,7 +95,7 @@ template <> struct type_caster } else { throw std::runtime_error( - "Input is of unexpected type, expected egapi.Example"); + "Input is of unexpected type, expected dpctl.SyclDevice"); } } From e88014310b111a4d679c08cdbf53189f47a8a061 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 23 Nov 2021 15:06:22 -0600 Subject: [PATCH 8/9] Per PR feedback: dpctl/include/syclinterface.h -> dpctl/include/dpctl_sycl_interface.h --- dpctl/apis/include/{syclinterface.h => dpctl_sycl_interface.h} | 1 - examples/cython/sycl_buffer/use_sycl_buffer.cpp | 2 +- examples/cython/sycl_buffer/use_sycl_buffer.h | 2 +- examples/cython/usm_memory/sycl_blackscholes.cpp | 2 +- examples/cython/usm_memory/sycl_blackscholes.hpp | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) rename dpctl/apis/include/{syclinterface.h => dpctl_sycl_interface.h} (99%) diff --git a/dpctl/apis/include/syclinterface.h b/dpctl/apis/include/dpctl_sycl_interface.h similarity index 99% rename from dpctl/apis/include/syclinterface.h rename to dpctl/apis/include/dpctl_sycl_interface.h index 04ab1cfbbb..4f4f4c2b19 100644 --- a/dpctl/apis/include/syclinterface.h +++ b/dpctl/apis/include/dpctl_sycl_interface.h @@ -37,7 +37,6 @@ #include "syclinterface/dpctl_sycl_platform_interface.h" #include "syclinterface/dpctl_sycl_queue_interface.h" #include "syclinterface/dpctl_sycl_usm_interface.h" - #include "syclinterface/dpctl_sycl_device_manager.h" #include "syclinterface/dpctl_sycl_platform_manager.h" #include "syclinterface/dpctl_sycl_queue_manager.h" diff --git a/examples/cython/sycl_buffer/use_sycl_buffer.cpp b/examples/cython/sycl_buffer/use_sycl_buffer.cpp index afbc814aa9..ba85510d09 100644 --- a/examples/cython/sycl_buffer/use_sycl_buffer.cpp +++ b/examples/cython/sycl_buffer/use_sycl_buffer.cpp @@ -28,7 +28,7 @@ //===----------------------------------------------------------------------===// #include "use_sycl_buffer.h" -#include "syclinterface.h" +#include "dpctl_sycl_interface.h" #include #include diff --git a/examples/cython/sycl_buffer/use_sycl_buffer.h b/examples/cython/sycl_buffer/use_sycl_buffer.h index 9697f81fd2..d9ea64c993 100644 --- a/examples/cython/sycl_buffer/use_sycl_buffer.h +++ b/examples/cython/sycl_buffer/use_sycl_buffer.h @@ -1,4 +1,4 @@ -#include "syclinterface.h" +#include "dpctl_sycl_interface.h" #include extern int c_columnwise_total(DPCTLSyclQueueRef q, diff --git a/examples/cython/usm_memory/sycl_blackscholes.cpp b/examples/cython/usm_memory/sycl_blackscholes.cpp index 87c1c517ce..8d6d0d6f85 100644 --- a/examples/cython/usm_memory/sycl_blackscholes.cpp +++ b/examples/cython/usm_memory/sycl_blackscholes.cpp @@ -27,7 +27,7 @@ //===----------------------------------------------------------------------===// #include "sycl_blackscholes.hpp" -#include "syclinterface.h" +#include "dpctl_sycl_interface.h" #include #include #include diff --git a/examples/cython/usm_memory/sycl_blackscholes.hpp b/examples/cython/usm_memory/sycl_blackscholes.hpp index e61b9b47f6..1c38ebef4b 100644 --- a/examples/cython/usm_memory/sycl_blackscholes.hpp +++ b/examples/cython/usm_memory/sycl_blackscholes.hpp @@ -24,7 +24,7 @@ /// //===----------------------------------------------------------------------===// -#include "syclinterface.h" +#include "dpctl_sycl_interface.h" #include template From d42e403c0771388776c2b65c6681d9209179da5e Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Tue, 23 Nov 2021 15:18:37 -0600 Subject: [PATCH 9/9] Added type caster for event and context --- dpctl/apis/include/dpctl4pybind11.hpp | 77 +++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/dpctl/apis/include/dpctl4pybind11.hpp b/dpctl/apis/include/dpctl4pybind11.hpp index b959c66c59..4182a2d9bb 100644 --- a/dpctl/apis/include/dpctl4pybind11.hpp +++ b/dpctl/apis/include/dpctl4pybind11.hpp @@ -107,3 +107,80 @@ template <> struct type_caster }; } // namespace detail } // namespace pybind11 + +namespace pybind11 +{ +namespace detail +{ +/* This type caster associates ``sycl::context`` C++ class with + * :class:`dpctl.SyclContext` for the purposes of generation of + * Python bindings by pybind11. + */ +template <> struct type_caster +{ +public: + PYBIND11_TYPE_CASTER(sycl::context, _("dpctl.SyclContext")); + + bool load(handle src, bool) + { + PyObject *source = src.ptr(); + if (PyObject_TypeCheck(source, &PySyclContextType)) { + DPCTLSyclContextRef CRef = get_context_ref( + reinterpret_cast(source)); + sycl::context *ctx = reinterpret_cast(CRef); + value = *ctx; + return true; + } + else { + throw std::runtime_error( + "Input is of unexpected type, expected dpctl.SyclContext"); + } + } + + static handle cast(sycl::context src, return_value_policy, handle) + { + auto tmp = + make_SyclContext(reinterpret_cast(&src)); + return handle(reinterpret_cast(tmp)); + } +}; +} // namespace detail +} // namespace pybind11 + +namespace pybind11 +{ +namespace detail +{ +/* This type caster associates ``sycl::event`` C++ class with + * :class:`dpctl.SyclEvent` for the purposes of generation of + * Python bindings by pybind11. + */ +template <> struct type_caster +{ +public: + PYBIND11_TYPE_CASTER(sycl::event, _("dpctl.SyclEvent")); + + bool load(handle src, bool) + { + PyObject *source = src.ptr(); + if (PyObject_TypeCheck(source, &PySyclEventType)) { + DPCTLSyclEventRef ERef = + get_event_ref(reinterpret_cast(source)); + sycl::event *ev = reinterpret_cast(ERef); + value = *ev; + return true; + } + else { + throw std::runtime_error( + "Input is of unexpected type, expected dpctl.SyclEvent"); + } + } + + static handle cast(sycl::event src, return_value_policy, handle) + { + auto tmp = make_SyclEvent(reinterpret_cast(&src)); + return handle(reinterpret_cast(tmp)); + } +}; +} // namespace detail +} // namespace pybind11