Browse Source

Add complex interface filters

Samuel Thibault 6 years ago
parent
commit
cdeae45d62

+ 2 - 1
examples/Makefile.am

@@ -969,7 +969,8 @@ endif
 
 interface_complex_SOURCES	=	\
 	interface/complex.c		\
-	interface/complex_interface.c
+	interface/complex_interface.c	\
+	interface/complex_filters.c
 if STARPU_USE_CUDA
 interface_complex_SOURCES	+=	\
 	interface/complex_kernels.cu

+ 74 - 1
examples/interface/complex.c

@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2012,2013                                Inria
  * Copyright (C) 2012,2013,2015,2017                      CNRS
- * Copyright (C) 2013,2014                                Université de Bordeaux
+ * Copyright (C) 2013,2014,2019                           Université de Bordeaux
  *
  * 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
@@ -83,6 +83,7 @@ int main(void)
 	int ret = 0;
 	starpu_data_handle_t handle1;
 	starpu_data_handle_t handle2;
+	starpu_data_handle_t handle3;
 
 	double real = 45.0;
 	double imaginary = 12.0;
@@ -92,6 +93,10 @@ int main(void)
 	int compare;
 	int *compare_ptr = &compare;
 
+	starpu_data_handle_t vectorh;
+	struct starpu_vector_interface *vectori;
+	double *vector;
+
 	ret = starpu_init(NULL);
 	if (ret == -ENODEV) return 77;
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
@@ -112,6 +117,7 @@ int main(void)
 	if (ret == -ENODEV) goto end;
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
 
+	/* Compare two different complexs.  */
 	ret = starpu_task_insert(&cl_compare,
 				 STARPU_R, handle1,
 				 STARPU_R, handle2,
@@ -126,6 +132,7 @@ int main(void)
 	     goto end;
 	}
 
+	/* Copy one into the other.  */
 	ret = starpu_task_insert(&cl_copy,
 				 STARPU_R, handle1,
 				 STARPU_W, handle2,
@@ -141,6 +148,7 @@ int main(void)
 	if (ret == -ENODEV) goto end;
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
 
+	/* And compare again.  */
 	ret = starpu_task_insert(&cl_compare,
 				 STARPU_R, handle1,
 				 STARPU_R, handle2,
@@ -156,6 +164,71 @@ int main(void)
 	     FPRINTF(stderr, "Complex numbers should be similar\n");
 	}
 
+	/* Put another value again */
+	starpu_data_acquire(handle2, STARPU_W);
+	copy_real = 78.0;
+	copy_imaginary = 77.0;
+	starpu_data_release(handle2);
+
+	/* Create a vector of two complexs.  */
+	starpu_complex_data_register(&handle3, -1, 0, 0, 2);
+
+	/* Split it in two pieces (thus one complex each).  */
+	struct starpu_data_filter f =
+	{
+		.filter_func = starpu_complex_filter_block,
+		.nchildren = 2,
+	};
+	starpu_data_partition(handle3, &f);
+
+	/* Copy the two complexs into each part */
+	ret = starpu_task_insert(&cl_copy,
+				 STARPU_R, handle1,
+				 STARPU_W, starpu_data_get_sub_data(handle3, 1, 0),
+				 0);
+	if (ret == -ENODEV) goto end;
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+	ret = starpu_task_insert(&cl_copy,
+				 STARPU_R, handle2,
+				 STARPU_W, starpu_data_get_sub_data(handle3, 1, 1),
+				 0);
+	if (ret == -ENODEV) goto end;
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_insert");
+
+	/* Gather the two pieces.  */
+	starpu_data_unpartition(handle3, STARPU_MAIN_RAM);
+
+	/* Show it.  */
+	ret = starpu_task_insert(&cl_display, STARPU_VALUE, "handle3", strlen("handle3")+1, STARPU_R, handle3, 0);
+
+	/* Get the real and imaginary vectors.  */
+	struct starpu_data_filter fcanon =
+	{
+		.filter_func = starpu_complex_filter_canonical,
+		.nchildren = 2,
+		.get_child_ops = starpu_complex_filter_canonical_child_ops,
+	};
+	starpu_data_partition(handle3, &fcanon);
+
+	/* Check the corresponding data.  */
+	vectorh = starpu_data_get_sub_data(handle3, 1, 0);
+	starpu_data_acquire(vectorh, STARPU_R);
+	vectori = starpu_data_get_interface_on_node(vectorh, STARPU_MAIN_RAM);
+	vector = (double*) vectori->ptr;
+	STARPU_ASSERT_MSG(vector[0] == 45., "Bogus value: %f instead of %f", vector[0], 45.);
+	STARPU_ASSERT_MSG(vector[1] == 78., "Bogus value: %f instead of %f", vector[1], 78.);
+	starpu_data_release(vectorh);
+
+	vectorh = starpu_data_get_sub_data(handle3, 1, 1);
+	starpu_data_acquire(vectorh, STARPU_R);
+	vectori = starpu_data_get_interface_on_node(vectorh, STARPU_MAIN_RAM);
+	vector = (double*) vectori->ptr;
+	STARPU_ASSERT_MSG(vector[0] == 12., "Bogus value: %f instead of %f", vector[0], 12.);
+	STARPU_ASSERT_MSG(vector[1] == 77., "Bogus value: %f instead of %f", vector[1], 77.);
+	starpu_data_release(vectorh);
+
+	starpu_data_unpartition(handle3, STARPU_MAIN_RAM);
+
 end:
 #ifdef STARPU_USE_OPENCL
 	{

+ 73 - 0
examples/interface/complex_filters.c

@@ -0,0 +1,73 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2019                                     Université de Bordeaux
+ *
+ * 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 "complex_interface.h"
+
+void starpu_complex_filter_block(void *father_interface, void *child_interface, STARPU_ATTRIBUTE_UNUSED struct starpu_data_filter *f, unsigned id, unsigned nchunks)
+{
+	struct starpu_complex_interface *complex_father = father_interface;
+	struct starpu_complex_interface *complex_child = child_interface;
+
+	uint32_t nx = complex_father->nx;
+	size_t elemsize = sizeof(double);
+
+	STARPU_ASSERT_MSG(nchunks <= nx, "%u parts for %u elements", nchunks, nx);
+
+	uint32_t child_nx;
+	size_t offset;
+	/* Compute the split */
+	starpu_filter_nparts_compute_chunk_size_and_offset(nx, nchunks, elemsize, id, 1,
+						     &child_nx, &offset);
+
+	complex_child->nx = child_nx;
+
+	if (complex_father->real)
+	{
+		complex_child->real = (void*) ((uintptr_t) complex_father->real + offset);
+		complex_child->imaginary = (void*) ((uintptr_t) complex_father->imaginary + offset);
+	}
+}
+
+void starpu_complex_filter_canonical(void *father_interface, void *child_interface, STARPU_ATTRIBUTE_UNUSED struct starpu_data_filter *f, unsigned id, unsigned nchunks)
+{
+	struct starpu_complex_interface *complex_father = father_interface;
+	struct starpu_vector_interface *vector_child = child_interface;
+
+	STARPU_ASSERT_MSG(nchunks == 2, "complex can only be split into two pieces");
+	STARPU_ASSERT_MSG(id < 2, "complex has only two pieces");
+
+	vector_child->id = STARPU_VECTOR_INTERFACE_ID;
+	if (id == 0)
+		vector_child->ptr = (uintptr_t) complex_father->real;
+	else
+		vector_child->ptr = (uintptr_t) complex_father->imaginary;
+
+	/* the complex interface doesn't support dev_handle/offset */
+	vector_child->dev_handle = vector_child->ptr;
+	vector_child->offset = 0;
+
+	vector_child->nx = complex_father->nx;
+	vector_child->elemsize = sizeof(double);
+	vector_child->slice_base = 0;
+	vector_child->allocsize = vector_child->nx * vector_child->elemsize;
+}
+
+struct starpu_data_interface_ops *starpu_complex_filter_canonical_child_ops(STARPU_ATTRIBUTE_UNUSED struct starpu_data_filter *f, unsigned child)
+{
+	return &starpu_interface_vector_ops;
+}

+ 7 - 0
examples/interface/complex_interface.h

@@ -38,4 +38,11 @@ int starpu_complex_get_nx(starpu_data_handle_t handle);
 #define STARPU_COMPLEX_GET_IMAGINARY(interface)	(((struct starpu_complex_interface *)(interface))->imaginary)
 #define STARPU_COMPLEX_GET_NX(interface)	(((struct starpu_complex_interface *)(interface))->nx)
 
+/* Split complex vector into smaller complex vectors */
+void starpu_complex_filter_block(void *father_interface, void *child_interface, struct starpu_data_filter *f, unsigned id, unsigned nchunks);
+
+/* Split complex into two simple vectors */
+void starpu_complex_filter_canonical(void *father_interface, void *child_interface, struct starpu_data_filter *f, unsigned id, unsigned nchunks);
+struct starpu_data_interface_ops *starpu_complex_filter_canonical_child_ops(struct starpu_data_filter *f, unsigned child);
+
 #endif /* __COMPLEX_INTERFACE_H */