diff --git a/backends/CMakeLists.txt b/backends/CMakeLists.txt index b812978ed0..abb8c022ff 100644 --- a/backends/CMakeLists.txt +++ b/backends/CMakeLists.txt @@ -101,6 +101,7 @@ add_library( source/dppl_sycl_platform_interface.cpp source/dppl_sycl_queue_interface.cpp source/dppl_sycl_queue_manager.cpp + source/dppl_sycl_usm_interface.cpp source/dppl_utils.cpp ) diff --git a/backends/include/dppl_sycl_types.h b/backends/include/dppl_sycl_types.h index d1777aae5d..7d265805bd 100644 --- a/backends/include/dppl_sycl_types.h +++ b/backends/include/dppl_sycl_types.h @@ -55,3 +55,10 @@ typedef struct DPPLOpaqueSyclQueue *DPPLSyclQueueRef; * */ typedef struct DPPLOpaqueSyclProgram *DPPLSyclProgramRef; + +/*! + * @brief Used to pass a sycl::usm memory opaquely through DPPL interfaces. + * + * @see sycl::usm + */ +typedef struct DPPLOpaqueSyclUSM *DPPLSyclUSMRef; diff --git a/backends/include/dppl_sycl_usm_interface.h b/backends/include/dppl_sycl_usm_interface.h new file mode 100644 index 0000000000..6a52fcff42 --- /dev/null +++ b/backends/include/dppl_sycl_usm_interface.h @@ -0,0 +1,89 @@ +//===--- dppl_sycl_usm_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::usm interface functions. +/// +//===----------------------------------------------------------------------===// + +#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 Crete USM shared memory. + * + * @return The pointer to USM shared memory. + */ +DPPL_API +__dppl_give DPPLSyclUSMRef +DPPLmalloc_shared (size_t size, __dppl_keep const DPPLSyclQueueRef QRef); + +/*! + * @brief Crete USM host memory. + * + * @return The pointer to USM host memory. + */ +DPPL_API +__dppl_give DPPLSyclUSMRef +DPPLmalloc_host (size_t size, __dppl_keep const DPPLSyclQueueRef QRef); + +/*! + * @brief Crete USM device memory. + * + * @return The pointer to USM device memory. + */ +DPPL_API +__dppl_give DPPLSyclUSMRef +DPPLmalloc_device (size_t size, __dppl_keep const DPPLSyclQueueRef QRef); + +/*! + * @brief Free USM memory. + * + */ +DPPL_API +void DPPLfree_with_queue (__dppl_take DPPLSyclUSMRef MRef, + __dppl_keep const DPPLSyclQueueRef QRef); + +/*! + * @brief Free USM memory. + * + */ +DPPL_API +void DPPLfree_with_context (__dppl_take DPPLSyclUSMRef MRef, + __dppl_keep const DPPLSyclContextRef CRef); + +/*! + * @brief Get pointer type. + * + * @return "host", "device", "shared" or "unknown" + */ +DPPL_API +const char * +DPPLUSM_GetPointerType (__dppl_keep const DPPLSyclUSMRef MRef, + __dppl_keep const DPPLSyclContextRef СRef); + +DPPL_C_EXTERN_C_END diff --git a/backends/source/dppl_sycl_usm_interface.cpp b/backends/source/dppl_sycl_usm_interface.cpp new file mode 100644 index 0000000000..4e1444634b --- /dev/null +++ b/backends/source/dppl_sycl_usm_interface.cpp @@ -0,0 +1,101 @@ +//===--- dppl_sycl_usm_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_usm_interface.h. +/// +//===----------------------------------------------------------------------===// + +#include "dppl_sycl_usm_interface.h" +#include "Support/CBindingWrapping.h" + +#include /* SYCL headers */ + +using namespace cl::sycl; + +namespace +{ +// Create wrappers for C Binding types (see CBindingWrapping.h). + DEFINE_SIMPLE_CONVERSION_FUNCTIONS(queue, DPPLSyclQueueRef) + DEFINE_SIMPLE_CONVERSION_FUNCTIONS(context, DPPLSyclContextRef) + DEFINE_SIMPLE_CONVERSION_FUNCTIONS(void, DPPLSyclUSMRef) + +} /* end of anonymous namespace */ + +__dppl_give DPPLSyclUSMRef +DPPLmalloc_shared (size_t size, __dppl_keep const DPPLSyclQueueRef QRef) +{ + auto Q = unwrap(QRef); + auto Ptr = malloc_shared(size, *Q); + return wrap(Ptr); +} + +__dppl_give DPPLSyclUSMRef +DPPLmalloc_host (size_t size, __dppl_keep const DPPLSyclQueueRef QRef) +{ + auto Q = unwrap(QRef); + auto Ptr = malloc_host(size, *Q); + return wrap(Ptr); +} + +__dppl_give DPPLSyclUSMRef +DPPLmalloc_device (size_t size, __dppl_keep const DPPLSyclQueueRef QRef) +{ + auto Q = unwrap(QRef); + auto Ptr = malloc_device(size, *Q); + return wrap(Ptr); +} + +void DPPLfree_with_queue (__dppl_take DPPLSyclUSMRef MRef, + __dppl_keep const DPPLSyclQueueRef QRef) +{ + auto Ptr = unwrap(MRef); + auto Q = unwrap(QRef); + free(Ptr, *Q); +} + +void DPPLfree_with_context (__dppl_take DPPLSyclUSMRef MRef, + __dppl_keep const DPPLSyclContextRef СRef) +{ + auto Ptr = unwrap(MRef); + auto C = unwrap(СRef); + free(Ptr, *C); +} + +const char * +DPPLUSM_GetPointerType (__dppl_keep const DPPLSyclUSMRef MRef, + __dppl_keep const DPPLSyclContextRef CRef) +{ + auto Ptr = unwrap(MRef); + auto C = unwrap(CRef); + + auto kind = get_pointer_type(Ptr, *C); + switch(kind) { + case usm::alloc::host: + return "host"; + case usm::alloc::device: + return "device"; + case usm::alloc::shared: + return "shared"; + default: + return "unknown"; + } +} diff --git a/dppl/_memory.pyx b/dppl/_memory.pyx new file mode 100644 index 0000000000..22b9329073 --- /dev/null +++ b/dppl/_memory.pyx @@ -0,0 +1,105 @@ +import dppl +from dppl.backend cimport * +from ._sycl_core cimport SyclContext, SyclQueue + +from cpython cimport Py_buffer + + +cdef class Memory: + cdef DPPLSyclUSMRef memory_ptr + cdef Py_ssize_t nbytes + cdef SyclContext context + + cdef _cinit(self, Py_ssize_t nbytes, ptr_type, SyclQueue queue): + cdef DPPLSyclUSMRef p + + self.memory_ptr = NULL + self.nbytes = 0 + self.context = None + + if (nbytes > 0): + if queue is None: + queue = dppl.get_current_queue() + + if (ptr_type == "shared"): + p = DPPLmalloc_shared(nbytes, queue.get_queue_ref()) + elif (ptr_type == "host"): + p = DPPLmalloc_host(nbytes, queue.get_queue_ref()) + elif (ptr_type == "device"): + p = DPPLmalloc_device(nbytes, queue.get_queue_ref()) + else: + raise RuntimeError("Pointer type is unknown: {}" \ + .format(ptr_type)) + + if (p): + self.memory_ptr = p + self.nbytes = nbytes + self.context = queue.get_sycl_context() + else: + raise RuntimeError("Null memory pointer returned") + else: + raise ValueError("Non-positive number of bytes found.") + + def __dealloc__(self): + if (self.memory_ptr): + DPPLfree_with_context(self.memory_ptr, + self.context.get_context_ref()) + self.memory_ptr = NULL + self.nbytes = 0 + self.context = None + + cdef _getbuffer(self, Py_buffer *buffer, int flags): + # memory_ptr is Ref which is pointer to SYCL type. For USM it is void*. + buffer.buf = self.memory_ptr + buffer.format = 'B' # byte + buffer.internal = NULL # see References + buffer.itemsize = 1 + buffer.len = self.nbytes + buffer.ndim = 1 + buffer.obj = self + buffer.readonly = 0 + buffer.shape = &self.nbytes + buffer.strides = &buffer.itemsize + buffer.suboffsets = NULL # for pointer arrays only + + property nbytes: + def __get__(self): + return self.nbytes + + property _context: + def __get__(self): + return self.context + + def __repr__(self): + return "" \ + .format(self.nbytes, hex((self.memory_ptr))) + + def _usm_type(self): + cdef const char* kind + kind = DPPLUSM_GetPointerType(self.memory_ptr, + self.context.get_context_ref()) + return kind.decode('UTF-8') + + +cdef class MemoryUSMShared(Memory): + + def __cinit__(self, Py_ssize_t nbytes, SyclQueue queue=None): + self._cinit(nbytes, "shared", queue) + + def __getbuffer__(self, Py_buffer *buffer, int flags): + self._getbuffer(buffer, flags) + + +cdef class MemoryUSMHost(Memory): + + def __cinit__(self, Py_ssize_t nbytes, SyclQueue queue=None): + self._cinit(nbytes, "host", queue) + + def __getbuffer__(self, Py_buffer *buffer, int flags): + self._getbuffer(buffer, flags) + + +cdef class MemoryUSMDevice(Memory): + + def __cinit__(self, Py_ssize_t nbytes, SyclQueue queue=None): + self._cinit(nbytes, "device", queue) diff --git a/dppl/_sycl_core.pxd b/dppl/_sycl_core.pxd new file mode 100644 index 0000000000..c4b8dd2ab1 --- /dev/null +++ b/dppl/_sycl_core.pxd @@ -0,0 +1,61 @@ +##===------------- sycl_core.pxd - DPPL interface ------*- Cython -*-------===## +## +## 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 the Cython interface for the Sycl API of PyDPPL. +## +##===----------------------------------------------------------------------===## + +from .backend cimport * + + +cdef class SyclContext: + ''' Wrapper class for a Sycl Context + ''' + cdef DPPLSyclContextRef ctxt_ptr + + @staticmethod + cdef SyclContext _create (DPPLSyclContextRef ctxt) + cdef DPPLSyclContextRef get_context_ref (self) + + +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 DPPLSyclDeviceRef get_device_ptr (self) + + +cdef class SyclQueue: + ''' Wrapper class for a Sycl queue. + ''' + cdef DPPLSyclQueueRef queue_ptr + + @staticmethod + cdef SyclQueue _create (DPPLSyclQueueRef qref) + cpdef SyclContext get_sycl_context (self) + cpdef SyclDevice get_sycl_device (self) + cdef DPPLSyclQueueRef get_queue_ref (self) diff --git a/dppl/backend.pxd b/dppl/backend.pxd new file mode 100644 index 0000000000..a427bbda3a --- /dev/null +++ b/dppl/backend.pxd @@ -0,0 +1,111 @@ +##===------------- backend.pyx - DPPL interface ------*- Cython -*-------===## +## +## 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 the Cython interface for the backend API of PyDPPL. +## +##===----------------------------------------------------------------------===## + +from libcpp cimport bool + + +cdef extern from "dppl_utils.h": + cdef void DPPLDeleteCString (const char *str) + + +cdef extern from "dppl_sycl_types.h": + cdef struct DPPLOpaqueSyclContext + cdef struct DPPLOpaqueSyclQueue + cdef struct DPPLOpaqueSyclDevice + cdef struct DPPLOpaqueSyclUSM + + ctypedef DPPLOpaqueSyclContext* DPPLSyclContextRef + ctypedef DPPLOpaqueSyclQueue* DPPLSyclQueueRef + ctypedef DPPLOpaqueSyclDevice* DPPLSyclDeviceRef + ctypedef DPPLOpaqueSyclUSM* DPPLSyclUSMRef + + +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 DPPLSyclQueueRef DPPLGetCurrentQueue () except + + cdef size_t DPPLGetNumCPUQueues () except + + cdef size_t DPPLGetNumGPUQueues () except + + cdef size_t DPPLGetNumActivatedQueues () except + + cdef DPPLSyclQueueRef DPPLGetQueue (_device_type DTy, + size_t device_num) except + + cdef void DPPLPopSyclQueue () except + + cdef DPPLSyclQueueRef DPPLPushSyclQueue (_device_type DTy, + size_t device_num) except + + cdef void DPPLSetAsDefaultQueue (_device_type DTy, + size_t device_num) except + + + +cdef extern from "dppl_sycl_usm_interface.h": + cdef DPPLSyclUSMRef DPPLmalloc_shared (size_t size, DPPLSyclQueueRef QRef) \ + except + + cdef DPPLSyclUSMRef DPPLmalloc_host (size_t size, DPPLSyclQueueRef QRef) \ + except + + cdef DPPLSyclUSMRef DPPLmalloc_device (size_t size, DPPLSyclQueueRef QRef) \ + except + + + cdef void DPPLfree_with_queue (DPPLSyclUSMRef MRef, + DPPLSyclQueueRef QRef) except + + cdef void DPPLfree_with_context (DPPLSyclUSMRef MRef, + DPPLSyclContextRef CRef) except + + + cdef const char* DPPLUSM_GetPointerType (DPPLSyclUSMRef MRef, + DPPLSyclContextRef CRef) except + diff --git a/dppl/sycl_core.pyx b/dppl/sycl_core.pyx index 1ed47334df..5df3af4367 100644 --- a/dppl/sycl_core.pyx +++ b/dppl/sycl_core.pyx @@ -29,10 +29,12 @@ from __future__ import print_function from enum import Enum, auto import logging -from libcpp cimport bool +from dppl.backend cimport * + _logger = logging.getLogger(__name__) + class device_type(Enum): gpu = auto() cpu = auto() @@ -44,71 +46,8 @@ cdef class UnsupportedDeviceTypeError(Exception): ''' pass -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 DPPLSyclQueueRef DPPLGetCurrentQueue () except + - cdef size_t DPPLGetNumCPUQueues () except + - cdef size_t DPPLGetNumGPUQueues () except + - cdef size_t DPPLGetNumActivatedQueues () except + - cdef DPPLSyclQueueRef DPPLGetQueue (_device_type DTy, - size_t device_num) except + - cdef void DPPLPopSyclQueue () except + - cdef DPPLSyclQueueRef DPPLPushSyclQueue (_device_type DTy, - size_t device_num) except + - cdef void DPPLSetAsDefaultQueue (_device_type DTy, - size_t device_num) except + - cdef class SyclContext: - cdef DPPLSyclContextRef ctxt_ptr @staticmethod cdef SyclContext _create (DPPLSyclContextRef ctxt): @@ -126,10 +65,6 @@ cdef class SyclContext: 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): @@ -178,7 +113,6 @@ cdef class SyclDevice: cdef class SyclQueue: ''' Wrapper class for a Sycl queue. ''' - cdef DPPLSyclQueueRef queue_ptr @staticmethod cdef SyclQueue _create (DPPLSyclQueueRef qref): @@ -189,10 +123,10 @@ cdef class SyclQueue: def __dealloc__ (self): DPPLDeleteSyclQueue(self.queue_ptr) - cpdef get_sycl_context (self): + cpdef SyclContext get_sycl_context (self): return SyclContext._create(DPPLGetContextFromQueue(self.queue_ptr)) - cpdef get_sycl_device (self): + cpdef SyclDevice get_sycl_device (self): return SyclDevice._create(DPPLGetDeviceFromQueue(self.queue_ptr)) cdef DPPLSyclQueueRef get_queue_ref (self): diff --git a/dppl/tests/__init__.py b/dppl/tests/__init__.py index b7d39c5dfd..6bd91b208f 100644 --- a/dppl/tests/__init__.py +++ b/dppl/tests/__init__.py @@ -1 +1,2 @@ from .test_dump_functions import * +from .dppl_tests import * diff --git a/dppl/tests/dppl_tests/__init__.py b/dppl/tests/dppl_tests/__init__.py index adcaad3954..dd992a0db9 100644 --- a/dppl/tests/dppl_tests/__init__.py +++ b/dppl/tests/dppl_tests/__init__.py @@ -1 +1,2 @@ -from .test_sycl_queue_manager import * \ No newline at end of file +from .test_sycl_queue_manager import * +from .test_sycl_usm import * diff --git a/dppl/tests/dppl_tests/test_sycl_usm.py b/dppl/tests/dppl_tests/test_sycl_usm.py new file mode 100644 index 0000000000..15bb397a9f --- /dev/null +++ b/dppl/tests/dppl_tests/test_sycl_usm.py @@ -0,0 +1,97 @@ +##===---------- test_sycl_queue_manager.py - dppl -------*- Python -*-----===## +## +## 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. +## +##===----------------------------------------------------------------------===## + +import unittest +import dppl +from dppl._memory import MemoryUSMShared, MemoryUSMHost, MemoryUSMDevice + + +class TestMemory (unittest.TestCase): + + def test_memory_create (self): + nbytes = 1024 + queue = dppl.get_current_queue() + mobj = MemoryUSMShared(nbytes, queue) + self.assertEqual(mobj.nbytes, nbytes) + + def _create_memory (self): + nbytes = 1024 + queue = dppl.get_current_queue() + mobj = MemoryUSMShared(nbytes, queue) + return mobj + + def test_memory_without_context (self): + mobj = self._create_memory() + + # Without context + self.assertEqual(mobj._usm_type(), 'shared') + + def test_memory_cpu_context (self): + mobj = self._create_memory() + + # CPU context + with dppl.device_context(dppl.device_type.cpu): + self.assertEqual(mobj._usm_type(), 'shared') + + def test_memory_gpu_context (self): + mobj = self._create_memory() + + # GPU context + with dppl.device_context(dppl.device_type.gpu): + self.assertEqual(mobj._usm_type(), 'shared') + + +class TestMemoryUSMBase: + """ Base tests for MemoryUSM* """ + + MemoryUSMClass = None + usm_type = None + + def test_create_with_queue (self): + q = dppl.get_current_queue() + m = self.MemoryUSMClass(1024, q) + self.assertEqual(m.nbytes, 1024) + self.assertEqual(m._usm_type(), self.usm_type) + + def test_create_without_queue (self): + m = self.MemoryUSMClass(1024) + self.assertEqual(m.nbytes, 1024) + self.assertEqual(m._usm_type(), self.usm_type) + + +class TestMemoryUSMShared(TestMemoryUSMBase, unittest.TestCase): + """ Tests for MemoryUSMShared """ + + MemoryUSMClass = MemoryUSMShared + usm_type = 'shared' + + +class TestMemoryUSMHost(TestMemoryUSMBase, unittest.TestCase): + """ Tests for MemoryUSMHost """ + + MemoryUSMClass = MemoryUSMHost + usm_type = 'host' + + +class TestMemoryUSMDevice(TestMemoryUSMBase, unittest.TestCase): + """ Tests for MemoryUSMDevice """ + + MemoryUSMClass = MemoryUSMDevice + usm_type = 'device' diff --git a/setup.py b/setup.py index a7c209ee3c..2a90338032 100644 --- a/setup.py +++ b/setup.py @@ -25,8 +25,8 @@ import sys import versioneer -from Cython.Build import cythonize from setuptools import setup, Extension, find_packages +from Cython.Build import cythonize import numpy as np @@ -78,7 +78,7 @@ def get_other_cxxflags(): # what compiler we are using. return ['/Ox', '/std:c++17'] -def getpyexts(): +def extensions(): # Security flags eca = get_sdl_cflags() ela = get_sdl_ldflags() @@ -104,17 +104,22 @@ def getpyexts(): elif IS_WIN: runtime_library_dirs = [] - exts = cythonize(Extension('dppl._sycl_core', - [os.path.abspath('dppl/sycl_core.pyx'),], - depends=[dppl_sycl_interface_include,], - include_dirs=[np.get_include(), - dppl_sycl_interface_include], - extra_compile_args=eca + get_other_cxxflags(), - extra_link_args=ela, - libraries=libs, - library_dirs=librarys, - runtime_library_dirs=runtime_library_dirs, - language='c++')) + extension_args = { + "depends": [dppl_sycl_interface_include,], + "include_dirs": [np.get_include(), dppl_sycl_interface_include], + "extra_compile_args": eca + get_other_cxxflags(), + "extra_link_args": ela, "libraries": libs, "library_dirs": librarys, + "runtime_library_dirs": runtime_library_dirs, "language": 'c++', + } + + extensions = [ + Extension('dppl._sycl_core', [os.path.abspath('dppl/sycl_core.pyx'),], + **extension_args), + Extension('dppl._memory', [os.path.abspath('dppl/_memory.pyx'),], + **extension_args), + ] + + exts = cythonize(extensions) return exts setup( @@ -126,7 +131,7 @@ def getpyexts(): author="Intel Corporation", url='https://github.com/IntelPython/PyDPPL', packages=find_packages(include=["dppl", "dppl.*"]), - ext_modules = getpyexts(), + ext_modules = extensions(), setup_requires=requirements, cffi_modules=[ "./dppl/opencl_core.py:ffi"