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

IntelPython / dpctl / 14808089933

03 May 2025 05:56AM UTC coverage: 86.372% (-0.05%) from 86.419%
14808089933

Pull #2067

github

web-flow
Merge 05c89234e into fa4eaa7a3
Pull Request #2067: Updating `repr()` function

3023 of 3720 branches covered (81.26%)

Branch coverage included in aggregate %.

15 of 15 new or added lines in 1 file covered. (100.0%)

217 existing lines in 4 files now uncovered.

12257 of 13971 relevant lines covered (87.73%)

6959.73 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✔
UNCOV
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✔
UNCOV
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✔
UNCOV
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✔
UNCOV
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✔
UNCOV
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✔
UNCOV
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✔
UNCOV
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✔
UNCOV
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✔
UNCOV
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✔
UNCOV
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!
UNCOV
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!
UNCOV
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:
×
UNCOV
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✔
UNCOV
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
    }
×
UNCOV
235
#endif
×
UNCOV
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✔
UNCOV
247
    }
×
UNCOV
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✔
UNCOV
344
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
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!
UNCOV
380
        context *ContextPtr = nullptr;
×
UNCOV
381
        try {
×
UNCOV
382
            ContextPtr = new context(*Device);
×
UNCOV
383
            CRef = wrap<context>(ContextPtr);
×
UNCOV
384
        } catch (std::exception const &e) {
×
UNCOV
385
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
386
            delete ContextPtr;
×
UNCOV
387
            return QRef;
×
UNCOV
388
        }
×
UNCOV
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,679✔
402
    delete unwrap<queue>(QRef);
227,679✔
403
}
227,679✔
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,553✔
411
    auto Queue = unwrap<queue>(QRef);
585,553✔
412
    if (Queue) {
585,553✔
413
        try {
585,552✔
414
            auto CopiedQueue = new queue(*Queue);
585,552✔
415
            return wrap<queue>(CopiedQueue);
585,552✔
416
        } catch (std::exception const &e) {
585,552✔
UNCOV
417
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
418
            return nullptr;
×
UNCOV
419
        }
×
420
    }
585,552✔
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,553✔
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✔
UNCOV
447
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
448
            return DPCTL_UNKNOWN_BACKEND;
×
UNCOV
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,735✔
458
    DPCTLSyclDeviceRef DRef = nullptr;
93,735✔
459
    auto Q = unwrap<queue>(QRef);
93,735✔
460
    if (Q) {
93,735✔
461
        try {
93,734✔
462
            auto Device = new device(Q->get_device());
93,734✔
463
            DRef = wrap<device>(Device);
93,734✔
464
        } catch (std::exception const &e) {
93,734✔
UNCOV
465
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
466
        }
×
467
    }
93,734✔
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,735✔
473
}
93,735✔
474

475
__dpctl_give DPCTLSyclContextRef
476
DPCTLQueue_GetContext(__dpctl_keep const DPCTLSyclQueueRef QRef)
477
{
94,724✔
478
    auto Q = unwrap<queue>(QRef);
94,724✔
479
    DPCTLSyclContextRef CRef = nullptr;
94,724✔
480
    if (Q)
94,724✔
481
        CRef = wrap<context>(new context(Q->get_context()));
94,714✔
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,724✔
487
}
94,724✔
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✔
UNCOV
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
        }
×
UNCOV
537
        default:
×
UNCOV
538
            error_handler("Range cannot be greater than three "
×
UNCOV
539
                          "dimensions.",
×
UNCOV
540
                          __FILE__, __func__, __LINE__, error_level::error);
×
UNCOV
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✔
UNCOV
547
        error_handler("Unknown exception encountered", __FILE__, __func__,
×
UNCOV
548
                      __LINE__, error_level::error);
×
UNCOV
549
        return nullptr;
×
UNCOV
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✔
UNCOV
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
        }
×
UNCOV
606
        default:
×
UNCOV
607
            error_handler("Range cannot be greater than three "
×
UNCOV
608
                          "dimensions.",
×
UNCOV
609
                          __FILE__, __func__, __LINE__, error_level::error);
×
UNCOV
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✔
UNCOV
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✔
UNCOV
631
    else {
×
UNCOV
632
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
×
UNCOV
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,882✔
642
    auto Q = unwrap<queue>(QRef);
92,882✔
643
    if (Q) {
92,882✔
644
        sycl::event ev;
92,881✔
645
        try {
92,881✔
646
            ev = Q->memcpy(Dest, Src, Count);
92,881✔
647
        } catch (std::exception const &e) {
92,881✔
648
            error_handler(e, __FILE__, __func__, __LINE__);
8✔
649
            return nullptr;
8✔
650
        }
8✔
651
        return wrap<event>(new event(std::move(ev)));
92,873✔
652
    }
92,881✔
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,882✔
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✔
UNCOV
708
                error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
709
                return nullptr;
×
UNCOV
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✔
UNCOV
738
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
739
            return nullptr;
×
UNCOV
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,696✔
772
    auto Q = unwrap<queue>(QRef);
325,696✔
773
    if (Q) {
325,696✔
774
        std::hash<queue> hash_fn;
325,693✔
775
        return hash_fn(*Q);
325,693✔
776
    }
325,693✔
777
    else {
3✔
778
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
3✔
779
        return 0;
3✔
780
    }
3✔
781
}
325,696✔
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✔
UNCOV
801
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
802
            return nullptr;
×
UNCOV
803
        }
×
804

805
        return wrap<event>(new event(std::move(e)));
117✔
806
    }
117✔
UNCOV
807
    else {
×
UNCOV
808
        error_handler("Argument QRef is NULL", __FILE__, __func__, __LINE__);
×
UNCOV
809
        return nullptr;
×
UNCOV
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✔
UNCOV
831
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
832
            return nullptr;
×
UNCOV
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✔
UNCOV
855
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
856
            return nullptr;
×
UNCOV
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✔
UNCOV
879
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
880
            return nullptr;
×
UNCOV
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✔
UNCOV
903
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
904
            return nullptr;
×
UNCOV
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✔
UNCOV
927
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
928
            return nullptr;
×
UNCOV
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✔
UNCOV
954
            error_handler(e, __FILE__, __func__, __LINE__);
×
UNCOV
955
            return nullptr;
×
UNCOV
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 · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc