From e98b86cbe32e88b6a5ee5c3e2dd15f8725d64e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Petit?= Date: Fri, 10 Jan 2020 15:16:12 +0000 Subject: [PATCH] Remove duplicate bufferreadwriterect compatibility test (#541) The only diff between the main and compatibility versions of the test is that the region overlap check was fixed in the main one (see 487c4696ff070e1a3cb23dbb08096d3f4ef11fe3 in Gitlab). Contributes to #494 Signed-off-by: Kevin Petit --- .../test_conformance/basic/CMakeLists.txt | 1 - .../test_conformance/basic/main.c | 2 - .../basic/test_bufferreadwriterect.c | 529 ------------------ 3 files changed, 532 deletions(-) delete mode 100644 test_conformance/compatibility/test_conformance/basic/test_bufferreadwriterect.c diff --git a/test_conformance/compatibility/test_conformance/basic/CMakeLists.txt b/test_conformance/compatibility/test_conformance/basic/CMakeLists.txt index f6dc173f..03cef4eb 100644 --- a/test_conformance/compatibility/test_conformance/basic/CMakeLists.txt +++ b/test_conformance/compatibility/test_conformance/basic/CMakeLists.txt @@ -5,7 +5,6 @@ set(${MODULE_NAME}_SOURCES test_readimage.c test_writeimage.c test_sizeof.c - test_bufferreadwriterect.c ) set(${MODULE_NAME}_LIBS harness-compat) diff --git a/test_conformance/compatibility/test_conformance/basic/main.c b/test_conformance/compatibility/test_conformance/basic/main.c index 38646b83..a6b4a856 100644 --- a/test_conformance/compatibility/test_conformance/basic/main.c +++ b/test_conformance/compatibility/test_conformance/basic/main.c @@ -34,8 +34,6 @@ test_definition test_list[] = { ADD_TEST( sizeof ), ADD_TEST( readimage ), ADD_TEST( writeimage ), - - ADD_TEST( bufferreadwriterect ), }; const int test_num = ARRAY_SIZE( test_list ); diff --git a/test_conformance/compatibility/test_conformance/basic/test_bufferreadwriterect.c b/test_conformance/compatibility/test_conformance/basic/test_bufferreadwriterect.c deleted file mode 100644 index 025f65ec..00000000 --- a/test_conformance/compatibility/test_conformance/basic/test_bufferreadwriterect.c +++ /dev/null @@ -1,529 +0,0 @@ -// -// 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 "harness/compat.h" - -#include -#include -#include -#include - -#include "procs.h" - -#define CL_EXIT_ERROR(cmd,format,...) \ -{ \ -if ((cmd) != CL_SUCCESS) { \ -log_error("CL ERROR: %s %u: ", __FILE__,__LINE__); \ -log_error(format,## __VA_ARGS__ ); \ -log_error("\n"); \ -/*abort();*/ \ -} \ -} - -typedef unsigned char BufferType; - -// Globals for test -cl_command_queue queue; - -// Width and height of each pair of images. -enum { TotalImages = 8 }; -size_t width [TotalImages]; -size_t height [TotalImages]; -size_t depth [TotalImages]; - -// cl buffer and host buffer. -cl_mem buffer [TotalImages]; -BufferType* verify[TotalImages]; -BufferType* backing[TotalImages]; - -// Temporary buffer used for read and write operations. -BufferType* tmp_buffer; -size_t tmp_buffer_size; - -size_t num_tries = 50; // Number of randomly selected operations to perform. -size_t alloc_scale = 2; // Scale term applied buffer allocation size. -MTdata mt; - -// Initialize a buffer in host memory containing random values of the specified size. -static void initialize_image(BufferType* ptr, size_t w, size_t h, size_t d, MTdata mt) -{ - enum { ElementSize = sizeof(BufferType)/sizeof(unsigned char) }; - - unsigned char* buf = (unsigned char*)ptr; - size_t size = w*h*d*ElementSize; - - for (size_t i = 0; i != size; i++) { - buf[i] = (unsigned char)(genrand_int32(mt) % 0xff); - } -} - -// This function prints the contents of a buffer to standard error. -void print_buffer(BufferType* buf, size_t w, size_t h, size_t d) { - log_error("Size = %lux%lux%lu (%lu total)\n",w,h,d,w*h*d); - for (unsigned k=0; k!=d;++k) { - log_error("Slice: %u\n",k); - for (unsigned j=0; j!=h;++j) { - for (unsigned i=0;i!=w;++i) { - log_error("%02x",buf[k*(w*h)+j*w+i]); - } - log_error("\n"); - } - log_error("\n"); - } -} - -// Returns true if the two specified regions overlap. -bool check_overlap(const size_t src_offset[3], const size_t dst_offset[3], const size_t region[3]) { - - const size_t src_min[] = {src_offset[0], src_offset[1], src_offset[2]}; - const size_t src_max[] = {src_offset[0]+region[0], src_offset[1]+region[1], src_offset[2]+region[2]}; - - const size_t dst_min[] = {dst_offset[0], dst_offset[1], dst_offset[2]}; - const size_t dst_max[] = {dst_offset[0]+region[0], dst_offset[1]+region[1], dst_offset[2]+region[2]}; - - // Check for overlap, using the span space formulation. - bool overlap = true; - unsigned i; - for (i=0; i != 3; ++i) { - overlap = overlap && (src_min[i] < dst_max[i]) && (src_max[i] > dst_min[i]); - } - - return overlap; -} - -// This function invokes the CopyBufferRect CL command and then mirrors the operation on the host side verify buffers. -int copy_region(size_t src, size_t soffset[3], size_t sregion[3], size_t dst, size_t doffset[3], size_t dregion[3]) { - - // Copy between cl buffers. - size_t src_slice_pitch = (width[src]*height[src] != 1) ? width[src]*height[src] : 0; - size_t dst_slice_pitch = (width[dst]*height[dst] != 1) ? width[dst]*height[dst] : 0; - - cl_int err; - if (check_overlap(soffset,doffset,sregion)) { - log_info( "Copy overlap reported, skipping copy buffer rect\n" ); - return CL_SUCCESS; - } else { - if ((err = clEnqueueCopyBufferRect(queue, - buffer[src],buffer[dst], - soffset, doffset, - sregion,/*dregion,*/ - width[src], src_slice_pitch, - width[dst], dst_slice_pitch, - 0, NULL, NULL)) != CL_SUCCESS) - { - CL_EXIT_ERROR(err, "clEnqueueCopyBufferRect failed between %u and %u",(unsigned)src,(unsigned)dst); - } - } - - // Copy between host buffers. - size_t total = sregion[0] * sregion[1] * sregion[2]; - - size_t spitch = width[src]; - size_t sslice = width[src]*height[src]; - - size_t dpitch = width[dst]; - size_t dslice = width[dst]*height[dst]; - - for (size_t i = 0; i != total; ++i) { - - // Compute the coordinates of the element within the source and destination regions. - size_t rslice = sregion[0]*sregion[1]; - size_t sz = i / rslice; - size_t sy = (i % rslice) / sregion[0]; - size_t sx = (i % rslice) % sregion[0]; - - size_t dz = sz; - size_t dy = sy; - size_t dx = sx; - - // Compute the offset in bytes of the source and destination. - size_t s_idx = (soffset[2]+sz)*sslice + (soffset[1]+sy)*spitch + soffset[0]+sx; - size_t d_idx = (doffset[2]+dz)*dslice + (doffset[1]+dy)*dpitch + doffset[0]+dx; - - verify[dst][d_idx] = verify[src][s_idx]; - } - - return 0; -} - -// This function compares the destination region in the buffer pointed -// to by device, to the source region of the specified verify buffer. -int verify_region(BufferType* device, size_t src, size_t soffset[3], size_t sregion[3], size_t dst, size_t doffset[3]) { - - // Copy between host buffers. - size_t spitch = width[src]; - size_t sslice = width[src]*height[src]; - - size_t dpitch = width[dst]; - size_t dslice = width[dst]*height[dst]; - - size_t total = sregion[0] * sregion[1] * sregion[2]; - for (size_t i = 0; i != total; ++i) { - - // Compute the coordinates of the element within the source and destination regions. - size_t rslice = sregion[0]*sregion[1]; - size_t sz = i / rslice; - size_t sy = (i % rslice) / sregion[0]; - size_t sx = (i % rslice) % sregion[0]; - - // Compute the offset in bytes of the source and destination. - size_t s_idx = (soffset[2]+sz)*sslice + (soffset[1]+sy)*spitch + soffset[0]+sx; - size_t d_idx = (doffset[2]+sz)*dslice + (doffset[1]+sy)*dpitch + doffset[0]+sx; - - if (device[d_idx] != verify[src][s_idx]) { - log_error("Verify failed on comparsion %lu: coordinate (%lu, %lu, %lu) of region\n",i,sx,sy,sz); - log_error("0x%02x != 0x%02x\n", device[d_idx], verify[src][s_idx]); -#if 0 - // Uncomment this section to print buffers. - log_error("Device (copy): [%lu]\n",dst); - print_buffer(device,width[dst],height[dst],depth[dst]); - log_error("\n"); - log_error("Verify: [%lu]\n",src); - print_buffer(verify[src],width[src],height[src],depth[src]); - log_error("\n"); - abort(); -#endif - return -1; - } - } - - return 0; -} - - -// This function invokes ReadBufferRect to read a region from the -// specified source buffer into a temporary destination buffer. The -// contents of the temporary buffer are then compared to the source -// region of the corresponding verify buffer. -int read_verify_region(size_t src, size_t soffset[3], size_t sregion[3], size_t dst, size_t doffset[3], size_t dregion[3]) { - - // Clear the temporary destination host buffer. - memset(tmp_buffer, 0xff, tmp_buffer_size); - - size_t src_slice_pitch = (width[src]*height[src] != 1) ? width[src]*height[src] : 0; - size_t dst_slice_pitch = (width[dst]*height[dst] != 1) ? width[dst]*height[dst] : 0; - - // Copy the source region of the cl buffer, to the destination region of the temporary buffer. - CL_EXIT_ERROR(clEnqueueReadBufferRect(queue, - buffer[src], - CL_TRUE, - soffset,doffset, - sregion, - width[src], src_slice_pitch, - width[dst], dst_slice_pitch, - tmp_buffer, - 0, NULL, NULL), "clEnqueueCopyBufferRect failed between %u and %u",(unsigned)src,(unsigned)dst); - - return verify_region(tmp_buffer,src,soffset,sregion,dst,doffset); -} - -// This function performs the same verification check as -// read_verify_region, except a MapBuffer command is used to access the -// device buffer data instead of a ReadBufferRect, and the whole -// buffer is checked. -int map_verify_region(size_t src) { - - size_t size_bytes = width[src]*height[src]*depth[src]*sizeof(BufferType); - - // Copy the source region of the cl buffer, to the destination region of the temporary buffer. - cl_int err; - BufferType* mapped = (BufferType*)clEnqueueMapBuffer(queue,buffer[src],CL_TRUE,CL_MAP_READ,0,size_bytes,0,NULL,NULL,&err); - CL_EXIT_ERROR(err, "clEnqueueMapBuffer failed for buffer %u",(unsigned)src); - - size_t soffset[] = { 0, 0, 0 }; - size_t sregion[] = { width[src], height[src], depth[src] }; - - int ret = verify_region(mapped,src,soffset,sregion,src,soffset); - - CL_EXIT_ERROR(clEnqueueUnmapMemObject(queue,buffer[src],mapped,0,NULL,NULL), - "clEnqueueUnmapMemObject failed for buffer %u",(unsigned)src); - - return ret; -} - -// This function generates a new temporary buffer and then writes a -// region of it to a region in the specified destination buffer. -int write_region(size_t src, size_t soffset[3], size_t sregion[3], size_t dst, size_t doffset[3], size_t dregion[3]) { - - initialize_image(tmp_buffer, tmp_buffer_size, 1, 1, mt); - // memset(tmp_buffer, 0xf0, tmp_buffer_size); - - size_t src_slice_pitch = (width[src]*height[src] != 1) ? width[src]*height[src] : 0; - size_t dst_slice_pitch = (width[dst]*height[dst] != 1) ? width[dst]*height[dst] : 0; - - // Copy the source region of the cl buffer, to the destination region of the temporary buffer. - CL_EXIT_ERROR(clEnqueueWriteBufferRect(queue, - buffer[dst], - CL_TRUE, - doffset,soffset, - /*sregion,*/dregion, - width[dst], dst_slice_pitch, - width[src], src_slice_pitch, - tmp_buffer, - 0, NULL, NULL), "clEnqueueWriteBufferRect failed between %u and %u",(unsigned)src,(unsigned)dst); - - // Copy from the temporary buffer to the host buffer. - size_t spitch = width[src]; - size_t sslice = width[src]*height[src]; - size_t dpitch = width[dst]; - size_t dslice = width[dst]*height[dst]; - - size_t total = sregion[0] * sregion[1] * sregion[2]; - for (size_t i = 0; i != total; ++i) { - - // Compute the coordinates of the element within the source and destination regions. - size_t rslice = sregion[0]*sregion[1]; - size_t sz = i / rslice; - size_t sy = (i % rslice) / sregion[0]; - size_t sx = (i % rslice) % sregion[0]; - - size_t dz = sz; - size_t dy = sy; - size_t dx = sx; - - // Compute the offset in bytes of the source and destination. - size_t s_idx = (soffset[2]+sz)*sslice + (soffset[1]+sy)*spitch + soffset[0]+sx; - size_t d_idx = (doffset[2]+dz)*dslice + (doffset[1]+dy)*dpitch + doffset[0]+dx; - - verify[dst][d_idx] = tmp_buffer[s_idx]; - } - return 0; -} - -void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void *data ) -{ - free( data ); -} - -// This is the main test function for the conformance test. -int -test_bufferreadwriterect(cl_device_id device, cl_context context, cl_command_queue queue_, int num_elements) -{ - queue = queue_; - cl_int err; - - // Initialize the random number generator. - mt = init_genrand( gRandomSeed ); - - // Compute a maximum buffer size based on the number of test images and the device maximum. - cl_ulong max_mem_alloc_size = 0; - CL_EXIT_ERROR(clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_mem_alloc_size, NULL),"Could not get device info"); - log_info("CL_DEVICE_MAX_MEM_ALLOC_SIZE = %llu bytes.\n", max_mem_alloc_size); - - // Confirm that the maximum allocation size is not zero. - if (max_mem_alloc_size == 0) { - log_error("Error: CL_DEVICE_MAX_MEM_ALLOC_SIZE is zero bytes\n"); - return -1; - } - - // Guess at a reasonable maximum dimension. - size_t max_mem_alloc_dim = (size_t)cbrt((double)(max_mem_alloc_size/sizeof(BufferType)))/alloc_scale; - if (max_mem_alloc_dim == 0) { - max_mem_alloc_dim = max_mem_alloc_size; - } - - log_info("Using maximum dimension = %lu.\n", max_mem_alloc_dim); - - // Create pairs of cl buffers and host buffers on which operations will be mirrored. - log_info("Creating %u pairs of random sized host and cl buffers.\n", TotalImages); - - size_t max_size = 0; - size_t total_bytes = 0; - - for (unsigned i=0; i != TotalImages; ++i) { - - // Determine a width and height for this buffer. - size_t size_bytes; - size_t tries = 0; - size_t max_tries = 1048576; - do { - width[i] = get_random_size_t(1, max_mem_alloc_dim, mt); - height[i] = get_random_size_t(1, max_mem_alloc_dim, mt); - depth[i] = get_random_size_t(1, max_mem_alloc_dim, mt); - ++tries; - } while ((tries < max_tries) && (size_bytes = width[i]*height[i]*depth[i]*sizeof(BufferType)) > max_mem_alloc_size); - - // Check to see if adequately sized buffers were found. - if (tries >= max_tries) { - log_error("Error: Could not find random buffer sized less than %llu bytes in %lu tries.\n", - max_mem_alloc_size, max_tries); - return -1; - } - - // Keep track of the dimensions of the largest buffer. - max_size = (size_bytes > max_size) ? size_bytes : max_size; - total_bytes += size_bytes; - - log_info("Buffer[%u] is (%lu,%lu,%lu) = %lu MB (truncated)\n",i,width[i],height[i],depth[i],(size_bytes)/1048576); - } - - log_info( "Total size: %lu MB (truncated)\n", total_bytes/1048576 ); - - // Allocate a temporary buffer for read and write operations. - tmp_buffer_size = max_size; - tmp_buffer = (BufferType*)malloc(tmp_buffer_size); - - // Initialize cl buffers - log_info( "Initializing buffers\n" ); - for (unsigned i=0; i != TotalImages; ++i) { - - size_t size_bytes = width[i]*height[i]*depth[i]*sizeof(BufferType); - - // Allocate a host copy of the buffer for verification. - verify[i] = (BufferType*)malloc(size_bytes); - CL_EXIT_ERROR(verify[i] ? CL_SUCCESS : -1, "malloc of host buffer failed for buffer %u", i); - - // Allocate the buffer in host memory. - backing[i] = (BufferType*)malloc(size_bytes); - CL_EXIT_ERROR(backing[i] ? CL_SUCCESS : -1, "malloc of backing buffer failed for buffer %u", i); - - // Generate a random buffer. - log_info( "Initializing buffer %u\n", i ); - initialize_image(verify[i], width[i], height[i], depth[i], mt); - - // Copy the image into a buffer which will passed to CL. - memcpy(backing[i], verify[i], size_bytes); - - // Create the CL buffer. - buffer[i] = clCreateBuffer (context, CL_MEM_USE_HOST_PTR | CL_MEM_READ_WRITE, size_bytes, backing[i], &err); - CL_EXIT_ERROR(err,"clCreateBuffer failed for buffer %u", i); - - // Make sure buffer is cleaned up appropriately if we encounter an error in the rest of the calls. - err = clSetMemObjectDestructorCallback( buffer[i], mem_obj_destructor_callback, backing[i] ); - CL_EXIT_ERROR(err, "Unable to set mem object destructor callback" ); - } - - // Main test loop, run num_tries times. - log_info( "Executing %u test operations selected at random.\n", (unsigned)num_tries ); - for (size_t iter = 0; iter < num_tries; ++iter) { - - // Determine a source and a destination. - size_t src = get_random_size_t(0,TotalImages,mt); - size_t dst = get_random_size_t(0,TotalImages,mt); - - // Determine the minimum dimensions. - size_t min_width = width[src] < width[dst] ? width[src] : width[dst]; - size_t min_height = height[src] < height[dst] ? height[src] : height[dst]; - size_t min_depth = depth[src] < depth[dst] ? depth[src] : depth[dst]; - - // Generate a random source rectangle within the minimum dimensions. - size_t mx = get_random_size_t(0, min_width-1, mt); - size_t my = get_random_size_t(0, min_height-1, mt); - size_t mz = get_random_size_t(0, min_depth-1, mt); - - size_t sw = get_random_size_t(1, (min_width - mx), mt); - size_t sh = get_random_size_t(1, (min_height - my), mt); - size_t sd = get_random_size_t(1, (min_depth - mz), mt); - - size_t sx = get_random_size_t(0, width[src]-sw, mt); - size_t sy = get_random_size_t(0, height[src]-sh, mt); - size_t sz = get_random_size_t(0, depth[src]-sd, mt); - - size_t soffset[] = { sx, sy, sz }; - size_t sregion[] = { sw, sh, sd }; - - // Generate a destination rectangle of the same size. - size_t dw = sw; - size_t dh = sh; - size_t dd = sd; - - // Generate a random destination offset within the buffer. - size_t dx = get_random_size_t(0, (width[dst] - dw), mt); - size_t dy = get_random_size_t(0, (height[dst] - dh), mt); - size_t dz = get_random_size_t(0, (depth[dst] - dd), mt); - size_t doffset[] = { dx, dy, dz }; - size_t dregion[] = { dw, dh, dd }; - - // Execute one of three operations: - // - Copy: Copies between src and dst within each set of host, buffer, and images. - // - Read & verify: Reads src region from buffer and image, and compares to host. - // - Write: Generates new buffer with src dimensions, and writes to cl buffer and image. - - enum { TotalOperations = 3 }; - size_t operation = get_random_size_t(0,TotalOperations,mt); - - switch (operation) { - case 0: - log_info("%lu Copy %lu offset (%lu,%lu,%lu) -> %lu offset (%lu,%lu,%lu) region (%lux%lux%lu = %lu)\n", - iter, - src, soffset[0], soffset[1], soffset[2], - dst, doffset[0], doffset[1], doffset[2], - sregion[0], sregion[1], sregion[2], - sregion[0]*sregion[1]*sregion[2]); - if ((err = copy_region(src, soffset, sregion, dst, doffset, dregion))) - return err; - break; - case 1: - log_info("%lu Read %lu offset (%lu,%lu,%lu) -> %lu offset (%lu,%lu,%lu) region (%lux%lux%lu = %lu)\n", - iter, - src, soffset[0], soffset[1], soffset[2], - dst, doffset[0], doffset[1], doffset[2], - sregion[0], sregion[1], sregion[2], - sregion[0]*sregion[1]*sregion[2]); - if ((err = read_verify_region(src, soffset, sregion, dst, doffset, dregion))) - return err; - break; - case 2: - log_info("%lu Write %lu offset (%lu,%lu,%lu) -> %lu offset (%lu,%lu,%lu) region (%lux%lux%lu = %lu)\n", - iter, - src, soffset[0], soffset[1], soffset[2], - dst, doffset[0], doffset[1], doffset[2], - sregion[0], sregion[1], sregion[2], - sregion[0]*sregion[1]*sregion[2]); - if ((err = write_region(src, soffset, sregion, dst, doffset, dregion))) - return err; - break; - } - -#if 0 - // Uncomment this section to verify each operation. - // If commented out, verification won't occur until the end of the - // test, and it will not be possible to determine which operation failed. - log_info("Verify src %lu offset (%u,%u,%u) region (%lux%lux%lu)\n", src, 0, 0, 0, width[src], height[src], depth[src]); - if (err = map_verify_region(src)) - return err; - - log_info("Verify dst %lu offset (%u,%u,%u) region (%lux%lux%lu)\n", dst, 0, 0, 0, width[dst], height[dst], depth[dst]); - if (err = map_verify_region(dst)) - return err; - - -#endif - - } // end main for loop. - - for (unsigned i=0;i