diff --git a/backends/CMakeLists.txt b/backends/CMakeLists.txt index 3a9a0434d4..b812978ed0 100644 --- a/backends/CMakeLists.txt +++ b/backends/CMakeLists.txt @@ -96,7 +96,12 @@ message(STATUS "OpenCL_LIBRARY: ${OpenCL_LIBRARY}") add_library( DPPLSyclInterface SHARED + source/dppl_sycl_context_interface.cpp + source/dppl_sycl_device_interface.cpp + source/dppl_sycl_platform_interface.cpp source/dppl_sycl_queue_interface.cpp + source/dppl_sycl_queue_manager.cpp + source/dppl_utils.cpp ) # Install DPPLOpenCLInterface diff --git a/backends/include/dppl_sycl_context_interface.h b/backends/include/dppl_sycl_context_interface.h new file mode 100644 index 0000000000..1f3506930e --- /dev/null +++ b/backends/include/dppl_sycl_context_interface.h @@ -0,0 +1,54 @@ +//===--- dppl_sycl_context_interface.h - DPPL-SYCL interface --*--C++ --*--===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 header declares a C API to SYCL's sycl::context interface. +/// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "dppl_data_types.h" +#include "dppl_sycl_types.h" +#include "Support/DllExport.h" +#include "Support/ExternC.h" +#include "Support/MemOwnershipAttrs.h" +#include + +DPPL_C_EXTERN_C_BEGIN + +/*! + * @brief Returns true if this SYCL context is a host context. + * + * @param CtxtRef A opaque pointer to a sycl::context. + * @return True if the SYCL context is a host context, else False. + */ +DPPL_API +bool DPPLIsHostContext (__dppl_keep const DPPLSyclContextRef CtxtRef); + +/*! + * @brief Delete the pointer after casting it to sycl::context + * + * @param CtxtRef The DPPLSyclContextRef pointer to be deleted. + */ +DPPL_API +void DPPLDeleteSyclContext (__dppl_take DPPLSyclContextRef CtxtRef); + +DPPL_C_EXTERN_C_END diff --git a/backends/include/dppl_sycl_device_interface.h b/backends/include/dppl_sycl_device_interface.h new file mode 100644 index 0000000000..adbc216662 --- /dev/null +++ b/backends/include/dppl_sycl_device_interface.h @@ -0,0 +1,151 @@ +//===--- dppl_sycl_device_interface.h - DPPL-SYCL interface ---*---C++ -*---===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 header declares a C interface to sycl::device. Not all of the device +/// API is exposed, only the bits needed in other places like context and queue +/// interfaces. +/// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "dppl_data_types.h" +#include "dppl_sycl_types.h" +#include "Support/DllExport.h" +#include "Support/ExternC.h" +#include "Support/MemOwnershipAttrs.h" + +DPPL_C_EXTERN_C_BEGIN + +/*! + * @brief Redefinition of Sycl's device_type so that we do not have to include + * sycl.hpp here and in the Python bindings. + * + */ +typedef enum +{ + DPPL_CPU, + DPPL_GPU, + DPPL_ACCELERATOR, + DPPL_CUSTOM, + DPPL_AUTOMATIC, + DPPL_HOST, + DPPL_ALL +} DPPLSyclDeviceType; + +/*! + * @brief Prints out some of the info::deivice attributes for the device. + * + * @param DRef A DPPLSyclDeviceRef pointer. + */ +DPPL_API +void DPPLDumpDeviceInfo (__dppl_keep const DPPLSyclDeviceRef DRef); + +/*! + * @brief Deletes a DPPLSyclDeviceRef pointer after casting to to sycl::device. + * + * @param DRef The DPPLSyclDeviceRef pointer to be freed. + */ +DPPL_API +void DPPLDeleteSyclDevice (__dppl_take DPPLSyclDeviceRef DRef); + +/*! + * @brief Returns true if this SYCL device is an OpenCL device and the device + * type is sycl::info::device_type::accelerator. + * + * @param DRef Opaque pointer to a sycl::device + * @return True if the device type is an accelerator, else False. + */ +DPPL_API +bool DPPLDeviceIsAccelerator (__dppl_keep const DPPLSyclDeviceRef DRef); + +/*! + * @brief Returns true if this SYCL device is an OpenCL device and the device + * type is sycl::info::device_type::cpu. + * + * @param DRef Opaque pointer to a sycl::device + * @return True if the device type is a cpu, else False. + */ +DPPL_API +bool DPPLDeviceIsCPU (__dppl_keep const DPPLSyclDeviceRef DRef); + +/*! + * @brief Returns true if this SYCL device is an OpenCL device and the device + * type is sycl::info::device_type::gpu. + * + * @param DRef Opaque pointer to a sycl::device + * @return True if the device type is a gpu, else False. + */ +DPPL_API +bool DPPLDeviceIsGPU (__dppl_keep const DPPLSyclDeviceRef DRef); + +/*! + * @brief Returns true if this SYCL device is a host device. + * + * @param DRef Opaque pointer to a sycl::device + * @return True if the device is a host device, else False. + */ +DPPL_API +bool DPPLDeviceIsHost (__dppl_keep const DPPLSyclDeviceRef DRef); + +/*! + * @brief Returns the OpenCL software driver version as a C string. + * + * @param DRef Opaque pointer to a sycl::device + * @return A C string in the form major_number.minor.number that corresponds + * to the OpenCL driver version if this is a OpenCL device. + */ +DPPL_API +__dppl_give const char* +DPPLGetDeviceDriverInfo (__dppl_keep const DPPLSyclDeviceRef DRef); + +/*! + * @brief Returns a C string for the device name. + * + * @param DRef Opaque pointer to a sycl::device + * @return A C string containing the OpenCL device name. + */ +DPPL_API +__dppl_give const char* +DPPLGetDeviceName (__dppl_keep const DPPLSyclDeviceRef DRef); + +/*! + * @brief Returns a C string corresponding to the vendor name. + * + * @param DRef Opaque pointer to a sycl::device + * @return A C string containing the OpenCL device vendor name. + */ +DPPL_API +__dppl_give const char* +DPPLGetDeviceVendorName (__dppl_keep const DPPLSyclDeviceRef DRef); + +/*! + * @brief Returns True if the device and the host share a unified memory + * subsystem, else returns False. + * + * @param DRef Opaque pointer to a sycl::device + * @return Boolean indicating if the device shares a unified memory subsystem + * with the host. + */ +DPPL_API +bool DPPLGetDeviceHostUnifiedMemory (__dppl_keep const DPPLSyclDeviceRef DRef); + +DPPL_C_EXTERN_C_END diff --git a/backends/include/dppl_sycl_platform_interface.h b/backends/include/dppl_sycl_platform_interface.h new file mode 100644 index 0000000000..459a39a1da --- /dev/null +++ b/backends/include/dppl_sycl_platform_interface.h @@ -0,0 +1,49 @@ +//===--- dppl_sycl_platform_interface.h - DPPL-SYCL interface ---*--C++ -*-===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 header declares a C interface to sycl::platform interface functions. +/// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "dppl_data_types.h" +#include "Support/DllExport.h" +#include "Support/ExternC.h" + +DPPL_C_EXTERN_C_BEGIN + +/*! + * @brief Get the number of sycl::platform available on the system. + * + * @return The number of available sycl::platforms. + */ +DPPL_API +size_t DPPLPlatform_GetNumPlatforms (); + +/*! + * @brief Prints out some selected info about all sycl::platform on the system. + * + */ +DPPL_API +void DPPLPlatform_DumpInfo (); + +DPPL_C_EXTERN_C_END diff --git a/backends/include/dppl_sycl_queue_interface.h b/backends/include/dppl_sycl_queue_interface.h index d85803b735..60d080e3f0 100644 --- a/backends/include/dppl_sycl_queue_interface.h +++ b/backends/include/dppl_sycl_queue_interface.h @@ -19,15 +19,9 @@ //===----------------------------------------------------------------------===// /// /// \file -/// This header declares a C interface to DPPL's sycl::queue manager class that -/// maintains a thread local stack of sycl::queues objects for use inside -/// Python programs. The C interface is designed in a way to not have to -/// include the Sycl headers inside a Python extension module, since that would -/// require the extension to be compiled using dpc++ or another Sycl compiler. -/// Compiling the extension with a compiler different from what was used to -/// compile the Python interpreter can cause run-time problems especially on MS -/// Windows. Additionally, the C interface makes it easier to interoperate with -/// Numba without having to deal with C++ name mangling. +/// This header declares a C interface to sycl::queue member functions. Note +/// that sycl::queue constructors are not exposed in this interface. Instead, +/// users should use the functions in dppl_sycl_queue_manager.h. /// //===----------------------------------------------------------------------===// @@ -42,151 +36,31 @@ DPPL_C_EXTERN_C_BEGIN /*! - * @brief Redefinition of Sycl's device_type so that we do not have to include - * sycl.hpp here and in the Python bindings. + * @brief Returns the Sycl context for the queue. * - */ -typedef enum -{ - DPPL_CPU, - DPPL_GPU, - DPPL_ACCELERATOR, - DPPL_CUSTOM, - DPPL_AUTOMATIC, - DPPL_HOST, - DPPL_ALL -} DPPLSyclDeviceType; - - -/*! - * @brief Get the number of sycl::platform available on the system. - * - * @return The number of available sycl::platforms. - */ -DPPL_API -size_t DPPLGetNumPlatforms (); - -/*! - * @brief Get the sycl::queue object that is currently activated for this - * thread. - * - * @return A copy of the current (top of the stack) sycl::queue is returned - * wrapped inside an opaque DPPLSyclQueueRef pointer. - */ -DPPL_API -__dppl_give DPPLSyclQueueRef DPPLGetCurrentQueue (); - -/*! - * @brief Get a sycl::queue object of the specified type and device id. - * - * @param DeviceTy The type of Sycl device (sycl_device_type) - * @param DNum Device id for the device (defaults to 0) - * - * @return A copy of the sycl::queue corresponding to the device is returned - * wrapped inside a DPPLSyclDeviceType pointer. A runtime_error exception is - * raised if no such device exists. - */ -DPPL_API -__dppl_give DPPLSyclQueueRef DPPLGetQueue (DPPLSyclDeviceType DeviceTy, - size_t DNum); - -/*! - * @brief Get the number of activated queues not including the global or - * default queue. - * - * @return The number of activated queues. - */ -DPPL_API -size_t DPPLGetNumActivatedQueues (); - -/*! - * @brief Get the number of GPU queues available on the system. - * - * @return The number of available GPU queues. - */ -DPPL_API -size_t DPPLGetNumGPUQueues (); - -/*! - * @brief Get the number of CPU queues available on the system. - * - * @return The number of available CPU queues. - */ -DPPL_API -size_t DPPLGetNumCPUQueues (); - -/*! -* @brief Set the default DPPL queue to the sycl::queue for the given device. -* -* If no such device is found the a runtime_error exception is thrown. -* -* @param DeviceTy The type of Sycl device (sycl_device_type) -* @param DNum Device id for the device (defaults to 0) -*/ -DPPL_API -void DPPLSetAsDefaultQueue (DPPLSyclDeviceType DeviceTy, - size_t DNum); - -/*! - * @brief Pushes a new sycl::queue object to the top of DPPL's thread-local - * stack of a "activated" queues, and returns a copy of the queue to caller. - * - * DPPL maintains a thread-local stack of sycl::queue objects to facilitate - * nested parallelism. The sycl::queue at the top of the stack is termed as the - * currently activated queue, and is always the one returned by - * DPPLGetCurrentQueue(). DPPLPushSyclQueueToStack creates a new sycl::queue - * corresponding to the specified device and pushes it to the top of the stack. - * A copy of the sycl::queue is returned to the caller wrapped inside the - * opaque DPPLSyclQueueRef pointer. A runtime_error exception is thrown when - * a new sycl::queue could not be created for the specified device. - * - * @param DeviceTy The type of Sycl device (sycl_device_type) - * @param DNum Device id for the device (defaults to 0) - * - * @return A copy of the sycl::queue that was pushed to the top of DPPL's - * stack of sycl::queue objects. - */ -DPPL_API -__dppl_give DPPLSyclQueueRef DPPLPushSyclQueue (DPPLSyclDeviceType DeviceTy, - size_t DNum); - -/*! - * @brief Pops the top of stack element from DPPL's stack of activated - * sycl::queue objects. - * - * DPPLPopSyclQueue only removes the reference from the DPPL stack of - * sycl::queue objects. Any instance of the popped queue that were previously - * acquired by calling DPPLPushSyclQueue() or DPPLGetCurrentQueue() needs to be - * freed separately. In addition, a runtime_error is thrown when the stack - * contains only one sycl::queue, i.e., the default queue. - * - */ -DPPL_API -void DPPLPopSyclQueue (); - -/*! - * @brief Prints out information about the Sycl environment, such as - * number of available platforms, number of activated queues, etc. + * @param QRef An opaque pointer to the sycl queue. + * @return A DPPLSyclContextRef pointer to the sycl context for the queue. */ DPPL_API -void DPPLDumpPlatformInfo (); +__dppl_give DPPLSyclContextRef +DPPLGetContextFromQueue (__dppl_keep const DPPLSyclQueueRef QRef); /*! - * @brief Prints out information about the device corresponding to the - * sycl::queue argument. + * @brief returns the Sycl device for the queue. * - * @param QRef A DPPLSyclQueueRef pointer whose metadata will be - * printed out. + * @param QRef An opaque pointer to the sycl queue. + * @return A DPPLSyclDeviceRef pointer to the sycl device for the queue. */ DPPL_API -void DPPLDumpDeviceInfo (__dppl_keep const DPPLSyclQueueRef QRef); +__dppl_give DPPLSyclDeviceRef +DPPLGetDeviceFromQueue (__dppl_keep const DPPLSyclQueueRef QRef); /*! - * @brief Delete the pointer after static casting it to sycl::queue. + * @brief Delete the pointer after casting it to sycl::queue. * * @param QRef A DPPLSyclQueueRef pointer that gets deleted. */ DPPL_API -void DPPLDeleteQueue (__dppl_take DPPLSyclQueueRef QRef); +void DPPLDeleteSyclQueue (__dppl_take DPPLSyclQueueRef QRef); DPPL_C_EXTERN_C_END diff --git a/backends/include/dppl_sycl_queue_manager.h b/backends/include/dppl_sycl_queue_manager.h new file mode 100644 index 0000000000..8d550be6b9 --- /dev/null +++ b/backends/include/dppl_sycl_queue_manager.h @@ -0,0 +1,143 @@ +//===--- dppl_sycl_queue_manager.h - DPPL-SYCL interface ---*---C++ ---*---===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 header declares a C interface to DPPL's sycl::queue manager to +/// maintain a thread local stack of sycl::queues objects for use inside +/// Python programs. The C interface is designed in a way to not have to +/// include the Sycl headers inside a Python extension module, since that would +/// require the extension to be compiled using dpc++ or another Sycl compiler. +/// Compiling the extension with a compiler different from what was used to +/// compile the Python interpreter can cause run-time problems especially on MS +/// Windows. Additionally, the C interface makes it easier to interoperate with +/// Numba without having to deal with C++ name mangling. +/// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "dppl_data_types.h" +#include "dppl_sycl_types.h" +#include "dppl_sycl_device_interface.h" +#include "Support/DllExport.h" +#include "Support/ExternC.h" +#include "Support/MemOwnershipAttrs.h" + +DPPL_C_EXTERN_C_BEGIN + +/*! + * @brief Get the sycl::queue object that is currently activated for this + * thread. + * + * @return A copy of the current (top of the stack) sycl::queue is returned + * wrapped inside an opaque DPPLSyclQueueRef pointer. + */ +DPPL_API +__dppl_give DPPLSyclQueueRef DPPLGetCurrentQueue (); + +/*! + * @brief Get a sycl::queue object of the specified type and device id. + * + * @param DeviceTy The type of Sycl device (sycl_device_type) + * @param DNum Device id for the device (defaults to 0) + * + * @return A copy of the sycl::queue corresponding to the device is returned + * wrapped inside a DPPLSyclDeviceType pointer. A runtime_error exception is + * raised if no such device exists. + */ +DPPL_API +__dppl_give DPPLSyclQueueRef DPPLGetQueue (DPPLSyclDeviceType DeviceTy, + size_t DNum); + +/*! + * @brief Get the number of activated queues not including the global or + * default queue. + * + * @return The number of activated queues. + */ +DPPL_API +size_t DPPLGetNumActivatedQueues (); + +/*! + * @brief Get the number of GPU queues available on the system. + * + * @return The number of available GPU queues. + */ +DPPL_API +size_t DPPLGetNumGPUQueues (); + +/*! + * @brief Get the number of CPU queues available on the system. + * + * @return The number of available CPU queues. + */ +DPPL_API +size_t DPPLGetNumCPUQueues (); + +/*! +* @brief Set the default DPPL queue to the sycl::queue for the given device. +* +* If no such device is found the a runtime_error exception is thrown. +* +* @param DeviceTy The type of Sycl device (sycl_device_type) +* @param DNum Device id for the device (defaults to 0) +*/ +DPPL_API +void DPPLSetAsDefaultQueue (DPPLSyclDeviceType DeviceTy, + size_t DNum); + +/*! + * @brief Pushes a new sycl::queue object to the top of DPPL's thread-local + * stack of a "activated" queues, and returns a copy of the queue to caller. + * + * DPPL maintains a thread-local stack of sycl::queue objects to facilitate + * nested parallelism. The sycl::queue at the top of the stack is termed as the + * currently activated queue, and is always the one returned by + * DPPLGetCurrentQueue(). DPPLPushSyclQueueToStack creates a new sycl::queue + * corresponding to the specified device and pushes it to the top of the stack. + * A copy of the sycl::queue is returned to the caller wrapped inside the + * opaque DPPLSyclQueueRef pointer. A runtime_error exception is thrown when + * a new sycl::queue could not be created for the specified device. + * + * @param DeviceTy The type of Sycl device (sycl_device_type) + * @param DNum Device id for the device (defaults to 0) + * + * @return A copy of the sycl::queue that was pushed to the top of DPPL's + * stack of sycl::queue objects. + */ +DPPL_API +__dppl_give DPPLSyclQueueRef DPPLPushSyclQueue (DPPLSyclDeviceType DeviceTy, + size_t DNum); + +/*! + * @brief Pops the top of stack element from DPPL's stack of activated + * sycl::queue objects. + * + * DPPLPopSyclQueue only removes the reference from the DPPL stack of + * sycl::queue objects. Any instance of the popped queue that were previously + * acquired by calling DPPLPushSyclQueue() or DPPLGetCurrentQueue() needs to be + * freed separately. In addition, a runtime_error is thrown when the stack + * contains only one sycl::queue, i.e., the default queue. + * + */ +DPPL_API +void DPPLPopSyclQueue (); + +DPPL_C_EXTERN_C_END diff --git a/backends/include/dppl_sycl_types.h b/backends/include/dppl_sycl_types.h index ea3d6b479b..d1777aae5d 100644 --- a/backends/include/dppl_sycl_types.h +++ b/backends/include/dppl_sycl_types.h @@ -23,10 +23,35 @@ /// //===----------------------------------------------------------------------===// +#pragma once + +/*! + * @brief + * + */ +typedef struct DPPLOpaqueSyclContext *DPPLSyclContextRef; + +/*! + * @brief + * + */ +typedef struct DPPLOpaqueSyclDevice *DPPLSyclDeviceRef; + +/*! + * @brief + * + */ +typedef struct DPPLOpaqueSyclPlatform *DPPLSyclPlatformRef; /*! - * Used to pass a sycl::queue opaquely through DPPL interfaces. + * @brief Used to pass a sycl::queue opaquely through DPPL interfaces. * * @see sycl::queue */ typedef struct DPPLOpaqueSyclQueue *DPPLSyclQueueRef; + +/*! + * @brief Used to pass a sycl::program opaquely through DPPL interfaces. + * + */ +typedef struct DPPLOpaqueSyclProgram *DPPLSyclProgramRef; diff --git a/backends/include/dppl_utils.h b/backends/include/dppl_utils.h new file mode 100644 index 0000000000..89071f19f9 --- /dev/null +++ b/backends/include/dppl_utils.h @@ -0,0 +1,41 @@ +//===------------- dppl_utils.h - DPPL-SYCL interface --*-- C++ -----*-----===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 common helper functions used in other places in DPPL. +//===----------------------------------------------------------------------===// + +#pragma once + +#include "Support/DllExport.h" +#include "Support/ExternC.h" +#include "Support/MemOwnershipAttrs.h" + +DPPL_C_EXTERN_C_BEGIN + +/*! + * @brief Deletes the C String argument + * + * @param str C string to be deleted + */ +DPPL_API +void DPPLDeleteCString (__dppl_take const char* str); + +DPPL_C_EXTERN_C_END diff --git a/backends/include/error_check_macros.h b/backends/include/error_check_macros.h index 201a0f071a..77bd462e5a 100644 --- a/backends/include/error_check_macros.h +++ b/backends/include/error_check_macros.h @@ -23,6 +23,7 @@ /// codes. /// //===----------------------------------------------------------------------===// + #pragma once #include diff --git a/backends/source/dppl_sycl_context_interface.cpp b/backends/source/dppl_sycl_context_interface.cpp new file mode 100644 index 0000000000..d27b150f74 --- /dev/null +++ b/backends/source/dppl_sycl_context_interface.cpp @@ -0,0 +1,58 @@ +//===--- dppl_sycl_context_interface.cpp - DPPL-SYCL interface --*- C++ -*-===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 the data types and functions declared in +/// dppl_sycl_context_interface.h. +/// +//===----------------------------------------------------------------------===// + +#include "dppl_sycl_context_interface.h" +#include "Support/CBindingWrapping.h" +#include + +using namespace cl::sycl; + +namespace +{ + // Create wrappers for C Binding types (see CBindingWrapping.h). + DEFINE_SIMPLE_CONVERSION_FUNCTIONS(context, DPPLSyclContextRef) +} /* end of anonymous namespace */ + +/*! + * @brief + * + * @param CtxtRef My Param doc + * @return {return} My Param doc + */ +bool DPPLIsHostContext (__dppl_keep const DPPLSyclContextRef CtxtRef) +{ + return unwrap(CtxtRef)->is_host(); +} + +/*! + * @brief + * + * @param CtxtRef My Param doc + */ +void DPPLDeleteSyclContext (__dppl_take DPPLSyclContextRef CtxtRef) +{ + delete unwrap(CtxtRef); +} diff --git a/backends/source/dppl_sycl_device_interface.cpp b/backends/source/dppl_sycl_device_interface.cpp new file mode 100644 index 0000000000..f70f34be1e --- /dev/null +++ b/backends/source/dppl_sycl_device_interface.cpp @@ -0,0 +1,132 @@ +//===--- dppl_sycl_device_interface.cpp - DPPL-SYCL interface --*- C++ -*--===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 the data types and functions declared in +/// dppl_sycl_device_interface.h. +/// +//===----------------------------------------------------------------------===// + +#include "dppl_sycl_device_interface.h" +#include "Support/CBindingWrapping.h" +#include +#include +#include /* SYCL headers */ + +using namespace cl::sycl; + +namespace +{ +// Create wrappers for C Binding types (see CBindingWrapping.h). + DEFINE_SIMPLE_CONVERSION_FUNCTIONS(device, DPPLSyclDeviceRef) + + /*! + * @brief Helper function to print the metadata for a sycl::device. + * + * @param Device My Param doc + */ +void dump_device_info (const device & Device) +{ + std::stringstream ss; + + ss << std::setw(4) << " " << std::left << std::setw(16) << "Name" + << Device.get_info() << '\n'; + ss << std::setw(4) << " " << std::left << std::setw(16) << "Driver version" + << Device.get_info() << '\n'; + ss << std::setw(4) << " " << std::left << std::setw(16) << "Vendor" + << Device.get_info() << '\n'; + ss << std::setw(4) << " " << std::left << std::setw(16) << "Profile" + << Device.get_info() << '\n'; + + std::cout << ss.str(); +} + +} /* end of anonymous namespace */ + +/*! + * Prints some of the device info metadata for the device corresponding to the + * specified sycl::queue. Currently, device name, driver version, device + * vendor, and device profile are printed out. More attributed may be added + * later. + */ +void DPPLDumpDeviceInfo (__dppl_keep const DPPLSyclDeviceRef DRef) +{ + auto Device = unwrap(DRef); + dump_device_info(*Device); +} + + +void DPPLDeleteSyclDevice (__dppl_take DPPLSyclDeviceRef DRef) +{ + delete unwrap(DRef); +} + +bool DPPLDeviceIsAccelerator (__dppl_keep const DPPLSyclDeviceRef DRef) +{ + return unwrap(DRef)->is_accelerator(); +} + +bool DPPLDeviceIsCPU (__dppl_keep const DPPLSyclDeviceRef DRef) +{ + return unwrap(DRef)->is_cpu(); +} + +bool DPPLDeviceIsGPU (__dppl_keep const DPPLSyclDeviceRef DRef) +{ + return unwrap(DRef)->is_gpu(); +} + + +bool DPPLDeviceIsHost (__dppl_keep const DPPLSyclDeviceRef DRef) +{ + return unwrap(DRef)->is_host(); +} + +__dppl_give const char* +DPPLGetDeviceName (__dppl_keep const DPPLSyclDeviceRef DRef) +{ + auto name = unwrap(DRef)->get_info(); + auto cstr_name = new char [name.length()+1]; + std::strcpy (cstr_name, name.c_str()); + return cstr_name; +} + +__dppl_give const char* +DPPLGetDeviceVendorName (__dppl_keep const DPPLSyclDeviceRef DRef) +{ + auto vendor = unwrap(DRef)->get_info(); + auto cstr_vendor = new char [vendor.length()+1]; + std::strcpy (cstr_vendor, vendor.c_str()); + return cstr_vendor; +} + +__dppl_give const char* +DPPLGetDeviceDriverInfo (__dppl_keep const DPPLSyclDeviceRef DRef) +{ + auto driver = unwrap(DRef)->get_info(); + auto cstr_driver = new char [driver.length()+1]; + std::strcpy (cstr_driver, driver.c_str()); + return cstr_driver; +} + +bool DPPLGetDeviceHostUnifiedMemory (__dppl_keep const DPPLSyclDeviceRef DRef) +{ + return unwrap(DRef)->get_info(); +} diff --git a/backends/source/dppl_sycl_platform_interface.cpp b/backends/source/dppl_sycl_platform_interface.cpp new file mode 100644 index 0000000000..271a64b31a --- /dev/null +++ b/backends/source/dppl_sycl_platform_interface.cpp @@ -0,0 +1,74 @@ +//===--- dppl_sycl_platform_interface.cpp - DPPL-SYCL interface --*- C++ -*-===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 the functions declared in +/// dppl_sycl_platform_interface.h. +/// +//===----------------------------------------------------------------------===// + +#include "dppl_sycl_platform_interface.h" +#include +#include +#include + +#include + +using namespace cl::sycl; + +/*! + * Prints out the following sycl::info::platform attributes for each platform + * found on the system: + * - info::platform::name + * - info::platform::version + * - info::platform::profile + * + */ +void DPPLPlatform_DumpInfo () +{ + size_t i = 0; + + // Print out the info for each platform + auto platforms = platform::get_platforms(); + for (auto &p : platforms) { + std::cout << "---Platform " << i << '\n'; + std::stringstream ss; + + ss << std::setw(4) << " " << std::left << std::setw(12) << "Name" + << p.get_info() << '\n'; + ss << std::setw(4) << " " << std::left << std::setw(12) << "Version" + << p.get_info() << '\n'; + ss << std::setw(4) << " " << std::left << std::setw(12) << "Vendor" + << p.get_info() << '\n'; + ss << std::setw(4) << " " << std::left << std::setw(12) << "Profile" + << p.get_info() << '\n'; + + std::cout << ss.str(); + ++i; + } +} + +/*! + * Returns the number of sycl::platform on the system. + */ +size_t DPPLPlatform_GetNumPlatforms () +{ + return platform::get_platforms().size(); +} diff --git a/backends/source/dppl_sycl_queue_interface.cpp b/backends/source/dppl_sycl_queue_interface.cpp index cf215c6795..e02479d69d 100644 --- a/backends/source/dppl_sycl_queue_interface.cpp +++ b/backends/source/dppl_sycl_queue_interface.cpp @@ -20,445 +20,44 @@ /// /// \file /// This file implements the data types and functions declared in -/// dppl_sycl_queue_interface.hpp. +/// dppl_sycl_queue_interface.h. /// //===----------------------------------------------------------------------===// + #include "dppl_sycl_queue_interface.h" #include "Support/CBindingWrapping.h" -#include -#include -#include -#include -#include -#include -#include #include /* SYCL headers */ using namespace cl::sycl; -/*------------------------------- Private helpers ----------------------------*/ - -// Anonymous namespace for private helpers namespace { - - // Create wrappers for C Binding types (see CBindingWrapping.h). +// Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(queue, DPPLSyclQueueRef) -/*! - * @brief - * - * @param Device My Param doc - */ -void dump_device_info (const device & Device) -{ - std::stringstream ss; - - ss << std::setw(4) << " " << std::left << std::setw(16) << "Name" - << Device.get_info() << '\n'; - ss << std::setw(4) << " " << std::left << std::setw(16) << "Driver version" - << Device.get_info() << '\n'; - ss << std::setw(4) << " " << std::left << std::setw(16) << "Vendor" - << Device.get_info() << '\n'; - ss << std::setw(4) << " " << std::left << std::setw(16) << "Profile" - << Device.get_info() << '\n'; - - std::cout << ss.str(); -} - -/*! - * @brief - * - * @param Platform My Param doc - */ -void dump_platform_info (const platform & Platform) -{ - std::stringstream ss; - - ss << std::setw(4) << " " << std::left << std::setw(12) << "Name" - << Platform.get_info() << '\n'; - ss << std::setw(4) << " " << std::left << std::setw(12) << "Version" - << Platform.get_info() << '\n'; - ss << std::setw(4) << " " << std::left << std::setw(12) << "Vendor" - << Platform.get_info() << '\n'; - ss << std::setw(4) << " " << std::left << std::setw(12) << "Profile" - << Platform.get_info() << '\n'; - - std::cout << ss.str(); -} - -void error_reporter (const std::string & msg) -{ - throw std::runtime_error("Error: " + msg); -} - -/*! - * @brief A helper class to support the DPPLSyclQueuemanager. - * - * The QMgrHelper is needed so that sycl headers are not exposed at the - * top-level DPPL API. - * - */ -class QMgrHelper -{ -public: - static std::vector& - cpu_queues_ () - { - static std::vector* cpu_queues = - QMgrHelper::init_queues(info::device_type::cpu); - return *cpu_queues; - } - - static std::vector& - gpu_queues_ () - { - static std::vector* gpu_queues = - QMgrHelper::init_queues(info::device_type::gpu); - return *gpu_queues; - } - - static std::vector& - active_queues_ () - { - thread_local static std::vector* active_queues = - new std::vector({default_selector()}); - return *active_queues; - } - - static __dppl_give DPPLSyclQueueRef - getQueue (DPPLSyclDeviceType DeviceTy, size_t DNum); - - static __dppl_give DPPLSyclQueueRef - getCurrentQueue (); - - static void - setAsDefaultQueue (DPPLSyclDeviceType DeviceTy, size_t DNum); - - static __dppl_give DPPLSyclQueueRef - pushSyclQueue (DPPLSyclDeviceType DeviceTy, size_t DNum); - - static void - popSyclQueue (); - - static cl::sycl::vector_class* - init_queues (info::device_type device_ty) - { - auto queues = new std::vector(); - for(auto d : device::get_devices(device_ty)) - queues->emplace_back(d); - return queues; - } -}; - -// make function call like access to variable -// it is for minimizing code changes during replacing static vars with functions -// it could be refactored by replacing variable with function call -// scope of this variables is only this file -#define cpu_queues cpu_queues_() -#define gpu_queues gpu_queues_() -#define active_queues active_queues_() - -/*! - * Allocates a new copy of the present top of stack queue, which can be the - * default queue and returns to caller. The caller owns the pointer and is - * responsible for deallocating it. The helper function deleteQueue can be used - * is for that purpose. - */ -DPPLSyclQueueRef QMgrHelper::getCurrentQueue () -{ - if(active_queues.empty()) - error_reporter("No currently active queues."); - auto last = QMgrHelper::active_queues.size() - 1; - return wrap(new queue(QMgrHelper::active_queues[last])); -} - -/*! - * Allocates a sycl::queue by copying from the cached {cpu|gpu}_queues vector - * and returns it to the caller. The caller owns the pointer and is responsible - * for deallocating it. The helper function deleteQueue can be used is for that - * purpose. - */ -DPPLSyclQueueRef -QMgrHelper::getQueue (DPPLSyclDeviceType DeviceTy, - size_t DNum) -{ - queue *QRef = nullptr; - - switch (DeviceTy) - { - case DPPLSyclDeviceType::DPPL_CPU: - { - if (DNum >= cpu_queues.size()) { - std::stringstream ss; - ss << "SYCL CPU device " << DNum << " not found on system."; - error_reporter(ss.str()); - } - QRef = new queue(QMgrHelper::cpu_queues[DNum]); - break; - } - case DPPLSyclDeviceType::DPPL_GPU: - { - if (DNum >= gpu_queues.size()) { - std::stringstream ss; - ss << "SYCL GPU device " << DNum << " not found on system."; - error_reporter(ss.str()); - } - QRef = new queue(QMgrHelper::gpu_queues[DNum]); - break; - } - default: - error_reporter("Unsupported device type."); - } - - return wrap(QRef); -} - -/*! - * Changes the first entry into the stack, i.e., the default queue to a new - * sycl::queue corresponding to the device type and device number. - */ -void -QMgrHelper::setAsDefaultQueue (DPPLSyclDeviceType DeviceTy, size_t DNum) -{ - if(active_queues.empty()) - error_reporter("active queue vector is corrupted."); - - switch (DeviceTy) - { - case DPPLSyclDeviceType::DPPL_CPU: - { - if (DNum >= cpu_queues.size()) { - std::stringstream ss; - ss << "SYCL CPU device " << DNum << " not found on system."; - error_reporter(ss.str()); - } - active_queues[0] = cpu_queues[DNum]; - break; - } - case DPPLSyclDeviceType::DPPL_GPU: - { - if (DNum >= gpu_queues.size()) { - std::stringstream ss; - ss << "SYCL GPU device " << DNum << " not found on system."; - error_reporter(ss.str()); - } - active_queues[0] = gpu_queues[DNum]; - break; - } - default: - { - error_reporter("Unsupported device type."); - } - } -} - -/*! - * Allocates a new sycl::queue by copying from the cached {cpu|gpu}_queues - * vector. The pointer returned is now owned by the caller and must be properly - * cleaned up. The helper function DPPLDeleteQueue() can be used is for that - * purpose. - */ -DPPLSyclQueueRef -QMgrHelper::pushSyclQueue (DPPLSyclDeviceType DeviceTy, size_t DNum) -{ - queue *QRef = nullptr; - if(active_queues.empty()) - error_reporter("Why is there no previous global context?"); - - switch (DeviceTy) - { - case DPPLSyclDeviceType::DPPL_CPU: - { - if (DNum >= cpu_queues.size()) { - std::stringstream ss; - ss << "SYCL CPU device " << DNum << " not found on system."; - error_reporter(ss.str()); - } - active_queues.emplace_back(cpu_queues[DNum]); - QRef = new queue(active_queues[active_queues.size()-1]); - break; - } - case DPPLSyclDeviceType::DPPL_GPU: - { - if (DNum >= gpu_queues.size()) { - std::stringstream ss; - ss << "SYCL GPU device " << DNum << " not found on system."; - error_reporter(ss.str()); - } - active_queues.emplace_back(gpu_queues[DNum]); - QRef = new queue(active_queues[active_queues.size()-1]); - break; - } - default: - { - error_reporter("Unsupported device type."); - } - } - - return wrap(QRef); -} - -/*! - * If there were any sycl::queue that were activated and added to the stack of - * activated queues then the top of the stack entry is popped. Note that since - * the same std::vector is used to keep track of the activated queues and the - * global queue a popSyclQueue call can never make the stack empty. Even - * after all activated queues are popped, the global queue is still available as - * the first element added to the stack. - */ -void -QMgrHelper::popSyclQueue () -{ - // The first queue which is the "default" queue can not be removed. - if(active_queues.size() <= 1 ) - error_reporter("No active contexts"); - active_queues.pop_back(); -} - } /* end of anonymous namespace */ -/*! - * Delete the passed in pointer after verifying it points to a sycl::queue. - */ -void DPPLDeleteQueue (__dppl_take DPPLSyclQueueRef QRef) -{ - delete unwrap(QRef); -} - -/*! - * Prints some of the device info metadata for the device corresponding to the - * specified sycl::queue. Currently, device name, driver version, device - * vendor, and device profile are printed out. More attributed may be added - * later. - */ -void DPPLDumpDeviceInfo (__dppl_keep const DPPLSyclQueueRef QRef) +__dppl_give DPPLSyclDeviceRef +DPPLGetDeviceFromQueue (__dppl_keep const DPPLSyclQueueRef QRef) { auto Q = unwrap(QRef); - dump_device_info(Q->get_device()); + auto Device = new device(Q->get_device()); + return reinterpret_cast(Device); } -/*! - * Prints out number of available SYCL platforms, number of CPU queues, number - * of GPU queues, metadata about the current global queue, and how many queues - * are currently activated. More information can be added in future, and - * functions to extract these information using SYCL API (e.g. device_info) - * may also be added. For now, this function can be used as a basic canary test - * to check if the queue manager was properly initialized. - * - */ -void DPPLDumpPlatformInfo () +__dppl_give DPPLSyclContextRef +DPPLGetContextFromQueue (__dppl_keep const DPPLSyclQueueRef QRef) { - size_t i = 0; - - // Print out the info for each platform - auto platforms = platform::get_platforms(); - for (auto &p : platforms) { - std::cout << "---Platform " << i << '\n'; - dump_platform_info(p); - ++i; - } - - // Print out the info for CPU devices - if (QMgrHelper::cpu_queues.size()) - std::cout << "---Number of available SYCL CPU queues: " - << QMgrHelper::cpu_queues.size() << '\n'; - else - std::cout << "---No available SYCL CPU device\n"; - - // Print out the info for GPU devices - if (QMgrHelper::gpu_queues.size()) - std::cout << "---Number of available SYCL GPU queues: " - << QMgrHelper::gpu_queues.size() << '\n'; - else - std::cout << "---No available SYCL GPU device\n"; - - std::cout << "---Current queue :\n"; - DPPLDumpDeviceInfo(wrap(&QMgrHelper::active_queues[0])); - - std::cout << "---Number of active queues : " - << QMgrHelper::active_queues.size() - << '\n'; -} - -/*! - * Returns the number of sycl::platform on the system. - */ -size_t DPPLGetNumPlatforms () -{ - return platform::get_platforms().size(); -} - -/*! - * Returns inside the number of activated queues not including the global queue - * (QMgrHelper::active_queues[0]). - */ -size_t DPPLGetNumActivatedQueues () -{ - if (QMgrHelper::active_queues.empty()) - error_reporter("No active contexts"); - return QMgrHelper::active_queues.size() - 1; -} - -/*! - * Returns the number of CPU queues. - */ -size_t DPPLGetNumCPUQueues () -{ - return QMgrHelper::cpu_queues.size(); -} - -/*! - * Returns the number of GPU queues. - */ -size_t DPPLGetNumGPUQueues () -{ - return QMgrHelper::gpu_queues.size(); -} - -/*! - * \see QMgrHelper::getCurrentQueue() - */ -DPPLSyclQueueRef DPPLGetCurrentQueue () -{ - return QMgrHelper::getCurrentQueue(); -} - -/*! - * Returns a copy of a sycl::queue corresponding to the specified device type - * and device number. A runtime_error gets thrown if no such device exists. - */ -DPPLSyclQueueRef DPPLGetQueue (DPPLSyclDeviceType DeviceTy, - size_t DNum) -{ - return QMgrHelper::getQueue(DeviceTy, DNum); -} - -/*! - * The function sets the global queue, i.e., the sycl::queue object at - * QMgrHelper::active_queues[0] vector to the sycl::queue corresponding to the - * specified device type and id. A runtime_error gets thrown if no such device - * exists. - */ -void DPPLSetAsDefaultQueue (DPPLSyclDeviceType DeviceTy, size_t DNum) -{ - QMgrHelper::setAsDefaultQueue(DeviceTy, DNum); -} - -/*! - * \see QMgrHelper::pushSyclQueue() - */ -__dppl_give DPPLSyclQueueRef DPPLPushSyclQueue (DPPLSyclDeviceType DeviceTy, - size_t DNum) -{ - return QMgrHelper::pushSyclQueue(DeviceTy, DNum); + auto Q = unwrap(QRef); + auto Context = new context(Q->get_context()); + return reinterpret_cast(Context); } /*! - * \see QMgrHelper::popSyclQueue() + * Delete the passed in pointer after verifying it points to a sycl::queue. */ -void DPPLPopSyclQueue () +void DPPLDeleteSyclQueue (__dppl_take DPPLSyclQueueRef QRef) { - QMgrHelper::popSyclQueue(); + delete unwrap(QRef); } diff --git a/backends/source/dppl_sycl_queue_manager.cpp b/backends/source/dppl_sycl_queue_manager.cpp new file mode 100644 index 0000000000..17776fda11 --- /dev/null +++ b/backends/source/dppl_sycl_queue_manager.cpp @@ -0,0 +1,350 @@ +//===--- dppl_sycl_queue_manager.cpp - DPPL-SYCL interface --*- C++ -*---===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 the data types and functions declared in +/// dppl_sycl_queue_manager.h. +/// +//===----------------------------------------------------------------------===// +#include "dppl_sycl_queue_manager.h" +#include "Support/CBindingWrapping.h" +#include +#include +#include + +#include /* SYCL headers */ + +using namespace cl::sycl; + +/*------------------------------- Private helpers ----------------------------*/ + +// Anonymous namespace for private helpers +namespace +{ + + // Create wrappers for C Binding types (see CBindingWrapping.h). + DEFINE_SIMPLE_CONVERSION_FUNCTIONS(queue, DPPLSyclQueueRef) + +void error_reporter (const std::string & msg) +{ + throw std::runtime_error("Error: " + msg); +} + +/*! + * @brief A helper class to support the DPPLSyclQueuemanager. + * + * The QMgrHelper is needed so that sycl headers are not exposed at the + * top-level DPPL API. + * + */ +class QMgrHelper +{ +public: + static std::vector& + cpu_queues_ () + { + static std::vector* cpu_queues = + QMgrHelper::init_queues(info::device_type::cpu); + return *cpu_queues; + } + + static std::vector& + gpu_queues_ () + { + static std::vector* gpu_queues = + QMgrHelper::init_queues(info::device_type::gpu); + return *gpu_queues; + } + + static std::vector& + active_queues_ () + { + thread_local static std::vector* active_queues = + new std::vector({default_selector()}); + return *active_queues; + } + + static __dppl_give DPPLSyclQueueRef + getQueue (DPPLSyclDeviceType DeviceTy, size_t DNum); + + static __dppl_give DPPLSyclQueueRef + getCurrentQueue (); + + static void + setAsDefaultQueue (DPPLSyclDeviceType DeviceTy, size_t DNum); + + static __dppl_give DPPLSyclQueueRef + pushSyclQueue (DPPLSyclDeviceType DeviceTy, size_t DNum); + + static void + popSyclQueue (); + + static cl::sycl::vector_class* + init_queues (info::device_type device_ty) + { + auto queues = new std::vector(); + for(auto d : device::get_devices(device_ty)) + queues->emplace_back(d); + return queues; + } +}; + +// make function call like access to variable +// it is for minimizing code changes during replacing static vars with functions +// it could be refactored by replacing variable with function call +// scope of this variables is only this file +#define cpu_queues cpu_queues_() +#define gpu_queues gpu_queues_() +#define active_queues active_queues_() + + +//----------------------------- Public API -----------------------------------// + +/*! + * Allocates a new copy of the present top of stack queue, which can be the + * default queue and returns to caller. The caller owns the pointer and is + * responsible for deallocating it. The helper function deleteQueue can be used + * is for that purpose. + */ +DPPLSyclQueueRef QMgrHelper::getCurrentQueue () +{ + if(active_queues.empty()) + error_reporter("No currently active queues."); + auto last = QMgrHelper::active_queues.size() - 1; + return wrap(new queue(QMgrHelper::active_queues[last])); +} + +/*! + * Allocates a sycl::queue by copying from the cached {cpu|gpu}_queues vector + * and returns it to the caller. The caller owns the pointer and is responsible + * for deallocating it. The helper function deleteQueue can be used is for that + * purpose. + */ +DPPLSyclQueueRef +QMgrHelper::getQueue (DPPLSyclDeviceType DeviceTy, + size_t DNum) +{ + queue *QRef = nullptr; + + switch (DeviceTy) + { + case DPPLSyclDeviceType::DPPL_CPU: + { + if (DNum >= cpu_queues.size()) { + std::stringstream ss; + ss << "SYCL CPU device " << DNum << " not found on system."; + error_reporter(ss.str()); + } + QRef = new queue(QMgrHelper::cpu_queues[DNum]); + break; + } + case DPPLSyclDeviceType::DPPL_GPU: + { + if (DNum >= gpu_queues.size()) { + std::stringstream ss; + ss << "SYCL GPU device " << DNum << " not found on system."; + error_reporter(ss.str()); + } + QRef = new queue(QMgrHelper::gpu_queues[DNum]); + break; + } + default: + error_reporter("Unsupported device type."); + } + + return wrap(QRef); +} + +/*! + * Changes the first entry into the stack, i.e., the default queue to a new + * sycl::queue corresponding to the device type and device number. + */ +void +QMgrHelper::setAsDefaultQueue (DPPLSyclDeviceType DeviceTy, size_t DNum) +{ + if(active_queues.empty()) + error_reporter("active queue vector is corrupted."); + + switch (DeviceTy) + { + case DPPLSyclDeviceType::DPPL_CPU: + { + if (DNum >= cpu_queues.size()) { + std::stringstream ss; + ss << "SYCL CPU device " << DNum << " not found on system."; + error_reporter(ss.str()); + } + active_queues[0] = cpu_queues[DNum]; + break; + } + case DPPLSyclDeviceType::DPPL_GPU: + { + if (DNum >= gpu_queues.size()) { + std::stringstream ss; + ss << "SYCL GPU device " << DNum << " not found on system."; + error_reporter(ss.str()); + } + active_queues[0] = gpu_queues[DNum]; + break; + } + default: + { + error_reporter("Unsupported device type."); + } + } +} + +/*! + * Allocates a new sycl::queue by copying from the cached {cpu|gpu}_queues + * vector. The pointer returned is now owned by the caller and must be properly + * cleaned up. The helper function DPPLDeleteSyclQueue() can be used is for that + * purpose. + */ +DPPLSyclQueueRef +QMgrHelper::pushSyclQueue (DPPLSyclDeviceType DeviceTy, size_t DNum) +{ + queue *QRef = nullptr; + if(active_queues.empty()) + error_reporter("Why is there no previous global context?"); + + switch (DeviceTy) + { + case DPPLSyclDeviceType::DPPL_CPU: + { + if (DNum >= cpu_queues.size()) { + std::stringstream ss; + ss << "SYCL CPU device " << DNum << " not found on system."; + error_reporter(ss.str()); + } + active_queues.emplace_back(cpu_queues[DNum]); + QRef = new queue(active_queues[active_queues.size()-1]); + break; + } + case DPPLSyclDeviceType::DPPL_GPU: + { + if (DNum >= gpu_queues.size()) { + std::stringstream ss; + ss << "SYCL GPU device " << DNum << " not found on system."; + error_reporter(ss.str()); + } + active_queues.emplace_back(gpu_queues[DNum]); + QRef = new queue(active_queues[active_queues.size()-1]); + break; + } + default: + { + error_reporter("Unsupported device type."); + } + } + + return wrap(QRef); +} + +/*! + * If there were any sycl::queue that were activated and added to the stack of + * activated queues then the top of the stack entry is popped. Note that since + * the same std::vector is used to keep track of the activated queues and the + * global queue a popSyclQueue call can never make the stack empty. Even + * after all activated queues are popped, the global queue is still available as + * the first element added to the stack. + */ +void +QMgrHelper::popSyclQueue () +{ + // The first queue which is the "default" queue can not be removed. + if(active_queues.size() <= 1 ) + error_reporter("No active contexts"); + active_queues.pop_back(); +} + +} /* end of anonymous namespace */ + +/*! + * Returns inside the number of activated queues not including the global queue + * (QMgrHelper::active_queues[0]). + */ +size_t DPPLGetNumActivatedQueues () +{ + if (QMgrHelper::active_queues.empty()) + error_reporter("No active contexts"); + return QMgrHelper::active_queues.size() - 1; +} + +/*! + * Returns the number of CPU queues. + */ +size_t DPPLGetNumCPUQueues () +{ + return QMgrHelper::cpu_queues.size(); +} + +/*! + * Returns the number of GPU queues. + */ +size_t DPPLGetNumGPUQueues () +{ + return QMgrHelper::gpu_queues.size(); +} + +/*! + * \see QMgrHelper::getCurrentQueue() + */ +DPPLSyclQueueRef DPPLGetCurrentQueue () +{ + return QMgrHelper::getCurrentQueue(); +} + +/*! + * Returns a copy of a sycl::queue corresponding to the specified device type + * and device number. A runtime_error gets thrown if no such device exists. + */ +DPPLSyclQueueRef DPPLGetQueue (DPPLSyclDeviceType DeviceTy, + size_t DNum) +{ + return QMgrHelper::getQueue(DeviceTy, DNum); +} + +/*! + * The function sets the global queue, i.e., the sycl::queue object at + * QMgrHelper::active_queues[0] vector to the sycl::queue corresponding to the + * specified device type and id. A runtime_error gets thrown if no such device + * exists. + */ +void DPPLSetAsDefaultQueue (DPPLSyclDeviceType DeviceTy, size_t DNum) +{ + QMgrHelper::setAsDefaultQueue(DeviceTy, DNum); +} + +/*! + * \see QMgrHelper::pushSyclQueue() + */ +__dppl_give DPPLSyclQueueRef DPPLPushSyclQueue (DPPLSyclDeviceType DeviceTy, + size_t DNum) +{ + return QMgrHelper::pushSyclQueue(DeviceTy, DNum); +} + +/*! + * \see QMgrHelper::popSyclQueue() + */ +void DPPLPopSyclQueue () +{ + QMgrHelper::popSyclQueue(); +} diff --git a/backends/source/dppl_utils.cpp b/backends/source/dppl_utils.cpp new file mode 100644 index 0000000000..39006153ae --- /dev/null +++ b/backends/source/dppl_utils.cpp @@ -0,0 +1,31 @@ +//===--------- dppl_utils.cpp - DPPL-SYCL interface ----*---- C++ ----*----===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 the helper functions defined in dppl_utils.h. +/// +//===----------------------------------------------------------------------===// + +#include "dppl_utils.h" + +void DPPLDeleteCString (__dppl_take const char* str) +{ + delete str; +} diff --git a/backends/tests/CMakeLists.txt b/backends/tests/CMakeLists.txt index b2558f4fab..c3add176ba 100644 --- a/backends/tests/CMakeLists.txt +++ b/backends/tests/CMakeLists.txt @@ -11,7 +11,7 @@ else() # We need thread support for gtest find_package(Threads REQUIRED) - set(CMAKE_CTEST_COMMAND ctest -V) + set(CMAKE_CTEST_COMMAND ctest -V) # Emulate autotools like make check target to build tests add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) @@ -24,6 +24,7 @@ else() set(PYDPPL_BACKEND_TEST_CASES test_sycl_queue_manager + test_sycl_platform_interface ) foreach(TEST_CASE ${PYDPPL_BACKEND_TEST_CASES}) diff --git a/backends/tests/test_sycl_platform_interface.cpp b/backends/tests/test_sycl_platform_interface.cpp new file mode 100644 index 0000000000..3de7029b40 --- /dev/null +++ b/backends/tests/test_sycl_platform_interface.cpp @@ -0,0 +1,50 @@ +//===--- test_sycl_platform_interface.cpp - DPPL-SYCL interface -*- C++ -*-===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 has unit test cases for functions defined in +/// dppl_sycl_platform_interface.h. +/// +//===----------------------------------------------------------------------===// +#include "dppl_sycl_platform_interface.h" +#include + +struct TestDPPLSyclPlatformInterface : public ::testing::Test +{ }; + + +TEST_F (TestDPPLSyclPlatformInterface, CheckGetNumPlatforms) +{ + auto nplatforms = DPPLPlatform_GetNumPlatforms(); + EXPECT_GE(nplatforms, 0); +} + +TEST_F (TestDPPLSyclPlatformInterface, CheckDPPLPlatformDumpInfo) +{ + EXPECT_NO_FATAL_FAILURE(DPPLPlatform_DumpInfo()); +} + +int +main (int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/backends/tests/test_sycl_queue_manager.cpp b/backends/tests/test_sycl_queue_manager.cpp index a64d06cdab..d38ddb2a8a 100644 --- a/backends/tests/test_sycl_queue_manager.cpp +++ b/backends/tests/test_sycl_queue_manager.cpp @@ -1,6 +1,32 @@ +//===--- test_sycl_queue_manager.cpp - DPPL-SYCL interface --*- C++ ---*---===// +// +// Python Data Parallel Processing Library (PyDPPL) +// +// Copyright 2020 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 has unit test cases for functions defined in +/// dppl_sycl_queue_interface.h and dppl_sycl_queue_manager.h. +/// +//===----------------------------------------------------------------------===// +#include "dppl_sycl_device_interface.h" +#include "dppl_sycl_queue_manager.h" #include "dppl_sycl_queue_interface.h" #include -#include #include using namespace std; @@ -15,8 +41,8 @@ namespace num = DPPLGetNumActivatedQueues(); DPPLPopSyclQueue(); DPPLPopSyclQueue(); - DPPLDeleteQueue(q1); - DPPLDeleteQueue(q2); + DPPLDeleteSyclQueue(q1); + DPPLDeleteSyclQueue(q2); } void bar (size_t & num) @@ -25,20 +51,12 @@ namespace // Capture the number of active queues in second num = DPPLGetNumActivatedQueues(); DPPLPopSyclQueue(); - DPPLDeleteQueue(q1); + DPPLDeleteSyclQueue(q1); } } struct TestDPPLSyclQueuemanager : public ::testing::Test -{ - -}; - -TEST_F (TestDPPLSyclQueuemanager, CheckGetNumPlatforms) -{ - auto nplatforms = DPPLGetNumPlatforms(); - EXPECT_GE(nplatforms, 0); -} +{ }; TEST_F (TestDPPLSyclQueuemanager, CheckDPPLGetCurrentQueue) @@ -102,21 +120,15 @@ TEST_F (TestDPPLSyclQueuemanager, CheckGetNumActivatedQueues) EXPECT_EQ(num2, 1); EXPECT_EQ(num4, 0); - DPPLDeleteQueue(q); -} - - -TEST_F (TestDPPLSyclQueuemanager, CheckDPPLDumpPlatformInfo) -{ - EXPECT_NO_FATAL_FAILURE(DPPLDumpPlatformInfo()); + DPPLDeleteSyclQueue(q); } TEST_F (TestDPPLSyclQueuemanager, CheckDPPLDumpDeviceInfo) { auto q = DPPLGetCurrentQueue(); - EXPECT_NO_FATAL_FAILURE(DPPLDumpDeviceInfo(q)); - EXPECT_NO_FATAL_FAILURE(DPPLDeleteQueue(q)); + EXPECT_NO_FATAL_FAILURE(DPPLDumpDeviceInfo(DPPLGetDeviceFromQueue(q))); + EXPECT_NO_FATAL_FAILURE(DPPLDeleteSyclQueue(q)); } diff --git a/dppl/sycl_core.pyx b/dppl/sycl_core.pyx index 2a8a5cd840..1ed47334df 100644 --- a/dppl/sycl_core.pyx +++ b/dppl/sycl_core.pyx @@ -27,11 +27,9 @@ # cython: language_level=3 from __future__ import print_function -from cpython.pycapsule cimport (PyCapsule_New, - PyCapsule_IsValid, - PyCapsule_GetPointer) from enum import Enum, auto import logging +from libcpp cimport bool _logger = logging.getLogger(__name__) @@ -46,25 +44,60 @@ cdef class UnsupportedDeviceTypeError(Exception): ''' pass -cdef extern from "dppl_sycl_types.h": +cdef extern from "dppl_utils.h": + cdef void DPPLDeleteCString (const char *str) +cdef extern from "dppl_sycl_types.h": + cdef struct DPPLOpaqueSyclContext: + pass cdef struct DPPLOpaqueSyclQueue: pass + cdef struct DPPLOpaqueSyclDevice: + pass + + ctypedef DPPLOpaqueSyclContext* DPPLSyclContextRef ctypedef DPPLOpaqueSyclQueue* DPPLSyclQueueRef + ctypedef DPPLOpaqueSyclDevice* DPPLSyclDeviceRef + +cdef extern from "dppl_sycl_context_interface.h": + cdef void DPPLDeleteSyclContext (DPPLSyclContextRef CtxtRef) except + + +cdef extern from "dppl_sycl_device_interface.h": + cdef void DPPLDumpDeviceInfo (const DPPLSyclDeviceRef DRef) except + + cdef void DPPLDeleteSyclDevice (DPPLSyclDeviceRef DRef) except + + cdef void DPPLDumpDeviceInfo (const DPPLSyclDeviceRef DRef) except + + cdef bool DPPLDeviceIsAccelerator (const DPPLSyclDeviceRef DRef) except + + cdef bool DPPLDeviceIsCPU (const DPPLSyclDeviceRef DRef) except + + cdef bool DPPLDeviceIsGPU (const DPPLSyclDeviceRef DRef) except + + cdef bool DPPLDeviceIsHost (const DPPLSyclDeviceRef DRef) except + + cdef const char* DPPLGetDeviceDriverInfo (const DPPLSyclDeviceRef DRef) \ + except + + cdef const char* DPPLGetDeviceName (const DPPLSyclDeviceRef DRef) except + + cdef const char* DPPLGetDeviceVendorName (const DPPLSyclDeviceRef DRef) \ + except + + cdef bool DPPLGetDeviceHostUnifiedMemory (const DPPLSyclDeviceRef DRef) \ + except + + +cdef extern from "dppl_sycl_platform_interface.h": + cdef size_t DPPLPlatform_GetNumPlatforms () + cdef void DPPLPlatform_DumpInfo () cdef extern from "dppl_sycl_queue_interface.h": + cdef void DPPLDeleteSyclQueue (DPPLSyclQueueRef QRef) except + + cdef DPPLSyclContextRef DPPLGetContextFromQueue (const DPPLSyclQueueRef Q) \ + except+ + cdef DPPLSyclDeviceRef DPPLGetDeviceFromQueue (const DPPLSyclQueueRef Q) \ + except + +cdef extern from "dppl_sycl_queue_manager.h": cdef enum _device_type 'DPPLSyclDeviceType': _GPU 'DPPL_GPU' _CPU 'DPPL_CPU' - cdef void DPPLDumpPlatformInfo () except + - cdef void DPPLDumpDeviceInfo (const DPPLSyclQueueRef Q) except + cdef DPPLSyclQueueRef DPPLGetCurrentQueue () except + cdef size_t DPPLGetNumCPUQueues () except + cdef size_t DPPLGetNumGPUQueues () except + cdef size_t DPPLGetNumActivatedQueues () except + - cdef size_t DPPLGetNumPlatforms () except + cdef DPPLSyclQueueRef DPPLGetQueue (_device_type DTy, size_t device_num) except + cdef void DPPLPopSyclQueue () except + @@ -72,15 +105,101 @@ cdef extern from "dppl_sycl_queue_interface.h": size_t device_num) except + cdef void DPPLSetAsDefaultQueue (_device_type DTy, size_t device_num) except + - cdef void DPPLDeleteQueue (DPPLSyclQueueRef Q) except + -# Destructor for a PyCapsule containing a SYCL queue -cdef void delete_queue (object cap): - DPPLDeleteQueue(PyCapsule_GetPointer(cap, NULL)) +cdef class SyclContext: + cdef DPPLSyclContextRef ctxt_ptr -cdef class _SyclQueueManager: + @staticmethod + cdef SyclContext _create (DPPLSyclContextRef ctxt): + cdef SyclContext ret = SyclContext.__new__(SyclContext) + ret.ctxt_ptr = ctxt + return ret + + def __dealloc__ (self): + DPPLDeleteSyclContext(self.ctxt_ptr) + + cdef DPPLSyclContextRef get_context_ref (self): + return self.ctxt_ptr + + +cdef class SyclDevice: + ''' Wrapper class for a Sycl Device + ''' + cdef DPPLSyclDeviceRef device_ptr + cdef const char *vendor_name + cdef const char *device_name + cdef const char *driver_version + + @staticmethod + cdef SyclDevice _create (DPPLSyclDeviceRef dref): + cdef SyclDevice ret = SyclDevice.__new__(SyclDevice) + ret.device_ptr = dref + ret.vendor_name = DPPLGetDeviceVendorName(dref) + ret.device_name = DPPLGetDeviceName(dref) + ret.driver_version = DPPLGetDeviceDriverInfo(dref) + return ret + + def __dealloc__ (self): + DPPLDeleteSyclDevice(self.device_ptr) + DPPLDeleteCString(self.device_name) + DPPLDeleteCString(self.vendor_name) + DPPLDeleteCString(self.driver_version) + + def dump_device_info (self): + ''' Print information about the SYCL device. + ''' + DPPLDumpDeviceInfo(self.device_ptr) + + def get_device_name (self): + ''' Returns the name of the device as a string + ''' + return self.device_name + + def get_vendor_name (self): + ''' Returns the device vendor name as a string + ''' + return self.vendor_name + + def get_driver_version (self): + ''' Returns the OpenCL software driver version as a string + in the form: major number.minor number, if this SYCL + device is an OpenCL device. Returns a string class + with the value "1.2" if this SYCL device is a host device. + ''' + return self.driver_version + + cdef DPPLSyclDeviceRef get_device_ptr (self): + ''' Returns the DPPLSyclDeviceRef pointer for this class. + ''' + return self.device_ptr + + +cdef class SyclQueue: + ''' Wrapper class for a Sycl queue. + ''' + cdef DPPLSyclQueueRef queue_ptr + + @staticmethod + cdef SyclQueue _create (DPPLSyclQueueRef qref): + cdef SyclQueue ret = SyclQueue.__new__(SyclQueue) + ret.queue_ptr = qref + return ret + + def __dealloc__ (self): + DPPLDeleteSyclQueue(self.queue_ptr) + + cpdef get_sycl_context (self): + return SyclContext._create(DPPLGetContextFromQueue(self.queue_ptr)) + cpdef get_sycl_device (self): + return SyclDevice._create(DPPLGetDeviceFromQueue(self.queue_ptr)) + + cdef DPPLSyclQueueRef get_queue_ref (self): + return self.queue_ptr + + +cdef class _SyclQueueManager: def _set_as_current_queue (self, device_ty, device_id): cdef DPPLSyclQueueRef queue_ptr if device_ty == device_type.gpu: @@ -91,14 +210,13 @@ cdef class _SyclQueueManager: e = UnsupportedDeviceTypeError("Device can only be cpu or gpu") raise e - return PyCapsule_New(queue_ptr, NULL, &delete_queue) + return SyclQueue._create(queue_ptr) def _remove_current_queue (self): DPPLPopSyclQueue() - def has_sycl_platforms (self): - cdef size_t num_platforms = DPPLGetNumPlatforms() + cdef size_t num_platforms = DPPLPlatform_GetNumPlatforms() if num_platforms: return True else: @@ -107,7 +225,7 @@ cdef class _SyclQueueManager: def get_num_platforms (self): ''' Returns the number of available SYCL/OpenCL platforms. ''' - return DPPLGetNumPlatforms() + return DPPLPlatform_GetNumPlatforms() def get_num_activated_queues (self): ''' Return the number of currently activated queues for this thread. @@ -117,8 +235,7 @@ cdef class _SyclQueueManager: def get_current_queue (self): ''' Returns the activated SYCL queue as a PyCapsule. ''' - cdef DPPLSyclQueueRef queue_ptr = DPPLGetCurrentQueue() - return PyCapsule_New(queue_ptr, NULL, &delete_queue) + return SyclQueue._create(DPPLGetCurrentQueue()) def set_default_queue (self, device_ty, device_id): if device_ty == device_type.gpu: @@ -146,17 +263,7 @@ cdef class _SyclQueueManager: def dump (self): ''' Prints information about the Runtime object. ''' - DPPLDumpPlatformInfo() - - def dump_device_info (self, queue_cap): - ''' Prints information about the SYCL queue object. - ''' - if PyCapsule_IsValid(queue_cap, NULL): - DPPLDumpDeviceInfo( - PyCapsule_GetPointer(queue_cap, NULL) - ) - else: - raise ValueError("Expected a PyCapsule encapsulating a SYCL queue") + DPPLPlatform_DumpInfo() def is_in_dppl_ctxt (self): cdef size_t num = DPPLGetNumActivatedQueues() @@ -171,7 +278,6 @@ _qmgr = _SyclQueueManager() # Global bound functions dump = _qmgr.dump -dump_device_info = _qmgr.dump_device_info get_current_queue = _qmgr.get_current_queue get_num_platforms = _qmgr.get_num_platforms get_num_activated_queues = _qmgr.get_num_activated_queues diff --git a/dppl/tests/dppl_tests/test_sycl_queue_manager.py b/dppl/tests/dppl_tests/test_sycl_queue_manager.py index 9fb44730d4..6f83f0fdc9 100644 --- a/dppl/tests/dppl_tests/test_sycl_queue_manager.py +++ b/dppl/tests/dppl_tests/test_sycl_queue_manager.py @@ -43,7 +43,7 @@ def test_dppl_dump (self): def test_dppl_dump_device_info (self): q = dppl.get_current_queue() try: - dppl.dump_device_info(q) + q.get_sycl_device().dump_device_info() except Exception: self.fail("Encountered an exception inside dump_device_info().") @@ -92,3 +92,6 @@ def SessionThread (self): self.assertEqual(dppl.get_num_activated_queues(), 1) Session1.start() Session2.start() + +if __name__ == '__main__': + unittest.main() diff --git a/dppl/tests/test_dump_functions.py b/dppl/tests/test_dump_functions.py index 3b054548fb..2af4744b8e 100644 --- a/dppl/tests/test_dump_functions.py +++ b/dppl/tests/test_dump_functions.py @@ -31,6 +31,10 @@ def test_dppl_dump (self): def test_dppl_dump_device_info (self): q = dppl.get_current_queue() try: - dppl.dump_device_info(q) + q.get_sycl_device().dump_device_info() except Exception: self.fail("Encountered an exception inside dump_device_info().") + + +if __name__ == '__main__': + unittest.main()