ソースを参照

Add peek_data interface method

Samuel Thibault 4 年 前
コミット
47c529c57b

+ 1 - 0
ChangeLog

@@ -50,6 +50,7 @@ New features:
   * Add starpu_mpi_datatype_node_register and
     starpu_mpi_interface_datatype_node_register which will be needed for
     MPI/NUMA/GPUDirect.
+  * Add peek_data interface method.
 
 Small changes:
   * Add a synthetic energy efficiency testcase.

+ 27 - 0
doc/doxygen/chapters/410_mpi_support.doxy

@@ -355,17 +355,44 @@ static int complex_unpack_data(starpu_data_handle_t handle, unsigned node, void
     memcpy(complex_interface->real, ptr, complex_interface->nx*sizeof(double));
     memcpy(complex_interface->imaginary, ptr+complex_interface->nx*sizeof(double), complex_interface->nx*sizeof(double));
 
+    starpu_free_on_node_flags(node, (uintptr_t) ptr, count, 0);
+
     return 0;
 }
+\endcode
+
+And the starpu_data_interface_ops::peek_data operation does
+the same, but without freeing the buffer. Of course one can
+implement starpu_data_interface_ops::unpack_data as merely calling
+starpu_data_interface_ops::peek_data and do the free:
+
+\code{.c}
+static int complex_peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+    STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
+    STARPU_ASSERT(count == complex_get_size(handle));
 
+    struct starpu_complex_interface *complex_interface = (struct starpu_complex_interface *) starpu_data_get_interface_on_node(handle, node);
+
+    memcpy(complex_interface->real, ptr, complex_interface->nx*sizeof(double));
+    memcpy(complex_interface->imaginary, ptr+complex_interface->nx*sizeof(double), complex_interface->nx*sizeof(double));
+
+    return 0;
+}
+\endcode
+
+\code{.c}
 static struct starpu_data_interface_ops interface_complex_ops =
 {
     ...
     .pack_data = complex_pack_data,
+    .peek_data = complex_peek_data
     .unpack_data = complex_unpack_data
 };
 \endcode
 
+
+
 Instead of defining pack and unpack operations, users may want to
 attach a MPI type to their user-defined data interface. The function
 starpu_mpi_interface_datatype_register() allows to do so. This function takes 3

+ 11 - 1
examples/cpp/add_vectors_interface.cpp

@@ -258,6 +258,7 @@ static uint32_t footprint_vector_cpp_interface_crc32(starpu_data_handle_t handle
 static int vector_cpp_compare(void *data_interface_a, void *data_interface_b);
 static void display_vector_cpp_interface(starpu_data_handle_t handle, FILE *f);
 static int pack_vector_cpp_handle(starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
+static int peek_vector_cpp_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static int unpack_vector_cpp_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static starpu_ssize_t vector_cpp_describe(void *data_interface, char *buf, size_t size);
 
@@ -287,6 +288,7 @@ static struct starpu_data_interface_ops interface_vector_cpp_ops =
 	.dontcache = 0,
 	.get_mf_ops = NULL,
 	.pack_data = pack_vector_cpp_handle,
+	.peek_data = peek_vector_cpp_handle,
 	.unpack_data = unpack_vector_cpp_handle,
 	.name = (char *) "VECTOR_CPP_INTERFACE"
 };
@@ -315,6 +317,7 @@ static struct starpu_data_interface_ops interface_vector_cpp_ops =
 	0,
 	NULL,
 	pack_vector_cpp_handle,
+	peek_vector_cpp_handle,
 	unpack_vector_cpp_handle,
 	(char *) "VECTOR_CPP_INTERFACE"
 };
@@ -458,7 +461,7 @@ static int pack_vector_cpp_handle(starpu_data_handle_t handle, unsigned node, vo
 	return 0;
 }
 
-static int unpack_vector_cpp_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int peek_vector_cpp_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
 
@@ -468,6 +471,13 @@ static int unpack_vector_cpp_handle(starpu_data_handle_t handle, unsigned node,
 	STARPU_ASSERT(count == vector_interface->elemsize * vector_interface->nx);
 	memcpy((void*)vector_interface->ptr, ptr, count);
 
+	return 0;
+}
+
+static int unpack_vector_cpp_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	peek_vector_cpp_handle(handle, node, ptr, count);
+
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 
 	return 0;

+ 9 - 1
examples/interface/complex_interface.c

@@ -147,7 +147,7 @@ static int complex_pack_data(starpu_data_handle_t handle, unsigned node, void **
 	return 0;
 }
 
-static int complex_unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int complex_peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	char *data = ptr;
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
@@ -159,6 +159,13 @@ static int complex_unpack_data(starpu_data_handle_t handle, unsigned node, void
 	memcpy(complex_interface->real, data, complex_interface->nx*sizeof(double));
 	memcpy(complex_interface->imaginary, data+complex_interface->nx*sizeof(double), complex_interface->nx*sizeof(double));
 
+	return 0;
+}
+
+static int complex_unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	complex_peek_data(handle, node, ptr, count);
+
 	starpu_free_on_node_flags(node, (uintptr_t) ptr, count, 0);
 
 	return 0;
@@ -217,6 +224,7 @@ static struct starpu_data_interface_ops interface_complex_ops =
 	.to_pointer = NULL,
 	.pointer_is_inside = complex_pointer_is_inside,
 	.pack_data = complex_pack_data,
+	.peek_data = complex_peek_data,
 	.unpack_data = complex_unpack_data,
 	.describe = complex_describe,
 	.compare = complex_compare

+ 24 - 2
include/starpu_data_interfaces.h

@@ -321,7 +321,7 @@ struct starpu_data_copy_methods
 	   data blocks. If the interface is more involved than
 	   this, i.e. it needs to collect pieces of data before
 	   transferring, starpu_data_interface_ops::pack_data and
-	   starpu_data_interface_ops::unpack_data should be implemented instead,
+	   starpu_data_interface_ops::peek_data should be implemented instead,
 	   and the core will just transfer the resulting data buffer.
 	*/
 	int (*any_to_any)(void *src_interface, unsigned src_node, void *dst_interface, unsigned dst_node, void *async_data);
@@ -540,6 +540,12 @@ struct starpu_data_interface_ops
 	int (*pack_data) (starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
 
 	/**
+	   Read the data handle from the contiguous buffer at the address
+	   \p ptr of size \p count.
+	*/
+	int (*peek_data) (starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
+
+	/**
 	   Unpack the data handle from the contiguous buffer at the address
 	   \p ptr of size \p count.
 	   The memory at the address \p ptr should be freed after the data unpacking operation.
@@ -637,9 +643,25 @@ int starpu_data_pack_node(starpu_data_handle_t handle, unsigned node, void **ptr
 int starpu_data_pack(starpu_data_handle_t handle, void **ptr, starpu_ssize_t *count);
 
 /**
+   Read in handle's \p node replicate the data located at \p ptr
+   of size \p count as described by the interface of the data. The interface
+   registered at \p handle must define a peeking operation (see
+   starpu_data_interface_ops).
+*/
+int starpu_data_peek_node(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
+
+/**
+   Read in handle's local replicate the data located at \p ptr
+   of size \p count as described by the interface of the data. The interface
+   registered at \p handle must define a peeking operation (see
+   starpu_data_interface_ops).
+*/
+int starpu_data_peek(starpu_data_handle_t handle, void *ptr, size_t count);
+
+/**
    Unpack in handle the data located at \p ptr of size \p count allocated
    on node \p node as described by the interface of the data. The interface
-   registered at \p handle must define a unpacking operation (see
+   registered at \p handle must define an unpacking operation (see
    starpu_data_interface_ops).
 */
 int starpu_data_unpack_node(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);

+ 18 - 1
mpi/examples/user_datatype/my_interface.c

@@ -201,6 +201,15 @@ static int data_pack_data(starpu_data_handle_t handle, unsigned node, void **ptr
 	return 0;
 }
 
+static int data_peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	(void)handle;
+	(void)node;
+	(void)ptr;
+	STARPU_ASSERT_MSG(0, "The data interface has been registered with starpu_mpi_datatype_register(). Calling the unpack_data function should not happen\n");
+	return 0;
+}
+
 static int data_unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	(void)handle;
@@ -231,7 +240,7 @@ static int data_pack_data2(starpu_data_handle_t handle, unsigned node, void **pt
 	return 0;
 }
 
-static int data_unpack_data2(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int data_peek_data2(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	(void)count;
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
@@ -243,6 +252,12 @@ static int data_unpack_data2(starpu_data_handle_t handle, unsigned node, void *p
 	char *x = ptr;
 	x += sizeof(int);
 	memcpy(&data->c, x, sizeof(char));
+	return 0;
+}
+
+static int data_unpack_data2(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	data_peek_data2(handle, node, ptr, count);
 
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 	return 0;
@@ -301,6 +316,7 @@ static struct starpu_data_interface_ops interface_data_ops =
 	.interface_size = sizeof(struct starpu_my_data_interface),
 	.to_pointer = data_to_pointer,
 	.pack_data = data_pack_data,
+	.peek_data = data_peek_data,
 	.unpack_data = data_unpack_data,
 	.describe = data_describe
 };
@@ -343,6 +359,7 @@ static struct starpu_data_interface_ops interface_data2_ops =
 	.interface_size = sizeof(struct starpu_my_data_interface),
 	.to_pointer = data_to_pointer,
 	.pack_data = data_pack_data2,
+	.peek_data = data_peek_data2,
 	.unpack_data = data_unpack_data2,
 	.describe = data_describe
 };

+ 11 - 2
mpi/src/load_balancer/policy/data_movements_interface.c

@@ -201,7 +201,7 @@ static int data_movements_pack_data(starpu_data_handle_t handle, unsigned node,
 	return 0;
 }
 
-static int data_movements_unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int data_movements_peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	char *data = ptr;
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
@@ -221,7 +221,15 @@ static int data_movements_unpack_data(starpu_data_handle_t handle, unsigned node
 		memcpy(dm_interface->ranks, data+sizeof(int)+(dm_interface->size*sizeof(starpu_mpi_tag_t)), dm_interface->size*sizeof(int));
 	}
 
-    return 0;
+	return 0;
+}
+
+static int data_movements_unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	data_movements_peek_data(handle, node, ptr, count);
+	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
+
+	return 0;
 }
 
 static int copy_any_to_any(void *src_interface, unsigned src_node,
@@ -262,6 +270,7 @@ static struct starpu_data_interface_ops interface_data_movements_ops =
 	.interface_size = sizeof(struct data_movements_interface),
 	.to_pointer = NULL,
 	.pack_data = data_movements_pack_data,
+	.peek_data = data_movements_peek_data,
 	.unpack_data = data_movements_unpack_data,
 	.describe = NULL
 };

+ 10 - 1
mpi/src/load_balancer/policy/load_data_interface.c

@@ -199,7 +199,7 @@ static int load_data_pack_data(starpu_data_handle_t handle, unsigned node, void
 	return 0;
 }
 
-static int load_data_unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int load_data_peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	char *data = ptr;
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
@@ -213,6 +213,14 @@ static int load_data_unpack_data(starpu_data_handle_t handle, unsigned node, voi
 	return 0;
 }
 
+static int load_data_unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	load_data_peek_data(handle, node, ptr, count);
+	starpu_free_on_node_flags(node, (uintptr_t) ptr, count, 0);
+
+	return 0;
+}
+
 static int copy_any_to_any(void *src_interface, unsigned src_node,
 			   void *dst_interface, unsigned dst_node,
 			   void *async_data)
@@ -243,6 +251,7 @@ static struct starpu_data_interface_ops interface_load_data_ops =
 	.interface_size = sizeof(struct load_data_interface),
 	.to_pointer = NULL,
 	.pack_data = load_data_pack_data,
+	.peek_data = load_data_peek_data,
 	.unpack_data = load_data_unpack_data,
 	.describe = NULL
 };

+ 11 - 7
mpi/src/mpi/starpu_mpi_mpi.c

@@ -887,8 +887,8 @@ static void _starpu_mpi_handle_request_termination(struct _starpu_mpi_req *req)
 				}
 				else if (req->request_type == RECV_REQ)
 				{
-					// req->ptr is freed by starpu_data_unpack
-					starpu_data_unpack_node(req->data_handle, req->node, req->ptr, req->count);
+					starpu_data_peek_node(req->data_handle, req->node, req->ptr, req->count);
+					starpu_free_on_node_flags(req->node, (uintptr_t)req->ptr, req->count, 0);
 					starpu_memory_deallocate(req->node, req->count);
 				}
 			}
@@ -946,11 +946,15 @@ static void _starpu_mpi_early_data_cb(void* arg)
 		}
 		else
 		{
-			STARPU_MPI_ASSERT_MSG(itf_dst->unpack_data, "The data interface does not define an unpack function\n");
-			// FIXME: args->buffer is in args->buffer_node, not req->node
-			// There is conflation between the memory node for the handle and the memory node for the buffer
-			// Actually we may not want unpack_data to free the buffer, for the case when we are participating to a collective send
-			itf_dst->unpack_data(args->data_handle, args->req->node, args->buffer, itf_src->get_size(args->early_handle));
+			STARPU_MPI_ASSERT_MSG(itf_dst->peek_data || itf_dst->unpack_data , "The data interface does not define an unpack function\n");
+			// FIXME: Actually we may not want unpack_data to free the buffer, for the case when we are participating to a collective send
+			if (itf_dst->peek_data)
+			{
+				itf_dst->peek_data(args->data_handle, args->req->node, args->buffer, itf_src->get_size(args->early_handle));
+				starpu_free_on_node_flags(args->buffer_node, (uintptr_t) args->buffer, itf_src->get_size(args->early_handle), 0);
+			}
+			else
+				itf_dst->unpack_data(args->data_handle, args->req->node, args->buffer, itf_src->get_size(args->early_handle));
 			args->buffer = NULL;
 		}
 	}

+ 2 - 4
mpi/src/nmad/starpu_mpi_nmad.c

@@ -346,10 +346,8 @@ void _starpu_mpi_handle_request_termination(struct _starpu_mpi_req* req)
 		if (req->registered_datatype == 0)
 		{
 			if (req->request_type == RECV_REQ)
-				// req->ptr is freed by starpu_data_unpack
-				starpu_data_unpack_node(req->data_handle, req->node, req->ptr, req->count);
-			else
-				starpu_free_on_node_flags(req->node, (uintptr_t) req->ptr, req->count, 0);
+				starpu_data_peek_node(req->data_handle, req->node, req->ptr, req->count);
+			starpu_free_on_node_flags(req->node, (uintptr_t) req->ptr, req->count, 0);
 		}
 		else
 		{

+ 8 - 1
mpi/tests/user_defined_datatype_value.h

@@ -105,7 +105,7 @@ static int value_pack_data(starpu_data_handle_t handle, unsigned node, void **pt
 	return 0;
 }
 
-static int value_unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int value_peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	(void)count;
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
@@ -117,6 +117,12 @@ static int value_unpack_data(starpu_data_handle_t handle, unsigned node, void *p
 
 	assert(value_interface->value[0] == 36);
 
+	return 0;
+}
+
+static int value_unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	value_peek_data(handle, node, ptr, count);
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 
 	return 0;
@@ -152,6 +158,7 @@ static struct starpu_data_interface_ops interface_value_ops =
 	.interface_size = sizeof(struct starpu_value_interface),
 	.to_pointer = value_to_pointer,
 	.pack_data = value_pack_data,
+	.peek_data = value_peek_data,
 	.unpack_data = value_unpack_data
 };
 

+ 9 - 1
src/datawizard/interfaces/bcsr_interface.c

@@ -40,6 +40,7 @@ static int bcsr_compare(void *data_interface_a, void *data_interface_b);
 static uint32_t footprint_bcsr_interface_crc32(starpu_data_handle_t handle);
 static starpu_ssize_t describe(void *data_interface, char *buf, size_t size);
 static int pack_data(starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
+static int peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static int unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 
 struct starpu_data_interface_ops starpu_interface_bcsr_ops =
@@ -58,6 +59,7 @@ struct starpu_data_interface_ops starpu_interface_bcsr_ops =
 	.pointer_is_inside = bcsr_pointer_is_inside,
 	.name = "STARPU_BCSR_INTERFACE",
 	.pack_data = pack_data,
+	.peek_data = peek_data,
 	.unpack_data = unpack_data
 };
 
@@ -464,7 +466,7 @@ static int pack_data(starpu_data_handle_t handle, unsigned node, void **ptr, sta
 	return 0;
 }
 
-static int unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
 
@@ -482,6 +484,12 @@ static int unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, si
 	}
 	memcpy((void*)bcsr->nzval, tmp, bcsr->r * bcsr->c * bcsr->nnz * bcsr->elemsize);
 
+	return 0;
+}
+
+static int unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	peek_data(handle, node, ptr, count);
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 
 	return 0;

+ 9 - 1
src/datawizard/interfaces/block_interface.c

@@ -37,6 +37,7 @@ static uint32_t footprint_block_interface_crc32(starpu_data_handle_t handle);
 static int block_compare(void *data_interface_a, void *data_interface_b);
 static void display_block_interface(starpu_data_handle_t handle, FILE *f);
 static int pack_block_handle(starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
+static int peek_block_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static int unpack_block_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static starpu_ssize_t describe(void *data_interface, char *buf, size_t size);
 
@@ -55,6 +56,7 @@ struct starpu_data_interface_ops starpu_interface_block_ops =
 	.interface_size = sizeof(struct starpu_block_interface),
 	.display = display_block_interface,
 	.pack_data = pack_block_handle,
+	.peek_data = peek_block_handle,
 	.unpack_data = unpack_block_handle,
 	.describe = describe,
 	.name = "STARPU_BLOCK_INTERFACE"
@@ -252,7 +254,7 @@ static int pack_block_handle(starpu_data_handle_t handle, unsigned node, void **
 	return 0;
 }
 
-static int unpack_block_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int peek_block_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
 
@@ -298,6 +300,12 @@ static int unpack_block_handle(starpu_data_handle_t handle, unsigned node, void
 		}
 	}
 
+	return 0;
+}
+
+static int unpack_block_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	peek_block_handle(handle, node, ptr, count);
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 
 	return 0;

+ 9 - 1
src/datawizard/interfaces/csr_interface.c

@@ -36,6 +36,7 @@ static int csr_compare(void *data_interface_a, void *data_interface_b);
 static uint32_t footprint_csr_interface_crc32(starpu_data_handle_t handle);
 static starpu_ssize_t describe(void *data_interface, char *buf, size_t size);
 static int pack_data(starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
+static int peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static int unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 
 struct starpu_data_interface_ops starpu_interface_csr_ops =
@@ -53,6 +54,7 @@ struct starpu_data_interface_ops starpu_interface_csr_ops =
 	.pointer_is_inside = csr_pointer_is_inside,
 	.name = "STARPU_CSR_INTERFACE",
 	.pack_data = pack_data,
+	.peek_data = peek_data,
 	.unpack_data = unpack_data
 };
 
@@ -403,7 +405,7 @@ static int pack_data(starpu_data_handle_t handle, unsigned node, void **ptr, sta
 	return 0;
 }
 
-static int unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int peek_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
 
@@ -421,6 +423,12 @@ static int unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, si
 	}
 	memcpy((void*)csr->nzval, tmp, csr->nnz * csr->elemsize);
 
+	return 0;
+}
+
+static int unpack_data(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	peek_data(handle, node, ptr, count);
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 
 	return 0;

+ 13 - 0
src/datawizard/interfaces/data_interface.c

@@ -1230,6 +1230,19 @@ int starpu_data_pack(starpu_data_handle_t handle, void **ptr, starpu_ssize_t *co
 	return starpu_data_pack_node(handle, starpu_worker_get_local_memory_node(), ptr, count);
 }
 
+int starpu_data_peek_node(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	STARPU_ASSERT_MSG(handle->ops->peek_data, "The datatype interface %s (%d) does not have an peek operation", handle->ops->name, handle->ops->interfaceid);
+	int ret;
+	ret = handle->ops->peek_data(handle, node, ptr, count);
+	return ret;
+}
+
+int starpu_data_peek(starpu_data_handle_t handle, void *ptr, size_t count)
+{
+	return starpu_data_peek_node(handle, starpu_worker_get_local_memory_node(), ptr, count);
+}
+
 int starpu_data_unpack_node(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	STARPU_ASSERT_MSG(handle->ops->unpack_data, "The datatype interface %s (%d) does not have an unpack operation", handle->ops->name, handle->ops->interfaceid);

+ 9 - 1
src/datawizard/interfaces/matrix_interface.c

@@ -40,6 +40,7 @@ static int matrix_compare(void *data_interface_a, void *data_interface_b);
 static int matrix_alloc_compare(void *data_interface_a, void *data_interface_b);
 static void display_matrix_interface(starpu_data_handle_t handle, FILE *f);
 static int pack_matrix_handle(starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
+static int peek_matrix_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static int unpack_matrix_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static starpu_ssize_t describe(void *data_interface, char *buf, size_t size);
 
@@ -62,6 +63,7 @@ struct starpu_data_interface_ops starpu_interface_matrix_ops =
 	.interface_size = sizeof(struct starpu_matrix_interface),
 	.display = display_matrix_interface,
 	.pack_data = pack_matrix_handle,
+	.peek_data = peek_matrix_handle,
 	.unpack_data = unpack_matrix_handle,
 	.describe = describe,
 	.name = "STARPU_MATRIX_INTERFACE"
@@ -277,7 +279,7 @@ static int pack_matrix_handle(starpu_data_handle_t handle, unsigned node, void *
 	return 0;
 }
 
-static int unpack_matrix_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int peek_matrix_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
 
@@ -344,6 +346,12 @@ static int unpack_matrix_handle(starpu_data_handle_t handle, unsigned node, void
 		}
 	}
 
+	return 0;
+}
+
+static int unpack_matrix_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	peek_matrix_handle(handle, node, ptr, count);
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 
 	return 0;

+ 9 - 1
src/datawizard/interfaces/tensor_interface.c

@@ -37,6 +37,7 @@ static uint32_t footprint_tensor_interface_crc32(starpu_data_handle_t handle);
 static int tensor_compare(void *data_interface_a, void *data_interface_b);
 static void display_tensor_interface(starpu_data_handle_t handle, FILE *f);
 static int pack_tensor_handle(starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
+static int peek_tensor_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static int unpack_tensor_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static starpu_ssize_t describe(void *data_interface, char *buf, size_t size);
 
@@ -55,6 +56,7 @@ struct starpu_data_interface_ops starpu_interface_tensor_ops =
 	.interface_size = sizeof(struct starpu_tensor_interface),
 	.display = display_tensor_interface,
 	.pack_data = pack_tensor_handle,
+	.peek_data = peek_tensor_handle,
 	.unpack_data = unpack_tensor_handle,
 	.describe = describe,
 	.name = "STARPU_TENSOR_INTERFACE"
@@ -277,7 +279,7 @@ static int pack_tensor_handle(starpu_data_handle_t handle, unsigned node, void *
 	return 0;
 }
 
-static int unpack_tensor_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int peek_tensor_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
 
@@ -338,6 +340,12 @@ static int unpack_tensor_handle(starpu_data_handle_t handle, unsigned node, void
 		}
 	}
 
+	return 0;
+}
+
+static int unpack_tensor_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	peek_tensor_handle(handle, node, ptr, count);
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 
 	return 0;

+ 9 - 1
src/datawizard/interfaces/variable_interface.c

@@ -36,6 +36,7 @@ static uint32_t footprint_variable_interface_crc32(starpu_data_handle_t handle);
 static int variable_compare(void *data_interface_a, void *data_interface_b);
 static void display_variable_interface(starpu_data_handle_t handle, FILE *f);
 static int pack_variable_handle(starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
+static int peek_variable_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static int unpack_variable_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static starpu_ssize_t describe(void *data_interface, char *buf, size_t size);
 
@@ -54,6 +55,7 @@ struct starpu_data_interface_ops starpu_interface_variable_ops =
 	.interface_size = sizeof(struct starpu_variable_interface),
 	.display = display_variable_interface,
 	.pack_data = pack_variable_handle,
+	.peek_data = peek_variable_handle,
 	.unpack_data = unpack_variable_handle,
 	.describe = describe,
 	.name = "STARPU_VARIABLE_INTERFACE"
@@ -177,7 +179,7 @@ static int pack_variable_handle(starpu_data_handle_t handle, unsigned node, void
 	return 0;
 }
 
-static int unpack_variable_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int peek_variable_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
 
@@ -188,6 +190,12 @@ static int unpack_variable_handle(starpu_data_handle_t handle, unsigned node, vo
 
 	memcpy((void*)variable_interface->ptr, ptr, variable_interface->elemsize);
 
+	return 0;
+}
+
+static int unpack_variable_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	peek_variable_handle(handle, node, ptr, count);
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 
 	return 0;

+ 9 - 1
src/datawizard/interfaces/vector_interface.c

@@ -40,6 +40,7 @@ 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 peek_vector_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static int unpack_vector_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static starpu_ssize_t describe(void *data_interface, char *buf, size_t size);
 
@@ -62,6 +63,7 @@ struct starpu_data_interface_ops starpu_interface_vector_ops =
 	.interface_size = sizeof(struct starpu_vector_interface),
 	.display = display_vector_interface,
 	.pack_data = pack_vector_handle,
+	.peek_data = peek_vector_handle,
 	.unpack_data = unpack_vector_handle,
 	.describe = describe,
 	.name = "STARPU_VECTOR_INTERFACE"
@@ -222,7 +224,7 @@ static int pack_vector_handle(starpu_data_handle_t handle, unsigned node, void *
 	return 0;
 }
 
-static int unpack_vector_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+static int peek_vector_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
 {
 	STARPU_ASSERT(starpu_data_test_if_allocated_on_node(handle, node));
 
@@ -232,6 +234,12 @@ static int unpack_vector_handle(starpu_data_handle_t handle, unsigned node, void
 	STARPU_ASSERT(count == vector_interface->elemsize * vector_interface->nx);
 	memcpy((void*)vector_interface->ptr, ptr, count);
 
+	return 0;
+}
+
+static int unpack_vector_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count)
+{
+	peek_vector_handle(handle, node, ptr, count);
 	starpu_free_on_node_flags(node, (uintptr_t)ptr, count, 0);
 
 	return 0;

+ 10 - 0
src/datawizard/interfaces/void_interface.c

@@ -35,6 +35,7 @@ static uint32_t footprint_void_interface_crc32(starpu_data_handle_t handle);
 static int void_compare(void *data_interface_a, void *data_interface_b);
 static void display_void_interface(starpu_data_handle_t handle, FILE *f);
 static int pack_void_handle(starpu_data_handle_t handle, unsigned node, void **ptr, starpu_ssize_t *count);
+static int peek_void_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static int unpack_void_handle(starpu_data_handle_t handle, unsigned node, void *ptr, size_t count);
 static starpu_ssize_t describe(void *data_interface, char *buf, size_t size);
 
@@ -51,6 +52,7 @@ struct starpu_data_interface_ops starpu_interface_void_ops =
 	.interface_size = 0,
 	.display = display_void_interface,
 	.pack_data = pack_void_handle,
+	.peek_data = peek_void_handle,
 	.unpack_data = unpack_void_handle,
 	.describe = describe,
 	.pointer_is_inside = void_pointer_is_inside,
@@ -104,6 +106,14 @@ static int pack_void_handle(starpu_data_handle_t handle STARPU_ATTRIBUTE_UNUSED,
 	return 0;
 }
 
+static int peek_void_handle(starpu_data_handle_t handle STARPU_ATTRIBUTE_UNUSED,
+			      unsigned node STARPU_ATTRIBUTE_UNUSED,
+			      void *ptr STARPU_ATTRIBUTE_UNUSED,
+			      size_t count STARPU_ATTRIBUTE_UNUSED)
+{
+	return 0;
+}
+
 static int unpack_void_handle(starpu_data_handle_t handle STARPU_ATTRIBUTE_UNUSED,
 			      unsigned node STARPU_ATTRIBUTE_UNUSED,
 			      void *ptr STARPU_ATTRIBUTE_UNUSED,

+ 2 - 1
tests/datawizard/data_register.c

@@ -1,6 +1,6 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
- * Copyright (C) 2020       Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
+ * Copyright (C) 2020-2021       Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  *
  * 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
@@ -64,6 +64,7 @@ static struct starpu_data_interface_ops starpu_interface_my_ops =
 	.interface_size = sizeof(struct my_interface),
 	.display = NULL,
 	.pack_data = NULL,
+	.peek_data = NULL,
 	.unpack_data = NULL,
 	.describe = NULL,
 };

+ 1 - 0
tests/datawizard/variable_size.c

@@ -202,6 +202,7 @@ static struct starpu_data_interface_ops starpu_interface_variable_size_ops =
 	.interface_size = sizeof(struct variable_size_interface),
 	.display = display_variable_size,
 	.pack_data = NULL,
+	.peek_data = NULL,
 	.unpack_data = NULL,
 	.describe = describe_variable_size,
 

+ 1 - 0
tools/starpu_replay.c

@@ -274,6 +274,7 @@ static struct starpu_data_interface_ops replay_interface_ops =
 	.interface_size = sizeof(struct replay_interface),
 	.display = display_replay,
 	.pack_data = NULL,
+	.peek_data = NULL,
 	.unpack_data = NULL,
 	.describe = describe_replay,