@@ -25,6 +25,77 @@ cl_map_flags convertURMapFlagsToCL(ur_map_flags_t URFlags) {
25
25
return CLFlags;
26
26
}
27
27
28
+ ur_result_t ValidateBufferSize (ur_mem_handle_t Buffer, size_t Size,
29
+ size_t Origin) {
30
+ size_t BufferSize = 0 ;
31
+ CL_RETURN_ON_FAILURE (clGetMemObjectInfo (cl_adapter::cast<cl_mem>(Buffer),
32
+ CL_MEM_SIZE, sizeof (BufferSize),
33
+ &BufferSize, nullptr ));
34
+ if (Size + Origin > BufferSize)
35
+ return UR_RESULT_ERROR_INVALID_SIZE;
36
+ return UR_RESULT_SUCCESS;
37
+ }
38
+
39
+ ur_result_t ValidateBufferRectSize (ur_mem_handle_t Buffer,
40
+ ur_rect_region_t Region,
41
+ ur_rect_offset_t Offset) {
42
+ size_t BufferSize = 0 ;
43
+ CL_RETURN_ON_FAILURE (clGetMemObjectInfo (cl_adapter::cast<cl_mem>(Buffer),
44
+ CL_MEM_SIZE, sizeof (BufferSize),
45
+ &BufferSize, nullptr ));
46
+ if (Offset.x >= BufferSize || Offset.y >= BufferSize ||
47
+ Offset.z >= BufferSize) {
48
+ return UR_RESULT_ERROR_INVALID_SIZE;
49
+ }
50
+
51
+ if ((Region.width + Offset.x ) * (Region.height + Offset.y ) *
52
+ (Region.depth + Offset.z ) >
53
+ BufferSize) {
54
+ return UR_RESULT_ERROR_INVALID_SIZE;
55
+ }
56
+
57
+ return UR_RESULT_SUCCESS;
58
+ }
59
+
60
+ ur_result_t ValidateImageSize (ur_mem_handle_t Image, ur_rect_region_t Region,
61
+ ur_rect_offset_t Origin) {
62
+ size_t Width = 0 ;
63
+ CL_RETURN_ON_FAILURE (clGetImageInfo (cl_adapter::cast<cl_mem>(Image),
64
+ CL_IMAGE_WIDTH, sizeof (Width), &Width,
65
+ nullptr ));
66
+ if (Region.width + Origin.x > Width) {
67
+ return UR_RESULT_ERROR_INVALID_SIZE;
68
+ }
69
+
70
+ size_t Height = 0 ;
71
+ CL_RETURN_ON_FAILURE (clGetImageInfo (cl_adapter::cast<cl_mem>(Image),
72
+ CL_IMAGE_HEIGHT, sizeof (Height), &Height,
73
+ nullptr ));
74
+
75
+ // CL returns a height and depth of 0 for images that don't have those
76
+ // dimensions, but regions for enqueue operations must set these to 1, so we
77
+ // need to make this adjustment to validate.
78
+ if (Height == 0 )
79
+ Height = 1 ;
80
+
81
+ if (Region.height + Origin.y > Height) {
82
+ return UR_RESULT_ERROR_INVALID_SIZE;
83
+ }
84
+
85
+ size_t Depth = 0 ;
86
+ CL_RETURN_ON_FAILURE (clGetImageInfo (cl_adapter::cast<cl_mem>(Image),
87
+ CL_IMAGE_DEPTH, sizeof (Depth), &Depth,
88
+ nullptr ));
89
+ if (Depth == 0 )
90
+ Depth = 1 ;
91
+
92
+ if (Region.depth + Origin.z > Depth) {
93
+ return UR_RESULT_ERROR_INVALID_SIZE;
94
+ }
95
+
96
+ return UR_RESULT_SUCCESS;
97
+ }
98
+
28
99
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueKernelLaunch (
29
100
ur_queue_handle_t hQueue, ur_kernel_handle_t hKernel, uint32_t workDim,
30
101
const size_t *pGlobalWorkOffset, const size_t *pGlobalWorkSize,
@@ -70,27 +141,33 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferRead(
70
141
size_t offset, size_t size, void *pDst, uint32_t numEventsInWaitList,
71
142
const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) {
72
143
73
- CL_RETURN_ON_FAILURE ( clEnqueueReadBuffer (
144
+ auto ClErr = clEnqueueReadBuffer (
74
145
cl_adapter::cast<cl_command_queue>(hQueue),
75
146
cl_adapter::cast<cl_mem>(hBuffer), blockingRead, offset, size, pDst,
76
147
numEventsInWaitList, cl_adapter::cast<const cl_event *>(phEventWaitList),
77
- cl_adapter::cast<cl_event *>(phEvent))) ;
148
+ cl_adapter::cast<cl_event *>(phEvent));
78
149
79
- return UR_RESULT_SUCCESS;
150
+ if (ClErr == CL_INVALID_VALUE) {
151
+ UR_RETURN_ON_FAILURE (ValidateBufferSize (hBuffer, size, offset));
152
+ }
153
+ return mapCLErrorToUR (ClErr);
80
154
}
81
155
82
156
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWrite (
83
157
ur_queue_handle_t hQueue, ur_mem_handle_t hBuffer, bool blockingWrite,
84
158
size_t offset, size_t size, const void *pSrc, uint32_t numEventsInWaitList,
85
159
const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) {
86
160
87
- CL_RETURN_ON_FAILURE ( clEnqueueWriteBuffer (
161
+ auto ClErr = clEnqueueWriteBuffer (
88
162
cl_adapter::cast<cl_command_queue>(hQueue),
89
163
cl_adapter::cast<cl_mem>(hBuffer), blockingWrite, offset, size, pSrc,
90
164
numEventsInWaitList, cl_adapter::cast<const cl_event *>(phEventWaitList),
91
- cl_adapter::cast<cl_event *>(phEvent))) ;
165
+ cl_adapter::cast<cl_event *>(phEvent));
92
166
93
- return UR_RESULT_SUCCESS;
167
+ if (ClErr == CL_INVALID_VALUE) {
168
+ UR_RETURN_ON_FAILURE (ValidateBufferSize (hBuffer, size, offset));
169
+ }
170
+ return mapCLErrorToUR (ClErr);
94
171
}
95
172
96
173
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferReadRect (
@@ -101,17 +178,20 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferReadRect(
101
178
uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList,
102
179
ur_event_handle_t *phEvent) {
103
180
104
- CL_RETURN_ON_FAILURE ( clEnqueueReadBufferRect (
181
+ auto ClErr = clEnqueueReadBufferRect (
105
182
cl_adapter::cast<cl_command_queue>(hQueue),
106
183
cl_adapter::cast<cl_mem>(hBuffer), blockingRead,
107
184
cl_adapter::cast<const size_t *>(&bufferOrigin),
108
185
cl_adapter::cast<const size_t *>(&hostOrigin),
109
186
cl_adapter::cast<const size_t *>(®ion), bufferRowPitch,
110
187
bufferSlicePitch, hostRowPitch, hostSlicePitch, pDst, numEventsInWaitList,
111
188
cl_adapter::cast<const cl_event *>(phEventWaitList),
112
- cl_adapter::cast<cl_event *>(phEvent))) ;
189
+ cl_adapter::cast<cl_event *>(phEvent));
113
190
114
- return UR_RESULT_SUCCESS;
191
+ if (ClErr == CL_INVALID_VALUE) {
192
+ UR_RETURN_ON_FAILURE (ValidateBufferRectSize (hBuffer, region, bufferOrigin));
193
+ }
194
+ return mapCLErrorToUR (ClErr);
115
195
}
116
196
117
197
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWriteRect (
@@ -122,17 +202,20 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWriteRect(
122
202
uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList,
123
203
ur_event_handle_t *phEvent) {
124
204
125
- CL_RETURN_ON_FAILURE ( clEnqueueWriteBufferRect (
205
+ auto ClErr = clEnqueueWriteBufferRect (
126
206
cl_adapter::cast<cl_command_queue>(hQueue),
127
207
cl_adapter::cast<cl_mem>(hBuffer), blockingWrite,
128
208
cl_adapter::cast<const size_t *>(&bufferOrigin),
129
209
cl_adapter::cast<const size_t *>(&hostOrigin),
130
210
cl_adapter::cast<const size_t *>(®ion), bufferRowPitch,
131
211
bufferSlicePitch, hostRowPitch, hostSlicePitch, pSrc, numEventsInWaitList,
132
212
cl_adapter::cast<const cl_event *>(phEventWaitList),
133
- cl_adapter::cast<cl_event *>(phEvent))) ;
213
+ cl_adapter::cast<cl_event *>(phEvent));
134
214
135
- return UR_RESULT_SUCCESS;
215
+ if (ClErr == CL_INVALID_VALUE) {
216
+ UR_RETURN_ON_FAILURE (ValidateBufferRectSize (hBuffer, region, bufferOrigin));
217
+ }
218
+ return mapCLErrorToUR (ClErr);
136
219
}
137
220
138
221
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopy (
@@ -141,14 +224,18 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopy(
141
224
uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList,
142
225
ur_event_handle_t *phEvent) {
143
226
144
- CL_RETURN_ON_FAILURE ( clEnqueueCopyBuffer (
227
+ auto ClErr = clEnqueueCopyBuffer (
145
228
cl_adapter::cast<cl_command_queue>(hQueue),
146
229
cl_adapter::cast<cl_mem>(hBufferSrc),
147
230
cl_adapter::cast<cl_mem>(hBufferDst), srcOffset, dstOffset, size,
148
231
numEventsInWaitList, cl_adapter::cast<const cl_event *>(phEventWaitList),
149
- cl_adapter::cast<cl_event *>(phEvent))) ;
232
+ cl_adapter::cast<cl_event *>(phEvent));
150
233
151
- return UR_RESULT_SUCCESS;
234
+ if (ClErr == CL_INVALID_VALUE) {
235
+ UR_RETURN_ON_FAILURE (ValidateBufferSize (hBufferSrc, size, srcOffset));
236
+ UR_RETURN_ON_FAILURE (ValidateBufferSize (hBufferDst, size, dstOffset));
237
+ }
238
+ return mapCLErrorToUR (ClErr);
152
239
}
153
240
154
241
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect (
@@ -159,7 +246,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect(
159
246
uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList,
160
247
ur_event_handle_t *phEvent) {
161
248
162
- CL_RETURN_ON_FAILURE ( clEnqueueCopyBufferRect (
249
+ auto ClErr = clEnqueueCopyBufferRect (
163
250
cl_adapter::cast<cl_command_queue>(hQueue),
164
251
cl_adapter::cast<cl_mem>(hBufferSrc),
165
252
cl_adapter::cast<cl_mem>(hBufferDst),
@@ -168,9 +255,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect(
168
255
cl_adapter::cast<const size_t *>(®ion), srcRowPitch, srcSlicePitch,
169
256
dstRowPitch, dstSlicePitch, numEventsInWaitList,
170
257
cl_adapter::cast<const cl_event *>(phEventWaitList),
171
- cl_adapter::cast<cl_event *>(phEvent))) ;
258
+ cl_adapter::cast<cl_event *>(phEvent));
172
259
173
- return UR_RESULT_SUCCESS;
260
+ if (ClErr == CL_INVALID_VALUE) {
261
+ UR_RETURN_ON_FAILURE (ValidateBufferRectSize (hBufferSrc, region, srcOrigin));
262
+ UR_RETURN_ON_FAILURE (ValidateBufferRectSize (hBufferDst, region, dstOrigin));
263
+ }
264
+ return mapCLErrorToUR (ClErr);
174
265
}
175
266
176
267
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill (
@@ -181,13 +272,16 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill(
181
272
// CL FillBuffer only allows pattern sizes up to the largest CL type:
182
273
// long16/double16
183
274
if (patternSize <= 128 ) {
184
- CL_RETURN_ON_FAILURE (
185
- clEnqueueFillBuffer (cl_adapter::cast<cl_command_queue>(hQueue),
186
- cl_adapter::cast<cl_mem>(hBuffer), pPattern,
187
- patternSize, offset, size, numEventsInWaitList,
188
- cl_adapter::cast<const cl_event *>(phEventWaitList),
189
- cl_adapter::cast<cl_event *>(phEvent)));
190
- return UR_RESULT_SUCCESS;
275
+ auto ClErr = (clEnqueueFillBuffer (
276
+ cl_adapter::cast<cl_command_queue>(hQueue),
277
+ cl_adapter::cast<cl_mem>(hBuffer), pPattern, patternSize, offset, size,
278
+ numEventsInWaitList,
279
+ cl_adapter::cast<const cl_event *>(phEventWaitList),
280
+ cl_adapter::cast<cl_event *>(phEvent)));
281
+ if (ClErr != CL_SUCCESS) {
282
+ UR_RETURN_ON_FAILURE (ValidateBufferSize (hBuffer, size, offset));
283
+ }
284
+ return mapCLErrorToUR (ClErr);
191
285
}
192
286
193
287
auto NumValues = size / sizeof (uint64_t );
@@ -205,6 +299,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill(
205
299
&WriteEvent);
206
300
if (ClErr != CL_SUCCESS) {
207
301
delete[] HostBuffer;
302
+ UR_RETURN_ON_FAILURE (ValidateBufferSize (hBuffer, offset, size));
208
303
CL_RETURN_ON_FAILURE (ClErr);
209
304
}
210
305
@@ -237,15 +332,18 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageRead(
237
332
size_t slicePitch, void *pDst, uint32_t numEventsInWaitList,
238
333
const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) {
239
334
240
- CL_RETURN_ON_FAILURE ( clEnqueueReadImage (
335
+ auto ClErr = clEnqueueReadImage (
241
336
cl_adapter::cast<cl_command_queue>(hQueue),
242
337
cl_adapter::cast<cl_mem>(hImage), blockingRead,
243
338
cl_adapter::cast<const size_t *>(&origin),
244
339
cl_adapter::cast<const size_t *>(®ion), rowPitch, slicePitch, pDst,
245
340
numEventsInWaitList, cl_adapter::cast<const cl_event *>(phEventWaitList),
246
- cl_adapter::cast<cl_event *>(phEvent))) ;
341
+ cl_adapter::cast<cl_event *>(phEvent));
247
342
248
- return UR_RESULT_SUCCESS;
343
+ if (ClErr == CL_INVALID_VALUE) {
344
+ UR_RETURN_ON_FAILURE (ValidateImageSize (hImage, region, origin));
345
+ }
346
+ return mapCLErrorToUR (ClErr);
249
347
}
250
348
251
349
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageWrite (
@@ -254,15 +352,18 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageWrite(
254
352
size_t slicePitch, void *pSrc, uint32_t numEventsInWaitList,
255
353
const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) {
256
354
257
- CL_RETURN_ON_FAILURE ( clEnqueueWriteImage (
355
+ auto ClErr = clEnqueueWriteImage (
258
356
cl_adapter::cast<cl_command_queue>(hQueue),
259
357
cl_adapter::cast<cl_mem>(hImage), blockingWrite,
260
358
cl_adapter::cast<const size_t *>(&origin),
261
359
cl_adapter::cast<const size_t *>(®ion), rowPitch, slicePitch, pSrc,
262
360
numEventsInWaitList, cl_adapter::cast<const cl_event *>(phEventWaitList),
263
- cl_adapter::cast<cl_event *>(phEvent))) ;
361
+ cl_adapter::cast<cl_event *>(phEvent));
264
362
265
- return UR_RESULT_SUCCESS;
363
+ if (ClErr == CL_INVALID_VALUE) {
364
+ UR_RETURN_ON_FAILURE (ValidateImageSize (hImage, region, origin));
365
+ }
366
+ return mapCLErrorToUR (ClErr);
266
367
}
267
368
268
369
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageCopy (
@@ -272,16 +373,20 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageCopy(
272
373
uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList,
273
374
ur_event_handle_t *phEvent) {
274
375
275
- CL_RETURN_ON_FAILURE ( clEnqueueCopyImage (
376
+ auto ClErr = clEnqueueCopyImage (
276
377
cl_adapter::cast<cl_command_queue>(hQueue),
277
378
cl_adapter::cast<cl_mem>(hImageSrc), cl_adapter::cast<cl_mem>(hImageDst),
278
379
cl_adapter::cast<const size_t *>(&srcOrigin),
279
380
cl_adapter::cast<const size_t *>(&dstOrigin),
280
381
cl_adapter::cast<const size_t *>(®ion), numEventsInWaitList,
281
382
cl_adapter::cast<const cl_event *>(phEventWaitList),
282
- cl_adapter::cast<cl_event *>(phEvent))) ;
383
+ cl_adapter::cast<cl_event *>(phEvent));
283
384
284
- return UR_RESULT_SUCCESS;
385
+ if (ClErr == CL_INVALID_VALUE) {
386
+ UR_RETURN_ON_FAILURE (ValidateImageSize (hImageSrc, region, srcOrigin));
387
+ UR_RETURN_ON_FAILURE (ValidateImageSize (hImageDst, region, dstOrigin));
388
+ }
389
+ return mapCLErrorToUR (ClErr);
285
390
}
286
391
287
392
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferMap (
@@ -298,9 +403,10 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferMap(
298
403
cl_adapter::cast<const cl_event *>(phEventWaitList),
299
404
cl_adapter::cast<cl_event *>(phEvent), &Err);
300
405
301
- CL_RETURN_ON_FAILURE (Err);
302
-
303
- return UR_RESULT_SUCCESS;
406
+ if (Err == CL_INVALID_VALUE) {
407
+ UR_RETURN_ON_FAILURE (ValidateBufferSize (hBuffer, size, offset));
408
+ }
409
+ return mapCLErrorToUR (Err);
304
410
}
305
411
306
412
UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemUnmap (
0 commit comments