Skip to content

Feature/sycl context #334

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 22 commits into from
Mar 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
81f6323
Added DPCTLDeviceVector_CreateFromArray
oleksandr-pavlyk Mar 24, 2021
79f3197
Added constructor for SyclContext
oleksandr-pavlyk Mar 24, 2021
b57009f
Added DPCTLContext_GetDevices(CRef)
oleksandr-pavlyk Mar 25, 2021
7738442
SyclContext.get_devices added
oleksandr-pavlyk Mar 25, 2021
db3c527
added some tests for sycl context
oleksandr-pavlyk Mar 25, 2021
d8e129b
Added __repr__
oleksandr-pavlyk Mar 25, 2021
490efd0
clang-format ran on dpctl-capi changes
oleksandr-pavlyk Mar 25, 2021
a8b45e9
Added DPCTLContext_DeviceCount
oleksandr-pavlyk Mar 25, 2021
bc644b7
Used DPCTLContext_DeviceCount for effiency and to simplify code
oleksandr-pavlyk Mar 25, 2021
0a389b2
SyclQueue/SyclContext constructor from device change
oleksandr-pavlyk Mar 26, 2021
9fe57dc
Added handling of returned error code
oleksandr-pavlyk Mar 26, 2021
e889a00
DPCTLContext_GetDevices checks for runtime_error per PR review
oleksandr-pavlyk Mar 26, 2021
0cf32b9
NULL-initialized DVRef
oleksandr-pavlyk Mar 26, 2021
02481f3
Marking *elem with __dpctl_keep per review
oleksandr-pavlyk Mar 26, 2021
feeaf8e
Change device_count to a property
oleksandr-pavlyk Mar 26, 2021
51bbb9e
Added docstring for _create explaining that it deleted arg
oleksandr-pavlyk Mar 29, 2021
d3a2493
Fixed build break by removing use of DeviceAndContextPair
oleksandr-pavlyk Mar 29, 2021
fb0b8f0
Added doc string for _create method
oleksandr-pavlyk Mar 29, 2021
cb88f4f
simplification of test_sycl_context_interface per PR feedback
oleksandr-pavlyk Mar 31, 2021
fe5782b
removed catch of bad_alloc per PR feedback
oleksandr-pavlyk Mar 31, 2021
fdfbe1b
DPCTLDeviceVector_CreateFromArray now copies devices too
oleksandr-pavlyk Mar 31, 2021
f5846cf
Since DPCTLDeviceVector_CreateFromArray makes copies of devices
oleksandr-pavlyk Mar 31, 2021
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
21 changes: 21 additions & 0 deletions dpctl-capi/include/dpctl_sycl_context_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,27 @@ DPCTL_API
__dpctl_give DPCTLSyclContextRef
DPCTLContext_Copy(__dpctl_keep const DPCTLSyclContextRef CRef);

/*!
* @brief Returns the number of devices associated with sycl::context referenced
* by DPCTLSyclContextRef object.
*
* @param CRef DPCTLSyclContexRef object to query.
* @return A positive count on success or zero on error.
*/
DPCTL_API
size_t DPCTLContext_DeviceCount(__dpctl_keep const DPCTLSyclContextRef CRef);

/*!
* @brief Returns a vector of devices associated with sycl::context referenced
* by DPCTLSyclContextRef object.
*
* @param CRef DPCTLSyclContexRef object to query.
* @return A DPCTLDeviceVectorRef with devices associated with given CRef.
*/
DPCTL_API
__dpctl_give DPCTLDeviceVectorRef
DPCTLContext_GetDevices(__dpctl_keep const DPCTLSyclContextRef CRef);

/*!
* @brief Returns true if this SYCL context is a host context.
*
Expand Down
4 changes: 4 additions & 0 deletions dpctl-capi/include/dpctl_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ DPCTL_C_EXTERN_C_BEGIN
__dpctl_give DPCTL##EL##VectorRef DPCTL##EL##Vector_Create(); \
\
DPCTL_API \
__dpctl_give DPCTL##EL##VectorRef DPCTL##EL##Vector_CreateFromArray( \
size_t len, __dpctl_keep DPCTLSycl##EL##Ref *elems); \
\
DPCTL_API \
void DPCTL##EL##Vector_Delete(__dpctl_take DPCTL##EL##VectorRef Ref); \
\
DPCTL_API \
Expand Down
47 changes: 47 additions & 0 deletions dpctl-capi/source/dpctl_sycl_context_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,53 @@ DPCTLContext_Copy(__dpctl_keep const DPCTLSyclContextRef CRef)
}
}

__dpctl_give DPCTLDeviceVectorRef
DPCTLContext_GetDevices(__dpctl_keep const DPCTLSyclContextRef CRef)
{
auto Context = unwrap(CRef);
if (!Context) {
std::cerr << "Can not retrieve devices from DPCTLSyclContextRef as "
"input is a nullptr\n";
return nullptr;
}
vector_class<DPCTLSyclDeviceRef> *DevicesVectorPtr = nullptr;
try {
DevicesVectorPtr = new vector_class<DPCTLSyclDeviceRef>();
} catch (std::bad_alloc const &ba) {
// \todo log error
std::cerr << ba.what() << '\n';
return nullptr;
}
try {
auto Devices = Context->get_devices();
DevicesVectorPtr->reserve(Devices.size());
for (const auto &Dev : Devices) {
DevicesVectorPtr->emplace_back(wrap(new device(Dev)));
}
return wrap(DevicesVectorPtr);
} catch (std::bad_alloc const &ba) {
// \todo log error
std::cerr << ba.what() << '\n';
return nullptr;
} catch (const runtime_error &re) {
// \todo log error
std::cerr << re.what() << '\n';
return nullptr;
}
}

size_t DPCTLContext_DeviceCount(__dpctl_keep const DPCTLSyclContextRef CRef)
{
auto Context = unwrap(CRef);
if (!Context) {
std::cerr << "Can not retrieve devices from DPCTLSyclContextRef as "
"input is a nullptr\n";
return 0;
}
const auto Devices = Context->get_devices();
return Devices.size();
}

bool DPCTLContext_IsHost(__dpctl_keep const DPCTLSyclContextRef CtxRef)
{
auto Ctx = unwrap(CtxRef);
Expand Down
22 changes: 22 additions & 0 deletions dpctl-capi/source/dpctl_vector_templ.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,28 @@ __dpctl_give VECTOR(EL) FN(EL, Create)()
}
}

/*!
* @brief Creates a new std::vector of the opaque SYCL pointer types from given
* C array with deep copy.
*
* @return A new dynamically allocated std::vector of opaque pointer types.
*/
__dpctl_give VECTOR(EL)
FN(EL, CreateFromArray)(size_t n, __dpctl_keep SYCLREF(EL) * elems)
{
try {
auto Vec = new vector_class<SYCLREF(EL)>();
for (size_t i = 0; i < n; ++i) {
auto Ref = unwrap(elems[i]);
Vec->emplace_back(
wrap(new std::remove_pointer<decltype(Ref)>::type(*Ref)));
}
return wrap(Vec);
} catch (std::bad_alloc const &ba) {
return nullptr;
}
}

/*!
* @brief Frees all the elements of the passed in std::vector and then frees the
* std::vector pointer.
Expand Down
89 changes: 60 additions & 29 deletions dpctl-capi/tests/test_sycl_context_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,20 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(vector_class<DPCTLSyclDeviceRef>,

struct TestDPCTLContextInterface : public ::testing::TestWithParam<const char *>
{
DPCTLSyclDeviceSelectorRef DSRef = nullptr;
DPCTLSyclDeviceRef DRef = nullptr;

TestDPCTLContextInterface()
{
EXPECT_NO_FATAL_FAILURE(DSRef = DPCTLFilterSelector_Create(GetParam()));
auto DS = DPCTLFilterSelector_Create(GetParam());
if (DS) {
EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DS));
}
DPCTLDeviceSelector_Delete(DS);
}

void SetUp()
{
if (!DSRef) {
if (!DRef) {
auto message = "Skipping as no device of type " +
std::string(GetParam()) + ".";
GTEST_SKIP_(message.c_str());
Expand All @@ -61,32 +65,23 @@ struct TestDPCTLContextInterface : public ::testing::TestWithParam<const char *>

~TestDPCTLContextInterface()
{
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceSelector_Delete(DSRef));
EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
}
};

TEST_P(TestDPCTLContextInterface, Chk_Create)
{
DPCTLSyclContextRef CRef = nullptr;
DPCTLSyclDeviceRef DRef = nullptr;
EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef));
if (!DRef)
GTEST_SKIP_("Device not found");
EXPECT_NO_FATAL_FAILURE(CRef = DPCTLContext_Create(DRef, nullptr, 0));
ASSERT_TRUE(CRef);
EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
}

TEST_P(TestDPCTLContextInterface, Chk_CreateWithDevices)
{
size_t nCUs = 0;
DPCTLSyclContextRef CRef = nullptr;
DPCTLSyclDeviceRef DRef = nullptr;
DPCTLDeviceVectorRef DVRef = nullptr;
EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef));
if (!DRef)
GTEST_SKIP_("Device not found");

/* TODO: Once we have wrappers for sub-device creation let us use those
* functions.
Expand All @@ -108,20 +103,67 @@ TEST_P(TestDPCTLContextInterface, Chk_CreateWithDevices)
GTEST_SKIP_("Skipping creating context for sub-devices");
}
}
EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceVector_Delete(DVRef));
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
}

TEST_P(TestDPCTLContextInterface, Chk_CreateWithDevices_GetDevices)
{
size_t nCUs = 0;
DPCTLSyclContextRef CRef = nullptr;
DPCTLDeviceVectorRef DVRef = nullptr;
DPCTLDeviceVectorRef Res_DVRef = nullptr;

/* TODO: Once we have wrappers for sub-device creation let us use those
* functions.
*/
EXPECT_NO_FATAL_FAILURE(nCUs = DPCTLDevice_GetMaxComputeUnits(DRef));
if (nCUs) {
auto D = unwrap(DRef);
try {
auto subDevices = D->create_sub_devices<
info::partition_property::partition_equally>(nCUs / 2);
const size_t len = subDevices.size();
auto ar = new DPCTLSyclDeviceRef[len];
for (size_t i = 0; i < len; ++i) {
ar[i] = wrap(&subDevices.at(i));
}
EXPECT_NO_FATAL_FAILURE(
DVRef = DPCTLDeviceVector_CreateFromArray(len, ar));
EXPECT_NO_FATAL_FAILURE(
CRef = DPCTLContext_CreateFromDevices(DVRef, nullptr, 0));
ASSERT_TRUE(CRef);
ASSERT_TRUE(DPCTLContext_DeviceCount(CRef) == len);
EXPECT_NO_FATAL_FAILURE(Res_DVRef = DPCTLContext_GetDevices(CRef));
ASSERT_TRUE(DPCTLDeviceVector_Size(Res_DVRef) == len);
delete[] ar;
} catch (feature_not_supported const &fnse) {
GTEST_SKIP_("Skipping creating context for sub-devices");
}
}
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceVector_Delete(DVRef));
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceVector_Delete(Res_DVRef));
}

TEST_P(TestDPCTLContextInterface, Chk_GetDevices)
{
DPCTLSyclContextRef CRef = nullptr;
DPCTLDeviceVectorRef DVRef = nullptr;
EXPECT_NO_FATAL_FAILURE(CRef = DPCTLContext_Create(DRef, nullptr, 0));
ASSERT_TRUE(CRef);
EXPECT_NO_FATAL_FAILURE(DVRef = DPCTLContext_GetDevices(CRef));
ASSERT_TRUE(DVRef);
EXPECT_TRUE(DPCTLDeviceVector_Size(DVRef) == 1);
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceVector_Delete(DVRef));
}

TEST_P(TestDPCTLContextInterface, Chk_AreEq)
{
DPCTLSyclContextRef CRef1 = nullptr, CRef2 = nullptr, CRef3 = nullptr;
DPCTLSyclDeviceRef DRef = nullptr;
bool are_eq = true, are_not_eq = false;

EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef));
if (!DRef)
GTEST_SKIP_("Device not found");
EXPECT_NO_FATAL_FAILURE(CRef1 = DPCTLContext_Create(DRef, nullptr, 0));
EXPECT_NO_FATAL_FAILURE(CRef2 = DPCTLContext_Copy(CRef1));
// TODO: This work till DPC++ does not have a default context per device,
Expand All @@ -136,7 +178,6 @@ TEST_P(TestDPCTLContextInterface, Chk_AreEq)
EXPECT_TRUE(are_eq);
EXPECT_FALSE(are_not_eq);

EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef1));
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef2));
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef3));
Expand All @@ -145,41 +186,31 @@ TEST_P(TestDPCTLContextInterface, Chk_AreEq)
TEST_P(TestDPCTLContextInterface, Chk_IsHost)
{
DPCTLSyclContextRef CRef = nullptr;
DPCTLSyclDeviceRef DRef = nullptr;
bool is_host_device = false, is_host_context = false;

EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef));
if (!DRef)
GTEST_SKIP_("Device not found");
EXPECT_NO_FATAL_FAILURE(CRef = DPCTLContext_Create(DRef, nullptr, 0));
ASSERT_TRUE(CRef);

EXPECT_NO_FATAL_FAILURE(is_host_device = DPCTLDevice_IsHost(DRef));
EXPECT_NO_FATAL_FAILURE(is_host_context = DPCTLContext_IsHost(CRef));
EXPECT_TRUE(is_host_device == is_host_context);

EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
}

TEST_P(TestDPCTLContextInterface, Chk_GetBackend)
{
DPCTLSyclContextRef CRef = nullptr;
DPCTLSyclDeviceRef DRef = nullptr;
DPCTLSyclBackendType context_backend = DPCTL_UNKNOWN_BACKEND,
device_backend = DPCTL_UNKNOWN_BACKEND;

EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef));
if (!DRef)
GTEST_SKIP_("Device not found");
EXPECT_NO_FATAL_FAILURE(CRef = DPCTLContext_Create(DRef, nullptr, 0));
ASSERT_TRUE(CRef);

EXPECT_NO_FATAL_FAILURE(device_backend = DPCTLDevice_GetBackend(DRef));
EXPECT_NO_FATAL_FAILURE(context_backend = DPCTLContext_GetBackend(CRef));
EXPECT_TRUE(device_backend == context_backend);

EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
}

Expand Down
16 changes: 16 additions & 0 deletions dpctl/_backend.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ cdef extern from "dpctl_sycl_device_interface.h":
cdef extern from "dpctl_sycl_device_manager.h":
cdef struct DPCTLDeviceVector
ctypedef DPCTLDeviceVector *DPCTLDeviceVectorRef
cdef DPCTLDeviceVectorRef DPCTLDeviceVector_CreateFromArray(
size_t nelems,
DPCTLSyclDeviceRef *elems)
cdef void DPCTLDeviceVector_Delete(DPCTLDeviceVectorRef DVRef)
cdef void DPCTLDeviceVector_Clear(DPCTLDeviceVectorRef DVRef)
cdef size_t DPCTLDeviceVector_Size(DPCTLDeviceVectorRef DVRef)
Expand Down Expand Up @@ -231,6 +234,19 @@ cdef extern from "dpctl_sycl_platform_interface.h":


cdef extern from "dpctl_sycl_context_interface.h":
cdef DPCTLSyclContextRef DPCTLContext_Create(
const DPCTLSyclDeviceRef DRef,
error_handler_callback *error_handler,
int properties)
cdef DPCTLSyclContextRef DPCTLContext_CreateFromDevices(
const DPCTLDeviceVectorRef DVRef,
error_handler_callback *error_handler,
int properties)
cdef DPCTLSyclContextRef DPCTLContext_Copy(
const DPCTLSyclContextRef CRef)
cdef DPCTLDeviceVectorRef DPCTLContext_GetDevices(
const DPCTLSyclContextRef CRef)
cdef size_t DPCTLContext_DeviceCount(const DPCTLSyclContextRef CRef)
cdef bool DPCTLContext_AreEq(const DPCTLSyclContextRef CtxRef1,
const DPCTLSyclContextRef CtxRef2)
cdef DPCTLSyclBackendType DPCTLContext_GetBackend(
Expand Down
16 changes: 13 additions & 3 deletions dpctl/_sycl_context.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,25 @@
"""

from ._backend cimport DPCTLSyclContextRef
from ._sycl_device cimport SyclDevice
from libcpp cimport bool

cdef class _SyclContext:
""" Data owner for SyclContext
"""
cdef DPCTLSyclContextRef _ctxt_ref


cdef class SyclContext:
cdef class SyclContext(_SyclContext):
''' Wrapper class for a Sycl Context
'''
cdef DPCTLSyclContextRef _ctxt_ref

@staticmethod
cdef SyclContext _create (DPCTLSyclContextRef ctxt)
cdef SyclContext _create (DPCTLSyclContextRef CRef)
@staticmethod
cdef void _init_helper(_SyclContext self, DPCTLSyclContextRef CRef)
cdef int _init_from__SyclContext(self, _SyclContext other)
cdef int _init_from_one_device(self, SyclDevice device, int props)
cdef int _init_from_devices(self, object devices, int props)
cpdef bool equals (self, SyclContext ctxt)
cdef DPCTLSyclContextRef get_context_ref (self)
Loading