diff options
Diffstat (limited to 'tests/test_mem.cpp')
-rw-r--r-- | tests/test_mem.cpp | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/tests/test_mem.cpp b/tests/test_mem.cpp new file mode 100644 index 0000000..a4fdfdb --- /dev/null +++ b/tests/test_mem.cpp @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2011, Denis Steckelmacher <steckdenis@yahoo.fr> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <iostream> + +#include "test_mem.h" +#include "CL/cl.h" + +START_TEST (test_create_buffer) +{ + cl_context ctx; + cl_mem buf; + cl_int result; + char s[] = "Hello, world !"; + + ctx = clCreateContextFromType(0, CL_DEVICE_TYPE_DEFAULT, 0, 0, &result); + fail_if( + result != CL_SUCCESS, + "unable to create a valid context" + ); + + buf = clCreateBuffer(0, CL_MEM_READ_WRITE, sizeof(s), 0, &result); + fail_if( + result != CL_INVALID_CONTEXT, + "0 is not a valid context" + ); + + buf = clCreateBuffer(ctx, 1337, sizeof(s), 0, &result); + fail_if( + result != CL_INVALID_VALUE, + "1337 is not a valid cl_mem_flags" + ); + + buf = clCreateBuffer(ctx, CL_MEM_USE_HOST_PTR, sizeof(s), 0, &result); + fail_if( + result != CL_INVALID_HOST_PTR, + "host_ptr cannot be NULL if flags is CL_MEM_USE_HOST_PTR" + ); + + buf = clCreateBuffer(ctx, CL_MEM_COPY_HOST_PTR, sizeof(s), 0, &result); + fail_if( + result != CL_INVALID_HOST_PTR, + "host_ptr cannot be NULL if flags is CL_MEM_COPY_HOST_PTR" + ); + + buf = clCreateBuffer(ctx, 0, sizeof(s), s, &result); + fail_if( + result != CL_INVALID_HOST_PTR, + "host_ptr must be NULL if flags is not CL_MEM_{COPY/USE}_HOST_PTR" + ); + + buf = clCreateBuffer(ctx, CL_MEM_USE_HOST_PTR, 0, s, &result); + fail_if( + result != CL_INVALID_BUFFER_SIZE, + "size cannot be 0" + ); + + buf = clCreateBuffer(ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, + sizeof(s), s, &result); + fail_if( + result != CL_SUCCESS, + "cannot create a valid CL_MEM_COPY_HOST_PTR read-write buffer" + ); + + clReleaseMemObject(buf); + clReleaseContext(ctx); +} +END_TEST + +START_TEST (test_create_sub_buffer) +{ + cl_context ctx; + cl_mem buf, subbuf; + cl_int result; + char s[] = "Hello, world !"; + + cl_buffer_region create_info; // "Hello, [world] !" + + create_info.origin = 7; + create_info.size = 5; + + ctx = clCreateContextFromType(0, CL_DEVICE_TYPE_DEFAULT, 0, 0, &result); + fail_if( + result != CL_SUCCESS, + "unable to create a valid context" + ); + + buf = clCreateBuffer(ctx, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, + sizeof(s), s, &result); + fail_if( + result != CL_SUCCESS, + "cannot create a valid CL_MEM_USE_HOST_PTR read-write buffer" + ); + + subbuf = clCreateSubBuffer(0, CL_MEM_WRITE_ONLY, + CL_BUFFER_CREATE_TYPE_REGION, + (void *)&create_info, &result); + fail_if( + result != CL_INVALID_MEM_OBJECT, + "0 is not a valid mem object" + ); + + subbuf = clCreateSubBuffer(buf, CL_MEM_READ_ONLY, + CL_BUFFER_CREATE_TYPE_REGION, + (void *)&create_info, &result); + fail_if( + result != CL_INVALID_VALUE, + "READ_ONLY is not compatible with WRITE_ONLY" + ); + + subbuf = clCreateSubBuffer(buf, CL_MEM_WRITE_ONLY, 1337, (void *)&create_info, + &result); + fail_if( + result != CL_INVALID_VALUE, + "1337 is not a valid buffer_create_type" + ); + + subbuf = clCreateSubBuffer(buf, CL_MEM_WRITE_ONLY, + CL_BUFFER_CREATE_TYPE_REGION, 0, &result); + fail_if( + result != CL_INVALID_VALUE, + "buffer_create_info cannot be NULL" + ); + + create_info.size = 0; + + subbuf = clCreateSubBuffer(buf, CL_MEM_WRITE_ONLY, + CL_BUFFER_CREATE_TYPE_REGION, + (void *)&create_info, &result); + fail_if( + result != CL_INVALID_BUFFER_SIZE, + "create_info.size cannot be 0" + ); + + create_info.size = 5; + + subbuf = clCreateSubBuffer(buf, CL_MEM_WRITE_ONLY, + CL_BUFFER_CREATE_TYPE_REGION, + (void *)&create_info, &result); + fail_if( + result != CL_SUCCESS || subbuf == 0, + "cannot create a valid sub-buffer" + ); + + clCreateSubBuffer(subbuf, CL_MEM_WRITE_ONLY, + CL_BUFFER_CREATE_TYPE_REGION, + (void *)&create_info, &result); + fail_if( + result != CL_INVALID_MEM_OBJECT, + "we cannot create a sub-buffer of a sub-buffer" + ); + + clReleaseMemObject(subbuf); + clReleaseMemObject(buf); + clReleaseContext(ctx); +} +END_TEST + +START_TEST (test_read_write_subbuf) +{ + cl_context ctx; + cl_mem buf, subbuf; + cl_command_queue queue; + cl_device_id device; + cl_int result; + char s[] = "Hello, Denis !"; + + cl_buffer_region create_info; + + create_info.origin = 7; // "Hello, [denis] !" + create_info.size = 5; + + result = clGetDeviceIDs(0, CL_DEVICE_TYPE_DEFAULT, 1, &device, 0); + fail_if( + result != CL_SUCCESS, + "cannot get a device" + ); + + ctx = clCreateContext(0, 1, &device, 0, 0, &result); + fail_if( + result != CL_SUCCESS, + "unable to create a valid context" + ); + + queue = clCreateCommandQueue(ctx, device, 0, &result); + fail_if( + result != CL_SUCCESS || queue == 0, + "cannot create a command queue" + ); + + buf = clCreateBuffer(ctx, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, + sizeof(s), s, &result); + fail_if( + result != CL_SUCCESS, + "cannot create a valid CL_MEM_USE_HOST_PTR read-write buffer" + ); + + subbuf = clCreateSubBuffer(buf, CL_MEM_WRITE_ONLY, + CL_BUFFER_CREATE_TYPE_REGION, + (void *)&create_info, &result); + fail_if( + result != CL_SUCCESS || subbuf == 0, + "cannot create a valid sub-buffer" + ); + + //// + char *hostptr; + char *valid_hostptr = s; + + valid_hostptr += create_info.origin; + + result = clGetMemObjectInfo(subbuf, CL_MEM_HOST_PTR, sizeof(char *), + (void *)&hostptr, 0); + fail_if( + result != CL_SUCCESS || hostptr != valid_hostptr, + "the host ptr of a subbuffer must point to a subportion of its parent buffer" + ); + + result = clEnqueueWriteBuffer(queue, subbuf, 1, 0, 5, "world", 0, 0, 0); + fail_if( + result != CL_SUCCESS, + "unable to write to the sub buffer" + ); + + char data[16]; + + result = clEnqueueReadBuffer(queue, subbuf, 1, 0, 5, data, 0, 0, 0); + fail_if( + result != CL_SUCCESS, + "unable to read the sub buffer" + ); + fail_if( + strncmp(data, "world", 5), + "the subbuffer must contain \"world\"" + ); + + result = clEnqueueReadBuffer(queue, buf, 1, 0, sizeof(s), data, 0, 0, 0); + fail_if( + result != CL_SUCCESS, + "unable to read the buffer" + ); + fail_if( + strncmp(data, "Hello, world !", sizeof(s)), + "the buffer must contain \"Hello, world !\"" + ); + + clReleaseCommandQueue(queue); + clReleaseMemObject(subbuf); + clReleaseMemObject(buf); + clReleaseContext(ctx); +} +END_TEST + +START_TEST (test_images) +{ + cl_context ctx; + cl_mem image2d, image3d; + cl_int result; + + unsigned char image2d_data_24bpp[] = { + 255, 0, 0, 0, 0, 255, 0, 0, + 0, 0, 255, 0, 255, 255, 0, 0 + }; + + unsigned char image3d_data_24bpp[] = { + 255, 0, 0, 0, 0, 255, 0, 0, + 0, 0, 255, 0, 255, 255, 0, 0, + + 128, 0, 0, 0, 0, 128, 0, 0, + 0, 0, 128, 0, 128, 128, 0, 0 + }; + + cl_image_format fmt; + + fmt.image_channel_data_type = CL_UNORM_INT8; + fmt.image_channel_order = CL_RGBA; + + ctx = clCreateContextFromType(0, CL_DEVICE_TYPE_DEFAULT, 0, 0, &result); + fail_if( + result != CL_SUCCESS, + "unable to create a valid context" + ); + + image2d = clCreateImage2D(ctx, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, &fmt, + 2, 2, 7, image2d_data_24bpp, &result); + fail_if( + result != CL_INVALID_IMAGE_SIZE, + "7 is not a valid row pitch for 24bpp, it isn't divisible by 3" + ); + + image2d = clCreateImage2D(ctx, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, &fmt, + 2, 2, 0, image2d_data_24bpp, &result); + fail_if( + result != CL_SUCCESS || image2d == 0, + "cannot create a valid 2x2 image2D" + ); + + image3d = clCreateImage3D(ctx, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, &fmt, + 2, 2, 2, 0, 0, image3d_data_24bpp, &result); + fail_if( + result != CL_SUCCESS || image3d == 0, + "cannot create a valid 2x2x2 image3D" + ); + + clReleaseMemObject(image3d); + clReleaseMemObject(image2d); + clReleaseContext(ctx); +} +END_TEST + +TCase *cl_mem_tcase_create(void) +{ + TCase *tc = NULL; + tc = tcase_create("mem"); + tcase_add_test(tc, test_create_buffer); +#if 0 // subbuffer tests need to be rewritten, they assume subbuffer alignment of 0! + tcase_add_test(tc, test_create_sub_buffer); + tcase_add_test(tc, test_read_write_subbuf); +#endif + tcase_add_test(tc, test_images); + return tc; +} |