Skip to content

Commit ec0de51

Browse files
author
Diptorup Deb
authored
Merge pull request #334 from IntelPython/feature/SyclContext
Feature/sycl context
2 parents de3c856 + f5846cf commit ec0de51

13 files changed

+764
-47
lines changed

dpctl-capi/include/dpctl_sycl_context_interface.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,27 @@ DPCTL_API
9999
__dpctl_give DPCTLSyclContextRef
100100
DPCTLContext_Copy(__dpctl_keep const DPCTLSyclContextRef CRef);
101101

102+
/*!
103+
* @brief Returns the number of devices associated with sycl::context referenced
104+
* by DPCTLSyclContextRef object.
105+
*
106+
* @param CRef DPCTLSyclContexRef object to query.
107+
* @return A positive count on success or zero on error.
108+
*/
109+
DPCTL_API
110+
size_t DPCTLContext_DeviceCount(__dpctl_keep const DPCTLSyclContextRef CRef);
111+
112+
/*!
113+
* @brief Returns a vector of devices associated with sycl::context referenced
114+
* by DPCTLSyclContextRef object.
115+
*
116+
* @param CRef DPCTLSyclContexRef object to query.
117+
* @return A DPCTLDeviceVectorRef with devices associated with given CRef.
118+
*/
119+
DPCTL_API
120+
__dpctl_give DPCTLDeviceVectorRef
121+
DPCTLContext_GetDevices(__dpctl_keep const DPCTLSyclContextRef CRef);
122+
102123
/*!
103124
* @brief Returns true if this SYCL context is a host context.
104125
*

dpctl-capi/include/dpctl_vector.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ DPCTL_C_EXTERN_C_BEGIN
4141
__dpctl_give DPCTL##EL##VectorRef DPCTL##EL##Vector_Create(); \
4242
\
4343
DPCTL_API \
44+
__dpctl_give DPCTL##EL##VectorRef DPCTL##EL##Vector_CreateFromArray( \
45+
size_t len, __dpctl_keep DPCTLSycl##EL##Ref *elems); \
46+
\
47+
DPCTL_API \
4448
void DPCTL##EL##Vector_Delete(__dpctl_take DPCTL##EL##VectorRef Ref); \
4549
\
4650
DPCTL_API \

dpctl-capi/source/dpctl_sycl_context_interface.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,53 @@ DPCTLContext_Copy(__dpctl_keep const DPCTLSyclContextRef CRef)
116116
}
117117
}
118118

119+
__dpctl_give DPCTLDeviceVectorRef
120+
DPCTLContext_GetDevices(__dpctl_keep const DPCTLSyclContextRef CRef)
121+
{
122+
auto Context = unwrap(CRef);
123+
if (!Context) {
124+
std::cerr << "Can not retrieve devices from DPCTLSyclContextRef as "
125+
"input is a nullptr\n";
126+
return nullptr;
127+
}
128+
vector_class<DPCTLSyclDeviceRef> *DevicesVectorPtr = nullptr;
129+
try {
130+
DevicesVectorPtr = new vector_class<DPCTLSyclDeviceRef>();
131+
} catch (std::bad_alloc const &ba) {
132+
// \todo log error
133+
std::cerr << ba.what() << '\n';
134+
return nullptr;
135+
}
136+
try {
137+
auto Devices = Context->get_devices();
138+
DevicesVectorPtr->reserve(Devices.size());
139+
for (const auto &Dev : Devices) {
140+
DevicesVectorPtr->emplace_back(wrap(new device(Dev)));
141+
}
142+
return wrap(DevicesVectorPtr);
143+
} catch (std::bad_alloc const &ba) {
144+
// \todo log error
145+
std::cerr << ba.what() << '\n';
146+
return nullptr;
147+
} catch (const runtime_error &re) {
148+
// \todo log error
149+
std::cerr << re.what() << '\n';
150+
return nullptr;
151+
}
152+
}
153+
154+
size_t DPCTLContext_DeviceCount(__dpctl_keep const DPCTLSyclContextRef CRef)
155+
{
156+
auto Context = unwrap(CRef);
157+
if (!Context) {
158+
std::cerr << "Can not retrieve devices from DPCTLSyclContextRef as "
159+
"input is a nullptr\n";
160+
return 0;
161+
}
162+
const auto Devices = Context->get_devices();
163+
return Devices.size();
164+
}
165+
119166
bool DPCTLContext_IsHost(__dpctl_keep const DPCTLSyclContextRef CtxRef)
120167
{
121168
auto Ctx = unwrap(CtxRef);

dpctl-capi/source/dpctl_vector_templ.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,28 @@ __dpctl_give VECTOR(EL) FN(EL, Create)()
4747
}
4848
}
4949

50+
/*!
51+
* @brief Creates a new std::vector of the opaque SYCL pointer types from given
52+
* C array with deep copy.
53+
*
54+
* @return A new dynamically allocated std::vector of opaque pointer types.
55+
*/
56+
__dpctl_give VECTOR(EL)
57+
FN(EL, CreateFromArray)(size_t n, __dpctl_keep SYCLREF(EL) * elems)
58+
{
59+
try {
60+
auto Vec = new vector_class<SYCLREF(EL)>();
61+
for (size_t i = 0; i < n; ++i) {
62+
auto Ref = unwrap(elems[i]);
63+
Vec->emplace_back(
64+
wrap(new std::remove_pointer<decltype(Ref)>::type(*Ref)));
65+
}
66+
return wrap(Vec);
67+
} catch (std::bad_alloc const &ba) {
68+
return nullptr;
69+
}
70+
}
71+
5072
/*!
5173
* @brief Frees all the elements of the passed in std::vector and then frees the
5274
* std::vector pointer.

dpctl-capi/tests/test_sycl_context_interface.cpp

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,20 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(vector_class<DPCTLSyclDeviceRef>,
4343

4444
struct TestDPCTLContextInterface : public ::testing::TestWithParam<const char *>
4545
{
46-
DPCTLSyclDeviceSelectorRef DSRef = nullptr;
46+
DPCTLSyclDeviceRef DRef = nullptr;
4747

4848
TestDPCTLContextInterface()
4949
{
50-
EXPECT_NO_FATAL_FAILURE(DSRef = DPCTLFilterSelector_Create(GetParam()));
50+
auto DS = DPCTLFilterSelector_Create(GetParam());
51+
if (DS) {
52+
EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DS));
53+
}
54+
DPCTLDeviceSelector_Delete(DS);
5155
}
5256

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

6266
~TestDPCTLContextInterface()
6367
{
64-
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceSelector_Delete(DSRef));
68+
EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
6569
}
6670
};
6771

6872
TEST_P(TestDPCTLContextInterface, Chk_Create)
6973
{
7074
DPCTLSyclContextRef CRef = nullptr;
71-
DPCTLSyclDeviceRef DRef = nullptr;
72-
EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef));
73-
if (!DRef)
74-
GTEST_SKIP_("Device not found");
7575
EXPECT_NO_FATAL_FAILURE(CRef = DPCTLContext_Create(DRef, nullptr, 0));
7676
ASSERT_TRUE(CRef);
77-
EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
7877
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
7978
}
8079

8180
TEST_P(TestDPCTLContextInterface, Chk_CreateWithDevices)
8281
{
8382
size_t nCUs = 0;
8483
DPCTLSyclContextRef CRef = nullptr;
85-
DPCTLSyclDeviceRef DRef = nullptr;
8684
DPCTLDeviceVectorRef DVRef = nullptr;
87-
EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef));
88-
if (!DRef)
89-
GTEST_SKIP_("Device not found");
9085

9186
/* TODO: Once we have wrappers for sub-device creation let us use those
9287
* functions.
@@ -108,20 +103,67 @@ TEST_P(TestDPCTLContextInterface, Chk_CreateWithDevices)
108103
GTEST_SKIP_("Skipping creating context for sub-devices");
109104
}
110105
}
111-
EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
112106
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceVector_Delete(DVRef));
113107
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
114108
}
115109

110+
TEST_P(TestDPCTLContextInterface, Chk_CreateWithDevices_GetDevices)
111+
{
112+
size_t nCUs = 0;
113+
DPCTLSyclContextRef CRef = nullptr;
114+
DPCTLDeviceVectorRef DVRef = nullptr;
115+
DPCTLDeviceVectorRef Res_DVRef = nullptr;
116+
117+
/* TODO: Once we have wrappers for sub-device creation let us use those
118+
* functions.
119+
*/
120+
EXPECT_NO_FATAL_FAILURE(nCUs = DPCTLDevice_GetMaxComputeUnits(DRef));
121+
if (nCUs) {
122+
auto D = unwrap(DRef);
123+
try {
124+
auto subDevices = D->create_sub_devices<
125+
info::partition_property::partition_equally>(nCUs / 2);
126+
const size_t len = subDevices.size();
127+
auto ar = new DPCTLSyclDeviceRef[len];
128+
for (size_t i = 0; i < len; ++i) {
129+
ar[i] = wrap(&subDevices.at(i));
130+
}
131+
EXPECT_NO_FATAL_FAILURE(
132+
DVRef = DPCTLDeviceVector_CreateFromArray(len, ar));
133+
EXPECT_NO_FATAL_FAILURE(
134+
CRef = DPCTLContext_CreateFromDevices(DVRef, nullptr, 0));
135+
ASSERT_TRUE(CRef);
136+
ASSERT_TRUE(DPCTLContext_DeviceCount(CRef) == len);
137+
EXPECT_NO_FATAL_FAILURE(Res_DVRef = DPCTLContext_GetDevices(CRef));
138+
ASSERT_TRUE(DPCTLDeviceVector_Size(Res_DVRef) == len);
139+
delete[] ar;
140+
} catch (feature_not_supported const &fnse) {
141+
GTEST_SKIP_("Skipping creating context for sub-devices");
142+
}
143+
}
144+
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceVector_Delete(DVRef));
145+
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
146+
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceVector_Delete(Res_DVRef));
147+
}
148+
149+
TEST_P(TestDPCTLContextInterface, Chk_GetDevices)
150+
{
151+
DPCTLSyclContextRef CRef = nullptr;
152+
DPCTLDeviceVectorRef DVRef = nullptr;
153+
EXPECT_NO_FATAL_FAILURE(CRef = DPCTLContext_Create(DRef, nullptr, 0));
154+
ASSERT_TRUE(CRef);
155+
EXPECT_NO_FATAL_FAILURE(DVRef = DPCTLContext_GetDevices(CRef));
156+
ASSERT_TRUE(DVRef);
157+
EXPECT_TRUE(DPCTLDeviceVector_Size(DVRef) == 1);
158+
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
159+
EXPECT_NO_FATAL_FAILURE(DPCTLDeviceVector_Delete(DVRef));
160+
}
161+
116162
TEST_P(TestDPCTLContextInterface, Chk_AreEq)
117163
{
118164
DPCTLSyclContextRef CRef1 = nullptr, CRef2 = nullptr, CRef3 = nullptr;
119-
DPCTLSyclDeviceRef DRef = nullptr;
120165
bool are_eq = true, are_not_eq = false;
121166

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

139-
EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
140181
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef1));
141182
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef2));
142183
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef3));
@@ -145,41 +186,31 @@ TEST_P(TestDPCTLContextInterface, Chk_AreEq)
145186
TEST_P(TestDPCTLContextInterface, Chk_IsHost)
146187
{
147188
DPCTLSyclContextRef CRef = nullptr;
148-
DPCTLSyclDeviceRef DRef = nullptr;
149189
bool is_host_device = false, is_host_context = false;
150190

151-
EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef));
152-
if (!DRef)
153-
GTEST_SKIP_("Device not found");
154191
EXPECT_NO_FATAL_FAILURE(CRef = DPCTLContext_Create(DRef, nullptr, 0));
155192
ASSERT_TRUE(CRef);
156193

157194
EXPECT_NO_FATAL_FAILURE(is_host_device = DPCTLDevice_IsHost(DRef));
158195
EXPECT_NO_FATAL_FAILURE(is_host_context = DPCTLContext_IsHost(CRef));
159196
EXPECT_TRUE(is_host_device == is_host_context);
160197

161-
EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
162198
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
163199
}
164200

165201
TEST_P(TestDPCTLContextInterface, Chk_GetBackend)
166202
{
167203
DPCTLSyclContextRef CRef = nullptr;
168-
DPCTLSyclDeviceRef DRef = nullptr;
169204
DPCTLSyclBackendType context_backend = DPCTL_UNKNOWN_BACKEND,
170205
device_backend = DPCTL_UNKNOWN_BACKEND;
171206

172-
EXPECT_NO_FATAL_FAILURE(DRef = DPCTLDevice_CreateFromSelector(DSRef));
173-
if (!DRef)
174-
GTEST_SKIP_("Device not found");
175207
EXPECT_NO_FATAL_FAILURE(CRef = DPCTLContext_Create(DRef, nullptr, 0));
176208
ASSERT_TRUE(CRef);
177209

178210
EXPECT_NO_FATAL_FAILURE(device_backend = DPCTLDevice_GetBackend(DRef));
179211
EXPECT_NO_FATAL_FAILURE(context_backend = DPCTLContext_GetBackend(CRef));
180212
EXPECT_TRUE(device_backend == context_backend);
181213

182-
EXPECT_NO_FATAL_FAILURE(DPCTLDevice_Delete(DRef));
183214
EXPECT_NO_FATAL_FAILURE(DPCTLContext_Delete(CRef));
184215
}
185216

dpctl/_backend.pxd

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ cdef extern from "dpctl_sycl_device_interface.h":
168168
cdef extern from "dpctl_sycl_device_manager.h":
169169
cdef struct DPCTLDeviceVector
170170
ctypedef DPCTLDeviceVector *DPCTLDeviceVectorRef
171+
cdef DPCTLDeviceVectorRef DPCTLDeviceVector_CreateFromArray(
172+
size_t nelems,
173+
DPCTLSyclDeviceRef *elems)
171174
cdef void DPCTLDeviceVector_Delete(DPCTLDeviceVectorRef DVRef)
172175
cdef void DPCTLDeviceVector_Clear(DPCTLDeviceVectorRef DVRef)
173176
cdef size_t DPCTLDeviceVector_Size(DPCTLDeviceVectorRef DVRef)
@@ -231,6 +234,19 @@ cdef extern from "dpctl_sycl_platform_interface.h":
231234

232235

233236
cdef extern from "dpctl_sycl_context_interface.h":
237+
cdef DPCTLSyclContextRef DPCTLContext_Create(
238+
const DPCTLSyclDeviceRef DRef,
239+
error_handler_callback *error_handler,
240+
int properties)
241+
cdef DPCTLSyclContextRef DPCTLContext_CreateFromDevices(
242+
const DPCTLDeviceVectorRef DVRef,
243+
error_handler_callback *error_handler,
244+
int properties)
245+
cdef DPCTLSyclContextRef DPCTLContext_Copy(
246+
const DPCTLSyclContextRef CRef)
247+
cdef DPCTLDeviceVectorRef DPCTLContext_GetDevices(
248+
const DPCTLSyclContextRef CRef)
249+
cdef size_t DPCTLContext_DeviceCount(const DPCTLSyclContextRef CRef)
234250
cdef bool DPCTLContext_AreEq(const DPCTLSyclContextRef CtxRef1,
235251
const DPCTLSyclContextRef CtxRef2)
236252
cdef DPCTLSyclBackendType DPCTLContext_GetBackend(

dpctl/_sycl_context.pxd

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,25 @@
2121
"""
2222

2323
from ._backend cimport DPCTLSyclContextRef
24+
from ._sycl_device cimport SyclDevice
2425
from libcpp cimport bool
2526

27+
cdef class _SyclContext:
28+
""" Data owner for SyclContext
29+
"""
30+
cdef DPCTLSyclContextRef _ctxt_ref
31+
2632

27-
cdef class SyclContext:
33+
cdef class SyclContext(_SyclContext):
2834
''' Wrapper class for a Sycl Context
2935
'''
30-
cdef DPCTLSyclContextRef _ctxt_ref
3136

3237
@staticmethod
33-
cdef SyclContext _create (DPCTLSyclContextRef ctxt)
38+
cdef SyclContext _create (DPCTLSyclContextRef CRef)
39+
@staticmethod
40+
cdef void _init_helper(_SyclContext self, DPCTLSyclContextRef CRef)
41+
cdef int _init_from__SyclContext(self, _SyclContext other)
42+
cdef int _init_from_one_device(self, SyclDevice device, int props)
43+
cdef int _init_from_devices(self, object devices, int props)
3444
cpdef bool equals (self, SyclContext ctxt)
3545
cdef DPCTLSyclContextRef get_context_ref (self)

0 commit comments

Comments
 (0)