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

IntelPython / dpctl / 31716258673

13 Aug 2026 03:35PM UTC coverage: 74.51% (+0.05%) from 74.462%
31716258673

Pull #2361

github

web-flow
Merge 8e1cfde7e into d81c8309d
Pull Request #2361: Add `dpctl.SyclQueue.memset()` method

1006 of 1422 branches covered (70.75%)

Branch coverage included in aggregate %.

24 of 27 new or added lines in 1 file covered. (88.89%)

3899 of 5161 relevant lines covered (75.55%)

278.6 hits per line

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

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

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

51
using namespace sycl;
52

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

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

128
using namespace dpctl::syclinterface;
129

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

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

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

188
    switch (ArgTy) {
502✔
189
    case DPCTL_INT8_T:
3✔
190
        cgh.set_arg(idx, *(std::int8_t *)Arg);
3✔
191
        break;
3✔
192
    case DPCTL_UINT8_T:
3✔
193
        cgh.set_arg(idx, *(std::uint8_t *)Arg);
3✔
194
        break;
3✔
195
    case DPCTL_INT16_T:
9✔
196
        cgh.set_arg(idx, *(std::int16_t *)Arg);
9✔
197
        break;
9✔
198
    case DPCTL_UINT16_T:
3✔
199
        cgh.set_arg(idx, *(std::uint16_t *)Arg);
3✔
200
        break;
3✔
201
    case DPCTL_INT32_T:
9✔
202
        cgh.set_arg(idx, *(std::int32_t *)Arg);
9✔
203
        break;
9✔
204
    case DPCTL_UINT32_T:
11✔
205
        cgh.set_arg(idx, *(std::uint32_t *)Arg);
11✔
206
        break;
11✔
207
    case DPCTL_INT64_T:
9✔
208
        cgh.set_arg(idx, *(std::int64_t *)Arg);
9✔
209
        break;
9✔
210
    case DPCTL_UINT64_T:
14✔
211
        cgh.set_arg(idx, *(std::uint64_t *)Arg);
14✔
212
        break;
14✔
213
    case DPCTL_FLOAT32_T:
9✔
214
        cgh.set_arg(idx, *(float *)Arg);
9✔
215
        break;
9✔
216
    case DPCTL_FLOAT64_T:
9✔
217
        cgh.set_arg(idx, *(double *)Arg);
9✔
218
        break;
9✔
219
    case DPCTL_VOID_PTR:
330✔
220
        cgh.set_arg(idx, Arg);
330✔
221
        break;
330✔
222
    case DPCTL_LOCAL_ACCESSOR:
31✔
223
        arg_set = set_local_accessor_arg(cgh, idx, (MDLocalAccessor *)Arg);
31✔
224
        break;
31✔
225
#ifdef SYCL_EXT_ONEAPI_WORK_GROUP_MEMORY
×
226
    case DPCTL_WORK_GROUP_MEMORY:
31✔
227
    {
31✔
228
        auto ref = static_cast<DPCTLSyclWorkGroupMemoryRef>(Arg);
31✔
229
        RawWorkGroupMemory *raw_mem = unwrap<RawWorkGroupMemory>(ref);
31✔
230
        size_t num_bytes = raw_mem->nbytes;
31✔
231
        sycl::ext::oneapi::experimental::work_group_memory<char[]> mem{
31✔
232
            num_bytes, cgh};
31✔
233
        cgh.set_arg(idx, mem);
31✔
234
        break;
31✔
235
    }
×
236
#endif
×
237
#ifdef SYCL_EXT_ONEAPI_RAW_KERNEL_ARG
×
238
    case DPCTL_RAW_KERNEL_ARG:
30✔
239
    {
30✔
240
        auto ref = static_cast<DPCTLSyclRawKernelArgRef>(Arg);
30✔
241
        std::vector<unsigned char> *raw_arg =
30✔
242
            unwrap<std::vector<unsigned char>>(ref);
30✔
243
        void *bytes = raw_arg->data();
30✔
244
        size_t count = raw_arg->size();
30✔
245
        sycl::ext::oneapi::experimental::raw_kernel_arg arg{bytes, count};
30✔
246
        cgh.set_arg(idx, arg);
30✔
247
        break;
30✔
248
    }
×
249
#endif
×
250
    default:
1✔
251
        arg_set = false;
1✔
252
        break;
1✔
253
    }
502✔
254
    return arg_set;
502✔
255
}
502✔
256

257
void set_kernel_args(handler &cgh,
258
                     __dpctl_keep void **Args,
259
                     __dpctl_keep const DPCTLKernelArgType *ArgTypes,
260
                     size_t NArgs)
261
{
177✔
262
    for (auto i = 0ul; i < NArgs; ++i) {
677✔
263
        if (!set_kernel_arg(cgh, i, Args[i], ArgTypes[i])) {
502✔
264
            error_handler("Kernel argument could not be created.", __FILE__,
2✔
265
                          __func__, __LINE__);
2✔
266
            throw std::invalid_argument(
2✔
267
                "Kernel argument could not be created.");
2✔
268
        }
2✔
269
    }
502✔
270
}
177✔
271

272
std::unique_ptr<property_list> create_property_list(int properties)
273
{
1,717✔
274
    std::unique_ptr<property_list> propList;
1,717✔
275
    int _prop = properties;
1,717✔
276
    if (_prop & DPCTL_ENABLE_PROFILING) {
1,717✔
277
        _prop = _prop ^ DPCTL_ENABLE_PROFILING;
66✔
278
        if (_prop & DPCTL_IN_ORDER) {
66✔
279
            _prop = _prop ^ DPCTL_IN_ORDER;
26✔
280
            propList = std::make_unique<property_list>(
26✔
281
                sycl::property::queue::enable_profiling(),
26✔
282
                sycl::property::queue::in_order());
26✔
283
        }
26✔
284
        else {
40✔
285
            propList = std::make_unique<property_list>(
40✔
286
                sycl::property::queue::enable_profiling());
40✔
287
        }
40✔
288
    }
66✔
289
    else if (_prop & DPCTL_IN_ORDER) {
1,651✔
290
        _prop = _prop ^ DPCTL_IN_ORDER;
541✔
291
        propList =
541✔
292
            std::make_unique<property_list>(sycl::property::queue::in_order());
541✔
293
    }
541✔
294
    else {
1,110✔
295
        propList = std::make_unique<property_list>();
1,110✔
296
    }
1,110✔
297

298
    if (_prop) {
1,717✔
299
        std::stringstream ss;
1✔
300
        ss << "Invalid queue property argument (" << std::hex << properties
1✔
301
           << "), interpreted as (" << (properties ^ _prop) << ").";
1✔
302
        error_handler(ss.str(), __FILE__, __func__, __LINE__);
1✔
303
    }
1✔
304
    return propList;
1,717✔
305
}
1,717✔
306

307
__dpctl_give DPCTLSyclQueueRef
308
getQueueImpl(__dpctl_keep DPCTLSyclContextRef cRef,
309
             __dpctl_keep DPCTLSyclDeviceRef dRef,
310
             error_handler_callback *handler,
311
             int properties)
312
{
167✔
313
    DPCTLSyclQueueRef qRef = nullptr;
167✔
314
    qRef = DPCTLQueue_Create(cRef, dRef, handler, properties);
167✔
315
    return qRef;
167✔
316
}
167✔
317

318
} /* end of anonymous namespace */
319

320
DPCTL_API
321
__dpctl_give DPCTLSyclQueueRef
322
DPCTLQueue_Create(__dpctl_keep const DPCTLSyclContextRef CRef,
323
                  __dpctl_keep const DPCTLSyclDeviceRef DRef,
324
                  error_handler_callback *handler,
325
                  int properties)
326
{
1,719✔
327
    DPCTLSyclQueueRef q = nullptr;
1,719✔
328
    auto dev = unwrap<device>(DRef);
1,719✔
329
    auto ctx = unwrap<context>(CRef);
1,719✔
330

331
    if (!(dev && ctx)) {
1,719✔
332
        error_handler("Cannot create queue from DPCTLSyclContextRef and "
2✔
333
                      "DPCTLSyclDeviceRef as input is a nullptr.",
2✔
334
                      __FILE__, __func__, __LINE__);
2✔
335
        return q;
2✔
336
    }
2✔
337
    auto propList = create_property_list(properties);
1,717✔
338

339
    if (handler) {
1,717✔
340
        try {
48✔
341
            auto Queue = new queue(*ctx, *dev, DPCTL_AsyncErrorHandler(handler),
48✔
342
                                   *propList);
48✔
343
            q = wrap<queue>(Queue);
48✔
344
        } catch (std::exception const &e) {
48✔
345
            error_handler(e, __FILE__, __func__, __LINE__);
×
346
        }
×
347
    }
48✔
348
    else {
1,669✔
349
        try {
1,669✔
350
            auto Queue = new queue(*ctx, *dev, *propList);
1,669✔
351
            q = wrap<queue>(Queue);
1,669✔
352
        } catch (std::exception const &e) {
1,669✔
353
            error_handler(e, __FILE__, __func__, __LINE__);
1✔
354
        }
1✔
355
    }
1,669✔
356

357
    return q;
1,717✔
358
}
1,717✔
359

360
__dpctl_give DPCTLSyclQueueRef
361
DPCTLQueue_CreateForDevice(__dpctl_keep const DPCTLSyclDeviceRef DRef,
362
                           error_handler_callback *handler,
363
                           int properties)
364
{
369✔
365
    DPCTLSyclContextRef CRef = nullptr;
369✔
366
    DPCTLSyclQueueRef QRef = nullptr;
369✔
367
    auto Device = unwrap<device>(DRef);
369✔
368

369
    if (!Device) {
369✔
370
        error_handler("Cannot create queue from NULL device reference.",
202✔
371
                      __FILE__, __func__, __LINE__);
202✔
372
        return QRef;
202✔
373
    }
202✔
374
    // Check if a cached default context exists for the device.
375
    CRef = DPCTLDeviceMgr_GetCachedContext(DRef);
167✔
376
    // If a cached default context was found, that context will be used to use
377
    // create the new queue. When a default cached context was not found, as
378
    // will be the case for non-root devices, i.e., sub-devices, a new context
379
    // will be allocated. Note that any newly allocated context is not cached.
380
    if (!CRef) {
167!
381
        context *ContextPtr = nullptr;
×
382
        try {
×
383
            ContextPtr = new context(*Device);
×
384
            CRef = wrap<context>(ContextPtr);
×
385
        } catch (std::exception const &e) {
×
386
            error_handler(e, __FILE__, __func__, __LINE__);
×
387
            delete ContextPtr;
×
388
            return QRef;
×
389
        }
×
390
    }
×
391
    // At this point we have a valid context and the queue can be allocated.
392
    QRef = getQueueImpl(CRef, DRef, handler, properties);
167✔
393
    // Free the context
394
    DPCTLContext_Delete(CRef);
167✔
395
    return QRef;
167✔
396
}
167✔
397

398
/*!
399
 * Delete the passed in pointer after verifying it points to a sycl::queue.
400
 */
401
void DPCTLQueue_Delete(__dpctl_take DPCTLSyclQueueRef QRef)
402
{
2,029✔
403
    delete unwrap<queue>(QRef);
2,029✔
404
}
2,029✔
405

406
/*!
407
 * Make copy of sycl::queue referenced by passed pointer
408
 */
409
__dpctl_give DPCTLSyclQueueRef
410
DPCTLQueue_Copy(__dpctl_keep const DPCTLSyclQueueRef QRef)
411
{
116✔
412
    auto Queue = unwrap<queue>(QRef);
116✔
413
    if (Queue) {
116✔
414
        try {
115✔
415
            auto CopiedQueue = new queue(*Queue);
115✔
416
            return wrap<queue>(CopiedQueue);
115✔
417
        } catch (std::exception const &e) {
115✔
418
            error_handler(e, __FILE__, __func__, __LINE__);
×
419
            return nullptr;
×
420
        }
×
421
    }
115✔
422
    else {
1✔
423
        error_handler("Cannot copy DPCTLSyclQueueRef as input is a nullptr",
1✔
424
                      __FILE__, __func__, __LINE__);
1✔
425
        return nullptr;
1✔
426
    }
1✔
427
}
116✔
428

429
bool DPCTLQueue_AreEq(__dpctl_keep const DPCTLSyclQueueRef QRef1,
430
                      __dpctl_keep const DPCTLSyclQueueRef QRef2)
431
{
13✔
432
    if (!(QRef1 && QRef2)) {
13✔
433
        error_handler("DPCTLSyclQueueRefs are nullptr.", __FILE__, __func__,
2✔
434
                      __LINE__);
2✔
435
        return false;
2✔
436
    }
2✔
437
    return (*unwrap<queue>(QRef1) == *unwrap<queue>(QRef2));
11✔
438
}
13✔
439

440
DPCTLSyclBackendType DPCTLQueue_GetBackend(__dpctl_keep DPCTLSyclQueueRef QRef)
441
{
10✔
442
    auto Q = unwrap<queue>(QRef);
10✔
443
    if (Q) {
10✔
444
        try {
9✔
445
            auto C = Q->get_context();
9✔
446
            return DPCTLContext_GetBackend(wrap<context>(&C));
9✔
447
        } catch (std::exception const &e) {
9✔
448
            error_handler(e, __FILE__, __func__, __LINE__);
×
449
            return DPCTL_UNKNOWN_BACKEND;
×
450
        }
×
451
    }
9✔
452
    else
1✔
453
        return DPCTL_UNKNOWN_BACKEND;
1✔
454
}
10✔
455

456
__dpctl_give DPCTLSyclDeviceRef
457
DPCTLQueue_GetDevice(__dpctl_keep const DPCTLSyclQueueRef QRef)
458
{
74✔
459
    DPCTLSyclDeviceRef DRef = nullptr;
74✔
460
    auto Q = unwrap<queue>(QRef);
74✔
461
    if (Q) {
74✔
462
        try {
73✔
463
            auto Device = new device(Q->get_device());
73✔
464
            DRef = wrap<device>(Device);
73✔
465
        } catch (std::exception const &e) {
73✔
466
            error_handler(e, __FILE__, __func__, __LINE__);
×
467
        }
×
468
    }
73✔
469
    else {
1✔
470
        error_handler("Could not get the device for this queue.", __FILE__,
1✔
471
                      __func__, __LINE__);
1✔
472
    }
1✔
473
    return DRef;
74✔
474
}
74✔
475

476
__dpctl_give DPCTLSyclContextRef
477
DPCTLQueue_GetContext(__dpctl_keep const DPCTLSyclQueueRef QRef)
478
{
140✔
479
    auto Q = unwrap<queue>(QRef);
140✔
480
    DPCTLSyclContextRef CRef = nullptr;
140✔
481
    if (Q)
140✔
482
        CRef = wrap<context>(new context(Q->get_context()));
130✔
483
    else {
10✔
484
        error_handler("Could not get the context for this queue.", __FILE__,
10✔
485
                      __func__, __LINE__);
10✔
486
    }
10✔
487
    return CRef;
140✔
488
}
140✔
489

490
__dpctl_give DPCTLSyclEventRef
491
DPCTLQueue_SubmitRange(__dpctl_keep const DPCTLSyclKernelRef KRef,
492
                       __dpctl_keep const DPCTLSyclQueueRef QRef,
493
                       __dpctl_keep void **Args,
494
                       __dpctl_keep const DPCTLKernelArgType *ArgTypes,
495
                       size_t NArgs,
496
                       __dpctl_keep const size_t Range[3],
497
                       size_t NDims,
498
                       __dpctl_keep const DPCTLSyclEventRef *DepEvents,
499
                       size_t NDepEvents)
500
{
63✔
501
    auto Kernel = unwrap<kernel>(KRef);
63✔
502
    auto Queue = unwrap<queue>(QRef);
63✔
503
    event e;
63✔
504

505
    try {
63✔
506
        switch (NDims) {
63✔
507
        case 1:
29✔
508
        {
29✔
509
            e = Queue->submit([&](handler &cgh) {
29✔
510
                // Depend on any event that was specified by the caller.
511
                set_dependent_events(cgh, DepEvents, NDepEvents);
29✔
512
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
29✔
513
                cgh.parallel_for(range<1>{Range[0]}, *Kernel);
29✔
514
            });
29✔
515
            return wrap<event>(new event(std::move(e)));
29✔
516
        }
×
517
        case 2:
17✔
518
        {
17✔
519
            e = Queue->submit([&](handler &cgh) {
17✔
520
                // Depend on any event that was specified by the caller.
521
                set_dependent_events(cgh, DepEvents, NDepEvents);
17✔
522
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
17✔
523
                cgh.parallel_for(range<2>{Range[0], Range[1]}, *Kernel);
17✔
524
            });
17✔
525
            return wrap<event>(new event(std::move(e)));
17✔
526
        }
×
527
        case 3:
17✔
528
        {
17✔
529
            e = Queue->submit([&](handler &cgh) {
17✔
530
                // Depend on any event that was specified by the caller.
531
                set_dependent_events(cgh, DepEvents, NDepEvents);
17✔
532
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
17✔
533
                cgh.parallel_for(range<3>{Range[0], Range[1], Range[2]},
17✔
534
                                 *Kernel);
17✔
535
            });
17✔
536
            return wrap<event>(new event(std::move(e)));
17✔
537
        }
×
538
        default:
×
539
            error_handler("Range cannot be greater than three "
×
540
                          "dimensions.",
×
541
                          __FILE__, __func__, __LINE__, error_level::error);
×
542
            return nullptr;
×
543
        }
63✔
544
    } catch (std::exception const &e) {
63✔
545
        error_handler(e, __FILE__, __func__, __LINE__, error_level::error);
1✔
546
        return nullptr;
1✔
547
    } catch (...) {
1✔
548
        error_handler("Unknown exception encountered", __FILE__, __func__,
×
549
                      __LINE__, error_level::error);
×
550
        return nullptr;
×
551
    }
×
552
}
63✔
553

554
__dpctl_give DPCTLSyclEventRef
555
DPCTLQueue_SubmitNDRange(__dpctl_keep const DPCTLSyclKernelRef KRef,
556
                         __dpctl_keep const DPCTLSyclQueueRef QRef,
557
                         __dpctl_keep void **Args,
558
                         __dpctl_keep const DPCTLKernelArgType *ArgTypes,
559
                         size_t NArgs,
560
                         __dpctl_keep const size_t gRange[3],
561
                         __dpctl_keep const size_t lRange[3],
562
                         size_t NDims,
563
                         __dpctl_keep const DPCTLSyclEventRef *DepEvents,
564
                         size_t NDepEvents)
565
{
114✔
566
    auto Kernel = unwrap<kernel>(KRef);
114✔
567
    auto Queue = unwrap<queue>(QRef);
114✔
568
    event e;
114✔
569

570
    try {
114✔
571
        switch (NDims) {
114✔
572
        case 1:
100✔
573
        {
100✔
574
            e = Queue->submit([&](handler &cgh) {
100✔
575
                // Depend on any event that was specified by the caller.
576
                set_dependent_events(cgh, DepEvents, NDepEvents);
100✔
577
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
100✔
578
                cgh.parallel_for(nd_range<1>{{gRange[0]}, {lRange[0]}},
100✔
579
                                 *Kernel);
100✔
580
            });
100✔
581
            return wrap<event>(new event(std::move(e)));
100✔
582
        }
×
583
        case 2:
7✔
584
        {
7✔
585
            e = Queue->submit([&](handler &cgh) {
7✔
586
                // Depend on any event that was specified by the caller.
587
                set_dependent_events(cgh, DepEvents, NDepEvents);
7✔
588
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
7✔
589
                cgh.parallel_for(
7✔
590
                    nd_range<2>{{gRange[0], gRange[1]}, {lRange[0], lRange[1]}},
7✔
591
                    *Kernel);
7✔
592
            });
7✔
593
            return wrap<event>(new event(std::move(e)));
7✔
594
        }
×
595
        case 3:
7✔
596
        {
7✔
597
            e = Queue->submit([&](handler &cgh) {
7✔
598
                // Depend on any event that was specified by the caller.
599
                set_dependent_events(cgh, DepEvents, NDepEvents);
7✔
600
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
7✔
601
                cgh.parallel_for(nd_range<3>{{gRange[0], gRange[1], gRange[2]},
7✔
602
                                             {lRange[0], lRange[1], lRange[2]}},
7✔
603
                                 *Kernel);
7✔
604
            });
7✔
605
            return wrap<event>(new event(std::move(e)));
7✔
606
        }
×
607
        default:
×
608
            error_handler("Range cannot be greater than three "
×
609
                          "dimensions.",
×
610
                          __FILE__, __func__, __LINE__, error_level::error);
×
611
            return nullptr;
×
612
        }
114✔
613
    } catch (std::exception const &e) {
114✔
614
        error_handler(e, __FILE__, __func__, __LINE__, error_level::error);
1✔
615
        return nullptr;
1✔
616
    } catch (...) {
1✔
617
        error_handler("Unknown exception encountered", __FILE__, __func__,
×
618
                      __LINE__, error_level::error);
×
619
        return nullptr;
×
620
    }
×
621
}
114✔
622

623
void DPCTLQueue_Wait(__dpctl_keep DPCTLSyclQueueRef QRef)
624
{
1✔
625
    // \todo what happens if the QRef is null or a pointer to a valid sycl
626
    // queue
627
    if (QRef) {
1!
628
        auto SyclQueue = unwrap<queue>(QRef);
1✔
629
        if (SyclQueue)
1!
630
            SyclQueue->wait();
1✔
631
    }
1✔
632
    else {
×
633
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
×
634
    }
×
635
}
1✔
636

637
__dpctl_give DPCTLSyclEventRef
638
DPCTLQueue_Memcpy(__dpctl_keep const DPCTLSyclQueueRef QRef,
639
                  void *Dest,
640
                  const void *Src,
641
                  size_t Count)
642
{
189✔
643
    auto Q = unwrap<queue>(QRef);
189✔
644
    if (Q) {
189✔
645
        sycl::event ev;
188✔
646
        try {
188✔
647
            ev = Q->memcpy(Dest, Src, Count);
188✔
648
        } catch (std::exception const &e) {
188✔
649
            error_handler(e, __FILE__, __func__, __LINE__);
8✔
650
            return nullptr;
8✔
651
        }
8✔
652
        return wrap<event>(new event(std::move(ev)));
180✔
653
    }
188✔
654
    else {
1✔
655
        error_handler("QRef passed to memcpy was NULL.", __FILE__, __func__,
1✔
656
                      __LINE__);
1✔
657
        return nullptr;
1✔
658
    }
1✔
659
}
189✔
660

661
__dpctl_give DPCTLSyclEventRef
662
DPCTLQueue_MemcpyWithEvents(__dpctl_keep const DPCTLSyclQueueRef QRef,
663
                            void *Dest,
664
                            const void *Src,
665
                            size_t Count,
666
                            const DPCTLSyclEventRef *DepEvents,
667
                            size_t DepEventsCount)
668
{
88✔
669
    event ev;
88✔
670
    auto Q = unwrap<queue>(QRef);
88✔
671
    if (Q) {
88✔
672
        try {
87✔
673
            ev = Q->submit([&](handler &cgh) {
87✔
674
                if (DepEvents)
87✔
675
                    for (size_t i = 0; i < DepEventsCount; ++i) {
231✔
676
                        event *ei = unwrap<event>(DepEvents[i]);
152✔
677
                        if (ei)
152!
678
                            cgh.depends_on(*ei);
152✔
679
                    }
152✔
680

681
                cgh.memcpy(Dest, Src, Count);
87✔
682
            });
87✔
683
        } catch (const std::exception &ex) {
87✔
684
            error_handler(ex, __FILE__, __func__, __LINE__);
8✔
685
            return nullptr;
8✔
686
        }
8✔
687
    }
87✔
688
    else {
1✔
689
        error_handler("QRef passed to memcpy was NULL.", __FILE__, __func__,
1✔
690
                      __LINE__);
1✔
691
        return nullptr;
1✔
692
    }
1✔
693

694
    return wrap<event>(new event(ev));
79✔
695
}
88✔
696

697
__dpctl_give DPCTLSyclEventRef
698
DPCTLQueue_CopyData(__dpctl_keep const DPCTLSyclQueueRef QRef,
699
                    void *Dest,
700
                    const void *Src,
701
                    size_t Count)
702
{
50✔
703
    auto Q = unwrap<queue>(QRef);
50✔
704
    if (Q) {
50✔
705
        sycl::event ev;
49✔
706
        try {
49✔
707
            // Copy uint8_t elements (1 byte each), so Count is a byte count.
708
            ev = Q->copy(static_cast<const std::uint8_t *>(Src),
49✔
709
                         static_cast<std::uint8_t *>(Dest), Count);
49✔
710
        } catch (std::exception const &e) {
49✔
711
            error_handler(e, __FILE__, __func__, __LINE__);
8✔
712
            return nullptr;
8✔
713
        }
8✔
714
        return wrap<event>(new event(std::move(ev)));
41✔
715
    }
49✔
716
    else {
1✔
717
        error_handler("QRef passed to copy was NULL.", __FILE__, __func__,
1✔
718
                      __LINE__);
1✔
719
        return nullptr;
1✔
720
    }
1✔
721
}
50✔
722

723
__dpctl_give DPCTLSyclEventRef
724
DPCTLQueue_CopyDataWithEvents(__dpctl_keep const DPCTLSyclQueueRef QRef,
725
                              void *Dest,
726
                              const void *Src,
727
                              size_t Count,
728
                              const DPCTLSyclEventRef *DepEvents,
729
                              size_t DepEventsCount)
730
{
10✔
731
    auto Q = unwrap<queue>(QRef);
10✔
732
    if (Q) {
10✔
733
        try {
9✔
734
            std::vector<event> dep_events;
9✔
735
            if (DepEvents) {
9✔
736
                dep_events.reserve(DepEventsCount);
1✔
737
                for (size_t i = 0; i < DepEventsCount; ++i) {
2✔
738
                    event *ei = unwrap<event>(DepEvents[i]);
1✔
739
                    if (ei)
1!
740
                        dep_events.push_back(*ei);
1✔
741
                }
1✔
742
            }
1✔
743

744
            // Copy uint8_t elements (1 byte each), so Count is a byte count.
745
            auto ev =
9✔
746
                Q->copy(static_cast<const std::uint8_t *>(Src),
9✔
747
                        static_cast<std::uint8_t *>(Dest), Count, dep_events);
9✔
748
            return wrap<event>(new event(std::move(ev)));
9✔
749
        } catch (const std::exception &ex) {
9✔
750
            error_handler(ex, __FILE__, __func__, __LINE__);
8✔
751
            return nullptr;
8✔
752
        }
8✔
753
    }
9✔
754
    else {
1✔
755
        error_handler("QRef passed to copy was NULL.", __FILE__, __func__,
1✔
756
                      __LINE__);
1✔
757
        return nullptr;
1✔
758
    }
1✔
759
}
10✔
760

761
__dpctl_give DPCTLSyclEventRef
762
DPCTLQueue_Prefetch(__dpctl_keep DPCTLSyclQueueRef QRef,
763
                    const void *Ptr,
764
                    size_t Count)
765
{
16✔
766
    auto Q = unwrap<queue>(QRef);
16✔
767
    if (Q) {
16✔
768
        if (Ptr) {
15✔
769
            sycl::event ev;
7✔
770
            try {
7✔
771
                ev = Q->prefetch(Ptr, Count);
7✔
772
            } catch (std::exception const &e) {
7✔
773
                error_handler(e, __FILE__, __func__, __LINE__);
×
774
                return nullptr;
×
775
            }
×
776
            return wrap<event>(new event(std::move(ev)));
7✔
777
        }
7✔
778
        else {
8✔
779
            error_handler("Attempt to prefetch USM-allocation at nullptr.",
8✔
780
                          __FILE__, __func__, __LINE__);
8✔
781
            return nullptr;
8✔
782
        }
8✔
783
    }
15✔
784
    else {
1✔
785
        error_handler("QRef passed to prefetch was NULL.", __FILE__, __func__,
1✔
786
                      __LINE__);
1✔
787
        return nullptr;
1✔
788
    }
1✔
789
}
16✔
790

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

815
bool DPCTLQueue_IsInOrder(__dpctl_keep const DPCTLSyclQueueRef QRef)
816
{
1,040✔
817
    auto Q = unwrap<queue>(QRef);
1,040✔
818
    if (Q) {
1,040✔
819
        return Q->is_in_order();
1,039✔
820
    }
1,039✔
821
    else
1✔
822
        return false;
1✔
823
}
1,040✔
824

825
bool DPCTLQueue_HasEnableProfiling(__dpctl_keep const DPCTLSyclQueueRef QRef)
826
{
67✔
827
    auto Q = unwrap<queue>(QRef);
67✔
828
    if (Q) {
67✔
829
        return Q->has_property<sycl::property::queue::enable_profiling>();
66✔
830
    }
66✔
831
    else
1✔
832
        return false;
1✔
833
}
67✔
834

835
size_t DPCTLQueue_Hash(__dpctl_keep const DPCTLSyclQueueRef QRef)
836
{
24✔
837
    auto Q = unwrap<queue>(QRef);
24✔
838
    if (Q) {
24✔
839
        std::hash<queue> hash_fn;
21✔
840
        return hash_fn(*Q);
21✔
841
    }
21✔
842
    else {
3✔
843
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
3✔
844
        return 0;
3✔
845
    }
3✔
846
}
24✔
847

848
__dpctl_give DPCTLSyclEventRef DPCTLQueue_SubmitBarrierForEvents(
849
    __dpctl_keep const DPCTLSyclQueueRef QRef,
850
    __dpctl_keep const DPCTLSyclEventRef *DepEvents,
851
    size_t NDepEvents)
852
{
107✔
853
    auto Q = unwrap<queue>(QRef);
107✔
854
    event e;
107✔
855
    if (Q) {
107!
856
        try {
107✔
857
            e = Q->submit([&](handler &cgh) {
107✔
858
                // Depend on any event that was specified by the caller.
859
                if (NDepEvents)
107✔
860
                    for (auto i = 0ul; i < NDepEvents; ++i)
18✔
861
                        cgh.depends_on(*unwrap<event>(DepEvents[i]));
12✔
862

863
                cgh.ext_oneapi_barrier();
107✔
864
            });
107✔
865
        } catch (std::exception const &e) {
107✔
866
            error_handler(e, __FILE__, __func__, __LINE__);
×
867
            return nullptr;
×
868
        }
×
869

870
        return wrap<event>(new event(std::move(e)));
107✔
871
    }
107✔
872
    else {
×
873
        error_handler("Argument QRef is NULL", __FILE__, __func__, __LINE__);
×
874
        return nullptr;
×
875
    }
×
876
}
107✔
877

878
__dpctl_give DPCTLSyclEventRef
879
DPCTLQueue_SubmitBarrier(__dpctl_keep const DPCTLSyclQueueRef QRef)
880
{
1✔
881
    return DPCTLQueue_SubmitBarrierForEvents(QRef, nullptr, 0);
1✔
882
}
1✔
883

884
__dpctl_give DPCTLSyclEventRef
885
DPCTLQueue_Memset(__dpctl_keep const DPCTLSyclQueueRef QRef,
886
                  void *USMRef,
887
                  uint8_t Value,
888
                  size_t Count)
889
{
81✔
890
    auto Q = unwrap<queue>(QRef);
81✔
891
    if (Q && USMRef) {
81!
892
        sycl::event ev;
80✔
893
        try {
80✔
894
            ev = Q->memset(USMRef, static_cast<int>(Value), Count);
80✔
895
        } catch (std::exception const &e) {
80✔
896
            error_handler(e, __FILE__, __func__, __LINE__);
×
897
            return nullptr;
×
898
        }
×
899
        return wrap<event>(new event(std::move(ev)));
80✔
900
    }
80✔
901
    else {
1✔
902
        error_handler("QRef or USMRef passed to memset were NULL.", __FILE__,
1✔
903
                      __func__, __LINE__);
1✔
904
        return nullptr;
1✔
905
    }
1✔
906
};
81✔
907

908
__dpctl_give DPCTLSyclEventRef
909
DPCTLQueue_MemsetWithEvents(__dpctl_keep const DPCTLSyclQueueRef QRef,
910
                            void *USMRef,
911
                            uint8_t Value,
912
                            size_t Count,
913
                            const DPCTLSyclEventRef *DepEvents,
914
                            size_t DepEventsCount)
915
{
10✔
916
    event ev;
10✔
917
    auto Q = unwrap<queue>(QRef);
10✔
918
    if (Q && USMRef) {
10!
919
        try {
9✔
920
            ev = Q->submit([&](handler &cgh) {
9✔
921
                if (DepEvents)
9!
922
                    for (size_t i = 0; i < DepEventsCount; ++i) {
18✔
923
                        event *ei = unwrap<event>(DepEvents[i]);
9✔
924
                        if (ei)
9!
925
                            cgh.depends_on(*ei);
9✔
926
                    }
9✔
927

928
                cgh.memset(USMRef, static_cast<int>(Value), Count);
9✔
929
            });
9✔
930
        } catch (const std::exception &ex) {
9✔
NEW
931
            error_handler(ex, __FILE__, __func__, __LINE__);
×
NEW
932
            return nullptr;
×
NEW
933
        }
×
934
    }
9✔
935
    else {
1✔
936
        error_handler("QRef or USMRef passed to memset were NULL.", __FILE__,
1✔
937
                      __func__, __LINE__);
1✔
938
        return nullptr;
1✔
939
    }
1✔
940

941
    return wrap<event>(new event(ev));
9✔
942
};
10✔
943

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

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

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

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

1040
__dpctl_give DPCTLSyclEventRef
1041
DPCTLQueue_Fill128(__dpctl_keep const DPCTLSyclQueueRef QRef,
1042
                   void *USMRef,
1043
                   uint64_t *Value,
1044
                   size_t Count)
1045
{
9✔
1046
    auto Q = unwrap<queue>(QRef);
9✔
1047
    if (Q && USMRef) {
9!
1048
        sycl::event ev;
8✔
1049
        try {
8✔
1050
            complexNumber Val;
8✔
1051
            Val.real = Value[0];
8✔
1052
            Val.imag = Value[1];
8✔
1053
            ev = Q->fill(USMRef, Val, Count);
8✔
1054
        } catch (std::exception const &e) {
8✔
1055
            error_handler(e, __FILE__, __func__, __LINE__);
×
1056
            return nullptr;
×
1057
        }
×
1058
        return wrap<event>(new event(std::move(ev)));
8✔
1059
    }
8✔
1060
    else {
1✔
1061
        error_handler("QRef or USMRef passed to fill128 were NULL.", __FILE__,
1✔
1062
                      __func__, __LINE__);
1063
        return nullptr;
1✔
1064
    }
1✔
1065
}
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