Kaynağa Gözat

Add STARPU_VECTOR_SET_NX

to change a vector size without reallocating the buffer.
Samuel Thibault 6 yıl önce
ebeveyn
işleme
88b88d662d

+ 2 - 2
ChangeLog

@@ -20,8 +20,8 @@ StarPU 1.4.0 (svn revision xxxx)
 ==============================================
 New features:
   * New schedulers modular-pheft, modular-prandom and modular-prandom-prio
-  * Add STARPU_MATRIX_SET_NX/NY/LD to change a matrix tile size without
-    reallocating the buffer.
+  * Add STARPU_MATRIX_SET_NX/NY/LD and STARPU_VECTOR_SET_NX to change a matrix
+    tile or vector size without reallocating the buffer.
 
 StarPU 1.3.0 (svn revision xxxx)
 ==============================================

+ 30 - 1
include/starpu_data_interfaces.h

@@ -839,6 +839,7 @@ size_t starpu_matrix_get_allocsize(starpu_data_handle_t handle);
    designated by \p interface.
 */
 #define STARPU_MATRIX_SET_NX(interface, newnx)	        do { \
+	STARPU_MATRIX_CHECK(interface); \
 	(((struct starpu_matrix_interface *)(interface))->nx) = (newnx); \
 } while (0)
 /**
@@ -846,6 +847,7 @@ size_t starpu_matrix_get_allocsize(starpu_data_handle_t handle);
    designated by \p interface.
 */
 #define STARPU_MATRIX_SET_NY(interface, newny)	        do { \
+	STARPU_MATRIX_CHECK(interface); \
 	(((struct starpu_matrix_interface *)(interface))->ny) = (newny); \
 } while(0)
 /**
@@ -854,6 +856,7 @@ size_t starpu_matrix_get_allocsize(starpu_data_handle_t handle);
    no padding.
 */
 #define STARPU_MATRIX_SET_LD(interface, newld)	        do { \
+	STARPU_MATRIX_CHECK(interface); \
 	(((struct starpu_matrix_interface *)(interface))->ld) = (newld); \
 } while(0)
 
@@ -1107,7 +1110,6 @@ extern struct starpu_data_interface_ops starpu_interface_vector_ops;
 
 /**
  */
-/* TODO: add allocsize support */
 struct starpu_vector_interface
 {
 	enum starpu_data_interface_id id; /**< Identifier of the interface */
@@ -1118,6 +1120,7 @@ struct starpu_vector_interface
 	uint32_t nx;                      /**< number of elements on the x-axis of the vector */
 	size_t elemsize;                  /**< size of the elements of the vector */
 	uint32_t slice_base;              /**< vector slice base, used by the StarPU OpenMP runtime support */
+	size_t allocsize;                 /**< size actually currently allocated */
 };
 
 /**
@@ -1133,6 +1136,12 @@ struct starpu_vector_interface
 void starpu_vector_data_register(starpu_data_handle_t *handle, int home_node, uintptr_t ptr, uint32_t nx, size_t elemsize);
 
 /**
+   Similar to starpu_matrix_data_register, but additionally specifies which
+   allocation size should be used instead of the initial nx*elemsize.
+*/
+void starpu_vector_data_register_allocsize(starpu_data_handle_t *handle, int home_node, uintptr_t ptr, uint32_t nx, size_t elemsize, size_t allocsize);
+
+/**
    Register into the \p handle that to store data on node \p node it should use the
    buffer located at \p ptr, or device handle \p dev_handle and offset \p offset
    (for OpenCL, notably)
@@ -1150,6 +1159,11 @@ uint32_t starpu_vector_get_nx(starpu_data_handle_t handle);
 size_t starpu_vector_get_elemsize(starpu_data_handle_t handle);
 
 /**
+  Return the allocated size of the array designated by \p handle.
+ */
+size_t starpu_vector_get_allocsize(starpu_data_handle_t handle);
+
+/**
    Return the local pointer associated with \p handle.
  */
 uintptr_t starpu_vector_get_local_ptr(starpu_data_handle_t handle);
@@ -1161,6 +1175,7 @@ uintptr_t starpu_vector_get_local_ptr(starpu_data_handle_t handle);
 #define STARPU_VECTOR_GET_OFFSET(interface)	({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->offset); })
 #define STARPU_VECTOR_GET_NX(interface)	        ({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->nx); })
 #define STARPU_VECTOR_GET_ELEMSIZE(interface)	({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->elemsize); })
+#define STARPU_VECTOR_GET_ALLOCSIZE(interface)	({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->allocsize); })
 #define STARPU_VECTOR_GET_SLICE_BASE(interface)	({ STARPU_VECTOR_CHECK(interface); (((struct starpu_vector_interface *)(interface))->slice_base); })
 #else
 /**
@@ -1191,12 +1206,26 @@ uintptr_t starpu_vector_get_local_ptr(starpu_data_handle_t handle);
  */
 #define STARPU_VECTOR_GET_ELEMSIZE(interface)	(((struct starpu_vector_interface *)(interface))->elemsize)
 /**
+   Return the size of each element of the array designated by
+   \p interface.
+ */
+#define STARPU_VECTOR_GET_ALLOCSIZE(interface)	(((struct starpu_vector_interface *)(interface))->allocsize)
+/**
    Return the OpenMP slice base annotation of each element of the array designated by
    \p interface.
  */
 #define STARPU_VECTOR_GET_SLICE_BASE(interface)	(((struct starpu_vector_interface *)(interface))->slice_base)
 #endif
 
+/**
+   Set the number of elements registered into the array designated by \p
+   interface.
+ */
+#define STARPU_VECTOR_SET_NX(interface, newnx)	do { \
+	STARPU_VECTOR_CHECK(interface); \
+	(((struct starpu_vector_interface *)(interface))->nx) = (newnx); \
+} while(0)
+
 /** @} */
 
 /** @name Variable Data Interface

+ 12 - 1
src/datawizard/interfaces/vector_filters.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2008-2014,2016,2017                      Université de Bordeaux
+ * Copyright (C) 2008-2014,2016,2017,2019                 Université de Bordeaux
  * Copyright (C) 2012                                     Inria
  * Copyright (C) 2010                                     Mehdi Juhoor
  * Copyright (C) 2010,2011,2013,2015-2017                 CNRS
@@ -40,6 +40,8 @@ void starpu_vector_filter_block(void *father_interface, void *child_interface, S
 	vector_child->id = vector_father->id;
 	vector_child->nx = child_nx;
 	vector_child->elemsize = elemsize;
+	STARPU_ASSERT_MSG(vector_father->allocsize == vector_father->nx * vector_father->elemsize, "partitioning vector with non-trival allocsize not supported yet, patch welcome");
+	vector_child->allocsize = vector_child->nx * elemsize;
 
 	if (vector_father->dev_handle)
 	{
@@ -74,6 +76,8 @@ void starpu_vector_filter_block_shadow(void *father_interface, void *child_inter
 	vector_child->id = vector_father->id;
 	vector_child->nx = child_nx;
 	vector_child->elemsize = elemsize;
+	STARPU_ASSERT_MSG(vector_father->allocsize == vector_father->nx * vector_father->elemsize, "partitioning vector with non-trival allocsize not supported yet, patch welcome");
+	vector_child->allocsize = vector_child->nx * elemsize;
 
 	if (vector_father->dev_handle)
 	{
@@ -102,12 +106,14 @@ void starpu_vector_filter_divide_in_2(void *father_interface, void *child_interf
 
 	STARPU_ASSERT_MSG(vector_father->id == STARPU_VECTOR_INTERFACE_ID, "%s can only be applied on a vector data", __func__);
 	vector_child->id = vector_father->id;
+	STARPU_ASSERT_MSG(vector_father->allocsize == vector_father->nx * vector_father->elemsize, "partitioning vector with non-trival allocsize not supported yet, patch welcome");
 
 	/* this is the first child */
 	if (id == 0)
 	{
 		vector_child->nx = length_first;
 		vector_child->elemsize = elemsize;
+		vector_child->allocsize = vector_child->nx * elemsize;
 
 		if (vector_father->dev_handle)
 		{
@@ -121,6 +127,7 @@ void starpu_vector_filter_divide_in_2(void *father_interface, void *child_interf
 	{
 		vector_child->nx = nx - length_first;
 		vector_child->elemsize = elemsize;
+		vector_child->allocsize = vector_child->nx * elemsize;
 
 		if (vector_father->dev_handle)
 		{
@@ -148,6 +155,8 @@ void starpu_vector_filter_list_long(void *father_interface, void *child_interfac
 	vector_child->id = vector_father->id;
 	vector_child->nx = chunk_size;
 	vector_child->elemsize = elemsize;
+	STARPU_ASSERT_MSG(vector_father->allocsize == vector_father->nx * vector_father->elemsize, "partitioning vector with non-trival allocsize not supported yet, patch welcome");
+	vector_child->allocsize = vector_child->nx * elemsize;
 
 	if (vector_father->dev_handle)
 	{
@@ -179,6 +188,8 @@ void starpu_vector_filter_list(void *father_interface, void *child_interface, st
 	vector_child->id = vector_father->id;
 	vector_child->nx = chunk_size;
 	vector_child->elemsize = elemsize;
+	STARPU_ASSERT_MSG(vector_father->allocsize == vector_father->nx * vector_father->elemsize, "partitioning vector with non-trival allocsize not supported yet, patch welcome");
+	vector_child->allocsize = vector_child->nx * elemsize;
 
 	if (vector_father->dev_handle)
 	{

+ 46 - 16
src/datawizard/interfaces/vector_interface.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2008-2018                                Université de Bordeaux
+ * Copyright (C) 2008-2019                                Université de Bordeaux
  * Copyright (C) 2011,2012,2014,2017                      Inria
  * Copyright (C) 2010-2015,2017                           CNRS
  *
@@ -44,7 +44,9 @@ static int vector_pointer_is_inside(void *data_interface, unsigned node, void *p
 static void free_vector_buffer_on_node(void *data_interface, unsigned node);
 static size_t vector_interface_get_size(starpu_data_handle_t handle);
 static uint32_t footprint_vector_interface_crc32(starpu_data_handle_t handle);
+static uint32_t alloc_footprint_vector_interface_crc32(starpu_data_handle_t handle);
 static int vector_compare(void *data_interface_a, void *data_interface_b);
+static int vector_alloc_compare(void *data_interface_a, void *data_interface_b);
 static void display_vector_interface(starpu_data_handle_t handle, FILE *f);
 static int pack_vector_handle(starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
 static int unpack_vector_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
@@ -60,7 +62,9 @@ struct starpu_data_interface_ops starpu_interface_vector_ops =
 	.copy_methods = &vector_copy_data_methods_s,
 	.get_size = vector_interface_get_size,
 	.footprint = footprint_vector_interface_crc32,
+	.alloc_footprint = alloc_footprint_vector_interface_crc32,
 	.compare = vector_compare,
+	.alloc_compare = vector_alloc_compare,
 	.interfaceid = STARPU_VECTOR_INTERFACE_ID,
 	.interface_size = sizeof(struct starpu_vector_interface),
 	.display = display_vector_interface,
@@ -113,13 +117,14 @@ static void register_vector_handle(starpu_data_handle_t handle, unsigned home_no
 		local_interface->id = vector_interface->id;
 		local_interface->nx = vector_interface->nx;
 		local_interface->elemsize = vector_interface->elemsize;
+		local_interface->allocsize = vector_interface->allocsize;
 		local_interface->slice_base = vector_interface->slice_base;
 	}
 }
 
 /* declare a new data with the vector interface */
-void starpu_vector_data_register(starpu_data_handle_t *handleptr, int home_node,
-                        uintptr_t ptr, uint32_t nx, size_t elemsize)
+void starpu_vector_data_register_allocsize(starpu_data_handle_t *handleptr, int home_node,
+		uintptr_t ptr, uint32_t nx, size_t elemsize, size_t allocsize)
 {
 	struct starpu_vector_interface vector =
 	{
@@ -129,7 +134,8 @@ void starpu_vector_data_register(starpu_data_handle_t *handleptr, int home_node,
 		.elemsize = elemsize,
                 .dev_handle = ptr,
 		.slice_base = 0,
-                .offset = 0
+                .offset = 0,
+		.allocsize = allocsize,
 	};
 #if (!defined(STARPU_SIMGRID) && !defined(STARPU_OPENMP))
 	if (home_node >= 0 && starpu_node_get_kind(home_node) == STARPU_CPU_RAM)
@@ -146,6 +152,12 @@ void starpu_vector_data_register(starpu_data_handle_t *handleptr, int home_node,
 	starpu_data_register(handleptr, home_node, &vector, &starpu_interface_vector_ops);
 }
 
+void starpu_vector_data_register(starpu_data_handle_t *handleptr, int home_node,
+                        uintptr_t ptr, uint32_t nx, size_t elemsize)
+{
+	starpu_vector_data_register_allocsize(handleptr, home_node, ptr, nx, elemsize, nx * elemsize);
+}
+
 void starpu_vector_ptr_register(starpu_data_handle_t handle, unsigned node,
 			uintptr_t ptr, uintptr_t dev_handle, size_t offset)
 {
@@ -162,6 +174,11 @@ static uint32_t footprint_vector_interface_crc32(starpu_data_handle_t handle)
 	return starpu_hash_crc32c_be(starpu_vector_get_nx(handle), 0);
 }
 
+static uint32_t alloc_footprint_vector_interface_crc32(starpu_data_handle_t handle)
+{
+	return starpu_hash_crc32c_be(starpu_vector_get_allocsize(handle), 0);
+}
+
 static int vector_compare(void *data_interface_a, void *data_interface_b)
 {
 	struct starpu_vector_interface *vector_a = (struct starpu_vector_interface *) data_interface_a;
@@ -172,6 +189,15 @@ static int vector_compare(void *data_interface_a, void *data_interface_b)
 		&& (vector_a->elemsize == vector_b->elemsize);
 }
 
+static int vector_alloc_compare(void *data_interface_a, void *data_interface_b)
+{
+	struct starpu_vector_interface *vector_a = (struct starpu_vector_interface *) data_interface_a;
+	struct starpu_vector_interface *vector_b = (struct starpu_vector_interface *) data_interface_b;
+
+	/* Two vectors are considered compatible if they have the same size */
+	return (vector_a->allocsize == vector_b->allocsize);
+}
+
 static void display_vector_interface(starpu_data_handle_t handle, FILE *f)
 {
 	struct starpu_vector_interface *vector_interface = (struct starpu_vector_interface *)
@@ -221,7 +247,7 @@ static size_t vector_interface_get_size(starpu_data_handle_t handle)
 	STARPU_ASSERT_MSG(vector_interface->id == STARPU_VECTOR_INTERFACE_ID, "Error. The given data is not a vector.");
 #endif
 
-	size = vector_interface->nx*vector_interface->elemsize;
+	size = vector_interface->allocsize;
 
 	return size;
 }
@@ -268,6 +294,18 @@ size_t starpu_vector_get_elemsize(starpu_data_handle_t handle)
 	return vector_interface->elemsize;
 }
 
+size_t starpu_vector_get_allocsize(starpu_data_handle_t handle)
+{
+	struct starpu_vector_interface *vector_interface = (struct starpu_vector_interface *)
+		starpu_data_get_interface_on_node(handle, STARPU_MAIN_RAM);
+
+#ifdef STARPU_DEBUG
+	STARPU_ASSERT_MSG(vector_interface->id == STARPU_VECTOR_INTERFACE_ID, "Error. The given data is not a vector.");
+#endif
+
+	return vector_interface->allocsize;
+}
+
 /* memory allocation/deallocation primitives for the vector interface */
 
 /* returns the size of the allocated area */
@@ -277,20 +315,14 @@ static starpu_ssize_t allocate_vector_buffer_on_node(void *data_interface_, unsi
 
 	struct starpu_vector_interface *vector_interface = (struct starpu_vector_interface *) data_interface_;
 
-	uint32_t nx = vector_interface->nx;
-	size_t elemsize = vector_interface->elemsize;
-
-	starpu_ssize_t allocated_memory;
-
-	handle = starpu_malloc_on_node(dst_node, nx*elemsize);
+	starpu_ssize_t allocated_memory = vector_interface->allocsize;
+	handle = starpu_malloc_on_node(dst_node, allocated_memory);
 	if (!handle)
 		return -ENOMEM;
 
 	if (starpu_node_get_kind(dst_node) != STARPU_OPENCL_RAM)
 		addr = handle;
 
-	allocated_memory = nx*elemsize;
-
 	/* update the data properly in consequence */
 	vector_interface->ptr = addr;
 	vector_interface->dev_handle = handle;
@@ -302,10 +334,8 @@ static starpu_ssize_t allocate_vector_buffer_on_node(void *data_interface_, unsi
 static void free_vector_buffer_on_node(void *data_interface, unsigned node)
 {
 	struct starpu_vector_interface *vector_interface = (struct starpu_vector_interface *) data_interface;
-	uint32_t nx = vector_interface->nx;
-	size_t elemsize = vector_interface->elemsize;
 
-	starpu_free_on_node(node, vector_interface->dev_handle, nx*elemsize);
+	starpu_free_on_node(node, vector_interface->dev_handle, vector_interface->allocsize);
 }
 
 static int copy_any_to_any(void *src_interface, unsigned src_node,