| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 | /* StarPU --- Runtime system for heterogeneous multicore architectures. * * Copyright (C) 2011  Institut National de Recherche en Informatique et Automatique * * StarPU is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * StarPU is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU Lesser General Public License in COPYING.LGPL for more details. */#include <starpu.h>#include "generic.h"#include "../../../../common/helper.h"extern struct stats global_stats;static int vector[NX];static starpu_data_handle_t handle;/* * Initially, our vector should be in RAM. It is then used on a CUDA device, * then on an OpenCL device, and finally, on a CUDA device again. * The following operations should be performed, in this specific order : * - CPU -> CUDA conversion * - CUDA kernel execution * - OpenCL kernel execution * - CUDA kernel execution * - CUDA -> CPU conversion * * Note that we will not run any conversion between CUDA and OpenCL, because * StarPU assumes that the data structures used on CUDA and OpenCL devices are * the same. */#if defined(STARPU_USE_CUDA) && defined(STARPU_USE_OPENCL)static inttest(void){	int ret;	struct starpu_task *task_cuda, *task_cuda2, *task_opencl;	static struct starpu_codelet cl_cuda =	{		.where     = STARPU_CUDA,		.cuda_func = cuda_func,		.nbuffers  = 1	};	task_cuda = starpu_task_create();	task_cuda->cl = &cl_cuda;	task_cuda->buffers[0].handle = handle;	task_cuda->buffers[0].mode = STARPU_RW;	ret = starpu_task_submit(task_cuda);	if (ret != 0)		return 1; 	static struct starpu_codelet cl_opencl =	{		.where       = STARPU_OPENCL,		.opencl_funcs = {opencl_func, NULL},		.nbuffers    = 1	};	task_opencl = starpu_task_create();	task_opencl->cl = &cl_opencl;	task_opencl->buffers[0].handle = handle;	task_opencl->buffers[0].mode = STARPU_RW;	ret = starpu_task_submit(task_opencl);	if (ret != 0)		return 1;	task_cuda2 = starpu_task_create();	task_cuda2->cl = &cl_cuda;	task_cuda2->buffers[0].handle = handle;	task_cuda2->buffers[0].mode = STARPU_RW;	ret = starpu_task_submit(task_cuda2);	if (ret != 0)		return 1;	return 0;}#endif /* !(STARPU_USE_CUDA && STARPU_USE_OPENCL) */static voidregister_handle(void){	int i;	for (i = 0; i < NX; i++)		vector[i] = i;	starpu_multiformat_data_register(&handle, 0, vector, NX, &ops);}static voidunregister_handle(void){	starpu_data_unregister(handle);}intmain(void){#if defined(STARPU_USE_CUDA) && defined(STARPU_USE_OPENCL)	int ret;	struct starpu_conf conf =	{		.ncpus   = -1,		.ncuda   = 1,		.nopencl = 1	};	ret = starpu_init(&conf);	if (ret == -ENODEV)		goto enodev;	reset_stats(&global_stats);	register_handle();	ret = test();	unregister_handle();	starpu_shutdown();	if (ret != 0)		return STARPU_TEST_SKIPPED;	struct stats expected_stats =	{#ifdef STARPU_USE_CPU		.cpu           = 0,#endif#ifdef STARPU_USE_CUDA		.cuda          = 2,		.cpu_to_cuda   = 1,		.cuda_to_cpu   = 1,#endif#ifdef STARPU_USE_OPENCL		.opencl        = 1,		.cpu_to_opencl = 0,		.opencl_to_cpu = 0#endif	};		ret = compare_stats(&global_stats, &expected_stats);	if (ret != 0)	{		print_stats(&global_stats);		print_stats(&expected_stats);		return EXIT_FAILURE;	}	return EXIT_SUCCESS;enodev:	return STARPU_TEST_SKIPPED;#else	return STARPU_TEST_SKIPPED;#endif}
 |