diff --git a/include/MMD/aocl_mmd.h b/include/MMD/aocl_mmd.h index fc7ee4b3..7fe7ef0e 100644 --- a/include/MMD/aocl_mmd.h +++ b/include/MMD/aocl_mmd.h @@ -484,7 +484,16 @@ typedef enum { * memory bank. It is invalid to specify this property without also specifying * AOCL_MMD_GLOBAL_MEMORY_INTERFACE. */ - AOCL_MMD_MEM_PROPERTIES_MEMORY_BANK + AOCL_MMD_MEM_PROPERTIES_MEMORY_BANK, + /** + * Specifies the buffer location used for USM API calls. The buffer location + * is an integer index that corresponds to a global memory location in the + * board_spec.xml file. Similar to AOCL_MMD_MEM_PROPERTIES_GLOBAL_MEMORY. + * The buffer location value may not have been validated by the OpenCL + * runtime, so it is the responsibility of the MMD layer to ensure the value + * is valid. + */ + AOCL_MMD_MEM_PROPERTIES_BUFFER_LOCATION } aocl_mmd_mem_properties_t; /** diff --git a/include/acl_hal.h b/include/acl_hal.h index e0fb58e3..01ab084f 100644 --- a/include/acl_hal.h +++ b/include/acl_hal.h @@ -230,7 +230,8 @@ typedef struct { /// Allocates USM host memory void *(*host_alloc)(const std::vector devices, size_t size, - size_t alignment, int *error); + size_t alignment, mem_properties_t *properties, + int *error); /// Frees allocated memory by the MMD int (*free)(cl_context context, void *ptr); diff --git a/src/acl_hal_mmd.cpp b/src/acl_hal_mmd.cpp index 27fef0f6..874974b9 100644 --- a/src/acl_hal_mmd.cpp +++ b/src/acl_hal_mmd.cpp @@ -65,7 +65,8 @@ void *acl_hal_mmd_shared_alloc(cl_device_id device, size_t size, size_t alignment, mem_properties_t *properties, int *error); void *acl_hal_mmd_host_alloc(const std::vector devices, - size_t size, size_t alignment, int *error); + size_t size, size_t alignment, + mem_properties_t *properties, int *error); int acl_hal_mmd_free(cl_context context, void *mem); int acl_hal_mmd_try_devices(cl_uint num_devices, const cl_device_id *devices, cl_platform_id platform); @@ -2519,7 +2520,7 @@ void *acl_hal_mmd_legacy_shared_alloc(cl_context context, size_t size, int error = 0; std::vector devices = std::vector( context->device, context->device + context->num_devices); - void *mem = acl_hal_mmd_host_alloc(devices, size, 0, &error); + void *mem = acl_hal_mmd_host_alloc(devices, size, 0, nullptr, &error); device_ptr_out = static_cast(mem); if (error) { switch (error) { @@ -2728,7 +2729,8 @@ void *acl_hal_mmd_shared_alloc(cl_device_id device, size_t size, } void *acl_hal_mmd_host_alloc(const std::vector devices, - size_t size, size_t alignment, int *error) { + size_t size, size_t alignment, + mem_properties_t *properties, int *error) { // Note we do not support devices in the same context with different MMDs // Safe to get the mmd handle from first device void *result = NULL; @@ -2749,8 +2751,9 @@ void *acl_hal_mmd_host_alloc(const std::vector devices, handles[i] = device_info[physical_device_id].handle; } - result = dispatch->aocl_mmd_host_alloc(handles, devices.size(), size, - alignment, nullptr, error); + result = dispatch->aocl_mmd_host_alloc( + handles, devices.size(), size, alignment, + (aocl_mmd_mem_properties_t *)properties, error); acl_delete_arr(handles); if (error) { diff --git a/src/acl_usm.cpp b/src/acl_usm.cpp index 94b8c6b4..211e86f5 100644 --- a/src/acl_usm.cpp +++ b/src/acl_usm.cpp @@ -3,9 +3,11 @@ // System headers. #include +#include #include #include #include +#include #include #include #include @@ -28,6 +30,8 @@ #include #include +#include + #ifdef __GNUC__ #pragma GCC visibility push(protected) #endif @@ -99,11 +103,15 @@ CL_API_ENTRY void *CL_API_CALL clHostMemAllocINTEL( // Iterate over properties. // The end of the properties list is specified with a zero. cl_mem_alloc_flags_intel alloc_flags = 0; + std::optional mem_id; while (properties != NULL && *properties != 0) { switch (*properties) { case CL_MEM_ALLOC_FLAGS_INTEL: { alloc_flags = *(properties + 1); } break; + case CL_MEM_ALLOC_BUFFER_LOCATION_INTEL: { + mem_id = (cl_uint) * (properties + 1); + } break; default: { UNLOCK_BAIL_INFO(CL_INVALID_PROPERTY, context, "Invalid properties"); } @@ -138,6 +146,16 @@ CL_API_ENTRY void *CL_API_CALL clHostMemAllocINTEL( } if (acl_get_hal()->host_alloc) { + std::array mmd_properties; + { + auto mmd_properties_it = mmd_properties.begin(); + if (mem_id) { + *mmd_properties_it++ = AOCL_MMD_MEM_PROPERTIES_BUFFER_LOCATION; + *mmd_properties_it++ = *mem_id; + } + *mmd_properties_it++ = 0; + } + acl_usm_allocation_t *usm_alloc = (acl_usm_allocation_t *)acl_malloc(sizeof(acl_usm_allocation_t)); @@ -146,7 +164,8 @@ CL_API_ENTRY void *CL_API_CALL clHostMemAllocINTEL( } int error = 0; - void *mem = acl_get_hal()->host_alloc(devices, size, alignment, &error); + void *mem = acl_get_hal()->host_alloc(devices, size, alignment, + mmd_properties.data(), &error); if (error) { acl_free(usm_alloc); switch (error) { @@ -380,6 +399,7 @@ clSharedMemAllocINTEL(cl_context context, cl_device_id device, // The end of the properties list is specified with a zero. cl_mem_alloc_flags_intel alloc_flags = 0; std::unordered_set seen_flags; + std::optional mem_id; while (properties != NULL && *properties != 0) { switch (*properties) { case CL_MEM_ALLOC_FLAGS_INTEL: { @@ -396,6 +416,14 @@ clSharedMemAllocINTEL(cl_context context, cl_device_id device, } alloc_flags = *(properties + 1); } break; + case CL_MEM_ALLOC_BUFFER_LOCATION_INTEL: { + if (seen_flags.insert(CL_MEM_ALLOC_BUFFER_LOCATION_INTEL).second == + false) { + UNLOCK_BAIL_INFO(CL_INVALID_PROPERTY, context, + "Property specified multiple times"); + } + mem_id = (cl_uint) * (properties + 1); + } break; default: { UNLOCK_BAIL_INFO(CL_INVALID_PROPERTY, context, "Invalid properties"); } @@ -404,6 +432,16 @@ clSharedMemAllocINTEL(cl_context context, cl_device_id device, } if (acl_get_hal()->shared_alloc) { + std::array mmd_properties; + { + auto mmd_properties_it = mmd_properties.begin(); + if (mem_id) { + *mmd_properties_it++ = AOCL_MMD_MEM_PROPERTIES_BUFFER_LOCATION; + *mmd_properties_it++ = *mem_id; + } + *mmd_properties_it++ = 0; + } + acl_usm_allocation_t *usm_alloc = (acl_usm_allocation_t *)acl_malloc(sizeof(acl_usm_allocation_t)); @@ -412,8 +450,8 @@ clSharedMemAllocINTEL(cl_context context, cl_device_id device, } int error; - void *mem = - acl_get_hal()->shared_alloc(device, size, alignment, nullptr, &error); + void *mem = acl_get_hal()->shared_alloc(device, size, alignment, + mmd_properties.data(), &error); if (mem == NULL) { acl_free(usm_alloc); switch (error) { diff --git a/test/acl_hal_test.cpp b/test/acl_hal_test.cpp index 03f752ab..266a9cd1 100644 --- a/test/acl_hal_test.cpp +++ b/test/acl_hal_test.cpp @@ -91,7 +91,8 @@ void *acl_test_hal_shared_alloc(cl_device_id device, size_t size, size_t alignment, mem_properties_t *properties, int *error); void *acl_test_hal_host_alloc(const std::vector devices, - size_t size, size_t alignment, int *error); + size_t size, size_t alignment, + mem_properties_t *properties, int *error); int acl_test_hal_free(cl_context context, void *ptr); static acl_event_update_callback acltest_hal_event_callback = NULL; @@ -661,11 +662,8 @@ void *acl_test_hal_shared_alloc(cl_device_id device, size_t size, return (void *)0xdeadbeefdeadbeef; } -void *acl_test_hal_host_alloc(const std::vector devices, - size_t size, size_t alignment, int *error) { - size = size; - alignment = alignment; - error = error; +void *acl_test_hal_host_alloc(const std::vector, size_t, size_t, + mem_properties_t *, int *) { return (void *)0xdeadbeefdeadbeef; }