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

IntelPython / dpctl / 28987370442

09 Jul 2026 01:22AM UTC coverage: 75.013% (+0.4%) from 74.579%
28987370442

Pull #2335

github

web-flow
Merge 3038c6e50 into 8d8b48a11
Pull Request #2335: Add dpctl dtype objects

902 of 1274 branches covered (70.8%)

Branch coverage included in aggregate %.

149 of 169 new or added lines in 3 files covered. (88.17%)

3523 of 4625 relevant lines covered (76.17%)

255.46 hits per line

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

85.82
/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 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 <complex>
39
#include <cstdint>
40
#include <exception>
41
#include <sstream>
42
#include <stdexcept>
43
#include <sycl/sycl.hpp> /* SYCL headers   */
44
#include <utility>
45
#include <vector>
46

47
#if defined(SYCL_EXT_ONEAPI_WORK_GROUP_MEMORY) ||                              \
48
    defined(SYCL_EXT_ONEAPI_RAW_KERNEL_ARG)
49
#include "dpctl_sycl_extension_interface.h"
50
#endif
51

52
using namespace sycl;
53

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

142
namespace
143
{
144
static_assert(__SYCL_COMPILER_VERSION >= __SYCL_COMPILER_VERSION_REQUIRED,
145
              "The compiler does not meet minimum version requirement");
146

147
using namespace dpctl::syclinterface;
148

149
typedef struct complex
150
{
151
    std::uint64_t real;
152
    std::uint64_t imag;
153
} complexNumber;
154

155
void set_dependent_events(handler &cgh,
156
                          __dpctl_keep const DPCTLSyclEventRef *DepEvents,
157
                          size_t NDepEvents)
158
{
193✔
159
    for (auto i = 0ul; i < NDepEvents; ++i) {
347✔
160
        auto ei = unwrap<event>(DepEvents[i]);
154✔
161
        if (ei)
154!
162
            cgh.depends_on(*ei);
154✔
163
    }
154✔
164
}
193✔
165

166
bool set_local_accessor_arg(handler &cgh,
167
                            size_t idx,
168
                            const MDLocalAccessor *mdstruct)
169
{
31✔
170
    switch (mdstruct->ndim) {
31✔
171
    case 1:
11✔
172
    {
11✔
173
        auto r = range<1>(mdstruct->dim0);
11✔
174
        SET_LOCAL_ACCESSOR_ARG(cgh, 1, mdstruct->dpctl_type_id, r, idx);
11✔
175
    }
×
176
    case 2:
10✔
177
    {
10✔
178
        auto r = range<2>(mdstruct->dim0, mdstruct->dim1);
10✔
179
        SET_LOCAL_ACCESSOR_ARG(cgh, 2, mdstruct->dpctl_type_id, r, idx);
10✔
180
    }
×
181
    case 3:
10✔
182
    {
10✔
183
        auto r = range<3>(mdstruct->dim0, mdstruct->dim1, mdstruct->dim2);
10✔
184
        SET_LOCAL_ACCESSOR_ARG(cgh, 3, mdstruct->dpctl_type_id, r, idx);
10✔
185
    }
×
186
    default:
×
187
        return false;
×
188
    }
31✔
189
}
31✔
190
/*!
191
 * @brief Set the kernel arg object
192
 *
193
 * @param cgh   SYCL command group handler using which a kernel is going to
194
 *              be submitted.
195
 * @param idx   The position of the argument in the list of arguments passed
196
 * to a kernel.
197
 * @param Arg   A void* representing a kernel argument.
198
 * @param Argty A typeid specifying the C++ type of the Arg parameter.
199
 */
200
bool set_kernel_arg(handler &cgh,
201
                    size_t idx,
202
                    __dpctl_keep void *Arg,
203
                    DPCTLKernelArgType ArgTy)
204
{
561✔
205
    bool arg_set = true;
561✔
206

207
    switch (ArgTy) {
561✔
208
    case DPCTL_INT8_T:
3✔
209
        cgh.set_arg(idx, *(std::int8_t *)Arg);
3✔
210
        break;
3✔
211
    case DPCTL_UINT8_T:
3✔
212
        cgh.set_arg(idx, *(std::uint8_t *)Arg);
3✔
213
        break;
3✔
214
    case DPCTL_INT16_T:
9✔
215
        cgh.set_arg(idx, *(std::int16_t *)Arg);
9✔
216
        break;
9✔
217
    case DPCTL_UINT16_T:
3✔
218
        cgh.set_arg(idx, *(std::uint16_t *)Arg);
3✔
219
        break;
3✔
220
    case DPCTL_INT32_T:
11✔
221
        cgh.set_arg(idx, *(std::int32_t *)Arg);
11✔
222
        break;
11✔
223
    case DPCTL_UINT32_T:
13✔
224
        cgh.set_arg(idx, *(std::uint32_t *)Arg);
13✔
225
        break;
13✔
226
    case DPCTL_INT64_T:
11✔
227
        cgh.set_arg(idx, *(std::int64_t *)Arg);
11✔
228
        break;
11✔
229
    case DPCTL_UINT64_T:
14✔
230
        cgh.set_arg(idx, *(std::uint64_t *)Arg);
14✔
231
        break;
14✔
232
    case DPCTL_FLOAT32_T:
11✔
233
        cgh.set_arg(idx, *(float *)Arg);
11✔
234
        break;
11✔
235
    case DPCTL_FLOAT64_T:
12✔
236
        cgh.set_arg(idx, *(double *)Arg);
12✔
237
        break;
12✔
238
    case DPCTL_FLOAT16_T:
2✔
239
        cgh.set_arg(idx, *(sycl::half *)Arg);
2✔
240
        break;
2✔
241
    case DPCTL_COMPLEX64_T:
2✔
242
        cgh.set_arg(idx, *(std::complex<float> *)Arg);
2✔
243
        break;
2✔
244
    case DPCTL_COMPLEX128_T:
2✔
245
        cgh.set_arg(idx, *(std::complex<double> *)Arg);
2✔
246
        break;
2✔
247
    case DPCTL_VOID_PTR:
372✔
248
        cgh.set_arg(idx, Arg);
372✔
249
        break;
372✔
250
    case DPCTL_LOCAL_ACCESSOR:
31✔
251
        arg_set = set_local_accessor_arg(cgh, idx, (MDLocalAccessor *)Arg);
31✔
252
        break;
31✔
253
#ifdef SYCL_EXT_ONEAPI_WORK_GROUP_MEMORY
×
254
    case DPCTL_WORK_GROUP_MEMORY:
31✔
255
    {
31✔
256
        auto ref = static_cast<DPCTLSyclWorkGroupMemoryRef>(Arg);
31✔
257
        RawWorkGroupMemory *raw_mem = unwrap<RawWorkGroupMemory>(ref);
31✔
258
        size_t num_bytes = raw_mem->nbytes;
31✔
259
        sycl::ext::oneapi::experimental::work_group_memory<char[]> mem{
31✔
260
            num_bytes, cgh};
31✔
261
        cgh.set_arg(idx, mem);
31✔
262
        break;
31✔
263
    }
×
264
#endif
×
265
#ifdef SYCL_EXT_ONEAPI_RAW_KERNEL_ARG
×
266
    case DPCTL_RAW_KERNEL_ARG:
30✔
267
    {
30✔
268
        auto ref = static_cast<DPCTLSyclRawKernelArgRef>(Arg);
30✔
269
        std::vector<unsigned char> *raw_arg =
30✔
270
            unwrap<std::vector<unsigned char>>(ref);
30✔
271
        void *bytes = raw_arg->data();
30✔
272
        size_t count = raw_arg->size();
30✔
273
        sycl::ext::oneapi::experimental::raw_kernel_arg arg{bytes, count};
30✔
274
        cgh.set_arg(idx, arg);
30✔
275
        break;
30✔
276
    }
×
277
#endif
×
278
    default:
1✔
279
        arg_set = false;
1✔
280
        break;
1✔
281
    }
561✔
282
    return arg_set;
561✔
283
}
561✔
284

285
void set_kernel_args(handler &cgh,
286
                     __dpctl_keep void **Args,
287
                     __dpctl_keep const DPCTLKernelArgType *ArgTypes,
288
                     size_t NArgs)
289
{
193✔
290
    for (auto i = 0ul; i < NArgs; ++i) {
752✔
291
        if (!set_kernel_arg(cgh, i, Args[i], ArgTypes[i])) {
561✔
292
            error_handler("Kernel argument could not be created.", __FILE__,
2✔
293
                          __func__, __LINE__);
2✔
294
            throw std::invalid_argument(
2✔
295
                "Kernel argument could not be created.");
2✔
296
        }
2✔
297
    }
561✔
298
}
193✔
299

300
std::unique_ptr<property_list> create_property_list(int properties)
301
{
1,430✔
302
    std::unique_ptr<property_list> propList;
1,430✔
303
    int _prop = properties;
1,430✔
304
    if (_prop & DPCTL_ENABLE_PROFILING) {
1,430✔
305
        _prop = _prop ^ DPCTL_ENABLE_PROFILING;
62✔
306
        if (_prop & DPCTL_IN_ORDER) {
62✔
307
            _prop = _prop ^ DPCTL_IN_ORDER;
24✔
308
            propList = std::make_unique<property_list>(
24✔
309
                sycl::property::queue::enable_profiling(),
24✔
310
                sycl::property::queue::in_order());
24✔
311
        }
24✔
312
        else {
38✔
313
            propList = std::make_unique<property_list>(
38✔
314
                sycl::property::queue::enable_profiling());
38✔
315
        }
38✔
316
    }
62✔
317
    else if (_prop & DPCTL_IN_ORDER) {
1,368✔
318
        _prop = _prop ^ DPCTL_IN_ORDER;
434✔
319
        propList =
434✔
320
            std::make_unique<property_list>(sycl::property::queue::in_order());
434✔
321
    }
434✔
322
    else {
934✔
323
        propList = std::make_unique<property_list>();
934✔
324
    }
934✔
325

326
    if (_prop) {
1,430✔
327
        std::stringstream ss;
1✔
328
        ss << "Invalid queue property argument (" << std::hex << properties
1✔
329
           << "), interpreted as (" << (properties ^ _prop) << ").";
1✔
330
        error_handler(ss.str(), __FILE__, __func__, __LINE__);
1✔
331
    }
1✔
332
    return propList;
1,430✔
333
}
1,430✔
334

335
__dpctl_give DPCTLSyclQueueRef
336
getQueueImpl(__dpctl_keep DPCTLSyclContextRef cRef,
337
             __dpctl_keep DPCTLSyclDeviceRef dRef,
338
             error_handler_callback *handler,
339
             int properties)
340
{
159✔
341
    DPCTLSyclQueueRef qRef = nullptr;
159✔
342
    qRef = DPCTLQueue_Create(cRef, dRef, handler, properties);
159✔
343
    return qRef;
159✔
344
}
159✔
345

346
} /* end of anonymous namespace */
347

348
DPCTL_API
349
__dpctl_give DPCTLSyclQueueRef
350
DPCTLQueue_Create(__dpctl_keep const DPCTLSyclContextRef CRef,
351
                  __dpctl_keep const DPCTLSyclDeviceRef DRef,
352
                  error_handler_callback *handler,
353
                  int properties)
354
{
1,432✔
355
    DPCTLSyclQueueRef q = nullptr;
1,432✔
356
    auto dev = unwrap<device>(DRef);
1,432✔
357
    auto ctx = unwrap<context>(CRef);
1,432✔
358

359
    if (!(dev && ctx)) {
1,432✔
360
        error_handler("Cannot create queue from DPCTLSyclContextRef and "
2✔
361
                      "DPCTLSyclDeviceRef as input is a nullptr.",
2✔
362
                      __FILE__, __func__, __LINE__);
2✔
363
        return q;
2✔
364
    }
2✔
365
    auto propList = create_property_list(properties);
1,430✔
366

367
    if (handler) {
1,430✔
368
        try {
44✔
369
            auto Queue = new queue(*ctx, *dev, DPCTL_AsyncErrorHandler(handler),
44✔
370
                                   *propList);
44✔
371
            q = wrap<queue>(Queue);
44✔
372
        } catch (std::exception const &e) {
44✔
373
            error_handler(e, __FILE__, __func__, __LINE__);
×
374
        }
×
375
    }
44✔
376
    else {
1,386✔
377
        try {
1,386✔
378
            auto Queue = new queue(*ctx, *dev, *propList);
1,386✔
379
            q = wrap<queue>(Queue);
1,386✔
380
        } catch (std::exception const &e) {
1,386✔
381
            error_handler(e, __FILE__, __func__, __LINE__);
1✔
382
        }
1✔
383
    }
1,386✔
384

385
    return q;
1,430✔
386
}
1,430✔
387

388
__dpctl_give DPCTLSyclQueueRef
389
DPCTLQueue_CreateForDevice(__dpctl_keep const DPCTLSyclDeviceRef DRef,
390
                           error_handler_callback *handler,
391
                           int properties)
392
{
345✔
393
    DPCTLSyclContextRef CRef = nullptr;
345✔
394
    DPCTLSyclQueueRef QRef = nullptr;
345✔
395
    auto Device = unwrap<device>(DRef);
345✔
396

397
    if (!Device) {
345✔
398
        error_handler("Cannot create queue from NULL device reference.",
186✔
399
                      __FILE__, __func__, __LINE__);
186✔
400
        return QRef;
186✔
401
    }
186✔
402
    // Check if a cached default context exists for the device.
403
    CRef = DPCTLDeviceMgr_GetCachedContext(DRef);
159✔
404
    // If a cached default context was found, that context will be used to use
405
    // create the new queue. When a default cached context was not found, as
406
    // will be the case for non-root devices, i.e., sub-devices, a new context
407
    // will be allocated. Note that any newly allocated context is not cached.
408
    if (!CRef) {
159!
409
        context *ContextPtr = nullptr;
×
410
        try {
×
411
            ContextPtr = new context(*Device);
×
412
            CRef = wrap<context>(ContextPtr);
×
413
        } catch (std::exception const &e) {
×
414
            error_handler(e, __FILE__, __func__, __LINE__);
×
415
            delete ContextPtr;
×
416
            return QRef;
×
417
        }
×
418
    }
×
419
    // At this point we have a valid context and the queue can be allocated.
420
    QRef = getQueueImpl(CRef, DRef, handler, properties);
159✔
421
    // Free the context
422
    DPCTLContext_Delete(CRef);
159✔
423
    return QRef;
159✔
424
}
159✔
425

426
/*!
427
 * Delete the passed in pointer after verifying it points to a sycl::queue.
428
 */
429
void DPCTLQueue_Delete(__dpctl_take DPCTLSyclQueueRef QRef)
430
{
1,726✔
431
    delete unwrap<queue>(QRef);
1,726✔
432
}
1,726✔
433

434
/*!
435
 * Make copy of sycl::queue referenced by passed pointer
436
 */
437
__dpctl_give DPCTLSyclQueueRef
438
DPCTLQueue_Copy(__dpctl_keep const DPCTLSyclQueueRef QRef)
439
{
116✔
440
    auto Queue = unwrap<queue>(QRef);
116✔
441
    if (Queue) {
116✔
442
        try {
115✔
443
            auto CopiedQueue = new queue(*Queue);
115✔
444
            return wrap<queue>(CopiedQueue);
115✔
445
        } catch (std::exception const &e) {
115✔
446
            error_handler(e, __FILE__, __func__, __LINE__);
×
447
            return nullptr;
×
448
        }
×
449
    }
115✔
450
    else {
1✔
451
        error_handler("Cannot copy DPCTLSyclQueueRef as input is a nullptr",
1✔
452
                      __FILE__, __func__, __LINE__);
1✔
453
        return nullptr;
1✔
454
    }
1✔
455
}
116✔
456

457
bool DPCTLQueue_AreEq(__dpctl_keep const DPCTLSyclQueueRef QRef1,
458
                      __dpctl_keep const DPCTLSyclQueueRef QRef2)
459
{
13✔
460
    if (!(QRef1 && QRef2)) {
13✔
461
        error_handler("DPCTLSyclQueueRefs are nullptr.", __FILE__, __func__,
2✔
462
                      __LINE__);
2✔
463
        return false;
2✔
464
    }
2✔
465
    return (*unwrap<queue>(QRef1) == *unwrap<queue>(QRef2));
11✔
466
}
13✔
467

468
DPCTLSyclBackendType DPCTLQueue_GetBackend(__dpctl_keep DPCTLSyclQueueRef QRef)
469
{
10✔
470
    auto Q = unwrap<queue>(QRef);
10✔
471
    if (Q) {
10✔
472
        try {
9✔
473
            auto C = Q->get_context();
9✔
474
            return DPCTLContext_GetBackend(wrap<context>(&C));
9✔
475
        } catch (std::exception const &e) {
9✔
476
            error_handler(e, __FILE__, __func__, __LINE__);
×
477
            return DPCTL_UNKNOWN_BACKEND;
×
478
        }
×
479
    }
9✔
480
    else
1✔
481
        return DPCTL_UNKNOWN_BACKEND;
1✔
482
}
10✔
483

484
__dpctl_give DPCTLSyclDeviceRef
485
DPCTLQueue_GetDevice(__dpctl_keep const DPCTLSyclQueueRef QRef)
486
{
74✔
487
    DPCTLSyclDeviceRef DRef = nullptr;
74✔
488
    auto Q = unwrap<queue>(QRef);
74✔
489
    if (Q) {
74✔
490
        try {
73✔
491
            auto Device = new device(Q->get_device());
73✔
492
            DRef = wrap<device>(Device);
73✔
493
        } catch (std::exception const &e) {
73✔
494
            error_handler(e, __FILE__, __func__, __LINE__);
×
495
        }
×
496
    }
73✔
497
    else {
1✔
498
        error_handler("Could not get the device for this queue.", __FILE__,
1✔
499
                      __func__, __LINE__);
1✔
500
    }
1✔
501
    return DRef;
74✔
502
}
74✔
503

504
__dpctl_give DPCTLSyclContextRef
505
DPCTLQueue_GetContext(__dpctl_keep const DPCTLSyclQueueRef QRef)
506
{
140✔
507
    auto Q = unwrap<queue>(QRef);
140✔
508
    DPCTLSyclContextRef CRef = nullptr;
140✔
509
    if (Q)
140✔
510
        CRef = wrap<context>(new context(Q->get_context()));
130✔
511
    else {
10✔
512
        error_handler("Could not get the context for this queue.", __FILE__,
10✔
513
                      __func__, __LINE__);
10✔
514
    }
10✔
515
    return CRef;
140✔
516
}
140✔
517

518
__dpctl_give DPCTLSyclEventRef
519
DPCTLQueue_SubmitRange(__dpctl_keep const DPCTLSyclKernelRef KRef,
520
                       __dpctl_keep const DPCTLSyclQueueRef QRef,
521
                       __dpctl_keep void **Args,
522
                       __dpctl_keep const DPCTLKernelArgType *ArgTypes,
523
                       size_t NArgs,
524
                       __dpctl_keep const size_t Range[3],
525
                       size_t NDims,
526
                       __dpctl_keep const DPCTLSyclEventRef *DepEvents,
527
                       size_t NDepEvents)
528
{
80✔
529
    auto Kernel = unwrap<kernel>(KRef);
80✔
530
    auto Queue = unwrap<queue>(QRef);
80✔
531
    event e;
80✔
532

533
    try {
80✔
534
        switch (NDims) {
80✔
535
        case 1:
46✔
536
        {
46✔
537
            e = Queue->submit([&](handler &cgh) {
46✔
538
                // Depend on any event that was specified by the caller.
539
                set_dependent_events(cgh, DepEvents, NDepEvents);
46✔
540
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
46✔
541
                cgh.parallel_for(range<1>{Range[0]}, *Kernel);
46✔
542
            });
46✔
543
            return wrap<event>(new event(std::move(e)));
46✔
544
        }
×
545
        case 2:
17✔
546
        {
17✔
547
            e = Queue->submit([&](handler &cgh) {
17✔
548
                // Depend on any event that was specified by the caller.
549
                set_dependent_events(cgh, DepEvents, NDepEvents);
17✔
550
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
17✔
551
                cgh.parallel_for(range<2>{Range[0], Range[1]}, *Kernel);
17✔
552
            });
17✔
553
            return wrap<event>(new event(std::move(e)));
17✔
554
        }
×
555
        case 3:
17✔
556
        {
17✔
557
            e = Queue->submit([&](handler &cgh) {
17✔
558
                // Depend on any event that was specified by the caller.
559
                set_dependent_events(cgh, DepEvents, NDepEvents);
17✔
560
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
17✔
561
                cgh.parallel_for(range<3>{Range[0], Range[1], Range[2]},
17✔
562
                                 *Kernel);
17✔
563
            });
17✔
564
            return wrap<event>(new event(std::move(e)));
17✔
565
        }
×
566
        default:
×
567
            error_handler("Range cannot be greater than three "
×
568
                          "dimensions.",
×
569
                          __FILE__, __func__, __LINE__, error_level::error);
×
570
            return nullptr;
×
571
        }
80✔
572
    } catch (std::exception const &e) {
80✔
573
        error_handler(e, __FILE__, __func__, __LINE__, error_level::error);
1✔
574
        return nullptr;
1✔
575
    } catch (...) {
1✔
576
        error_handler("Unknown exception encountered", __FILE__, __func__,
×
577
                      __LINE__, error_level::error);
×
578
        return nullptr;
×
579
    }
×
580
}
80✔
581

582
__dpctl_give DPCTLSyclEventRef
583
DPCTLQueue_SubmitNDRange(__dpctl_keep const DPCTLSyclKernelRef KRef,
584
                         __dpctl_keep const DPCTLSyclQueueRef QRef,
585
                         __dpctl_keep void **Args,
586
                         __dpctl_keep const DPCTLKernelArgType *ArgTypes,
587
                         size_t NArgs,
588
                         __dpctl_keep const size_t gRange[3],
589
                         __dpctl_keep const size_t lRange[3],
590
                         size_t NDims,
591
                         __dpctl_keep const DPCTLSyclEventRef *DepEvents,
592
                         size_t NDepEvents)
593
{
113✔
594
    auto Kernel = unwrap<kernel>(KRef);
113✔
595
    auto Queue = unwrap<queue>(QRef);
113✔
596
    event e;
113✔
597

598
    try {
113✔
599
        switch (NDims) {
113✔
600
        case 1:
99✔
601
        {
99✔
602
            e = Queue->submit([&](handler &cgh) {
99✔
603
                // Depend on any event that was specified by the caller.
604
                set_dependent_events(cgh, DepEvents, NDepEvents);
99✔
605
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
99✔
606
                cgh.parallel_for(nd_range<1>{{gRange[0]}, {lRange[0]}},
99✔
607
                                 *Kernel);
99✔
608
            });
99✔
609
            return wrap<event>(new event(std::move(e)));
99✔
610
        }
×
611
        case 2:
7✔
612
        {
7✔
613
            e = Queue->submit([&](handler &cgh) {
7✔
614
                // Depend on any event that was specified by the caller.
615
                set_dependent_events(cgh, DepEvents, NDepEvents);
7✔
616
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
7✔
617
                cgh.parallel_for(
7✔
618
                    nd_range<2>{{gRange[0], gRange[1]}, {lRange[0], lRange[1]}},
7✔
619
                    *Kernel);
7✔
620
            });
7✔
621
            return wrap<event>(new event(std::move(e)));
7✔
622
        }
×
623
        case 3:
7✔
624
        {
7✔
625
            e = Queue->submit([&](handler &cgh) {
7✔
626
                // Depend on any event that was specified by the caller.
627
                set_dependent_events(cgh, DepEvents, NDepEvents);
7✔
628
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
7✔
629
                cgh.parallel_for(nd_range<3>{{gRange[0], gRange[1], gRange[2]},
7✔
630
                                             {lRange[0], lRange[1], lRange[2]}},
7✔
631
                                 *Kernel);
7✔
632
            });
7✔
633
            return wrap<event>(new event(std::move(e)));
7✔
634
        }
×
635
        default:
×
636
            error_handler("Range cannot be greater than three "
×
637
                          "dimensions.",
×
638
                          __FILE__, __func__, __LINE__, error_level::error);
×
639
            return nullptr;
×
640
        }
113✔
641
    } catch (std::exception const &e) {
113✔
642
        error_handler(e, __FILE__, __func__, __LINE__, error_level::error);
1✔
643
        return nullptr;
1✔
644
    } catch (...) {
1✔
645
        error_handler("Unknown exception encountered", __FILE__, __func__,
×
646
                      __LINE__, error_level::error);
×
647
        return nullptr;
×
648
    }
×
649
}
113✔
650

651
void DPCTLQueue_Wait(__dpctl_keep DPCTLSyclQueueRef QRef)
652
{
1✔
653
    // \todo what happens if the QRef is null or a pointer to a valid sycl
654
    // queue
655
    if (QRef) {
1!
656
        auto SyclQueue = unwrap<queue>(QRef);
1✔
657
        if (SyclQueue)
1!
658
            SyclQueue->wait();
1✔
659
    }
1✔
660
    else {
×
661
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
×
662
    }
×
663
}
1✔
664

665
__dpctl_give DPCTLSyclEventRef
666
DPCTLQueue_Memcpy(__dpctl_keep const DPCTLSyclQueueRef QRef,
667
                  void *Dest,
668
                  const void *Src,
669
                  size_t Count)
670
{
231✔
671
    auto Q = unwrap<queue>(QRef);
231✔
672
    if (Q) {
231✔
673
        sycl::event ev;
230✔
674
        try {
230✔
675
            ev = Q->memcpy(Dest, Src, Count);
230✔
676
        } catch (std::exception const &e) {
230✔
677
            error_handler(e, __FILE__, __func__, __LINE__);
8✔
678
            return nullptr;
8✔
679
        }
8✔
680
        return wrap<event>(new event(std::move(ev)));
222✔
681
    }
230✔
682
    else {
1✔
683
        error_handler("QRef passed to memcpy was NULL.", __FILE__, __func__,
1✔
684
                      __LINE__);
1✔
685
        return nullptr;
1✔
686
    }
1✔
687
}
231✔
688

689
__dpctl_give DPCTLSyclEventRef
690
DPCTLQueue_MemcpyWithEvents(__dpctl_keep const DPCTLSyclQueueRef QRef,
691
                            void *Dest,
692
                            const void *Src,
693
                            size_t Count,
694
                            const DPCTLSyclEventRef *DepEvents,
695
                            size_t DepEventsCount)
696
{
80✔
697
    event ev;
80✔
698
    auto Q = unwrap<queue>(QRef);
80✔
699
    if (Q) {
80✔
700
        try {
79✔
701
            ev = Q->submit([&](handler &cgh) {
79✔
702
                if (DepEvents)
79✔
703
                    for (size_t i = 0; i < DepEventsCount; ++i) {
242✔
704
                        event *ei = unwrap<event>(DepEvents[i]);
171✔
705
                        if (ei)
171!
706
                            cgh.depends_on(*ei);
171✔
707
                    }
171✔
708

709
                cgh.memcpy(Dest, Src, Count);
79✔
710
            });
79✔
711
        } catch (const std::exception &ex) {
79✔
712
            error_handler(ex, __FILE__, __func__, __LINE__);
8✔
713
            return nullptr;
8✔
714
        }
8✔
715
    }
79✔
716
    else {
1✔
717
        error_handler("QRef passed to memcpy was NULL.", __FILE__, __func__,
1✔
718
                      __LINE__);
1✔
719
        return nullptr;
1✔
720
    }
1✔
721

722
    return wrap<event>(new event(ev));
71✔
723
}
80✔
724

725
__dpctl_give DPCTLSyclEventRef
726
DPCTLQueue_CopyData(__dpctl_keep const DPCTLSyclQueueRef QRef,
727
                    void *Dest,
728
                    const void *Src,
729
                    size_t Count)
730
{
50✔
731
    auto Q = unwrap<queue>(QRef);
50✔
732
    if (Q) {
50✔
733
        sycl::event ev;
49✔
734
        try {
49✔
735
            // Copy uint8_t elements (1 byte each), so Count is a byte count.
736
            ev = Q->copy(static_cast<const std::uint8_t *>(Src),
49✔
737
                         static_cast<std::uint8_t *>(Dest), Count);
49✔
738
        } catch (std::exception const &e) {
49✔
739
            error_handler(e, __FILE__, __func__, __LINE__);
8✔
740
            return nullptr;
8✔
741
        }
8✔
742
        return wrap<event>(new event(std::move(ev)));
41✔
743
    }
49✔
744
    else {
1✔
745
        error_handler("QRef passed to copy was NULL.", __FILE__, __func__,
1✔
746
                      __LINE__);
1✔
747
        return nullptr;
1✔
748
    }
1✔
749
}
50✔
750

751
__dpctl_give DPCTLSyclEventRef
752
DPCTLQueue_CopyDataWithEvents(__dpctl_keep const DPCTLSyclQueueRef QRef,
753
                              void *Dest,
754
                              const void *Src,
755
                              size_t Count,
756
                              const DPCTLSyclEventRef *DepEvents,
757
                              size_t DepEventsCount)
758
{
10✔
759
    auto Q = unwrap<queue>(QRef);
10✔
760
    if (Q) {
10✔
761
        try {
9✔
762
            std::vector<event> dep_events;
9✔
763
            if (DepEvents) {
9✔
764
                dep_events.reserve(DepEventsCount);
1✔
765
                for (size_t i = 0; i < DepEventsCount; ++i) {
2✔
766
                    event *ei = unwrap<event>(DepEvents[i]);
1✔
767
                    if (ei)
1!
768
                        dep_events.push_back(*ei);
1✔
769
                }
1✔
770
            }
1✔
771

772
            // Copy uint8_t elements (1 byte each), so Count is a byte count.
773
            auto ev =
9✔
774
                Q->copy(static_cast<const std::uint8_t *>(Src),
9✔
775
                        static_cast<std::uint8_t *>(Dest), Count, dep_events);
9✔
776
            return wrap<event>(new event(std::move(ev)));
9✔
777
        } catch (const std::exception &ex) {
9✔
778
            error_handler(ex, __FILE__, __func__, __LINE__);
8✔
779
            return nullptr;
8✔
780
        }
8✔
781
    }
9✔
782
    else {
1✔
783
        error_handler("QRef passed to copy was NULL.", __FILE__, __func__,
1✔
784
                      __LINE__);
1✔
785
        return nullptr;
1✔
786
    }
1✔
787
}
10✔
788

789
__dpctl_give DPCTLSyclEventRef
790
DPCTLQueue_Prefetch(__dpctl_keep DPCTLSyclQueueRef QRef,
791
                    const void *Ptr,
792
                    size_t Count)
793
{
16✔
794
    auto Q = unwrap<queue>(QRef);
16✔
795
    if (Q) {
16✔
796
        if (Ptr) {
15✔
797
            sycl::event ev;
7✔
798
            try {
7✔
799
                ev = Q->prefetch(Ptr, Count);
7✔
800
            } catch (std::exception const &e) {
7✔
801
                error_handler(e, __FILE__, __func__, __LINE__);
×
802
                return nullptr;
×
803
            }
×
804
            return wrap<event>(new event(std::move(ev)));
7✔
805
        }
7✔
806
        else {
8✔
807
            error_handler("Attempt to prefetch USM-allocation at nullptr.",
8✔
808
                          __FILE__, __func__, __LINE__);
8✔
809
            return nullptr;
8✔
810
        }
8✔
811
    }
15✔
812
    else {
1✔
813
        error_handler("QRef passed to prefetch was NULL.", __FILE__, __func__,
1✔
814
                      __LINE__);
1✔
815
        return nullptr;
1✔
816
    }
1✔
817
}
16✔
818

819
__dpctl_give DPCTLSyclEventRef
820
DPCTLQueue_MemAdvise(__dpctl_keep DPCTLSyclQueueRef QRef,
821
                     const void *Ptr,
822
                     size_t Count,
823
                     int Advice)
824
{
16✔
825
    auto Q = unwrap<queue>(QRef);
16✔
826
    if (Q) {
16✔
827
        sycl::event ev;
15✔
828
        try {
15✔
829
            ev = Q->mem_advise(Ptr, Count, Advice);
15✔
830
        } catch (std::exception const &e) {
15✔
831
            error_handler(e, __FILE__, __func__, __LINE__);
×
832
            return nullptr;
×
833
        }
×
834
        return wrap<event>(new event(std::move(ev)));
15✔
835
    }
15✔
836
    else {
1✔
837
        error_handler("QRef passed to prefetch was NULL.", __FILE__, __func__,
1✔
838
                      __LINE__);
1✔
839
        return nullptr;
1✔
840
    }
1✔
841
}
16✔
842

843
bool DPCTLQueue_IsInOrder(__dpctl_keep const DPCTLSyclQueueRef QRef)
844
{
830✔
845
    auto Q = unwrap<queue>(QRef);
830✔
846
    if (Q) {
830✔
847
        return Q->is_in_order();
829✔
848
    }
829✔
849
    else
1✔
850
        return false;
1✔
851
}
830✔
852

853
bool DPCTLQueue_HasEnableProfiling(__dpctl_keep const DPCTLSyclQueueRef QRef)
854
{
67✔
855
    auto Q = unwrap<queue>(QRef);
67✔
856
    if (Q) {
67✔
857
        return Q->has_property<sycl::property::queue::enable_profiling>();
66✔
858
    }
66✔
859
    else
1✔
860
        return false;
1✔
861
}
67✔
862

863
size_t DPCTLQueue_Hash(__dpctl_keep const DPCTLSyclQueueRef QRef)
864
{
24✔
865
    auto Q = unwrap<queue>(QRef);
24✔
866
    if (Q) {
24✔
867
        std::hash<queue> hash_fn;
21✔
868
        return hash_fn(*Q);
21✔
869
    }
21✔
870
    else {
3✔
871
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
3✔
872
        return 0;
3✔
873
    }
3✔
874
}
24✔
875

876
__dpctl_give DPCTLSyclEventRef DPCTLQueue_SubmitBarrierForEvents(
877
    __dpctl_keep const DPCTLSyclQueueRef QRef,
878
    __dpctl_keep const DPCTLSyclEventRef *DepEvents,
879
    size_t NDepEvents)
880
{
107✔
881
    auto Q = unwrap<queue>(QRef);
107✔
882
    event e;
107✔
883
    if (Q) {
107!
884
        try {
107✔
885
            e = Q->submit([&](handler &cgh) {
107✔
886
                // Depend on any event that was specified by the caller.
887
                if (NDepEvents)
107✔
888
                    for (auto i = 0ul; i < NDepEvents; ++i)
18✔
889
                        cgh.depends_on(*unwrap<event>(DepEvents[i]));
12✔
890

891
                cgh.ext_oneapi_barrier();
107✔
892
            });
107✔
893
        } catch (std::exception const &e) {
107✔
894
            error_handler(e, __FILE__, __func__, __LINE__);
×
895
            return nullptr;
×
896
        }
×
897

898
        return wrap<event>(new event(std::move(e)));
107✔
899
    }
107✔
900
    else {
×
901
        error_handler("Argument QRef is NULL", __FILE__, __func__, __LINE__);
×
902
        return nullptr;
×
903
    }
×
904
}
107✔
905

906
__dpctl_give DPCTLSyclEventRef
907
DPCTLQueue_SubmitBarrier(__dpctl_keep const DPCTLSyclQueueRef QRef)
908
{
1✔
909
    return DPCTLQueue_SubmitBarrierForEvents(QRef, nullptr, 0);
1✔
910
}
1✔
911

912
__dpctl_give DPCTLSyclEventRef
913
DPCTLQueue_Memset(__dpctl_keep const DPCTLSyclQueueRef QRef,
914
                  void *USMRef,
915
                  uint8_t Value,
916
                  size_t Count)
917
{
62✔
918
    auto Q = unwrap<queue>(QRef);
62✔
919
    if (Q && USMRef) {
62!
920
        sycl::event ev;
61✔
921
        try {
61✔
922
            ev = Q->memset(USMRef, static_cast<int>(Value), Count);
61✔
923
        } catch (std::exception const &e) {
61✔
924
            error_handler(e, __FILE__, __func__, __LINE__);
×
925
            return nullptr;
×
926
        }
×
927
        return wrap<event>(new event(std::move(ev)));
61✔
928
    }
61✔
929
    else {
1✔
930
        error_handler("QRef or USMRef passed to fill8 were NULL.", __FILE__,
1✔
931
                      __func__, __LINE__);
1✔
932
        return nullptr;
1✔
933
    }
1✔
934
};
62✔
935

936
__dpctl_give DPCTLSyclEventRef
937
DPCTLQueue_Fill8(__dpctl_keep const DPCTLSyclQueueRef QRef,
938
                 void *USMRef,
939
                 uint8_t Value,
940
                 size_t Count)
941
{
9✔
942
    auto Q = unwrap<queue>(QRef);
9✔
943
    if (Q && USMRef) {
9!
944
        sycl::event ev;
8✔
945
        try {
8✔
946
            ev = Q->fill<uint8_t>(USMRef, Value, Count);
8✔
947
        } catch (std::exception const &e) {
8✔
948
            error_handler(e, __FILE__, __func__, __LINE__);
×
949
            return nullptr;
×
950
        }
×
951
        return wrap<event>(new event(std::move(ev)));
8✔
952
    }
8✔
953
    else {
1✔
954
        error_handler("QRef or USMRef passed to fill8 were NULL.", __FILE__,
1✔
955
                      __func__, __LINE__);
1✔
956
        return nullptr;
1✔
957
    }
1✔
958
}
9✔
959

960
__dpctl_give DPCTLSyclEventRef
961
DPCTLQueue_Fill16(__dpctl_keep const DPCTLSyclQueueRef QRef,
962
                  void *USMRef,
963
                  uint16_t Value,
964
                  size_t Count)
965
{
9✔
966
    auto Q = unwrap<queue>(QRef);
9✔
967
    if (Q && USMRef) {
9!
968
        sycl::event ev;
8✔
969
        try {
8✔
970
            ev = Q->fill<uint16_t>(USMRef, Value, Count);
8✔
971
        } catch (std::exception const &e) {
8✔
972
            error_handler(e, __FILE__, __func__, __LINE__);
×
973
            return nullptr;
×
974
        }
×
975
        return wrap<event>(new event(std::move(ev)));
8✔
976
    }
8✔
977
    else {
1✔
978
        error_handler("QRef or USMRef passed to fill16 were NULL.", __FILE__,
1✔
979
                      __func__, __LINE__);
1✔
980
        return nullptr;
1✔
981
    }
1✔
982
}
9✔
983

984
__dpctl_give DPCTLSyclEventRef
985
DPCTLQueue_Fill32(__dpctl_keep const DPCTLSyclQueueRef QRef,
986
                  void *USMRef,
987
                  uint32_t Value,
988
                  size_t Count)
989
{
9✔
990
    auto Q = unwrap<queue>(QRef);
9✔
991
    if (Q && USMRef) {
9!
992
        sycl::event ev;
8✔
993
        try {
8✔
994
            ev = Q->fill<uint32_t>(USMRef, Value, Count);
8✔
995
        } catch (std::exception const &e) {
8✔
996
            error_handler(e, __FILE__, __func__, __LINE__);
×
997
            return nullptr;
×
998
        }
×
999
        return wrap<event>(new event(std::move(ev)));
8✔
1000
    }
8✔
1001
    else {
1✔
1002
        error_handler("QRef or USMRef passed to fill32 were NULL.", __FILE__,
1✔
1003
                      __func__, __LINE__);
1✔
1004
        return nullptr;
1✔
1005
    }
1✔
1006
}
9✔
1007

1008
__dpctl_give DPCTLSyclEventRef
1009
DPCTLQueue_Fill64(__dpctl_keep const DPCTLSyclQueueRef QRef,
1010
                  void *USMRef,
1011
                  uint64_t Value,
1012
                  size_t Count)
1013
{
9✔
1014
    auto Q = unwrap<queue>(QRef);
9✔
1015
    if (Q && USMRef) {
9!
1016
        sycl::event ev;
8✔
1017
        try {
8✔
1018
            ev = Q->fill<uint64_t>(USMRef, Value, Count);
8✔
1019
        } catch (std::exception const &e) {
8✔
1020
            error_handler(e, __FILE__, __func__, __LINE__);
×
1021
            return nullptr;
×
1022
        }
×
1023
        return wrap<event>(new event(std::move(ev)));
8✔
1024
    }
8✔
1025
    else {
1✔
1026
        error_handler("QRef or USMRef passed to fill64 were NULL.", __FILE__,
1✔
1027
                      __func__, __LINE__);
1✔
1028
        return nullptr;
1✔
1029
    }
1✔
1030
}
9✔
1031

1032
__dpctl_give DPCTLSyclEventRef
1033
DPCTLQueue_Fill128(__dpctl_keep const DPCTLSyclQueueRef QRef,
1034
                   void *USMRef,
1035
                   uint64_t *Value,
1036
                   size_t Count)
1037
{
9✔
1038
    auto Q = unwrap<queue>(QRef);
9✔
1039
    if (Q && USMRef) {
9!
1040
        sycl::event ev;
8✔
1041
        try {
8✔
1042
            complexNumber Val;
8✔
1043
            Val.real = Value[0];
8✔
1044
            Val.imag = Value[1];
8✔
1045
            ev = Q->fill(USMRef, Val, Count);
8✔
1046
        } catch (std::exception const &e) {
8✔
1047
            error_handler(e, __FILE__, __func__, __LINE__);
×
1048
            return nullptr;
×
1049
        }
×
1050
        return wrap<event>(new event(std::move(ev)));
8✔
1051
    }
8✔
1052
    else {
1✔
1053
        error_handler("QRef or USMRef passed to fill128 were NULL.", __FILE__,
1✔
1054
                      __func__, __LINE__);
1055
        return nullptr;
1✔
1056
    }
1✔
1057
}
9✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc