示例#1
0
static
int test_codelet(struct starpu_codelet *codelet, int task_insert, int args, int x, float f)
{
        starpu_data_handle_t data_handles[2];
	int xx = x;
	float ff = f;
	int i, ret;

	starpu_variable_data_register(&data_handles[0], STARPU_MAIN_RAM, (uintptr_t)&xx, sizeof(xx));
	starpu_variable_data_register(&data_handles[1], STARPU_MAIN_RAM, (uintptr_t)&ff, sizeof(ff));

        FPRINTF(stderr, "values: %d (%d) %f (%f)\n", xx, _ifactor, ff, _ffactor);

	if (task_insert)
	{
		if (args)
			ret = starpu_task_insert(codelet,
						 STARPU_VALUE, &_ifactor, sizeof(_ifactor),
						 STARPU_VALUE, &_ffactor, sizeof(_ffactor),
						 STARPU_RW, data_handles[0], STARPU_RW, data_handles[1],
						 0);
		else
			ret = starpu_task_insert(codelet,
						 STARPU_RW, data_handles[0], STARPU_RW, data_handles[1],
						 0);
		if (ret == -ENODEV) goto enodev;
		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
	}
	else
	{
		struct starpu_task *task;
		if (args)
			task = starpu_task_build(codelet,
						 STARPU_VALUE, &_ifactor, sizeof(_ifactor),
						 STARPU_VALUE, &_ffactor, sizeof(_ffactor),
						 STARPU_RW, data_handles[0], STARPU_RW, data_handles[1],
						 0);
		else
			task = starpu_task_build(codelet,
						 STARPU_RW, data_handles[0], STARPU_RW, data_handles[1],
						 0);
		task->cl_arg_free = 1;
		ret = starpu_task_submit(task);
		if (ret == -ENODEV) goto enodev;
		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
	}

enodev:
        for(i=0 ; i<2 ; i++)
	{
                starpu_data_unregister(data_handles[i]);
        }

        FPRINTF(stderr, "values: %d (should be %d) %f (should be %f)\n\n", xx, x*_ifactor, ff, f*_ffactor);
	return (ret == -ENODEV ? ret : xx == x*_ifactor && ff == f*_ffactor);
}
int main(int argc, char **argv)
{
	int ret, rank, size;
	starpu_data_handle_t handle;
	int var;

	MPI_Init(&argc, &argv);
	starpu_mpi_comm_rank(MPI_COMM_WORLD, &rank);
	starpu_mpi_comm_size(MPI_COMM_WORLD, &size);

	ret = starpu_init(NULL);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
	ret = starpu_mpi_init(NULL, NULL, 0);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_mpi_init");

	if (size<3)
	{
		FPRINTF(stderr, "We need more than 2 processes.\n");
		starpu_mpi_shutdown();
		starpu_shutdown();
		MPI_Finalize();
		return STARPU_TEST_SKIPPED;
	}

	if (rank == 0)
	{
		int n;
		for(n=1 ; n<size ; n++)
		{
			MPI_Status status;

			FPRINTF_MPI(stderr, "receiving from node %d\n", n);
			starpu_variable_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)&var, sizeof(var));
			starpu_mpi_recv(handle, n, 42, MPI_COMM_WORLD, &status);
			starpu_data_acquire(handle, STARPU_R);
			STARPU_ASSERT_MSG(var == n, "Received incorrect value <%d> from node <%d>\n", var, n);
			FPRINTF_MPI(stderr, "received <%d> from node %d\n", var, n);
			starpu_data_release(handle);
			starpu_data_unregister(handle);
		}
	}
	else
	{
		FPRINTF_MPI(stderr, "sending to node %d\n", 0);
		var = rank;
		starpu_variable_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)&var, sizeof(var));
		starpu_mpi_send(handle, 0, 42, MPI_COMM_WORLD);
		starpu_data_unregister(handle);
	}

	starpu_mpi_shutdown();
	starpu_shutdown();
	MPI_Finalize();

	return 0;
}
示例#3
0
//FIXME: we don't consider offset!!! We assume that ptr targets the same kind of data structure as handle
static int starpu_data_readwrite_buffer(starpu_data_handle handle, void*ptr, size_t offset, size_t size, int num_events, starpu_event *events, starpu_event *event, int direction){
   //FIXME
   assert(offset == 0);

   /* Create temporary variable data on host */
   starpu_data_handle handle2;
   starpu_variable_data_register(&handle2, 0, (uintptr_t)ptr, size);

   struct starpu_readwrite_buffer_args * arg = malloc(sizeof(struct starpu_readwrite_buffer_args));
   arg->direction = direction;

   if (direction) {
      arg->src_handle = handle;
      arg->dst_handle = handle2;
   }
   else {
      arg->src_handle = handle2;
      arg->dst_handle = handle;
   }

   arg->event = _starpu_event_create();

   if (event != NULL) {
      starpu_event_retain(arg->event);
      *event = arg->event;
   }

   /* We create a trigger that will post the request */
   starpu_trigger trigger = _starpu_trigger_create(enqueue_readwrite_callback, arg, NULL);
   _starpu_trigger_events_register(trigger, num_events, events);
   _starpu_trigger_enable(trigger);

   return 0;
}
示例#4
0
int main(int argc, char **argv)
{
	int v=40;
	int ret;

	ret = starpu_init(NULL);
	if (ret == -ENODEV)
		return 77;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");

	starpu_variable_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)&v, sizeof(int));
	double *x = (double*)malloc(sizeof(double));

	struct starpu_task *task = starpu_task_create();
	task->cl = &cl;
	task->prologue_callback_func = callback_func;
	task->prologue_callback_arg = NULL;

	task->prologue_callback_pop_func = pop_prologue_callback_func;
	task->prologue_callback_pop_arg = (void*) 5;

	task->handles[0] = handle;

	ret = starpu_task_submit(task);
	if (ret == -ENODEV) goto enodev;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");

	*x = -999.0;
	ret = starpu_task_insert(&cl,
				 STARPU_RW, handle,
				 STARPU_PROLOGUE_CALLBACK, prologue_callback_func,
				 STARPU_PROLOGUE_CALLBACK_ARG, x,
				 STARPU_PROLOGUE_CALLBACK_POP, pop_prologue_callback_func,
				 STARPU_PROLOGUE_CALLBACK_POP_ARG, 5,
				 0);
	if (ret == -ENODEV) goto enodev;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");

	starpu_task_wait_for_all();

enodev:
	starpu_data_unregister(handle);
	free(x);
	FPRINTF(stderr, "v -> %d\n", v);
	starpu_shutdown();
	return (ret == -ENODEV) ? 77 : 0;
}
int main(int argc, char **argv)
{
	int ret;

	ret = starpu_initialize(NULL, &argc, &argv);
	if (ret == -ENODEV) return STARPU_TEST_SKIPPED;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");

	unsigned b;
	for (b = 0; b < NBUFFERS; b++)
	{
		buffers[b].index = b;
		starpu_variable_data_register(&buffers[b].handle, STARPU_MAIN_RAM, (uintptr_t)&buffers[b].val, sizeof(unsigned));
	}

	unsigned iter;
	for (iter = 0; iter < NITER; iter++)
	{
		for (b = 0; b < NBUFFERS; b++)
		{
			ret = starpu_data_acquire_cb(buffers[b].handle, STARPU_RW,
						     callback_sync_data, &buffers[b]);
			STARPU_CHECK_RETURN_VALUE(ret, "starpu_data_acquire_cb");
		}
	}

	ret = starpu_task_wait_for_all();
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_wait_for_all");

	/* do some cleanup */
	ret = EXIT_SUCCESS;
	for (b = 0; b < NBUFFERS; b++)
	{
		starpu_data_unregister(buffers[b].handle);

		/* check result */
		if (buffers[b].val != NITER)
		{
			FPRINTF(stderr, "buffer[%u] = %u should be %d\n", b, buffers[b].val, NITER);
			ret = EXIT_FAILURE;
		}
	}

	starpu_shutdown();

	return ret;
}
int exchange_variable(int rank, int detached)
{
	int ret, i;
	starpu_data_handle_t tab_handle[NB];
	int value[NB];

	FPRINTF_MPI(stderr, "Exchanging variable data with detached=%d\n", detached);

	for(i=0 ; i<NB ; i++)
	{
		value[i]=i*rank;
		starpu_variable_data_register(&tab_handle[i], STARPU_MAIN_RAM, (uintptr_t)&value[i], sizeof(int));
		starpu_mpi_data_register(tab_handle[i], i, rank);
	}
	ret = exchange(rank, tab_handle, check_variable, detached);
	for(i=0 ; i<NB ; i++)
		starpu_data_unregister(tab_handle[i]);

	return ret;
}
int main(int argc, char **argv)
{
     int ret;
     int var = 42;
     starpu_data_handle_t handle;

     ret = starpu_init(NULL);
     if (ret == -ENODEV) return STARPU_TEST_SKIPPED;
     STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");

     int copy = starpu_asynchronous_copy_disabled();
     FPRINTF(stderr, "copy %d\n", copy);

     starpu_variable_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)&var, sizeof(var));

     ret = starpu_task_insert(&cl,
			      STARPU_R, handle,
			      0);
     if (ret == -ENODEV) goto enodev;
     STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");

     starpu_task_wait_for_all();

     starpu_data_unregister(handle);

     starpu_shutdown();

     return 0;

enodev:
     starpu_data_unregister(handle);
     starpu_shutdown();
     /* yes, we do not perform the computation but we did detect that no one
      * could perform the kernel, so this is not an error from StarPU */
     fprintf(stderr, "WARNING: No one can execute this task\n");
     return STARPU_TEST_SKIPPED;
}
int main(int argc, char **argv)
{
	int ret;

	/* Not supported yet */
	if (starpu_get_env_number_default("STARPU_GLOBAL_ARBITER", 0) > 0)
		return 77;

	ret = starpu_init(NULL);
	if (ret == -ENODEV)
		return 77;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");

#ifdef STARPU_USE_OPENCL
	ret = starpu_opencl_load_opencl_from_file("examples/reductions/dot_product_opencl_kernels.cl",
						  &_opencl_program, NULL);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_opencl_load_opencl_from_file");
#endif

#ifdef STARPU_USE_CUDA
	/* cublasSdot has synchronization issues when using a non-blocking stream */
	cublasGetVersion(&cublas_version);
	if (cublas_version >= 7050)
		starpu_cublas_init();
#endif

	unsigned long nelems = _nblocks*_entries_per_block;
	size_t size = nelems*sizeof(float);

	_x = (float *) malloc(size);
	_y = (float *) malloc(size);

	_x_handles = (starpu_data_handle_t *) calloc(_nblocks, sizeof(starpu_data_handle_t));
	_y_handles = (starpu_data_handle_t *) calloc(_nblocks, sizeof(starpu_data_handle_t));

	assert(_x && _y);

        starpu_srand48(0);

	DOT_TYPE reference_dot = 0.0;

	unsigned long i;
	for (i = 0; i < nelems; i++)
	{
		_x[i] = (float)starpu_drand48();
		_y[i] = (float)starpu_drand48();

		reference_dot += (DOT_TYPE)_x[i]*(DOT_TYPE)_y[i];
	}

	unsigned block;
	for (block = 0; block < _nblocks; block++)
	{
		starpu_vector_data_register(&_x_handles[block], STARPU_MAIN_RAM,
			(uintptr_t)&_x[_entries_per_block*block], _entries_per_block, sizeof(float));
		starpu_vector_data_register(&_y_handles[block], STARPU_MAIN_RAM,
			(uintptr_t)&_y[_entries_per_block*block], _entries_per_block, sizeof(float));
	}

	starpu_variable_data_register(&_dot_handle, STARPU_MAIN_RAM, (uintptr_t)&_dot, sizeof(DOT_TYPE));

	/*
	 *	Compute dot product with StarPU
	 */
	starpu_data_set_reduction_methods(_dot_handle, &redux_codelet, &init_codelet);

	for (block = 0; block < _nblocks; block++)
	{
		struct starpu_task *task = starpu_task_create();

		task->cl = &dot_codelet;
		task->destroy = 1;

		task->handles[0] = _x_handles[block];
		task->handles[1] = _y_handles[block];
		task->handles[2] = _dot_handle;

		ret = starpu_task_submit(task);
		if (ret == -ENODEV) goto enodev;
		STARPU_ASSERT(!ret);
	}

	for (block = 0; block < _nblocks; block++)
	{
		starpu_data_unregister(_x_handles[block]);
		starpu_data_unregister(_y_handles[block]);
	}
	starpu_data_unregister(_dot_handle);

	FPRINTF(stderr, "Reference : %e vs. %e (Delta %e)\n", reference_dot, _dot, reference_dot - _dot);

#ifdef STARPU_USE_CUDA
	if (cublas_version >= 7050)
		starpu_cublas_shutdown();
#endif

#ifdef STARPU_USE_OPENCL
        ret = starpu_opencl_unload_opencl(&_opencl_program);
        STARPU_CHECK_RETURN_VALUE(ret, "starpu_opencl_unload_opencl");
#endif
	starpu_shutdown();

	free(_x);
	free(_y);
	free(_x_handles);
	free(_y_handles);

	if (fabs(reference_dot - _dot) < reference_dot * 1e-6)
		return EXIT_SUCCESS;
	else
		return EXIT_FAILURE;

enodev:
	fprintf(stderr, "WARNING: No one can execute this task\n");
	/* yes, we do not perform the computation but we did detect that no one
 	 * could perform the kernel, so this is not an error from StarPU */
	return 77;
}
示例#9
0
文件: variable.c 项目: alucas/StarPU
int main(int argc, char **argv)
{
	unsigned i;
        float foo;
	starpu_data_handle float_array_handle;
	starpu_codelet cl;

	starpu_init(NULL);
        if (argc == 2) niter = atoi(argv[1]);
        foo = 0.0f;

	starpu_variable_data_register(&float_array_handle, 0 /* home node */,
                                      (uintptr_t)&foo, sizeof(float));

#ifdef STARPU_USE_OPENCL
        starpu_opencl_load_opencl_from_file("examples/basic_examples/variable_kernels_opencl_codelet.cl", &opencl_code);
#endif

	cl.where = STARPU_CPU|STARPU_CUDA|STARPU_OPENCL;
        cl.cpu_func = cpu_codelet;
#ifdef STARPU_USE_CUDA
        cl.cuda_func = cuda_codelet;
#endif
#ifdef STARPU_USE_OPENCL
        cl.opencl_func = opencl_codelet;
#endif
        cl.nbuffers = 1;
        cl.model = NULL;

	for (i = 0; i < niter; i++)
	{
		struct starpu_task *task = starpu_task_create();
                int ret;

		task->cl = &cl;

		task->callback_func = NULL;

		task->buffers[0].handle = float_array_handle;
		task->buffers[0].mode = STARPU_RW;

		ret = starpu_task_submit(task, NULL);
		if (STARPU_UNLIKELY(ret == -ENODEV))
		{
			fprintf(stderr, "No worker may execute this task\n");
			exit(0);
		}
	}

	starpu_task_wait_for_all();

	/* update the array in RAM */
	starpu_data_acquire(float_array_handle, STARPU_R);

	fprintf(stderr, "variable -> %f\n", foo);

	starpu_data_release(float_array_handle);

	starpu_shutdown();

	return 0;
}
示例#10
0
int main(int argc, char **argv)
{
	int ret, rank, size;

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);

	if (size<3)
	{
		FPRINTF(stderr, "We need more than 2 processes.\n");
		MPI_Finalize();
		return STARPU_TEST_SKIPPED;
	}

	ret = starpu_init(NULL);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
	ret = starpu_mpi_init(NULL, NULL, 0);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_mpi_init");

	if (rank == 0)
	{
		int n;
		for(n=1 ; n<size ; n++)
		{
			int i, var[2];
			MPI_Status status[3];
			starpu_data_handle_t handle[2];

			FPRINTF_MPI(stderr, "receiving from node %d\n", n);
			for(i=0 ; i<2 ; i++)
				starpu_variable_data_register(&handle[i], STARPU_MAIN_RAM, (uintptr_t)&var[i], sizeof(var[i]));

			starpu_mpi_recv(handle[0], n, 42, MPI_COMM_WORLD, &status[0]);
			starpu_data_acquire(handle[0], STARPU_R);
			STARPU_ASSERT_MSG(var[0] == n, "Received incorrect value <%d> from node <%d>\n", var[0], n);
			FPRINTF_MPI(stderr, "received <%d> from node %d\n", var[0], n);
			starpu_data_release(handle[0]);

			starpu_mpi_recv(handle[0], n, 42, MPI_COMM_WORLD, &status[1]);
			starpu_mpi_recv(handle[1], n, 44, MPI_COMM_WORLD, &status[2]);
			for(i=0 ; i<2 ; i++)
				starpu_data_acquire(handle[i], STARPU_R);
			STARPU_ASSERT_MSG(var[0] == n*2, "Received incorrect value <%d> from node <%d>\n", var[0], n);
			STARPU_ASSERT_MSG(var[1] == n*4, "Received incorrect value <%d> from node <%d>\n", var[0], n);
			FPRINTF_MPI(stderr, "received <%d> and <%d> from node %d\n", var[0], var[1], n);
			for(i=0 ; i<2 ; i++)
				starpu_data_release(handle[i]);
			for(i=0 ; i<2 ; i++)
				starpu_data_unregister(handle[i]);
		}
	}
	else
	{
		int i, var[3];
		starpu_data_handle_t handle[3];

		FPRINTF_MPI(stderr, "sending to node %d\n", 0);
		var[0] = rank;
		var[1] = var[0] * 2;
		var[2] = var[0] * 4;
		for(i=0 ; i<3 ; i++)
			starpu_variable_data_register(&handle[i], STARPU_MAIN_RAM, (uintptr_t)&var[i], sizeof(var[i]));
		starpu_mpi_send(handle[0], 0, 42, MPI_COMM_WORLD);
		starpu_mpi_send(handle[1], 0, 42, MPI_COMM_WORLD);
		starpu_mpi_send(handle[2], 0, 44, MPI_COMM_WORLD);
		for(i=0 ; i<3 ; i++)
			starpu_data_unregister(handle[i]);
	}

	starpu_mpi_shutdown();
	starpu_shutdown();
	MPI_Finalize();

	return 0;
}
示例#11
0
int main(int argc, char **argv)
{
	int size, n, x=789;
	int rank, other_rank;
	int ret;
	starpu_data_handle_t data[2];

        MPI_Init(&argc, &argv);
        starpu_mpi_comm_rank(MPI_COMM_WORLD, &rank);
        starpu_mpi_comm_size(MPI_COMM_WORLD, &size);

        if (size % 2)
        {
		FPRINTF(stderr, "We need a even number of processes.\n");
                MPI_Finalize();
                return STARPU_TEST_SKIPPED;
        }

	other_rank = rank%2 == 0 ? rank+1 : rank-1;
	FPRINTF_MPI(stderr, "rank %d exchanging with rank %d\n", rank, other_rank);

	if (rank % 2)
	{
		MPI_Send(&rank, 1, MPI_INT, other_rank, 10, MPI_COMM_WORLD);
		FPRINTF(stderr, "[%d] sending %d\n", rank, rank);
	}
	else
	{
		MPI_Recv(&x, 1, MPI_INT, other_rank, 10, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		FPRINTF(stderr, "[%d] received %d\n", rank, x);
	}

        ret = starpu_init(NULL);
        STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
        ret = starpu_mpi_init(NULL, NULL, 0);
        STARPU_CHECK_RETURN_VALUE(ret, "starpu_mpi_init");

	if (rank % 2)
	{
		starpu_variable_data_register(&data[0], STARPU_MAIN_RAM, (uintptr_t)&rank, sizeof(unsigned));
		starpu_variable_data_register(&data[1], STARPU_MAIN_RAM, (uintptr_t)&rank, sizeof(unsigned));
		starpu_mpi_data_register(data[1], 22, 0);
	}
	else
		starpu_variable_data_register(&data[0], -1, (uintptr_t)NULL, sizeof(unsigned));
	starpu_mpi_data_register(data[0], 12, 0);

	if (rank % 2)
	{
		starpu_mpi_req req;
		starpu_mpi_issend(data[1], &req, other_rank, 22, MPI_COMM_WORLD);
		starpu_mpi_send(data[0], other_rank, 12, MPI_COMM_WORLD);
		starpu_mpi_wait(&req, MPI_STATUS_IGNORE);
	}
	else
	{
		int *xx;

		starpu_mpi_recv(data[0], other_rank, 12, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		xx = (int *)starpu_variable_get_local_ptr(data[0]);
		FPRINTF_MPI(stderr, "received %d\n", *xx);
		STARPU_ASSERT_MSG(x==*xx, "Received value %d is incorrect (should be %d)\n", *xx, x);

		starpu_variable_data_register(&data[1], -1, (uintptr_t)NULL, sizeof(unsigned));
		starpu_mpi_data_register(data[1], 22, 0);
		starpu_mpi_recv(data[0],  other_rank, 22, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		xx = (int *)starpu_variable_get_local_ptr(data[0]);
		STARPU_ASSERT_MSG(x==*xx, "Received value %d is incorrect (should be %d)\n", *xx, x);
	}

	starpu_data_unregister(data[0]);
	starpu_data_unregister(data[1]);

	starpu_mpi_shutdown();
	starpu_shutdown();
        MPI_Finalize();
	return 0;
}
示例#12
0
int main(int argc, char **argv)
{
	int size, x;
	int color;
	MPI_Comm newcomm;
	int rank, newrank;
	int ret;
	starpu_data_handle_t data[3];
	int value = 90;

        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &size);

        if (size < 4)
        {
		FPRINTF(stderr, "We need at least 4 processes.\n");
                MPI_Finalize();
                return STARPU_TEST_SKIPPED;
        }

	color = rank%2;
	MPI_Comm_split(MPI_COMM_WORLD, color, rank, &newcomm);
	MPI_Comm_rank(newcomm, &newrank);
	FPRINTF(stderr, "[%d][%d] color %d\n", rank, newrank, color);

	if (newrank == 0)
	{
		FPRINTF(stderr, "[%d][%d] sending %d\n", rank, newrank, rank);
		MPI_Send(&rank, 1, MPI_INT, 1, 10, newcomm);
	}
	else if (newrank == 1)
	{
		MPI_Recv(&x, 1, MPI_INT, 0, 10, newcomm, MPI_STATUS_IGNORE);
		FPRINTF(stderr, "[%d][%d] received %d\n", rank, newrank, x);
	}

        ret = starpu_init(NULL);
        STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
        ret = starpu_mpi_init(NULL, NULL, 0);
        STARPU_CHECK_RETURN_VALUE(ret, "starpu_mpi_init");

	if (rank == 0)
	{
		starpu_variable_data_register(&data[2], STARPU_MAIN_RAM, (uintptr_t)&value, sizeof(int));
	}
	else
		starpu_variable_data_register(&data[2], -1, (uintptr_t)NULL, sizeof(int));
	starpu_mpi_data_register_comm(data[2], 44, 0, MPI_COMM_WORLD);

	if (newrank == 0)
	{
		starpu_variable_data_register(&data[0], STARPU_MAIN_RAM, (uintptr_t)&rank, sizeof(int));
		starpu_variable_data_register(&data[1], STARPU_MAIN_RAM, (uintptr_t)&rank, sizeof(int));
		starpu_mpi_data_register_comm(data[1], 22, 0, newcomm);
	}
	else
		starpu_variable_data_register(&data[0], -1, (uintptr_t)NULL, sizeof(int));
	starpu_mpi_data_register_comm(data[0], 12, 0, newcomm);

	if (newrank == 0)
	{
		starpu_mpi_req req[2];
		starpu_mpi_issend(data[1], &req[0], 1, 22, newcomm);
		starpu_mpi_isend(data[0], &req[1], 1, 12, newcomm);
		starpu_mpi_wait(&req[0], MPI_STATUS_IGNORE);
		starpu_mpi_wait(&req[1], MPI_STATUS_IGNORE);
	}
	else if (newrank == 1)
	{
		int *xx;

		starpu_mpi_recv(data[0], 0, 12, newcomm, MPI_STATUS_IGNORE);
		starpu_data_acquire(data[0], STARPU_RW);
		xx = (int *)starpu_variable_get_local_ptr(data[0]);
		starpu_data_release(data[0]);
		FPRINTF(stderr, "[%d][%d] received %d\n", rank, newrank, *xx);
		STARPU_ASSERT_MSG(x==*xx, "Received value %d is incorrect (should be %d)\n", *xx, x);

		starpu_variable_data_register(&data[1], -1, (uintptr_t)NULL, sizeof(int));
		starpu_mpi_data_register_comm(data[1], 22, 0, newcomm);
		starpu_mpi_recv(data[0], 0, 22, newcomm, MPI_STATUS_IGNORE);
		starpu_data_acquire(data[0], STARPU_RW);
		xx = (int *)starpu_variable_get_local_ptr(data[0]);
		starpu_data_release(data[0]);
		FPRINTF(stderr, "[%d][%d] received %d\n", rank, newrank, *xx);
		STARPU_ASSERT_MSG(x==*xx, "Received value %d is incorrect (should be %d)\n", *xx, x);
	}

	if (rank == 0)
	{
		starpu_data_acquire(data[2], STARPU_RW);
		int rvalue = *((int *)starpu_variable_get_local_ptr(data[2]));
		starpu_data_release(data[2]);
		FPRINTF_MPI(stderr, "sending value %d to %d and receiving from %d\n", rvalue, 1, size-1);
		starpu_mpi_send(data[2], 1, 44, MPI_COMM_WORLD);
		starpu_mpi_recv(data[2], size-1, 44, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		starpu_data_acquire(data[2], STARPU_RW);
		int *xx = (int *)starpu_variable_get_local_ptr(data[2]);
		starpu_data_release(data[2]);
		FPRINTF_MPI(stderr, "Value back is %d\n", *xx);
		STARPU_ASSERT_MSG(*xx == rvalue + (2*(size-1)), "Received value %d is incorrect (should be %d)\n", *xx, rvalue + (2*(size-1)));
	}
	else
	{
		int next = (rank == size-1) ? 0 : rank+1;
		starpu_mpi_recv(data[2], rank-1, 44, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		starpu_data_acquire(data[2], STARPU_RW);
		int *xx = (int *)starpu_variable_get_local_ptr(data[2]);
		FPRINTF_MPI(stderr, "receiving %d from %d and sending %d to %d\n", *xx, rank-1, *xx+2, next);
		*xx = *xx + 2;
		starpu_data_release(data[2]);
		starpu_mpi_send(data[2], next, 44, MPI_COMM_WORLD);
	}

	if (newrank == 0 || newrank == 1)
	{
		starpu_mpi_insert_task(newcomm, &mycodelet,
				       STARPU_RW, data[0],
				       STARPU_VALUE, &x, sizeof(x),
				       STARPU_EXECUTE_ON_NODE, 1,
				       0);

		starpu_task_wait_for_all();
		starpu_data_unregister(data[0]);
		starpu_data_unregister(data[1]);
	}
	starpu_data_unregister(data[2]);

	starpu_mpi_shutdown();
	starpu_shutdown();
	MPI_Comm_free(&newcomm);
        MPI_Finalize();
	return 0;
}
示例#13
0
int main(int argc, char **argv)
{
	int my_rank, size, x, y, loop;
	float mean=0;
	float matrix[X][Y];
	starpu_data_handle_t data_handles[X][Y];

	int ret = starpu_init(NULL);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
	starpu_mpi_init(&argc, &argv, 1);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);

	parse_args(argc, argv);

	/* Initial data values */
	starpu_srand48((long int)time(NULL));
	for(x = 0; x < X; x++)
	{
		for (y = 0; y < Y; y++)
		{
			matrix[x][y] = (float)starpu_drand48();
			mean += matrix[x][y];
		}
	}
	mean /= (X*Y);

	if (display)
	{
		FPRINTF_MPI(stdout, "mean=%2.2f\n", mean);
		for(x = 0; x < X; x++)
		{
			fprintf(stdout, "[%d] ", my_rank);
			for (y = 0; y < Y; y++)
			{
				fprintf(stdout, "%2.2f ", matrix[x][y]);
			}
			fprintf(stdout, "\n");
		}
	}

	/* Initial distribution */
	for(x = 0; x < X; x++)
	{
		for (y = 0; y < Y; y++)
		{
			int mpi_rank = my_distrib(x, y, size);
			if (mpi_rank == my_rank)
			{
				//FPRINTF(stderr, "[%d] Owning data[%d][%d]\n", my_rank, x, y);
				starpu_variable_data_register(&data_handles[x][y], 0, (uintptr_t)&(matrix[x][y]), sizeof(float));
			}
			else if (my_rank == my_distrib(x+1, y, size) || my_rank == my_distrib(x-1, y, size)
				 || my_rank == my_distrib(x, y+1, size) || my_rank == my_distrib(x, y-1, size))
			{
				/* I don't own that index, but will need it for my computations */
				//FPRINTF(stderr, "[%d] Neighbour of data[%d][%d]\n", my_rank, x, y);
				starpu_variable_data_register(&data_handles[x][y], -1, (uintptr_t)NULL, sizeof(float));
			}
			else
			{
				/* I know it's useless to allocate anything for this */
				data_handles[x][y] = NULL;
			}
			if (data_handles[x][y])
			{
				starpu_mpi_data_register(data_handles[x][y], (y*X)+x, mpi_rank);
			}
		}
	}

	/* First computation with initial distribution */
	for(loop=0 ; loop<niter; loop++)
	{
		for (x = 1; x < X-1; x++)
		{
			for (y = 1; y < Y-1; y++)
			{
				starpu_mpi_task_insert(MPI_COMM_WORLD, &stencil5_cl, STARPU_RW, data_handles[x][y],
						       STARPU_R, data_handles[x-1][y], STARPU_R, data_handles[x+1][y],
						       STARPU_R, data_handles[x][y-1], STARPU_R, data_handles[x][y+1],
						       0);
			}
		}
	}
	FPRINTF(stderr, "Waiting ...\n");
	starpu_task_wait_for_all();

	/* Now migrate data to a new distribution */

	/* First register newly needed data */
	for(x = 0; x < X; x++)
	{
		for (y = 0; y < Y; y++)
		{
			int mpi_rank = my_distrib2(x, y, size);
			if (!data_handles[x][y] && (mpi_rank == my_rank
				 || my_rank == my_distrib2(x+1, y, size) || my_rank == my_distrib2(x-1, y, size)
				 || my_rank == my_distrib2(x, y+1, size) || my_rank == my_distrib2(x, y-1, size)))
			{
				/* Register newly-needed data */
				starpu_variable_data_register(&data_handles[x][y], -1, (uintptr_t)NULL, sizeof(float));
				starpu_mpi_data_register(data_handles[x][y], (y*X)+x, mpi_rank);
			}
			if (data_handles[x][y] && mpi_rank != starpu_mpi_data_get_rank(data_handles[x][y]))
			{
				/* Migrate the data */
				starpu_mpi_get_data_on_node_detached(MPI_COMM_WORLD, data_handles[x][y], mpi_rank, NULL, NULL);
				/* And register new rank of the matrix */
				starpu_mpi_data_set_rank(data_handles[x][y], mpi_rank);
			}
		}
	}

	/* Second computation with new distribution */
	for(loop=0 ; loop<niter; loop++)
	{
		for (x = 1; x < X-1; x++)
		{
			for (y = 1; y < Y-1; y++)
			{
				starpu_mpi_task_insert(MPI_COMM_WORLD, &stencil5_cl, STARPU_RW, data_handles[x][y],
						       STARPU_R, data_handles[x-1][y], STARPU_R, data_handles[x+1][y],
						       STARPU_R, data_handles[x][y-1], STARPU_R, data_handles[x][y+1],
						       0);
			}
		}
	}
	FPRINTF(stderr, "Waiting ...\n");
	starpu_task_wait_for_all();

	/* Unregister data */
	for(x = 0; x < X; x++)
	{
		for (y = 0; y < Y; y++)
		{
			if (data_handles[x][y])
			{
				int mpi_rank = my_distrib(x, y, size);
				/* Get back data to original place where the user-provided buffer is. */
				starpu_mpi_get_data_on_node_detached(MPI_COMM_WORLD, data_handles[x][y], mpi_rank, NULL, NULL);
				/* Register original rank of the matrix (although useless) */
				starpu_mpi_data_set_rank(data_handles[x][y], mpi_rank);
				/* And unregister it */
				starpu_data_unregister(data_handles[x][y]);
			}
		}
	}

	starpu_mpi_shutdown();
	starpu_shutdown();

	if (display)
	{
		FPRINTF(stdout, "[%d] mean=%2.2f\n", my_rank, mean);
		for(x = 0; x < X; x++)
		{
			FPRINTF(stdout, "[%d] ", my_rank);
			for (y = 0; y < Y; y++)
			{
				FPRINTF(stdout, "%2.2f ", matrix[x][y]);
			}
			FPRINTF(stdout, "\n");
		}
	}

	return 0;
}
int main(int argc, char **argv)
{
	int rank, size, err;
	int x[2];
	int ret, i;
	starpu_data_handle_t data_handles[2];
	int values[2];

	ret = starpu_init(NULL);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
	ret = starpu_mpi_init(&argc, &argv, 1);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_mpi_init");
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);

	if (rank == 0)
	{
		x[0] = 11;
		starpu_variable_data_register(&data_handles[0], STARPU_MAIN_RAM, (uintptr_t)&x[0], sizeof(x[0]));
		starpu_variable_data_register(&data_handles[1], -1, (uintptr_t)NULL, sizeof(x[1]));
	}
	else if (rank == 1)
	{
		x[1] = 12;
		starpu_variable_data_register(&data_handles[0], -1, (uintptr_t)NULL, sizeof(x[0]));
		starpu_variable_data_register(&data_handles[1], STARPU_MAIN_RAM, (uintptr_t)&x[1], sizeof(x[1]));
	}
	else
	{
		starpu_variable_data_register(&data_handles[0], -1, (uintptr_t)NULL, sizeof(x[0]));
		starpu_variable_data_register(&data_handles[1], -1, (uintptr_t)NULL, sizeof(x[1]));
	}

	starpu_mpi_data_register(data_handles[0], 0, 0);
	starpu_mpi_data_register(data_handles[1], 1, 1);

	err = starpu_mpi_task_insert(MPI_COMM_WORLD, &mycodelet,
				     STARPU_RW, data_handles[0], STARPU_RW, data_handles[1],
				     STARPU_EXECUTE_ON_DATA, data_handles[1],
				     0);
	assert(err == 0);
	starpu_task_wait_for_all();

	for(i=0 ; i<2 ; i++)
	{
		starpu_mpi_get_data_on_node_detached(MPI_COMM_WORLD, data_handles[i], 0, NULL, NULL);
		if (rank == 0)
		{
			starpu_data_acquire(data_handles[i], STARPU_R);
			values[i] = *((int *)starpu_data_get_local_ptr(data_handles[i]));
			starpu_data_release(data_handles[i]);		}
	}
	ret = 0;
	if (rank == 0)
	{
		FPRINTF(stderr, "[%d][local ptr] VALUES: %d %d\n", rank, values[0], values[1]);
		if (values[0] != 12 || values[1] != 144)
		{
			ret = EXIT_FAILURE;
		}
	}

	starpu_data_unregister(data_handles[0]);
	starpu_data_unregister(data_handles[1]);

	starpu_mpi_shutdown();
	starpu_shutdown();

	return ret;
}
int main(int argc, char **argv)
{
	int ret, rank, size, err, node;
	long x0=32;
	int x1=23;
	starpu_data_handle_t data_handlesx0;
	starpu_data_handle_t data_handlesx1;

	ret = starpu_init(NULL);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
	ret = starpu_mpi_init(&argc, &argv, 1);
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_mpi_init");
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);

	if (rank != 0 && rank != 1) goto end;

	if (rank == 0)
	{
		starpu_variable_data_register(&data_handlesx0, STARPU_MAIN_RAM, (uintptr_t)&x0, sizeof(x0));
		starpu_mpi_data_register(data_handlesx0, 0, rank);
		starpu_variable_data_register(&data_handlesx1, -1, (uintptr_t)NULL, sizeof(x1));
		starpu_mpi_data_register(data_handlesx1, 1, 1);
	}
	else if (rank == 1)
	{
		starpu_variable_data_register(&data_handlesx1, STARPU_MAIN_RAM, (uintptr_t)&x1, sizeof(x1));
		starpu_mpi_data_register(data_handlesx1, 1, rank);
		starpu_variable_data_register(&data_handlesx0, -1, (uintptr_t)NULL, sizeof(x0));
		starpu_mpi_data_register(data_handlesx0, 0, 0);
	}

	node = starpu_mpi_data_get_rank(data_handlesx1);
	err = starpu_mpi_task_insert(MPI_COMM_WORLD, &mycodelet_r_w,
				     STARPU_VALUE, &node, sizeof(node),
				     STARPU_R, data_handlesx0, STARPU_W, data_handlesx1,
				     0);
	assert(err == 0);

	node = starpu_mpi_data_get_rank(data_handlesx0);
	err = starpu_mpi_task_insert(MPI_COMM_WORLD, &mycodelet_rw_r,
				     STARPU_VALUE, &node, sizeof(node),
				     STARPU_RW, data_handlesx0, STARPU_R, data_handlesx1,
				     0);
	assert(err == 0);

	err = starpu_mpi_task_insert(MPI_COMM_WORLD, &mycodelet_rw_rw,
				     STARPU_VALUE, &node, sizeof(node),
				     STARPU_RW, data_handlesx0, STARPU_RW, data_handlesx1,
				     0);
	assert(err == 0);

	node = 1;
	err = starpu_mpi_task_insert(MPI_COMM_WORLD, &mycodelet_rw_rw,
				     STARPU_VALUE, &node, sizeof(node),
				     STARPU_RW, data_handlesx0, STARPU_RW, data_handlesx1, STARPU_EXECUTE_ON_NODE, node,
				     0);
	assert(err == 0);

	node = 0;
	err = starpu_mpi_task_insert(MPI_COMM_WORLD, &mycodelet_rw_rw,
				     STARPU_VALUE, &node, sizeof(node),
				     STARPU_RW, data_handlesx0, STARPU_RW, data_handlesx1, STARPU_EXECUTE_ON_NODE, node,
				     0);
	assert(err == 0);

	node = 0;
	err = starpu_mpi_task_insert(MPI_COMM_WORLD, &mycodelet_r_r,
				     STARPU_VALUE, &node, sizeof(node),
				     STARPU_R, data_handlesx0, STARPU_R, data_handlesx1, STARPU_EXECUTE_ON_NODE, node,
				     0);
	assert(err == 0);

	/* Here the value specified by the property STARPU_EXECUTE_ON_NODE is
	   going to overwrite the node even though the data model clearly specifies
	   which node is going to execute the codelet */
	node = 0;
	err = starpu_mpi_task_insert(MPI_COMM_WORLD, &mycodelet_r_w,
				     STARPU_VALUE, &node, sizeof(node),
				     STARPU_R, data_handlesx0, STARPU_W, data_handlesx1, STARPU_EXECUTE_ON_NODE, node,
				     0);
	assert(err == 0);

	/* Here the value specified by the property STARPU_EXECUTE_ON_NODE is
	   going to overwrite the node even though the data model clearly specifies
	   which node is going to execute the codelet */
	node = 0;
	err = starpu_mpi_task_insert(MPI_COMM_WORLD, &mycodelet_w_r,
				     STARPU_VALUE, &node, sizeof(node),
				     STARPU_W, data_handlesx0, STARPU_R, data_handlesx1, STARPU_EXECUTE_ON_NODE, node,
				     0);
	assert(err == 0);

	FPRINTF_MPI(stderr, "Waiting ...\n");
	starpu_task_wait_for_all();
	starpu_data_unregister(data_handlesx0);
	starpu_data_unregister(data_handlesx1);

end:
	starpu_mpi_shutdown();
	starpu_shutdown();

	return 0;
}
示例#16
0
int do_test(int rank, int sdetached, int rdetached)
{
	int ret, i;
	int val[2];
	starpu_data_handle_t data[2];

	ret = starpu_init(NULL);
        STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
        ret = starpu_mpi_init(NULL, NULL, 0);
        STARPU_CHECK_RETURN_VALUE(ret, "starpu_mpi_init");

	if (rank == 1)
	{
		val[0] = VAL0;
		val[1] = VAL1;
	}
	else
	{
		val[0] = -1;
		val[1] = -1;
	}
	starpu_variable_data_register(&data[0], STARPU_MAIN_RAM, (uintptr_t)&val[0], sizeof(val[0]));
	starpu_variable_data_register(&data[1], STARPU_MAIN_RAM, (uintptr_t)&val[1], sizeof(val[1]));
	starpu_mpi_data_register(data[0], 77, 1);
	starpu_mpi_data_register(data[1], 88, 1);

	if (rank == 1)
	{
		for(i=1 ; i>=0 ; i--)
		{
			if (sdetached)
				starpu_mpi_isend_detached(data[i], 0, starpu_data_get_tag(data[i]), MPI_COMM_WORLD, NULL, NULL);
			else
				starpu_mpi_send(data[i], 0, starpu_data_get_tag(data[i]), MPI_COMM_WORLD);
		}
	}
	else if (rank == 0)
	{
		int received = 0;

		for(i=0 ; i<2 ; i++)
			FPRINTF_MPI(stderr, "Value[%d] = %d\n", i, val[i]);
		for(i=0 ; i<2 ; i++)
		{
			if (rdetached)
				starpu_mpi_irecv_detached(data[i], 1, starpu_data_get_tag(data[i]), MPI_COMM_WORLD, callback, &received);
			else
				starpu_mpi_recv(data[i], 1, starpu_data_get_tag(data[i]), MPI_COMM_WORLD, MPI_STATUS_IGNORE);
		}

		if (rdetached)
		{
			STARPU_PTHREAD_MUTEX_LOCK(&mutex);
			while (received != 2)
			{
				FPRINTF_MPI(stderr, "Received %d messages\n", received);
				STARPU_PTHREAD_COND_WAIT(&cond, &mutex);
			}
			STARPU_PTHREAD_MUTEX_UNLOCK(&mutex);
		}

		for(i=0 ; i<2 ; i++)
			starpu_data_acquire(data[i], STARPU_R);
		for(i=0 ; i<2 ; i++)
			FPRINTF_MPI(stderr, "Value[%d] = %d\n", i, val[i]);
		for(i=0 ; i<2 ; i++)
			starpu_data_release(data[i]);
	}
	FPRINTF_MPI(stderr, "Waiting ...\n");
	starpu_task_wait_for_all();

	starpu_data_unregister(data[0]);
	starpu_data_unregister(data[1]);

	if (rank == 0)
	{
		ret = (val[0] == VAL0 && val[1] == VAL1) ? 0 : 1;
	}
	starpu_mpi_shutdown();
	starpu_shutdown();
	return ret;
}
int main(int argc, char **argv)
{
        int i, j, ret;

	ret = starpu_initialize(NULL, &argc, &argv);
	if (ret == -ENODEV) return STARPU_TEST_SKIPPED;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_initialize");

	float *data;
	starpu_malloc((void**)&data, sizeof(*data) * NB_BUNDLE);
	float factors[NB_BUNDLE];
        starpu_data_handle_t handles[NB_BUNDLE];

	struct starpu_task *task[NB_ITERATION];

	starpu_task_bundle_t bundles[NB_BUNDLE];

	for (i = 0; i < NB_BUNDLE; i++)
	{
		data[i] = i + 1;
		factors[i] = NB_BUNDLE - i;
	}

	for (i = 0; i < NB_BUNDLE; i++)
		starpu_variable_data_register(&handles[i], STARPU_MAIN_RAM, (uintptr_t)&data[i], sizeof(float));

        FPRINTF(stderr, "VALUES:");
	for (i = 0; i < NB_BUNDLE; i++)
		FPRINTF(stderr, " %f (%f)", data[i], factors[i]);
        FPRINTF(stderr, "\n");

	for (i = 0; i < NB_BUNDLE; i++)
	{
		starpu_task_bundle_create(&bundles[i]);

		for (j = 0; j < NB_ITERATION; j++)
		{
			task[j] = starpu_task_create();

			task[j]->cl = &codelet;

			task[j]->cl_arg = &factors[i];
			task[j]->cl_arg_size = sizeof(float);

			task[j]->handles[0] = handles[i];

			ret = starpu_task_bundle_insert(bundles[i], task[j]);
			STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
		}

		ret = starpu_task_bundle_remove(bundles[i], task[NB_ITERATION / 2]);
		STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_remove");

		for (j = 0; j < NB_ITERATION; j++)
		{
			ret = starpu_task_submit(task[j]);
			if (ret == -ENODEV) goto enodev;
			STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
		}

		starpu_task_bundle_close(bundles[i]);
	}

        ret = starpu_task_wait_for_all();
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_wait_for_all");

        for(i = 0; i < NB_BUNDLE ; i++)
	{
                ret = starpu_data_acquire(handles[i], STARPU_R);
		STARPU_CHECK_RETURN_VALUE(ret, "starpu_data_acquire");
        }

        FPRINTF(stderr, "VALUES:");
	for (i = 0; i < NB_BUNDLE; i++)
		FPRINTF(stderr, " %f (%f)", data[i], factors[i]);
        FPRINTF(stderr, "\n");

        for(i = 0; i < NB_BUNDLE ; i++)
	{
                starpu_data_release(handles[i]);
		starpu_data_unregister(handles[i]);
	}

		starpu_free(data);

	starpu_shutdown();

	return EXIT_SUCCESS;

enodev:
	starpu_shutdown();
	fprintf(stderr, "WARNING: No one can execute this task\n");
	/* yes, we do not perform the computation but we did detect that no one
 	 * could perform the kernel, so this is not an error from StarPU */
	return STARPU_TEST_SKIPPED;
}
int main(int argc, char **argv)
{
	unsigned long i;
	int ret;

	/* Not supported yet */
	if (starpu_get_env_number_default("STARPU_GLOBAL_ARBITER", 0) > 0)
		return 77;

	ret = starpu_init(NULL);
	if (ret == -ENODEV)
		return 77;
	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");

	unsigned long nelems = _nblocks*_entries_per_bock;
	size_t size = nelems*sizeof(TYPE);

	_x = (TYPE *) malloc(size);
	_x_handles = (starpu_data_handle_t *) calloc(_nblocks, sizeof(starpu_data_handle_t));

	assert(_x && _x_handles);

	/* Initialize the vector with random values */
        starpu_srand48(0);
	for (i = 0; i < nelems; i++)
		_x[i] = (TYPE)starpu_drand48();

	unsigned block;
	for (block = 0; block < _nblocks; block++)
	{
		uintptr_t block_start = (uintptr_t)&_x[_entries_per_bock*block];
		starpu_vector_data_register(&_x_handles[block], STARPU_MAIN_RAM, block_start,
					    _entries_per_bock, sizeof(TYPE));
	}

	/* Initialize current min */
	_minmax[0] = TYPE_MAX;

	/* Initialize current max */
	_minmax[1] = TYPE_MIN;

	starpu_variable_data_register(&_minmax_handle, STARPU_MAIN_RAM, (uintptr_t)_minmax, 2*sizeof(TYPE));

	/* Set the methods to define neutral elements and to perform the reduction operation */
	starpu_data_set_reduction_methods(_minmax_handle, &minmax_redux_codelet, &minmax_init_codelet);

	for (block = 0; block < _nblocks; block++)
	{
		struct starpu_task *task = starpu_task_create();

		task->cl = &minmax_codelet;

		task->handles[0] = _x_handles[block];
		task->handles[1] = _minmax_handle;

		ret = starpu_task_submit(task);
		if (ret)
		{
			STARPU_ASSERT(ret == -ENODEV);
			FPRINTF(stderr, "This test can only run on CPUs, but there are no CPU workers (this is not a bug).\n");
			return 77;
		}
	}

	for (block = 0; block < _nblocks; block++)
	{
		starpu_data_unregister(_x_handles[block]);
	}
	starpu_data_unregister(_minmax_handle);

	FPRINTF(stderr, "Min : %e\n", _minmax[0]);
	FPRINTF(stderr, "Max : %e\n", _minmax[1]);

	STARPU_ASSERT(_minmax[0] <= _minmax[1]);

	free(_x);
	free(_x_handles);
	starpu_shutdown();

	return 0;
}