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

IntelPython / dpctl / 14929317467

09 May 2025 12:49PM UTC coverage: 85.335% (-1.0%) from 86.372%
14929317467

Pull #2049

github

web-flow
Merge 153ec69eb into 3aff6ca34
Pull Request #2049: Support compilation from SYCL source code

2965 of 3732 branches covered (79.45%)

Branch coverage included in aggregate %.

122 of 199 new or added lines in 4 files covered. (61.31%)

94 existing lines in 17 files now uncovered.

12298 of 14154 relevant lines covered (86.89%)

6867.74 hits per line

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

79.79
/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 <cstring>
37
#include <stddef.h>
38
#include <sycl/sycl.hpp> /* SYCL headers   */
39
#include <utility>
40
#include <vector>
41

42
using namespace sycl;
43

44
namespace
45
{
46

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

50
using namespace dpctl::syclinterface;
51

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

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

83
} /* end of anonymous namespace */
84

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

429
namespace
430
{
431

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

447
} // end of anonymous namespace
448

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

907
bool DPCTLDevice_CanCompileSPIRV(__dpctl_keep const DPCTLSyclDeviceRef DRef)
NEW
908
{
×
NEW
909
    auto Dev = unwrap<device>(DRef);
×
NEW
910
    auto Backend = Dev->get_platform().get_backend();
×
NEW
911
    return Backend == backend::opencl ||
×
NEW
912
           Backend == backend::ext_oneapi_level_zero;
×
NEW
913
}
×
914

915
bool DPCTLDevice_CanCompileOpenCL(__dpctl_keep const DPCTLSyclDeviceRef DRef)
NEW
916
{
×
NEW
917
    auto Dev = unwrap<device>(DRef);
×
NEW
918
    return Dev->get_platform().get_backend() == backend::opencl;
×
NEW
919
}
×
920

921
bool DPCTLDevice_CanCompileSYCL(__dpctl_keep const DPCTLSyclDeviceRef DRef)
922
{
2✔
923
#ifdef SYCL_EXT_ONEAPI_KERNEL_COMPILER
2✔
924
    auto Dev = unwrap<device>(DRef);
2✔
925
    return Dev->ext_oneapi_can_compile(
2✔
926
        ext::oneapi::experimental::source_language::sycl);
2✔
927
#else
928
    return false;
929
#endif
930
}
2✔
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