mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
test allocations: restore small number of work items in case of reduction (#1932)
This commit is contained in:
committed by
GitHub
parent
4fceb78b93
commit
b377b8537b
@@ -1,6 +1,6 @@
|
||||
//
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
//
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
@@ -17,273 +17,379 @@
|
||||
#include "allocation_fill.h"
|
||||
|
||||
|
||||
static cl_image_format image_format = { CL_RGBA, CL_UNSIGNED_INT32 };
|
||||
static cl_image_format image_format = { CL_RGBA, CL_UNSIGNED_INT32 };
|
||||
|
||||
int allocate_buffer(cl_context context, cl_command_queue *queue, cl_device_id device_id, cl_mem *mem, size_t size_to_allocate, cl_bool blocking_write) {
|
||||
int error;
|
||||
// log_info("\t\tAttempting to allocate a %gMB array and fill with %s writes.\n", (size_to_allocate/(1024.0*1024.0)), (blocking_write ? "blocking" : "non-blocking"));
|
||||
*mem = clCreateBuffer(context, CL_MEM_READ_WRITE, size_to_allocate, NULL, &error);
|
||||
return check_allocation_error(context, device_id, error, queue);
|
||||
int allocate_buffer(cl_context context, cl_command_queue *queue,
|
||||
cl_device_id device_id, cl_mem *mem,
|
||||
size_t size_to_allocate, cl_bool blocking_write)
|
||||
{
|
||||
int error;
|
||||
// log_info("\t\tAttempting to allocate a %gMB array and fill with %s
|
||||
// writes.\n", (size_to_allocate/(1024.0*1024.0)), (blocking_write ?
|
||||
// "blocking" : "non-blocking"));
|
||||
*mem = clCreateBuffer(context, CL_MEM_READ_WRITE, size_to_allocate, NULL,
|
||||
&error);
|
||||
return check_allocation_error(context, device_id, error, queue);
|
||||
}
|
||||
|
||||
|
||||
int find_good_image_size(cl_device_id device_id, size_t size_to_allocate, size_t *width, size_t *height, size_t* max_size) {
|
||||
size_t max_width, max_height, num_pixels, found_width, found_height;
|
||||
int error;
|
||||
int find_good_image_size(cl_device_id device_id, size_t size_to_allocate,
|
||||
size_t *width, size_t *height, size_t *max_size)
|
||||
{
|
||||
size_t max_width, max_height, num_pixels, found_width, found_height;
|
||||
int error;
|
||||
|
||||
if (checkForImageSupport(device_id)) {
|
||||
log_info("Can not allocate an image on this device because it does not support images.");
|
||||
return FAILED_ABORT;
|
||||
}
|
||||
|
||||
if (size_to_allocate == 0) {
|
||||
log_error("Trying to allocate a zero sized image.\n");
|
||||
return FAILED_ABORT;
|
||||
}
|
||||
|
||||
error = clGetDeviceInfo( device_id, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof( max_width ), &max_width, NULL );
|
||||
test_error_abort(error, "clGetDeviceInfo failed.");
|
||||
error = clGetDeviceInfo( device_id, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof( max_height ), &max_height, NULL );
|
||||
test_error_abort(error, "clGetDeviceInfo failed.");
|
||||
|
||||
num_pixels = size_to_allocate / (sizeof(cl_uint)*4);
|
||||
|
||||
// Use a 64-bit variable to avoid overflow in 32-bit architectures
|
||||
long long unsigned max_pixels = (long long unsigned)max_width * max_height;
|
||||
|
||||
if (num_pixels > max_pixels) {
|
||||
if(NULL != max_size) {
|
||||
*max_size = max_width * max_height * sizeof(cl_uint) * 4;
|
||||
if (checkForImageSupport(device_id))
|
||||
{
|
||||
log_info("Can not allocate an image on this device because it does not "
|
||||
"support images.");
|
||||
return FAILED_ABORT;
|
||||
}
|
||||
return FAILED_TOO_BIG;
|
||||
}
|
||||
|
||||
// We want a close-to-square aspect ratio.
|
||||
// Note that this implicitly assumes that max width >= max height
|
||||
found_width = (int)sqrt( (double) num_pixels );
|
||||
if( found_width > max_width ) {
|
||||
found_width = max_width;
|
||||
}
|
||||
if (found_width == 0)
|
||||
found_width = 1;
|
||||
if (size_to_allocate == 0)
|
||||
{
|
||||
log_error("Trying to allocate a zero sized image.\n");
|
||||
return FAILED_ABORT;
|
||||
}
|
||||
|
||||
found_height = (size_t)num_pixels/found_width;
|
||||
if (found_height > max_height) {
|
||||
found_height = max_height;
|
||||
}
|
||||
if (found_height == 0)
|
||||
found_height = 1;
|
||||
error = clGetDeviceInfo(device_id, CL_DEVICE_IMAGE2D_MAX_WIDTH,
|
||||
sizeof(max_width), &max_width, NULL);
|
||||
test_error_abort(error, "clGetDeviceInfo failed.");
|
||||
error = clGetDeviceInfo(device_id, CL_DEVICE_IMAGE2D_MAX_HEIGHT,
|
||||
sizeof(max_height), &max_height, NULL);
|
||||
test_error_abort(error, "clGetDeviceInfo failed.");
|
||||
|
||||
*width = found_width;
|
||||
*height = found_height;
|
||||
num_pixels = size_to_allocate / (sizeof(cl_uint) * 4);
|
||||
|
||||
if(NULL != max_size) {
|
||||
*max_size = found_width * found_height * sizeof(cl_uint) * 4;
|
||||
}
|
||||
// Use a 64-bit variable to avoid overflow in 32-bit architectures
|
||||
long long unsigned max_pixels = (long long unsigned)max_width * max_height;
|
||||
|
||||
return SUCCEEDED;
|
||||
if (num_pixels > max_pixels)
|
||||
{
|
||||
if (NULL != max_size)
|
||||
{
|
||||
*max_size = max_width * max_height * sizeof(cl_uint) * 4;
|
||||
}
|
||||
return FAILED_TOO_BIG;
|
||||
}
|
||||
|
||||
// We want a close-to-square aspect ratio.
|
||||
// Note that this implicitly assumes that max width >= max height
|
||||
found_width = (int)sqrt((double)num_pixels);
|
||||
if (found_width > max_width)
|
||||
{
|
||||
found_width = max_width;
|
||||
}
|
||||
if (found_width == 0) found_width = 1;
|
||||
|
||||
found_height = (size_t)num_pixels / found_width;
|
||||
if (found_height > max_height)
|
||||
{
|
||||
found_height = max_height;
|
||||
}
|
||||
if (found_height == 0) found_height = 1;
|
||||
|
||||
*width = found_width;
|
||||
*height = found_height;
|
||||
|
||||
if (NULL != max_size)
|
||||
{
|
||||
*max_size = found_width * found_height * sizeof(cl_uint) * 4;
|
||||
}
|
||||
|
||||
return SUCCEEDED;
|
||||
}
|
||||
|
||||
|
||||
int allocate_image2d_read(cl_context context, cl_command_queue *queue, cl_device_id device_id, cl_mem *mem, size_t size_to_allocate, cl_bool blocking_write) {
|
||||
size_t width, height;
|
||||
int error;
|
||||
int allocate_image2d_read(cl_context context, cl_command_queue *queue,
|
||||
cl_device_id device_id, cl_mem *mem,
|
||||
size_t size_to_allocate, cl_bool blocking_write)
|
||||
{
|
||||
size_t width, height;
|
||||
int error;
|
||||
|
||||
error = find_good_image_size(device_id, size_to_allocate, &width, &height, NULL);
|
||||
if (error != SUCCEEDED)
|
||||
return error;
|
||||
error = find_good_image_size(device_id, size_to_allocate, &width, &height,
|
||||
NULL);
|
||||
if (error != SUCCEEDED) return error;
|
||||
|
||||
log_info("\t\tAttempting to allocate a %gMB read-only image (%d x %d) and fill with %s writes.\n",
|
||||
(size_to_allocate/(1024.0*1024.0)), (int)width, (int)height, (blocking_write ? "blocking" : "non-blocking"));
|
||||
*mem = create_image_2d(context, CL_MEM_READ_ONLY, &image_format, width, height, 0, NULL, &error);
|
||||
log_info("\t\tAttempting to allocate a %gMB read-only image (%d x %d) and "
|
||||
"fill with %s writes.\n",
|
||||
(size_to_allocate / (1024.0 * 1024.0)), (int)width, (int)height,
|
||||
(blocking_write ? "blocking" : "non-blocking"));
|
||||
*mem = create_image_2d(context, CL_MEM_READ_ONLY, &image_format, width,
|
||||
height, 0, NULL, &error);
|
||||
|
||||
return check_allocation_error(context, device_id, error, queue);
|
||||
return check_allocation_error(context, device_id, error, queue);
|
||||
}
|
||||
|
||||
|
||||
int allocate_image2d_write(cl_context context, cl_command_queue *queue, cl_device_id device_id, cl_mem *mem, size_t size_to_allocate, cl_bool blocking_write) {
|
||||
size_t width, height;
|
||||
int error;
|
||||
int allocate_image2d_write(cl_context context, cl_command_queue *queue,
|
||||
cl_device_id device_id, cl_mem *mem,
|
||||
size_t size_to_allocate, cl_bool blocking_write)
|
||||
{
|
||||
size_t width, height;
|
||||
int error;
|
||||
|
||||
error = find_good_image_size(device_id, size_to_allocate, &width, &height, NULL);
|
||||
if (error != SUCCEEDED)
|
||||
return error;
|
||||
error = find_good_image_size(device_id, size_to_allocate, &width, &height,
|
||||
NULL);
|
||||
if (error != SUCCEEDED) return error;
|
||||
|
||||
//log_info("\t\tAttempting to allocate a %gMB write-only image (%d x %d) and fill with %s writes.\n",
|
||||
//(size_to_allocate/(1024.0*1024.0)), (int)width, (int)height, (blocking_write ? "blocking" : "non-blocking"));
|
||||
*mem = create_image_2d(context, CL_MEM_WRITE_ONLY, &image_format, width, height, 0, NULL, &error);
|
||||
// log_info("\t\tAttempting to allocate a %gMB write-only image (%d x %d)
|
||||
// and fill with %s writes.\n", (size_to_allocate/(1024.0*1024.0)),
|
||||
//(int)width, (int)height, (blocking_write ? "blocking" : "non-blocking"));
|
||||
*mem = create_image_2d(context, CL_MEM_WRITE_ONLY, &image_format, width,
|
||||
height, 0, NULL, &error);
|
||||
|
||||
return check_allocation_error(context, device_id, error, queue);
|
||||
return check_allocation_error(context, device_id, error, queue);
|
||||
}
|
||||
|
||||
int do_allocation(cl_context context, cl_command_queue *queue, cl_device_id device_id, size_t size_to_allocate, int type, cl_mem *mem) {
|
||||
if (type == BUFFER) return allocate_buffer(context, queue, device_id, mem, size_to_allocate, true);
|
||||
if (type == IMAGE_READ) return allocate_image2d_read(context, queue, device_id, mem, size_to_allocate, true);
|
||||
if (type == IMAGE_WRITE) return allocate_image2d_write(context, queue, device_id, mem, size_to_allocate, true);
|
||||
if (type == BUFFER_NON_BLOCKING) return allocate_buffer(context, queue, device_id, mem, size_to_allocate, false);
|
||||
if (type == IMAGE_READ_NON_BLOCKING) return allocate_image2d_read(context, queue, device_id, mem, size_to_allocate, false);
|
||||
if (type == IMAGE_WRITE_NON_BLOCKING) return allocate_image2d_write(context, queue, device_id, mem, size_to_allocate, false);
|
||||
int do_allocation(cl_context context, cl_command_queue *queue,
|
||||
cl_device_id device_id, size_t size_to_allocate, int type,
|
||||
cl_mem *mem)
|
||||
{
|
||||
if (type == BUFFER)
|
||||
return allocate_buffer(context, queue, device_id, mem, size_to_allocate,
|
||||
true);
|
||||
if (type == IMAGE_READ)
|
||||
return allocate_image2d_read(context, queue, device_id, mem,
|
||||
size_to_allocate, true);
|
||||
if (type == IMAGE_WRITE)
|
||||
return allocate_image2d_write(context, queue, device_id, mem,
|
||||
size_to_allocate, true);
|
||||
if (type == BUFFER_NON_BLOCKING)
|
||||
return allocate_buffer(context, queue, device_id, mem, size_to_allocate,
|
||||
false);
|
||||
if (type == IMAGE_READ_NON_BLOCKING)
|
||||
return allocate_image2d_read(context, queue, device_id, mem,
|
||||
size_to_allocate, false);
|
||||
if (type == IMAGE_WRITE_NON_BLOCKING)
|
||||
return allocate_image2d_write(context, queue, device_id, mem,
|
||||
size_to_allocate, false);
|
||||
log_error("Invalid allocation type: %d\n", type);
|
||||
return FAILED_ABORT;
|
||||
return FAILED_ABORT;
|
||||
}
|
||||
|
||||
|
||||
int allocate_size(cl_context context, cl_command_queue *queue, cl_device_id device_id, int multiple_allocations, size_t size_to_allocate,
|
||||
int type, cl_mem mems[], int *number_of_mems, size_t *final_size, int force_fill, MTdata d) {
|
||||
int allocate_size(cl_context context, cl_command_queue *queue,
|
||||
cl_device_id device_id, int multiple_allocations,
|
||||
size_t size_to_allocate, int type, cl_mem mems[],
|
||||
int *number_of_mems, size_t *final_size, int force_fill,
|
||||
MTdata d)
|
||||
{
|
||||
|
||||
cl_ulong max_individual_allocation_size, global_mem_size;
|
||||
int error, result;
|
||||
size_t amount_allocated;
|
||||
size_t reduction_amount;
|
||||
int current_allocation;
|
||||
size_t allocation_this_time, actual_allocation;
|
||||
int error, result;
|
||||
size_t amount_allocated;
|
||||
size_t reduction_amount;
|
||||
int current_allocation;
|
||||
size_t allocation_this_time, actual_allocation;
|
||||
|
||||
// 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;
|
||||
// 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");
|
||||
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");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
amount_allocated = 0;
|
||||
current_allocation = 0;
|
||||
|
||||
// If allocating for images, reduce the maximum allocation size to the maximum image size.
|
||||
// If we don't do this, then the value of CL_DEVICE_MAX_MEM_ALLOC_SIZE / 4 can be higher
|
||||
// than the maximum image size on systems with 16GB or RAM or more. In this case, we
|
||||
// succeed in allocating an image but its size is less than CL_DEVICE_MAX_MEM_ALLOC_SIZE / 4
|
||||
// (min_allocation_allowed) and thus we fail the allocation below.
|
||||
if(type == IMAGE_READ || type == IMAGE_READ_NON_BLOCKING || type == IMAGE_WRITE || type == IMAGE_WRITE_NON_BLOCKING) {
|
||||
size_t width;
|
||||
size_t height;
|
||||
size_t max_size;
|
||||
error = find_good_image_size(device_id, size_to_allocate, &width, &height, &max_size);
|
||||
if (!(error == SUCCEEDED || error == FAILED_TOO_BIG))
|
||||
return error;
|
||||
if(max_size < max_individual_allocation_size)
|
||||
max_individual_allocation_size = max_size;
|
||||
}
|
||||
|
||||
reduction_amount = (size_t)max_individual_allocation_size/16;
|
||||
|
||||
if (type == BUFFER || type == BUFFER_NON_BLOCKING) log_info("\tAttempting to allocate a buffer of size %gMB.\n", toMB(size_to_allocate));
|
||||
else if (type == IMAGE_READ || type == IMAGE_READ_NON_BLOCKING) log_info("\tAttempting to allocate a read-only image of size %gMB.\n", toMB(size_to_allocate));
|
||||
else if (type == IMAGE_WRITE || type == IMAGE_WRITE_NON_BLOCKING) log_info("\tAttempting to allocate a write-only image of size %gMB.\n", toMB(size_to_allocate));
|
||||
|
||||
// log_info("\t\t(Reduction size is %gMB per iteration, minimum allowable individual allocation size is %gMB.)\n",
|
||||
// toMB(reduction_amount), toMB(min_allocation_allowed));
|
||||
// if (force_fill && type != IMAGE_WRITE && type != IMAGE_WRITE_NON_BLOCKING) log_info("\t\t(Allocations will be filled with random data for checksum calculation.)\n");
|
||||
|
||||
// If we are only doing a single allocation, only allow 1
|
||||
int max_to_allocate = multiple_allocations ? MAX_NUMBER_TO_ALLOCATE : 1;
|
||||
|
||||
// Make sure that the maximum number of images allocated is constrained by the
|
||||
// maximum that may be passed to a kernel
|
||||
if (type != BUFFER && type != BUFFER_NON_BLOCKING) {
|
||||
cl_device_info param_name = (type == IMAGE_READ || type == IMAGE_READ_NON_BLOCKING) ?
|
||||
CL_DEVICE_MAX_READ_IMAGE_ARGS : CL_DEVICE_MAX_WRITE_IMAGE_ARGS;
|
||||
|
||||
cl_uint max_image_args;
|
||||
error = clGetDeviceInfo(device_id, param_name, sizeof(max_image_args), &max_image_args, NULL);
|
||||
test_error( error, "clGetDeviceInfo failed for CL_DEVICE_MAX IMAGE_ARGS");
|
||||
|
||||
if ((int)max_image_args < max_to_allocate) {
|
||||
log_info("\t\tMaximum number of images per kernel limited to %d\n",(int)max_image_args);
|
||||
max_to_allocate = max_image_args;
|
||||
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;
|
||||
}
|
||||
|
||||
amount_allocated = 0;
|
||||
current_allocation = 0;
|
||||
|
||||
// If allocating for images, reduce the maximum allocation size to the
|
||||
// maximum image size. If we don't do this, then the value of
|
||||
// CL_DEVICE_MAX_MEM_ALLOC_SIZE / 4 can be higher than the maximum image
|
||||
// size on systems with 16GB or RAM or more. In this case, we succeed in
|
||||
// allocating an image but its size is less than
|
||||
// CL_DEVICE_MAX_MEM_ALLOC_SIZE / 4 (min_allocation_allowed) and thus we
|
||||
// fail the allocation below.
|
||||
if (type == IMAGE_READ || type == IMAGE_READ_NON_BLOCKING
|
||||
|| type == IMAGE_WRITE || type == IMAGE_WRITE_NON_BLOCKING)
|
||||
{
|
||||
size_t width;
|
||||
size_t height;
|
||||
size_t max_size;
|
||||
error = find_good_image_size(device_id, size_to_allocate, &width,
|
||||
&height, &max_size);
|
||||
if (!(error == SUCCEEDED || error == FAILED_TOO_BIG)) return error;
|
||||
if (max_size < max_individual_allocation_size)
|
||||
max_individual_allocation_size = max_size;
|
||||
}
|
||||
|
||||
reduction_amount = (size_t)max_individual_allocation_size / 16;
|
||||
|
||||
if (type == BUFFER || type == BUFFER_NON_BLOCKING)
|
||||
log_info("\tAttempting to allocate a buffer of size %gMB.\n",
|
||||
toMB(size_to_allocate));
|
||||
else if (type == IMAGE_READ || type == IMAGE_READ_NON_BLOCKING)
|
||||
log_info("\tAttempting to allocate a read-only image of size %gMB.\n",
|
||||
toMB(size_to_allocate));
|
||||
else if (type == IMAGE_WRITE || type == IMAGE_WRITE_NON_BLOCKING)
|
||||
log_info("\tAttempting to allocate a write-only image of size %gMB.\n",
|
||||
toMB(size_to_allocate));
|
||||
|
||||
// log_info("\t\t(Reduction size is %gMB per iteration, minimum allowable
|
||||
// individual allocation size is %gMB.)\n",
|
||||
// toMB(reduction_amount), toMB(min_allocation_allowed));
|
||||
// if (force_fill && type != IMAGE_WRITE && type !=
|
||||
// IMAGE_WRITE_NON_BLOCKING) log_info("\t\t(Allocations will be filled with
|
||||
// random data for checksum calculation.)\n");
|
||||
|
||||
// If we are only doing a single allocation, only allow 1
|
||||
int max_to_allocate = multiple_allocations ? MAX_NUMBER_TO_ALLOCATE : 1;
|
||||
|
||||
// Make sure that the maximum number of images allocated is constrained by
|
||||
// the maximum that may be passed to a kernel
|
||||
if (type != BUFFER && type != BUFFER_NON_BLOCKING)
|
||||
{
|
||||
cl_device_info param_name =
|
||||
(type == IMAGE_READ || type == IMAGE_READ_NON_BLOCKING)
|
||||
? CL_DEVICE_MAX_READ_IMAGE_ARGS
|
||||
: CL_DEVICE_MAX_WRITE_IMAGE_ARGS;
|
||||
|
||||
cl_uint max_image_args;
|
||||
error = clGetDeviceInfo(device_id, param_name, sizeof(max_image_args),
|
||||
&max_image_args, NULL);
|
||||
test_error(error,
|
||||
"clGetDeviceInfo failed for CL_DEVICE_MAX IMAGE_ARGS");
|
||||
|
||||
if ((int)max_image_args < max_to_allocate)
|
||||
{
|
||||
log_info("\t\tMaximum number of images per kernel limited to %d\n",
|
||||
(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) {
|
||||
// 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;
|
||||
// Determine how much more is needed
|
||||
allocation_this_time = size_to_allocate - amount_allocated;
|
||||
|
||||
// Bound by the individual allocation size
|
||||
if (allocation_this_time > max_individual_allocation_size)
|
||||
allocation_this_time = (size_t)max_individual_allocation_size;
|
||||
// Bound by the individual allocation size
|
||||
if (allocation_this_time > max_individual_allocation_size)
|
||||
allocation_this_time = (size_t)max_individual_allocation_size;
|
||||
|
||||
// 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) {
|
||||
// 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)
|
||||
{
|
||||
|
||||
// Create the object
|
||||
result = do_allocation(context, queue, device_id, allocation_this_time, type, &mems[current_allocation]);
|
||||
if (result == SUCCEEDED) {
|
||||
// Allocation succeeded, another memory object was added to the array
|
||||
*number_of_mems = (current_allocation+1);
|
||||
// Create the object
|
||||
result =
|
||||
do_allocation(context, queue, device_id, allocation_this_time,
|
||||
type, &mems[current_allocation]);
|
||||
if (result == SUCCEEDED)
|
||||
{
|
||||
// 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;
|
||||
// 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 creation failed, try to create a smaller object
|
||||
if (result == FAILED_TOO_BIG)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 creation failed, try to create a smaller object
|
||||
if (result == FAILED_TOO_BIG) {
|
||||
//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;
|
||||
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;
|
||||
}
|
||||
|
||||
// Otherwise we succeeded
|
||||
if (result != SUCCEEDED)
|
||||
{
|
||||
log_error("Test logic error.");
|
||||
exit(-1);
|
||||
}
|
||||
amount_allocated += allocation_this_time;
|
||||
|
||||
*final_size = amount_allocated;
|
||||
|
||||
current_allocation++;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Otherwise we succeeded
|
||||
if (result != SUCCEEDED) {
|
||||
log_error("Test logic error.");
|
||||
exit(-1);
|
||||
}
|
||||
amount_allocated += allocation_this_time;
|
||||
|
||||
*final_size = amount_allocated;
|
||||
|
||||
current_allocation++;
|
||||
}
|
||||
|
||||
log_info("\t\tSucceeded in allocating %gMB using %d memory objects.\n", toMB(amount_allocated), current_allocation);
|
||||
return SUCCEEDED;
|
||||
log_info("\t\tSucceeded in allocating %gMB using %d memory objects.\n",
|
||||
toMB(amount_allocated), current_allocation);
|
||||
return SUCCEEDED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user