Browse Source

Add starpu_data_pointer_is_inside

Samuel Thibault 6 years ago
parent
commit
8ca621ccb8

+ 1 - 0
ChangeLog

@@ -119,6 +119,7 @@ StarPU 1.2.5 (git revision xxx)
 Small features:
 Small features:
   * Add a new value STARPU_TASK_COLOR to be used in
   * Add a new value STARPU_TASK_COLOR to be used in
     starpu_task_insert() to pick up the color of a task in dag.dot
     starpu_task_insert() to pick up the color of a task in dag.dot
+  * Add starpu_data_pointer_is_inside().
 
 
 Changes:
 Changes:
   * Do not export -lcuda -lcudart -lOpenCL in *starpu*.pc.
   * Do not export -lcuda -lcudart -lOpenCL in *starpu*.pc.

+ 9 - 0
doc/doxygen/chapters/api/data_interfaces.doxy

@@ -50,6 +50,9 @@ Per-interface data transfer methods.
 \var void *(*starpu_data_interface_ops::to_pointer)(void *data_interface, unsigned node)
 \var void *(*starpu_data_interface_ops::to_pointer)(void *data_interface, unsigned node)
     Return the current pointer (if any) for the given interface on the given node.
     Return the current pointer (if any) for the given interface on the given node.
 
 
+\var int (*starpu_data_interface_ops::pointer_is_inside)(void *data_interface, unsigned node, void *pointer)
+    Return whether the given \p pointer is within the data for the given interface on the given node.
+
 \var size_t (*starpu_data_interface_ops::get_size)(starpu_data_handle_t handle)
 \var size_t (*starpu_data_interface_ops::get_size)(starpu_data_handle_t handle)
     Return an estimation of the size of data, for performance models.
     Return an estimation of the size of data, for performance models.
 
 
@@ -529,6 +532,12 @@ Return the pointer associated with \p handle on node \p node or <c>NULL</c>
 if handle’s interface does not support this operation or data for this
 if handle’s interface does not support this operation or data for this
 \p handle is not allocated on that \p node.
 \p handle is not allocated on that \p node.
 
 
+\fn int starpu_data_pointer_is_inside(starpu_data_handle_t handle, unsigned node, void *pointer)
+\ingroup API_Data_Interfaces
+Return whether the given \p pointer is within the data for \p handle on node \p
+node (1) or not (0). If the handle interface does not support this operation,
+and thus the result is unknown, -1 is returned.
+
 \fn void *starpu_data_get_local_ptr(starpu_data_handle_t handle)
 \fn void *starpu_data_get_local_ptr(starpu_data_handle_t handle)
 \ingroup API_Data_Interfaces
 \ingroup API_Data_Interfaces
 Return the local pointer associated with \p handle or <c>NULL</c> if
 Return the local pointer associated with \p handle or <c>NULL</c> if

+ 12 - 0
examples/cpp/add_vectors_interface.cpp

@@ -260,6 +260,7 @@ static const struct starpu_data_copy_methods vector_cpp_copy_data_methods_s =
 static void register_vector_cpp_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void register_vector_cpp_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static starpu_ssize_t allocate_vector_cpp_buffer_on_node(void *data_interface_, unsigned dst_node);
 static starpu_ssize_t allocate_vector_cpp_buffer_on_node(void *data_interface_, unsigned dst_node);
 static void *vector_cpp_to_pointer(void *data_interface, unsigned node);
 static void *vector_cpp_to_pointer(void *data_interface, unsigned node);
+static void *vector_cpp_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static void free_vector_cpp_buffer_on_node(void *data_interface, unsigned node);
 static void free_vector_cpp_buffer_on_node(void *data_interface, unsigned node);
 static void free_vector_cpp_buffer_on_node(void *data_interface, unsigned node);
 static void free_vector_cpp_buffer_on_node(void *data_interface, unsigned node);
 static size_t vector_cpp_interface_get_size(starpu_data_handle_t handle);
 static size_t vector_cpp_interface_get_size(starpu_data_handle_t handle);
@@ -278,6 +279,7 @@ static struct starpu_data_interface_ops interface_vector_cpp_ops =
 	.free_data_on_node = free_vector_cpp_buffer_on_node,
 	.free_data_on_node = free_vector_cpp_buffer_on_node,
 	.copy_methods = &vector_cpp_copy_data_methods_s,
 	.copy_methods = &vector_cpp_copy_data_methods_s,
 	.to_pointer = vector_cpp_to_pointer,
 	.to_pointer = vector_cpp_to_pointer,
+	.pointer_is_inside = vector_cpp_pointer_is_inside,
 	.get_size = vector_cpp_interface_get_size,
 	.get_size = vector_cpp_interface_get_size,
 	.footprint = footprint_vector_cpp_interface_crc32,
 	.footprint = footprint_vector_cpp_interface_crc32,
 	.compare = vector_cpp_compare,
 	.compare = vector_cpp_compare,
@@ -300,6 +302,7 @@ static struct starpu_data_interface_ops interface_vector_cpp_ops =
 	free_vector_cpp_buffer_on_node,
 	free_vector_cpp_buffer_on_node,
 	&vector_cpp_copy_data_methods_s,
 	&vector_cpp_copy_data_methods_s,
 	vector_cpp_to_pointer,
 	vector_cpp_to_pointer,
+	vector_cpp_pointer_is_inside,
 	vector_cpp_interface_get_size,
 	vector_cpp_interface_get_size,
 	footprint_vector_cpp_interface_crc32,
 	footprint_vector_cpp_interface_crc32,
 	vector_cpp_compare,
 	vector_cpp_compare,
@@ -324,6 +327,15 @@ static void *vector_cpp_to_pointer(void *data_interface, unsigned node)
 	return (void*) vector_interface->ptr;
 	return (void*) vector_interface->ptr;
 }
 }
 
 
+static int vector_cpp_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	(void) node;
+	struct vector_cpp_interface *vector_interface = (struct vector_cpp_interface *) data_interface;
+
+	return ptr >= vector_interface->ptr &&
+		ptr < vector_interface->ptr + vector_interface->nx*vector_interface->elemsize;
+}
+
 static void register_vector_cpp_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 static void register_vector_cpp_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 {
 {
 	struct vector_cpp_interface *vector_interface = (struct vector_cpp_interface *) data_interface;
 	struct vector_cpp_interface *vector_interface = (struct vector_cpp_interface *) data_interface;

+ 27 - 0
examples/filters/custom_mf/custom_interface.c

@@ -74,6 +74,7 @@ static void     register_custom_handle(starpu_data_handle_t handle,
 static starpu_ssize_t  allocate_custom_buffer_on_node(void *data_interface_,
 static starpu_ssize_t  allocate_custom_buffer_on_node(void *data_interface_,
 					       unsigned dst_node);
 					       unsigned dst_node);
 static void*    custom_to_pointer(void *data_interface, unsigned node);
 static void*    custom_to_pointer(void *data_interface, unsigned node);
+static int      custom_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static void     free_custom_buffer_on_node(void *data_interface, unsigned node);
 static void     free_custom_buffer_on_node(void *data_interface, unsigned node);
 static size_t   custom_interface_get_size(starpu_data_handle_t handle);
 static size_t   custom_interface_get_size(starpu_data_handle_t handle);
 static uint32_t footprint_custom_interface_crc32(starpu_data_handle_t handle);
 static uint32_t footprint_custom_interface_crc32(starpu_data_handle_t handle);
@@ -94,6 +95,7 @@ static struct starpu_data_interface_ops interface_custom_ops =
 	.register_data_handle  = register_custom_handle,
 	.register_data_handle  = register_custom_handle,
 	.allocate_data_on_node = allocate_custom_buffer_on_node,
 	.allocate_data_on_node = allocate_custom_buffer_on_node,
 	.to_pointer            = custom_to_pointer,
 	.to_pointer            = custom_to_pointer,
+	.pointer_is_inside     = custom_pointer_is_inside,
 	.free_data_on_node     = free_custom_buffer_on_node,
 	.free_data_on_node     = free_custom_buffer_on_node,
 	.copy_methods          = &custom_copy_data_methods_s,
 	.copy_methods          = &custom_copy_data_methods_s,
 	.get_size              = custom_interface_get_size,
 	.get_size              = custom_interface_get_size,
@@ -224,6 +226,31 @@ custom_to_pointer(void *data, unsigned node)
 	}
 	}
 }
 }
 
 
+static int
+custom_pointer_is_inside(void *data, unsigned node, void *ptr)
+{
+	struct custom_data_interface *data_interface = data;
+
+	switch(starpu_node_get_kind(node))
+	{
+		case STARPU_CPU_RAM:
+			return ptr >= data_interface->cpu_ptr &&
+				ptr < data_interface->cpu_ptr + data_interface->nx * data_interface->ops->cpu_elemsize;
+#ifdef STARPU_USE_CUDA
+		case STARPU_CUDA_RAM:
+			return ptr >= data_interface->cuda_ptr &&
+				ptr < data_interface->cuda_ptr + data_interface->nx * data_interface->ops->cuda_elemsize;
+#endif
+#ifdef STARPU_USE_OPENCL
+		case STARPU_OPENCL_RAM:
+			return ptr >= data_interface->opencl_ptr &&
+				ptr < data_interface->opencl_ptr + data_interface->nx * data_interface->ops->opencl_elemsize;
+#endif
+		default:
+			assert(0);
+	}
+}
+
 static size_t custom_interface_get_size(starpu_data_handle_t handle)
 static size_t custom_interface_get_size(starpu_data_handle_t handle)
 {
 {
 	size_t size;
 	size_t size;

+ 11 - 0
examples/interface/complex_interface.c

@@ -20,6 +20,16 @@
 
 
 #include "complex_interface.h"
 #include "complex_interface.h"
 
 
+static int complex_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	struct starpu_complex_interface *complex_interface = data_interface;
+
+	return ptr >= &complex_interface->real &&
+		ptr < &complex_interface->real + 1
+	    || ptr >= &complex_interface->imaginary &&
+		ptr < &complex_interface->imaginary + 1;
+}
+
 double *starpu_complex_get_real(starpu_data_handle_t handle)
 double *starpu_complex_get_real(starpu_data_handle_t handle)
 {
 {
 	struct starpu_complex_interface *complex_interface =
 	struct starpu_complex_interface *complex_interface =
@@ -196,6 +206,7 @@ static struct starpu_data_interface_ops interface_complex_ops =
 	.interfaceid = STARPU_UNKNOWN_INTERFACE_ID,
 	.interfaceid = STARPU_UNKNOWN_INTERFACE_ID,
 	.interface_size = sizeof(struct starpu_complex_interface),
 	.interface_size = sizeof(struct starpu_complex_interface),
 	.to_pointer = NULL,
 	.to_pointer = NULL,
+	.pointer_is_inside = complex_pointer_is_inside,
 	.pack_data = complex_pack_data,
 	.pack_data = complex_pack_data,
 	.unpack_data = complex_unpack_data,
 	.unpack_data = complex_unpack_data,
 	.describe = complex_describe
 	.describe = complex_describe

+ 10 - 1
include/fstarpu_mod.f90

@@ -2,7 +2,7 @@
 !
 !
 ! Copyright (C) 2017, 2018                                     CNRS
 ! Copyright (C) 2017, 2018                                     CNRS
 ! Copyright (C) 2016-2017                                Inria
 ! Copyright (C) 2016-2017                                Inria
-! Copyright (C) 2016-2017                                Université de Bordeaux
+! Copyright (C) 2016-2018                                Université de Bordeaux
 !
 !
 ! StarPU is free software; you can redistribute it and/or modify
 ! 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
 ! it under the terms of the GNU Lesser General Public License as published by
@@ -784,6 +784,15 @@ module fstarpu_mod
                         integer(c_int), value, intent(in) :: node
                         integer(c_int), value, intent(in) :: node
                 end function fstarpu_data_handle_to_pointer
                 end function fstarpu_data_handle_to_pointer
 
 
+                ! void *starpu_data_pointer_is_inside(starpu_data_handle_t handle, unsigned node, void *ptr);
+                function fstarpu_data_handle_to_pointer (dh,node,ptr) bind(C,name="starpu_data_pointer_is_inside")
+                        use iso_c_binding, only: c_ptr, c_int, c_ptr
+                        type(int) :: fstarpu_data_pointer_is_inside
+                        type(c_ptr), value, intent(in) :: dh
+                        integer(c_int), value, intent(in) :: node
+                        type(c_ptr), value, intent(in) :: ptr
+                end function fstarpu_data_pointer_is_inside
+
                 ! void *starpu_data_get_local_ptr(starpu_data_handle_t handle);
                 ! void *starpu_data_get_local_ptr(starpu_data_handle_t handle);
                 function fstarpu_data_get_local_ptr (dh) bind(C,name="starpu_data_get_local_ptr")
                 function fstarpu_data_get_local_ptr (dh) bind(C,name="starpu_data_get_local_ptr")
                         use iso_c_binding, only: c_ptr, c_int
                         use iso_c_binding, only: c_ptr, c_int

+ 2 - 0
include/starpu_data_interfaces.h

@@ -126,6 +126,7 @@ struct starpu_data_interface_ops
 	const struct starpu_data_copy_methods *copy_methods;
 	const struct starpu_data_copy_methods *copy_methods;
 	void * 		 (*handle_to_pointer)		(starpu_data_handle_t handle, unsigned node); /* deprecated */
 	void * 		 (*handle_to_pointer)		(starpu_data_handle_t handle, unsigned node); /* deprecated */
 	void * 		 (*to_pointer)			(void *data_interface, unsigned node);
 	void * 		 (*to_pointer)			(void *data_interface, unsigned node);
+	int 		 (*pointer_is_inside)		(void *data_interface, unsigned node, void *ptr);
 	size_t 		 (*get_size)			(starpu_data_handle_t handle);
 	size_t 		 (*get_size)			(starpu_data_handle_t handle);
 	uint32_t 	 (*footprint)			(starpu_data_handle_t handle);
 	uint32_t 	 (*footprint)			(starpu_data_handle_t handle);
 	int 		 (*compare)			(void *data_interface_a, void *data_interface_b);
 	int 		 (*compare)			(void *data_interface_a, void *data_interface_b);
@@ -151,6 +152,7 @@ void starpu_data_ptr_register(starpu_data_handle_t handle, unsigned node);
 void starpu_data_register_same(starpu_data_handle_t *handledst, starpu_data_handle_t handlesrc);
 void starpu_data_register_same(starpu_data_handle_t *handledst, starpu_data_handle_t handlesrc);
 
 
 void *starpu_data_handle_to_pointer(starpu_data_handle_t handle, unsigned node);
 void *starpu_data_handle_to_pointer(starpu_data_handle_t handle, unsigned node);
+int starpu_data_pointer_is_inside(starpu_data_handle_t handle, unsigned node, void *ptr);
 void *starpu_data_get_local_ptr(starpu_data_handle_t handle);
 void *starpu_data_get_local_ptr(starpu_data_handle_t handle);
 
 
 void *starpu_data_get_interface_on_node(starpu_data_handle_t handle, unsigned memory_node);
 void *starpu_data_get_interface_on_node(starpu_data_handle_t handle, unsigned memory_node);

+ 15 - 0
src/datawizard/interfaces/bcsr_interface.c

@@ -43,6 +43,7 @@ static const struct starpu_data_copy_methods bcsr_copy_data_methods_s =
 
 
 static void register_bcsr_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void register_bcsr_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void *bcsr_to_pointer(void *data_interface, unsigned node);
 static void *bcsr_to_pointer(void *data_interface, unsigned node);
+static int bcsr_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static starpu_ssize_t allocate_bcsr_buffer_on_node(void *data_interface, unsigned dst_node);
 static starpu_ssize_t allocate_bcsr_buffer_on_node(void *data_interface, unsigned dst_node);
 static void free_bcsr_buffer_on_node(void *data_interface, unsigned node);
 static void free_bcsr_buffer_on_node(void *data_interface, unsigned node);
 static size_t bcsr_interface_get_size(starpu_data_handle_t handle);
 static size_t bcsr_interface_get_size(starpu_data_handle_t handle);
@@ -65,6 +66,7 @@ struct starpu_data_interface_ops starpu_interface_bcsr_ops =
 	.compare = bcsr_compare,
 	.compare = bcsr_compare,
 	.describe = describe,
 	.describe = describe,
 	.to_pointer = bcsr_to_pointer,
 	.to_pointer = bcsr_to_pointer,
+	.pointer_is_inside = bcsr_pointer_is_inside,
 	.name = "STARPU_BCSR_INTERFACE",
 	.name = "STARPU_BCSR_INTERFACE",
 	.pack_data = pack_data,
 	.pack_data = pack_data,
 	.unpack_data = unpack_data
 	.unpack_data = unpack_data
@@ -78,6 +80,19 @@ static void *bcsr_to_pointer(void *data_interface, unsigned node)
 	return (void*) bcsr_interface->nzval;
 	return (void*) bcsr_interface->nzval;
 }
 }
 
 
+static int bcsr_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	(void) node;
+	struct starpu_bcsr_interface *bcsr_interface = data_interface;
+
+	return ((char*) ptr >= (char*) bcsr_interface->nzval &&
+		(char*) ptr < (char*) bcsr_interface->nzval + bcsr_interface->nnz*bcsr_interface->r*bcsr_interface->c*bcsr_interface->elemsize)
+	    || ((char*) ptr >= (char*) bcsr_interface->colind &&
+		(char*) ptr < (char*) bcsr_interface->colind + bcsr_interface->nnz*sizeof(uint32_t))
+	    || ((char*) ptr >= (char*) bcsr_interface->rowptr &&
+		(char*) ptr < (char*) bcsr_interface->rowptr + (bcsr_interface->nrow+1)*sizeof(uint32_t));
+}
+
 static void register_bcsr_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 static void register_bcsr_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 {
 {
 	struct starpu_bcsr_interface *bcsr_interface = (struct starpu_bcsr_interface *) data_interface;
 	struct starpu_bcsr_interface *bcsr_interface = (struct starpu_bcsr_interface *) data_interface;

+ 11 - 0
src/datawizard/interfaces/block_interface.c

@@ -72,6 +72,7 @@ static const struct starpu_data_copy_methods block_copy_data_methods_s =
 
 
 static void register_block_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void register_block_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void *block_to_pointer(void *data_interface, unsigned node);
 static void *block_to_pointer(void *data_interface, unsigned node);
+static int block_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static starpu_ssize_t allocate_block_buffer_on_node(void *data_interface_, unsigned dst_node);
 static starpu_ssize_t allocate_block_buffer_on_node(void *data_interface_, unsigned dst_node);
 static void free_block_buffer_on_node(void *data_interface, unsigned node);
 static void free_block_buffer_on_node(void *data_interface, unsigned node);
 static size_t block_interface_get_size(starpu_data_handle_t handle);
 static size_t block_interface_get_size(starpu_data_handle_t handle);
@@ -87,6 +88,7 @@ struct starpu_data_interface_ops starpu_interface_block_ops =
 	.register_data_handle = register_block_handle,
 	.register_data_handle = register_block_handle,
 	.allocate_data_on_node = allocate_block_buffer_on_node,
 	.allocate_data_on_node = allocate_block_buffer_on_node,
 	.to_pointer = block_to_pointer,
 	.to_pointer = block_to_pointer,
+	.pointer_is_inside = block_pointer_is_inside,
 	.free_data_on_node = free_block_buffer_on_node,
 	.free_data_on_node = free_block_buffer_on_node,
 	.copy_methods = &block_copy_data_methods_s,
 	.copy_methods = &block_copy_data_methods_s,
 	.get_size = block_interface_get_size,
 	.get_size = block_interface_get_size,
@@ -109,6 +111,15 @@ static void *block_to_pointer(void *data_interface, unsigned node)
 	return (void*) block_interface->ptr;
 	return (void*) block_interface->ptr;
 }
 }
 
 
+static int block_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	(void) node;
+	struct starpu_block_interface *block_interface = data_interface;
+
+	return (char*) ptr >= (char*) block_interface->ptr &&
+		(char*) ptr < (char*) block_interface->ptr + block_interface->nx*block_interface->ny*block_interface->nz*block_interface->elemsize;
+}
+
 static void register_block_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 static void register_block_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 {
 {
 	struct starpu_block_interface *block_interface = (struct starpu_block_interface *) data_interface;
 	struct starpu_block_interface *block_interface = (struct starpu_block_interface *) data_interface;

+ 15 - 0
src/datawizard/interfaces/coo_interface.c

@@ -149,6 +149,20 @@ free_coo_buffer_on_node(void *data_interface, unsigned node)
 	starpu_free_on_node(node, coo_interface->values, n_values * elemsize);
 	starpu_free_on_node(node, coo_interface->values, n_values * elemsize);
 }
 }
 
 
+static int
+coo_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	struct starpu_coo_interface *coo_interface = (struct starpu_coo_interface *) data_interface;
+	(void) node;
+
+	return ((char*) ptr >= (char*) coo_interface->columns &&
+		(char*) ptr < (char*) coo_interface->columns + coo_interface->n_values * sizeof(coo_interface->columns[0]))
+	    || ((char*) ptr >= (char*) coo_interface->rows &&
+		(char*) ptr < (char*) coo_interface->rows + coo_interface->n_values * sizeof(coo_interface->rows[0]))
+	    || ((char*) ptr >= (char*) coo_interface->values &&
+		(char*) ptr < (char*) coo_interface->values + coo_interface->n_values * coo_interface->elemsize);
+}
+
 static size_t
 static size_t
 coo_interface_get_size(starpu_data_handle_t handle)
 coo_interface_get_size(starpu_data_handle_t handle)
 {
 {
@@ -208,6 +222,7 @@ struct starpu_data_interface_ops starpu_interface_coo_ops =
 	.register_data_handle  = register_coo_handle,
 	.register_data_handle  = register_coo_handle,
 	.allocate_data_on_node = allocate_coo_buffer_on_node,
 	.allocate_data_on_node = allocate_coo_buffer_on_node,
 	.to_pointer            = NULL,
 	.to_pointer            = NULL,
+	.pointer_is_inside     = coo_pointer_is_inside,
 	.free_data_on_node     = free_coo_buffer_on_node,
 	.free_data_on_node     = free_coo_buffer_on_node,
 	.copy_methods          = &coo_copy_data_methods,
 	.copy_methods          = &coo_copy_data_methods,
 	.get_size              = coo_interface_get_size,
 	.get_size              = coo_interface_get_size,

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

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
  * Copyright (C) 2011-2012,2017                           Inria
  * Copyright (C) 2011-2012,2017                           Inria
- * Copyright (C) 2008-2017                                Université de Bordeaux
+ * Copyright (C) 2008-2018                                Université de Bordeaux
  * Copyright (C) 2010                                     Mehdi Juhoor
  * Copyright (C) 2010                                     Mehdi Juhoor
  * Copyright (C) 2010-2015,2017                           CNRS
  * Copyright (C) 2010-2015,2017                           CNRS
  *
  *
@@ -41,6 +41,7 @@ static const struct starpu_data_copy_methods csr_copy_data_methods_s =
 };
 };
 
 
 static void register_csr_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void register_csr_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
+static int csr_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static starpu_ssize_t allocate_csr_buffer_on_node(void *data_interface_, unsigned dst_node);
 static starpu_ssize_t allocate_csr_buffer_on_node(void *data_interface_, unsigned dst_node);
 static void free_csr_buffer_on_node(void *data_interface, unsigned node);
 static void free_csr_buffer_on_node(void *data_interface, unsigned node);
 static size_t csr_interface_get_size(starpu_data_handle_t handle);
 static size_t csr_interface_get_size(starpu_data_handle_t handle);
@@ -62,11 +63,25 @@ struct starpu_data_interface_ops starpu_interface_csr_ops =
 	.footprint = footprint_csr_interface_crc32,
 	.footprint = footprint_csr_interface_crc32,
 	.compare = csr_compare,
 	.compare = csr_compare,
 	.describe = describe,
 	.describe = describe,
+	.pointer_is_inside = csr_pointer_is_inside,
 	.name = "STARPU_CSR_INTERFACE",
 	.name = "STARPU_CSR_INTERFACE",
 	.pack_data = pack_data,
 	.pack_data = pack_data,
 	.unpack_data = unpack_data
 	.unpack_data = unpack_data
 };
 };
 
 
+static int csr_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	(void) node;
+	struct starpu_csr_interface *csr_interface = data_interface;
+
+	return ((char*) ptr >= (char*) csr_interface->nzval &&
+		(char*) ptr < (char*) csr_interface->nzval + csr_interface->nnz*csr_interface->elemsize)
+	    || ((char*) ptr >= (char*) csr_interface->colind &&
+		(char*) ptr < (char*) csr_interface->colind + csr_interface->nnz*sizeof(uint32_t))
+	    || ((char*) ptr >= (char*) csr_interface->rowptr &&
+		(char*) ptr < (char*) csr_interface->rowptr + (csr_interface->nrow+1)*sizeof(uint32_t));
+}
+
 static void register_csr_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 static void register_csr_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 {
 {
 	struct starpu_csr_interface *csr_interface = (struct starpu_csr_interface *) data_interface;
 	struct starpu_csr_interface *csr_interface = (struct starpu_csr_interface *) data_interface;

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

@@ -523,6 +523,20 @@ void *starpu_data_handle_to_pointer(starpu_data_handle_t handle, unsigned node)
 	return NULL;
 	return NULL;
 }
 }
 
 
+int starpu_data_pointer_is_inside(starpu_data_handle_t handle, unsigned node, void *ptr)
+{
+	/* Check whether the operation is supported and the node has actually
+	 * been allocated.  */
+	if (!starpu_data_test_if_allocated_on_node(handle, node))
+		return 0;
+	if (handle->ops->pointer_is_inside)
+	{
+		return handle->ops->pointer_is_inside(starpu_data_get_interface_on_node(handle, node), node, ptr);
+	}
+	/* Don't know :/ */
+	return -1;
+}
+
 void *starpu_data_get_local_ptr(starpu_data_handle_t handle)
 void *starpu_data_get_local_ptr(starpu_data_handle_t handle)
 {
 {
 	return starpu_data_handle_to_pointer(handle,
 	return starpu_data_handle_to_pointer(handle,

+ 11 - 0
src/datawizard/interfaces/matrix_interface.c

@@ -87,6 +87,7 @@ static const struct starpu_data_copy_methods matrix_copy_data_methods_s =
 
 
 static void register_matrix_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void register_matrix_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void *matrix_to_pointer(void *data_interface, unsigned node);
 static void *matrix_to_pointer(void *data_interface, unsigned node);
+static int matrix_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static starpu_ssize_t allocate_matrix_buffer_on_node(void *data_interface_, unsigned dst_node);
 static starpu_ssize_t allocate_matrix_buffer_on_node(void *data_interface_, unsigned dst_node);
 static void free_matrix_buffer_on_node(void *data_interface, unsigned node);
 static void free_matrix_buffer_on_node(void *data_interface, unsigned node);
 static size_t matrix_interface_get_size(starpu_data_handle_t handle);
 static size_t matrix_interface_get_size(starpu_data_handle_t handle);
@@ -102,6 +103,7 @@ struct starpu_data_interface_ops starpu_interface_matrix_ops =
 	.register_data_handle = register_matrix_handle,
 	.register_data_handle = register_matrix_handle,
 	.allocate_data_on_node = allocate_matrix_buffer_on_node,
 	.allocate_data_on_node = allocate_matrix_buffer_on_node,
 	.to_pointer = matrix_to_pointer,
 	.to_pointer = matrix_to_pointer,
+	.pointer_is_inside = matrix_pointer_is_inside,
 	.free_data_on_node = free_matrix_buffer_on_node,
 	.free_data_on_node = free_matrix_buffer_on_node,
 	.copy_methods = &matrix_copy_data_methods_s,
 	.copy_methods = &matrix_copy_data_methods_s,
 	.get_size = matrix_interface_get_size,
 	.get_size = matrix_interface_get_size,
@@ -156,6 +158,15 @@ static void *matrix_to_pointer(void *data_interface, unsigned node)
 	return (void*) matrix_interface->ptr;
 	return (void*) matrix_interface->ptr;
 }
 }
 
 
+static int matrix_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	(void) node;
+	struct starpu_matrix_interface *matrix_interface = data_interface;
+
+	return (char*) ptr >= (char*) matrix_interface->ptr &&
+		(char*) ptr < (char*) matrix_interface->ptr + matrix_interface->nx*matrix_interface->ny*matrix_interface->elemsize;
+}
+
 
 
 /* declare a new data with the matrix interface */
 /* declare a new data with the matrix interface */
 void starpu_matrix_data_register(starpu_data_handle_t *handleptr, int home_node,
 void starpu_matrix_data_register(starpu_data_handle_t *handleptr, int home_node,

+ 32 - 0
src/datawizard/interfaces/multiformat_interface.c

@@ -85,6 +85,7 @@ static const struct starpu_data_copy_methods multiformat_copy_data_methods_s =
 static void register_multiformat_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void register_multiformat_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static starpu_ssize_t allocate_multiformat_buffer_on_node(void *data_interface_, unsigned dst_node);
 static starpu_ssize_t allocate_multiformat_buffer_on_node(void *data_interface_, unsigned dst_node);
 static void *multiformat_to_pointer(void *data_interface, unsigned node);
 static void *multiformat_to_pointer(void *data_interface, unsigned node);
+static int multiformat_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static void free_multiformat_buffer_on_node(void *data_interface, unsigned node);
 static void free_multiformat_buffer_on_node(void *data_interface, unsigned node);
 static size_t multiformat_interface_get_size(starpu_data_handle_t handle);
 static size_t multiformat_interface_get_size(starpu_data_handle_t handle);
 static uint32_t footprint_multiformat_interface_crc32(starpu_data_handle_t handle);
 static uint32_t footprint_multiformat_interface_crc32(starpu_data_handle_t handle);
@@ -106,6 +107,7 @@ struct starpu_data_interface_ops starpu_interface_multiformat_ops =
 	.register_data_handle  = register_multiformat_handle,
 	.register_data_handle  = register_multiformat_handle,
 	.allocate_data_on_node = allocate_multiformat_buffer_on_node,
 	.allocate_data_on_node = allocate_multiformat_buffer_on_node,
 	.to_pointer            = multiformat_to_pointer,
 	.to_pointer            = multiformat_to_pointer,
+	.pointer_is_inside     = multiformat_pointer_is_inside,
 	.free_data_on_node     = free_multiformat_buffer_on_node,
 	.free_data_on_node     = free_multiformat_buffer_on_node,
 	.copy_methods          = &multiformat_copy_data_methods_s,
 	.copy_methods          = &multiformat_copy_data_methods_s,
 	.get_size              = multiformat_interface_get_size,
 	.get_size              = multiformat_interface_get_size,
@@ -144,6 +146,36 @@ static void *multiformat_to_pointer(void *data_interface, unsigned node)
 	return NULL;
 	return NULL;
 }
 }
 
 
+static int multiformat_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	struct starpu_multiformat_interface *multiformat_interface = data_interface;
+
+	switch(starpu_node_get_kind(node))
+	{
+		case STARPU_CPU_RAM:
+			return (char*) ptr >= (char*) multiformat_interface->cpu_ptr &&
+				(char*) ptr < (char*) multiformat_interface->cpu_ptr + multiformat_interface->nx * multiformat_interface->ops->cpu_elemsize;
+#ifdef STARPU_USE_CUDA
+		case STARPU_CUDA_RAM:
+			return (char*) ptr >= (char*) multiformat_interface->cuda_ptr &&
+				(char*) ptr < (char*) multiformat_interface->cuda_ptr + multiformat_interface->nx * multiformat_interface->ops->cuda_elemsize;
+#endif
+#ifdef STARPU_USE_OPENCL
+		case STARPU_OPENCL_RAM:
+			return (char*) ptr >= (char*) multiformat_interface->opencl_ptr &&
+				(char*) ptr < (char*) multiformat_interface->opencl_ptr + multiformat_interface->nx * multiformat_interface->ops->opencl_elemsize;
+#endif
+#ifdef STARPU_USE_MIC
+		case STARPU_MIC_RAM:
+			return (char*) ptr >= (char*) multiformat_interface->mic_ptr &&
+				(char*) ptr < (char*) multiformat_interface->mic_ptr + multiformat_interface->nx * multiformat_interface->ops->mic_elemsize;
+#endif
+		default:
+			STARPU_ABORT();
+	}
+	return -1;
+}
+
 static void register_multiformat_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 static void register_multiformat_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 {
 {
 	struct starpu_multiformat_interface *multiformat_interface;
 	struct starpu_multiformat_interface *multiformat_interface;

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

@@ -40,6 +40,7 @@ static const struct starpu_data_copy_methods variable_copy_data_methods_s =
 static void register_variable_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void register_variable_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static starpu_ssize_t allocate_variable_buffer_on_node(void *data_interface_, unsigned dst_node);
 static starpu_ssize_t allocate_variable_buffer_on_node(void *data_interface_, unsigned dst_node);
 static void *variable_to_pointer(void *data_interface, unsigned node);
 static void *variable_to_pointer(void *data_interface, unsigned node);
+static int variable_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static void free_variable_buffer_on_node(void *data_interface, unsigned node);
 static void free_variable_buffer_on_node(void *data_interface, unsigned node);
 static size_t variable_interface_get_size(starpu_data_handle_t handle);
 static size_t variable_interface_get_size(starpu_data_handle_t handle);
 static uint32_t footprint_variable_interface_crc32(starpu_data_handle_t handle);
 static uint32_t footprint_variable_interface_crc32(starpu_data_handle_t handle);
@@ -54,6 +55,7 @@ struct starpu_data_interface_ops starpu_interface_variable_ops =
 	.register_data_handle = register_variable_handle,
 	.register_data_handle = register_variable_handle,
 	.allocate_data_on_node = allocate_variable_buffer_on_node,
 	.allocate_data_on_node = allocate_variable_buffer_on_node,
 	.to_pointer = variable_to_pointer,
 	.to_pointer = variable_to_pointer,
+	.pointer_is_inside = variable_pointer_is_inside,
 	.free_data_on_node = free_variable_buffer_on_node,
 	.free_data_on_node = free_variable_buffer_on_node,
 	.copy_methods = &variable_copy_data_methods_s,
 	.copy_methods = &variable_copy_data_methods_s,
 	.get_size = variable_interface_get_size,
 	.get_size = variable_interface_get_size,
@@ -74,6 +76,14 @@ static void *variable_to_pointer(void *data_interface, unsigned node)
 	return (void*) STARPU_VARIABLE_GET_PTR(data_interface);
 	return (void*) STARPU_VARIABLE_GET_PTR(data_interface);
 }
 }
 
 
+static int variable_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	(void) node;
+	struct starpu_variable_interface *variable_interface = data_interface;
+	return (char*) ptr >= (char*) variable_interface->ptr &&
+		(char*) ptr < (char*) variable_interface->ptr + variable_interface->elemsize;
+}
+
 static void register_variable_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 static void register_variable_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 {
 {
 	struct starpu_variable_interface *variable_interface = (struct starpu_variable_interface *)data_interface;
 	struct starpu_variable_interface *variable_interface = (struct starpu_variable_interface *)data_interface;

+ 11 - 0
src/datawizard/interfaces/vector_interface.c

@@ -40,6 +40,7 @@ static const struct starpu_data_copy_methods vector_copy_data_methods_s =
 static void register_vector_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void register_vector_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static starpu_ssize_t allocate_vector_buffer_on_node(void *data_interface_, unsigned dst_node);
 static starpu_ssize_t allocate_vector_buffer_on_node(void *data_interface_, unsigned dst_node);
 static void *vector_to_pointer(void *data_interface, unsigned node);
 static void *vector_to_pointer(void *data_interface, unsigned node);
+static int vector_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static void free_vector_buffer_on_node(void *data_interface, unsigned node);
 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 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 footprint_vector_interface_crc32(starpu_data_handle_t handle);
@@ -54,6 +55,7 @@ struct starpu_data_interface_ops starpu_interface_vector_ops =
 	.register_data_handle = register_vector_handle,
 	.register_data_handle = register_vector_handle,
 	.allocate_data_on_node = allocate_vector_buffer_on_node,
 	.allocate_data_on_node = allocate_vector_buffer_on_node,
 	.to_pointer = vector_to_pointer,
 	.to_pointer = vector_to_pointer,
+	.pointer_is_inside = vector_pointer_is_inside,
 	.free_data_on_node = free_vector_buffer_on_node,
 	.free_data_on_node = free_vector_buffer_on_node,
 	.copy_methods = &vector_copy_data_methods_s,
 	.copy_methods = &vector_copy_data_methods_s,
 	.get_size = vector_interface_get_size,
 	.get_size = vector_interface_get_size,
@@ -76,6 +78,15 @@ static void *vector_to_pointer(void *data_interface, unsigned node)
 	return (void*) vector_interface->ptr;
 	return (void*) vector_interface->ptr;
 }
 }
 
 
+static int vector_pointer_is_inside(void *data_interface, unsigned node, void *ptr)
+{
+	(void) node;
+	struct starpu_vector_interface *vector_interface = data_interface;
+
+	return (char*) ptr >= (char*) vector_interface->ptr &&
+		(char*) ptr < (char*) vector_interface->ptr + vector_interface->nx*vector_interface->elemsize;
+}
+
 static void register_vector_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 static void register_vector_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
 {
 {
 	struct starpu_vector_interface *vector_interface = (struct starpu_vector_interface *) data_interface;
 	struct starpu_vector_interface *vector_interface = (struct starpu_vector_interface *) data_interface;

+ 8 - 1
src/datawizard/interfaces/void_interface.c

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  *
  * Copyright (C) 2012-2013                                Inria
  * Copyright (C) 2012-2013                                Inria
- * Copyright (C) 2010-2014                                Université de Bordeaux
+ * Copyright (C) 2010-2014, 2018                                Université de Bordeaux
  * Copyright (C) 2011-2015,2017                           CNRS
  * Copyright (C) 2011-2015,2017                           CNRS
  *
  *
  * StarPU is free software; you can redistribute it and/or modify
  * StarPU is free software; you can redistribute it and/or modify
@@ -35,6 +35,7 @@ static const struct starpu_data_copy_methods void_copy_data_methods_s =
 
 
 static void register_void_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static void register_void_handle(starpu_data_handle_t handle, unsigned home_node, void *data_interface);
 static starpu_ssize_t allocate_void_buffer_on_node(void *data_interface_, unsigned dst_node);
 static starpu_ssize_t allocate_void_buffer_on_node(void *data_interface_, unsigned dst_node);
+static int void_pointer_is_inside(void *data_interface, unsigned node, void *ptr);
 static void free_void_buffer_on_node(void *data_interface, unsigned node);
 static void free_void_buffer_on_node(void *data_interface, unsigned node);
 static size_t void_interface_get_size(starpu_data_handle_t handle);
 static size_t void_interface_get_size(starpu_data_handle_t handle);
 static uint32_t footprint_void_interface_crc32(starpu_data_handle_t handle);
 static uint32_t footprint_void_interface_crc32(starpu_data_handle_t handle);
@@ -59,9 +60,15 @@ struct starpu_data_interface_ops starpu_interface_void_ops =
 	.pack_data = pack_void_handle,
 	.pack_data = pack_void_handle,
 	.unpack_data = unpack_void_handle,
 	.unpack_data = unpack_void_handle,
 	.describe = describe,
 	.describe = describe,
+	.pointer_is_inside = void_pointer_is_inside,
 	.name = "STARPU_VOID_INTERFACE"
 	.name = "STARPU_VOID_INTERFACE"
 };
 };
 
 
+static int void_pointer_is_inside(void *data_interface STARPU_ATTRIBUTE_UNUSED, unsigned node STARPU_ATTRIBUTE_UNUSED, void *ptr STARPU_ATTRIBUTE_UNUSED)
+{
+	return 0;
+}
+
 static void register_void_handle(starpu_data_handle_t handle STARPU_ATTRIBUTE_UNUSED,
 static void register_void_handle(starpu_data_handle_t handle STARPU_ATTRIBUTE_UNUSED,
 				unsigned home_node STARPU_ATTRIBUTE_UNUSED,
 				unsigned home_node STARPU_ATTRIBUTE_UNUSED,
 				void *data_interface STARPU_ATTRIBUTE_UNUSED)
 				void *data_interface STARPU_ATTRIBUTE_UNUSED)

+ 5 - 1
tests/datawizard/handle_to_pointer.c

@@ -2,7 +2,7 @@
  *
  *
  * Copyright (C) 2011-2013                                Inria
  * Copyright (C) 2011-2013                                Inria
  * Copyright (C) 2012-2013,2015-2017                      CNRS
  * Copyright (C) 2012-2013,2015-2017                      CNRS
- * Copyright (C) 2012-2014,2016                           Université de Bordeaux
+ * Copyright (C) 2012-2014,2016,2018                      Université de Bordeaux
  *
  *
  * StarPU is free software; you can redistribute it and/or modify
  * 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
  * it under the terms of the GNU Lesser General Public License as published by
@@ -119,16 +119,19 @@ int main(int argc, char *argv[])
 	starpu_variable_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)pointer,
 	starpu_variable_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)pointer,
 				      sizeof(int));
 				      sizeof(int));
 	STARPU_ASSERT(starpu_data_handle_to_pointer(handle, STARPU_MAIN_RAM) == pointer);
 	STARPU_ASSERT(starpu_data_handle_to_pointer(handle, STARPU_MAIN_RAM) == pointer);
+	STARPU_ASSERT(starpu_data_pointer_is_inside(handle, STARPU_MAIN_RAM, pointer));
 	starpu_data_unregister(handle);
 	starpu_data_unregister(handle);
 
 
 	starpu_vector_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)pointer,
 	starpu_vector_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)pointer,
 				    count, sizeof(int));
 				    count, sizeof(int));
 	STARPU_ASSERT(starpu_data_handle_to_pointer(handle, STARPU_MAIN_RAM) == pointer);
 	STARPU_ASSERT(starpu_data_handle_to_pointer(handle, STARPU_MAIN_RAM) == pointer);
+	STARPU_ASSERT(starpu_data_pointer_is_inside(handle, STARPU_MAIN_RAM, pointer));
 	starpu_data_unregister(handle);
 	starpu_data_unregister(handle);
 
 
 	starpu_matrix_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)pointer, 0,
 	starpu_matrix_data_register(&handle, STARPU_MAIN_RAM, (uintptr_t)pointer, 0,
 				    count, 1, sizeof(int));
 				    count, 1, sizeof(int));
 	STARPU_ASSERT(starpu_data_handle_to_pointer(handle, STARPU_MAIN_RAM) == pointer);
 	STARPU_ASSERT(starpu_data_handle_to_pointer(handle, STARPU_MAIN_RAM) == pointer);
+	STARPU_ASSERT(starpu_data_pointer_is_inside(handle, STARPU_MAIN_RAM, pointer));
 	starpu_data_unregister(handle);
 	starpu_data_unregister(handle);
 
 
 	starpu_free(pointer);
 	starpu_free(pointer);
@@ -164,6 +167,7 @@ int main(int argc, char *argv[])
 		for(i = 0; i < count; i++)
 		for(i = 0; i < count; i++)
 		{
 		{
 			int *numbers = (int *)pointer;
 			int *numbers = (int *)pointer;
+			STARPU_ASSERT(starpu_data_pointer_is_inside(handle, STARPU_MAIN_RAM, numbers));
 			if (numbers[i] != i)
 			if (numbers[i] != i)
 			{
 			{
 				FPRINTF(stderr, "Incorrect value numbers[%d] == %d should be %d\n", (int)i, numbers[i], (int)i);
 				FPRINTF(stderr, "Incorrect value numbers[%d] == %d should be %d\n", (int)i, numbers[i], (int)i);

+ 44 - 0
tests/datawizard/interfaces/test_interfaces.c

@@ -88,6 +88,7 @@ struct data_interface_test_summary
 	int compare;
 	int compare;
 #ifdef STARPU_USE_CPU
 #ifdef STARPU_USE_CPU
 	int to_pointer;
 	int to_pointer;
+	int pointer_is_inside;
 #endif
 #endif
 };
 };
 
 
@@ -147,6 +148,8 @@ void data_interface_test_summary_print(FILE *f,
 		enum_to_string(s->cpu_to_cpu));
 		enum_to_string(s->cpu_to_cpu));
 	FPRINTF(f, "to_pointer() : %s\n",
 	FPRINTF(f, "to_pointer() : %s\n",
 		enum_to_string(s->to_pointer));
 		enum_to_string(s->to_pointer));
+	FPRINTF(f, "pointer_is_inside() : %s\n",
+		enum_to_string(s->pointer_is_inside));
 #endif /* !STARPU_USE_CPU */
 #endif /* !STARPU_USE_CPU */
 	FPRINTF(f, "compare()        : %s\n",
 	FPRINTF(f, "compare()        : %s\n",
 		enum_to_string(s->compare));
 		enum_to_string(s->compare));
@@ -268,6 +271,7 @@ static struct data_interface_test_summary summary =
 #endif
 #endif
 #ifdef STARPU_USE_CPU
 #ifdef STARPU_USE_CPU
 	.to_pointer            = UNTESTED,
 	.to_pointer            = UNTESTED,
+	.pointer_is_inside     = UNTESTED,
 #endif
 #endif
 	.success               = SUCCESS
 	.success               = SUCCESS
 };
 };
@@ -812,6 +816,45 @@ to_pointer(void)
 	if (tests > 0)
 	if (tests > 0)
 		summary.to_pointer = SUCCESS;
 		summary.to_pointer = SUCCESS;
 }
 }
+
+static void
+pointer_is_inside(void)
+{
+	void *ptr;
+	unsigned int node;
+	unsigned int tests = 0;
+	starpu_data_handle_t handle;
+	void * data_interface;
+
+	handle = *current_config->handle;
+	if (!handle->ops->pointer_is_inside || !handle->ops->to_pointer)
+		return;
+
+	for (node = 0; node < STARPU_MAXNODES; node++)
+	{
+		if (starpu_node_get_kind(node) != STARPU_CPU_RAM)
+			continue;
+		if (!starpu_data_test_if_allocated_on_node(handle, node))
+			continue;
+
+		data_interface = starpu_data_get_interface_on_node(handle, node);
+		ptr = handle->ops->to_pointer(data_interface, node);
+		if (starpu_data_lookup(ptr) != handle)
+		{
+			summary.pointer_is_inside = FAILURE;
+			return;
+		}
+		if (!starpu_data_pointer_is_inside(handle, node, ptr))
+		{
+			summary.pointer_is_inside = FAILURE;
+			return;
+		}
+		tests++;
+	}
+
+	if (tests > 0)
+		summary.pointer_is_inside = SUCCESS;
+}
 #endif /* !STARPU_USE_CPU */
 #endif /* !STARPU_USE_CPU */
 
 
 static int
 static int
@@ -856,6 +899,7 @@ run_tests(struct test_config *conf)
 	ram_to_ram();
 	ram_to_ram();
 	compare();
 	compare();
 	to_pointer();
 	to_pointer();
+	pointer_is_inside();
 #endif
 #endif
 
 
 	return &summary;
 	return &summary;