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
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;
|
|
}
|
|
|
|
|
|
|