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

IntelPython / dpctl / 8358802394

20 Mar 2024 12:21PM UTC coverage: 87.941% (+0.1%) from 87.832%
8358802394

push

github

web-flow
Merge pull request #1576 from IntelPython/remove/device_context

3359 of 3833 branches covered (87.63%)

Branch coverage included in aggregate %.

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

7 existing lines in 2 files now uncovered.

10388 of 11799 relevant lines covered (88.04%)

8167.6 hits per line

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

87.57
/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-2024 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
#include <exception>
35
#include <stdexcept>
36
#include <sycl/sycl.hpp> /* SYCL headers   */
37
#include <utility>
38

39
using namespace sycl;
40

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

111
namespace
112
{
113
static_assert(__SYCL_COMPILER_VERSION >= __SYCL_COMPILER_VERSION_REQUIRED,
114
              "The compiler does not meet minimum version requirement");
115

116
using namespace dpctl::syclinterface;
117

118
typedef struct complex
119
{
120
    uint64_t real;
121
    uint64_t imag;
122
} complexNumber;
123

124
void set_dependent_events(handler &cgh,
125
                          __dpctl_keep const DPCTLSyclEventRef *DepEvents,
126
                          size_t NDepEvents)
127
{
113✔
128
    for (auto i = 0ul; i < NDepEvents; ++i) {
198✔
129
        auto ei = unwrap<event>(DepEvents[i]);
85✔
130
        if (ei)
85!
131
            cgh.depends_on(*ei);
85✔
132
    }
85✔
133
}
113✔
134

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

176
    switch (ArgTy) {
367✔
177
    case DPCTL_INT8_T:
3✔
178
        cgh.set_arg(idx, *(int8_t *)Arg);
3✔
179
        break;
3✔
180
    case DPCTL_UINT8_T:
3✔
181
        cgh.set_arg(idx, *(uint8_t *)Arg);
3✔
182
        break;
3✔
183
    case DPCTL_INT16_T:
9✔
184
        cgh.set_arg(idx, *(int16_t *)Arg);
9✔
185
        break;
9✔
186
    case DPCTL_UINT16_T:
3✔
187
        cgh.set_arg(idx, *(uint16_t *)Arg);
3✔
188
        break;
3✔
189
    case DPCTL_INT32_T:
9✔
190
        cgh.set_arg(idx, *(int32_t *)Arg);
9✔
191
        break;
9✔
192
    case DPCTL_UINT32_T:
11✔
193
        cgh.set_arg(idx, *(uint32_t *)Arg);
11✔
194
        break;
11✔
195
    case DPCTL_INT64_T:
9✔
196
        cgh.set_arg(idx, *(int64_t *)Arg);
9✔
197
        break;
9✔
198
    case DPCTL_UINT64_T:
9✔
199
        cgh.set_arg(idx, *(uint64_t *)Arg);
9✔
200
        break;
9✔
201
    case DPCTL_FLOAT32_T:
9✔
202
        cgh.set_arg(idx, *(float *)Arg);
9✔
203
        break;
9✔
204
    case DPCTL_FLOAT64_T:
9✔
205
        cgh.set_arg(idx, *(double *)Arg);
9✔
206
        break;
9✔
207
    case DPCTL_VOID_PTR:
261✔
208
        cgh.set_arg(idx, Arg);
261✔
209
        break;
261✔
210
    case DPCTL_LOCAL_ACCESSOR:
31✔
211
        arg_set = set_local_accessor_arg(cgh, idx, (MDLocalAccessor *)Arg);
31✔
212
        break;
31✔
213
    default:
1✔
214
        arg_set = false;
1✔
215
        break;
1✔
216
    }
367✔
217
    return arg_set;
367✔
218
}
367✔
219

220
void set_kernel_args(handler &cgh,
221
                     __dpctl_keep void **Args,
222
                     __dpctl_keep const DPCTLKernelArgType *ArgTypes,
223
                     size_t NArgs)
224
{
113✔
225
    for (auto i = 0ul; i < NArgs; ++i) {
478✔
226
        if (!set_kernel_arg(cgh, i, Args[i], ArgTypes[i])) {
367✔
227
            error_handler("Kernel argument could not be created.", __FILE__,
2✔
228
                          __func__, __LINE__);
2✔
229
            throw std::invalid_argument(
2✔
230
                "Kernel argument could not be created.");
2✔
231
        }
2✔
232
    }
367✔
233
}
113✔
234

235
std::unique_ptr<property_list> create_property_list(int properties)
236
{
39,002✔
237
    std::unique_ptr<property_list> propList;
39,002✔
238
    int _prop = properties;
39,002✔
239
    if (_prop & DPCTL_ENABLE_PROFILING) {
39,002✔
240
        _prop = _prop ^ DPCTL_ENABLE_PROFILING;
61✔
241
        if (_prop & DPCTL_IN_ORDER) {
61✔
242
            _prop = _prop ^ DPCTL_IN_ORDER;
24✔
243
            propList = std::make_unique<property_list>(
24✔
244
                sycl::property::queue::enable_profiling(),
24✔
245
                sycl::property::queue::in_order());
24✔
246
        }
24✔
247
        else {
37✔
248
            propList = std::make_unique<property_list>(
37✔
249
                sycl::property::queue::enable_profiling());
37✔
250
        }
37✔
251
    }
61✔
252
    else if (_prop & DPCTL_IN_ORDER) {
38,941✔
253
        _prop = _prop ^ DPCTL_IN_ORDER;
431✔
254
        propList =
431✔
255
            std::make_unique<property_list>(sycl::property::queue::in_order());
431✔
256
    }
431✔
257
    else {
38,510✔
258
        propList = std::make_unique<property_list>();
38,510✔
259
    }
38,510✔
260

261
    if (_prop) {
39,002✔
262
        std::stringstream ss;
1✔
263
        ss << "Invalid queue property argument (" << std::hex << properties
1✔
264
           << "), interpreted as (" << (properties ^ _prop) << ").";
1✔
265
        error_handler(ss.str(), __FILE__, __func__, __LINE__);
1✔
266
    }
1✔
267
    return propList;
39,002✔
268
}
39,002✔
269

270
__dpctl_give DPCTLSyclQueueRef
271
getQueueImpl(__dpctl_keep DPCTLSyclContextRef cRef,
272
             __dpctl_keep DPCTLSyclDeviceRef dRef,
273
             error_handler_callback *handler,
274
             int properties)
275
{
139✔
276
    DPCTLSyclQueueRef qRef = nullptr;
139✔
277
    qRef = DPCTLQueue_Create(cRef, dRef, handler, properties);
139✔
278
    return qRef;
139✔
279
}
139✔
280

281
} /* end of anonymous namespace */
282

283
DPCTL_API
284
__dpctl_give DPCTLSyclQueueRef
285
DPCTLQueue_Create(__dpctl_keep const DPCTLSyclContextRef CRef,
286
                  __dpctl_keep const DPCTLSyclDeviceRef DRef,
287
                  error_handler_callback *handler,
288
                  int properties)
289
{
39,004✔
290
    DPCTLSyclQueueRef q = nullptr;
39,004✔
291
    auto dev = unwrap<device>(DRef);
39,004✔
292
    auto ctx = unwrap<context>(CRef);
39,004✔
293

294
    if (!(dev && ctx)) {
39,004✔
295
        error_handler("Cannot create queue from DPCTLSyclContextRef and "
2✔
296
                      "DPCTLSyclDeviceRef as input is a nullptr.",
2✔
297
                      __FILE__, __func__, __LINE__);
2✔
298
        return q;
2✔
299
    }
2✔
300
    auto propList = create_property_list(properties);
39,002✔
301

302
    if (handler) {
39,002✔
303
        try {
44✔
304
            auto Queue = new queue(*ctx, *dev, DPCTL_AsyncErrorHandler(handler),
44✔
305
                                   *propList);
44✔
306
            q = wrap<queue>(Queue);
44✔
307
        } catch (std::exception const &e) {
44✔
308
            error_handler(e, __FILE__, __func__, __LINE__);
×
309
        }
×
310
    }
44✔
311
    else {
38,958✔
312
        try {
38,958✔
313
            auto Queue = new queue(*ctx, *dev, *propList);
38,958✔
314
            q = wrap<queue>(Queue);
38,958✔
315
        } catch (std::exception const &e) {
38,958✔
316
            error_handler(e, __FILE__, __func__, __LINE__);
2✔
317
        }
2✔
318
    }
38,958✔
319

320
    return q;
39,002✔
321
}
39,002✔
322

323
__dpctl_give DPCTLSyclQueueRef
324
DPCTLQueue_CreateForDevice(__dpctl_keep const DPCTLSyclDeviceRef DRef,
325
                           error_handler_callback *handler,
326
                           int properties)
327
{
325✔
328
    DPCTLSyclContextRef CRef = nullptr;
325✔
329
    DPCTLSyclQueueRef QRef = nullptr;
325✔
330
    auto Device = unwrap<device>(DRef);
325✔
331

332
    if (!Device) {
325✔
333
        error_handler("Cannot create queue from NULL device reference.",
186✔
334
                      __FILE__, __func__, __LINE__);
186✔
335
        return QRef;
186✔
336
    }
186✔
337
    // Check if a cached default context exists for the device.
338
    CRef = DPCTLDeviceMgr_GetCachedContext(DRef);
139✔
339
    // If a cached default context was found, that context will be used to use
340
    // create the new queue. When a default cached context was not found, as
341
    // will be the case for non-root devices, i.e., sub-devices, a new context
342
    // will be allocated. Note that any newly allocated context is not cached.
343
    if (!CRef) {
139!
UNCOV
344
        context *ContextPtr = nullptr;
×
UNCOV
345
        try {
×
UNCOV
346
            ContextPtr = new context(*Device);
×
UNCOV
347
            CRef = wrap<context>(ContextPtr);
×
UNCOV
348
        } catch (std::exception const &e) {
×
349
            error_handler(e, __FILE__, __func__, __LINE__);
×
350
            delete ContextPtr;
×
351
            return QRef;
×
352
        }
×
UNCOV
353
    }
×
354
    // At this point we have a valid context and the queue can be allocated.
355
    QRef = getQueueImpl(CRef, DRef, handler, properties);
139✔
356
    // Free the context
357
    DPCTLContext_Delete(CRef);
139✔
358
    return QRef;
139✔
359
}
139✔
360

361
/*!
362
 * Delete the passed in pointer after verifying it points to a sycl::queue.
363
 */
364
void DPCTLQueue_Delete(__dpctl_take DPCTLSyclQueueRef QRef)
365
{
227,571✔
366
    delete unwrap<queue>(QRef);
227,571✔
367
}
227,571✔
368

369
/*!
370
 * Make copy of sycl::queue referenced by passed pointer
371
 */
372
__dpctl_give DPCTLSyclQueueRef
373
DPCTLQueue_Copy(__dpctl_keep const DPCTLSyclQueueRef QRef)
374
{
544,328✔
375
    auto Queue = unwrap<queue>(QRef);
544,328✔
376
    if (Queue) {
544,328✔
377
        try {
544,327✔
378
            auto CopiedQueue = new queue(*Queue);
544,327✔
379
            return wrap<queue>(CopiedQueue);
544,327✔
380
        } catch (std::exception const &e) {
544,327✔
381
            error_handler(e, __FILE__, __func__, __LINE__);
×
382
            return nullptr;
×
383
        }
×
384
    }
544,327✔
385
    else {
1✔
386
        error_handler("Cannot copy DPCTLSyclQueueRef as input is a nullptr",
1✔
387
                      __FILE__, __func__, __LINE__);
1✔
388
        return nullptr;
1✔
389
    }
1✔
390
}
544,328✔
391

392
bool DPCTLQueue_AreEq(__dpctl_keep const DPCTLSyclQueueRef QRef1,
393
                      __dpctl_keep const DPCTLSyclQueueRef QRef2)
394
{
41,310✔
395
    if (!(QRef1 && QRef2)) {
41,310✔
396
        error_handler("DPCTLSyclQueueRefs are nullptr.", __FILE__, __func__,
2✔
397
                      __LINE__);
2✔
398
        return false;
2✔
399
    }
2✔
400
    return (*unwrap<queue>(QRef1) == *unwrap<queue>(QRef2));
41,308✔
401
}
41,310✔
402

403
DPCTLSyclBackendType DPCTLQueue_GetBackend(__dpctl_keep DPCTLSyclQueueRef QRef)
404
{
10✔
405
    auto Q = unwrap<queue>(QRef);
10✔
406
    if (Q) {
10✔
407
        try {
9✔
408
            auto C = Q->get_context();
9✔
409
            return DPCTLContext_GetBackend(wrap<context>(&C));
9✔
410
        } catch (std::exception const &e) {
9✔
411
            error_handler(e, __FILE__, __func__, __LINE__);
×
412
            return DPCTL_UNKNOWN_BACKEND;
×
413
        }
×
414
    }
9✔
415
    else
1✔
416
        return DPCTL_UNKNOWN_BACKEND;
1✔
417
}
10✔
418

419
__dpctl_give DPCTLSyclDeviceRef
420
DPCTLQueue_GetDevice(__dpctl_keep const DPCTLSyclQueueRef QRef)
421
{
94,213✔
422
    DPCTLSyclDeviceRef DRef = nullptr;
94,213✔
423
    auto Q = unwrap<queue>(QRef);
94,213✔
424
    if (Q) {
94,213✔
425
        try {
94,212✔
426
            auto Device = new device(Q->get_device());
94,212✔
427
            DRef = wrap<device>(Device);
94,212✔
428
        } catch (std::exception const &e) {
94,212✔
429
            error_handler(e, __FILE__, __func__, __LINE__);
×
430
        }
×
431
    }
94,212✔
432
    else {
1✔
433
        error_handler("Could not get the device for this queue.", __FILE__,
1✔
434
                      __func__, __LINE__);
1✔
435
    }
1✔
436
    return DRef;
94,213✔
437
}
94,213✔
438

439
__dpctl_give DPCTLSyclContextRef
440
DPCTLQueue_GetContext(__dpctl_keep const DPCTLSyclQueueRef QRef)
441
{
95,910✔
442
    auto Q = unwrap<queue>(QRef);
95,910✔
443
    DPCTLSyclContextRef CRef = nullptr;
95,910✔
444
    if (Q)
95,910✔
445
        CRef = wrap<context>(new context(Q->get_context()));
95,900✔
446
    else {
10✔
447
        error_handler("Could not get the context for this queue.", __FILE__,
10✔
448
                      __func__, __LINE__);
10✔
449
    }
10✔
450
    return CRef;
95,910✔
451
}
95,910✔
452

453
__dpctl_give DPCTLSyclEventRef
454
DPCTLQueue_SubmitRange(__dpctl_keep const DPCTLSyclKernelRef KRef,
455
                       __dpctl_keep const DPCTLSyclQueueRef QRef,
456
                       __dpctl_keep void **Args,
457
                       __dpctl_keep const DPCTLKernelArgType *ArgTypes,
458
                       size_t NArgs,
459
                       __dpctl_keep const size_t Range[3],
460
                       size_t NDims,
461
                       __dpctl_keep const DPCTLSyclEventRef *DepEvents,
462
                       size_t NDepEvents)
463
{
61✔
464
    auto Kernel = unwrap<kernel>(KRef);
61✔
465
    auto Queue = unwrap<queue>(QRef);
61✔
466
    event e;
61✔
467

468
    try {
61✔
469
        switch (NDims) {
61✔
470
        case 1:
27✔
471
        {
27✔
472
            e = Queue->submit([&](handler &cgh) {
27✔
473
                // Depend on any event that was specified by the caller.
474
                set_dependent_events(cgh, DepEvents, NDepEvents);
27✔
475
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
27✔
476
                cgh.parallel_for(range<1>{Range[0]}, *Kernel);
27✔
477
            });
27✔
478
            return wrap<event>(new event(std::move(e)));
27✔
479
        }
×
480
        case 2:
17✔
481
        {
17✔
482
            e = Queue->submit([&](handler &cgh) {
17✔
483
                // Depend on any event that was specified by the caller.
484
                set_dependent_events(cgh, DepEvents, NDepEvents);
17✔
485
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
17✔
486
                cgh.parallel_for(range<2>{Range[0], Range[1]}, *Kernel);
17✔
487
            });
17✔
488
            return wrap<event>(new event(std::move(e)));
17✔
489
        }
×
490
        case 3:
17✔
491
        {
17✔
492
            e = Queue->submit([&](handler &cgh) {
17✔
493
                // Depend on any event that was specified by the caller.
494
                set_dependent_events(cgh, DepEvents, NDepEvents);
17✔
495
                set_kernel_args(cgh, Args, ArgTypes, NArgs);
17✔
496
                cgh.parallel_for(range<3>{Range[0], Range[1], Range[2]},
17✔
497
                                 *Kernel);
17✔
498
            });
17✔
499
            return wrap<event>(new event(std::move(e)));
17✔
500
        }
×
501
        default:
×
502
            error_handler("Range cannot be greater than three "
×
503
                          "dimensions.",
×
504
                          __FILE__, __func__, __LINE__, error_level::error);
×
505
            return nullptr;
×
506
        }
61✔
507
    } catch (std::exception const &e) {
61✔
508
        error_handler(e, __FILE__, __func__, __LINE__, error_level::error);
1✔
509
        return nullptr;
1✔
510
    } catch (...) {
1✔
511
        error_handler("Unknown exception encountered", __FILE__, __func__,
×
512
                      __LINE__, error_level::error);
×
513
        return nullptr;
×
514
    }
×
515
}
61✔
516

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

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

586
void DPCTLQueue_Wait(__dpctl_keep DPCTLSyclQueueRef QRef)
587
{
1✔
588
    // \todo what happens if the QRef is null or a pointer to a valid sycl
589
    // queue
590
    if (QRef) {
1!
591
        auto SyclQueue = unwrap<queue>(QRef);
1✔
592
        if (SyclQueue)
1!
593
            SyclQueue->wait();
1✔
594
    }
1✔
595
    else {
×
596
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
×
597
    }
×
598
}
1✔
599

600
__dpctl_give DPCTLSyclEventRef
601
DPCTLQueue_Memcpy(__dpctl_keep const DPCTLSyclQueueRef QRef,
602
                  void *Dest,
603
                  const void *Src,
604
                  size_t Count)
605
{
92,641✔
606
    auto Q = unwrap<queue>(QRef);
92,641✔
607
    if (Q) {
92,641✔
608
        sycl::event ev;
92,640✔
609
        try {
92,640✔
610
            ev = Q->memcpy(Dest, Src, Count);
92,640✔
611
        } catch (std::exception const &e) {
92,640✔
612
            error_handler(e, __FILE__, __func__, __LINE__);
8✔
613
            return nullptr;
8✔
614
        }
8✔
615
        return wrap<event>(new event(std::move(ev)));
92,632✔
616
    }
92,640✔
617
    else {
1✔
618
        error_handler("QRef passed to memcpy was NULL.", __FILE__, __func__,
1✔
619
                      __LINE__);
1✔
620
        return nullptr;
1✔
621
    }
1✔
622
}
92,641✔
623

624
__dpctl_give DPCTLSyclEventRef
625
DPCTLQueue_MemcpyWithEvents(__dpctl_keep const DPCTLSyclQueueRef QRef,
626
                            void *Dest,
627
                            const void *Src,
628
                            size_t Count,
629
                            const DPCTLSyclEventRef *DepEvents,
630
                            size_t DepEventsCount)
631
{
60✔
632
    event ev;
60✔
633
    auto Q = unwrap<queue>(QRef);
60✔
634
    if (Q) {
60✔
635
        try {
59✔
636
            ev = Q->submit([&](handler &cgh) {
59✔
637
                if (DepEvents)
59✔
638
                    for (size_t i = 0; i < DepEventsCount; ++i) {
102✔
639
                        event *ei = unwrap<event>(DepEvents[i]);
51✔
640
                        if (ei)
51!
641
                            cgh.depends_on(*ei);
51✔
642
                    }
51✔
643

644
                cgh.memcpy(Dest, Src, Count);
59✔
645
            });
59✔
646
        } catch (const std::exception &ex) {
59✔
647
            error_handler(ex, __FILE__, __func__, __LINE__);
8✔
648
            return nullptr;
8✔
649
        }
8✔
650
    }
59✔
651
    else {
1✔
652
        error_handler("QRef passed to memcpy was NULL.", __FILE__, __func__,
1✔
653
                      __LINE__);
1✔
654
        return nullptr;
1✔
655
    }
1✔
656

657
    return wrap<event>(new event(ev));
51✔
658
}
60✔
659

660
__dpctl_give DPCTLSyclEventRef
661
DPCTLQueue_Prefetch(__dpctl_keep DPCTLSyclQueueRef QRef,
662
                    const void *Ptr,
663
                    size_t Count)
664
{
16✔
665
    auto Q = unwrap<queue>(QRef);
16✔
666
    if (Q) {
16✔
667
        if (Ptr) {
15✔
668
            sycl::event ev;
7✔
669
            try {
7✔
670
                ev = Q->prefetch(Ptr, Count);
7✔
671
            } catch (std::exception const &e) {
7✔
672
                error_handler(e, __FILE__, __func__, __LINE__);
×
673
                return nullptr;
×
674
            }
×
675
            return wrap<event>(new event(std::move(ev)));
7✔
676
        }
7✔
677
        else {
8✔
678
            error_handler("Attempt to prefetch USM-allocation at nullptr.",
8✔
679
                          __FILE__, __func__, __LINE__);
8✔
680
            return nullptr;
8✔
681
        }
8✔
682
    }
15✔
683
    else {
1✔
684
        error_handler("QRef passed to prefetch was NULL.", __FILE__, __func__,
1✔
685
                      __LINE__);
1✔
686
        return nullptr;
1✔
687
    }
1✔
688
}
16✔
689

690
__dpctl_give DPCTLSyclEventRef
691
DPCTLQueue_MemAdvise(__dpctl_keep DPCTLSyclQueueRef QRef,
692
                     const void *Ptr,
693
                     size_t Count,
694
                     int Advice)
695
{
16✔
696
    auto Q = unwrap<queue>(QRef);
16✔
697
    if (Q) {
16✔
698
        sycl::event ev;
15✔
699
        try {
15✔
700
            ev = Q->mem_advise(Ptr, Count, Advice);
15✔
701
        } catch (std::exception const &e) {
15✔
702
            error_handler(e, __FILE__, __func__, __LINE__);
×
703
            return nullptr;
×
704
        }
×
705
        return wrap<event>(new event(std::move(ev)));
15✔
706
    }
15✔
707
    else {
1✔
708
        error_handler("QRef passed to prefetch was NULL.", __FILE__, __func__,
1✔
709
                      __LINE__);
1✔
710
        return nullptr;
1✔
711
    }
1✔
712
}
16✔
713

714
bool DPCTLQueue_IsInOrder(__dpctl_keep const DPCTLSyclQueueRef QRef)
715
{
820✔
716
    auto Q = unwrap<queue>(QRef);
820✔
717
    if (Q) {
820✔
718
        return Q->is_in_order();
819✔
719
    }
819✔
720
    else
1✔
721
        return false;
1✔
722
}
820✔
723

724
bool DPCTLQueue_HasEnableProfiling(__dpctl_keep const DPCTLSyclQueueRef QRef)
725
{
56✔
726
    auto Q = unwrap<queue>(QRef);
56✔
727
    if (Q) {
56✔
728
        return Q->has_property<sycl::property::queue::enable_profiling>();
55✔
729
    }
55✔
730
    else
1✔
731
        return false;
1✔
732
}
56✔
733

734
size_t DPCTLQueue_Hash(__dpctl_keep const DPCTLSyclQueueRef QRef)
735
{
38✔
736
    auto Q = unwrap<queue>(QRef);
38✔
737
    if (Q) {
38✔
738
        std::hash<queue> hash_fn;
35✔
739
        return hash_fn(*Q);
35✔
740
    }
35✔
741
    else {
3✔
742
        error_handler("Argument QRef is NULL.", __FILE__, __func__, __LINE__);
3✔
743
        return 0;
3✔
744
    }
3✔
745
}
38✔
746

747
__dpctl_give DPCTLSyclEventRef DPCTLQueue_SubmitBarrierForEvents(
748
    __dpctl_keep const DPCTLSyclQueueRef QRef,
749
    __dpctl_keep const DPCTLSyclEventRef *DepEvents,
750
    size_t NDepEvents)
751
{
105✔
752
    auto Q = unwrap<queue>(QRef);
105✔
753
    event e;
105✔
754
    if (Q) {
105!
755
        try {
105✔
756
            e = Q->submit([&](handler &cgh) {
105✔
757
                // Depend on any event that was specified by the caller.
758
                if (NDepEvents)
105✔
759
                    for (auto i = 0ul; i < NDepEvents; ++i)
20✔
760
                        cgh.depends_on(*unwrap<event>(DepEvents[i]));
13✔
761

762
                cgh.ext_oneapi_barrier();
105✔
763
            });
105✔
764
        } catch (std::exception const &e) {
105✔
765
            error_handler(e, __FILE__, __func__, __LINE__);
×
766
            return nullptr;
×
767
        }
×
768

769
        return wrap<event>(new event(std::move(e)));
105✔
770
    }
105✔
771
    else {
×
772
        error_handler("Argument QRef is NULL", __FILE__, __func__, __LINE__);
×
773
        return nullptr;
×
774
    }
×
775
}
105✔
776

777
__dpctl_give DPCTLSyclEventRef
778
DPCTLQueue_SubmitBarrier(__dpctl_keep const DPCTLSyclQueueRef QRef)
779
{
1✔
780
    return DPCTLQueue_SubmitBarrierForEvents(QRef, nullptr, 0);
1✔
781
}
1✔
782

783
__dpctl_give DPCTLSyclEventRef
784
DPCTLQueue_Memset(__dpctl_keep const DPCTLSyclQueueRef QRef,
785
                  void *USMRef,
786
                  uint8_t Value,
787
                  size_t Count)
788
{
3,401✔
789
    auto Q = unwrap<queue>(QRef);
3,401✔
790
    if (Q && USMRef) {
3,401!
791
        sycl::event ev;
3,400✔
792
        try {
3,400✔
793
            ev = Q->memset(USMRef, static_cast<int>(Value), Count);
3,400✔
794
        } catch (std::exception const &e) {
3,400✔
795
            error_handler(e, __FILE__, __func__, __LINE__);
×
796
            return nullptr;
×
797
        }
×
798
        return wrap<event>(new event(std::move(ev)));
3,400✔
799
    }
3,400✔
800
    else {
1✔
801
        error_handler("QRef or USMRef passed to fill8 were NULL.", __FILE__,
1✔
802
                      __func__, __LINE__);
1✔
803
        return nullptr;
1✔
804
    }
1✔
805
};
3,401✔
806

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

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

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

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

903
__dpctl_give DPCTLSyclEventRef
904
DPCTLQueue_Fill128(__dpctl_keep const DPCTLSyclQueueRef QRef,
905
                   void *USMRef,
906
                   uint64_t *Value,
907
                   size_t Count)
908
{
9✔
909
    auto Q = unwrap<queue>(QRef);
9✔
910
    if (Q && USMRef) {
9!
911
        sycl::event ev;
8✔
912
        try {
8✔
913
            complexNumber Val;
8✔
914
            Val.real = Value[0];
8✔
915
            Val.imag = Value[1];
8✔
916
            ev = Q->fill(USMRef, Val, Count);
8✔
917
        } catch (std::exception const &e) {
8✔
918
            error_handler(e, __FILE__, __func__, __LINE__);
×
919
            return nullptr;
×
920
        }
×
921
        return wrap<event>(new event(std::move(ev)));
8✔
922
    }
8✔
923
    else {
1✔
924
        error_handler("QRef or USMRef passed to fill128 were NULL.", __FILE__,
1✔
925
                      __func__, __LINE__);
1✔
926
        return nullptr;
1✔
927
    }
1✔
928
}
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