-
Notifications
You must be signed in to change notification settings - Fork 32
Implementing USM memory management #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 7 commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
defc264
Move _memory.pyx
PokhodenkoSA 8b811c5
Import setuptools before Cython. Otherwise, both might disagree about…
PokhodenkoSA 0704258
Add dppl._memory Cython module.
PokhodenkoSA e57927d
Run dppl/tests/dppl_tests too when run all unit tests.
PokhodenkoSA 267492f
Add tests for memory manager.
PokhodenkoSA 5ff3eb0
Split tests for memory. One test one context (no, CPU, GPU).
PokhodenkoSA 902bc8a
[opt] Rename getpyexts() to extensions().
PokhodenkoSA 5d81879
Adds C and Cython API for portions of Sycl queue, device, context int…
diptorupd 758aacc
Add C-API stub library for sycl memory.
PokhodenkoSA 35a4674
Add missing DPPL_API.
diptorupd 7bb5faf
Move platform specific functions into a separate file.
diptorupd 4a11490
Create a single utility function to delete C strings.
diptorupd 6e246fb
Update backends/source/dppl_utils.cpp
PokhodenkoSA 97b53ca
Merge branch 'pr/30' into feature/usm
PokhodenkoSA abcf6f3
Add _sycl_core.pxd file.
PokhodenkoSA 039b794
Remove using of PyCapsule in _memory.pyx.
PokhodenkoSA dc72b03
Small style fixes in _memory.pyx.
PokhodenkoSA b5ab5d6
Moved functions from _memory.pyx to C-API interface library.
PokhodenkoSA c57c05c
Move Cython definitions for backend to single pxd file.
PokhodenkoSA c075f0c
Remove SyclQueue from _memory.pyx
PokhodenkoSA 708fd1f
Use SyclQueue from
PokhodenkoSA 5d3db20
Remove cl::sycl::queue from _memory.pyx
PokhodenkoSA 6747080
Removed commented code from _memory.pyx
PokhodenkoSA 56241ef
Eliminate temporary context object.
PokhodenkoSA 7fabbe4
Fix style.
PokhodenkoSA abd373b
Add MemoryUSM* classes.
PokhodenkoSA ba3e497
Add __getbuffer__ to Shared and Host MemoryUSM classes.
PokhodenkoSA 00d63b0
Rename C-API types for USM.
PokhodenkoSA 28f0496
Add DPPLUSM_GetPointerType and remove types from CL/sycl.hpp from _me…
PokhodenkoSA 80cec2a
Clean unused code from _memory_.pyx
PokhodenkoSA debc2eb
Merge branch 'master' into feature/usm
PokhodenkoSA 8ef95df
Small fixes.
PokhodenkoSA fa585da
Remove unused code.
PokhodenkoSA 533e74b
Fix style.
PokhodenkoSA ab7a9ba
Fix style
PokhodenkoSA b5674b4
Use wrap().
PokhodenkoSA 5e93d6e
Store context instead of queue in Memory class.
PokhodenkoSA 6bd1756
Pass queue as parameter to constructor. If queue is None then get dpp…
PokhodenkoSA 1333676
Add comment about casting memory_ptr to char*.
PokhodenkoSA b82eab5
Remove pointer property from Memory.
PokhodenkoSA 1b5f804
Rename file with usm tests.
PokhodenkoSA File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| import dppl | ||
|
|
||
| from cython.operator cimport dereference as deref | ||
|
|
||
| from cpython.pycapsule cimport PyCapsule_GetPointer | ||
| from cpython cimport Py_buffer | ||
|
|
||
| cdef extern from "CL/sycl.hpp" namespace "cl::sycl::usm": | ||
| cdef enum alloc: | ||
| host 'cl::sycl::usm::alloc::host' | ||
| device 'cl::sycl::usm::alloc::device' | ||
| shared 'cl::sycl::usm::alloc::shared' | ||
| unknown 'cl::sycl::usm::alloc::unknown' | ||
|
|
||
| cdef extern from "CL/sycl.hpp" namespace "cl::sycl": | ||
| cdef cppclass context nogil: | ||
| pass | ||
|
|
||
| cdef cppclass queue nogil: | ||
| context get_context() nogil | ||
| pass | ||
|
|
||
| cdef void* malloc_shared(Py_ssize_t, queue&) nogil | ||
| cdef void free(void *, queue&) nogil | ||
| cdef alloc get_pointer_type(void *, context&) nogil | ||
|
|
||
|
|
||
| cdef class SyclQueue: | ||
| cdef object queue_cap | ||
| cdef queue q | ||
|
|
||
| def __cinit__(self): | ||
| cdef void* q_ptr | ||
| self.queue_cap = dppl.get_current_queue() | ||
| q_ptr = PyCapsule_GetPointer(self.queue_cap, NULL) | ||
| if (q_ptr): | ||
| self.q = deref(<queue *>q_ptr) | ||
| else: | ||
| raise ValueError("NULL pointer returned by the Capsule") | ||
|
|
||
| def get_pointer_type(self, Py_ssize_t p): | ||
PokhodenkoSA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| cdef context ctx = self.q.get_context() | ||
| cdef void * p_ptr = <void *> p | ||
|
|
||
| ptr_type = get_pointer_type(p_ptr, ctx) | ||
| if (ptr_type == alloc.shared): | ||
| return "shared" | ||
| elif (ptr_type == alloc.host): | ||
| return "host" | ||
| elif (ptr_type == alloc.device): | ||
| return "device" | ||
| else: | ||
| return "unknown" | ||
|
|
||
| property get_capsule: | ||
| def __get__(self): | ||
| return self.queue_cap | ||
|
|
||
| cdef queue get_queue(self): | ||
| return self.q | ||
|
|
||
|
|
||
| cdef class Memory: | ||
| cdef void* _ptr | ||
| cdef Py_ssize_t nbytes | ||
| cdef object queue_cap | ||
|
|
||
| def __cinit__(self, Py_ssize_t nbytes): | ||
| cdef object q_cap | ||
| cdef void* queue_ptr | ||
| cdef void* p | ||
|
|
||
| self._ptr = NULL | ||
| self.queue_cap = None | ||
| self.nbytes = 0 | ||
|
|
||
| if (nbytes > 0): | ||
| q_cap = dppl.get_current_queue() | ||
| queue_ptr = PyCapsule_GetPointer(q_cap, NULL) | ||
| p = malloc_shared(nbytes, deref(<queue *>queue_ptr)) | ||
| if (p): | ||
| self._ptr = p | ||
| self.nbytes = nbytes | ||
| self.queue_cap = q_cap | ||
| else: | ||
| raise RuntimeError("Null memory pointer returned") | ||
| else: | ||
| raise ValueError("Non-positive number of bytes found.") | ||
|
|
||
| def __dealloc__(self): | ||
| cdef void* queue_ptr | ||
|
|
||
| if (self._ptr): | ||
| queue_ptr = PyCapsule_GetPointer(self.queue_cap, NULL) | ||
| free(self._ptr, deref(<queue *>queue_ptr)) | ||
| self._ptr = NULL | ||
| self.nbytes = 0 | ||
| self.queue_cap = None | ||
|
|
||
| def __getbuffer__(self, Py_buffer *buffer, int flags): | ||
| buffer.buf = <char *>self._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 pointer: | ||
| def __get__(self): | ||
| return <object>(<Py_ssize_t>self._ptr) | ||
|
|
||
| property nbytes: | ||
| def __get__(self): | ||
| return self.nbytes | ||
|
|
||
| property _queue: | ||
| def __get__(self): | ||
| return self.queue_cap | ||
|
|
||
| def __repr__(self): | ||
| return "<Intel(R) USM allocated memory block of {} bytes at {}>".format(self.nbytes, hex(<object>(<Py_ssize_t>self._ptr))) | ||
PokhodenkoSA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| def _usm_type(self, qcaps=None): | ||
| cdef void *q_ptr | ||
| cdef alloc ptr_type | ||
|
|
||
| _cap = qcaps if (qcaps) else self.queue_cap | ||
| q_ptr = PyCapsule_GetPointer(_cap, NULL) | ||
| ptr_type = get_pointer_type(self._ptr, deref(<queue*>q_ptr).get_context()) | ||
| if (ptr_type == alloc.shared): | ||
| return "shared" | ||
| elif (ptr_type == alloc.host): | ||
| return "host" | ||
| elif (ptr_type == alloc.device): | ||
| return "device" | ||
| else: | ||
| return "unknown" | ||
|
|
||
| # cdef void* _ptr | ||
| # cdef Py_ssize_t nbytes | ||
| # cdef object queue_cap | ||
|
|
||
| @staticmethod | ||
| cdef Memory create(void *p, Py_ssize_t nbytes, object queue_cap): | ||
| cdef Memory ret = Memory.__new__() | ||
| ret._ptr = p | ||
| ret.nbytes = nbytes | ||
| ret.q_cap = queue_cap | ||
| return ret | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| from .test_dump_functions import * | ||
| from .dppl_tests import * |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| from .test_sycl_queue_manager import * | ||
| from .test_sycl_queue_manager import * | ||
| from .test_sycl_memory_manager import * | ||
PokhodenkoSA marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| ##===---------- 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 | ||
| import dppl._memory as mem | ||
|
|
||
|
|
||
| class TestMemory (unittest.TestCase): | ||
| # @unittest.skipIf(not dppl.has_sycl_platforms, "No SYCL platforms available") | ||
| def test_memory_create (self): | ||
| nbytes = 1024 | ||
| mobj = mem.Memory(nbytes) | ||
| self.assertEqual(mobj.nbytes, nbytes) | ||
|
|
||
| def _create_memory (self): | ||
| nbytes = 1024 | ||
| mobj = mem.Memory(nbytes) | ||
| return mobj | ||
|
|
||
| def test_memory_without_context (self): | ||
| mobj = self._create_memory() | ||
|
|
||
| # Without context | ||
| self.assertEqual(mem.SyclQueue().get_pointer_type(mobj.pointer), 'shared') | ||
| 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(mem.SyclQueue().get_pointer_type(mobj.pointer), 'unknown') | ||
| 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(mem.SyclQueue().get_pointer_type(mobj.pointer), 'unknown') | ||
| self.assertEqual(mobj._usm_type(), 'shared') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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'),], | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename |
||
| **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" | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.