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

IntelPython / dpctl / 16270219306

14 Jul 2025 02:53PM UTC coverage: 85.89%. Remained the same
16270219306

Pull #2123

github

web-flow
Merge 4947f5cfd into e2789db9a
Pull Request #2123: Allow type casting of zero-sized array to any dtype

3227 of 3878 branches covered (83.21%)

Branch coverage included in aggregate %.

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

2 existing lines in 2 files now uncovered.

12235 of 14124 relevant lines covered (86.63%)

6889.19 hits per line

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

74.73
/libsyclinterface/source/dpctl_sycl_device_interface.cpp
1
//===--- dpctl_sycl_device_interface.cpp - Implements C API for sycl::device =//
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_device_interface.h.
24
///
25
//===----------------------------------------------------------------------===//
26

27
#include "dpctl_sycl_device_interface.h"
28
#include "Config/dpctl_config.h"
29
#include "dpctl_device_selection.hpp"
30
#include "dpctl_error_handlers.h"
31
#include "dpctl_string_utils.hpp"
32
#include "dpctl_sycl_device_manager.h"
33
#include "dpctl_sycl_type_casters.hpp"
34
#include "dpctl_utils_helper.h"
35
#include <algorithm>
36
#include <stddef.h>
37
#include <sycl/sycl.hpp> /* SYCL headers   */
38
#include <utility>
39
#include <vector>
40

41
using namespace sycl;
42

43
namespace
44
{
45

46
static_assert(__SYCL_COMPILER_VERSION >= __SYCL_COMPILER_VERSION_REQUIRED,
47
              "The compiler does not meet minimum version requirement");
48

49
using namespace dpctl::syclinterface;
50

51
device *new_device_from_selector(const dpctl_device_selector *sel)
52
{
20,988✔
53
    return new device(
20,988✔
54
        [=](const device &d) -> int { return sel->operator()(d); });
20,988✔
55
}
20,988✔
56

57
template <int dim>
58
__dpctl_keep size_t *
59
DPCTLDevice__GetMaxWorkItemSizes(__dpctl_keep const DPCTLSyclDeviceRef DRef)
60
{
272,773✔
61
    size_t *sizes = nullptr;
272,773✔
62
    auto D = unwrap<device>(DRef);
272,773✔
63
    if (D) {
272,773✔
64
        try {
272,770✔
65
#if __SYCL_COMPILER_VERSION >= __SYCL_COMPILER_MAX_WORK_ITEM_SIZE_THRESHOLD
272,770✔
66
            auto id_sizes =
272,770✔
67
                D->get_info<info::device::max_work_item_sizes<dim>>();
272,770✔
68
#else
69
            auto id_sizes = D->get_info<info::device::max_work_item_sizes>();
70
#endif
71
            sizes = new size_t[dim];
272,770✔
72
            for (auto i = 0ul; i < dim; ++i) {
1,091,011✔
73
                sizes[i] = id_sizes[i];
818,241✔
74
            }
818,241✔
75
        } catch (std::exception const &e) {
272,770✔
76
            error_handler(e, __FILE__, __func__, __LINE__);
×
77
        }
×
78
    }
272,770✔
79
    return sizes;
272,773✔
80
}
272,773✔
81

82
} /* end of anonymous namespace */
83

84
__dpctl_give DPCTLSyclDeviceRef
85
DPCTLDevice_Copy(__dpctl_keep const DPCTLSyclDeviceRef DRef)
86
{
161,514✔
87
    auto Device = unwrap<device>(DRef);
161,514✔
88
    if (!Device) {
161,514✔
89
        error_handler("Cannot copy DPCTLSyclDeviceRef as input is a nullptr",
1✔
90
                      __FILE__, __func__, __LINE__);
1✔
91
        return nullptr;
1✔
92
    }
1✔
93
    try {
161,513✔
94
        auto CopiedDevice = new device(*Device);
161,513✔
95
        return wrap<device>(CopiedDevice);
161,513✔
96
    } catch (std::exception const &e) {
161,513✔
97
        error_handler(e, __FILE__, __func__, __LINE__);
×
98
        return nullptr;
×
99
    }
×
100
}
161,513✔
101

102
__dpctl_give DPCTLSyclDeviceRef DPCTLDevice_Create()
103
{
1✔
104
    try {
1✔
105
        auto Device = new device();
1✔
106
        return wrap<device>(Device);
1✔
107
    } catch (std::exception const &e) {
1✔
108
        error_handler(e, __FILE__, __func__, __LINE__);
×
109
        return nullptr;
×
110
    }
×
111
}
1✔
112

113
__dpctl_give DPCTLSyclDeviceRef DPCTLDevice_CreateFromSelector(
114
    __dpctl_keep const DPCTLSyclDeviceSelectorRef DSRef)
115
{
21,002✔
116
    auto Selector = unwrap<dpctl_device_selector>(DSRef);
21,002✔
117
    if (!Selector) {
21,002✔
118
        error_handler("Cannot define device selector for DPCTLSyclDeviceRef "
14✔
119
                      "as input is a nullptr.",
14✔
120
                      __FILE__, __func__, __LINE__);
14✔
121
        return nullptr;
14✔
122
    }
14✔
123
    try {
20,988✔
124
        auto Device = new_device_from_selector(Selector);
20,988✔
125
        return wrap<device>(Device);
20,988✔
126
    } catch (std::exception const &e) {
20,988✔
127
        error_handler(e, __FILE__, __func__, __LINE__);
3,114✔
128
        return nullptr;
3,114✔
129
    }
3,114✔
130
}
20,988✔
131

132
void DPCTLDevice_Delete(__dpctl_take DPCTLSyclDeviceRef DRef)
133
{
275,569✔
134
    delete unwrap<device>(DRef);
275,569✔
135
}
275,569✔
136

137
DPCTLSyclDeviceType
138
DPCTLDevice_GetDeviceType(__dpctl_keep const DPCTLSyclDeviceRef DRef)
139
{
67✔
140
    DPCTLSyclDeviceType DTy = DPCTLSyclDeviceType::DPCTL_UNKNOWN_DEVICE;
67✔
141
    auto D = unwrap<device>(DRef);
67✔
142
    if (D) {
67✔
143
        try {
66✔
144
            auto SyclDTy = D->get_info<info::device::device_type>();
66✔
145
            DTy = DPCTL_SyclDeviceTypeToDPCTLDeviceType(SyclDTy);
66✔
146
        } catch (std::exception const &e) {
66✔
147
            error_handler(e, __FILE__, __func__, __LINE__);
×
148
        }
×
149
    }
66✔
150
    return DTy;
67✔
151
}
67✔
152

153
bool DPCTLDevice_IsAccelerator(__dpctl_keep const DPCTLSyclDeviceRef DRef)
154
{
78✔
155
    auto D = unwrap<device>(DRef);
78✔
156
    if (D) {
78✔
157
        return D->is_accelerator();
77✔
158
    }
77✔
159
    return false;
1✔
160
}
78✔
161

162
bool DPCTLDevice_IsCPU(__dpctl_keep const DPCTLSyclDeviceRef DRef)
163
{
26✔
164
    auto D = unwrap<device>(DRef);
26✔
165
    if (D) {
26✔
166
        return D->is_cpu();
25✔
167
    }
25✔
168
    return false;
1✔
169
}
26✔
170

171
bool DPCTLDevice_IsGPU(__dpctl_keep const DPCTLSyclDeviceRef DRef)
172
{
24✔
173
    auto D = unwrap<device>(DRef);
24✔
174
    if (D) {
24✔
175
        return D->is_gpu();
23✔
176
    }
23✔
177
    return false;
1✔
178
}
24✔
179

180
DPCTLSyclBackendType
181
DPCTLDevice_GetBackend(__dpctl_keep const DPCTLSyclDeviceRef DRef)
182
{
66✔
183
    DPCTLSyclBackendType BTy = DPCTLSyclBackendType::DPCTL_UNKNOWN_BACKEND;
66✔
184
    auto D = unwrap<device>(DRef);
66✔
185
    if (D) {
66!
186
        BTy = DPCTL_SyclBackendToDPCTLBackendType(D->get_backend());
66✔
187
    }
66✔
188
    return BTy;
66✔
189
}
66✔
190

191
uint32_t
192
DPCTLDevice_GetMaxComputeUnits(__dpctl_keep const DPCTLSyclDeviceRef DRef)
193
{
104✔
194
    uint32_t nComputeUnits = 0;
104✔
195
    auto D = unwrap<device>(DRef);
104✔
196
    if (D) {
104✔
197
        try {
103✔
198
            nComputeUnits = D->get_info<info::device::max_compute_units>();
103✔
199
        } catch (std::exception const &e) {
103✔
200
            error_handler(e, __FILE__, __func__, __LINE__);
×
201
        }
×
202
    }
103✔
203
    return nComputeUnits;
104✔
204
}
104✔
205

206
uint64_t
207
DPCTLDevice_GetGlobalMemSize(__dpctl_keep const DPCTLSyclDeviceRef DRef)
208
{
24✔
209
    uint64_t GlobalMemSize = 0;
24✔
210
    auto D = unwrap<device>(DRef);
24✔
211
    if (D) {
24✔
212
        try {
23✔
213
            GlobalMemSize = D->get_info<info::device::global_mem_size>();
23✔
214
        } catch (std::exception const &e) {
23✔
215
            error_handler(e, __FILE__, __func__, __LINE__);
×
216
        }
×
217
    }
23✔
218
    return GlobalMemSize;
24✔
219
}
24✔
220

221
uint64_t DPCTLDevice_GetLocalMemSize(__dpctl_keep const DPCTLSyclDeviceRef DRef)
222
{
24✔
223
    uint64_t LocalMemSize = 0;
24✔
224
    auto D = unwrap<device>(DRef);
24✔
225
    if (D) {
24✔
226
        try {
23✔
227
            LocalMemSize = D->get_info<info::device::local_mem_size>();
23✔
228
        } catch (std::exception const &e) {
23✔
229
            error_handler(e, __FILE__, __func__, __LINE__);
×
230
        }
×
231
    }
23✔
232
    return LocalMemSize;
24✔
233
}
24✔
234

235
uint32_t
236
DPCTLDevice_GetMaxWorkItemDims(__dpctl_keep const DPCTLSyclDeviceRef DRef)
237
{
24✔
238
    uint32_t maxWorkItemDims = 0;
24✔
239
    auto D = unwrap<device>(DRef);
24✔
240
    if (D) {
24✔
241
        try {
23✔
242
            maxWorkItemDims =
23✔
243
                D->get_info<info::device::max_work_item_dimensions>();
23✔
244
        } catch (std::exception const &e) {
23✔
245
            error_handler(e, __FILE__, __func__, __LINE__);
×
246
        }
×
247
    }
23✔
248
    return maxWorkItemDims;
24✔
249
}
24✔
250

251
__dpctl_keep size_t *
252
DPCTLDevice_GetMaxWorkItemSizes1d(__dpctl_keep const DPCTLSyclDeviceRef DRef)
253
{
24✔
254
    return DPCTLDevice__GetMaxWorkItemSizes<1>(DRef);
24✔
255
}
24✔
256

257
__dpctl_keep size_t *
258
DPCTLDevice_GetMaxWorkItemSizes2d(__dpctl_keep const DPCTLSyclDeviceRef DRef)
259
{
24✔
260
    return DPCTLDevice__GetMaxWorkItemSizes<2>(DRef);
24✔
261
}
24✔
262

263
__dpctl_keep size_t *
264
DPCTLDevice_GetMaxWorkItemSizes3d(__dpctl_keep const DPCTLSyclDeviceRef DRef)
265
{
272,725✔
266
    return DPCTLDevice__GetMaxWorkItemSizes<3>(DRef);
272,725✔
267
}
272,725✔
268

269
size_t
270
DPCTLDevice_GetMaxWorkGroupSize(__dpctl_keep const DPCTLSyclDeviceRef DRef)
271
{
25✔
272
    size_t max_wg_size = 0;
25✔
273
    auto D = unwrap<device>(DRef);
25✔
274
    if (D) {
25✔
275
        try {
24✔
276
            max_wg_size = D->get_info<info::device::max_work_group_size>();
24✔
277
        } catch (std::exception const &e) {
24✔
278
            error_handler(e, __FILE__, __func__, __LINE__);
×
279
        }
×
280
    }
24✔
281
    return max_wg_size;
25✔
282
}
25✔
283

284
uint32_t
285
DPCTLDevice_GetMaxNumSubGroups(__dpctl_keep const DPCTLSyclDeviceRef DRef)
286
{
24✔
287
    size_t max_nsubgroups = 0;
24✔
288
    auto D = unwrap<device>(DRef);
24✔
289
    if (D) {
24✔
290
        try {
23✔
291
            max_nsubgroups = D->get_info<info::device::max_num_sub_groups>();
23✔
292
        } catch (std::exception const &e) {
23✔
293
            error_handler(e, __FILE__, __func__, __LINE__);
×
294
        }
×
295
    }
23✔
296
    return max_nsubgroups;
24✔
297
}
24✔
298

299
__dpctl_give DPCTLSyclPlatformRef
300
DPCTLDevice_GetPlatform(__dpctl_keep const DPCTLSyclDeviceRef DRef)
301
{
2,329✔
302
    DPCTLSyclPlatformRef PRef = nullptr;
2,329✔
303
    auto D = unwrap<device>(DRef);
2,329✔
304
    if (D) {
2,329✔
305
        try {
2,328✔
306
            PRef = wrap<platform>(new platform(D->get_platform()));
2,328✔
307
        } catch (std::exception const &e) {
2,328✔
308
            error_handler(e, __FILE__, __func__, __LINE__);
×
309
        }
×
310
    }
2,328✔
311
    return PRef;
2,329✔
312
}
2,329✔
313

314
__dpctl_give const char *
315
DPCTLDevice_GetName(__dpctl_keep const DPCTLSyclDeviceRef DRef)
316
{
272,725✔
317
    const char *cstr_name = nullptr;
272,725✔
318
    auto D = unwrap<device>(DRef);
272,725✔
319
    if (D) {
272,725✔
320
        try {
272,724✔
321
            auto name = D->get_info<info::device::name>();
272,724✔
322
            cstr_name = dpctl::helper::cstring_from_string(name);
272,724✔
323
        } catch (std::exception const &e) {
272,724✔
324
            error_handler(e, __FILE__, __func__, __LINE__);
×
325
        }
×
326
    }
272,724✔
327
    return cstr_name;
272,725✔
328
}
272,725✔
329

330
__dpctl_give const char *
331
DPCTLDevice_GetVendor(__dpctl_keep const DPCTLSyclDeviceRef DRef)
332
{
272,725✔
333
    const char *cstr_vendor = nullptr;
272,725✔
334
    auto D = unwrap<device>(DRef);
272,725✔
335
    if (D) {
272,725✔
336
        try {
272,724✔
337
            auto vendor = D->get_info<info::device::vendor>();
272,724✔
338
            cstr_vendor = dpctl::helper::cstring_from_string(vendor);
272,724✔
339
        } catch (std::exception const &e) {
272,724✔
340
            error_handler(e, __FILE__, __func__, __LINE__);
×
341
        }
×
342
    }
272,724✔
343
    return cstr_vendor;
272,725✔
344
}
272,725✔
345

346
__dpctl_give const char *
347
DPCTLDevice_GetDriverVersion(__dpctl_keep const DPCTLSyclDeviceRef DRef)
348
{
272,725✔
349
    const char *cstr_driver = nullptr;
272,725✔
350
    auto D = unwrap<device>(DRef);
272,725✔
351
    if (D) {
272,725✔
352
        try {
272,724✔
353
            auto driver = D->get_info<info::device::driver_version>();
272,724✔
354
            cstr_driver = dpctl::helper::cstring_from_string(driver);
272,724✔
355
        } catch (std::exception const &e) {
272,724✔
356
            error_handler(e, __FILE__, __func__, __LINE__);
×
357
        }
×
358
    }
272,724✔
359
    return cstr_driver;
272,725✔
360
}
272,725✔
361

362
bool DPCTLDevice_AreEq(__dpctl_keep const DPCTLSyclDeviceRef DRef1,
363
                       __dpctl_keep const DPCTLSyclDeviceRef DRef2)
364
{
3,778✔
365
    auto D1 = unwrap<device>(DRef1);
3,778✔
366
    auto D2 = unwrap<device>(DRef2);
3,778✔
367
    if (D1 && D2)
3,778!
368
        return *D1 == *D2;
3,777✔
369
    else
1✔
370
        return false;
1✔
371
}
3,778✔
372

373
bool DPCTLDevice_HasAspect(__dpctl_keep const DPCTLSyclDeviceRef DRef,
374
                           DPCTLSyclAspectType AT)
375
{
376,455✔
376
    bool hasAspect = false;
376,455✔
377
    auto D = unwrap<device>(DRef);
376,455✔
378
    if (D) {
376,455✔
379
        try {
376,454✔
380
            hasAspect = D->has(DPCTL_DPCTLAspectTypeToSyclAspect(AT));
376,454✔
381
        } catch (std::exception const &e) {
376,454✔
382
            error_handler(e, __FILE__, __func__, __LINE__);
×
383
        }
×
384
    }
376,454✔
385
    return hasAspect;
376,455✔
386
}
376,455✔
387

388
#define declmethod(FUNC, NAME, TYPE)                                           \
389
    TYPE DPCTLDevice_##FUNC(__dpctl_keep const DPCTLSyclDeviceRef DRef)        \
390
    {                                                                          \
168✔
391
        TYPE result = 0;                                                       \
168✔
392
        auto D = unwrap<device>(DRef);                                         \
168✔
393
        if (D) {                                                               \
168✔
394
            try {                                                              \
161✔
395
                result = D->get_info<info::device::NAME>();                    \
161✔
396
            } catch (std::exception const &e) {                                \
161✔
397
                error_handler(e, __FILE__, __func__, __LINE__);                \
×
398
            }                                                                  \
×
399
        }                                                                      \
161✔
400
        return result;                                                         \
168✔
401
    }
168✔
402
declmethod(GetMaxReadImageArgs, max_read_image_args, uint32_t);
403
declmethod(GetMaxWriteImageArgs, max_write_image_args, uint32_t);
404
declmethod(GetImage2dMaxWidth, image2d_max_width, size_t);
405
declmethod(GetImage2dMaxHeight, image2d_max_height, size_t);
406
declmethod(GetImage3dMaxWidth, image3d_max_width, size_t);
407
declmethod(GetImage3dMaxHeight, image3d_max_height, size_t);
408
declmethod(GetImage3dMaxDepth, image3d_max_depth, size_t);
409
#undef declmethod
410

411
bool DPCTLDevice_GetSubGroupIndependentForwardProgress(
412
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
413
{
24✔
414
    bool SubGroupProgress = false;
24✔
415
    auto D = unwrap<device>(DRef);
24✔
416
    if (D) {
24✔
417
        try {
23✔
418
            SubGroupProgress = D->get_info<
23✔
419
                info::device::sub_group_independent_forward_progress>();
23✔
420
        } catch (std::exception const &e) {
23✔
421
            error_handler(e, __FILE__, __func__, __LINE__);
×
422
        }
×
423
    }
23✔
424
    return SubGroupProgress;
24✔
425
}
24✔
426

427
namespace
428
{
429

430
template <typename descriptorT>
431
uint32_t get_uint32_descriptor(__dpctl_keep const DPCTLSyclDeviceRef DRef)
432
{
329✔
433
    uint32_t descr_val = 0;
329✔
434
    auto D = unwrap<device>(DRef);
329✔
435
    if (D) {
329!
436
        try {
322✔
437
            descr_val = D->get_info<descriptorT>();
322✔
438
        } catch (std::exception const &e) {
322✔
439
            error_handler(e, __FILE__, __func__, __LINE__);
×
440
        }
×
441
    }
322✔
442
    return descr_val;
329✔
443
}
329✔
444

445
} // end of anonymous namespace
446

447
uint32_t DPCTLDevice_GetPreferredVectorWidthChar(
448
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
449
{
24✔
450
    return get_uint32_descriptor<info::device::preferred_vector_width_char>(
24✔
451
        DRef);
24✔
452
}
24✔
453

454
uint32_t DPCTLDevice_GetPreferredVectorWidthShort(
455
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
456
{
24✔
457
    return get_uint32_descriptor<info::device::preferred_vector_width_short>(
24✔
458
        DRef);
24✔
459
}
24✔
460

461
uint32_t DPCTLDevice_GetPreferredVectorWidthInt(
462
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
463
{
24✔
464
    return get_uint32_descriptor<info::device::preferred_vector_width_int>(
24✔
465
        DRef);
24✔
466
}
24✔
467

468
uint32_t DPCTLDevice_GetPreferredVectorWidthLong(
469
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
470
{
24✔
471
    return get_uint32_descriptor<info::device::preferred_vector_width_long>(
24✔
472
        DRef);
24✔
473
}
24✔
474

475
uint32_t DPCTLDevice_GetPreferredVectorWidthFloat(
476
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
477
{
24✔
478
    return get_uint32_descriptor<info::device::preferred_vector_width_float>(
24✔
479
        DRef);
24✔
480
}
24✔
481

482
uint32_t DPCTLDevice_GetPreferredVectorWidthDouble(
483
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
484
{
24✔
485
    return get_uint32_descriptor<info::device::preferred_vector_width_double>(
24✔
486
        DRef);
24✔
487
}
24✔
488

489
uint32_t DPCTLDevice_GetPreferredVectorWidthHalf(
490
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
491
{
24✔
492
    return get_uint32_descriptor<info::device::preferred_vector_width_half>(
24✔
493
        DRef);
24✔
494
}
24✔
495

496
//
497
uint32_t
498
DPCTLDevice_GetNativeVectorWidthChar(__dpctl_keep const DPCTLSyclDeviceRef DRef)
499
{
23✔
500
    return get_uint32_descriptor<info::device::native_vector_width_char>(DRef);
23✔
501
}
23✔
502

503
uint32_t DPCTLDevice_GetNativeVectorWidthShort(
504
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
505
{
23✔
506
    return get_uint32_descriptor<info::device::native_vector_width_short>(DRef);
23✔
507
}
23✔
508

509
uint32_t
510
DPCTLDevice_GetNativeVectorWidthInt(__dpctl_keep const DPCTLSyclDeviceRef DRef)
511
{
23✔
512
    return get_uint32_descriptor<info::device::native_vector_width_int>(DRef);
23✔
513
}
23✔
514

515
uint32_t
516
DPCTLDevice_GetNativeVectorWidthLong(__dpctl_keep const DPCTLSyclDeviceRef DRef)
517
{
23✔
518
    return get_uint32_descriptor<info::device::native_vector_width_long>(DRef);
23✔
519
}
23✔
520

521
uint32_t DPCTLDevice_GetNativeVectorWidthFloat(
522
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
523
{
23✔
524
    return get_uint32_descriptor<info::device::native_vector_width_float>(DRef);
23✔
525
}
23✔
526

527
uint32_t DPCTLDevice_GetNativeVectorWidthDouble(
528
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
529
{
23✔
530
    return get_uint32_descriptor<info::device::native_vector_width_double>(
23✔
531
        DRef);
23✔
532
}
23✔
533

534
uint32_t
535
DPCTLDevice_GetNativeVectorWidthHalf(__dpctl_keep const DPCTLSyclDeviceRef DRef)
536
{
23✔
537
    return get_uint32_descriptor<info::device::native_vector_width_half>(DRef);
23✔
538
}
23✔
539

540
__dpctl_give DPCTLSyclDeviceRef
541
DPCTLDevice_GetParentDevice(__dpctl_keep const DPCTLSyclDeviceRef DRef)
542
{
1,731✔
543
    auto D = unwrap<device>(DRef);
1,731✔
544
    if (D) {
1,731✔
545
        bool is_unpartitioned = false;
1,730✔
546
        try {
1,730✔
547
            auto pp =
1,730✔
548
                D->get_info<sycl::info::device::partition_type_property>();
1,730✔
549
            is_unpartitioned =
1,730✔
550
                (pp == sycl::info::partition_property::no_partition);
1,730✔
551
        } catch (std::exception const &e) {
1,730✔
552
            error_handler(e, __FILE__, __func__, __LINE__);
×
553
            return nullptr;
×
554
        }
×
555
        if (is_unpartitioned)
1,730✔
556
            return nullptr;
1,721✔
557
        try {
9✔
558
            const auto &parent_D = D->get_info<info::device::parent_device>();
9✔
559
            return wrap<device>(new device(parent_D));
9✔
560
        } catch (std::exception const &e) {
9✔
561
            error_handler(e, __FILE__, __func__, __LINE__);
×
562
            return nullptr;
×
563
        }
×
564
    }
9✔
565
    else
1✔
566
        return nullptr;
1✔
567
}
1,731✔
568

569
uint32_t DPCTLDevice_GetPartitionMaxSubDevices(
570
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
571
{
24✔
572
    auto D = unwrap<device>(DRef);
24✔
573
    if (D) {
24✔
574
        try {
23✔
575
            uint32_t part_max_sub_devs =
23✔
576
                D->get_info<info::device::partition_max_sub_devices>();
23✔
577
            return part_max_sub_devs;
23✔
578
        } catch (std::exception const &e) {
23✔
579
            error_handler(e, __FILE__, __func__, __LINE__);
×
580
            return 0;
×
581
        }
×
582
    }
23✔
583
    else
1✔
584
        return 0;
1✔
585
}
24✔
586

587
__dpctl_give DPCTLDeviceVectorRef
588
DPCTLDevice_CreateSubDevicesEqually(__dpctl_keep const DPCTLSyclDeviceRef DRef,
589
                                    size_t count)
590
{
40✔
591
    using vecTy = std::vector<DPCTLSyclDeviceRef>;
40✔
592
    vecTy *Devices = nullptr;
40✔
593
    if (DRef) {
40✔
594
        if (count == 0) {
39✔
595
            error_handler("Cannot create sub-devices with zero compute units",
8✔
596
                          __FILE__, __func__, __LINE__);
8✔
597
            return nullptr;
8✔
598
        }
8✔
599
        auto D = unwrap<device>(DRef);
31✔
600
        const auto &supported_properties =
31✔
601
            D->get_info<info::device::partition_properties>();
31✔
602
        const auto &beg_it = supported_properties.begin();
31✔
603
        const auto &end_it = supported_properties.end();
31✔
604
        if (std::find(beg_it, end_it,
31!
605
                      info::partition_property::partition_equally) == end_it)
31✔
606
        {
×
607
            // device does not support partition equally
608
            return nullptr;
×
609
        }
×
610
        try {
31✔
611
            auto subDevices = D->create_sub_devices<
31✔
612
                info::partition_property::partition_equally>(count);
31✔
613
            Devices = new vecTy();
31✔
614
            for (const auto &sd : subDevices) {
62✔
615
                Devices->emplace_back(wrap<device>(new device(sd)));
62✔
616
            }
62✔
617
        } catch (std::exception const &e) {
31✔
618
            delete Devices;
×
619
            error_handler(e, __FILE__, __func__, __LINE__);
×
620
            return nullptr;
×
621
        }
×
622
    }
31✔
623
    return wrap<vecTy>(Devices);
32✔
624
}
40✔
625

626
__dpctl_give DPCTLDeviceVectorRef
627
DPCTLDevice_CreateSubDevicesByCounts(__dpctl_keep const DPCTLSyclDeviceRef DRef,
628
                                     __dpctl_keep size_t *counts,
629
                                     size_t ncounts)
630
{
39✔
631
    using vecTy = std::vector<DPCTLSyclDeviceRef>;
39✔
632
    vecTy *Devices = nullptr;
39✔
633
    std::vector<size_t> vcounts(ncounts);
39✔
634
    vcounts.assign(counts, counts + ncounts);
39✔
635
    size_t min_elem = *std::min_element(vcounts.begin(), vcounts.end());
39✔
636
    if (min_elem == 0) {
39✔
637
        error_handler("Cannot create sub-devices with zero compute units",
8✔
638
                      __FILE__, __func__, __LINE__);
8✔
639
        return nullptr;
8✔
640
    }
8✔
641
    if (DRef) {
31✔
642
        auto D = unwrap<device>(DRef);
30✔
643
        const auto &supported_properties =
30✔
644
            D->get_info<info::device::partition_properties>();
30✔
645
        const auto &beg_it = supported_properties.begin();
30✔
646
        const auto &end_it = supported_properties.end();
30✔
647
        if (std::find(beg_it, end_it,
30!
648
                      info::partition_property::partition_by_counts) == end_it)
30✔
649
        {
×
650
            // device does not support partition by counts
651
            return nullptr;
×
652
        }
×
653
        std::vector<std::remove_pointer<decltype(D)>::type> subDevices;
30✔
654
        try {
30✔
655
            subDevices = D->create_sub_devices<
30✔
656
                info::partition_property::partition_by_counts>(vcounts);
30✔
657
        } catch (std::exception const &e) {
30✔
658
            error_handler(e, __FILE__, __func__, __LINE__);
×
659
            return nullptr;
×
660
        }
×
661
        try {
30✔
662
            Devices = new vecTy();
30✔
663
            for (const auto &sd : subDevices) {
60✔
664
                Devices->emplace_back(wrap<device>(new device(sd)));
60✔
665
            }
60✔
666
        } catch (std::exception const &e) {
30✔
667
            delete Devices;
×
668
            error_handler(e, __FILE__, __func__, __LINE__);
×
669
            return nullptr;
×
670
        }
×
671
    }
30✔
672
    return wrap<vecTy>(Devices);
31✔
673
}
31✔
674

675
__dpctl_give DPCTLDeviceVectorRef DPCTLDevice_CreateSubDevicesByAffinity(
676
    __dpctl_keep const DPCTLSyclDeviceRef DRef,
677
    DPCTLPartitionAffinityDomainType PartitionAffinityDomainTy)
678
{
157✔
679
    using vecTy = std::vector<DPCTLSyclDeviceRef>;
157✔
680
    vecTy *Devices = nullptr;
157✔
681
    auto D = unwrap<device>(DRef);
157✔
682
    if (D) {
157✔
683
        const auto &supported_properties =
156✔
684
            D->get_info<info::device::partition_properties>();
156✔
685
        const auto &beg_it = supported_properties.begin();
156✔
686
        const auto &end_it = supported_properties.end();
156✔
687
        if (std::find(beg_it, end_it,
156!
688
                      info::partition_property::partition_by_affinity_domain) ==
156✔
689
            end_it)
156✔
690
        {
156✔
691
            // device does not support partition by affinity domain
692
            return nullptr;
156✔
693
        }
156✔
694
        try {
×
695
            auto domain = DPCTL_DPCTLPartitionAffinityDomainTypeToSycl(
×
696
                PartitionAffinityDomainTy);
×
697
            const auto &supported_affinity_domains =
×
698
                D->get_info<info::device::partition_affinity_domains>();
×
699
            const auto &beg_it = supported_affinity_domains.begin();
×
700
            const auto &end_it = supported_affinity_domains.end();
×
701
            if (std::find(beg_it, end_it, domain) == end_it) {
×
702
                // device does not support partitioning by this particular
703
                // affinity domain
704
                return nullptr;
×
705
            }
×
706
            auto subDevices = D->create_sub_devices<
×
707
                info::partition_property::partition_by_affinity_domain>(domain);
×
708
            Devices = new vecTy();
×
709
            for (const auto &sd : subDevices) {
×
710
                Devices->emplace_back(wrap<device>(new device(sd)));
×
711
            }
×
712
        } catch (std::exception const &e) {
×
713
            delete Devices;
×
714
            error_handler(e, __FILE__, __func__, __LINE__);
×
715
            return nullptr;
×
716
        }
×
717
    }
×
718
    return wrap<vecTy>(Devices);
1✔
719
}
157✔
720

721
size_t DPCTLDevice_Hash(__dpctl_keep const DPCTLSyclDeviceRef DRef)
722
{
51,765✔
723
    if (DRef) {
51,765✔
724
        auto D = unwrap<device>(DRef);
51,764✔
725
        std::hash<device> hash_fn;
51,764✔
726
        return hash_fn(*D);
51,764✔
727
    }
51,764✔
728
    else {
1✔
729
        error_handler("Argument DRef is null", __FILE__, __func__, __LINE__);
1✔
730
        return 0;
1✔
731
    }
1✔
732
}
51,765✔
733

734
size_t DPCTLDevice_GetProfilingTimerResolution(
735
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
736
{
24✔
737
    if (DRef) {
24✔
738
        auto D = unwrap<device>(DRef);
23✔
739
        return D->get_info<info::device::profiling_timer_resolution>();
23✔
740
    }
23✔
741
    else {
1✔
742
        error_handler("Argument DRef is null", __FILE__, __func__, __LINE__);
1✔
743
        return 0;
1✔
744
    }
1✔
745
}
24✔
746

747
uint32_t DPCTLDevice_GetGlobalMemCacheLineSize(
748
    __dpctl_keep const DPCTLSyclDeviceRef DRef)
749
{
24✔
750
    if (DRef) {
24✔
751
        auto D = unwrap<device>(DRef);
23✔
752
        return D->get_info<info::device::global_mem_cache_line_size>();
23✔
753
    }
23✔
754
    else {
1✔
755
        error_handler("Argument DRef is null", __FILE__, __func__, __LINE__);
1✔
756
        return 0;
1✔
757
    }
1✔
758
}
24✔
759

760
uint32_t
761
DPCTLDevice_GetMaxClockFrequency(__dpctl_keep const DPCTLSyclDeviceRef DRef)
762
{
24✔
763
    if (DRef) {
24✔
764
        auto D = unwrap<device>(DRef);
23✔
765
        return D->get_info<info::device::max_clock_frequency>();
23✔
766
    }
23✔
767
    else {
1✔
768
        error_handler("Argument DRef is null", __FILE__, __func__, __LINE__);
1✔
769
        return 0;
1✔
770
    }
1✔
771
}
24✔
772

773
uint64_t
774
DPCTLDevice_GetMaxMemAllocSize(__dpctl_keep const DPCTLSyclDeviceRef DRef)
775
{
24✔
776
    if (DRef) {
24✔
777
        auto D = unwrap<device>(DRef);
23✔
778
        return D->get_info<info::device::max_mem_alloc_size>();
23✔
779
    }
23✔
780
    else {
1✔
781
        error_handler("Argument DRef is null", __FILE__, __func__, __LINE__);
1✔
782
        return 0;
1✔
783
    }
1✔
784
}
24✔
785

786
uint64_t
787
DPCTLDevice_GetGlobalMemCacheSize(__dpctl_keep const DPCTLSyclDeviceRef DRef)
788
{
24✔
789
    if (DRef) {
24✔
790
        auto D = unwrap<device>(DRef);
23✔
791
        return D->get_info<info::device::global_mem_cache_size>();
23✔
792
    }
23✔
793
    else {
1✔
794
        error_handler("Argument DRef is null", __FILE__, __func__, __LINE__);
1✔
795
        return 0;
1✔
796
    }
1✔
797
}
24✔
798

799
DPCTLGlobalMemCacheType
800
DPCTLDevice_GetGlobalMemCacheType(__dpctl_keep const DPCTLSyclDeviceRef DRef)
801
{
24✔
802
    if (DRef) {
24✔
803
        auto D = unwrap<device>(DRef);
23✔
804
        auto mem_type = D->get_info<info::device::global_mem_cache_type>();
23✔
805
        switch (mem_type) {
23!
806
        case info::global_mem_cache_type::none:
×
807
            return DPCTL_MEM_CACHE_TYPE_NONE;
×
808
        case info::global_mem_cache_type::read_only:
×
809
            return DPCTL_MEM_CACHE_TYPE_READ_ONLY;
×
810
        case info::global_mem_cache_type::read_write:
23!
811
            return DPCTL_MEM_CACHE_TYPE_READ_WRITE;
23✔
812
        }
23✔
813
        // If execution reaches here unrecognized mem_type was returned. Check
814
        // values in the enumeration `info::global_mem_cache_type` in SYCL specs
815
        assert(false);
23!
816
        return DPCTL_MEM_CACHE_TYPE_INDETERMINATE;
×
817
    }
×
818
    else {
1✔
819
        error_handler("Argument DRef is null", __FILE__, __func__, __LINE__);
1✔
820
        return DPCTL_MEM_CACHE_TYPE_INDETERMINATE;
1✔
821
    }
1✔
822
}
24✔
823

824
__dpctl_keep size_t *
825
DPCTLDevice_GetSubGroupSizes(__dpctl_keep const DPCTLSyclDeviceRef DRef,
826
                             size_t *res_len)
827
{
24✔
828
    size_t *sizes = nullptr;
24✔
829
    std::vector<size_t> sg_sizes;
24✔
830
    *res_len = 0;
24✔
831
    auto D = unwrap<device>(DRef);
24✔
832
    if (D) {
24✔
833
        try {
23✔
834
            sg_sizes = D->get_info<info::device::sub_group_sizes>();
23✔
835
            *res_len = sg_sizes.size();
23✔
836
        } catch (std::exception const &e) {
23✔
837
            error_handler(e, __FILE__, __func__, __LINE__);
×
838
        }
×
839
        try {
23✔
840
            sizes = new size_t[sg_sizes.size()];
23✔
841
        } catch (std::exception const &e) {
23✔
842
            error_handler(e, __FILE__, __func__, __LINE__);
×
843
        }
×
844
        for (auto i = 0ul; (sizes != nullptr) && i < sg_sizes.size(); ++i) {
138!
845
            sizes[i] = sg_sizes[i];
115✔
846
        }
115✔
847
    }
23✔
848
    return sizes;
24✔
849
}
24✔
850

851
__dpctl_give DPCTLDeviceVectorRef
852
DPCTLDevice_GetComponentDevices(__dpctl_keep const DPCTLSyclDeviceRef DRef)
853
{
1✔
854
    using vecTy = std::vector<DPCTLSyclDeviceRef>;
1✔
855
    vecTy *ComponentDevicesVectorPtr = nullptr;
1✔
856
    if (DRef) {
1!
857
        auto D = unwrap<device>(DRef);
×
858
        try {
×
859
            auto componentDevices =
×
860
                D->get_info<sycl::ext::oneapi::experimental::info::device::
×
861
                                component_devices>();
×
862
            ComponentDevicesVectorPtr = new vecTy();
×
863
            ComponentDevicesVectorPtr->reserve(componentDevices.size());
×
864
            for (const auto &cd : componentDevices) {
×
865
                ComponentDevicesVectorPtr->emplace_back(
×
866
                    wrap<device>(new device(cd)));
×
867
            }
×
868
        } catch (std::exception const &e) {
×
869
            delete ComponentDevicesVectorPtr;
×
870
            error_handler(e, __FILE__, __func__, __LINE__);
×
871
            return nullptr;
×
872
        }
×
873
    }
×
874
    return wrap<vecTy>(ComponentDevicesVectorPtr);
1✔
875
}
1✔
876

877
__dpctl_give DPCTLSyclDeviceRef
878
DPCTLDevice_GetCompositeDevice(__dpctl_keep const DPCTLSyclDeviceRef DRef)
879
{
9✔
880
    auto D = unwrap<device>(DRef);
9✔
881
    if (D) {
9✔
882
        bool is_component = false;
8✔
883
        try {
8✔
884
            is_component = D->has(sycl::aspect::ext_oneapi_is_component);
8✔
885
        } catch (std::exception const &e) {
8✔
886
            error_handler(e, __FILE__, __func__, __LINE__);
×
887
            return nullptr;
×
888
        }
×
889
        if (!is_component)
8!
890
            return nullptr;
8✔
891
        try {
×
892
            const auto &compositeDevice =
×
893
                D->get_info<sycl::ext::oneapi::experimental::info::device::
×
894
                                composite_device>();
×
895
            return wrap<device>(new device(compositeDevice));
×
896
        } catch (std::exception const &e) {
×
897
            error_handler(e, __FILE__, __func__, __LINE__);
×
898
            return nullptr;
×
899
        }
×
900
    }
×
901
    else
1✔
902
        return nullptr;
1✔
903
}
9✔
904

905
static inline bool _CallPeerAccess(device dev, device peer)
906
{
×
907
    auto BE1 = dev.get_backend();
×
908
    auto BE2 = peer.get_backend();
×
909

910
    if ((BE1 == BE2) &&
×
911
        (BE1 == sycl::backend::ext_oneapi_level_zero ||
×
912
         BE1 == sycl::backend::ext_oneapi_cuda ||
×
913
         BE1 == sycl::backend::ext_oneapi_hip) &&
×
914
        (BE2 == sycl::backend::ext_oneapi_level_zero ||
×
915
         BE2 == sycl::backend::ext_oneapi_cuda ||
×
916
         BE2 == sycl::backend::ext_oneapi_hip) &&
×
917
        (dev != peer))
×
918
    {
×
919
        return true;
×
920
    }
×
921
    return false;
×
922
}
×
923

924
bool DPCTLDevice_CanAccessPeer(__dpctl_keep const DPCTLSyclDeviceRef DRef,
925
                               __dpctl_keep const DPCTLSyclDeviceRef PDRef,
926
                               DPCTLPeerAccessType PT)
927
{
2✔
928
    bool canAccess = false;
2✔
929
    auto D = unwrap<device>(DRef);
2✔
930
    auto PD = unwrap<device>(PDRef);
2✔
931
    if (D && PD) {
2!
932
        if (_CallPeerAccess(*D, *PD)) {
×
933
            try {
×
934
                canAccess = D->ext_oneapi_can_access_peer(
×
935
                    *PD, DPCTL_DPCTLPeerAccessTypeToSycl(PT));
×
936
            } catch (std::exception const &e) {
×
937
                error_handler(e, __FILE__, __func__, __LINE__);
×
938
            }
×
939
        }
×
940
    }
×
941
    return canAccess;
2✔
942
}
2✔
943

944
void DPCTLDevice_EnablePeerAccess(__dpctl_keep const DPCTLSyclDeviceRef DRef,
945
                                  __dpctl_keep const DPCTLSyclDeviceRef PDRef)
946
{
1✔
947
    auto D = unwrap<device>(DRef);
1✔
948
    auto PD = unwrap<device>(PDRef);
1✔
949
    if (D && PD) {
1!
950
        if (_CallPeerAccess(*D, *PD)) {
×
951
            try {
×
952
                D->ext_oneapi_enable_peer_access(*PD);
×
953
            } catch (std::exception const &e) {
×
954
                error_handler(e, __FILE__, __func__, __LINE__);
×
955
            }
×
956
        }
×
957
        else {
×
958
            error_handler("Devices do not support peer access", __FILE__,
×
959
                          __func__, __LINE__);
×
960
        }
×
961
    }
×
962
    return;
1✔
963
}
1✔
964

965
void DPCTLDevice_DisablePeerAccess(__dpctl_keep const DPCTLSyclDeviceRef DRef,
966
                                   __dpctl_keep const DPCTLSyclDeviceRef PDRef)
967
{
1✔
968
    auto D = unwrap<device>(DRef);
1✔
969
    auto PD = unwrap<device>(PDRef);
1✔
970
    if (D && PD) {
1!
971
        if (_CallPeerAccess(*D, *PD)) {
×
972
            try {
×
973
                D->ext_oneapi_disable_peer_access(*PD);
×
974
            } catch (std::exception const &e) {
×
975
                error_handler(e, __FILE__, __func__, __LINE__);
×
976
            }
×
977
        }
×
978
        else {
×
979
            error_handler("Devices do not support peer access", __FILE__,
×
980
                          __func__, __LINE__);
×
981
        }
×
982
    }
×
983
    return;
1✔
984
}
1✔
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