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

IntelPython / dpctl / 14769796435

01 May 2025 04:30AM UTC coverage: 86.363% (-0.06%) from 86.419%
14769796435

Pull #2070

github

web-flow
Merge 8b0017898 into 32948cd15
Pull Request #2070: [MAINT] Update OCL RT in OS compiler workflow

3021 of 3718 branches covered (81.25%)

Branch coverage included in aggregate %.

12248 of 13962 relevant lines covered (87.72%)

6966.68 hits per line

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

80.2
/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
#if defined(SYCL_EXT_ONEAPI_WORK_GROUP_MEMORY) ||                              \
46
    defined(SYCL_EXT_ONEAPI_RAW_KERNEL_ARG)
47
#include "dpctl_sycl_extension_interface.h"
48
#endif
49

50
using namespace sycl;
51

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

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

127
using namespace dpctl::syclinterface;
128

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

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

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

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

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

271
std::unique_ptr<property_list> create_property_list(int properties)
272
{
40,069 ✔
273
    std::unique_ptr<property_list> propList;
40,069 ✔
274
    int _prop = properties;
40,069 ✔
275
    if (_prop & DPCTL_ENABLE_PROFILING) {
40,069 ✔
276
        _prop = _prop ^ DPCTL_ENABLE_PROFILING;
71 ✔
277
        if (_prop & DPCTL_IN_ORDER) {
71 ✔
278
            _prop = _prop ^ DPCTL_IN_ORDER;
24 ✔
279
            propList = std::make_unique<property_list>(
24 ✔
280
                sycl::property::queue::enable_profiling(),
24 ✔
281
                sycl::property::queue::in_order());
24 ✔
282
        }
24 ✔
283
        else {
47 ✔
284
            propList = std::make_unique<property_list>(
47 ✔
285
                sycl::property::queue::enable_profiling());
47 ✔
286
        }
47 ✔
287
    }
71 ✔
288
    else if (_prop & DPCTL_IN_ORDER) {
39,998 ✔
289
        _prop = _prop ^ DPCTL_IN_ORDER;
436 ✔
290
        propList =
436 ✔
291
            std::make_unique<property_list>(sycl::property::queue::in_order());
436 ✔
292
    }
436 ✔
293
    else {
39,562 ✔
294
        propList = std::make_unique<property_list>();
39,562 ✔
295
    }
39,562 ✔
296

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

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

317
} /* end of anonymous namespace */
318

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

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

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

356
    return q;
40,069 ✔
357
}
40,069 ✔
358

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

693
    return wrap<event>(new event(ev));
50 ✔
694
}
59 ✔
695

696
__dpctl_give DPCTLSyclEventRef
697
DPCTLQueue_Prefetch(__dpctl_keep DPCTLSyclQueueRef QRef,
698
                    const void *Ptr,
699
                    size_t Count)
700
{
16 ✔
701
    auto Q = unwrap<queue>(QRef);
16 ✔
702
    if (Q) {
16 ✔
703
        if (Ptr) {
15 ✔
704
            sycl::event ev;
7 ✔
705
            try {
7 ✔
706
                ev = Q->prefetch(Ptr, Count);
7 ✔
707
            } catch (std::exception const &e) {
7 ✔
708
                error_handler(e, __FILE__, __func__, __LINE__);
×
709
                return nullptr;
×
710
            }
×
711
            return wrap<event>(new event(std::move(ev)));
7 ✔
712
        }
7 ✔
713
        else {
8 ✔
714
            error_handler("Attempt to prefetch USM-allocation at nullptr.",
8 ✔
715
                          __FILE__, __func__, __LINE__);
8 ✔
716
            return nullptr;
8 ✔
717
        }
8 ✔
718
    }
15 ✔
719
    else {
1 ✔
720
        error_handler("QRef passed to prefetch was NULL.", __FILE__, __func__,
1 ✔
721
                      __LINE__);
1 ✔
722
        return nullptr;
1 ✔
723
    }
1 ✔
724
}
16 ✔
725

726
__dpctl_give DPCTLSyclEventRef
727
DPCTLQueue_MemAdvise(__dpctl_keep DPCTLSyclQueueRef QRef,
728
                     const void *Ptr,
729
                     size_t Count,
730
                     int Advice)
731
{
16 ✔
732
    auto Q = unwrap<queue>(QRef);
16 ✔
733
    if (Q) {
16 ✔
734
        sycl::event ev;
15 ✔
735
        try {
15 ✔
736
            ev = Q->mem_advise(Ptr, Count, Advice);
15 ✔
737
        } catch (std::exception const &e) {
15 ✔
738
            error_handler(e, __FILE__, __func__, __LINE__);
×
739
            return nullptr;
×
740
        }
×
741
        return wrap<event>(new event(std::move(ev)));
15 ✔
742
    }
15 ✔
743
    else {
1 ✔
744
        error_handler("QRef passed to prefetch was NULL.", __FILE__, __func__,
1 ✔
745
                      __LINE__);
1 ✔
746
        return nullptr;
1 ✔
747
    }
1 ✔
748
}
16 ✔
749

750
bool DPCTLQueue_IsInOrder(__dpctl_keep const DPCTLSyclQueueRef QRef)
751
{
830 ✔
752
    auto Q = unwrap<queue>(QRef);
830 ✔
753
    if (Q) {
830 ✔
754
        return Q->is_in_order();
829 ✔
755
    }
829 ✔
756
    else
1 ✔
757
        return false;
1 ✔
758
}
830 ✔
759

760
bool DPCTLQueue_HasEnableProfiling(__dpctl_keep const DPCTLSyclQueueRef QRef)
761
{
75 ✔
762
    auto Q = unwrap<queue>(QRef);
75 ✔
763
    if (Q) {
75 ✔
764
        return Q->has_property<sycl::property::queue::enable_profiling>();
74 ✔
765
    }
74 ✔
766
    else
1 ✔
767
        return false;
1 ✔
768
}
75 ✔
769

770
size_t DPCTLQueue_Hash(__dpctl_keep const DPCTLSyclQueueRef QRef)
771
{
325,694 ✔
772
    auto Q = unwrap<queue>(QRef);
325,694 ✔
773
    if (Q) {
325,694 ✔
774
        std::hash<queue> hash_fn;
325,691 ✔
775
        return hash_fn(*Q);
325,691 ✔
776
    }
325,691 ✔
777
    else {
3 ✔
778
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
3 ✔
779
        return 0;
3 ✔
780
    }
3 ✔
781
}
325,694 ✔
782

783
__dpctl_give DPCTLSyclEventRef DPCTLQueue_SubmitBarrierForEvents(
784
    __dpctl_keep const DPCTLSyclQueueRef QRef,
785
    __dpctl_keep const DPCTLSyclEventRef *DepEvents,
786
    size_t NDepEvents)
787
{
117 ✔
788
    auto Q = unwrap<queue>(QRef);
117 ✔
789
    event e;
117 ✔
790
    if (Q) {
117 !
791
        try {
117 ✔
792
            e = Q->submit([&](handler &cgh) {
117 ✔
793
                // Depend on any event that was specified by the caller.
794
                if (NDepEvents)
117 ✔
795
                    for (auto i = 0ul; i < NDepEvents; ++i)
28 ✔
796
                        cgh.depends_on(*unwrap<event>(DepEvents[i]));
17 ✔
797

798
                cgh.ext_oneapi_barrier();
117 ✔
799
            });
117 ✔
800
        } catch (std::exception const &e) {
117 ✔
801
            error_handler(e, __FILE__, __func__, __LINE__);
×
802
            return nullptr;
×
803
        }
×
804

805
        return wrap<event>(new event(std::move(e)));
117 ✔
806
    }
117 ✔
807
    else {
×
808
        error_handler("Argument QRef is NULL", __FILE__, __func__, __LINE__);
×
809
        return nullptr;
×
810
    }
×
811
}
117 ✔
812

813
__dpctl_give DPCTLSyclEventRef
814
DPCTLQueue_SubmitBarrier(__dpctl_keep const DPCTLSyclQueueRef QRef)
815
{
1 ✔
816
    return DPCTLQueue_SubmitBarrierForEvents(QRef, nullptr, 0);
1 ✔
817
}
1 ✔
818

819
__dpctl_give DPCTLSyclEventRef
820
DPCTLQueue_Memset(__dpctl_keep const DPCTLSyclQueueRef QRef,
821
                  void *USMRef,
822
                  uint8_t Value,
823
                  size_t Count)
824
{
25 ✔
825
    auto Q = unwrap<queue>(QRef);
25 ✔
826
    if (Q && USMRef) {
25 !
827
        sycl::event ev;
24 ✔
828
        try {
24 ✔
829
            ev = Q->memset(USMRef, static_cast<int>(Value), Count);
24 ✔
830
        } catch (std::exception const &e) {
24 ✔
831
            error_handler(e, __FILE__, __func__, __LINE__);
×
832
            return nullptr;
×
833
        }
×
834
        return wrap<event>(new event(std::move(ev)));
24 ✔
835
    }
24 ✔
836
    else {
1 ✔
837
        error_handler("QRef or USMRef passed to fill8 were NULL.", __FILE__,
1 ✔
838
                      __func__, __LINE__);
1 ✔
839
        return nullptr;
1 ✔
840
    }
1 ✔
841
};
25 ✔
842

843
__dpctl_give DPCTLSyclEventRef
844
DPCTLQueue_Fill8(__dpctl_keep const DPCTLSyclQueueRef QRef,
845
                 void *USMRef,
846
                 uint8_t Value,
847
                 size_t Count)
848
{
9 ✔
849
    auto Q = unwrap<queue>(QRef);
9 ✔
850
    if (Q && USMRef) {
9 !
851
        sycl::event ev;
8 ✔
852
        try {
8 ✔
853
            ev = Q->fill<uint8_t>(USMRef, Value, Count);
8 ✔
854
        } catch (std::exception const &e) {
8 ✔
855
            error_handler(e, __FILE__, __func__, __LINE__);
×
856
            return nullptr;
×
857
        }
×
858
        return wrap<event>(new event(std::move(ev)));
8 ✔
859
    }
8 ✔
860
    else {
1 ✔
861
        error_handler("QRef or USMRef passed to fill8 were NULL.", __FILE__,
1 ✔
862
                      __func__, __LINE__);
1 ✔
863
        return nullptr;
1 ✔
864
    }
1 ✔
865
}
9 ✔
866

867
__dpctl_give DPCTLSyclEventRef
868
DPCTLQueue_Fill16(__dpctl_keep const DPCTLSyclQueueRef QRef,
869
                  void *USMRef,
870
                  uint16_t Value,
871
                  size_t Count)
872
{
9 ✔
873
    auto Q = unwrap<queue>(QRef);
9 ✔
874
    if (Q && USMRef) {
9 !
875
        sycl::event ev;
8 ✔
876
        try {
8 ✔
877
            ev = Q->fill<uint16_t>(USMRef, Value, Count);
8 ✔
878
        } catch (std::exception const &e) {
8 ✔
879
            error_handler(e, __FILE__, __func__, __LINE__);
×
880
            return nullptr;
×
881
        }
×
882
        return wrap<event>(new event(std::move(ev)));
8 ✔
883
    }
8 ✔
884
    else {
1 ✔
885
        error_handler("QRef or USMRef passed to fill16 were NULL.", __FILE__,
1 ✔
886
                      __func__, __LINE__);
1 ✔
887
        return nullptr;
1 ✔
888
    }
1 ✔
889
}
9 ✔
890

891
__dpctl_give DPCTLSyclEventRef
892
DPCTLQueue_Fill32(__dpctl_keep const DPCTLSyclQueueRef QRef,
893
                  void *USMRef,
894
                  uint32_t Value,
895
                  size_t Count)
896
{
9 ✔
897
    auto Q = unwrap<queue>(QRef);
9 ✔
898
    if (Q && USMRef) {
9 !
899
        sycl::event ev;
8 ✔
900
        try {
8 ✔
901
            ev = Q->fill<uint32_t>(USMRef, Value, Count);
8 ✔
902
        } catch (std::exception const &e) {
8 ✔
903
            error_handler(e, __FILE__, __func__, __LINE__);
×
904
            return nullptr;
×
905
        }
×
906
        return wrap<event>(new event(std::move(ev)));
8 ✔
907
    }
8 ✔
908
    else {
1 ✔
909
        error_handler("QRef or USMRef passed to fill32 were NULL.", __FILE__,
1 ✔
910
                      __func__, __LINE__);
1 ✔
911
        return nullptr;
1 ✔
912
    }
1 ✔
913
}
9 ✔
914

915
__dpctl_give DPCTLSyclEventRef
916
DPCTLQueue_Fill64(__dpctl_keep const DPCTLSyclQueueRef QRef,
917
                  void *USMRef,
918
                  uint64_t Value,
919
                  size_t Count)
920
{
9 ✔
921
    auto Q = unwrap<queue>(QRef);
9 ✔
922
    if (Q && USMRef) {
9 !
923
        sycl::event ev;
8 ✔
924
        try {
8 ✔
925
            ev = Q->fill<uint64_t>(USMRef, Value, Count);
8 ✔
926
        } catch (std::exception const &e) {
8 ✔
927
            error_handler(e, __FILE__, __func__, __LINE__);
×
928
            return nullptr;
×
929
        }
×
930
        return wrap<event>(new event(std::move(ev)));
8 ✔
931
    }
8 ✔
932
    else {
1 ✔
933
        error_handler("QRef or USMRef passed to fill64 were NULL.", __FILE__,
1 ✔
934
                      __func__, __LINE__);
1 ✔
935
        return nullptr;
1 ✔
936
    }
1 ✔
937
}
9 ✔
938

939
__dpctl_give DPCTLSyclEventRef
940
DPCTLQueue_Fill128(__dpctl_keep const DPCTLSyclQueueRef QRef,
941
                   void *USMRef,
942
                   uint64_t *Value,
943
                   size_t Count)
944
{
9 ✔
945
    auto Q = unwrap<queue>(QRef);
9 ✔
946
    if (Q && USMRef) {
9 !
947
        sycl::event ev;
8 ✔
948
        try {
8 ✔
949
            complexNumber Val;
8 ✔
950
            Val.real = Value[0];
8 ✔
951
            Val.imag = Value[1];
8 ✔
952
            ev = Q->fill(USMRef, Val, Count);
8 ✔
953
        } catch (std::exception const &e) {
8 ✔
954
            error_handler(e, __FILE__, __func__, __LINE__);
×
955
            return nullptr;
×
956
        }
×
957
        return wrap<event>(new event(std::move(ev)));
8 ✔
958
    }
8 ✔
959
    else {
1 ✔
960
        error_handler("QRef or USMRef passed to fill128 were NULL.", __FILE__,
1 ✔
961
                      __func__, __LINE__);
962
        return nullptr;
1 ✔
963
    }
1 ✔
964
}
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