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

IntelPython / dpctl / 14040639877

24 Mar 2025 04:31PM UTC coverage: 86.752% (-0.9%) from 87.677%
14040639877

push

github

web-flow
Merge pull request #2028 from IntelPython/dependabot/github_actions/github/codeql-action-3.28.13

Bump github/codeql-action from 3.28.11 to 3.28.13

3002 of 3684 branches covered (81.49%)

Branch coverage included in aggregate %.

12033 of 13647 relevant lines covered (88.17%)

7092.15 hits per line

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

80.31
/libsyclinterface/source/dpctl_sycl_queue_interface.cpp
1
//===----- dpctl_sycl_queue_interface.cpp - Implements C API for sycl::queue =//
2
//
3
//                      Data Parallel Control (dpctl)
4
//
5
// Copyright 2020-2025 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_queue_interface.h.
24
///
25
//===----------------------------------------------------------------------===//
26

27
#include "dpctl_sycl_queue_interface.h"
28
#include "Config/dpctl_config.h"
29
#include "dpctl_error_handlers.h"
30
#include "dpctl_sycl_context_interface.h"
31
#include "dpctl_sycl_device_interface.h"
32
#include "dpctl_sycl_device_manager.h"
33
#include "dpctl_sycl_type_casters.hpp"
34

35
#include <stddef.h>
36
#include <stdint.h>
37

38
#include <cstdint>
39
#include <exception>
40
#include <sstream>
41
#include <stdexcept>
42
#include <sycl/sycl.hpp> /* SYCL headers   */
43
#include <utility>
44

45
#ifdef SYCL_EXT_ONEAPI_WORK_GROUP_MEMORY
46
#include "dpctl_sycl_extension_interface.h"
47
#endif
48

49
using namespace sycl;
50

51
#define SET_LOCAL_ACCESSOR_ARG(CGH, NDIM, ARGTY, R, IDX)                       \
52
    do {                                                                       \
31 ✔
53
        switch ((ARGTY)) {                                                     \
31 ✔
54
        case DPCTL_INT8_T:                                                     \
3 ✔
55
        {                                                                      \
3 ✔
56
            auto la = local_accessor<std::int8_t, NDIM>(R, CGH);               \
3 ✔
57
            CGH.set_arg(IDX, la);                                              \
3 ✔
58
            return true;                                                       \
3 ✔
59
        }                                                                      \
×
60
        case DPCTL_UINT8_T:                                                    \
3 ✔
61
        {                                                                      \
3 ✔
62
            auto la = local_accessor<std::uint8_t, NDIM>(R, CGH);              \
3 ✔
63
            CGH.set_arg(IDX, la);                                              \
3 ✔
64
            return true;                                                       \
3 ✔
65
        }                                                                      \
×
66
        case DPCTL_INT16_T:                                                    \
3 ✔
67
        {                                                                      \
3 ✔
68
            auto la = local_accessor<std::int16_t, NDIM>(R, CGH);              \
3 ✔
69
            CGH.set_arg(IDX, la);                                              \
3 ✔
70
            return true;                                                       \
3 ✔
71
        }                                                                      \
×
72
        case DPCTL_UINT16_T:                                                   \
3 ✔
73
        {                                                                      \
3 ✔
74
            auto la = local_accessor<std::uint16_t, NDIM>(R, CGH);             \
3 ✔
75
            CGH.set_arg(IDX, la);                                              \
3 ✔
76
            return true;                                                       \
3 ✔
77
        }                                                                      \
×
78
        case DPCTL_INT32_T:                                                    \
3 ✔
79
        {                                                                      \
3 ✔
80
            auto la = local_accessor<std::int32_t, NDIM>(R, CGH);              \
3 ✔
81
            CGH.set_arg(IDX, la);                                              \
3 ✔
82
            return true;                                                       \
3 ✔
83
        }                                                                      \
×
84
        case DPCTL_UINT32_T:                                                   \
3 ✔
85
        {                                                                      \
3 ✔
86
            auto la = local_accessor<std::uint32_t, NDIM>(R, CGH);             \
3 ✔
87
            CGH.set_arg(IDX, la);                                              \
3 ✔
88
            return true;                                                       \
3 ✔
89
        }                                                                      \
×
90
        case DPCTL_INT64_T:                                                    \
3 ✔
91
        {                                                                      \
3 ✔
92
            auto la = local_accessor<std::int64_t, NDIM>(R, CGH);              \
3 ✔
93
            CGH.set_arg(IDX, la);                                              \
3 ✔
94
            return true;                                                       \
3 ✔
95
        }                                                                      \
×
96
        case DPCTL_UINT64_T:                                                   \
3 ✔
97
        {                                                                      \
3 ✔
98
            auto la = local_accessor<std::uint64_t, NDIM>(R, CGH);             \
3 ✔
99
            CGH.set_arg(IDX, la);                                              \
3 ✔
100
            return true;                                                       \
3 ✔
101
        }                                                                      \
×
102
        case DPCTL_FLOAT32_T:                                                  \
3 ✔
103
        {                                                                      \
3 ✔
104
            auto la = local_accessor<float, NDIM>(R, CGH);                     \
3 ✔
105
            CGH.set_arg(IDX, la);                                              \
3 ✔
106
            return true;                                                       \
3 ✔
107
        }                                                                      \
×
108
        case DPCTL_FLOAT64_T:                                                  \
3 ✔
109
        {                                                                      \
3 ✔
110
            auto la = local_accessor<double, NDIM>(R, CGH);                    \
3 ✔
111
            CGH.set_arg(IDX, la);                                              \
3 ✔
112
            return true;                                                       \
3 ✔
113
        }                                                                      \
×
114
        default:                                                               \
1 ✔
115
            error_handler("Kernel argument could not be created.", __FILE__,   \
1 ✔
116
                          __func__, __LINE__, error_level::error);             \
1 ✔
117
            return false;                                                      \
1 ✔
118
        }                                                                      \
31 ✔
119
    } while (0);
31 ✔
120

121
namespace
122
{
123
static_assert(__SYCL_COMPILER_VERSION >= __SYCL_COMPILER_VERSION_REQUIRED,
124
              "The compiler does not meet minimum version requirement");
125

126
using namespace dpctl::syclinterface;
127

128
typedef struct complex
129
{
130
    std::uint64_t real;
131
    std::uint64_t imag;
132
} complexNumber;
133

134
void set_dependent_events(handler &cgh,
135
                          __dpctl_keep const DPCTLSyclEventRef *DepEvents,
136
                          size_t NDepEvents)
137
{
144 ✔
138
    for (auto i = 0ul; i < NDepEvents; ++i) {
259 ✔
139
        auto ei = unwrap<event>(DepEvents[i]);
115 ✔
140
        if (ei)
115 !
141
            cgh.depends_on(*ei);
115 ✔
142
    }
115 ✔
143
}
144 ✔
144

145
bool set_local_accessor_arg(handler &cgh,
146
                            size_t idx,
147
                            const MDLocalAccessor *mdstruct)
148
{
31 ✔
149
    switch (mdstruct->ndim) {
31 ✔
150
    case 1:
11 !
151
    {
11 ✔
152
        auto r = range<1>(mdstruct->dim0);
11 ✔
153
        SET_LOCAL_ACCESSOR_ARG(cgh, 1, mdstruct->dpctl_type_id, r, idx);
11 !
154
    }
×
155
    case 2:
10 !
156
    {
10 ✔
157
        auto r = range<2>(mdstruct->dim0, mdstruct->dim1);
10 ✔
158
        SET_LOCAL_ACCESSOR_ARG(cgh, 2, mdstruct->dpctl_type_id, r, idx);
10 !
159
    }
×
160
    case 3:
10 !
161
    {
10 ✔
162
        auto r = range<3>(mdstruct->dim0, mdstruct->dim1, mdstruct->dim2);
10 ✔
163
        SET_LOCAL_ACCESSOR_ARG(cgh, 3, mdstruct->dpctl_type_id, r, idx);
10 !
164
    }
×
165
    default:
×
166
        return false;
×
167
    }
31 ✔
168
}
31 ✔
169
/*!
170
 * @brief Set the kernel arg object
171
 *
172
 * @param cgh   SYCL command group handler using which a kernel is going to
173
 *              be submitted.
174
 * @param idx   The position of the argument in the list of arguments passed
175
 * to a kernel.
176
 * @param Arg   A void* representing a kernel argument.
177
 * @param Argty A typeid specifying the C++ type of the Arg parameter.
178
 */
179
bool set_kernel_arg(handler &cgh,
180
                    size_t idx,
181
                    __dpctl_keep void *Arg,
182
                    DPCTLKernelArgType ArgTy)
183
{
430 ✔
184
    bool arg_set = true;
430 ✔
185

186
    switch (ArgTy) {
430 ✔
187
    case DPCTL_INT8_T:
3 !
188
        cgh.set_arg(idx, *(std::int8_t *)Arg);
3 ✔
189
        break;
3 ✔
190
    case DPCTL_UINT8_T:
3 !
191
        cgh.set_arg(idx, *(std::uint8_t *)Arg);
3 ✔
192
        break;
3 ✔
193
    case DPCTL_INT16_T:
9 !
194
        cgh.set_arg(idx, *(std::int16_t *)Arg);
9 ✔
195
        break;
9 ✔
196
    case DPCTL_UINT16_T:
3 !
197
        cgh.set_arg(idx, *(std::uint16_t *)Arg);
3 ✔
198
        break;
3 ✔
199
    case DPCTL_INT32_T:
9 !
200
        cgh.set_arg(idx, *(std::int32_t *)Arg);
9 ✔
201
        break;
9 ✔
202
    case DPCTL_UINT32_T:
11 !
203
        cgh.set_arg(idx, *(std::uint32_t *)Arg);
11 ✔
204
        break;
11 ✔
205
    case DPCTL_INT64_T:
9 !
206
        cgh.set_arg(idx, *(std::int64_t *)Arg);
9 ✔
207
        break;
9 ✔
208
    case DPCTL_UINT64_T:
9 !
209
        cgh.set_arg(idx, *(std::uint64_t *)Arg);
9 ✔
210
        break;
9 ✔
211
    case DPCTL_FLOAT32_T:
9 !
212
        cgh.set_arg(idx, *(float *)Arg);
9 ✔
213
        break;
9 ✔
214
    case DPCTL_FLOAT64_T:
9 !
215
        cgh.set_arg(idx, *(double *)Arg);
9 ✔
216
        break;
9 ✔
217
    case DPCTL_VOID_PTR:
293 !
218
        cgh.set_arg(idx, Arg);
293 ✔
219
        break;
293 ✔
220
    case DPCTL_LOCAL_ACCESSOR:
31 !
221
        arg_set = set_local_accessor_arg(cgh, idx, (MDLocalAccessor *)Arg);
31 ✔
222
        break;
31 ✔
223
#ifdef SYCL_EXT_ONEAPI_WORK_GROUP_MEMORY
×
224
    case DPCTL_WORK_GROUP_MEMORY:
31 !
225
    {
31 ✔
226
        auto ref = static_cast<DPCTLSyclWorkGroupMemoryRef>(Arg);
31 ✔
227
        RawWorkGroupMemory *raw_mem = unwrap<RawWorkGroupMemory>(ref);
31 ✔
228
        size_t num_bytes = raw_mem->nbytes;
31 ✔
229
        sycl::ext::oneapi::experimental::work_group_memory<char[]> mem{
31 ✔
230
            num_bytes, cgh};
31 ✔
231
        cgh.set_arg(idx, mem);
31 ✔
232
        break;
31 ✔
233
    }
×
234
#endif
×
235
    default:
1 !
236
        arg_set = false;
1 ✔
237
        break;
1 ✔
238
    }
430 ✔
239
    return arg_set;
430 ✔
240
}
430 ✔
241

242
void set_kernel_args(handler &cgh,
243
                     __dpctl_keep void **Args,
244
                     __dpctl_keep const DPCTLKernelArgType *ArgTypes,
245
                     size_t NArgs)
246
{
144 ✔
247
    for (auto i = 0ul; i < NArgs; ++i) {
572 ✔
248
        if (!set_kernel_arg(cgh, i, Args[i], ArgTypes[i])) {
430 ✔
249
            error_handler("Kernel argument could not be created.", __FILE__,
2 ✔
250
                          __func__, __LINE__);
2 ✔
251
            throw std::invalid_argument(
2 ✔
252
                "Kernel argument could not be created.");
2 ✔
253
        }
2 ✔
254
    }
430 ✔
255
}
144 ✔
256

257
std::unique_ptr<property_list> create_property_list(int properties)
258
{
40,015 ✔
259
    std::unique_ptr<property_list> propList;
40,015 ✔
260
    int _prop = properties;
40,015 ✔
261
    if (_prop & DPCTL_ENABLE_PROFILING) {
40,015 ✔
262
        _prop = _prop ^ DPCTL_ENABLE_PROFILING;
71 ✔
263
        if (_prop & DPCTL_IN_ORDER) {
71 ✔
264
            _prop = _prop ^ DPCTL_IN_ORDER;
24 ✔
265
            propList = std::make_unique<property_list>(
24 ✔
266
                sycl::property::queue::enable_profiling(),
24 ✔
267
                sycl::property::queue::in_order());
24 ✔
268
        }
24 ✔
269
        else {
47 ✔
270
            propList = std::make_unique<property_list>(
47 ✔
271
                sycl::property::queue::enable_profiling());
47 ✔
272
        }
47 ✔
273
    }
71 ✔
274
    else if (_prop & DPCTL_IN_ORDER) {
39,944 ✔
275
        _prop = _prop ^ DPCTL_IN_ORDER;
436 ✔
276
        propList =
436 ✔
277
            std::make_unique<property_list>(sycl::property::queue::in_order());
436 ✔
278
    }
436 ✔
279
    else {
39,508 ✔
280
        propList = std::make_unique<property_list>();
39,508 ✔
281
    }
39,508 ✔
282

283
    if (_prop) {
40,015 ✔
284
        std::stringstream ss;
1 ✔
285
        ss << "Invalid queue property argument (" << std::hex << properties
1 ✔
286
           << "), interpreted as (" << (properties ^ _prop) << ").";
1 ✔
287
        error_handler(ss.str(), __FILE__, __func__, __LINE__);
1 ✔
288
    }
1 ✔
289
    return propList;
40,015 ✔
290
}
40,015 ✔
291

292
__dpctl_give DPCTLSyclQueueRef
293
getQueueImpl(__dpctl_keep DPCTLSyclContextRef cRef,
294
             __dpctl_keep DPCTLSyclDeviceRef dRef,
295
             error_handler_callback *handler,
296
             int properties)
297
{
149 ✔
298
    DPCTLSyclQueueRef qRef = nullptr;
149 ✔
299
    qRef = DPCTLQueue_Create(cRef, dRef, handler, properties);
149 ✔
300
    return qRef;
149 ✔
301
}
149 ✔
302

303
} /* end of anonymous namespace */
304

305
DPCTL_API
306
__dpctl_give DPCTLSyclQueueRef
307
DPCTLQueue_Create(__dpctl_keep const DPCTLSyclContextRef CRef,
308
                  __dpctl_keep const DPCTLSyclDeviceRef DRef,
309
                  error_handler_callback *handler,
310
                  int properties)
311
{
40,017 ✔
312
    DPCTLSyclQueueRef q = nullptr;
40,017 ✔
313
    auto dev = unwrap<device>(DRef);
40,017 ✔
314
    auto ctx = unwrap<context>(CRef);
40,017 ✔
315

316
    if (!(dev && ctx)) {
40,017 ✔
317
        error_handler("Cannot create queue from DPCTLSyclContextRef and "
2 ✔
318
                      "DPCTLSyclDeviceRef as input is a nullptr.",
2 ✔
319
                      __FILE__, __func__, __LINE__);
2 ✔
320
        return q;
2 ✔
321
    }
2 ✔
322
    auto propList = create_property_list(properties);
40,015 ✔
323

324
    if (handler) {
40,015 ✔
325
        try {
44 ✔
326
            auto Queue = new queue(*ctx, *dev, DPCTL_AsyncErrorHandler(handler),
44 ✔
327
                                   *propList);
44 ✔
328
            q = wrap<queue>(Queue);
44 ✔
329
        } catch (std::exception const &e) {
44 ✔
330
            error_handler(e, __FILE__, __func__, __LINE__);
×
331
        }
×
332
    }
44 ✔
333
    else {
39,971 ✔
334
        try {
39,971 ✔
335
            auto Queue = new queue(*ctx, *dev, *propList);
39,971 ✔
336
            q = wrap<queue>(Queue);
39,971 ✔
337
        } catch (std::exception const &e) {
39,971 ✔
338
            error_handler(e, __FILE__, __func__, __LINE__);
3 ✔
339
        }
3 ✔
340
    }
39,971 ✔
341

342
    return q;
40,015 ✔
343
}
40,015 ✔
344

345
__dpctl_give DPCTLSyclQueueRef
346
DPCTLQueue_CreateForDevice(__dpctl_keep const DPCTLSyclDeviceRef DRef,
347
                           error_handler_callback *handler,
348
                           int properties)
349
{
335 ✔
350
    DPCTLSyclContextRef CRef = nullptr;
335 ✔
351
    DPCTLSyclQueueRef QRef = nullptr;
335 ✔
352
    auto Device = unwrap<device>(DRef);
335 ✔
353

354
    if (!Device) {
335 ✔
355
        error_handler("Cannot create queue from NULL device reference.",
186 ✔
356
                      __FILE__, __func__, __LINE__);
186 ✔
357
        return QRef;
186 ✔
358
    }
186 ✔
359
    // Check if a cached default context exists for the device.
360
    CRef = DPCTLDeviceMgr_GetCachedContext(DRef);
149 ✔
361
    // If a cached default context was found, that context will be used to use
362
    // create the new queue. When a default cached context was not found, as
363
    // will be the case for non-root devices, i.e., sub-devices, a new context
364
    // will be allocated. Note that any newly allocated context is not cached.
365
    if (!CRef) {
149 !
366
        context *ContextPtr = nullptr;
×
367
        try {
×
368
            ContextPtr = new context(*Device);
×
369
            CRef = wrap<context>(ContextPtr);
×
370
        } catch (std::exception const &e) {
×
371
            error_handler(e, __FILE__, __func__, __LINE__);
×
372
            delete ContextPtr;
×
373
            return QRef;
×
374
        }
×
375
    }
×
376
    // At this point we have a valid context and the queue can be allocated.
377
    QRef = getQueueImpl(CRef, DRef, handler, properties);
149 ✔
378
    // Free the context
379
    DPCTLContext_Delete(CRef);
149 ✔
380
    return QRef;
149 ✔
381
}
149 ✔
382

383
/*!
384
 * Delete the passed in pointer after verifying it points to a sycl::queue.
385
 */
386
void DPCTLQueue_Delete(__dpctl_take DPCTLSyclQueueRef QRef)
387
{
226,487 ✔
388
    delete unwrap<queue>(QRef);
226,487 ✔
389
}
226,487 ✔
390

391
/*!
392
 * Make copy of sycl::queue referenced by passed pointer
393
 */
394
__dpctl_give DPCTLSyclQueueRef
395
DPCTLQueue_Copy(__dpctl_keep const DPCTLSyclQueueRef QRef)
396
{
583,378 ✔
397
    auto Queue = unwrap<queue>(QRef);
583,378 ✔
398
    if (Queue) {
583,378 ✔
399
        try {
583,377 ✔
400
            auto CopiedQueue = new queue(*Queue);
583,377 ✔
401
            return wrap<queue>(CopiedQueue);
583,377 ✔
402
        } catch (std::exception const &e) {
583,377 ✔
403
            error_handler(e, __FILE__, __func__, __LINE__);
×
404
            return nullptr;
×
405
        }
×
406
    }
583,377 ✔
407
    else {
1 ✔
408
        error_handler("Cannot copy DPCTLSyclQueueRef as input is a nullptr",
1 ✔
409
                      __FILE__, __func__, __LINE__);
1 ✔
410
        return nullptr;
1 ✔
411
    }
1 ✔
412
}
583,378 ✔
413

414
bool DPCTLQueue_AreEq(__dpctl_keep const DPCTLSyclQueueRef QRef1,
415
                      __dpctl_keep const DPCTLSyclQueueRef QRef2)
416
{
44,359 ✔
417
    if (!(QRef1 && QRef2)) {
44,359 ✔
418
        error_handler("DPCTLSyclQueueRefs are nullptr.", __FILE__, __func__,
2 ✔
419
                      __LINE__);
2 ✔
420
        return false;
2 ✔
421
    }
2 ✔
422
    return (*unwrap<queue>(QRef1) == *unwrap<queue>(QRef2));
44,357 ✔
423
}
44,359 ✔
424

425
DPCTLSyclBackendType DPCTLQueue_GetBackend(__dpctl_keep DPCTLSyclQueueRef QRef)
426
{
10 ✔
427
    auto Q = unwrap<queue>(QRef);
10 ✔
428
    if (Q) {
10 ✔
429
        try {
9 ✔
430
            auto C = Q->get_context();
9 ✔
431
            return DPCTLContext_GetBackend(wrap<context>(&C));
9 ✔
432
        } catch (std::exception const &e) {
9 ✔
433
            error_handler(e, __FILE__, __func__, __LINE__);
×
434
            return DPCTL_UNKNOWN_BACKEND;
×
435
        }
×
436
    }
9 ✔
437
    else
1 ✔
438
        return DPCTL_UNKNOWN_BACKEND;
1 ✔
439
}
10 ✔
440

441
__dpctl_give DPCTLSyclDeviceRef
442
DPCTLQueue_GetDevice(__dpctl_keep const DPCTLSyclQueueRef QRef)
443
{
93,166 ✔
444
    DPCTLSyclDeviceRef DRef = nullptr;
93,166 ✔
445
    auto Q = unwrap<queue>(QRef);
93,166 ✔
446
    if (Q) {
93,166 ✔
447
        try {
93,165 ✔
448
            auto Device = new device(Q->get_device());
93,165 ✔
449
            DRef = wrap<device>(Device);
93,165 ✔
450
        } catch (std::exception const &e) {
93,165 ✔
451
            error_handler(e, __FILE__, __func__, __LINE__);
×
452
        }
×
453
    }
93,165 ✔
454
    else {
1 ✔
455
        error_handler("Could not get the device for this queue.", __FILE__,
1 ✔
456
                      __func__, __LINE__);
1 ✔
457
    }
1 ✔
458
    return DRef;
93,166 ✔
459
}
93,166 ✔
460

461
__dpctl_give DPCTLSyclContextRef
462
DPCTLQueue_GetContext(__dpctl_keep const DPCTLSyclQueueRef QRef)
463
{
94,145 ✔
464
    auto Q = unwrap<queue>(QRef);
94,145 ✔
465
    DPCTLSyclContextRef CRef = nullptr;
94,145 ✔
466
    if (Q)
94,145 ✔
467
        CRef = wrap<context>(new context(Q->get_context()));
94,135 ✔
468
    else {
10 ✔
469
        error_handler("Could not get the context for this queue.", __FILE__,
10 ✔
470
                      __func__, __LINE__);
10 ✔
471
    }
10 ✔
472
    return CRef;
94,145 ✔
473
}
94,145 ✔
474

475
__dpctl_give DPCTLSyclEventRef
476
DPCTLQueue_SubmitRange(__dpctl_keep const DPCTLSyclKernelRef KRef,
477
                       __dpctl_keep const DPCTLSyclQueueRef QRef,
478
                       __dpctl_keep void **Args,
479
                       __dpctl_keep const DPCTLKernelArgType *ArgTypes,
480
                       size_t NArgs,
481
                       __dpctl_keep const size_t Range[3],
482
                       size_t NDims,
483
                       __dpctl_keep const DPCTLSyclEventRef *DepEvents,
484
                       size_t NDepEvents)
485
{
61 ✔
486
    auto Kernel = unwrap<kernel>(KRef);
61 ✔
487
    auto Queue = unwrap<queue>(QRef);
61 ✔
488
    event e;
61 ✔
489

490
    try {
61 ✔
491
        switch (NDims) {
61 ✔
492
        case 1:
27 !
493
        {
27 ✔
494
            e = Queue->submit([&](handler &cgh) {
27 ✔
495
                // Depend on any event that was specified by the caller.
496
                set_dependent_events(cgh, DepEvents, NDepEvents);
27 ✔
497
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
27 ✔
498
                cgh.parallel_for(range<1>{Range[0]}, *Kernel);
27 ✔
499
            });
27 ✔
500
            return wrap<event>(new event(std::move(e)));
27 ✔
501
        }
×
502
        case 2:
17 !
503
        {
17 ✔
504
            e = Queue->submit([&](handler &cgh) {
17 ✔
505
                // Depend on any event that was specified by the caller.
506
                set_dependent_events(cgh, DepEvents, NDepEvents);
17 ✔
507
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
17 ✔
508
                cgh.parallel_for(range<2>{Range[0], Range[1]}, *Kernel);
17 ✔
509
            });
17 ✔
510
            return wrap<event>(new event(std::move(e)));
17 ✔
511
        }
×
512
        case 3:
17 !
513
        {
17 ✔
514
            e = Queue->submit([&](handler &cgh) {
17 ✔
515
                // Depend on any event that was specified by the caller.
516
                set_dependent_events(cgh, DepEvents, NDepEvents);
17 ✔
517
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
17 ✔
518
                cgh.parallel_for(range<3>{Range[0], Range[1], Range[2]},
17 ✔
519
                                 *Kernel);
17 ✔
520
            });
17 ✔
521
            return wrap<event>(new event(std::move(e)));
17 ✔
522
        }
×
523
        default:
×
524
            error_handler("Range cannot be greater than three "
×
525
                          "dimensions.",
×
526
                          __FILE__, __func__, __LINE__, error_level::error);
×
527
            return nullptr;
×
528
        }
61 ✔
529
    } catch (std::exception const &e) {
61 ✔
530
        error_handler(e, __FILE__, __func__, __LINE__, error_level::error);
1 ✔
531
        return nullptr;
1 ✔
532
    } catch (...) {
1 ✔
533
        error_handler("Unknown exception encountered", __FILE__, __func__,
×
534
                      __LINE__, error_level::error);
×
535
        return nullptr;
×
536
    }
×
537
}
61 ✔
538

539
__dpctl_give DPCTLSyclEventRef
540
DPCTLQueue_SubmitNDRange(__dpctl_keep const DPCTLSyclKernelRef KRef,
541
                         __dpctl_keep const DPCTLSyclQueueRef QRef,
542
                         __dpctl_keep void **Args,
543
                         __dpctl_keep const DPCTLKernelArgType *ArgTypes,
544
                         size_t NArgs,
545
                         __dpctl_keep const size_t gRange[3],
546
                         __dpctl_keep const size_t lRange[3],
547
                         size_t NDims,
548
                         __dpctl_keep const DPCTLSyclEventRef *DepEvents,
549
                         size_t NDepEvents)
550
{
83 ✔
551
    auto Kernel = unwrap<kernel>(KRef);
83 ✔
552
    auto Queue = unwrap<queue>(QRef);
83 ✔
553
    event e;
83 ✔
554

555
    try {
83 ✔
556
        switch (NDims) {
83 ✔
557
        case 1:
69 !
558
        {
69 ✔
559
            e = Queue->submit([&](handler &cgh) {
69 ✔
560
                // Depend on any event that was specified by the caller.
561
                set_dependent_events(cgh, DepEvents, NDepEvents);
69 ✔
562
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
69 ✔
563
                cgh.parallel_for(nd_range<1>{{gRange[0]}, {lRange[0]}},
69 ✔
564
                                 *Kernel);
69 ✔
565
            });
69 ✔
566
            return wrap<event>(new event(std::move(e)));
69 ✔
567
        }
×
568
        case 2:
7 !
569
        {
7 ✔
570
            e = Queue->submit([&](handler &cgh) {
7 ✔
571
                // Depend on any event that was specified by the caller.
572
                set_dependent_events(cgh, DepEvents, NDepEvents);
7 ✔
573
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
7 ✔
574
                cgh.parallel_for(
7 ✔
575
                    nd_range<2>{{gRange[0], gRange[1]}, {lRange[0], lRange[1]}},
7 ✔
576
                    *Kernel);
7 ✔
577
            });
7 ✔
578
            return wrap<event>(new event(std::move(e)));
7 ✔
579
        }
×
580
        case 3:
7 !
581
        {
7 ✔
582
            e = Queue->submit([&](handler &cgh) {
7 ✔
583
                // Depend on any event that was specified by the caller.
584
                set_dependent_events(cgh, DepEvents, NDepEvents);
7 ✔
585
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
7 ✔
586
                cgh.parallel_for(nd_range<3>{{gRange[0], gRange[1], gRange[2]},
7 ✔
587
                                             {lRange[0], lRange[1], lRange[2]}},
7 ✔
588
                                 *Kernel);
7 ✔
589
            });
7 ✔
590
            return wrap<event>(new event(std::move(e)));
7 ✔
591
        }
×
592
        default:
×
593
            error_handler("Range cannot be greater than three "
×
594
                          "dimensions.",
×
595
                          __FILE__, __func__, __LINE__, error_level::error);
×
596
            return nullptr;
×
597
        }
83 ✔
598
    } catch (std::exception const &e) {
83 ✔
599
        error_handler(e, __FILE__, __func__, __LINE__, error_level::error);
1 ✔
600
        return nullptr;
1 ✔
601
    } catch (...) {
1 ✔
602
        error_handler("Unknown exception encountered", __FILE__, __func__,
×
603
                      __LINE__, error_level::error);
×
604
        return nullptr;
×
605
    }
×
606
}
83 ✔
607

608
void DPCTLQueue_Wait(__dpctl_keep DPCTLSyclQueueRef QRef)
609
{
109,483 ✔
610
    // \todo what happens if the QRef is null or a pointer to a valid sycl
611
    // queue
612
    if (QRef) {
109,483 !
613
        auto SyclQueue = unwrap<queue>(QRef);
109,483 ✔
614
        if (SyclQueue)
109,483 !
615
            SyclQueue->wait();
109,483 ✔
616
    }
109,483 ✔
617
    else {
×
618
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
×
619
    }
×
620
}
109,483 ✔
621

622
__dpctl_give DPCTLSyclEventRef
623
DPCTLQueue_Memcpy(__dpctl_keep const DPCTLSyclQueueRef QRef,
624
                  void *Dest,
625
                  const void *Src,
626
                  size_t Count)
627
{
92,313 ✔
628
    auto Q = unwrap<queue>(QRef);
92,313 ✔
629
    if (Q) {
92,313 ✔
630
        sycl::event ev;
92,312 ✔
631
        try {
92,312 ✔
632
            ev = Q->memcpy(Dest, Src, Count);
92,312 ✔
633
        } catch (std::exception const &e) {
92,312 ✔
634
            error_handler(e, __FILE__, __func__, __LINE__);
8 ✔
635
            return nullptr;
8 ✔
636
        }
8 ✔
637
        return wrap<event>(new event(std::move(ev)));
92,304 ✔
638
    }
92,312 ✔
639
    else {
1 ✔
640
        error_handler("QRef passed to memcpy was NULL.", __FILE__, __func__,
1 ✔
641
                      __LINE__);
1 ✔
642
        return nullptr;
1 ✔
643
    }
1 ✔
644
}
92,313 ✔
645

646
__dpctl_give DPCTLSyclEventRef
647
DPCTLQueue_MemcpyWithEvents(__dpctl_keep const DPCTLSyclQueueRef QRef,
648
                            void *Dest,
649
                            const void *Src,
650
                            size_t Count,
651
                            const DPCTLSyclEventRef *DepEvents,
652
                            size_t DepEventsCount)
653
{
59 ✔
654
    event ev;
59 ✔
655
    auto Q = unwrap<queue>(QRef);
59 ✔
656
    if (Q) {
59 ✔
657
        try {
58 ✔
658
            ev = Q->submit([&](handler &cgh) {
58 ✔
659
                if (DepEvents)
58 ✔
660
                    for (size_t i = 0; i < DepEventsCount; ++i) {
100 ✔
661
                        event *ei = unwrap<event>(DepEvents[i]);
50 ✔
662
                        if (ei)
50 !
663
                            cgh.depends_on(*ei);
50 ✔
664
                    }
50 ✔
665

666
                cgh.memcpy(Dest, Src, Count);
58 ✔
667
            });
58 ✔
668
        } catch (const std::exception &ex) {
58 ✔
669
            error_handler(ex, __FILE__, __func__, __LINE__);
8 ✔
670
            return nullptr;
8 ✔
671
        }
8 ✔
672
    }
58 ✔
673
    else {
1 ✔
674
        error_handler("QRef passed to memcpy was NULL.", __FILE__, __func__,
1 ✔
675
                      __LINE__);
1 ✔
676
        return nullptr;
1 ✔
677
    }
1 ✔
678

679
    return wrap<event>(new event(ev));
50 ✔
680
}
59 ✔
681

682
__dpctl_give DPCTLSyclEventRef
683
DPCTLQueue_Prefetch(__dpctl_keep DPCTLSyclQueueRef QRef,
684
                    const void *Ptr,
685
                    size_t Count)
686
{
16 ✔
687
    auto Q = unwrap<queue>(QRef);
16 ✔
688
    if (Q) {
16 ✔
689
        if (Ptr) {
15 ✔
690
            sycl::event ev;
7 ✔
691
            try {
7 ✔
692
                ev = Q->prefetch(Ptr, Count);
7 ✔
693
            } catch (std::exception const &e) {
7 ✔
694
                error_handler(e, __FILE__, __func__, __LINE__);
×
695
                return nullptr;
×
696
            }
×
697
            return wrap<event>(new event(std::move(ev)));
7 ✔
698
        }
7 ✔
699
        else {
8 ✔
700
            error_handler("Attempt to prefetch USM-allocation at nullptr.",
8 ✔
701
                          __FILE__, __func__, __LINE__);
8 ✔
702
            return nullptr;
8 ✔
703
        }
8 ✔
704
    }
15 ✔
705
    else {
1 ✔
706
        error_handler("QRef passed to prefetch was NULL.", __FILE__, __func__,
1 ✔
707
                      __LINE__);
1 ✔
708
        return nullptr;
1 ✔
709
    }
1 ✔
710
}
16 ✔
711

712
__dpctl_give DPCTLSyclEventRef
713
DPCTLQueue_MemAdvise(__dpctl_keep DPCTLSyclQueueRef QRef,
714
                     const void *Ptr,
715
                     size_t Count,
716
                     int Advice)
717
{
16 ✔
718
    auto Q = unwrap<queue>(QRef);
16 ✔
719
    if (Q) {
16 ✔
720
        sycl::event ev;
15 ✔
721
        try {
15 ✔
722
            ev = Q->mem_advise(Ptr, Count, Advice);
15 ✔
723
        } catch (std::exception const &e) {
15 ✔
724
            error_handler(e, __FILE__, __func__, __LINE__);
×
725
            return nullptr;
×
726
        }
×
727
        return wrap<event>(new event(std::move(ev)));
15 ✔
728
    }
15 ✔
729
    else {
1 ✔
730
        error_handler("QRef passed to prefetch was NULL.", __FILE__, __func__,
1 ✔
731
                      __LINE__);
1 ✔
732
        return nullptr;
1 ✔
733
    }
1 ✔
734
}
16 ✔
735

736
bool DPCTLQueue_IsInOrder(__dpctl_keep const DPCTLSyclQueueRef QRef)
737
{
830 ✔
738
    auto Q = unwrap<queue>(QRef);
830 ✔
739
    if (Q) {
830 ✔
740
        return Q->is_in_order();
829 ✔
741
    }
829 ✔
742
    else
1 ✔
743
        return false;
1 ✔
744
}
830 ✔
745

746
bool DPCTLQueue_HasEnableProfiling(__dpctl_keep const DPCTLSyclQueueRef QRef)
747
{
75 ✔
748
    auto Q = unwrap<queue>(QRef);
75 ✔
749
    if (Q) {
75 ✔
750
        return Q->has_property<sycl::property::queue::enable_profiling>();
74 ✔
751
    }
74 ✔
752
    else
1 ✔
753
        return false;
1 ✔
754
}
75 ✔
755

756
size_t DPCTLQueue_Hash(__dpctl_keep const DPCTLSyclQueueRef QRef)
757
{
324,606 ✔
758
    auto Q = unwrap<queue>(QRef);
324,606 ✔
759
    if (Q) {
324,606 ✔
760
        std::hash<queue> hash_fn;
324,603 ✔
761
        return hash_fn(*Q);
324,603 ✔
762
    }
324,603 ✔
763
    else {
3 ✔
764
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
3 ✔
765
        return 0;
3 ✔
766
    }
3 ✔
767
}
324,606 ✔
768

769
__dpctl_give DPCTLSyclEventRef DPCTLQueue_SubmitBarrierForEvents(
770
    __dpctl_keep const DPCTLSyclQueueRef QRef,
771
    __dpctl_keep const DPCTLSyclEventRef *DepEvents,
772
    size_t NDepEvents)
773
{
117 ✔
774
    auto Q = unwrap<queue>(QRef);
117 ✔
775
    event e;
117 ✔
776
    if (Q) {
117 !
777
        try {
117 ✔
778
            e = Q->submit([&](handler &cgh) {
117 ✔
779
                // Depend on any event that was specified by the caller.
780
                if (NDepEvents)
117 ✔
781
                    for (auto i = 0ul; i < NDepEvents; ++i)
28 ✔
782
                        cgh.depends_on(*unwrap<event>(DepEvents[i]));
17 ✔
783

784
                cgh.ext_oneapi_barrier();
117 ✔
785
            });
117 ✔
786
        } catch (std::exception const &e) {
117 ✔
787
            error_handler(e, __FILE__, __func__, __LINE__);
×
788
            return nullptr;
×
789
        }
×
790

791
        return wrap<event>(new event(std::move(e)));
117 ✔
792
    }
117 ✔
793
    else {
×
794
        error_handler("Argument QRef is NULL", __FILE__, __func__, __LINE__);
×
795
        return nullptr;
×
796
    }
×
797
}
117 ✔
798

799
__dpctl_give DPCTLSyclEventRef
800
DPCTLQueue_SubmitBarrier(__dpctl_keep const DPCTLSyclQueueRef QRef)
801
{
1 ✔
802
    return DPCTLQueue_SubmitBarrierForEvents(QRef, nullptr, 0);
1 ✔
803
}
1 ✔
804

805
__dpctl_give DPCTLSyclEventRef
806
DPCTLQueue_Memset(__dpctl_keep const DPCTLSyclQueueRef QRef,
807
                  void *USMRef,
808
                  uint8_t Value,
809
                  size_t Count)
810
{
25 ✔
811
    auto Q = unwrap<queue>(QRef);
25 ✔
812
    if (Q && USMRef) {
25 !
813
        sycl::event ev;
24 ✔
814
        try {
24 ✔
815
            ev = Q->memset(USMRef, static_cast<int>(Value), Count);
24 ✔
816
        } catch (std::exception const &e) {
24 ✔
817
            error_handler(e, __FILE__, __func__, __LINE__);
×
818
            return nullptr;
×
819
        }
×
820
        return wrap<event>(new event(std::move(ev)));
24 ✔
821
    }
24 ✔
822
    else {
1 ✔
823
        error_handler("QRef or USMRef passed to fill8 were NULL.", __FILE__,
1 ✔
824
                      __func__, __LINE__);
1 ✔
825
        return nullptr;
1 ✔
826
    }
1 ✔
827
};
25 ✔
828

829
__dpctl_give DPCTLSyclEventRef
830
DPCTLQueue_Fill8(__dpctl_keep const DPCTLSyclQueueRef QRef,
831
                 void *USMRef,
832
                 uint8_t Value,
833
                 size_t Count)
834
{
9 ✔
835
    auto Q = unwrap<queue>(QRef);
9 ✔
836
    if (Q && USMRef) {
9 !
837
        sycl::event ev;
8 ✔
838
        try {
8 ✔
839
            ev = Q->fill<uint8_t>(USMRef, Value, Count);
8 ✔
840
        } catch (std::exception const &e) {
8 ✔
841
            error_handler(e, __FILE__, __func__, __LINE__);
×
842
            return nullptr;
×
843
        }
×
844
        return wrap<event>(new event(std::move(ev)));
8 ✔
845
    }
8 ✔
846
    else {
1 ✔
847
        error_handler("QRef or USMRef passed to fill8 were NULL.", __FILE__,
1 ✔
848
                      __func__, __LINE__);
1 ✔
849
        return nullptr;
1 ✔
850
    }
1 ✔
851
}
9 ✔
852

853
__dpctl_give DPCTLSyclEventRef
854
DPCTLQueue_Fill16(__dpctl_keep const DPCTLSyclQueueRef QRef,
855
                  void *USMRef,
856
                  uint16_t Value,
857
                  size_t Count)
858
{
9 ✔
859
    auto Q = unwrap<queue>(QRef);
9 ✔
860
    if (Q && USMRef) {
9 !
861
        sycl::event ev;
8 ✔
862
        try {
8 ✔
863
            ev = Q->fill<uint16_t>(USMRef, Value, Count);
8 ✔
864
        } catch (std::exception const &e) {
8 ✔
865
            error_handler(e, __FILE__, __func__, __LINE__);
×
866
            return nullptr;
×
867
        }
×
868
        return wrap<event>(new event(std::move(ev)));
8 ✔
869
    }
8 ✔
870
    else {
1 ✔
871
        error_handler("QRef or USMRef passed to fill16 were NULL.", __FILE__,
1 ✔
872
                      __func__, __LINE__);
1 ✔
873
        return nullptr;
1 ✔
874
    }
1 ✔
875
}
9 ✔
876

877
__dpctl_give DPCTLSyclEventRef
878
DPCTLQueue_Fill32(__dpctl_keep const DPCTLSyclQueueRef QRef,
879
                  void *USMRef,
880
                  uint32_t Value,
881
                  size_t Count)
882
{
9 ✔
883
    auto Q = unwrap<queue>(QRef);
9 ✔
884
    if (Q && USMRef) {
9 !
885
        sycl::event ev;
8 ✔
886
        try {
8 ✔
887
            ev = Q->fill<uint32_t>(USMRef, Value, Count);
8 ✔
888
        } catch (std::exception const &e) {
8 ✔
889
            error_handler(e, __FILE__, __func__, __LINE__);
×
890
            return nullptr;
×
891
        }
×
892
        return wrap<event>(new event(std::move(ev)));
8 ✔
893
    }
8 ✔
894
    else {
1 ✔
895
        error_handler("QRef or USMRef passed to fill32 were NULL.", __FILE__,
1 ✔
896
                      __func__, __LINE__);
1 ✔
897
        return nullptr;
1 ✔
898
    }
1 ✔
899
}
9 ✔
900

901
__dpctl_give DPCTLSyclEventRef
902
DPCTLQueue_Fill64(__dpctl_keep const DPCTLSyclQueueRef QRef,
903
                  void *USMRef,
904
                  uint64_t Value,
905
                  size_t Count)
906
{
9 ✔
907
    auto Q = unwrap<queue>(QRef);
9 ✔
908
    if (Q && USMRef) {
9 !
909
        sycl::event ev;
8 ✔
910
        try {
8 ✔
911
            ev = Q->fill<uint64_t>(USMRef, Value, Count);
8 ✔
912
        } catch (std::exception const &e) {
8 ✔
913
            error_handler(e, __FILE__, __func__, __LINE__);
×
914
            return nullptr;
×
915
        }
×
916
        return wrap<event>(new event(std::move(ev)));
8 ✔
917
    }
8 ✔
918
    else {
1 ✔
919
        error_handler("QRef or USMRef passed to fill64 were NULL.", __FILE__,
1 ✔
920
                      __func__, __LINE__);
1 ✔
921
        return nullptr;
1 ✔
922
    }
1 ✔
923
}
9 ✔
924

925
__dpctl_give DPCTLSyclEventRef
926
DPCTLQueue_Fill128(__dpctl_keep const DPCTLSyclQueueRef QRef,
927
                   void *USMRef,
928
                   uint64_t *Value,
929
                   size_t Count)
930
{
9 ✔
931
    auto Q = unwrap<queue>(QRef);
9 ✔
932
    if (Q && USMRef) {
9 !
933
        sycl::event ev;
8 ✔
934
        try {
8 ✔
935
            complexNumber Val;
8 ✔
936
            Val.real = Value[0];
8 ✔
937
            Val.imag = Value[1];
8 ✔
938
            ev = Q->fill(USMRef, Val, Count);
8 ✔
939
        } catch (std::exception const &e) {
8 ✔
940
            error_handler(e, __FILE__, __func__, __LINE__);
×
941
            return nullptr;
×
942
        }
×
943
        return wrap<event>(new event(std::move(ev)));
8 ✔
944
    }
8 ✔
945
    else {
1 ✔
946
        error_handler("QRef or USMRef passed to fill128 were NULL.", __FILE__,
1 ✔
947
                      __func__, __LINE__);
948
        return nullptr;
1 ✔
949
    }
1 ✔
950
}
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