Skip to content

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 41 commits into from
Sep 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
defc264
Move _memory.pyx
PokhodenkoSA Sep 15, 2020
8b811c5
Import setuptools before Cython. Otherwise, both might disagree about…
PokhodenkoSA Sep 15, 2020
0704258
Add dppl._memory Cython module.
PokhodenkoSA Sep 15, 2020
e57927d
Run dppl/tests/dppl_tests too when run all unit tests.
PokhodenkoSA Sep 15, 2020
267492f
Add tests for memory manager.
PokhodenkoSA Sep 15, 2020
5ff3eb0
Split tests for memory. One test one context (no, CPU, GPU).
PokhodenkoSA Sep 15, 2020
902bc8a
[opt] Rename getpyexts() to extensions().
PokhodenkoSA Sep 15, 2020
5d81879
Adds C and Cython API for portions of Sycl queue, device, context int…
diptorupd Sep 15, 2020
758aacc
Add C-API stub library for sycl memory.
PokhodenkoSA Sep 16, 2020
35a4674
Add missing DPPL_API.
diptorupd Sep 16, 2020
7bb5faf
Move platform specific functions into a separate file.
diptorupd Sep 16, 2020
4a11490
Create a single utility function to delete C strings.
diptorupd Sep 16, 2020
6e246fb
Update backends/source/dppl_utils.cpp
PokhodenkoSA Sep 17, 2020
97b53ca
Merge branch 'pr/30' into feature/usm
PokhodenkoSA Sep 17, 2020
abcf6f3
Add _sycl_core.pxd file.
PokhodenkoSA Sep 17, 2020
039b794
Remove using of PyCapsule in _memory.pyx.
PokhodenkoSA Sep 17, 2020
dc72b03
Small style fixes in _memory.pyx.
PokhodenkoSA Sep 17, 2020
b5ab5d6
Moved functions from _memory.pyx to C-API interface library.
PokhodenkoSA Sep 17, 2020
c57c05c
Move Cython definitions for backend to single pxd file.
PokhodenkoSA Sep 17, 2020
c075f0c
Remove SyclQueue from _memory.pyx
PokhodenkoSA Sep 17, 2020
708fd1f
Use SyclQueue from
PokhodenkoSA Sep 17, 2020
5d3db20
Remove cl::sycl::queue from _memory.pyx
PokhodenkoSA Sep 17, 2020
6747080
Removed commented code from _memory.pyx
PokhodenkoSA Sep 17, 2020
56241ef
Eliminate temporary context object.
PokhodenkoSA Sep 17, 2020
7fabbe4
Fix style.
PokhodenkoSA Sep 17, 2020
abd373b
Add MemoryUSM* classes.
PokhodenkoSA Sep 18, 2020
ba3e497
Add __getbuffer__ to Shared and Host MemoryUSM classes.
PokhodenkoSA Sep 18, 2020
00d63b0
Rename C-API types for USM.
PokhodenkoSA Sep 18, 2020
28f0496
Add DPPLUSM_GetPointerType and remove types from CL/sycl.hpp from _me…
PokhodenkoSA Sep 18, 2020
80cec2a
Clean unused code from _memory_.pyx
PokhodenkoSA Sep 18, 2020
debc2eb
Merge branch 'master' into feature/usm
PokhodenkoSA Sep 18, 2020
8ef95df
Small fixes.
PokhodenkoSA Sep 18, 2020
fa585da
Remove unused code.
PokhodenkoSA Sep 18, 2020
533e74b
Fix style.
PokhodenkoSA Sep 18, 2020
ab7a9ba
Fix style
PokhodenkoSA Sep 18, 2020
b5674b4
Use wrap().
PokhodenkoSA Sep 19, 2020
5e93d6e
Store context instead of queue in Memory class.
PokhodenkoSA Sep 19, 2020
6bd1756
Pass queue as parameter to constructor. If queue is None then get dpp…
PokhodenkoSA Sep 19, 2020
1333676
Add comment about casting memory_ptr to char*.
PokhodenkoSA Sep 19, 2020
b82eab5
Remove pointer property from Memory.
PokhodenkoSA Sep 19, 2020
1b5f804
Rename file with usm tests.
PokhodenkoSA Sep 19, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backends/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)

Expand Down
7 changes: 7 additions & 0 deletions backends/include/dppl_sycl_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
89 changes: 89 additions & 0 deletions backends/include/dppl_sycl_usm_interface.h
Original file line number Diff line number Diff line change
@@ -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
101 changes: 101 additions & 0 deletions backends/source/dppl_sycl_usm_interface.cpp
Original file line number Diff line number Diff line change
@@ -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 <CL/sycl.hpp> /* 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";
}
}
105 changes: 105 additions & 0 deletions dppl/_memory.pyx
Original file line number Diff line number Diff line change
@@ -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 = <char *>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 "<Intel(R) USM allocated memory block of {} bytes at {}>" \
.format(self.nbytes, hex(<object>(<Py_ssize_t>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)
61 changes: 61 additions & 0 deletions dppl/_sycl_core.pxd
Original file line number Diff line number Diff line change
@@ -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)
Loading