diff --git a/include/ur_api.h b/include/ur_api.h index 09f6d77a6b..63f5fc8083 100644 --- a/include/ur_api.h +++ b/include/ur_api.h @@ -5972,7 +5972,7 @@ urEnqueueEventsWaitWithBarrier( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -6021,7 +6021,7 @@ urEnqueueMemBufferRead( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being written @@ -6080,7 +6080,7 @@ urEnqueueMemBufferWrite( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -6146,7 +6146,7 @@ urEnqueueMemBufferReadRect( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -6199,8 +6199,8 @@ urEnqueueMemBufferWriteRect( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_mem_handle_t hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -6252,8 +6252,8 @@ urEnqueueMemBufferCopy( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_mem_handle_t hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t region, ///< [in] source 3D rectangular region descriptor: width, height, depth @@ -6307,7 +6307,7 @@ urEnqueueMemBufferCopyRect( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object const void *pPattern, ///< [in] pointer to the fill pattern size_t patternSize, ///< [in] size in bytes of the pattern size_t offset, ///< [in] offset into the buffer @@ -6357,7 +6357,7 @@ urEnqueueMemBufferFill( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image ur_rect_region_t region, ///< [in] defines the (width, height, depth) in pixels of the 1D, 2D, or 3D @@ -6410,7 +6410,7 @@ urEnqueueMemImageRead( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image ur_rect_region_t region, ///< [in] defines the (width, height, depth) in pixels of the 1D, 2D, or 3D @@ -6457,8 +6457,8 @@ urEnqueueMemImageWrite( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageCopy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_mem_handle_t hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image ur_rect_offset_t dstOrigin, ///< [in] defines the (x,y,z) offset in pixels in the destination 1D, 2D, @@ -6543,7 +6543,7 @@ typedef enum ur_usm_migration_flag_t { UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -6611,7 +6611,7 @@ urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hQueue` /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == ptr` +/// + `NULL == pMem` /// + `NULL == pPattern` /// - ::UR_RESULT_ERROR_INVALID_QUEUE /// - ::UR_RESULT_ERROR_INVALID_EVENT @@ -6631,7 +6631,7 @@ urEnqueueMemUnmap( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. const void *pPattern, ///< [in] pointer with the bytes of the pattern to set. @@ -6674,8 +6674,8 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object + void *pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void *pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t *phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -6720,7 +6720,7 @@ urEnqueueUSMMemcpy( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMPrefetch( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object + const void *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list @@ -6762,7 +6762,7 @@ urEnqueueUSMPrefetch( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMAdvise( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object + const void *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t *phEvent ///< [out][optional] return an event object that identifies this particular @@ -6803,7 +6803,7 @@ urEnqueueUSMAdvise( UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void *pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -6853,9 +6853,10 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void *pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void *pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. size_t height, ///< [in] the height of columns to be copied. @@ -9856,7 +9857,7 @@ typedef struct ur_enqueue_mem_unmap_params_t { /// allowing the callback the ability to modify the parameter's value typedef struct ur_enqueue_usm_fill_params_t { ur_queue_handle_t *phQueue; - void **pptr; + void **ppMem; size_t *ppatternSize; const void **ppPattern; size_t *psize; diff --git a/include/ur_print.hpp b/include/ur_print.hpp index dc7442068c..9a0ce9e657 100644 --- a/include/ur_print.hpp +++ b/include/ur_print.hpp @@ -12512,10 +12512,10 @@ inline std::ostream &operator<<(std::ostream &os, [[maybe_unused]] const struct *(params->phQueue)); os << ", "; - os << ".ptr = "; + os << ".pMem = "; ur::details::printPtr(os, - *(params->pptr)); + *(params->ppMem)); os << ", "; os << ".patternSize = "; diff --git a/scripts/YaML.md b/scripts/YaML.md index 291e4263c7..ee22cd39d6 100644 --- a/scripts/YaML.md +++ b/scripts/YaML.md @@ -616,13 +616,18 @@ class ur_name_t(Structure): - `out` is used for params that are write-only; if the param is a pointer, then the memory being pointed to is also write-only - `in,out` is used for params that are both read and write; typically this is used for pointers to other data structures that contain both read and write params - `nocheck` is used to specify that no additional validation checks will be generated. - + `desc` may include one the following annotations: {`"[optional]"`, `"[range(start,end)]"`, `"[release]"`, `"[typename(typeVarName)]"`} + + `desc` may include one the following annotations: {`"[optional]"`, `"[range(start,end)]"`, `"[release]"`, `"[typename(typeVarName)]"`, `"[bounds(offset,size)]"`} - `optional` is used for params that are handles or pointers where it is legal for the value to be `nullptr` - `range` is used for params that are array pointers to specify the valid range that the is valid to read + `start` and `end` must be an ISO-C standard identifier or literal + `start` is inclusive and `end` is exclusive - `release` is used for params that are handles or pointers to handles where the function will destroy any backing memory associated with the handle(s) - `typename` is used to denote the type enum for params that are opaque pointers to values of tagged data types. + - `bounds` is used for params that are memory objects or USM allocations. It specifies the range within the memory allocation represented by the param that will be accessed by the operation. + + `offset` and `size` must be an ISO-C standard identifier or literal + + The sum of `offset` and `size` will be compared against the size of the memory allocation represented by the param. + + If `offset` and `size` are not both integers they must be of the types `$x_rect_offset` and `$x_rect_region` respectively. + + If `bounds` is used the operation must also take a parameter of type `$x_queue_handle_t` + `type` must be an ISO-C standard identifier + `name` must be a unique ISO-C standard identifier - A param may take the following optional scalar field: {`init`, `version`} diff --git a/scripts/core/enqueue.yml b/scripts/core/enqueue.yml index 7da1c8f680..7af03074c9 100644 --- a/scripts/core/enqueue.yml +++ b/scripts/core/enqueue.yml @@ -158,7 +158,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(offset, size)] handle of the buffer object" - type: bool name: blockingRead desc: "[in] indicates blocking (true), non-blocking (false)" @@ -211,7 +211,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(offset, size)] handle of the buffer object" - type: bool name: blockingWrite desc: "[in] indicates blocking (true), non-blocking (false)" @@ -265,7 +265,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(bufferOrigin, region)] handle of the buffer object" - type: bool name: blockingRead desc: "[in] indicates blocking (true), non-blocking (false)" @@ -341,7 +341,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(bufferOrigin, region)] handle of the buffer object" - type: bool name: blockingWrite desc: "[in] indicates blocking (true), non-blocking (false)" @@ -414,10 +414,10 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBufferSrc - desc: "[in] handle of the src buffer object" + desc: "[in][bounds(srcOffset, size)] handle of the src buffer object" - type: $x_mem_handle_t name: hBufferDst - desc: "[in] handle of the dest buffer object" + desc: "[in][bounds(dstOffset, size)] handle of the dest buffer object" - type: size_t name: srcOffset desc: "[in] offset into hBufferSrc to begin copying from" @@ -466,10 +466,10 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBufferSrc - desc: "[in] handle of the source buffer object" + desc: "[in][bounds(srcOrigin, region)] handle of the source buffer object" - type: $x_mem_handle_t name: hBufferDst - desc: "[in] handle of the dest buffer object" + desc: "[in][bounds(dstOrigin, region)] handle of the dest buffer object" - type: $x_rect_offset_t name: srcOrigin desc: "[in] 3D offset in the source buffer" @@ -537,7 +537,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(offset, size)] handle of the buffer object" - type: "const void*" name: pPattern desc: "[in] pointer to the fill pattern" @@ -595,7 +595,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hImage - desc: "[in] handle of the image object" + desc: "[in][bounds(origin, region)] handle of the image object" - type: bool name: blockingRead desc: "[in] indicates blocking (true), non-blocking (false)" @@ -654,7 +654,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hImage - desc: "[in] handle of the image object" + desc: "[in][bounds(origin, region)] handle of the image object" - type: bool name: blockingWrite desc: "[in] indicates blocking (true), non-blocking (false)" @@ -711,10 +711,10 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hImageSrc - desc: "[in] handle of the src image object" + desc: "[in][bounds(srcOrigin, region)] handle of the src image object" - type: $x_mem_handle_t name: hImageDst - desc: "[in] handle of the dest image object" + desc: "[in][bounds(dstOrigin, region)] handle of the dest image object" - type: $x_rect_offset_t name: srcOrigin desc: "[in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D image" @@ -842,7 +842,7 @@ params: desc: "[in] handle of the queue object" - type: $x_mem_handle_t name: hBuffer - desc: "[in] handle of the buffer object" + desc: "[in][bounds(offset, size)] handle of the buffer object" - type: bool name: blockingMap desc: "[in] indicates blocking (true), non-blocking (false)" @@ -996,8 +996,8 @@ params: name: hQueue desc: "[in] handle of the queue object" - type: void* - name: ptr - desc: "[in] pointer to USM memory object" + name: pMem + desc: "[in][bounds(0, size)] pointer to USM memory object" - type: size_t name: patternSize desc: "[in] the size in bytes of the pattern. Must be a power of 2 and less than or equal to width." @@ -1050,10 +1050,10 @@ params: desc: "[in] blocking or non-blocking copy" - type: void* name: pDst - desc: "[in] pointer to the destination USM memory object" + desc: "[in][bounds(0, size)] pointer to the destination USM memory object" - type: "const void*" name: pSrc - desc: "[in] pointer to the source USM memory object" + desc: "[in][bounds(0, size)] pointer to the source USM memory object" - type: size_t name: size desc: "[in] size in bytes to be copied" @@ -1097,7 +1097,7 @@ params: desc: "[in] handle of the queue object" - type: "const void*" name: pMem - desc: "[in] pointer to the USM memory object" + desc: "[in][bounds(0, size)] pointer to the USM memory object" - type: size_t name: size desc: "[in] size in bytes to be fetched" @@ -1144,7 +1144,7 @@ params: desc: "[in] handle of the queue object" - type: "const void*" name: pMem - desc: "[in] pointer to the USM memory object" + desc: "[in][bounds(0, size)] pointer to the USM memory object" - type: size_t name: size desc: "[in] size in bytes to be advised" @@ -1176,7 +1176,7 @@ params: desc: "[in] handle of the queue to submit to." - type: void* name: pMem - desc: "[in] pointer to memory to be filled." + desc: "[in][bounds(0, pitch * height)] pointer to memory to be filled." - type: size_t name: pitch desc: "[in] the total width of the destination memory including padding." @@ -1238,13 +1238,13 @@ params: desc: "[in] indicates if this operation should block the host." - type: void* name: pDst - desc: "[in] pointer to memory where data will be copied." + desc: "[in][bounds(0, dstPitch * height)] pointer to memory where data will be copied." - type: size_t name: dstPitch desc: "[in] the total width of the source memory including padding." - type: "const void*" name: pSrc - desc: "[in] pointer to memory to be copied." + desc: "[in][bounds(0, srcPitch * height)] pointer to memory to be copied." - type: size_t name: srcPitch desc: "[in] the total width of the source memory including padding." diff --git a/scripts/parse_specs.py b/scripts/parse_specs.py index a1477ce534..332af88cc7 100644 --- a/scripts/parse_specs.py +++ b/scripts/parse_specs.py @@ -338,6 +338,15 @@ def __validate_params(d, tags): if not param_traits.is_range(item): raise Exception(prefix+"handle type must include a range(start, end) as part of 'desc'") + if param_traits.is_bounds(item): + has_queue = False + for p in d['params']: + if re.match(r"hQueue$", p['name']): + has_queue = True + + if not has_queue: + raise Exception(prefix+"bounds must only be used on entry points which take a `hQueue` parameter") + ver = __validate_version(item, prefix=prefix, base_version=d_ver) if ver < max_ver: raise Exception(prefix+"'version' must be increasing: %s"%item['version']) diff --git a/scripts/templates/helper.py b/scripts/templates/helper.py index 4fbb2ca47b..928db1675c 100644 --- a/scripts/templates/helper.py +++ b/scripts/templates/helper.py @@ -356,6 +356,7 @@ class param_traits: RE_RELEASE = r".*\[release\].*" RE_TYPENAME = r".*\[typename\((.+),\s(.+)\)\].*" RE_TAGGED = r".*\[tagged_by\((.+)\)].*" + RE_BOUNDS = r".*\[bounds\((.+),\s*(.+)\)].*" @classmethod def is_mbz(cls, item): @@ -412,6 +413,13 @@ def is_tagged(cls, item): return True if re.match(cls.RE_TAGGED, item['desc']) else False except: return False + + @classmethod + def is_bounds(cls, item): + try: + return True if re.match(cls.RE_BOUNDS, item['desc']) else False + except: + return False @classmethod def tagged_member(cls, item): @@ -457,6 +465,22 @@ def typename_size(cls, item): else: return None + @classmethod + def bounds_offset(cls, item): + match = re.match(cls.RE_BOUNDS, item['desc']) + if match: + return match.group(1) + else: + return None + + @classmethod + def bounds_size(cls, item): + match = re.match(cls.RE_BOUNDS, item['desc']) + if match: + return match.group(2) + else: + return None + """ Extracts traits from a function object """ @@ -1041,7 +1065,35 @@ def make_pfncb_param_type(namespace, tags, obj): """ Public: - returns a dict of auto-generated c++ parameter validation checks + returns an appropriate bounds helper function call for an entry point + parameter with the [bounds] tag +""" +def get_bounds_check(param, bounds_error): + # Images need their own helper, since function signature wise they would be + # identical to buffer rect + bounds_function = 'boundsImage' if 'image' in param['name'].lower() else 'bounds' + bounds_check = "auto {0} = {1}({2}, {3}, {4})".format( + bounds_error, + bounds_function, + param["name"], + param_traits.bounds_offset(param), + param_traits.bounds_size(param), + ) + bounds_check += '; {0} != UR_RESULT_SUCCESS'.format(bounds_error) + + # USM bounds checks need the queue handle parameter to be able to use the + # GetMemAllocInfo entry point + if type_traits.is_pointer(param['type']): + # If no `hQueue` parameter exists that should have been caught at spec + # generation. + return re.sub(r'bounds\(', 'bounds(hQueue, ', bounds_check) + + return bounds_check + +""" +Public: + returns a dict of auto-generated c++ parameter validation checks for the + given function (specified by `obj`) """ def make_param_checks(namespace, tags, obj, cpp=False, meta=None): checks = {} @@ -1054,6 +1106,13 @@ def make_param_checks(namespace, tags, obj, cpp=False, meta=None): if key not in checks: checks[key] = [] checks[key].append(subt(namespace, tags, code.group(1), False, cpp)) + + for p in obj.get('params', []): + if param_traits.is_bounds(p): + if 'boundsError' not in checks: + checks['boundsError'] = [] + checks['boundsError'].append(get_bounds_check(p, 'boundsError')) + return checks """ diff --git a/source/adapters/hip/usm.cpp b/source/adapters/hip/usm.cpp index 7af7401f87..0aaf6de53e 100644 --- a/source/adapters/hip/usm.cpp +++ b/source/adapters/hip/usm.cpp @@ -190,9 +190,6 @@ urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem, #endif return ReturnValue(UR_USM_TYPE_UNKNOWN); } - case UR_USM_ALLOC_INFO_BASE_PTR: - case UR_USM_ALLOC_INFO_SIZE: - return UR_RESULT_ERROR_INVALID_VALUE; case UR_USM_ALLOC_INFO_DEVICE: { // get device index associated with this pointer UR_CHECK_ERROR(hipPointerGetAttributes(&hipPointerAttributeType, pMem)); @@ -222,6 +219,9 @@ urUSMGetMemAllocInfo(ur_context_handle_t hContext, const void *pMem, } return ReturnValue(Pool); } + case UR_USM_ALLOC_INFO_BASE_PTR: + case UR_USM_ALLOC_INFO_SIZE: + return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION; default: return UR_RESULT_ERROR_INVALID_ENUMERATION; } diff --git a/source/adapters/null/ur_nullddi.cpp b/source/adapters/null/ur_nullddi.cpp index a4e91e3dc0..f016830d11 100644 --- a/source/adapters/null/ur_nullddi.cpp +++ b/source/adapters/null/ur_nullddi.cpp @@ -2917,7 +2917,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// @brief Intercept function for urEnqueueMemBufferRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -2956,7 +2957,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( /// @brief Intercept function for urEnqueueMemBufferWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -2997,7 +2999,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// @brief Intercept function for urEnqueueMemBufferReadRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -3050,7 +3053,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// @brief Intercept function for urEnqueueMemBufferWriteRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -3105,9 +3109,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -3144,9 +3150,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopyRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -3195,10 +3203,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// @brief Intercept function for urEnqueueMemBufferFill __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -3234,7 +3243,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( /// @brief Intercept function for urEnqueueMemImageRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -3278,7 +3288,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( /// @brief Intercept function for urEnqueueMemImageWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -3322,9 +3333,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemImageCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -3368,7 +3381,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( /// @brief Intercept function for urEnqueueMemBufferMap __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -3445,7 +3459,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemUnmap( /// @brief Intercept function for urEnqueueUSMFill __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -3468,7 +3482,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( // if the driver has created a custom function, then call it instead of using the generic path auto pfnUSMFill = d_context.urDdiTable.Enqueue.pfnUSMFill; if (nullptr != pfnUSMFill) { - result = pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + result = pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitList, phEvent); } else { // generic implementation @@ -3487,9 +3501,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -3522,9 +3538,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMPrefetch __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -3558,9 +3575,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMAdvise __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -3588,7 +3606,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( /// @brief Intercept function for urEnqueueUSMFill2D __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -3635,10 +3654,13 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. diff --git a/source/adapters/opencl/enqueue.cpp b/source/adapters/opencl/enqueue.cpp index 24d60e62f5..6830a28eec 100644 --- a/source/adapters/opencl/enqueue.cpp +++ b/source/adapters/opencl/enqueue.cpp @@ -25,77 +25,6 @@ cl_map_flags convertURMapFlagsToCL(ur_map_flags_t URFlags) { return CLFlags; } -ur_result_t ValidateBufferSize(ur_mem_handle_t Buffer, size_t Size, - size_t Origin) { - size_t BufferSize = 0; - CL_RETURN_ON_FAILURE(clGetMemObjectInfo(cl_adapter::cast(Buffer), - CL_MEM_SIZE, sizeof(BufferSize), - &BufferSize, nullptr)); - if (Size + Origin > BufferSize) - return UR_RESULT_ERROR_INVALID_SIZE; - return UR_RESULT_SUCCESS; -} - -ur_result_t ValidateBufferRectSize(ur_mem_handle_t Buffer, - ur_rect_region_t Region, - ur_rect_offset_t Offset) { - size_t BufferSize = 0; - CL_RETURN_ON_FAILURE(clGetMemObjectInfo(cl_adapter::cast(Buffer), - CL_MEM_SIZE, sizeof(BufferSize), - &BufferSize, nullptr)); - if (Offset.x >= BufferSize || Offset.y >= BufferSize || - Offset.z >= BufferSize) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - if ((Region.width + Offset.x) * (Region.height + Offset.y) * - (Region.depth + Offset.z) > - BufferSize) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - return UR_RESULT_SUCCESS; -} - -ur_result_t ValidateImageSize(ur_mem_handle_t Image, ur_rect_region_t Region, - ur_rect_offset_t Origin) { - size_t Width = 0; - CL_RETURN_ON_FAILURE(clGetImageInfo(cl_adapter::cast(Image), - CL_IMAGE_WIDTH, sizeof(Width), &Width, - nullptr)); - if (Region.width + Origin.x > Width) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - size_t Height = 0; - CL_RETURN_ON_FAILURE(clGetImageInfo(cl_adapter::cast(Image), - CL_IMAGE_HEIGHT, sizeof(Height), &Height, - nullptr)); - - // CL returns a height and depth of 0 for images that don't have those - // dimensions, but regions for enqueue operations must set these to 1, so we - // need to make this adjustment to validate. - if (Height == 0) - Height = 1; - - if (Region.height + Origin.y > Height) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - size_t Depth = 0; - CL_RETURN_ON_FAILURE(clGetImageInfo(cl_adapter::cast(Image), - CL_IMAGE_DEPTH, sizeof(Depth), &Depth, - nullptr)); - if (Depth == 0) - Depth = 1; - - if (Region.depth + Origin.z > Depth) { - return UR_RESULT_ERROR_INVALID_SIZE; - } - - return UR_RESULT_SUCCESS; -} - UR_APIEXPORT ur_result_t UR_APICALL urEnqueueKernelLaunch( ur_queue_handle_t hQueue, ur_kernel_handle_t hKernel, uint32_t workDim, const size_t *pGlobalWorkOffset, const size_t *pGlobalWorkSize, @@ -141,16 +70,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferRead( size_t offset, size_t size, void *pDst, uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { - auto ClErr = clEnqueueReadBuffer( + CL_RETURN_ON_FAILURE(clEnqueueReadBuffer( cl_adapter::cast(hQueue), cl_adapter::cast(hBuffer), blockingRead, offset, size, pDst, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, size, offset)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWrite( @@ -158,16 +84,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWrite( size_t offset, size_t size, const void *pSrc, uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { - auto ClErr = clEnqueueWriteBuffer( + CL_RETURN_ON_FAILURE(clEnqueueWriteBuffer( cl_adapter::cast(hQueue), cl_adapter::cast(hBuffer), blockingWrite, offset, size, pSrc, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, size, offset)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferReadRect( @@ -182,18 +105,15 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferReadRect( const size_t HostOrigin[3] = {hostOrigin.x, hostOrigin.y, hostOrigin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueReadBufferRect( + CL_RETURN_ON_FAILURE(clEnqueueReadBufferRect( cl_adapter::cast(hQueue), cl_adapter::cast(hBuffer), blockingRead, BufferOrigin, HostOrigin, Region, bufferRowPitch, bufferSlicePitch, hostRowPitch, hostSlicePitch, pDst, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferRectSize(hBuffer, region, bufferOrigin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( @@ -208,18 +128,15 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( const size_t HostOrigin[3] = {hostOrigin.x, hostOrigin.y, hostOrigin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueWriteBufferRect( + CL_RETURN_ON_FAILURE(clEnqueueWriteBufferRect( cl_adapter::cast(hQueue), cl_adapter::cast(hBuffer), blockingWrite, BufferOrigin, HostOrigin, Region, bufferRowPitch, bufferSlicePitch, hostRowPitch, hostSlicePitch, pSrc, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferRectSize(hBuffer, region, bufferOrigin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopy( @@ -228,18 +145,14 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopy( uint32_t numEventsInWaitList, const ur_event_handle_t *phEventWaitList, ur_event_handle_t *phEvent) { - auto ClErr = clEnqueueCopyBuffer( + CL_RETURN_ON_FAILURE(clEnqueueCopyBuffer( cl_adapter::cast(hQueue), cl_adapter::cast(hBufferSrc), cl_adapter::cast(hBufferDst), srcOffset, dstOffset, size, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBufferSrc, size, srcOffset)); - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBufferDst, size, dstOffset)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( @@ -253,19 +166,15 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( const size_t DstOrigin[3] = {dstOrigin.x, dstOrigin.y, dstOrigin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueCopyBufferRect( + CL_RETURN_ON_FAILURE(clEnqueueCopyBufferRect( cl_adapter::cast(hQueue), cl_adapter::cast(hBufferSrc), cl_adapter::cast(hBufferDst), SrcOrigin, DstOrigin, Region, srcRowPitch, srcSlicePitch, dstRowPitch, dstSlicePitch, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferRectSize(hBufferSrc, region, srcOrigin)); - UR_RETURN_ON_FAILURE(ValidateBufferRectSize(hBufferDst, region, dstOrigin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill( @@ -276,16 +185,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill( // CL FillBuffer only allows pattern sizes up to the largest CL type: // long16/double16 if (patternSize <= 128) { - auto ClErr = (clEnqueueFillBuffer( - cl_adapter::cast(hQueue), - cl_adapter::cast(hBuffer), pPattern, patternSize, offset, size, - numEventsInWaitList, - cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent))); - if (ClErr != CL_SUCCESS) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, size, offset)); - } - return mapCLErrorToUR(ClErr); + CL_RETURN_ON_FAILURE( + clEnqueueFillBuffer(cl_adapter::cast(hQueue), + cl_adapter::cast(hBuffer), pPattern, + patternSize, offset, size, numEventsInWaitList, + cl_adapter::cast(phEventWaitList), + cl_adapter::cast(phEvent))); + return UR_RESULT_SUCCESS; } auto NumValues = size / sizeof(uint64_t); @@ -303,7 +209,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferFill( &WriteEvent); if (ClErr != CL_SUCCESS) { delete[] HostBuffer; - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, offset, size)); CL_RETURN_ON_FAILURE(ClErr); } @@ -338,17 +243,14 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageRead( const size_t Origin[3] = {origin.x, origin.y, origin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueReadImage( + CL_RETURN_ON_FAILURE(clEnqueueReadImage( cl_adapter::cast(hQueue), cl_adapter::cast(hImage), blockingRead, Origin, Region, rowPitch, slicePitch, pDst, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateImageSize(hImage, region, origin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageWrite( @@ -359,17 +261,14 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageWrite( const size_t Origin[3] = {origin.x, origin.y, origin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueWriteImage( + CL_RETURN_ON_FAILURE(clEnqueueWriteImage( cl_adapter::cast(hQueue), cl_adapter::cast(hImage), blockingWrite, Origin, Region, rowPitch, slicePitch, pSrc, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateImageSize(hImage, region, origin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageCopy( @@ -382,18 +281,14 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemImageCopy( const size_t DstOrigin[3] = {dstOrigin.x, dstOrigin.y, dstOrigin.z}; const size_t Region[3] = {region.width, region.height, region.depth}; - auto ClErr = clEnqueueCopyImage( + CL_RETURN_ON_FAILURE(clEnqueueCopyImage( cl_adapter::cast(hQueue), cl_adapter::cast(hImageSrc), cl_adapter::cast(hImageDst), SrcOrigin, DstOrigin, Region, numEventsInWaitList, cl_adapter::cast(phEventWaitList), - cl_adapter::cast(phEvent)); + cl_adapter::cast(phEvent))); - if (ClErr == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateImageSize(hImageSrc, region, srcOrigin)); - UR_RETURN_ON_FAILURE(ValidateImageSize(hImageDst, region, dstOrigin)); - } - return mapCLErrorToUR(ClErr); + return UR_RESULT_SUCCESS; } UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferMap( @@ -410,9 +305,6 @@ UR_APIEXPORT ur_result_t UR_APICALL urEnqueueMemBufferMap( cl_adapter::cast(phEventWaitList), cl_adapter::cast(phEvent), &Err); - if (Err == CL_INVALID_VALUE) { - UR_RETURN_ON_FAILURE(ValidateBufferSize(hBuffer, size, offset)); - } return mapCLErrorToUR(Err); } diff --git a/source/loader/layers/tracing/ur_trcddi.cpp b/source/loader/layers/tracing/ur_trcddi.cpp index d33a3aaf51..402b64d638 100644 --- a/source/loader/layers/tracing/ur_trcddi.cpp +++ b/source/loader/layers/tracing/ur_trcddi.cpp @@ -3325,7 +3325,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// @brief Intercept function for urEnqueueMemBufferRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -3367,7 +3368,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( /// @brief Intercept function for urEnqueueMemBufferWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -3412,7 +3414,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// @brief Intercept function for urEnqueueMemBufferReadRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -3479,7 +3482,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// @brief Intercept function for urEnqueueMemBufferWriteRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -3549,9 +3553,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -3590,9 +3596,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopyRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -3646,10 +3654,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// @brief Intercept function for urEnqueueMemBufferFill __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -3693,7 +3702,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( /// @brief Intercept function for urEnqueueMemImageRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -3741,7 +3751,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( /// @brief Intercept function for urEnqueueMemImageWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -3789,9 +3800,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemImageCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -3837,7 +3850,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( /// @brief Intercept function for urEnqueueMemBufferMap __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -3920,7 +3934,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemUnmap( /// @brief Intercept function for urEnqueueUSMFill __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -3945,14 +3959,14 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( } ur_enqueue_usm_fill_params_t params = { - &hQueue, &ptr, &patternSize, + &hQueue, &pMem, &patternSize, &pPattern, &size, &numEventsInWaitList, &phEventWaitList, &phEvent}; uint64_t instance = context.notify_begin(UR_FUNCTION_ENQUEUE_USM_FILL, "urEnqueueUSMFill", ¶ms); ur_result_t result = - pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitList, phEvent); context.notify_end(UR_FUNCTION_ENQUEUE_USM_FILL, "urEnqueueUSMFill", @@ -3966,9 +3980,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -4004,9 +4020,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMPrefetch __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4043,9 +4060,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMAdvise __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -4074,7 +4092,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( /// @brief Intercept function for urEnqueueUSMFill2D __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -4124,10 +4143,13 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. diff --git a/source/loader/layers/validation/ur_valddi.cpp b/source/loader/layers/validation/ur_valddi.cpp index ec0df692cf..72e225028c 100644 --- a/source/loader/layers/validation/ur_valddi.cpp +++ b/source/loader/layers/validation/ur_valddi.cpp @@ -4084,7 +4084,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// @brief Intercept function for urEnqueueMemBufferRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -4126,6 +4127,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hBuffer, offset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4146,7 +4152,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( /// @brief Intercept function for urEnqueueMemBufferWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -4190,6 +4197,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hBuffer, offset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4210,7 +4222,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// @brief Intercept function for urEnqueueMemBufferReadRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -4304,6 +4317,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = bounds(hBuffer, bufferOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4325,7 +4343,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// @brief Intercept function for urEnqueueMemBufferWriteRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -4423,6 +4442,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = bounds(hBuffer, bufferOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4443,9 +4467,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -4486,6 +4512,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hBufferSrc, srcOffset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = bounds(hBufferDst, dstOffset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4505,9 +4541,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopyRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -4593,6 +4631,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = bounds(hBufferSrc, srcOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = bounds(hBufferDst, dstOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4614,10 +4662,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// @brief Intercept function for urEnqueueMemBufferFill __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4676,6 +4725,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = bounds(hBuffer, offset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4696,7 +4750,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( /// @brief Intercept function for urEnqueueMemImageRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -4747,6 +4802,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = boundsImage(hImage, origin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4767,7 +4827,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( /// @brief Intercept function for urEnqueueMemImageWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -4819,6 +4880,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = boundsImage(hImage, origin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4838,9 +4904,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemImageCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -4891,6 +4959,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( return UR_RESULT_ERROR_INVALID_SIZE; } + if (auto boundsError = boundsImage(hImageSrc, srcOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = boundsImage(hImageDst, dstOrigin, region); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -4911,7 +4989,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( /// @brief Intercept function for urEnqueueMemBufferMap __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -4959,6 +5038,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hBuffer, offset, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5039,7 +5123,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemUnmap( /// @brief Intercept function for urEnqueueUSMFill __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -5068,7 +5152,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( return UR_RESULT_ERROR_INVALID_NULL_HANDLE; } - if (NULL == ptr) { + if (NULL == pMem) { return UR_RESULT_ERROR_INVALID_NULL_POINTER; } @@ -5100,6 +5184,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pMem, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5110,7 +5199,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( } ur_result_t result = - pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitList, phEvent); return result; @@ -5121,9 +5210,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -5165,6 +5256,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pDst, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = bounds(hQueue, pSrc, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5184,9 +5285,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMPrefetch __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -5229,6 +5331,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pMem, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5248,9 +5355,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMAdvise __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -5278,6 +5386,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( if (size == 0) { return UR_RESULT_ERROR_INVALID_SIZE; } + + if (auto boundsError = bounds(hQueue, pMem, 0, size); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } } ur_result_t result = pfnUSMAdvise(hQueue, pMem, size, advice, phEvent); @@ -5289,7 +5402,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( /// @brief Intercept function for urEnqueueUSMFill2D __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -5370,6 +5484,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pMem, 0, pitch * height); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { @@ -5391,10 +5510,13 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. @@ -5456,6 +5578,16 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( return UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST; } + if (auto boundsError = bounds(hQueue, pDst, 0, dstPitch * height); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + + if (auto boundsError = bounds(hQueue, pSrc, 0, srcPitch * height); + boundsError != UR_RESULT_SUCCESS) { + return boundsError; + } + if (phEventWaitList != NULL && numEventsInWaitList > 0) { for (uint32_t i = 0; i < numEventsInWaitList; ++i) { if (phEventWaitList[i] == NULL) { diff --git a/source/loader/layers/validation/ur_validation_layer.cpp b/source/loader/layers/validation/ur_validation_layer.cpp index 5cd3f8c13a..3e040fcc50 100644 --- a/source/loader/layers/validation/ur_validation_layer.cpp +++ b/source/loader/layers/validation/ur_validation_layer.cpp @@ -11,6 +11,8 @@ */ #include "ur_validation_layer.hpp" +#include + namespace ur_validation_layer { context_t context; @@ -20,4 +22,127 @@ context_t::context_t() : logger(logger::create_logger("validation")) {} /////////////////////////////////////////////////////////////////////////////// context_t::~context_t() {} +// Some adapters don't support all the queries yet, we should be lenient and +// just not attempt to validate in those cases to preserve functionality. +#define RETURN_ON_FAILURE(result) \ + if (result == UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION || \ + result == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) \ + return UR_RESULT_SUCCESS; \ + if (result != UR_RESULT_SUCCESS) { \ + context.logger.error("Unexpected non-success result code from {}", \ + #result); \ + assert(0); \ + return result; \ + } + +ur_result_t bounds(ur_mem_handle_t buffer, size_t offset, size_t size) { + auto pfnMemGetInfo = context.urDdiTable.Mem.pfnGetInfo; + + size_t bufferSize = 0; + RETURN_ON_FAILURE(pfnMemGetInfo(buffer, UR_MEM_INFO_SIZE, + sizeof(bufferSize), &bufferSize, nullptr)); + + if (size + offset > bufferSize) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + return UR_RESULT_SUCCESS; +} + +ur_result_t bounds(ur_mem_handle_t buffer, ur_rect_offset_t offset, + ur_rect_region_t region) { + auto pfnMemGetInfo = context.urDdiTable.Mem.pfnGetInfo; + + size_t bufferSize = 0; + RETURN_ON_FAILURE(pfnMemGetInfo(buffer, UR_MEM_INFO_SIZE, + sizeof(bufferSize), &bufferSize, nullptr)); + + if (offset.x >= bufferSize || offset.y >= bufferSize || + offset.z >= bufferSize) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + if ((region.width + offset.x) * (region.height + offset.y) * + (region.depth + offset.z) > + bufferSize) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + return UR_RESULT_SUCCESS; +} + +ur_result_t bounds(ur_queue_handle_t queue, const void *ptr, size_t offset, + size_t size) { + auto pfnQueueGetInfo = context.urDdiTable.Queue.pfnGetInfo; + auto pfnUSMGetMemAllocInfo = context.urDdiTable.USM.pfnGetMemAllocInfo; + + ur_context_handle_t urContext = nullptr; + RETURN_ON_FAILURE(pfnQueueGetInfo(queue, UR_QUEUE_INFO_CONTEXT, + sizeof(ur_context_handle_t), &urContext, + nullptr)); + ur_usm_type_t usmType = UR_USM_TYPE_UNKNOWN; + RETURN_ON_FAILURE( + pfnUSMGetMemAllocInfo(urContext, ptr, UR_USM_ALLOC_INFO_TYPE, + sizeof(usmType), &usmType, nullptr)); + + // We can't reliably get size info about pointers that didn't come from the + // USM alloc entry points. + if (usmType == UR_USM_TYPE_UNKNOWN) { + return UR_RESULT_SUCCESS; + } + + size_t allocSize = 0; + RETURN_ON_FAILURE( + pfnUSMGetMemAllocInfo(urContext, ptr, UR_USM_ALLOC_INFO_SIZE, + sizeof(allocSize), &allocSize, nullptr)); + + if (size + offset > allocSize) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + return UR_RESULT_SUCCESS; +} + +ur_result_t boundsImage(ur_mem_handle_t image, ur_rect_offset_t origin, + ur_rect_region_t region) { + auto pfnMemImageGetInfo = context.urDdiTable.Mem.pfnImageGetInfo; + + size_t width = 0; + RETURN_ON_FAILURE(pfnMemImageGetInfo(image, UR_IMAGE_INFO_WIDTH, + sizeof(width), &width, nullptr)); + if (region.width + origin.x > width) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + size_t height = 0; + RETURN_ON_FAILURE(pfnMemImageGetInfo(image, UR_IMAGE_INFO_HEIGHT, + sizeof(height), &height, nullptr)); + + // Some adapters return a height and depth of 0 for images that don't have + // those dimensions, but regions for enqueue operations must set these to + // 1, so we need to make this adjustment to properly validate. + if (height == 0) { + height = 1; + } + + if (region.height + origin.y > height) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + size_t depth = 0; + RETURN_ON_FAILURE(pfnMemImageGetInfo(image, UR_IMAGE_INFO_DEPTH, + sizeof(depth), &depth, nullptr)); + if (depth == 0) { + depth = 1; + } + + if (region.depth + origin.z > depth) { + return UR_RESULT_ERROR_INVALID_SIZE; + } + + return UR_RESULT_SUCCESS; +} + +#undef RETURN_ON_FAILURE + } // namespace ur_validation_layer diff --git a/source/loader/layers/validation/ur_validation_layer.hpp b/source/loader/layers/validation/ur_validation_layer.hpp index e41c621dc8..d29b64230e 100644 --- a/source/loader/layers/validation/ur_validation_layer.hpp +++ b/source/loader/layers/validation/ur_validation_layer.hpp @@ -44,6 +44,17 @@ class __urdlllocal context_t : public proxy_layer_context_t { const std::string nameLeakChecking = "UR_LAYER_LEAK_CHECKING"; }; +ur_result_t bounds(ur_mem_handle_t buffer, size_t offset, size_t size); + +ur_result_t bounds(ur_mem_handle_t buffer, ur_rect_offset_t offset, + ur_rect_region_t region); + +ur_result_t bounds(ur_queue_handle_t queue, const void *ptr, size_t offset, + size_t size); + +ur_result_t boundsImage(ur_mem_handle_t image, ur_rect_offset_t origin, + ur_rect_region_t region); + extern context_t context; } // namespace ur_validation_layer diff --git a/source/loader/ur_ldrddi.cpp b/source/loader/ur_ldrddi.cpp index 27d8011cf7..5d7df7e672 100644 --- a/source/loader/ur_ldrddi.cpp +++ b/source/loader/ur_ldrddi.cpp @@ -3852,7 +3852,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// @brief Intercept function for urEnqueueMemBufferRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -3916,7 +3917,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferRead( /// @brief Intercept function for urEnqueueMemBufferWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -3982,7 +3984,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// @brief Intercept function for urEnqueueMemBufferReadRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -4059,7 +4062,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// @brief Intercept function for urEnqueueMemBufferWriteRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -4138,9 +4142,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -4205,9 +4211,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemBufferCopyRect __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -4283,10 +4291,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// @brief Intercept function for urEnqueueMemBufferFill __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4347,7 +4356,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferFill( /// @brief Intercept function for urEnqueueMemImageRead __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -4416,7 +4426,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageRead( /// @brief Intercept function for urEnqueueMemImageWrite __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -4485,9 +4496,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageWrite( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueMemImageCopy __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -4559,7 +4572,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemImageCopy( /// @brief Intercept function for urEnqueueMemBufferMap __urdlllocal ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -4686,7 +4700,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueMemUnmap( /// @brief Intercept function for urEnqueueUSMFill __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -4726,7 +4740,7 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( // forward to device-platform result = - pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitListLocal.data(), phEvent); if (UR_RESULT_SUCCESS != result) { @@ -4751,9 +4765,11 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -4809,9 +4825,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMPrefetch __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4867,9 +4884,10 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMPrefetch( /////////////////////////////////////////////////////////////////////////////// /// @brief Intercept function for urEnqueueUSMAdvise __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -4911,7 +4929,8 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMAdvise( /// @brief Intercept function for urEnqueueUSMFill2D __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -4980,10 +4999,13 @@ __urdlllocal ur_result_t UR_APICALL urEnqueueUSMFill2D( __urdlllocal ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. diff --git a/source/loader/ur_libapi.cpp b/source/loader/ur_libapi.cpp index de9e029536..80d1bc3fb6 100644 --- a/source/loader/ur_libapi.cpp +++ b/source/loader/ur_libapi.cpp @@ -4833,7 +4833,8 @@ ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -4894,7 +4895,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferRead( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -4967,7 +4969,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -5052,7 +5055,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -5125,9 +5129,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -5191,9 +5197,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferCopy( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -5266,10 +5274,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -5329,7 +5338,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferFill( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -5396,7 +5406,8 @@ ur_result_t UR_APICALL urEnqueueMemImageRead( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -5458,9 +5469,11 @@ ur_result_t UR_APICALL urEnqueueMemImageWrite( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -5532,7 +5545,8 @@ ur_result_t UR_APICALL urEnqueueMemImageCopy( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -5625,7 +5639,7 @@ ur_result_t UR_APICALL urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hQueue` /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == ptr` +/// + `NULL == pMem` /// + `NULL == pPattern` /// - ::UR_RESULT_ERROR_INVALID_QUEUE /// - ::UR_RESULT_ERROR_INVALID_EVENT @@ -5644,7 +5658,7 @@ ur_result_t UR_APICALL urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -5667,7 +5681,7 @@ ur_result_t UR_APICALL urEnqueueUSMFill( return UR_RESULT_ERROR_UNINITIALIZED; } - return pfnUSMFill(hQueue, ptr, patternSize, pPattern, size, + return pfnUSMFill(hQueue, pMem, patternSize, pPattern, size, numEventsInWaitList, phEventWaitList, phEvent); } catch (...) { return exceptionToResult(std::current_exception()); @@ -5701,9 +5715,11 @@ ur_result_t UR_APICALL urEnqueueUSMFill( ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -5757,9 +5773,10 @@ ur_result_t UR_APICALL urEnqueueUSMMemcpy( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -5810,9 +5827,10 @@ ur_result_t UR_APICALL urEnqueueUSMPrefetch( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -5861,7 +5879,8 @@ ur_result_t UR_APICALL urEnqueueUSMAdvise( /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -5926,10 +5945,13 @@ ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied. diff --git a/source/ur_api.cpp b/source/ur_api.cpp index ca1f82019c..3a7cebca8c 100644 --- a/source/ur_api.cpp +++ b/source/ur_api.cpp @@ -4094,7 +4094,8 @@ ur_result_t UR_APICALL urEnqueueEventsWaitWithBarrier( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object size_t size, ///< [in] size in bytes of data being read @@ -4147,7 +4148,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferRead( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) size_t offset, ///< [in] offset in bytes in the buffer object @@ -4212,7 +4214,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferWrite( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferReadRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer ur_rect_offset_t hostOrigin, ///< [in] 3D offset in the host region @@ -4287,7 +4290,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferReadRect( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(bufferOrigin, region)] handle of the buffer object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t bufferOrigin, ///< [in] 3D offset in the buffer @@ -4350,9 +4354,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferWriteRect( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the src buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOffset, size)] handle of the src buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOffset, size)] handle of the dest buffer object size_t srcOffset, ///< [in] offset into hBufferSrc to begin copying from size_t dstOffset, ///< [in] offset info hBufferDst to begin copying into size_t size, ///< [in] size in bytes of data being copied @@ -4407,9 +4413,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferCopy( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBufferSrc, ///< [in] handle of the source buffer object - ur_mem_handle_t hBufferDst, ///< [in] handle of the dest buffer object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hBufferSrc, ///< [in][bounds(srcOrigin, region)] handle of the source buffer object + ur_mem_handle_t + hBufferDst, ///< [in][bounds(dstOrigin, region)] handle of the dest buffer object ur_rect_offset_t srcOrigin, ///< [in] 3D offset in the source buffer ur_rect_offset_t dstOrigin, ///< [in] 3D offset in the destination buffer ur_rect_region_t @@ -4472,10 +4480,11 @@ ur_result_t UR_APICALL urEnqueueMemBufferCopyRect( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object - const void *pPattern, ///< [in] pointer to the fill pattern - size_t patternSize, ///< [in] size in bytes of the pattern - size_t offset, ///< [in] offset into the buffer + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object + const void *pPattern, ///< [in] pointer to the fill pattern + size_t patternSize, ///< [in] size in bytes of the pattern + size_t offset, ///< [in] offset into the buffer size_t size, ///< [in] fill size in bytes, must be a multiple of patternSize uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4526,7 +4535,8 @@ ur_result_t UR_APICALL urEnqueueMemBufferFill( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageRead( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingRead, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t origin, ///< [in] defines the (x,y,z) offset in pixels in the 1D, 2D, or 3D image @@ -4585,7 +4595,8 @@ ur_result_t UR_APICALL urEnqueueMemImageRead( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageWrite( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImage, ///< [in] handle of the image object + ur_mem_handle_t + hImage, ///< [in][bounds(origin, region)] handle of the image object bool blockingWrite, ///< [in] indicates blocking (true), non-blocking (false) ur_rect_offset_t @@ -4638,9 +4649,11 @@ ur_result_t UR_APICALL urEnqueueMemImageWrite( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemImageCopy( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hImageSrc, ///< [in] handle of the src image object - ur_mem_handle_t hImageDst, ///< [in] handle of the dest image object + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + ur_mem_handle_t + hImageSrc, ///< [in][bounds(srcOrigin, region)] handle of the src image object + ur_mem_handle_t + hImageDst, ///< [in][bounds(dstOrigin, region)] handle of the dest image object ur_rect_offset_t srcOrigin, ///< [in] defines the (x,y,z) offset in pixels in the source 1D, 2D, or 3D ///< image @@ -4704,7 +4717,8 @@ ur_result_t UR_APICALL urEnqueueMemImageCopy( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueMemBufferMap( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - ur_mem_handle_t hBuffer, ///< [in] handle of the buffer object + ur_mem_handle_t + hBuffer, ///< [in][bounds(offset, size)] handle of the buffer object bool blockingMap, ///< [in] indicates blocking (true), non-blocking (false) ur_map_flags_t mapFlags, ///< [in] flags for read, write, readwrite mapping size_t offset, ///< [in] offset in bytes of the buffer region being mapped @@ -4782,7 +4796,7 @@ ur_result_t UR_APICALL urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_INVALID_NULL_HANDLE /// + `NULL == hQueue` /// - ::UR_RESULT_ERROR_INVALID_NULL_POINTER -/// + `NULL == ptr` +/// + `NULL == pMem` /// + `NULL == pPattern` /// - ::UR_RESULT_ERROR_INVALID_QUEUE /// - ::UR_RESULT_ERROR_INVALID_EVENT @@ -4801,7 +4815,7 @@ ur_result_t UR_APICALL urEnqueueMemUnmap( /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMFill( ur_queue_handle_t hQueue, ///< [in] handle of the queue object - void *ptr, ///< [in] pointer to USM memory object + void *pMem, ///< [in][bounds(0, size)] pointer to USM memory object size_t patternSize, ///< [in] the size in bytes of the pattern. Must be a power of 2 and less ///< than or equal to width. @@ -4851,9 +4865,11 @@ ur_result_t UR_APICALL urEnqueueUSMFill( ur_result_t UR_APICALL urEnqueueUSMMemcpy( ur_queue_handle_t hQueue, ///< [in] handle of the queue object bool blocking, ///< [in] blocking or non-blocking copy - void *pDst, ///< [in] pointer to the destination USM memory object - const void *pSrc, ///< [in] pointer to the source USM memory object - size_t size, ///< [in] size in bytes to be copied + void * + pDst, ///< [in][bounds(0, size)] pointer to the destination USM memory object + const void * + pSrc, ///< [in][bounds(0, size)] pointer to the source USM memory object + size_t size, ///< [in] size in bytes to be copied uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * phEventWaitList, ///< [in][optional][range(0, numEventsInWaitList)] pointer to a list of @@ -4900,9 +4916,10 @@ ur_result_t UR_APICALL urEnqueueUSMMemcpy( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMPrefetch( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be fetched + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be fetched ur_usm_migration_flags_t flags, ///< [in] USM prefetch flags uint32_t numEventsInWaitList, ///< [in] size of the event wait list const ur_event_handle_t * @@ -4946,9 +4963,10 @@ ur_result_t UR_APICALL urEnqueueUSMPrefetch( /// - ::UR_RESULT_ERROR_OUT_OF_HOST_MEMORY /// - ::UR_RESULT_ERROR_OUT_OF_RESOURCES ur_result_t UR_APICALL urEnqueueUSMAdvise( - ur_queue_handle_t hQueue, ///< [in] handle of the queue object - const void *pMem, ///< [in] pointer to the USM memory object - size_t size, ///< [in] size in bytes to be advised + ur_queue_handle_t hQueue, ///< [in] handle of the queue object + const void + *pMem, ///< [in][bounds(0, size)] pointer to the USM memory object + size_t size, ///< [in] size in bytes to be advised ur_usm_advice_flags_t advice, ///< [in] USM memory advice ur_event_handle_t * phEvent ///< [out][optional] return an event object that identifies this particular @@ -4991,7 +5009,8 @@ ur_result_t UR_APICALL urEnqueueUSMAdvise( /// - ::UR_RESULT_ERROR_UNSUPPORTED_FEATURE ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. - void *pMem, ///< [in] pointer to memory to be filled. + void * + pMem, ///< [in][bounds(0, pitch * height)] pointer to memory to be filled. size_t pitch, ///< [in] the total width of the destination memory including padding. size_t @@ -5049,10 +5068,13 @@ ur_result_t UR_APICALL urEnqueueUSMFill2D( ur_result_t UR_APICALL urEnqueueUSMMemcpy2D( ur_queue_handle_t hQueue, ///< [in] handle of the queue to submit to. bool blocking, ///< [in] indicates if this operation should block the host. - void *pDst, ///< [in] pointer to memory where data will be copied. + void * + pDst, ///< [in][bounds(0, dstPitch * height)] pointer to memory where data will + ///< be copied. size_t dstPitch, ///< [in] the total width of the source memory including padding. - const void *pSrc, ///< [in] pointer to memory to be copied. + const void * + pSrc, ///< [in][bounds(0, srcPitch * height)] pointer to memory to be copied. size_t srcPitch, ///< [in] the total width of the source memory including padding. size_t width, ///< [in] the width in bytes of each row to be copied.