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.
  • Loading branch information
ouakheli committed May 24, 2021
1 parent ba9312e commit 743a633
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 103 deletions.
39 changes: 39 additions & 0 deletions test_common/harness/deviceInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,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 @@ -46,4 +46,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
11 changes: 3 additions & 8 deletions test_conformance/allocations/allocation_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,19 +141,14 @@ int allocate_size(cl_context context, cl_command_queue *queue, cl_device_id devi
// Set the number of mems used to 0 so if we fail to create even a single 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");
return FAILED_ABORT;
Expand Down
19 changes: 9 additions & 10 deletions test_conformance/allocations/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,9 @@ static void printUsage( const char *execName );
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",
llu( g_max_individual_allocation_size ), toMB( g_max_individual_allocation_size ),
Expand Down Expand Up @@ -94,6 +87,12 @@ test_status init_cl( cl_device_id device ) {
g_global_mem_size *= 0.60;
}

/* Cap the allocation size as the global size was deduced */
if (g_max_individual_allocation_size > g_global_mem_size)
{
g_max_individual_allocation_size = g_global_mem_size;
}

if( gReSeed )
{
g_seed = RandomSeed( gRandomSeed );
Expand Down
109 changes: 51 additions & 58 deletions test_conformance/api/test_api_min_max.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ const char *sample_const_max_arg_kernel_pattern =
"\n"
"}\n";

#define PASSING_FRACTION 4

int test_min_max_thread_dimensions(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
int error, retVal;
Expand Down Expand Up @@ -481,7 +483,7 @@ int test_min_max_write_image_args(cl_device_id deviceID, cl_context context, cl_
int test_min_max_mem_alloc_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
int error;
cl_ulong maxAllocSize, memSize, minSizeToTry;
cl_ulong maxAllocSize, memSize, minSizeToTry, currentSize;
clMemWrapper memHdl;

cl_ulong requiredAllocSize;
Expand All @@ -491,47 +493,40 @@ int test_min_max_mem_alloc_size(cl_device_id deviceID, cl_context context, cl_co
else
requiredAllocSize = 128 * 1024 * 1024;

/* Get the max mem alloc size */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof( maxAllocSize ), &maxAllocSize, NULL );
test_error( error, "Unable to get max mem alloc size from device" );
/* Get the max mem alloc size, limit the alloc to half of the available
* memory */
maxAllocSize = get_device_info_max_mem_alloc_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
memSize = get_device_info_global_mem_size(deviceID,
MAX_DEVICE_MEMORY_SIZE_DIVISOR);

error = clGetDeviceInfo( deviceID, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof( memSize ), &memSize, NULL );
test_error( error, "Unable to get global memory size from device" );
if (memSize < maxAllocSize)
{
log_info("Global memory size is less than max allocation size, using "
"that.\n");
maxAllocSize = memSize;
}

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

if( maxAllocSize < requiredAllocSize)
if ((0 == gIsEmbedded && maxAllocSize < 128 * 1024 * 1024)
|| maxAllocSize < 1 * 1024 * 1024)
{
log_error( "ERROR: Reported max allocation size is less than required %lldMB! (%llu or %lluMB, from a total mem size of %lldMB)\n", (requiredAllocSize / 1024) / 1024, maxAllocSize, (maxAllocSize / 1024)/1024, (memSize / 1024)/1024 );
log_error("ERROR: Reported max allocation size is less than required");
return -1;
}

requiredAllocSize = ((memSize / 4) > (1024 * 1024 * 1024)) ? 1024 * 1024 * 1024 : memSize / 4;

if (gIsEmbedded)
requiredAllocSize = (requiredAllocSize < 1 * 1024 * 1024) ? 1 * 1024 * 1024 : requiredAllocSize;
else
requiredAllocSize = (requiredAllocSize < 128 * 1024 * 1024) ? 128 * 1024 * 1024 : requiredAllocSize;

if( maxAllocSize < requiredAllocSize )
{
log_error( "ERROR: Reported max allocation size is less than required of total memory! (%llu or %lluMB, from a total mem size of %lluMB)\n", maxAllocSize, (maxAllocSize / 1024)/1024, (requiredAllocSize / 1024)/1024 );
return -1;
}

log_info("Reported max allocation size of %lld bytes (%gMB) and global mem size of %lld bytes (%gMB).\n",
maxAllocSize, maxAllocSize/(1024.0*1024.0), requiredAllocSize, requiredAllocSize/(1024.0*1024.0));

if ( memSize < maxAllocSize ) {
log_info("Global memory size is less than max allocation size, using that.\n");
maxAllocSize = memSize;
}
log_info("Reported max allocation size of %lld bytes (%gMB) and global mem "
"size of %lld bytes (%gMB).\n",
maxAllocSize, maxAllocSize / (1024.0 * 1024.0), memSize,
memSize / (1024.0 * 1024.0));

minSizeToTry = maxAllocSize/16;
while (maxAllocSize > (maxAllocSize/4)) {

currentSize = maxAllocSize;
while (currentSize >= maxAllocSize / PASSING_FRACTION)
{
log_info("Trying to create a buffer of size of %lld bytes (%gMB).\n", maxAllocSize, (double)maxAllocSize/(1024.0*1024.0));
memHdl = clCreateBuffer( context, CL_MEM_READ_ONLY, (size_t)maxAllocSize, NULL, &error );
if (error == CL_MEM_OBJECT_ALLOCATION_FAILURE || error == CL_OUT_OF_RESOURCES || error == CL_OUT_OF_HOST_MEMORY) {
Expand Down Expand Up @@ -594,8 +589,8 @@ int test_min_max_image_2d_width(cl_device_id deviceID, cl_context context, cl_co
}

/* Verify that we can actually allocate an image that large */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof ( maxAllocSize ), &maxAllocSize, NULL );
test_error( error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE." );
maxAllocSize = get_device_info_max_mem_alloc_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
if ( (cl_ulong)maxDimension*1*4 > maxAllocSize ) {
log_error("Can not allocate a large enough image (min size: %lld bytes, max allowed: %lld bytes) to test.\n",
(cl_ulong)maxDimension*1*4, maxAllocSize);
Expand Down Expand Up @@ -661,8 +656,8 @@ int test_min_max_image_2d_height(cl_device_id deviceID, cl_context context, cl_c
}

/* Verify that we can actually allocate an image that large */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof ( maxAllocSize ), &maxAllocSize, NULL );
test_error( error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE." );
maxAllocSize = get_device_info_max_mem_alloc_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
if ( (cl_ulong)maxDimension*1*4 > maxAllocSize ) {
log_error("Can not allocate a large enough image (min size: %lld bytes, max allowed: %lld bytes) to test.\n",
(cl_ulong)maxDimension*1*4, maxAllocSize);
Expand Down Expand Up @@ -718,8 +713,8 @@ int test_min_max_image_3d_width(cl_device_id deviceID, cl_context context, cl_co
}

/* Verify that we can actually allocate an image that large */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof ( maxAllocSize ), &maxAllocSize, NULL );
test_error( error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE." );
maxAllocSize = get_device_info_max_mem_alloc_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
if ( (cl_ulong)maxDimension*2*4 > maxAllocSize ) {
log_error("Can not allocate a large enough image (min size: %lld bytes, max allowed: %lld bytes) to test.\n",
(cl_ulong)maxDimension*2*4, maxAllocSize);
Expand Down Expand Up @@ -775,8 +770,8 @@ int test_min_max_image_3d_height(cl_device_id deviceID, cl_context context, cl_c
}

/* Verify that we can actually allocate an image that large */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof ( maxAllocSize ), &maxAllocSize, NULL );
test_error( error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE." );
maxAllocSize = get_device_info_max_mem_alloc_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
if ( (cl_ulong)maxDimension*2*4 > maxAllocSize ) {
log_error("Can not allocate a large enough image (min size: %lld bytes, max allowed: %lld bytes) to test.\n",
(cl_ulong)maxDimension*2*4, maxAllocSize);
Expand Down Expand Up @@ -833,8 +828,8 @@ int test_min_max_image_3d_depth(cl_device_id deviceID, cl_context context, cl_co
}

/* Verify that we can actually allocate an image that large */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof ( maxAllocSize ), &maxAllocSize, NULL );
test_error( error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE." );
maxAllocSize = get_device_info_max_mem_alloc_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
if ( (cl_ulong)maxDimension*1*4 > maxAllocSize ) {
log_error("Can not allocate a large enough image (min size: %lld bytes, max allowed: %lld bytes) to test.\n",
(cl_ulong)maxDimension*1*4, maxAllocSize);
Expand Down Expand Up @@ -889,8 +884,8 @@ int test_min_max_image_array_size(cl_device_id deviceID, cl_context context, cl_
}

/* Verify that we can actually allocate an image that large */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof ( maxAllocSize ), &maxAllocSize, NULL );
test_error( error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE." );
maxAllocSize = get_device_info_max_mem_alloc_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
if ( (cl_ulong)maxDimension*1*4 > maxAllocSize ) {
log_error("Can not allocate a large enough image (min size: %lld bytes, max allowed: %lld bytes) to test.\n",
(cl_ulong)maxDimension*1*4, maxAllocSize);
Expand Down Expand Up @@ -923,9 +918,9 @@ int test_min_max_image_buffer_size(cl_device_id deviceID, cl_context context, cl

PASSIVE_REQUIRE_IMAGE_SUPPORT( deviceID );

/* Get the max memory allocation size */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof ( maxAllocSize ), &maxAllocSize, NULL );
test_error( error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE." );
/* Get the max memory allocation size, divide it */
maxAllocSize = get_device_info_max_mem_alloc_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);

/* Get the max image array width */
error = clGetDeviceInfo( deviceID, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE, sizeof( maxDimensionPixels ), &maxDimensionPixels, NULL );
Expand Down Expand Up @@ -1288,7 +1283,6 @@ int test_min_max_samplers(cl_device_id deviceID, cl_context context, cl_command_
return 0;
}

#define PASSING_FRACTION 4
int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements)
{
int error;
Expand All @@ -1303,8 +1297,8 @@ int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context,
MTdata d;

/* Verify our test buffer won't be bigger than allowed */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof( maxSize ), &maxSize, 0 );
test_error( error, "Unable to get max constant buffer size" );
maxSize = get_device_info_max_constant_buffer_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);

if( ( 0 == gIsEmbedded && maxSize < 64L * 1024L ) || maxSize < 1L * 1024L )
{
Expand All @@ -1314,16 +1308,15 @@ int test_min_max_constant_buffer_size(cl_device_id deviceID, cl_context context,

log_info("Reported max constant buffer size of %lld bytes.\n", maxSize);

// Limit test buffer size to 1/8 of CL_DEVICE_GLOBAL_MEM_SIZE
error = clGetDeviceInfo(deviceID, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(maxGlobalSize), &maxGlobalSize, 0);
test_error(error, "Unable to get CL_DEVICE_GLOBAL_MEM_SIZE");
/* We have four buffers allocations */
maxGlobalSize = get_device_info_global_mem_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR * 4);

if (maxSize > maxGlobalSize / 8)
maxSize = maxGlobalSize / 8;
if (maxSize > maxGlobalSize) maxSize = maxGlobalSize;

maxAllocSize = get_device_info_max_mem_alloc_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);

error = clGetDeviceInfo(deviceID, CL_DEVICE_MAX_MEM_ALLOC_SIZE , sizeof(maxAllocSize), &maxAllocSize, 0);
test_error(error, "Unable to get CL_DEVICE_MAX_MEM_ALLOC_SIZE ");

if (maxSize > maxAllocSize)
maxSize = maxAllocSize;

Expand Down Expand Up @@ -1487,8 +1480,8 @@ int test_min_max_constant_args(cl_device_id deviceID, cl_context context, cl_com
return -1;
}

error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof( maxSize ), &maxSize, 0 );
test_error( error, "Unable to get max constant buffer size" );
maxSize = get_device_info_max_constant_buffer_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
individualBufferSize = ((int)maxSize/2)/maxArgs;

log_info("Reported max constant arg count of %d and max constant buffer size of %d. Test will attempt to allocate half of that, or %d buffers of size %d.\n",
Expand Down
4 changes: 2 additions & 2 deletions test_conformance/api/test_kernels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,8 @@ int test_set_kernel_arg_constant(cl_device_id deviceID, cl_context context, cl_c
std::vector<cl_int> randomTestDataB(num_elements);

/* Verify our test buffer won't be bigger than allowed */
error = clGetDeviceInfo( deviceID, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof( maxSize ), &maxSize, 0 );
test_error( error, "Unable to get max constant buffer size" );
maxSize = get_device_info_max_constant_buffer_size(
deviceID, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
if (maxSize < sizeof(cl_int) * num_elements)
{
log_error( "ERROR: Unable to test constant argument to kernel: max size of constant buffer is reported as %d!\n", (int)maxSize );
Expand Down
15 changes: 10 additions & 5 deletions test_conformance/images/clGetInfo/test_1D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,18 @@ int test_get_image_info_1D( cl_device_id device, cl_context context, cl_image_fo
pixelSize = get_pixel_size( imageInfo.format );

int error = clGetDeviceInfo( device, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof( maxWidth ), &maxWidth, NULL );
error |= clGetDeviceInfo( device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof( maxAllocSize ), &maxAllocSize, NULL );
error |= clGetDeviceInfo( device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof( memSize ), &memSize, NULL );
test_error( error, "Unable to get max image 1D size from device" );

if (memSize > (cl_ulong)SIZE_MAX) {
memSize = (cl_ulong)SIZE_MAX;
}
/* Reduce the size used by the test by half */
maxAllocSize = get_device_info_max_mem_alloc_size(
device, MAX_DEVICE_MEMORY_SIZE_DIVISOR);
memSize =
get_device_info_global_mem_size(device, MAX_DEVICE_MEMORY_SIZE_DIVISOR);

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

if( gTestSmallImages )
{
Expand Down
Loading

0 comments on commit 743a633

Please sign in to comment.