You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
9.7 KiB

//
// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "allocation_fill.h"
#define BUFFER_CHUNK_SIZE 8*1024*1024
#define IMAGE_LINES 8
#include "harness/compat.h"
int fill_buffer_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, size_t size, MTdata d, cl_bool blocking_write) {
size_t i, j;
cl_uint *data;
int error, result;
cl_uint checksum_delta = 0;
cl_event event;
size_t size_to_use = BUFFER_CHUNK_SIZE;
if (size_to_use > size)
size_to_use = size;
data = (cl_uint*)malloc(size_to_use);
if (data == NULL) {
log_error("Failed to malloc host buffer for writing into buffer.\n");
return FAILED_ABORT;
}
for (i=0; i<size-size_to_use; i+=size_to_use) {
// Put values in the data, and keep a checksum as we go along.
for (j=0; j<size_to_use/sizeof(cl_uint); j++) {
data[j] = genrand_int32(d);
checksum_delta += data[j];
}
if (blocking_write) {
error = clEnqueueWriteBuffer(*queue, mem, CL_TRUE, i, size_to_use, data, 0, NULL, NULL);
result = check_allocation_error(context, device_id, error, queue);
if (result == FAILED_ABORT) {
print_error(error, "clEnqueueWriteBuffer failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
free(data);
clReleaseMemObject(mem);
return result;
}
} else {
error = clEnqueueWriteBuffer(*queue, mem, CL_FALSE, i, size_to_use, data, 0, NULL, &event);
result = check_allocation_error(context, device_id, error, queue);
if (result == FAILED_ABORT) {
print_error(error, "clEnqueueWriteBuffer failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
free(data);
clReleaseMemObject(mem);
return result;
}
error = clWaitForEvents(1, &event);
result = check_allocation_error(context, device_id, error, queue, &event);
if (result == FAILED_ABORT) {
print_error(error, "clWaitForEvents failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
clReleaseEvent(event);
free(data);
clReleaseMemObject(mem);
return result;
}
clReleaseEvent(event);
}
}
// Deal with any leftover bits
if (i < size) {
// Put values in the data, and keep a checksum as we go along.
for (j=0; j<(size-i)/sizeof(cl_uint); j++) {
data[j] = (cl_uint)genrand_int32(d);
checksum_delta += data[j];
}
if (blocking_write) {
error = clEnqueueWriteBuffer(*queue, mem, CL_TRUE, i, size-i, data, 0, NULL, NULL);
result = check_allocation_error(context, device_id, error, queue);
if (result == FAILED_ABORT) {
print_error(error, "clEnqueueWriteBuffer failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
clReleaseMemObject(mem);
free(data);
return result;
}
} else {
error = clEnqueueWriteBuffer(*queue, mem, CL_FALSE, i, size-i, data, 0, NULL, &event);
result = check_allocation_error(context, device_id, error, queue);
if (result == FAILED_ABORT) {
print_error(error, "clEnqueueWriteBuffer failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
clReleaseMemObject(mem);
free(data);
return result;
}
error = clWaitForEvents(1, &event);
result = check_allocation_error(context, device_id, error, queue, &event);
if (result == FAILED_ABORT) {
print_error(error, "clWaitForEvents failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
clReleaseEvent(event);
free(data);
clReleaseMemObject(mem);
return result;
}
clReleaseEvent(event);
}
}
free(data);
// Only update the checksum if this succeeded.
checksum += checksum_delta;
return SUCCEEDED;
}
int fill_image_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, size_t width, size_t height, MTdata d, cl_bool blocking_write) {
size_t origin[3], region[3], j;
int error, result;
cl_uint *data;
cl_uint checksum_delta = 0;
cl_event event;
size_t image_lines_to_use;
image_lines_to_use = IMAGE_LINES;
if (image_lines_to_use > height)
image_lines_to_use = height;
data = (cl_uint*)malloc(width*4*sizeof(cl_uint)*image_lines_to_use);
if (data == NULL) {
log_error("Failed to malloc host buffer for writing into image.\n");
return FAILED_ABORT;
}
origin[0] = 0;
origin[1] = 0;
origin[2] = 0;
region[0] = width;
region[1] = image_lines_to_use;
region[2] = 1;
for (origin[1] = 0; origin[1] < height - image_lines_to_use; origin[1] += image_lines_to_use) {
// Put values in the data, and keep a checksum as we go along.
for (j=0; j<width*4*image_lines_to_use; j++) {
data[j] = (cl_uint)genrand_int32(d);
checksum_delta += data[j];
}
if (blocking_write) {
error = clEnqueueWriteImage(*queue, mem, CL_TRUE, origin, region, 0, 0, data, 0, NULL, NULL);
result = check_allocation_error(context, device_id, error, queue);
if (result == FAILED_ABORT) {
print_error(error, "clEnqueueWriteImage failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
clReleaseMemObject(mem);
free(data);
return result;
}
result = clFinish(*queue);
if (result != SUCCEEDED)
{
print_error(error, "clFinish failed after successful enquing filling buffer with data.");
return result;
}
} else {
error = clEnqueueWriteImage(*queue, mem, CL_FALSE, origin, region, 0, 0, data, 0, NULL, &event);
result = check_allocation_error(context, device_id, error, queue);
if (result == FAILED_ABORT) {
print_error(error, "clEnqueueWriteImage failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
clReleaseMemObject(mem);
free(data);
return result;
}
error = clWaitForEvents(1, &event);
result = check_allocation_error(context, device_id, error, queue, &event);
if (result == FAILED_ABORT) {
print_error(error, "clWaitForEvents failed.");
}
if (result != SUCCEEDED) {
clReleaseEvent(event);
free(data);
clReleaseMemObject(mem);
return result;
}
clReleaseEvent(event);
}
}
// Deal with any leftover bits
if (origin[1] < height) {
// Put values in the data, and keep a checksum as we go along.
for (j=0; j<width*4*(height-origin[1]); j++) {
data[j] = (cl_uint)genrand_int32(d);
checksum_delta += data[j];
}
region[1] = height-origin[1];
if(blocking_write) {
error = clEnqueueWriteImage(*queue, mem, CL_TRUE, origin, region, 0, 0, data, 0, NULL, NULL);
result = check_allocation_error(context, device_id, error, queue);
if (result == FAILED_ABORT) {
print_error(error, "clEnqueueWriteImage failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
clReleaseMemObject(mem);
free(data);
return result;
}
} else {
error = clEnqueueWriteImage(*queue, mem, CL_FALSE, origin, region, 0, 0, data, 0, NULL, &event);
result = check_allocation_error(context, device_id, error, queue);
if (result == FAILED_ABORT) {
print_error(error, "clEnqueueWriteImage failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
clReleaseMemObject(mem);
free(data);
return result;
}
error = clWaitForEvents(1, &event);
result = check_allocation_error(context, device_id, error, queue, &event);
if (result == FAILED_ABORT) {
print_error(error, "clWaitForEvents failed.");
}
if (result != SUCCEEDED) {
clFinish(*queue);
clReleaseEvent(event);
free(data);
clReleaseMemObject(mem);
return result;
}
clReleaseEvent(event);
}
}
free(data);
// Only update the checksum if this succeeded.
checksum += checksum_delta;
return SUCCEEDED;
}
int fill_mem_with_data(cl_context context, cl_device_id device_id, cl_command_queue *queue, cl_mem mem, MTdata d, cl_bool blocking_write) {
int error;
cl_mem_object_type type;
size_t size, width, height;
error = clGetMemObjectInfo(mem, CL_MEM_TYPE, sizeof(type), &type, NULL);
test_error_abort(error, "clGetMemObjectInfo failed for CL_MEM_TYPE.");
if (type == CL_MEM_OBJECT_BUFFER) {
error = clGetMemObjectInfo(mem, CL_MEM_SIZE, sizeof(size), &size, NULL);
test_error_abort(error, "clGetMemObjectInfo failed for CL_MEM_SIZE.");
return fill_buffer_with_data(context, device_id, queue, mem, size, d, blocking_write);
} else if (type == CL_MEM_OBJECT_IMAGE2D) {
error = clGetImageInfo(mem, CL_IMAGE_WIDTH, sizeof(width), &width, NULL);
test_error_abort(error, "clGetImageInfo failed for CL_IMAGE_WIDTH.");
error = clGetImageInfo(mem, CL_IMAGE_HEIGHT, sizeof(height), &height, NULL);
test_error_abort(error, "clGetImageInfo failed for CL_IMAGE_HEIGHT.");
return fill_image_with_data(context, device_id, queue, mem, width, height, d, blocking_write);
}
log_error("Invalid CL_MEM_TYPE: %d\n", type);
return FAILED_ABORT;
}