Skip to content

Commit 6827fa0

Browse files
committed
apply review comments
1 parent bbb322a commit 6827fa0

5 files changed

Lines changed: 106 additions & 32 deletions

File tree

‎dpctl/program/__init__.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
2222
"""
2323

24+
from . import utils
2425
from ._program import (
2526
SpecializationConstant,
2627
SyclKernel,

‎dpctl/program/_program.pyx‎

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ from cpython.buffer cimport (
3636
PyObject_GetBuffer,
3737
)
3838
from cpython.bytes cimport PyBytes_FromStringAndSize
39-
from libc.stdint cimport uint32_t
39+
from libc.stdint cimport UINT32_MAX, uint32_t
4040
from libc.stdlib cimport free, malloc
4141
from libc.string cimport memcmp, memcpy
4242

@@ -337,13 +337,23 @@ cdef class SpecializationConstant:
337337
f"{len(args) + 1}."
338338
)
339339

340+
if spec_id < 0 or spec_id > UINT32_MAX:
341+
raise ValueError(
342+
"Specialization constant ID must fit in a 32-bit unsigned "
343+
f"integer (0 <= id <= {UINT32_MAX}), got {spec_id}"
344+
)
340345
self._spec_const.id = <uint32_t>spec_id
341346

342347
if len(args) == 2:
343348
if (
344349
isinstance(args[0], numbers.Integral) and
345350
isinstance(args[1], numbers.Integral)
346351
):
352+
if args[0] <= 0:
353+
raise ValueError(
354+
"Size must be a positive integer when constructing "
355+
f"from a pointer and size, got {args[0]}"
356+
)
347357
target_obj = PyBytes_FromStringAndSize(
348358
<const char *><size_t>args[1], <Py_ssize_t>args[0]
349359
)
@@ -380,6 +390,12 @@ cdef class SpecializationConstant:
380390
"Failed to get buffer view for the provided object."
381391
)
382392

393+
if _local_buffer.len <= 0:
394+
PyBuffer_Release(&(_local_buffer))
395+
raise ValueError(
396+
"Specialization constant value must not be zero-sized."
397+
)
398+
383399
self._spec_const.size = <size_t>_local_buffer.len
384400
copied_data = malloc(self._spec_const.size)
385401

@@ -403,7 +419,7 @@ cdef class SpecializationConstant:
403419

404420
def __eq__(self, other):
405421
if not isinstance(other, SpecializationConstant):
406-
return False
422+
return NotImplemented
407423
cdef SpecializationConstant _other = <SpecializationConstant>other
408424
if (
409425
self._spec_const.id != _other._spec_const.id or
@@ -418,6 +434,16 @@ cdef class SpecializationConstant:
418434
self._spec_const.size
419435
) == 0
420436

437+
def __hash__(self):
438+
cdef bytes value_bytes
439+
if self._spec_const.value != NULL:
440+
value_bytes = (<char *>self._spec_const.value)[
441+
:self._spec_const.size
442+
]
443+
else:
444+
value_bytes = b""
445+
return hash((self._spec_const.id, value_bytes))
446+
421447
@property
422448
def id(self):
423449
"""Returns the specialization ID for this specialization constant."""
@@ -551,13 +577,14 @@ cpdef create_kernel_bundle_from_spirv(
551577
raise MemoryError(
552578
"Failed to allocate memory for specialization constants."
553579
)
554-
for i, spconst in enumerate(specializations):
555-
if not isinstance(spconst, SpecializationConstant):
580+
for i, _spconst in enumerate(specializations):
581+
if not isinstance(_spconst, SpecializationConstant):
556582
free(spconsts)
557583
raise TypeError(
558584
"All items in specializations must be of type "
559-
f"`SpecializationConstant`, got {type(spconst)}"
585+
f"`SpecializationConstant`, got {type(_spconst)}"
560586
)
587+
spconst = <SpecializationConstant>_spconst
561588
spconsts[i] = spconst._spec_const
562589
else:
563590
num_spconsts = 0

‎dpctl/program/utils/_utils.py‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,13 @@ def parse_spirv_specializations(
117117
# parsing, so we can stop parsing at this point
118118
break
119119
elif opcode == SpirvOpCode.OpTypeBool:
120+
if word_count < 2:
121+
raise ValueError(f"Truncated OpTypeBool at word index {i}")
120122
result_id = int(words[i + 1])
121123
types[result_id] = {"dtype": "?", "itemsize": 1}
122124
elif opcode == SpirvOpCode.OpTypeInt:
125+
if word_count < 4:
126+
raise ValueError(f"Truncated OpTypeInt at word index {i}")
123127
result_id = int(words[i + 1])
124128
width = int(words[i + 2])
125129
signed = int(words[i + 3])
@@ -129,37 +133,62 @@ def parse_spirv_specializations(
129133
"itemsize": width // 8,
130134
}
131135
elif opcode == SpirvOpCode.OpTypeFloat:
136+
if word_count < 3:
137+
raise ValueError(f"Truncated OpTypeFloat at word index {i}")
132138
result_id = int(words[i + 1])
133139
width = int(words[i + 2])
134140
types[result_id] = {
135141
"dtype": f"f{width // 8}",
136142
"itemsize": width // 8,
137143
}
138144
elif opcode == SpirvOpCode.OpSpecConstant:
145+
if word_count < 3:
146+
raise ValueError(f"Truncated OpSpecConstant at word index {i}")
139147
type_id = int(words[i + 1])
140148
result_id = int(words[i + 2])
141149
constants[result_id] = type_id
142150
literal_words = words[i + 3 : i + word_count]
143151
defaults[result_id] = literal_words.tobytes()
144152
elif opcode == SpirvOpCode.OpSpecConstantTrue:
153+
if word_count < 3:
154+
raise ValueError(
155+
f"Truncated OpSpecConstantTrue at word index {i}"
156+
)
145157
type_id = int(words[i + 1])
146158
result_id = int(words[i + 2])
147159
constants[result_id] = type_id
148160
defaults[result_id] = True
149161
elif opcode == SpirvOpCode.OpSpecConstantFalse:
162+
if word_count < 3:
163+
raise ValueError(
164+
f"Truncated OpSpecConstantFalse at word index {i}"
165+
)
150166
type_id = int(words[i + 1])
151167
result_id = int(words[i + 2])
152168
constants[result_id] = type_id
153169
defaults[result_id] = False
154170
elif opcode == SpirvOpCode.OpDecorate:
171+
if word_count < 3:
172+
raise ValueError(f"Truncated OpDecorate at word index {i}")
155173
target_id = int(words[i + 1])
156174
decoration = int(words[i + 2])
157175
if decoration == SpirvDecoration.SpecId:
176+
if word_count < 4:
177+
raise ValueError(
178+
f"Truncated OpDecorate SpecId at word index {i}"
179+
)
158180
ids[target_id] = int(words[i + 3])
159181
elif opcode == SpirvOpCode.OpName:
182+
if word_count < 2:
183+
raise ValueError(f"Truncated OpName at word index {i}")
160184
target_id = int(words[i + 1])
161185
name_bytes = words[i + 2 : i + word_count].tobytes()
162-
names[target_id] = name_bytes.split(b"\x00", 1)[0].decode("utf-8")
186+
try:
187+
names[target_id] = name_bytes.split(b"\x00", 1)[0].decode(
188+
"utf-8"
189+
)
190+
except UnicodeDecodeError:
191+
raise ValueError(f"Invalid UTF-8 in OpName at word index {i}")
163192

164193
i += word_count
165194

‎libsyclinterface/include/syclinterface/dpctl_sycl_kernel_bundle_interface.h‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,14 @@ typedef struct DPCTLSpecConstTy
6565
* @ingroup KernelBundleInterface
6666
*/
6767
DPCTL_API
68-
__dpctl_give DPCTLSyclKernelBundleRef
69-
DPCTLKernelBundle_CreateFromSpirv(__dpctl_keep const DPCTLSyclContextRef Ctx,
70-
__dpctl_keep const DPCTLSyclDeviceRef Dev,
71-
__dpctl_keep const void *IL,
72-
size_t Length,
73-
const char *CompileOpts,
74-
size_t NumSpecConsts,
75-
const DPCTLSpecConst *SpecConsts);
68+
__dpctl_give DPCTLSyclKernelBundleRef DPCTLKernelBundle_CreateFromSpirv(
69+
__dpctl_keep const DPCTLSyclContextRef Ctx,
70+
__dpctl_keep const DPCTLSyclDeviceRef Dev,
71+
__dpctl_keep const void *IL,
72+
size_t Length,
73+
const char *CompileOpts,
74+
size_t NumSpecConsts,
75+
__dpctl_keep const DPCTLSpecConst *SpecConsts);
7676

7777
/*!
7878
* @brief Create a Sycl kernel bundle from an OpenCL kernel source string.

‎libsyclinterface/source/dpctl_sycl_kernel_bundle_interface.cpp‎

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ _CreateKernelBundleWithIL_ocl_impl(const context &ctx,
293293
return nullptr;
294294
}
295295

296+
if (NumSpecConsts > 0 && SpecConsts == nullptr) {
297+
error_handler("NumSpecConsts > 0 but SpecConsts is NULL.", __FILE__,
298+
__func__, __LINE__);
299+
return nullptr;
300+
}
301+
296302
if (SpecConsts != nullptr && NumSpecConsts > 0) {
297303
auto clSetProgramSpecConstF = get_clSetProgramSpecializationConstant();
298304
if (clSetProgramSpecConstF) {
@@ -520,6 +526,12 @@ _CreateKernelBundleWithIL_ze_impl(const context &SyclCtx,
520526
backend_traits<ze_be>::return_type<device> ZeDevice;
521527
ZeDevice = get_native<ze_be>(SyclDev);
522528

529+
if (NumSpecConsts > 0 && SpecConsts == nullptr) {
530+
error_handler("NumSpecConsts > 0 but SpecConsts is NULL.", __FILE__,
531+
__func__, __LINE__);
532+
return nullptr;
533+
}
534+
523535
std::vector<std::uint32_t> spec_ids;
524536
std::vector<const void *> spec_values;
525537

@@ -532,7 +544,7 @@ _CreateKernelBundleWithIL_ze_impl(const context &SyclCtx,
532544
}
533545
}
534546
ze_module_constants_t ZeSpecConstants = {};
535-
ZeSpecConstants.numConstants = static_cast<std::uint32_t>(NumSpecConsts);
547+
ZeSpecConstants.numConstants = static_cast<std::uint32_t>(spec_ids.size());
536548
ZeSpecConstants.pConstantIds = spec_ids.empty() ? nullptr : spec_ids.data();
537549
ZeSpecConstants.pConstantValues =
538550
spec_values.empty() ? nullptr : spec_values.data();
@@ -699,25 +711,30 @@ DPCTLKernelBundle_CreateFromSpirv(__dpctl_keep const DPCTLSyclContextRef CtxRef,
699711
context *SyclCtx = unwrap<context>(CtxRef);
700712
device *SyclDev = unwrap<device>(DevRef);
701713
// get the backend type
702-
auto BE = SyclCtx->get_platform().get_backend();
703-
switch (BE) {
704-
case backend::opencl:
705-
KBRef = _CreateKernelBundleWithIL_ocl_impl(*SyclCtx, *SyclDev, IL,
706-
length, CompileOpts,
707-
NumSpecConsts, SpecConsts);
708-
break;
709-
case backend::ext_oneapi_level_zero:
714+
try {
715+
auto BE = SyclCtx->get_platform().get_backend();
716+
switch (BE) {
717+
case backend::opencl:
718+
KBRef = _CreateKernelBundleWithIL_ocl_impl(
719+
*SyclCtx, *SyclDev, IL, length, CompileOpts, NumSpecConsts,
720+
SpecConsts);
721+
break;
722+
case backend::ext_oneapi_level_zero:
710723
#ifdef DPCTL_ENABLE_L0_PROGRAM_CREATION
711-
KBRef = _CreateKernelBundleWithIL_ze_impl(*SyclCtx, *SyclDev, IL,
712-
length, CompileOpts,
713-
NumSpecConsts, SpecConsts);
714-
break;
724+
KBRef = _CreateKernelBundleWithIL_ze_impl(
725+
*SyclCtx, *SyclDev, IL, length, CompileOpts, NumSpecConsts,
726+
SpecConsts);
727+
break;
715728
#endif
716-
default:
717-
std::ostringstream os;
718-
os << "Backend " << BE << " is not supported";
719-
error_handler(os.str(), __FILE__, __func__, __LINE__);
720-
break;
729+
default:
730+
std::ostringstream os;
731+
os << "Backend " << BE << " is not supported";
732+
error_handler(os.str(), __FILE__, __func__, __LINE__);
733+
break;
734+
}
735+
} catch (std::exception const &e) {
736+
error_handler(e, __FILE__, __func__, __LINE__);
737+
return nullptr;
721738
}
722739
return KBRef;
723740
}

0 commit comments

Comments
 (0)