Skip to content

Commit

Permalink
Limit buffers sizes to leave some memory for the platform
Browse files Browse the repository at this point in the history
Some conformance tests use directly the size returned by the runtime
for max memory size to allocate buffers.
This doesn't leave enough memory for the system to run the tests.

Change-Id: I34e88d63f9b811d5ed5058fd469d8a8c4454a465
  • Loading branch information
ouakheli authored and ahesham-arm committed Jun 17, 2024
1 parent d379b58 commit 10816f8
Show file tree
Hide file tree
Showing 10 changed files with 896 additions and 633 deletions.
39 changes: 39 additions & 0 deletions test_common/harness/deviceInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,42 @@ size_t get_max_param_size(cl_device_id device)
}
return ret;
}

static cl_ulong get_device_info_max_size(cl_device_id device,
cl_device_info info,
unsigned int divisor)
{
cl_ulong max_size;

if (divisor == 0)
{
throw std::runtime_error("Allocation divisor should not be 0\n");
}

if (clGetDeviceInfo(device, info, sizeof(max_size), &max_size, NULL)
!= CL_SUCCESS)
{
throw std::runtime_error("clGetDeviceInfo failed\n");
}
return max_size / divisor;
}

cl_ulong get_device_info_max_mem_alloc_size(cl_device_id device,
unsigned int divisor)
{
return get_device_info_max_size(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
divisor);
}

cl_ulong get_device_info_global_mem_size(cl_device_id device,
unsigned int divisor)
{
return get_device_info_max_size(device, CL_DEVICE_GLOBAL_MEM_SIZE, divisor);
}

cl_ulong get_device_info_max_constant_buffer_size(cl_device_id device,
unsigned int divisor)
{
return get_device_info_max_size(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,
divisor);
}
12 changes: 12 additions & 0 deletions test_common/harness/deviceInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,16 @@ std::string get_device_name(cl_device_id device);
// Returns the maximum size in bytes for Kernel Parameters
size_t get_max_param_size(cl_device_id device);

/* We need to use a portion of available alloc size,
* divide it to leave some memory for the platform. */
#define MAX_DEVICE_MEMORY_SIZE_DIVISOR (2)

/* Get max allocation size. */
cl_ulong get_device_info_max_mem_alloc_size(cl_device_id device,
unsigned int divisor = 1);
cl_ulong get_device_info_global_mem_size(cl_device_id device,
unsigned int divisor = 1);
cl_ulong get_device_info_max_constant_buffer_size(cl_device_id device,
unsigned int divisor = 1);

#endif // _deviceInfo_h
191 changes: 91 additions & 100 deletions test_conformance/allocations/allocation_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,27 +188,15 @@ int allocate_size(cl_context context, cl_command_queue *queue,
// one we don't end up returning a garbage value
*number_of_mems = 0;

error = clGetDeviceInfo(device_id, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
sizeof(max_individual_allocation_size),
&max_individual_allocation_size, NULL);
test_error_abort(error,
"clGetDeviceInfo failed for CL_DEVICE_MAX_MEM_ALLOC_SIZE");
error = clGetDeviceInfo(device_id, CL_DEVICE_GLOBAL_MEM_SIZE,
sizeof(global_mem_size), &global_mem_size, NULL);
test_error_abort(error,
"clGetDeviceInfo failed for CL_DEVICE_GLOBAL_MEM_SIZE");
max_individual_allocation_size =
get_device_info_max_mem_alloc_size(device_id);
global_mem_size = get_device_info_global_mem_size(device_id);

if (global_mem_size > (cl_ulong)SIZE_MAX)
{
global_mem_size = (cl_ulong)SIZE_MAX;
}

// log_info("Device reports CL_DEVICE_MAX_MEM_ALLOC_SIZE=%llu bytes (%gMB),
// CL_DEVICE_GLOBAL_MEM_SIZE=%llu bytes (%gMB).\n",
// max_individual_allocation_size,
// toMB(max_individual_allocation_size), global_mem_size,
// toMB(global_mem_size));

if (size_to_allocate > global_mem_size)
{
log_error("Can not allocate more than the global memory size.\n");
Expand Down Expand Up @@ -281,112 +269,115 @@ int allocate_size(cl_context context, cl_command_queue *queue,
(int)max_image_args);
max_to_allocate = max_image_args;
}
}


// Try to allocate the requested amount.
while (amount_allocated != size_to_allocate
&& current_allocation < max_to_allocate)
{

// Determine how much more is needed
allocation_this_time = size_to_allocate - amount_allocated;
// Try to allocate the requested amount.
while (amount_allocated != size_to_allocate
&& current_allocation < max_to_allocate)
{

// Bound by the individual allocation size
if (allocation_this_time > max_individual_allocation_size)
allocation_this_time = (size_t)max_individual_allocation_size;
// Determine how much more is needed
allocation_this_time = size_to_allocate - amount_allocated;

// Allocate the largest object possible
result = FAILED_TOO_BIG;
// log_info("\t\tTrying sub-allocation %d at size %gMB.\n",
// current_allocation, toMB(allocation_this_time));
while (result == FAILED_TOO_BIG && allocation_this_time != 0)
{
// Bound by the individual allocation size
if (allocation_this_time > max_individual_allocation_size)
allocation_this_time = (size_t)max_individual_allocation_size;

// Create the object
result =
do_allocation(context, queue, device_id, allocation_this_time,
type, &mems[current_allocation]);
if (result == SUCCEEDED)
// Allocate the largest object possible
result = FAILED_TOO_BIG;
// log_info("\t\tTrying sub-allocation %d at size %gMB.\n",
// current_allocation, toMB(allocation_this_time));
while (result == FAILED_TOO_BIG && allocation_this_time != 0)
{
// Allocation succeeded, another memory object was added to the
// array
*number_of_mems = (current_allocation + 1);

// Verify the size is correct to within 1MB.
actual_allocation =
get_actual_allocation_size(mems[current_allocation]);
if (fabs((double)allocation_this_time
- (double)actual_allocation)
> 1024.0 * 1024.0)

// Create the object
result = do_allocation(context, queue, device_id,
allocation_this_time, type,
&mems[current_allocation]);
if (result == SUCCEEDED)
{
log_error("Allocation not of expected size. Expected %gMB, "
"got %gMB.\n",
toMB(allocation_this_time),
toMB(actual_allocation));
return FAILED_ABORT;
// Allocation succeeded, another memory object was added to
// the array
*number_of_mems = (current_allocation + 1);

// Verify the size is correct to within 1MB.
actual_allocation =
get_actual_allocation_size(mems[current_allocation]);
if (fabs((double)allocation_this_time
- (double)actual_allocation)
> 1024.0 * 1024.0)
{
log_error(
"Allocation not of expected size. Expected %gMB, "
"got %gMB.\n",
toMB(allocation_this_time),
toMB(actual_allocation));
return FAILED_ABORT;
}

// If we are filling the allocation for verification do so
if (force_fill)
{
// log_info("\t\t\tWriting random values to object and
// calculating checksum.\n");
cl_bool blocking_write = true;
if (type == BUFFER_NON_BLOCKING
|| type == IMAGE_READ_NON_BLOCKING
|| type == IMAGE_WRITE_NON_BLOCKING)
{
blocking_write = false;
}
result = fill_mem_with_data(context, device_id, queue,
mems[current_allocation], d,
blocking_write);
}
}

// If we are filling the allocation for verification do so
if (force_fill)
// If creation failed, try to create a smaller object
if (result == FAILED_TOO_BIG)
{
// log_info("\t\t\tWriting random values to object and
// calculating checksum.\n");
cl_bool blocking_write = true;
if (type == BUFFER_NON_BLOCKING
|| type == IMAGE_READ_NON_BLOCKING
|| type == IMAGE_WRITE_NON_BLOCKING)
// log_info("\t\t\tAllocation %d failed at size %gMB. Trying
// smaller.\n", current_allocation,
// toMB(allocation_this_time));
if (allocation_this_time > reduction_amount)
allocation_this_time -= reduction_amount;
else if (reduction_amount > 1)
{
blocking_write = false;
reduction_amount /= 2;
}
else
{
allocation_this_time = 0;
}
result = fill_mem_with_data(context, device_id, queue,
mems[current_allocation], d,
blocking_write);
}
}

// If creation failed, try to create a smaller object
if (result == FAILED_TOO_BIG)
if (result == FAILED_ABORT)
{
// log_info("\t\t\tAllocation %d failed at size %gMB. Trying
// smaller.\n", current_allocation, toMB(allocation_this_time));
if (allocation_this_time > reduction_amount)
allocation_this_time -= reduction_amount;
else if (reduction_amount > 1)
{
reduction_amount /= 2;
}
else
{
allocation_this_time = 0;
}
log_error("\t\tAllocation failed.\n");
return FAILED_ABORT;
}
}

if (result == FAILED_ABORT)
{
log_error("\t\tAllocation failed.\n");
return FAILED_ABORT;
}

if (!allocation_this_time)
{
log_info("\t\tFailed to allocate %gMB across several objects.\n",
toMB(size_to_allocate));
return FAILED_TOO_BIG;
}
if (!allocation_this_time)
{
log_info(
"\t\tFailed to allocate %gMB across several objects.\n",
toMB(size_to_allocate));
return FAILED_TOO_BIG;
}

// Otherwise we succeeded
if (result != SUCCEEDED)
{
log_error("Test logic error.");
exit(-1);
}
amount_allocated += allocation_this_time;
// Otherwise we succeeded
if (result != SUCCEEDED)
{
log_error("Test logic error.");
exit(-1);
}
amount_allocated += allocation_this_time;

*final_size = amount_allocated;
*final_size = amount_allocated;

current_allocation++;
current_allocation++;
}
}

log_info("\t\tSucceeded in allocating %gMB using %d memory objects.\n",
Expand Down
25 changes: 6 additions & 19 deletions test_conformance/allocations/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@

typedef long long unsigned llu;

#define REDUCTION_PERCENTAGE_DEFAULT 50

int g_repetition_count = 1;
int g_reduction_percentage = 100;
int g_reduction_percentage = REDUCTION_PERCENTAGE_DEFAULT;
int g_write_allocations = 1;
int g_multiple_allocations = 0;
int g_execute_kernel = 1;
Expand All @@ -44,24 +46,9 @@ test_status init_cl(cl_device_id device)
{
int error;

error = clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE,
sizeof(g_max_individual_allocation_size),
&g_max_individual_allocation_size, NULL);
if (error)
{
print_error(error,
"clGetDeviceInfo failed for CL_DEVICE_MAX_MEM_ALLOC_SIZE");
return TEST_FAIL;
}
error =
clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE,
sizeof(g_global_mem_size), &g_global_mem_size, NULL);
if (error)
{
print_error(error,
"clGetDeviceInfo failed for CL_DEVICE_GLOBAL_MEM_SIZE");
return TEST_FAIL;
}
g_max_individual_allocation_size =
get_device_info_max_mem_alloc_size(device);
g_global_mem_size = get_device_info_global_mem_size(device);

log_info("Device reports CL_DEVICE_MAX_MEM_ALLOC_SIZE=%llu bytes (%gMB), "
"CL_DEVICE_GLOBAL_MEM_SIZE=%llu bytes (%gMB).\n",
Expand Down
Loading

0 comments on commit 10816f8

Please sign in to comment.