• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IntelPython / dpctl / 31109981292

06 Aug 2026 02:16PM UTC coverage: 74.19% (+0.1%) from 74.054%
31109981292

Pull #2354

github

web-flow
Merge 5a849fd69 into be1985837
Pull Request #2354: Add `sycl::info::context` queries to `dpctl.SyclContext`

971 of 1374 branches covered (70.67%)

Branch coverage included in aggregate %.

49 of 56 new or added lines in 1 file covered. (87.5%)

3703 of 4926 relevant lines covered (75.17%)

289.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.05
/libsyclinterface/source/dpctl_sycl_context_interface.cpp
1
//===- dpctl_sycl_context_interface.cpp - Implements C API for sycl::context =//
2
//
3
//                      Data Parallel Control (dpctl)
4
//
5
// Copyright 2020 Intel Corporation
6
//
7
// Licensed under the Apache License, Version 2.0 (the "License");
8
// you may not use this file except in compliance with the License.
9
// You may obtain a copy of the License at
10
//
11
//    http://www.apache.org/licenses/LICENSE-2.0
12
//
13
// Unless required by applicable law or agreed to in writing, software
14
// distributed under the License is distributed on an "AS IS" BASIS,
15
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
// See the License for the specific language governing permissions and
17
// limitations under the License.
18
//
19
//===----------------------------------------------------------------------===//
20
///
21
/// \file
22
/// This file implements the data types and functions declared in
23
/// dpctl_sycl_context_interface.h.
24
///
25
//===----------------------------------------------------------------------===//
26

27
#include "dpctl_sycl_context_interface.h"
28
#include "Config/dpctl_config.h"
29
#include "dpctl_error_handlers.h"
30
#include "dpctl_sycl_type_casters.hpp"
31
#include "dpctl_utils_helper.h"
32
#include <stddef.h>
33
#include <sycl/sycl.hpp>
34
#include <utility>
35
#include <vector>
36

37
using namespace sycl;
38

39
namespace
40
{
41
static_assert(__SYCL_COMPILER_VERSION >= __SYCL_COMPILER_VERSION_REQUIRED,
42
              "The compiler does not meet minimum version requirement");
43

44
using namespace dpctl::syclinterface;
45
} // end of anonymous namespace
46

47
__dpctl_give DPCTLSyclContextRef
48
DPCTLContext_Create(__dpctl_keep const DPCTLSyclDeviceRef DRef,
49
                    error_handler_callback *handler,
50
                    int /**/)
51
{
46✔
52
    DPCTLSyclContextRef CRef = nullptr;
46✔
53
    auto Device = unwrap<device>(DRef);
46✔
54
    if (!Device) {
46✔
55
        error_handler("Cannot create device from DPCTLSyclDeviceRef"
1✔
56
                      "as input is a nullptr.",
1✔
57
                      __FILE__, __func__, __LINE__);
1✔
58
        return nullptr;
1✔
59
    }
1✔
60
    try {
45✔
61
        CRef = wrap<context>(
45✔
62
            new context(*Device, DPCTL_AsyncErrorHandler(handler)));
45✔
63
    } catch (std::exception const &e) {
45✔
64
        error_handler(e, __FILE__, __func__, __LINE__);
×
65
    }
×
66

67
    return CRef;
45✔
68
}
45✔
69

70
__dpctl_give DPCTLSyclContextRef
71
DPCTLContext_CreateFromDevices(__dpctl_keep const DPCTLDeviceVectorRef DVRef,
72
                               error_handler_callback *handler,
73
                               int /**/)
74
{
10✔
75
    DPCTLSyclContextRef CRef = nullptr;
10✔
76
    std::vector<device> Devices;
10✔
77
    auto DeviceRefs = unwrap<std::vector<DPCTLSyclDeviceRef>>(DVRef);
10✔
78
    if (!DeviceRefs) {
10✔
79
        error_handler("Cannot create device reference from DPCTLDeviceVectorRef"
1✔
80
                      "as input is a nullptr.",
1✔
81
                      __FILE__, __func__, __LINE__);
1✔
82
        return CRef;
1✔
83
    }
1✔
84
    Devices.reserve(DeviceRefs->size());
9✔
85

86
    for (auto const &DRef : *DeviceRefs) {
18✔
87
        Devices.emplace_back(*unwrap<device>(DRef));
18✔
88
    }
18✔
89

90
    try {
9✔
91
        CRef = wrap<context>(
9✔
92
            new context(std::move(Devices), DPCTL_AsyncErrorHandler(handler)));
9✔
93
    } catch (std::exception const &e) {
9✔
94
        error_handler(e, __FILE__, __func__, __LINE__);
×
95
    }
×
96

97
    return CRef;
9✔
98
}
9✔
99

100
bool DPCTLContext_AreEq(__dpctl_keep const DPCTLSyclContextRef CtxRef1,
101
                        __dpctl_keep const DPCTLSyclContextRef CtxRef2)
102
{
115✔
103
    if (!(CtxRef1 && CtxRef2)) {
115!
104
        error_handler("DPCTLSyclContextRefs are nullptr.", __FILE__, __func__,
1✔
105
                      __LINE__);
1✔
106
        return false;
1✔
107
    }
1✔
108
    return (*unwrap<context>(CtxRef1) == *unwrap<context>(CtxRef2));
114✔
109
}
115✔
110

111
__dpctl_give DPCTLSyclContextRef
112
DPCTLContext_Copy(__dpctl_keep const DPCTLSyclContextRef CRef)
113
{
1,605✔
114
    auto Context = unwrap<context>(CRef);
1,605✔
115
    if (!Context) {
1,605✔
116
        error_handler("Cannot copy DPCTLSyclContextRef as input is a nullptr.",
1✔
117
                      __FILE__, __func__, __LINE__);
1✔
118
        return nullptr;
1✔
119
    }
1✔
120
    try {
1,604✔
121
        auto CopiedContext = new context(*Context);
1,604✔
122
        return wrap<context>(CopiedContext);
1,604✔
123
    } catch (std::exception const &e) {
1,604✔
124
        error_handler(e, __FILE__, __func__, __LINE__);
×
125
        return nullptr;
×
126
    }
×
127
}
1,604✔
128

129
__dpctl_give DPCTLDeviceVectorRef
130
DPCTLContext_GetDevices(__dpctl_keep const DPCTLSyclContextRef CRef)
131
{
43✔
132
    auto Context = unwrap<context>(CRef);
43✔
133
    if (!Context) {
43✔
134
        error_handler("Cannot retrieve devices from DPCTLSyclContextRef as "
1✔
135
                      "input is a nullptr.",
1✔
136
                      __FILE__, __func__, __LINE__);
1✔
137
        return nullptr;
1✔
138
    }
1✔
139
    using vecTy = std::vector<DPCTLSyclDeviceRef>;
42✔
140
    vecTy *DevicesVectorPtr = nullptr;
42✔
141
    try {
42✔
142
        DevicesVectorPtr = new vecTy();
42✔
143
    } catch (std::exception const &e) {
42✔
144
        delete DevicesVectorPtr;
×
145
        error_handler(e, __FILE__, __func__, __LINE__);
×
146
        return nullptr;
×
147
    }
×
148
    try {
42✔
149
        auto Devices = Context->get_devices();
42✔
150
        DevicesVectorPtr->reserve(Devices.size());
42✔
151
        for (const auto &Dev : Devices) {
46✔
152
            DevicesVectorPtr->emplace_back(
46✔
153
                wrap<device>(new device(std::move(Dev))));
46✔
154
        }
46✔
155
        return wrap<vecTy>(DevicesVectorPtr);
42✔
156
    } catch (std::exception const &e) {
42✔
157
        delete DevicesVectorPtr;
×
158
        error_handler(e, __FILE__, __func__, __LINE__);
×
159
        return nullptr;
×
160
    }
×
161
}
42✔
162

163
size_t DPCTLContext_DeviceCount(__dpctl_keep const DPCTLSyclContextRef CRef)
164
{
14✔
165
    auto Context = unwrap<context>(CRef);
14✔
166
    if (!Context) {
14✔
167
        error_handler("Cannot retrieve devices from DPCTLSyclContextRef as "
1✔
168
                      "input is a nullptr.",
1✔
169
                      __FILE__, __func__, __LINE__);
1✔
170
        return 0;
1✔
171
    }
1✔
172
    const auto Devices = Context->get_devices();
13✔
173
    return Devices.size();
13✔
174
}
14✔
175

176
void DPCTLContext_Delete(__dpctl_take DPCTLSyclContextRef CtxRef)
177
{
3,571✔
178
    delete unwrap<context>(CtxRef);
3,571✔
179
}
3,571✔
180

181
DPCTLSyclBackendType
182
DPCTLContext_GetBackend(__dpctl_keep const DPCTLSyclContextRef CtxRef)
183
{
14✔
184
    if (!CtxRef) {
14✔
185
        return DPCTL_UNKNOWN_BACKEND;
1✔
186
    }
1✔
187

188
    auto BE = unwrap<context>(CtxRef)->get_platform().get_backend();
13✔
189

190
    switch (BE) {
13✔
191
    case backend::opencl:
13!
192
        return DPCTL_OPENCL;
13✔
193
    case backend::ext_oneapi_level_zero:
×
194
        return DPCTL_LEVEL_ZERO;
×
195
    case backend::ext_oneapi_cuda:
×
196
        return DPCTL_CUDA;
×
197
    case backend::ext_oneapi_hip:
×
198
        return DPCTL_HIP;
×
199
    default:
×
200
        return DPCTL_UNKNOWN_BACKEND;
×
201
    }
13✔
202
}
13✔
203

204
size_t DPCTLContext_Hash(__dpctl_keep const DPCTLSyclContextRef CtxRef)
205
{
56✔
206
    if (CtxRef) {
56✔
207
        auto C = unwrap<context>(CtxRef);
55✔
208
        std::hash<context> hash_fn;
55✔
209
        return hash_fn(*C);
55✔
210
    }
55✔
211
    else {
1✔
212
        error_handler("Argument CtxRef is null.", __FILE__, __func__, __LINE__);
1✔
213
        return 0;
1✔
214
    }
1✔
215
}
56✔
216

217
__dpctl_give DPCTLSyclPlatformRef
218
DPCTLContext_GetPlatform(__dpctl_keep const DPCTLSyclContextRef CtxRef)
219
{
9✔
220
    DPCTLSyclPlatformRef PRef = nullptr;
9✔
221
    auto C = unwrap<context>(CtxRef);
9✔
222
    if (C) {
9✔
223
        try {
8✔
224
            PRef = wrap<platform>(
8✔
225
                new platform(C->get_info<info::context::platform>()));
8✔
226
        } catch (std::exception const &e) {
8✔
NEW
227
            error_handler(e, __FILE__, __func__, __LINE__);
×
NEW
228
        }
×
229
    }
8✔
230
    return PRef;
9✔
231
}
9✔
232

233
namespace
234
{
235

236
template <typename InfoDescT, typename ConvertFn>
237
int *get_context_info_enum_array(__dpctl_keep const DPCTLSyclContextRef CtxRef,
238
                                 size_t *res_len,
239
                                 ConvertFn convert)
240
{
36✔
241
    int *arr = nullptr;
36✔
242
    *res_len = 0;
36✔
243
    auto C = unwrap<context>(CtxRef);
36✔
244
    if (C) {
36✔
245
        try {
32✔
246
            auto values = C->get_info<InfoDescT>();
32✔
247
            *res_len = values.size();
32✔
248
            if (*res_len > 0) {
32!
249
                arr = new int[*res_len];
32✔
250
                for (size_t i = 0; i < *res_len; ++i) {
192✔
251
                    arr[i] = convert(values[i]);
160✔
252
                }
160✔
253
            }
32✔
254
        } catch (std::exception const &e) {
32✔
NEW
255
            error_handler(e, __FILE__, __func__, __LINE__);
×
NEW
256
            delete[] arr;
×
NEW
257
            arr = nullptr;
×
NEW
258
            *res_len = 0;
×
NEW
259
        }
×
260
    }
32✔
261
    return arr;
36✔
262
}
36✔
263

264
} // end of anonymous namespace
265

266
__dpctl_give int *DPCTLContext_GetAtomicMemoryOrderCapabilities(
267
    __dpctl_keep const DPCTLSyclContextRef CtxRef,
268
    size_t *res_len)
269
{
9✔
270
    return get_context_info_enum_array<
9✔
271
        info::context::atomic_memory_order_capabilities>(
9✔
272
        CtxRef, res_len, DPCTL_SyclMemoryOrderToDPCTLType);
9✔
273
}
9✔
274

275
__dpctl_give int *DPCTLContext_GetAtomicFenceOrderCapabilities(
276
    __dpctl_keep const DPCTLSyclContextRef CtxRef,
277
    size_t *res_len)
278
{
9✔
279
    return get_context_info_enum_array<
9✔
280
        info::context::atomic_fence_order_capabilities>(
9✔
281
        CtxRef, res_len, DPCTL_SyclMemoryOrderToDPCTLType);
9✔
282
}
9✔
283

284
__dpctl_give int *DPCTLContext_GetAtomicMemoryScopeCapabilities(
285
    __dpctl_keep const DPCTLSyclContextRef CtxRef,
286
    size_t *res_len)
287
{
9✔
288
    return get_context_info_enum_array<
9✔
289
        info::context::atomic_memory_scope_capabilities>(
9✔
290
        CtxRef, res_len, DPCTL_SyclMemoryScopeToDPCTLType);
9✔
291
}
9✔
292

293
__dpctl_give int *DPCTLContext_GetAtomicFenceScopeCapabilities(
294
    __dpctl_keep const DPCTLSyclContextRef CtxRef,
295
    size_t *res_len)
296
{
9✔
297
    return get_context_info_enum_array<
9✔
298
        info::context::atomic_fence_scope_capabilities>(
9✔
299
        CtxRef, res_len, DPCTL_SyclMemoryScopeToDPCTLType);
9✔
300
}
9✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc