123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- /*
- * This file is part of the StarPU Handbook.
- * Copyright (C) 2009--2011 Universit@'e de Bordeaux
- * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016 CNRS
- * Copyright (C) 2011, 2012 INRIA
- * See the file version.doxy for copying conditions.
- */
- /*! \defgroup API_Data_Management Data Management
- \brief This section describes the data management facilities provided
- by StarPU. We show how to use existing data interfaces in
- \ref API_Data_Interfaces, but developers can design their own data interfaces if
- required.
- \typedef starpu_data_handle_t
- \ingroup API_Data_Management
- StarPU uses ::starpu_data_handle_t as an opaque handle to
- manage a piece of data. Once a piece of data has been registered to
- StarPU, it is associated to a ::starpu_data_handle_t which keeps track
- of the state of the piece of data over the entire machine, so that we
- can maintain data consistency and locate data replicates for instance.
- \typedef starpu_arbiter_t
- \ingroup API_Data_Management
- This is an arbiter, which implements an advanced but centralized management of
- concurrent data accesses, see \ref ConcurrentDataAccess for the details.
- \enum starpu_data_access_mode
- \ingroup API_Data_Management
- This datatype describes a data access mode.
- \var starpu_data_access_mode::STARPU_NONE
- \ingroup API_Data_Management
- TODO
- \var starpu_data_access_mode::STARPU_R
- \ingroup API_Data_Management
- read-only mode.
- \var starpu_data_access_mode::STARPU_W
- \ingroup API_Data_Management
- write-only mode.
- \var starpu_data_access_mode::STARPU_RW
- \ingroup API_Data_Management
- read-write mode. This is equivalent to ::STARPU_R|::STARPU_W
- \var starpu_data_access_mode::STARPU_SCRATCH
- \ingroup API_Data_Management
- A temporary buffer is allocated for the task, but StarPU does not
- enforce data consistency---i.e. each device has its own buffer,
- independently from each other (even for CPUs), and no data transfer is
- ever performed. This is useful for temporary variables to avoid
- allocating/freeing buffers inside each task. Currently, no behavior is
- defined concerning the relation with the ::STARPU_R and ::STARPU_W modes
- and the value provided at registration --- i.e., the value of the
- scratch buffer is undefined at entry of the codelet function. It is
- being considered for future extensions at least to define the initial
- value. For now, data to be used in ::STARPU_SCRATCH mode should be
- registered with node <c>-1</c> and a <c>NULL</c> pointer, since the
- value of the provided buffer is simply ignored for now.
- \var starpu_data_access_mode::STARPU_REDUX
- \ingroup API_Data_Management
- todo
- \var starpu_data_access_mode::STARPU_COMMUTE
- \ingroup API_Data_Management
- In addition to that, ::STARPU_COMMUTE can be passed along ::STARPU_W
- or ::STARPU_RW to express that StarPU can let tasks commute, which is
- useful e.g. when bringing a contribution into some data, which can be
- done in any order (but still require sequential consistency against
- reads or non-commutative writes).
- \var starpu_data_access_mode::STARPU_SSEND
- \ingroup API_Data_Management
- used in starpu_mpi_insert_task() to specify the data has to be sent
- using a synchronous and non-blocking mode (see starpu_mpi_issend())
- \var starpu_data_access_mode::STARPU_LOCALITY
- \ingroup API_Data_Management
- used to tell the scheduler which data is the most important for the task, and
- should thus be used to try to group tasks on the same core or cache, etc. For
- now only the ws and lws schedulers take this flag into account, and only when
- rebuild with USE_LOCALITY flag defined in the
- src/sched_policies/work_stealing_policy.c source code.
- @name Basic Data Management API
- \ingroup API_Data_Management
- Data management is done at a high-level in StarPU: rather than
- accessing a mere list of contiguous buffers, the tasks may manipulate
- data that are described by a high-level construct which we call data
- interface.
- An example of data interface is the "vector" interface which describes
- a contiguous data array on a spefic memory node. This interface is a
- simple structure containing the number of elements in the array, the
- size of the elements, and the address of the array in the appropriate
- address space (this address may be invalid if there is no valid copy
- of the array in the memory node). More informations on the data
- interfaces provided by StarPU are given in \ref API_Data_Interfaces.
- When a piece of data managed by StarPU is used by a task, the task
- implementation is given a pointer to an interface describing a valid
- copy of the data that is accessible from the current processing unit.
- Every worker is associated to a memory node which is a logical
- abstraction of the address space from which the processing unit gets
- its data. For instance, the memory node associated to the different
- CPU workers represents main memory (RAM), the memory node associated
- to a GPU is DRAM embedded on the device. Every memory node is
- identified by a logical index which is accessible from the
- function starpu_worker_get_memory_node(). When registering a piece of
- data to StarPU, the specified memory node indicates where the piece of
- data initially resides (we also call this memory node the home node of
- a piece of data).
- In the case of NUMA systems, functions starpu_numaphysid_get_memory_node()
- and starpu_memory_node_get_numaphysid() can be used to convert from NUMA node
- numbers as seen by the Operating System and NUMA node numbers as seen by StarPU.
- \fn void starpu_data_register(starpu_data_handle_t *handleptr, int home_node, void *data_interface, struct starpu_data_interface_ops *ops)
- \ingroup API_Data_Management
- Register a piece of data into the handle located at the
- \p handleptr address. The \p data_interface buffer contains the initial
- description of the data in the \p home_node. The \p ops argument is a
- pointer to a structure describing the different methods used to
- manipulate this type of interface. See starpu_data_interface_ops for
- more details on this structure.
- If \p home_node is -1, StarPU will automatically allocate the memory when
- it is used for the first time in write-only mode. Once such data
- handle has been automatically allocated, it is possible to access it
- using any access mode.
- Note that StarPU supplies a set of predefined types of interface (e.g.
- vector or matrix) which can be registered by the means of helper
- functions (e.g. starpu_vector_data_register() or
- starpu_matrix_data_register()).
- \fn void starpu_data_ptr_register(starpu_data_handle_t handle, unsigned node)
- \ingroup API_Data_Management
- Register that a buffer for \p handle on \p node will be set. This is typically
- used by starpu_*_ptr_register helpers before setting the interface pointers for
- this node, to tell the core that that is now allocated.
- \fn void starpu_data_register_same(starpu_data_handle_t *handledst, starpu_data_handle_t handlesrc)
- \ingroup API_Data_Management
- Register a new piece of data into the handle \p handledst with the
- same interface as the handle \p handlesrc.
- \fn void starpu_data_unregister(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- This function unregisters a data handle from StarPU. If the
- data was automatically allocated by StarPU because the home node was
- -1, all automatically allocated buffers are freed. Otherwise, a valid
- copy of the data is put back into the home node in the buffer that was
- initially registered. Using a data handle that has been unregistered
- from StarPU results in an undefined behaviour. In case we do not need
- to update the value of the data in the home node, we can use
- the function starpu_data_unregister_no_coherency() instead.
- \fn void starpu_data_unregister_no_coherency(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- This is the same as starpu_data_unregister(), except that
- StarPU does not put back a valid copy into the home node, in the
- buffer that was initially registered.
- \fn void starpu_data_unregister_submit(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- Destroy the data handle once it is not needed anymore by any
- submitted task. No coherency is assumed.
- \fn void starpu_data_invalidate(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- Destroy all replicates of the data handle immediately. After
- data invalidation, the first access to the handle must be performed in
- write-only mode. Accessing an invalidated data in read-mode results in
- undefined behaviour.
- \fn void starpu_data_invalidate_submit(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- Submits invalidation of the data handle after completion of
- previously submitted tasks.
- \fn void starpu_data_set_wt_mask(starpu_data_handle_t handle, uint32_t wt_mask)
- \ingroup API_Data_Management
- This function sets the write-through mask of a given data (and
- its children), i.e. a bitmask of nodes where the data should be always
- replicated after modification. It also prevents the data from being
- evicted from these nodes when memory gets scarse. When the data is
- modified, it is automatically transfered into those memory node. For
- instance a <c>1<<0</c> write-through mask means that the CUDA workers
- will commit their changes in main memory (node 0).
- \fn int starpu_data_fetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
- \ingroup API_Data_Management
- Issue a fetch request for a given data to a given node, i.e.
- requests that the data be replicated to the given node as soon as possible, so that it is
- available there for tasks. If the \p async parameter is 0, the call will
- block until the transfer is achieved, else the call will return immediately,
- after having just queued the request. In the latter case, the request will
- asynchronously wait for the completion of any task writing on the data.
- \fn int starpu_data_prefetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
- \ingroup API_Data_Management
- Issue a prefetch request for a given data to a given node, i.e.
- requests that the data be replicated to the given node when there is room for it, so that it is
- available there for tasks. If the \p async parameter is 0, the call will
- block until the transfer is achieved, else the call will return immediately,
- after having just queued the request. In the latter case, the request will
- asynchronously wait for the completion of any task writing on the data.
- \fn int starpu_data_idle_prefetch_on_node(starpu_data_handle_t handle, unsigned node, unsigned async)
- \ingroup API_Data_Management
- Issue an idle prefetch request for a given data to a given node, i.e.
- requests that the data be replicated to the given node, so that it is
- available there for tasks, but only when the bus is really idle. If the \p async parameter is 0, the call will
- block until the transfer is achieved, else the call will return immediately,
- after having just queued the request. In the latter case, the request will
- asynchronously wait for the completion of any task writing on the data.
- \fn void starpu_data_wont_use(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- Advise StarPU that this handle will not be used in the close future, and is
- thus a good candidate for eviction from GPUs. StarPU will thus write its value
- back to its home node when the bus is idle, and select this data in priority
- for eviction when memory gets low.
- \fn starpu_data_handle_t starpu_data_lookup(const void *ptr)
- \ingroup API_Data_Management
- Return the handle corresponding to the data pointed to by the \p ptr host pointer.
- \fn int starpu_data_request_allocation(starpu_data_handle_t handle, unsigned node)
- \ingroup API_Data_Management
- Explicitly ask StarPU to allocate room for a piece of data on
- the specified memory node.
- \fn void starpu_data_query_status(starpu_data_handle_t handle, int memory_node, int *is_allocated, int *is_valid, int *is_requested)
- \ingroup API_Data_Management
- Query the status of \p handle on the specified \p memory_node.
- \fn void starpu_data_advise_as_important(starpu_data_handle_t handle, unsigned is_important)
- \ingroup API_Data_Management
- This function allows to specify that a piece of data can be
- discarded without impacting the application.
- \fn void starpu_data_set_reduction_methods(starpu_data_handle_t handle, struct starpu_codelet *redux_cl, struct starpu_codelet *init_cl)
- \ingroup API_Data_Management
- This sets the codelets to be used for \p handle when it is
- accessed in the mode ::STARPU_REDUX. Per-worker buffers will be initialized with
- the codelet \p init_cl, and reduction between per-worker buffers will be
- done with the codelet \p redux_cl.
- \fn struct starpu_data_interface_ops* starpu_data_get_interface_ops(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- todo
- \fn void starpu_data_set_user_data(starpu_data_handle_t handle, void* user_data)
- \ingroup API_Data_Management
- This sets the "user_data" field for the \p handle to \p user_data . It can
- then be retrieved with starpu_data_get_user_data. \p user_data can be any
- application-defined value, for instance a pointer to an object-oriented
- container for the data.
- \fn void *starpu_data_get_user_data(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- This retrieves the "user_data" field previously set for the \p handle .
- @name Access registered data from the application
- \ingroup API_Data_Management
- \fn int starpu_data_acquire(starpu_data_handle_t handle, enum starpu_data_access_mode mode)
- \ingroup API_Data_Management
- The application must call this function prior to accessing
- registered data from main memory outside tasks. StarPU ensures that
- the application will get an up-to-date copy of the data in main memory
- located where the data was originally registered, and that all
- concurrent accesses (e.g. from tasks) will be consistent with the
- access mode specified in the mode argument. starpu_data_release() must
- be called once the application does not need to access the piece of
- data anymore. Note that implicit data dependencies are also enforced
- by starpu_data_acquire(), i.e. starpu_data_acquire() will wait for all
- tasks scheduled to work on the data, unless they have been disabled
- explictly by calling starpu_data_set_default_sequential_consistency_flag() or
- starpu_data_set_sequential_consistency_flag(). starpu_data_acquire() is a
- blocking call, so that it cannot be called from tasks or from their
- callbacks (in that case, starpu_data_acquire() returns <c>-EDEADLK</c>). Upon
- successful completion, this function returns 0.
- \fn int starpu_data_acquire_cb(starpu_data_handle_t handle, enum starpu_data_access_mode mode, void (*callback)(void *), void *arg)
- \ingroup API_Data_Management
- Asynchronous equivalent of starpu_data_acquire(). When the data
- specified in \p handle is available in the appropriate access
- mode, the \p callback function is executed. The application may access
- the requested data during the execution of this \p callback. The \p callback
- function must call starpu_data_release() once the application does not
- need to access the piece of data anymore. Note that implicit data
- dependencies are also enforced by starpu_data_acquire_cb() in case they
- are not disabled. Contrary to starpu_data_acquire(), this function is
- non-blocking and may be called from task callbacks. Upon successful
- completion, this function returns 0.
- \fn int starpu_data_acquire_cb_sequential_consistency(starpu_data_handle_t handle, enum starpu_data_access_mode mode, void (*callback)(void *), void *arg, int sequential_consistency)
- \ingroup API_Data_Management
- Equivalent of starpu_data_acquire_cb() with the possibility of enabling or disabling data dependencies.
- When the data specified in \p handle is available in the appropriate access
- mode, the \p callback function is executed. The application may access
- the requested data during the execution of this \p callback. The \p callback
- function must call starpu_data_release() once the application does not
- need to access the piece of data anymore. Note that implicit data
- dependencies are also enforced by starpu_data_acquire_cb_sequential_consistency() in case they
- are not disabled specifically for the given \p handle or by the parameter \p sequential_consistency.
- Similarly to starpu_data_acquire_cb(), this function is
- non-blocking and may be called from task callbacks. Upon successful
- completion, this function returns 0.
- \def STARPU_ACQUIRE_NO_NODE
- \ingroup API_Data_Management
- This macro can be used to acquire data, but not require it to be available on a given node, only enforce R/W dependencies.
- This can for instance be used to wait for tasks which produce the data, but without requesting a fetch to the main memory.
- \def STARPU_ACQUIRE_NO_NODE_LOCK_ALL
- \ingroup API_Data_Management
- This is the same as STARPU_ACQUIRE_NO_NODE, but will lock the data on all nodes, preventing them from being evicted for instance.
- This is mostly useful inside starpu only.
- \fn int starpu_data_acquire_on_node(starpu_data_handle_t handle, int node, enum starpu_data_access_mode mode)
- \ingroup API_Data_Management
- This is the same as starpu_data_acquire(), except that the data
- will be available on the given memory node instead of main
- memory.
- STARPU_ACQUIRE_NO_NODE and STARPU_ACQUIRE_NO_NODE_LOCK_ALL can be used instead of an
- explicit node number.
- \fn int starpu_data_acquire_on_node_cb(starpu_data_handle_t handle, int node, enum starpu_data_access_mode mode, void (*callback)(void *), void *arg)
- \ingroup API_Data_Management
- This is the same as starpu_data_acquire_cb(), except that the
- data will be available on the given memory node instead of main
- memory.
- STARPU_ACQUIRE_NO_NODE and STARPU_ACQUIRE_NO_NODE_LOCK_ALL can be used instead of an
- explicit node number.
- \fn int starpu_data_acquire_on_node_cb_sequential_consistency(starpu_data_handle_t handle, int node, enum starpu_data_access_mode mode, void (*callback)(void *), void *arg, int sequential_consistency)
- \ingroup API_Data_Management
- This is the same as starpu_data_acquire_cb_sequential_consistency(), except that the
- data will be available on the given memory node instead of main
- memory.
- STARPU_ACQUIRE_NO_NODE and STARPU_ACQUIRE_NO_NODE_LOCK_ALL can be used instead of an
- explicit node number.
- \def STARPU_DATA_ACQUIRE_CB(handle, mode, code)
- \ingroup API_Data_Management
- STARPU_DATA_ACQUIRE_CB() is the same as starpu_data_acquire_cb(),
- except that the code to be executed in a callback is directly provided
- as a macro parameter, and the data \p handle is automatically released
- after it. This permits to easily execute code which depends on the
- value of some registered data. This is non-blocking too and may be
- called from task callbacks.
- \fn void starpu_data_release(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- This function releases the piece of data acquired by the
- application either by starpu_data_acquire() or by
- starpu_data_acquire_cb().
- \fn void starpu_data_release_on_node(starpu_data_handle_t handle, int node)
- \ingroup API_Data_Management
- This is the same as starpu_data_release(), except that the data
- will be available on the given memory \p node instead of main memory.
- The \p node parameter must be exactly the same as the corresponding starpu_data_acquire_on_node* call.
- \fn starpu_arbiter_t starpu_arbiter_create(void)
- \ingroup API_Data_Management
- This creates a data access arbiter, see \ref ConcurrentDataAccess for the details
- \fn void starpu_data_assign_arbiter(starpu_data_handle_t handle, starpu_arbiter_t arbiter)
- \ingroup API_Data_Management
- This makes accesses to \p handle managed by \p arbiter
- \fn void starpu_arbiter_destroy(starpu_arbiter_t arbiter)
- \ingroup API_Data_Management
- This destroys the \p arbiter . This must only be called after all data assigned
- to it have been unregistered.
- */
|