Example #1
0
int
piglit_cl_get_device_version(cl_device_id device)
{
	char* version_string;
	const char *version_number_string;
	int scanf_count;
	int major;
	int minor;

	/*
	 * Returned format:
	 *   OpenCL<space><major_version.minor_version><space><platform-specific information>
	 */
	version_string = piglit_cl_get_device_info(device, CL_DEVICE_VERSION);

	/* skip to version number */
	version_number_string = version_string + 6;

	/* Interpret version number */
	scanf_count = sscanf(version_number_string, "%i.%i", &major, &minor);
	if (scanf_count != 2) {
		printf("Unable to interpret CL_DEVICE_VERSION string: %s\n",
		       version_string);
		free(version_string);
		piglit_report_result(PIGLIT_FAIL);
	}
	free(version_string);

	return 10*major+minor;
}
/* Print test configuration */
static void
print_test_info(const struct piglit_cl_test_config_header* config,
                int version,
                const cl_platform_id platform_id,
                const cl_device_id device_id) {
	if(config->run_per_platform || config->run_per_device) {
		char* platform_name;

		platform_name = piglit_cl_get_platform_info(platform_id,
		                                            CL_PLATFORM_NAME);

		printf("# Running on:\n"
		       "#   Platform: %s\n",
		       platform_name);

		if(config->run_per_device) {
			char* device_name = piglit_cl_get_device_info(device_id,
			                                              CL_DEVICE_NAME);

			printf("#   Device: %s\n", device_name);

			free(device_name);
		}

		printf("#   OpenCL version: %d.%d\n", version/10, version%10);

		free(platform_name);
	} else {
		// print nothing
	}
}
Example #3
0
bool
piglit_cl_is_device_extension_supported(cl_device_id device, const char *name)
{
	char* extensions = piglit_cl_get_device_info(device, CL_DEVICE_EXTENSIONS);
	bool supported = piglit_is_extension_in_string(extensions, name);

	free(extensions);

	return supported;
}
bool piglit_cl_framework_check_local_work_size(
	cl_device_id device_id,
	size_t *local_work_size)
{
	unsigned i;
	size_t workgroup_size = 1;
	size_t *max_workgroup_size = piglit_cl_get_device_info(device_id,
						CL_DEVICE_MAX_WORK_GROUP_SIZE);
	size_t *max_workitem_sizes = piglit_cl_get_device_info(device_id,
						CL_DEVICE_MAX_WORK_ITEM_SIZES);
	bool ret = true;

	if (!local_work_size) {
		goto out;
	}

	if (!max_workgroup_size || !max_workitem_sizes) {
		ret = false;
		goto out;
	}

	for (i = 0; i < 3; i++) {
		size_t local_size = local_work_size[i];
		if (local_size > max_workitem_sizes[i]) {
			ret = false;
			goto out;
		}
		if (local_size > 0) {
			workgroup_size *= local_size;
		}
	}

	if (workgroup_size > *max_workgroup_size) {
		ret = false;
	}
out:
	free(max_workgroup_size);
	free(max_workitem_sizes);
	return ret;
}
Example #5
0
bool
piglit_cl_get_device_image_support(cl_device_id device)
{
	bool ret = false;

	cl_bool *image_support =
		piglit_cl_get_device_info(device, CL_DEVICE_IMAGE_SUPPORT);

	if (image_support)
		ret = *image_support;

	free(image_support);

	return ret;
}
bool
piglit_cl_get_device_arg(const int argc, const char** argv,
                         cl_platform_id platform_id, cl_device_id* device_id)
{
	int i;
	const char* arg_value;

	/* First check argument then environment */
	arg_value = piglit_cl_get_arg_value(argc, argv, "device");
	if(arg_value == NULL) {
		arg_value = getenv("PIGLIT_CL_DEVICE");
	}

	if(arg_value != NULL) {
		unsigned int num_devices;
		cl_device_id* device_ids;

		num_devices = piglit_cl_get_device_ids(platform_id,
		                                       CL_DEVICE_TYPE_ALL,
		                                       &device_ids);

		for(i = 0; i < num_devices; i++) {
			char* device_name = piglit_cl_get_device_info(device_ids[i],
			                                              CL_DEVICE_NAME);

			if(!strncmp(arg_value, device_name, strlen(arg_value))) {
				*device_id = device_ids[i];

				free(device_ids);
				free(device_name);
				return true;
			}

			free(device_name);
		}

		free(device_ids);
		fprintf(stderr,
		        "Could not find device: %s\n",
		        arg_value);
		piglit_report_result(PIGLIT_WARN);
	}

	return false;
}
bool check_device_extensions(cl_device_id device_id, char* extensions)
{
	char* pch;

	if (!extensions)
		return true;

	pch = strtok(extensions, " ");
	while(pch != NULL) {
		if(   strlen(pch) > 0
		   && !piglit_cl_is_device_extension_supported(device_id, pch)) {
			char* device_name = piglit_cl_get_device_info(device_id,
			                                              CL_DEVICE_NAME);
			printf("\n# Skipping device %s because extension %s is not supported.\n\n",
			       device_name,
			       pch);
			free(device_name);
			return false;
		}
		pch = strtok(NULL, " ");
	}

	return true;
}
Example #8
0
enum piglit_result
piglit_cl_test(const int argc,
               const char** argv,
               const struct piglit_cl_api_test_config* config,
               const struct piglit_cl_api_test_env* env)
{
#if defined(CL_VERSION_1_2)
	enum piglit_result result = PIGLIT_PASS;

	int i;
	cl_program_binary_type* binary_type;
	cl_program compiled_programs[2];
	cl_program function_prog;
	cl_program kernel_prog;
	cl_program linked_prog;

	/* Create compiled program */
	function_prog = compile_program(env->context->cl_ctx,
	                                env->context->num_devices, env->context->device_ids,
	                                1, &strings[0],
	                                "function program");
	kernel_prog = compile_program(env->context->cl_ctx,
	                              env->context->num_devices, env->context->device_ids,
	                              2, &strings[1],
                                 "kernel program");

	if (!function_prog || !kernel_prog) {
		clReleaseProgram(function_prog);
		clReleaseProgram(kernel_prog);
		return PIGLIT_FAIL;
	}

	compiled_programs[0] = function_prog;
	compiled_programs[1] = kernel_prog;

/*** Normal usage ***/
	test(env->context->cl_ctx,
	     env->context->num_devices, env->context->device_ids,
	     "-create-library",
	     1, compiled_programs,
	     NULL, NULL,
	     &linked_prog,
	     CL_SUCCESS, &result, "Link program as library");

	for(i = 0; i < env->context->num_devices; ++i) {
		binary_type = piglit_cl_get_program_build_info(linked_prog,
		                                               env->context->device_ids[i],
		                                               CL_PROGRAM_BINARY_TYPE);
		if (*binary_type != CL_PROGRAM_BINARY_TYPE_LIBRARY) {
			piglit_merge_result(&result, PIGLIT_FAIL);
			fprintf(stderr,
		           "Failed: binary is not of type CL_PROGRAM_BINARY_TYPE_LIBRARY.\n");
		}
		free(binary_type);
	}

	clReleaseProgram(linked_prog);

	test(env->context->cl_ctx,
	     env->context->num_devices, env->context->device_ids,
	     "",
	     2, compiled_programs,
	     NULL, NULL,
	     &linked_prog,
	     CL_SUCCESS, &result, "Link program as executable");

	for(i = 0; i < env->context->num_devices; ++i) {
		binary_type = piglit_cl_get_program_build_info(linked_prog,
		                                               env->context->device_ids[i],
		                                               CL_PROGRAM_BINARY_TYPE);
		if (*binary_type != CL_PROGRAM_BINARY_TYPE_EXECUTABLE) {
			piglit_merge_result(&result, PIGLIT_FAIL);
			fprintf(stderr,
		           "Failed: binary is not of type CL_PROGRAM_BINARY_TYPE_EXECUTABLE.\n");
		}
		free(binary_type);
	}


/*** Errors ***/

	/*
	 * CL_INVALID_VALUE if device_list is NULL and num_devices is greater than
	 * zero, or if device_list is not NULL and num_devices is zero
	 */
	test(env->context->cl_ctx,
	     env->context->num_devices, NULL,
	     "",
	     2, compiled_programs,
	     NULL, NULL,
	     NULL,
	     CL_INVALID_VALUE, &result,
	     "Trigger CL_INVALID_VALUE if device_list is NULL and num_devices is greater than zero");

	test(env->context->cl_ctx,
	     0, env->context->device_ids,
	     "",
	     2, compiled_programs,
	     NULL, NULL,
	     NULL,
	     CL_INVALID_VALUE, &result,
	     "Trigger CL_INVALID_VALUE if device_list is not NULL and num_devices is zero");

	/*
	 * CL_INVALID_VALUE if num_input_programs is zero and input_programs is NULL
	 * or if num_input_programs is zero and input_programs is not NULL
	 * or if num_input_programs is not zero and input_programs is NULL
	 */
	test(env->context->cl_ctx,
	     env->context->num_devices, env->context->device_ids,
	     "",
	     0, NULL,
	     NULL, NULL,
	     NULL,
	     CL_INVALID_VALUE, &result,
	     "Trigger CL_INVALID_VALUE if num_input_programs is zero and input_programs is NULL");

	test(env->context->cl_ctx,
	     env->context->num_devices, env->context->device_ids,
	     "",
	     0, compiled_programs,
	     NULL, NULL,
	     NULL,
	     CL_INVALID_VALUE, &result,
	     "Trigger CL_INVALID_VALUE if num_input_programs is zero and input_programs is not NULL");

	test(env->context->cl_ctx,
	     env->context->num_devices, env->context->device_ids,
	     "",
	     2, NULL,
	     NULL, NULL,
	     NULL,
	     CL_INVALID_VALUE, &result,
	     "Trigger CL_INVALID_VALUE if num_input_programs is not zero and input_programs is NULL");

	/*
	 * CL_INVALID_PROGRAM if programs specified in input_programs are not valid program objects
	 */


	/*
	 * CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL.
	 */
	test(env->context->cl_ctx,
	     env->context->num_devices, env->context->device_ids,
	     "",
	     2, compiled_programs,
	     NULL, &i,
	     NULL,
	     CL_INVALID_VALUE, &result,
	     "Trigger CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL");

	/*
	 * CL_INVALID_DEVICE if OpenCL devices listed in device_list are not in the
	 * list of devices associated with context
	 */


	/*
	 * CL_INVALID_LINKER_OPTIONS if the linker options specified by options are
	 * invalid
	 */
	test(env->context->cl_ctx,
	     env->context->num_devices, env->context->device_ids,
	     "-invalid- --link-- options",
	     2, compiled_programs,
	     NULL, NULL,
	     NULL,
	     CL_INVALID_LINKER_OPTIONS, &result,
	     "Trigger CL_INVALID_LINKER_OPTIONS if the linker options specified by options are invalid");

	/*
	 * CL_INVALID_OPERATION if the compilation or build of a program executable
	 * for any of the devices listed in device_list by a previous call to
	 * clCompileProgram or clBuildProgram for program has not completed
	 */


	/*
	 * CL_INVALID_OPERATION if the rules for devices containing compiled binaries
	 * or libraries as described in input_programs argument above are not followed
	 */
	compiled_programs[0] = linked_prog;
	test(env->context->cl_ctx,
	     env->context->num_devices, env->context->device_ids,
	     "",
	     2, compiled_programs,
	     NULL, NULL,
	     NULL,
	     CL_INVALID_OPERATION, &result,
	     "Trigger CL_INVALID_OPERATION if the rules for devices containing compiled binaries or libraries as described in input_programs argument above are not followed");

	/*
	 * CL_LINKER_NOT_AVAILABLE if a linker is not available
	 * i.e. CL_DEVICE_LINKER_AVAILABLE specified in the table of allowed values
	 * for param_name for clGetDeviceInfo is set to CL_FALSE.
	 */
	for(i = 0; i < env->context->num_devices; ++i) {
		cl_bool* linker_available =
			piglit_cl_get_device_info(env->context->device_ids[i],
			                          CL_DEVICE_LINKER_AVAILABLE);
			if(!(*linker_available)) {
				test(env->context->cl_ctx,
				     env->context->num_devices, env->context->device_ids,
				     "",
				     2, compiled_programs,
				     NULL, NULL,
				     NULL,
				     CL_LINKER_NOT_AVAILABLE, &result,
				     "Trigger CL_LINKER_NOT_AVAILABLE if a linker is not available");
		}
		free(linker_available);
	}


/* Release programs */
	clReleaseProgram(function_prog);
	clReleaseProgram(kernel_prog);
	clReleaseProgram(linked_prog);

	/*
	 * CL_LINK_PROGRAM_FAILURE if there is a failure to link the compiled binaries
	 * and/or libraries.
	 */
	function_prog = compile_program(env->context->cl_ctx,
	                                env->context->num_devices, env->context->device_ids,
	                                1, &strings[0],
	                                "2nd function program");
	kernel_prog = compile_program(env->context->cl_ctx,
	                              env->context->num_devices, env->context->device_ids,
	                              2, &strings[2],
                                 "2nd kernel program");

	if (!function_prog || !kernel_prog) {
		result = PIGLIT_FAIL;
	} else {
		compiled_programs[0] = function_prog;
		compiled_programs[1] = kernel_prog;

		test(env->context->cl_ctx,
		     env->context->num_devices, env->context->device_ids,
		     "",
		     2, compiled_programs,
		     NULL, NULL,
		     NULL,
		     CL_LINK_PROGRAM_FAILURE, &result,
		     "Trigger CL_LINK_PROGRAM_FAILURE if there is a failure to link the compiled binaries and/or libraries");
	}

/* Release programs */
	clReleaseProgram(function_prog);
	clReleaseProgram(kernel_prog);

	return result;
#else
	return PIGLIT_SKIP;
#endif
}
Example #9
0
cl_program
piglit_cl_build_program_with_binary_extended(piglit_cl_context context,
                                             size_t* lenghts,
                                             unsigned char** binaries,
                                             const char* options, bool fail)
{
	cl_int errNo;
	cl_program program;

	cl_int* binary_status = malloc(sizeof(cl_int) * context->num_devices);

	program = clCreateProgramWithBinary(context->cl_ctx,
	                                    context->num_devices,
	                                    context->device_ids,
	                                    lenghts,
	                                    (const unsigned char**)binaries,
	                                    binary_status,
	                                    &errNo);
	if(errNo != CL_SUCCESS) {
		int i;

		fprintf(stderr,
		        "Could not create program with binary: %s\n",
		        piglit_cl_get_error_name(errNo));

		printf("Create error with binaries:\n");
		for(i = 0; i < context->num_devices; i++) {
			char* device_name = piglit_cl_get_device_info(context->device_ids[i],
			                                              CL_DEVICE_NAME);
			
			printf("Error for %s: %s\n",
			       device_name,
			       piglit_cl_get_error_name(binary_status[i]));
			
			free(device_name);
		}

		free(binary_status);
		return NULL;
	}
	free(binary_status);
	
	errNo = clBuildProgram(program,
	                       context->num_devices,
	                       context->device_ids,
	                       options,
	                       NULL,
	                       NULL);
	if(   (!fail && errNo != CL_SUCCESS)
	   || ( fail && errNo == CL_SUCCESS)) {
		int i;

		fprintf(stderr,
		        !fail ? "Could not build program: %s\n"
		              : "Program built when it should have failed: %s\n",
		        piglit_cl_get_error_name(errNo));

		printf("Build log for binaries.\n");

		for(i = 0; i < context->num_devices; i++) {
			char* device_name = piglit_cl_get_device_info(context->device_ids[i],
			                                              CL_DEVICE_NAME);
			char* log = piglit_cl_get_program_build_info(program,
			                                             context->device_ids[i],
			                                             CL_PROGRAM_BUILD_LOG);
			
			printf("Build log for device %s:\n -------- \n%s\n -------- \n",
			       device_name,
			       log);
			
			free(device_name);
			free(log);
		}

		clReleaseProgram(program);
		return NULL;
	}

	return program;
}
Example #10
0
cl_program
piglit_cl_build_program_with_source_extended(piglit_cl_context context,
                                             cl_uint count, char** strings,
                                             const char* options, bool fail)
{
	cl_int errNo;
	cl_program program;

	program = clCreateProgramWithSource(context->cl_ctx,
	                                    count,
	                                    (const char**)strings,
	                                    NULL,
	                                    &errNo);
	if(errNo != CL_SUCCESS) {
		fprintf(stderr,
		        "Could not create program with source: %s\n",
		        piglit_cl_get_error_name(errNo));
		return NULL;
	}
	
	errNo = clBuildProgram(program,
	                       context->num_devices,
	                       context->device_ids,
	                       options,
	                       NULL,
	                       NULL);
	if(   (!fail && errNo != CL_SUCCESS)
	   || ( fail && errNo == CL_SUCCESS)) {
		int i;

		fprintf(stderr,
		        !fail ? "Could not build program: %s\n"
		              : "Program built when it should have failed: %s\n",
		        piglit_cl_get_error_name(errNo));

		/*printf("Build log for source:\n");
		for(i = 0; i < count; i++) {
			printf("%s\n", strings[i]);
		}*/

		for(i = 0; i < context->num_devices; i++) {
			char* device_name = piglit_cl_get_device_info(context->device_ids[i],
			                                              CL_DEVICE_NAME);
			char* log = piglit_cl_get_program_build_info(program,
			                                             context->device_ids[i],
			                                             CL_PROGRAM_BUILD_LOG);
			
			printf("Build log for device %s:\n -------- \n%s\n -------- \n",
			       device_name,
			       log);

			free(device_name);
			free(log);
		}

		clReleaseProgram(program);
		return NULL;
	}

	return program;
}
Example #11
0
enum piglit_result
piglit_cl_test(const int argc,
               const char **argv,
               const struct piglit_cl_api_test_config* config,
               const struct piglit_cl_api_test_env* env)
{
#if defined(CL_VERSION_1_2)
	enum piglit_result result = PIGLIT_PASS;
	cl_int err;

#define IMG_WIDTH 4
#define IMG_HEIGHT 4
#define IMG_DATA_SIZE 4
#define IMG_BUFFER_SIZE IMG_WIDTH * IMG_HEIGHT * IMG_DATA_SIZE

	unsigned char img_buf[IMG_BUFFER_SIZE] = {0};
	unsigned char dst_buf[IMG_BUFFER_SIZE] = {0};
	unsigned char exp_buf[IMG_BUFFER_SIZE] = {0};
	int pattern[4] = {129, 33, 77, 255};
	size_t origin[3] = {0, 0, 0};
	size_t region[3] = {2, 2, 1};
	size_t tmp;
	cl_event event;
	cl_mem image;
	cl_image_format img_format;
	cl_image_desc img_desc = {0};
	cl_command_queue queue = env->context->command_queues[0];
	int i;

	cl_bool *image_support =
		piglit_cl_get_device_info(env->context->device_ids[0],
		                          CL_DEVICE_IMAGE_SUPPORT);

	if (!*image_support) {
		fprintf(stderr, "No image support\n");
		free(image_support);
		return PIGLIT_SKIP;
	}

	img_format.image_channel_order = CL_RGBA;
	img_format.image_channel_data_type = CL_UNSIGNED_INT8;
	img_desc.image_type = CL_MEM_OBJECT_IMAGE2D;
	img_desc.image_width = IMG_WIDTH;
	img_desc.image_height = IMG_HEIGHT;
	img_desc.buffer = NULL;

/*** Normal usage ***/
	image = clCreateImage(env->context->cl_ctx,
	                      CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
	                      &img_format, &img_desc, &img_buf, &err);

	if(!piglit_cl_check_error(err, CL_SUCCESS)) {
		fprintf(stderr, "Failed (error code: %s): Creating an image\n",
		        piglit_cl_get_error_name(err));
		return PIGLIT_FAIL;
	}

	if (!test(queue, image, pattern, origin, region,
	          0, NULL, NULL,
	          CL_SUCCESS, &result, "Enqueuing the image to be filled")) {
		return PIGLIT_FAIL;
	}

	region[0] = IMG_WIDTH;
	region[1] = IMG_HEIGHT;
	err = clEnqueueReadImage(queue, image, 1, origin, region, 0, 0,
	                         dst_buf, 0, NULL, NULL);
	if(!piglit_cl_check_error(err, CL_SUCCESS)) {
		fprintf(stderr, "Failed (error code: %s): Reading image\n",
		        piglit_cl_get_error_name(err));
		return PIGLIT_FAIL;
	}

	/*
	 * fill the host buffer with the pattern
	 * for exemple : pattern == 1234
	 *
	 * 12341234abcdabcd
	 * 12341234abcdabcd
	 * abcdabcdabcdabcd
	 * abcdabcdabcdabcd
	 */
	exp_buf[0] = pattern[0];
	exp_buf[1] = pattern[1];
	exp_buf[2] = pattern[2];
	exp_buf[3] = pattern[3];
	memcpy(exp_buf + (IMG_DATA_SIZE * 1), exp_buf, IMG_DATA_SIZE);
	memcpy(exp_buf + (IMG_DATA_SIZE * 4), exp_buf, IMG_DATA_SIZE);
	memcpy(exp_buf + (IMG_DATA_SIZE * 5), exp_buf, IMG_DATA_SIZE);

	for (i = 0; i < sizeof(dst_buf) / sizeof(dst_buf[0]); ++i) {
		if (!piglit_cl_probe_integer(dst_buf[i], exp_buf[i], 0)) {
			fprintf(stderr, "Error at %d: got %d, expected %d\n",
			        i, dst_buf[i], exp_buf[i]);
			return PIGLIT_FAIL;
		}
	}

/*** Errors ***/

	/*
	 * CL_INVALID_COMMAND_QUEUE if command_queue is not a valid command-queue.
	 */
	test(NULL, image, pattern, origin, region,
		  0, NULL, NULL,
		  CL_INVALID_COMMAND_QUEUE, &result,
		  "CL_INVALID_COMMAND_QUEUE if command_queue is not a valid command-queue");

	/*
	 * CL_INVALID_CONTEXT if the context associated with command_queue and
	 * image are not the same or if the context associated with command_queue
	 * and events in event_wait_list are not the same.
	 */
	{
		piglit_cl_context context;
		cl_int err;
		context = piglit_cl_create_context(env->platform_id,
		                                   env->context->device_ids, 1);
		if (context) {
			event = clCreateUserEvent(context->cl_ctx, &err);
			if (err == CL_SUCCESS) {
				err = clSetUserEventStatus(event, CL_COMPLETE);
				if (err == CL_SUCCESS) {
					test(context->command_queues[0], image, pattern, origin, region,
					     0, NULL, NULL,
					     CL_INVALID_CONTEXT, &result,
					     "CL_INVALID_CONTEXT if the context associated with command_queue and image are not the same");

					test(queue, image, pattern, origin, region,
					     1, &event, NULL,
					     CL_INVALID_CONTEXT, &result,
					     "CL_INVALID_CONTEXT if the context associated with command_queue and events in event_wait_list are not the same");
				} else {
					fprintf(stderr, "Could not set event status.\n");
					piglit_merge_result(&result, PIGLIT_WARN);
				}
				clReleaseEvent(event);
			} else {
				fprintf(stderr, "Could not create user event.\n");
				piglit_merge_result(&result, PIGLIT_WARN);
			}

			piglit_cl_release_context(context);
		} else {
			fprintf(stderr, "Could not test triggering CL_INVALID_CONTEXT.\n");
			piglit_merge_result(&result, PIGLIT_WARN);
		}
	}

	/*
	 * CL_INVALID_MEM_OBJECT if image is not a valid buffer object.
	 */
	test(queue, NULL, pattern, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_MEM_OBJECT, &result,
	     "CL_INVALID_MEM_OBJECT if image is not a valid buffer object");

	/*
	 * CL_INVALID_VALUE if fill_color is NULL.
	 */
	test(queue, image, NULL, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if fill_color is NULL");

	/*
	 * CL_INVALID_VALUE if the region being written specified by origin and
	 * region is out of bounds or if ptr is a NULL value.
	 */
	tmp = origin[0];
	origin[0] = IMG_WIDTH + 1;
	test(queue, image, pattern, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if the region being written specified by origin and region is out of bounds (origin)");
	origin[0] = tmp;

	tmp = region[0];
	region[0] = IMG_WIDTH + 1;
	test(queue, image, pattern, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if the region being written specified by origin and region is out of bounds (region)");
	region[0] = tmp;

	test(queue, image, pattern, NULL, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if ptr is a NULL value (origin)");

	test(queue, image, pattern, origin, NULL,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if ptr is a NULL value (region)");

	/*
	 * CL_INVALID_VALUE if values in origin and region do not follow rules
	 * described in the argument description for origin and region.
	 */
	tmp = origin[2];
	origin[2] = 1;
	test(queue, image, pattern, origin, region,
	     0, NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "CL_INVALID_VALUE if values in origin do not follow rules described in the argument description for origin");
	origin[2] = tmp;

	tmp = region[2];
	region[2] = 0;
	test(queue, image, pattern, origin, region,
		  0, NULL, NULL,
		CL_INVALID_VALUE, &result,
		"CL_INVALID_VALUE if values in region do not follow rules described in the argument description for region");
	region[2] = tmp;

	/*
	 * CL_INVALID_EVENT_WAIT_LIST if event_wait_list is NULL and
	 * num_events_in_wait_list > 0, or event_wait_list is not NULL and
	 * num_events_in_wait_list is 0, or if event objects in event_wait_list
	 * are not valid events.
	 */
	event = NULL;
	test(queue, image, pattern, origin, region,
	     1, NULL, NULL,
	     CL_INVALID_EVENT_WAIT_LIST, &result,
	     "CL_INVALID_EVENT_WAIT_LIST if event_wait_list is NULL and num_events_in_wait_list > 0");

	test(queue, image, pattern, origin, region,
	     0, &event, NULL,
	     CL_INVALID_EVENT_WAIT_LIST, &result,
	     "CL_INVALID_EVENT_WAIT_LIST if event_wait_list is not NULL and num_events_in_wait_list is 0");

	test(queue, image, pattern, origin, region,
	     1, &event, NULL,
	     CL_INVALID_EVENT_WAIT_LIST, &result,
	     "CL_INVALID_EVENT_WAIT_LIST if event objects in event_wait_list are not valid events");

	/*
	 * CL_INVALID_IMAGE_SIZE if image dimensions (image width, height, specified
	 * or compute row and/or slice pitch) for image are not supported by device
	 * associated with queue.
	 */
	/* This is a per device test, clCreateImage would have failed before */

	/*
	 * CL_INVALID_IMAGE_FORMAT if image format (image channel order and data type)
	 * for image are not supported by device associated with queue.
	 */
	/* This is a per device test, clCreateImage would have failed before */

	free(image_support);
	clReleaseMemObject(image);
	return result;
#else
	return PIGLIT_SKIP;
#endif
}
Example #12
0
enum piglit_result
piglit_cl_test(const int argc,
               const char** argv,
               const struct piglit_cl_api_test_config* config,
               const struct piglit_cl_api_test_env* env)
{
	enum piglit_result result = PIGLIT_PASS;

	int i;
	cl_int errNo;
	cl_program program;
	cl_program temp_program;
	cl_kernel kernel;

	/*** Normal usage ***/

	/* Create program */

	/* with binary */
	//TODO
	
	/* with source */
	program = clCreateProgramWithSource(env->context->cl_ctx,
	                                    2,
	                                    strings,
	                                    NULL,
	                                    &errNo);
	if(!piglit_cl_check_error(errNo, CL_SUCCESS)) {
		fprintf(stderr,
		        "Failed (error code: %s): Create program with source.\n",
		        piglit_cl_get_error_name(errNo));
		return PIGLIT_FAIL;
	}

	test(program, env->context->num_devices, env->context->device_ids, "",
	     NULL, NULL,
	     CL_SUCCESS, &result, "Build program");


	// TODO: test callback

	/*** Errors ***/

	/*
	 * CL_INVALID_PROGRAM if program is not a valid program object.
	 */
	test(NULL, env->context->num_devices, env->context->device_ids, "",
	     NULL, NULL,
	     CL_INVALID_PROGRAM, &result,
	     "Trigger CL_INVALID_PROGRAM if program is not a valid program object");

	/*
	 * CL_INVALID_VALUE if device_list is NULL and num_devices is greater than
	 * zero, or if device_list is not NULL and num_devices is zero.
	 */
	test(program, 1, NULL, "", NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "Trigger CL_INVALID_VALUE if device_list is NULL and num_devices is greater than zero");
	test(program, 0, env->context->device_ids, "", NULL, NULL,
	     CL_INVALID_VALUE, &result,
	     "Trigger CL_INVALID_VALUE if device_list is not NULL and num_devices is zero");

	/*
	 * CL_INVALID_VALUE if pfn_notify is NULL but user_data is not NULL.
	 */
	test(program, env->context->num_devices, env->context->device_ids, "",
	     NULL, &result,
	     CL_INVALID_VALUE, &result,
	     "Trigger CL_INVALID_VALUE if pfn_notify is NULL and user_data is not NULL");

	/*
	 * CL_INVALID_DEVICE if OpenCL devices listed in device_list are not in the
	 * list of devices associated with program.
	 *
	 * TODO
	 */

	/*
	 * CL_INVALID_BINARY if program is created with
	 * clCreateWithProgramWithBinary and devices listed in device_list do not
	 * have a valid program binary loaded.
	 *
	 * TODO
	 */

	/*
	 * CL_INVALID_BUILD_OPTIONS if the build options specified by options are
	 * invalid.
	 */
	test(program, env->context->num_devices, env->context->device_ids,
	     "-invalid- --build-- options", NULL, NULL,
	     CL_INVALID_BUILD_OPTIONS, &result,
	     "Trigger CL_INVALID_BUILD_OPTIONS if the build options specified by options are invalid");

	/*
	 * CL_INVALID_OPERATION if the build of a program executable for any of the
	 * devices listed in device_list by a previous call to clBuildProgram for
	 * program has not completed.
	 *
	 * TODO
	 */

	/*
	 * CL_COMPILER_NOT_AVAILABLE if program is created with
	 * clCreateProgramWithSource and a compiler is not available i.e.
	 * CL_DEVICE_COMPILER_AVAILABLE specified in the table of OpenCL Device
	 * Queries for clGetDeviceInfo is set to CL_FALSE.
	 *
	 * Note: If this is true for any device, then a normal usage test returns a
	 * false error.
	 */
	for(i = 0; i < env->context->num_devices; i++) {
		cl_bool* compiler_available =
			piglit_cl_get_device_info(env->context->device_ids[i],
			                          CL_DEVICE_COMPILER_AVAILABLE);
		if(!(*compiler_available)) {
			test(program, env->context->num_devices, env->context->device_ids,
			     "", NULL, NULL,
			     CL_COMPILER_NOT_AVAILABLE, &result,
			     "Trigger CL_COMPILER_NOT_AVAILABLE if program is created with clCreateProgramWithSource and a compiler is not available");
		}
		free(compiler_available);
	}

	/*
	 * CL_BUILD_PROGRAM_FAILURE if there is a failure to build the program
	 * executable. This error will be returned if clBuildProgram does not return
	 * until the build has completed.
	 */
	temp_program = clCreateProgramWithSource(env->context->cl_ctx,
	                                         1,
	                                         invalid_strings,
	                                         NULL,
	                                         &errNo);
	if(piglit_cl_check_error(errNo, CL_SUCCESS)) {
		test(temp_program, env->context->num_devices, env->context->device_ids,
		     "", NULL, NULL,
		     CL_BUILD_PROGRAM_FAILURE, &result,
		     "Trigger CL_BUILD_PROGRAM_FAILURE if there is a failure to build the program executable");
		clReleaseProgram(temp_program);
	}

	/*
	 * CL_INVALID_OPERATION if there are kernel objects attached to program.
	 */
	test(program, env->context->num_devices, env->context->device_ids, "",
	     NULL, NULL,
	     CL_SUCCESS, &result,
	     "Build program");
	kernel = clCreateKernel(program, "dummy_kernel", &errNo);
	if(piglit_cl_check_error(errNo, CL_SUCCESS)) {
		test(program, env->context->num_devices, env->context->device_ids, "",
		     NULL, NULL,
		     CL_INVALID_OPERATION, &result,
		     "Trigger CL_INVALID_OPERATION if there are kernel objects attached to program");
		clReleaseKernel(kernel);
	}

	/*
	 * CL_SUCCESS when compiling an empty string
	 */
	temp_program = clCreateProgramWithSource(env->context->cl_ctx,
	                                         1,
	                                         empty_strings,
	                                         NULL,
	                                         &errNo);
	if(piglit_cl_check_error(errNo, CL_SUCCESS)) {
		test(temp_program, env->context->num_devices, env->context->device_ids,
		     "", NULL, NULL,
		     CL_SUCCESS, &result,
		     "CL_SUCCESS when compiling an empty string.");
		clReleaseProgram(temp_program);
	}

	/*
	 * CL_INVALID_OPERATION if program was not created with
	 * clCreateProgramWithSource or clCreateProgramWithBinary.
	 *
	 * Version: 1.2
	 *
	 * TODO
	 */

	clReleaseProgram(program);

	return result;
}
Example #13
0
enum piglit_result
piglit_cl_test(const int argc,
               const char** argv,
               const struct piglit_cl_api_test_config* config,
               const struct piglit_cl_api_test_env* env)
{
	enum piglit_result result = PIGLIT_PASS;
	char test_str[1024];

	int i;
	int mask;
	cl_ulong alloc_size = BUFFER_SIZE; // max alloc size per device >= 128*1024*1024
	cl_ulong max_alloc;
	unsigned char host_buffer[BUFFER_SIZE];
	unsigned char host_buffer_read[BUFFER_SIZE];
	cl_mem_flags mixed_mem_flags;

	int num_mem_flags = PIGLIT_CL_ENUM_NUM(cl_mem_flags, env->version);
	const cl_mem_flags* mem_flags = PIGLIT_CL_ENUM_ARRAY(cl_mem_flags);

	int num_mutexes = PIGLIT_CL_ENUM_NUM(cl_mem_flags_mutexes, env->version);
	const cl_mem_flags* mutexes = PIGLIT_CL_ENUM_ARRAY(cl_mem_flags_mutexes);

	/*** Normal usage ***/

	for (i = 0; i < BUFFER_SIZE; i++){
		host_buffer[i] = (unsigned char)i;
	}

	/*
	 * For each memory flags mix.
	 * There are 2^(num_mem_flags)-1 possible options without
	 * excluding mutually exclusive options.
	 */
	for(mask = 1; mask < (1 << num_mem_flags); mask++) {
		mixed_mem_flags = get_mixed_mem_flags(mask, mem_flags);
		
		/* exclude invalid mixes */
		if(!mem_flags_valid(mixed_mem_flags, num_mutexes, mutexes)) {
			continue;
		}

		sprintf(test_str,
		        "Create buffer using 0x%X as memory flags",
		        (unsigned int)mixed_mem_flags);

		if(   (mixed_mem_flags & CL_MEM_USE_HOST_PTR)
		   || (mixed_mem_flags & CL_MEM_COPY_HOST_PTR)) {
			cl_mem buffer;

			/* test if function returns right values */
			test(env->context->cl_ctx,
			     mixed_mem_flags,
			     alloc_size,
			     host_buffer,
			     CL_SUCCESS,
			     &result,
			     test_str);

			/* test if buffer gets initialized properly */
			buffer = clCreateBuffer(env->context->cl_ctx,
			                        mixed_mem_flags,
			                        alloc_size,
			                        host_buffer,
			                        NULL);
			if(buffer) {
				cl_int errNo;
				
				errNo = clEnqueueReadBuffer(env->context->command_queues[0],
				                            buffer,
				                            true,
				                            0,
				                            alloc_size,
				                            host_buffer_read,
				                            0, NULL, NULL);
				
				if(errNo == CL_SUCCESS) {
					for(i = 0; i < BUFFER_SIZE; i++) {
						if(host_buffer[i] != host_buffer_read[i]) {
							printf("Buffer data was not initialized properly.\n");
							fprintf(stderr,
							        "Buffer data was not properly initialized using 0x%X as memory flags.\n",
							        (unsigned int)mixed_mem_flags);
							piglit_merge_result(&result, PIGLIT_FAIL);
							break;
						}
					}
				}
			}
		} else {
			test(env->context->cl_ctx, mixed_mem_flags, alloc_size, NULL,
			     CL_SUCCESS, &result, test_str);
		}
	}

#if defined(CL_VERSION_1_2)
	if(env->version >= 12) {
		test(env->context->cl_ctx,
		     0, // defaults to CL_MEM_READ_WRITE
		     alloc_size,
		     NULL,
		     CL_SUCCESS, &result,
		     "Create buffer using 0 (defaults to CL_MEM_READ_WRITE) as memory flags");
	}
#endif //CL_VERSION_1_2


	/*** Errors ***/

	/*
	 * CL_INVALID_CONTEXT if context is not a valid context.
	 */
	test(NULL, CL_MEM_READ_WRITE, alloc_size, NULL,
	     CL_INVALID_CONTEXT, &result,
	     "Trigger CL_INVALID_CONTEXT if context is not a valid context");

	/*
	 * CL_INVALID_VALUE if values specified in flags are not valid.
	 */
	for(mask = 1; mask < (1 << num_mem_flags); mask++) {
		mixed_mem_flags = get_mixed_mem_flags(mask, mem_flags);
		
		/* only invalid mixes */
		if(!mem_flags_valid(mixed_mem_flags, num_mutexes, mutexes)) {
			sprintf(test_str,
			        "Trigger CL_INVALID_VALUE if values specified in flags are not valid (using 0x%X as memory flags)",
			        (unsigned int)mixed_mem_flags);

			if(   (mixed_mem_flags & CL_MEM_USE_HOST_PTR)
			   || (mixed_mem_flags & CL_MEM_COPY_HOST_PTR)) {
				test(env->context->cl_ctx, mixed_mem_flags,
				     alloc_size, host_buffer,
				     CL_INVALID_VALUE, &result, test_str);
			} else {
				test(env->context->cl_ctx, mixed_mem_flags, alloc_size, NULL,
				     CL_INVALID_VALUE, &result, test_str);
			}
		}
	}

	/*
	 * CL_INVALID_BUFFER_SIZE if size is 0 or is greater than
	 * CL_DEVICE_MAX_MEM_ALLOC_SIZE value specified in table of
	 * OpenCL Device Queries for clGetDeviceInfo for all devices
	 * in context.
	 */
	test(env->context->cl_ctx, CL_MEM_READ_WRITE, 0, NULL,
	     CL_INVALID_BUFFER_SIZE, &result,
	     "Trigger CL_INVALID_BUFFER_SIZE if size is 0");
	
	max_alloc = 0;
	for(i = 0; i < env->context->num_devices; i++) {
		cl_ulong* max_device_alloc;

		max_device_alloc = piglit_cl_get_device_info(env->context->device_ids[i],
		                                             CL_DEVICE_MAX_MEM_ALLOC_SIZE);
		if(*max_device_alloc > max_alloc) {
			max_alloc = *max_device_alloc;
		}

		free(max_device_alloc);
	}
	
	test(env->context->cl_ctx,
	     CL_MEM_READ_WRITE,
	     max_alloc+1, // if we get to overflow, we're back at 0 and errNo must be the same
	     NULL,
	     CL_INVALID_BUFFER_SIZE, &result,
	     "Trigger CL_INVALID_BUFFER_SIZE if size is greater than CL_DEVICE_MAX_MEM_ALLOC_SIZE");

	/*
	 * CL_INVALID_HOST_PTR if host_ptr is NULL and CL_MEM_USE_HOST_PTR
	 * or CL_MEM_COPY_HOST_PTR are set in flags or if host_ptr is not
	 * NULL but CL_MEM_COPY_HOST_PTR or CL_MEM_USE_HOST_PTR are not
	 * set in flags.
	 */
	test(env->context->cl_ctx, CL_MEM_USE_HOST_PTR, alloc_size, NULL,
	     CL_INVALID_HOST_PTR, &result,
	     "Trigger CL_INVALID_HOST_PTR if host_ptr is NULL and CL_MEM_USE_HOST_PTR is set in flags");
	test(env->context->cl_ctx, CL_MEM_COPY_HOST_PTR, alloc_size, NULL,
	     CL_INVALID_HOST_PTR, &result,
	     "Trigger CL_INVALID_HOST_PTR if host_ptr is NULL and CL_MEM_COPY_HOST_PTR is set in flags");
	test(env->context->cl_ctx, CL_MEM_READ_WRITE, alloc_size, host_buffer,
	     CL_INVALID_HOST_PTR, &result,
	     "Trigger CL_INVALID_HOST_PTR if host_ptr is not NULL CL_MEM_USE_HOST_PTR or CL_MEM_COPY_HOST_PTR are not set in flags");

	return result;
}
/* Run the test(s) */
int piglit_cl_framework_run(int argc, char** argv)
{
	enum piglit_result result = PIGLIT_SKIP;

	int version = 0;
	cl_platform_id platform_id = NULL;
	cl_device_id device_id = NULL;

	/* Get test configuration */
	struct piglit_cl_test_config_header *config =
		piglit_cl_get_test_config(argc,
		                          (const char**)argv,
		                          &PIGLIT_CL_DEFAULT_TEST_CONFIG_HEADER);

	/* Check that config is valid */
	// run_per_platform, run_per_device
	if(config->run_per_platform && config->run_per_device) {
		fprintf(stderr,
		        "Invalid configuration, only one of run_per_platform and run_per_device can be true.\n");
		piglit_report_result(PIGLIT_WARN);
	}

	/* Init */
	if(config->init_func != NULL) {
		config->init_func(argc, (const char**)argv, config);
	}

	/* Print test name and file */
	printf("## Test: %s (%s) ##\n\n", config->name != NULL ? config->name : "",
	       config->_filename);

	/* Get version to test against */
	version = piglit_cl_get_version_arg(argc, (const char **)argv);
	if(version > 0) {
		if(version > PIGLIT_CL_VERSION) {
			printf("Piglit was compiled with lower OpenCL version (%d.%d) than version argument: %d.%d.\n",
			       PIGLIT_CL_VERSION/10, PIGLIT_CL_VERSION%10,
			       version/10, version%10);
			piglit_report_result(PIGLIT_SKIP);
		}
	} else {
		/*
		 * If version was not provided on the command line, set it to
		 * the version against which Piglit was compiled (PIGLIT_CL_VERSION)
		 */
		version = PIGLIT_CL_VERSION;
	}

	/* Run the actual test */
	if(!(config->run_per_platform || config->run_per_device)) {
		print_test_info(config, version, NULL, NULL);
		result = config->_test_run(argc, (const char**)argv, (void*)config,
		                           version, NULL, NULL);
	} else {
		/* Run tests per platform or device */
		int i;
		regex_t platform_regex;
		regex_t device_regex;

		bool platform_defined;
		unsigned int num_platforms;
		cl_platform_id* platform_ids;

		/* Create regexes */
		if(   config->platform_regex != NULL
		   && regcomp(&platform_regex, config->platform_regex, REG_EXTENDED | REG_NEWLINE)) {
			fprintf(stderr,
			        "Regex to filter platforms is invalid, ignoring it.\n");
			regcomp(&platform_regex, "", REG_EXTENDED | REG_NEWLINE);
			piglit_merge_result(&result, PIGLIT_WARN);
		}
		if(   config->device_regex != NULL
		   && regcomp(&device_regex, config->device_regex, REG_EXTENDED | REG_NEWLINE)) {
			fprintf(stderr,
			        "Regex to filter devices is invalid, ignoring it.\n");
			regcomp(&device_regex, "", REG_EXTENDED | REG_NEWLINE);
			piglit_merge_result(&result, PIGLIT_WARN);
		}

		/* check for command-line/environment platform */
		platform_defined = piglit_cl_get_platform_arg(argc, (const char**)argv,
		                                              &platform_id);

		/* generate platforms list */
		if(platform_defined) {
			/* use platform defined by command-line/environment */
			num_platforms = 1;
			platform_ids = malloc(sizeof(cl_platform_id));
			platform_ids[0] = platform_id;
		} else {
			/* use all available platforms */
			num_platforms = piglit_cl_get_platform_ids(&platform_ids);
		}

		/* execute test for each platform in platforms list */
		for(i = 0; i < num_platforms; i++) {
			int final_version = version;
			int platform_version;

			platform_id = platform_ids[i];

			/* Filter platform */
			if(config->platform_regex != NULL) {
				char* platform_name;

				platform_name = piglit_cl_get_platform_info(platform_id,
				                                            CL_PLATFORM_NAME);
				if(regexec(&platform_regex, platform_name, 0, NULL, 0)) {
					printf("\n# Skipping platform %s because it does not match platform_regex.\n\n",
					       platform_name);
					free(platform_name);
					continue;
				}
				free(platform_name);
			}

			/* Check platform extensions */
			if(!check_platform_extensions(platform_id, config->require_platform_extensions)) {
				continue;
			}

			/* Get platform version */
			platform_version = piglit_cl_get_platform_version(platform_id);

			if(config->run_per_platform) {
				/* Check platform version */
				if(platform_version < final_version) {
					printf("# Platform supporting only version %d.%d. Running test on that version.\n",
					       platform_version/10, platform_version%10);
					final_version = platform_version;
				}

				/* run test on platform */
				print_test_info(config, final_version, platform_id, NULL);
				piglit_merge_result(&result,
				                    config->_test_run(argc,
				                                      (const char**)argv,
				                                      (void*)config,
				                                      final_version,
				                                      platform_id,
				                                      NULL));
			} else { //config->run_per_device
				int j;

				bool device_defined;
				unsigned int num_devices;
				cl_device_id* device_ids;

				/* check for command-line/environment device */
				device_defined = piglit_cl_get_device_arg(argc,
				                                          (const char**)argv,
				                                          platform_id,
				                                          &device_id);

				/* generate devices list */
				if(device_defined) {
					/* use device defined by command-line/environment */
					num_devices = 1;
					device_ids = malloc(sizeof(cl_device_id));
					device_ids[0] = device_id;
				} else {
					/* use all available devices */
					num_devices = piglit_cl_get_device_ids(platform_id,
					                                       CL_DEVICE_TYPE_ALL,
					                                       &device_ids);
				}

				/* run tests per each device */
				for(j = 0; j < num_devices; j++) {
					int device_version;

					device_id = device_ids[j];

					/* Filter device */
					if(config->device_regex != NULL) {
						char* device_name;

						device_name = piglit_cl_get_device_info(device_id,
						                                        CL_DEVICE_NAME);
						if(regexec(&device_regex, device_name, 0, NULL, 0)) {
							printf("\n# Skipping device %s because it does not match device_regex.\n\n",
								   device_name);
							free(device_name);
							continue;
						}
						free(device_name);
					}

					/* Check device extensions */
					if(!check_device_extensions(device_id, config->require_device_extensions)) {
						continue;
					}

					/* Check platform version */
					if(platform_version < final_version) {
						printf("# Platform supporting only version %d.%d. Running test on that version.\n",
						       platform_version/10, platform_version%10);
						final_version = platform_version;
					}
					/* Check device version */
					device_version = piglit_cl_get_device_version(device_id);
					if(device_version < final_version) {
						printf("# Device supporting only version %d.%d. Running test on that version.\n",
						       device_version/10, device_version%10);
						final_version = device_version;
					}

					print_test_info(config, version, platform_id, device_id);
					piglit_merge_result(&result,
					                    config->_test_run(argc,
					                                      (const char**)argv,
					                                      (void*)config,
					                                      final_version,
					                                      platform_id,
					                                      device_id));
				}

				free(device_ids);
			}
		}

		if(config->platform_regex != NULL) {
			regfree(&platform_regex);
		}
		if(config->device_regex != NULL) {
			regfree(&device_regex);
		}

		free(platform_ids);
	}

	/* Clean */
	if(config->clean_func != NULL) {
		config->clean_func(argc, (const char**)argv, config);
	}

	/* Report merged result */
	printf("# Result:\n");
	piglit_report_result(result);

	/* UNREACHED */
	return 1;
}