소스 검색

Complete documentation of interfaces and filters

Samuel Thibault 8 년 전
부모
커밋
f4a099b0eb
3개의 변경된 파일53개의 추가작업 그리고 14개의 파일을 삭제
  1. 17 3
      doc/doxygen/chapters/310_data_management.doxy
  2. 17 6
      doc/doxygen/chapters/api/data_interfaces.doxy
  3. 19 5
      doc/doxygen/chapters/api/data_partition.doxy

+ 17 - 3
doc/doxygen/chapters/310_data_management.doxy

@@ -245,6 +245,8 @@ back to its home node, and evict it from GPUs when room is needed.
 An existing piece of data can be partitioned in sub parts to be used by different tasks, for instance:
 
 \code{.c}
+#define NX 1048576
+#define PARTS 16
 int vector[NX];
 starpu_data_handle_t handle;
 
@@ -288,7 +290,7 @@ Partitioning can be applied several times, see
 Wherever the whole piece of data is already available, the partitioning will
 be done in-place, i.e. without allocating new buffers but just using pointers
 inside the existing copy. This is particularly important to be aware of when
-using OpenCL, where the kernel parameters are not pointers, but handles. The
+using OpenCL, where the kernel parameters are not pointers, but cl_mem handles. The
 kernel thus needs to be also passed the offset within the OpenCL buffer:
 
 \code{.c}
@@ -316,7 +318,10 @@ __kernel void opencl_kernel(__global int *vector, unsigned offset)
 
 StarPU provides various interfaces and filters for matrices, vectors, etc.,
 but applications can also write their own data interfaces and filters, see
-<c>examples/interface</c> and <c>examples/filters/custom_mf</c> for an example.
+<c>examples/interface</c> and <c>examples/filters/custom_mf</c> for an example,
+and see \ref DefiningANewDataInterface and \ref DefiningANewDataFilter
+for documentation.
+
 
 \section AsynchronousPartitioning Asynchronous Partitioning
 
@@ -432,6 +437,14 @@ starpu_data_invalidate_submit(handle);
 
 And now we can start using vertical slices, etc.
 
+\section DefiningANewDataFilter Defining A New Data Filter
+
+StarPU provides a series of predefined filters in API_Data_Partition, but
+additional filters can be defined by the application. The principle is that the
+filter function just fills the memory location of the i-th subpart of a data.
+Examples are provided in <c>src/datawizard/interfaces/*_filters.c</c>,
+and see \ref starpu_data_filter::filter_func for the details.
+
 \section DataReduction Data Reduction
 
 In various cases, some piece of data is used to accumulate intermediate
@@ -760,7 +773,8 @@ Different operations need to be defined for a data interface through
 the type starpu_data_interface_ops. We only define here the basic
 operations needed to run simple applications. The source code for the
 different functions can be found in the file
-<c>examples/interface/complex_interface.c</c>.
+<c>examples/interface/complex_interface.c</c>, the details of the hooks to be
+provided are documented \ref starpu_data_interface_ops .
 
 \code{.c}
 static struct starpu_data_interface_ops interface_complex_ops =

+ 17 - 6
doc/doxygen/chapters/api/data_interfaces.doxy

@@ -14,14 +14,23 @@ Per-interface data transfer methods.
 \var void (*starpu_data_interface_ops::register_data_handle)(starpu_data_handle_t handle, unsigned home_node, void *data_interface)
     Register an existing interface into a data handle.
 
+    This iterates over all memory nodes to initialize all fields of the data
+    interface on each of them. Since data is not allocated yet except on the
+    home node, pointers should be left as NULL except on the \p home_node, for
+    which the pointers should be copied from the given \p data_interface, which
+    was filled with the application's pointers.
+
 \var starpu_ssize_t (*starpu_data_interface_ops::allocate_data_on_node)(void *data_interface, unsigned node)
-    Allocate data for the interface on a given node.
+    Allocate data for the interface on a given node. This should use
+    starpu_malloc_on_node to perform the allocation(s), and fill the pointers
+    in the data interface. It should return the size of the allocated memory, or
+    -ENOMEM if memory could not be allocated.
 
 \var void (*starpu_data_interface_ops::free_data_on_node)(void *data_interface, unsigned node)
     Free data of the interface on a given node.
 
 \var const struct starpu_data_copy_methods *starpu_data_interface_ops::copy_methods
-    ram/cuda/opencl synchronous and asynchronous transfer methods.
+    This provides a series of methods for performing ram/cuda/opencl synchronous and asynchronous transfers.
 
 \var void *(*starpu_data_interface_ops::handle_to_pointer)(starpu_data_handle_t handle, unsigned node)
     Return the current pointer (if any) for the handle on the given node.
@@ -30,21 +39,23 @@ Per-interface data transfer methods.
     Return an estimation of the size of data, for performance models.
 
 \var uint32_t (*starpu_data_interface_ops::footprint)(starpu_data_handle_t handle)
-    Return a 32bit footprint which characterizes the data size.
+    Return a 32bit footprint which characterizes the data size and layout (nx, ny, ld, elemsize, etc.)
 
 \var int (*starpu_data_interface_ops::compare)(void *data_interface_a, void *data_interface_b)
-    Compare the data size of two interfaces.
+    Compare the data size and layout of two interfaces (nx, ny, ld, elemsize,
+    etc.). It should return 1 if the two interfaces size and layout match, and 0
+    otherwise.
 
 \var void (*starpu_data_interface_ops::display)(starpu_data_handle_t handle, FILE *f)
     Dump the sizes of a handle to a file.
 
 \var starpu_ssize_t (*starpu_data_interface_ops::describe)(void *data_interface, char *buf, size_t size)
-    Describe the data into a string.
+    Describe the data into a string in a brief way, such as one letter to describe the type of data, and the data dimensions.
 
 \var enum starpu_data_interface_id starpu_data_interface_ops::interfaceid
     An identifier that is unique to each interface.
 
-\var enum starpu_data_interface_id starpu_data_interface_ops::name
+\var char *starpu_data_interface_ops::name
     Name of the interface
 
 \var size_t starpu_data_interface_ops::interface_size

+ 19 - 5
doc/doxygen/chapters/api/data_partition.doxy

@@ -12,10 +12,24 @@
 The filter structure describes a data partitioning operation, to be
 given to the starpu_data_partition() function.
 \ingroup API_Data_Partition
-\var void (*starpu_data_filter::filter_func)(void *father_interface, void *child_interface, struct starpu_data_filter *, unsigned id, unsigned nparts)
+\var void (*starpu_data_filter::filter_func)(void *father_interface, void *child_interface, struct starpu_data_filter *filter, unsigned i, unsigned nparts)
     Fill the \p child_interface structure with interface information
-    for the \p id -th child of the parent \p father_interface (among
-    \p nparts).
+    for the \p i -th child of the parent \p father_interface (among
+    \p nparts). The \p filter structure is provided, allowing to inspect the
+    starpu_data_filter::filter_arg and starpu_data_filter::filter_arg_ptr
+    parameters.
+
+    The details of what needs to be filled in \p child_interface vary according
+    to the data interface, but generally speaking:
+    <ul>
+    <li> <c>id</c> is usually just copied over from the father, when the sub data has the same structure as the father, e.g. a subvector is a vector, a submatrix is a matrix, etc. This is however not the case for instance when dividing a BCSR matrix into its dense blocks, which then are matrices. </li>
+    <li> <c>nx</c>, <c>ny</c> and alike are usually divided by the number of subdata, depending how the subdivision is done (e.g. nx division vs ny division for vertical matrix division vs horizontal matrix division). </li>
+    <li> <c>ld</c> for matrix interfaces are usually just copied over: the leading dimension (ld) usually does not change. </li>
+    <li> <c>elemsize</c> is usually just copied over. </li>
+    <li> <c>ptr</c>, the pointer to the data, has to be computed according to \p i and the father's <c>ptr</c>, so as to point to the start of the sub data. This should however be done only if the father has <c>ptr</c> different from NULL: in the OpenCL case notably, the <c>dev_handle</c> and <c>offset</c> fields are used instead. </li>
+    <li> <c>dev_handle</c> should be just copied over from the parent. </li>
+    <li> <c>offset</c> has to be computed according to \p i and the father's <c>offset</c>, so as to provide the offset of the start of the sub data. This is notably used for the OpenCL case.
+    </ul>
 \var unsigned starpu_data_filter::nchildren
     Number of parts to partition the data into.
 \var unsigned (*starpu_data_filter::get_nchildren)(struct starpu_data_filter *, starpu_data_handle_t initial_handle)
@@ -27,9 +41,9 @@ given to the starpu_data_partition() function.
     this function returns which interface is used by child number \p
     id.
 \var unsigned starpu_data_filter::filter_arg
-    Allow to define an additional parameter for the filter function.
+    Additional parameter for the filter function
 \var void *starpu_data_filter::filter_arg_ptr
-    Allow to define an additional pointer parameter for the filter
+    Additional pointer parameter for the filter
     function, such as the sizes of the different parts.
 
 @name Basic API