// // 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 "testBase.h" #include "harness/typeWrappers.h" #include "harness/conversions.h" #include #include #include using namespace std; const char *clone_kernel_test_img[] = { "__kernel void img_read_kernel(read_only image2d_t img, sampler_t sampler, __global int* outbuf)\n" "{\n" " uint4 color;\n" "\n" " color = read_imageui(img, sampler, (int2)(0,0));\n" " \n" " // 7, 8, 9, 10th DWORD\n" " outbuf[7] = color.x;\n" " outbuf[8] = color.y;\n" " outbuf[9] = color.z;\n" " outbuf[10] = color.w;\n" "}\n" "\n" "__kernel void img_write_kernel(write_only image2d_t img, uint4 color)\n" "{\n" " write_imageui (img, (int2)(0, 0), color);\n" "}\n" }; const char *clone_kernel_test_double[] = { "#pragma OPENCL EXTENSION cl_khr_fp64 : enable\n" "__kernel void clone_kernel_test1(double d, __global double* outbuf)\n" "{\n" " // use the same outbuf as rest of the tests\n" " outbuf[2] = d;\n" "}\n" }; const char *clone_kernel_test_kernel[] = { "typedef struct\n" "{\n" " int i;\n" " float f;\n" "} structArg;\n" "\n" "// value type test\n" "__kernel void clone_kernel_test0(int iarg, float farg, structArg sarg, __local int* localbuf, __global int* outbuf)\n" "{\n" " int tid = get_global_id(0);\n" "\n" " outbuf[0] = iarg;\n" " outbuf[1] = sarg.i;\n" " \n" " ((__global float*)outbuf)[2] = farg;\n" " ((__global float*)outbuf)[3] = sarg.f;\n" "}\n" "\n" "__kernel void buf_read_kernel(__global int* buf, __global int* outbuf)\n" "{\n" " // 6th DWORD\n" " outbuf[6] = buf[0];\n" "}\n" "\n" "__kernel void buf_write_kernel(__global int* buf, int write_val)\n" "{\n" " buf[0] = write_val;\n" "}\n" }; const int BUF_SIZE = 128; struct structArg { int i; float f; }; static unsigned char * generate_8888_image(int w, int h, MTdata d) { unsigned char *ptr = (unsigned char*)malloc(w * h * 4); int i; for (i=0; i 0.0000001) { test_error( error, "clCloneKernel test failed." ); return -1; } return 0; } int test_clone_kernel(cl_device_id deviceID, cl_context context, cl_command_queue queue, int num_elements) { int error; clProgramWrapper program; clProgramWrapper program_buf_read; clProgramWrapper program_buf_write; clKernelWrapper kernel; clKernelWrapper kernel_pipe_read; clKernelWrapper kernel_buf_read; clKernelWrapper kernel_pipe_write; clKernelWrapper kernel_buf_write; clKernelWrapper kernel_pipe_read_cloned; clKernelWrapper kernel_buf_read_cloned; size_t ndrange1 = 1; int write_val = 123; cl_bool bimg = CL_FALSE; cl_bool bdouble = CL_FALSE; // test image support error = clGetDeviceInfo(deviceID, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &bimg, NULL); test_error( error, "clGetDeviceInfo failed." ); // test double support if (is_extension_available(deviceID, "cl_khr_fp64")) { bdouble = CL_TRUE; } /* Create kernels to test with */ if( create_single_kernel_helper( context, &program, &kernel, 1, clone_kernel_test_kernel, "clone_kernel_test0" ) != 0 ) { return -1; } if (create_single_kernel_helper(context, &program_buf_read, &kernel_buf_read, 1, clone_kernel_test_kernel, "buf_read_kernel") != 0) { return -1; } if (create_single_kernel_helper( context, &program_buf_write, &kernel_buf_write, 1, clone_kernel_test_kernel, "buf_write_kernel") != 0) { return -1; } // Kernel args // Value type int intarg = 0; float farg = 1.0; structArg sa = { 1, 1.0f }; // cl_mem clMemWrapper buf, bufOut; char* pbuf = new char[BUF_SIZE]; char* pbufRes = new char[BUF_SIZE]; buf = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, BUF_SIZE, pbuf, &error); test_error( error, "clCreateBuffer failed." ); bufOut = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, BUF_SIZE, NULL, &error); test_error( error, "clCreateBuffer failed." ); error = clSetKernelArg(kernel, 0, sizeof(int), &intarg); error += clSetKernelArg(kernel, 1, sizeof(float), &farg); error += clSetKernelArg(kernel, 2, sizeof(structArg), &sa); error += clSetKernelArg(kernel, 3, 128, NULL); // local mem test_error( error, "clSetKernelArg failed." ); // clone the kernel clKernelWrapper clonek = clCloneKernel(kernel, &error); test_error( error, "clCloneKernel failed." ); // set the last arg and enqueue error = clSetKernelArg(clonek, 4, sizeof(cl_mem), &bufOut); test_error( error, "clSetKernelArg failed." ); error = clEnqueueNDRangeKernel(queue, clonek, 1, NULL, &ndrange1, NULL, 0, NULL, NULL); test_error( error, "clEnqueueNDRangeKernel failed." ); // shallow clone tests for buffer error = clSetKernelArg(kernel_buf_write, 0, sizeof(cl_mem), &buf); error += clSetKernelArg(kernel_buf_write, 1, sizeof(int), &write_val); test_error( error, "clSetKernelArg failed." ); error = clEnqueueNDRangeKernel(queue, kernel_buf_write, 1, NULL, &ndrange1, NULL, 0, NULL, NULL); test_error( error, "clEnqueueNDRangeKernel failed." ); error = clSetKernelArg(kernel_buf_read, 0, sizeof(cl_mem), &buf); error += clSetKernelArg(kernel_buf_read, 1, sizeof(cl_mem), &bufOut); test_error( error, "clSetKernelArg failed." ); // clone the kernel kernel_buf_read_cloned = clCloneKernel(kernel_buf_read, &error); test_error( error, "clCloneKernel API call failed." ); error = clEnqueueNDRangeKernel(queue, kernel_buf_read_cloned, 1, NULL, &ndrange1, NULL, 0, NULL, NULL); test_error( error, "clEnqueueNDRangeKernel failed." ); // read result back error = clEnqueueReadBuffer(queue, bufOut, CL_TRUE, 0, BUF_SIZE, pbufRes, 0, NULL, NULL); test_error( error, "clEnqueueReadBuffer failed." ); // Compare the results if (((int*)pbufRes)[0] != intarg) { test_error( error, "clCloneKernel test failed. Failed to clone integer type argument." ); return -1; } if (((int*)pbufRes)[1] != sa.i) { test_error( error, "clCloneKernel test failed. Failed to clone structure type argument." ); return -1; } if (((float*)pbufRes)[2] != farg) { test_error( error, "clCloneKernel test failed. Failed to clone structure type argument." ); return -1; } if (((float*)pbufRes)[3] != sa.f) { test_error( error, "clCloneKernel test failed. Failed to clone float type argument." ); return -1; } if (((int*)pbufRes)[6] != write_val) { test_error( error, "clCloneKernel test failed. Failed to clone cl_mem argument." ); return -1; } if (bimg) { error = test_image_arg_shallow_clone(deviceID, context, queue, num_elements, pbufRes, bufOut); test_error( error, "image arg shallow clone test failed." ); } if (bdouble) { error = test_double_arg_clone(deviceID, context, queue, num_elements, pbufRes, bufOut); test_error( error, "double arg clone test failed." ); } delete [] pbuf; delete [] pbufRes; return 0; }