123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- /* StarPU --- Runtime system for heterogeneous multicore architectures.
- *
- * Copyright (C) 2011,2012,2017 Inria
- * Copyright (C) 2010-2019 CNRS
- * Copyright (C) 2009-2011,2014-2017,2019 Université de Bordeaux
- *
- * 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
- * the Free Software Foundation; either version 2.1 of the License, or (at
- * your option) any later version.
- *
- * StarPU is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * See the GNU Lesser General Public License in COPYING.LGPL for more details.
- */
- /*! \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
- TODO
- \var starpu_data_access_mode::STARPU_R
- read-only mode.
- \var starpu_data_access_mode::STARPU_W
- write-only mode.
- \var starpu_data_access_mode::STARPU_RW
- read-write mode. This is equivalent to ::STARPU_R|::STARPU_W
- \var starpu_data_access_mode::STARPU_SCRATCH
- 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 -1 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
- todo
- \var starpu_data_access_mode::STARPU_COMMUTE
- ::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
- 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
- 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.
- \var starpu_data_access_mode::STARPU_ACCESS_MODE_MAX
- todo
- @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_memory_nodes_numa_devid_to_id()
- and starpu_memory_nodes_numa_id_to_devid() 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
- Unregister a data \p 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 \p handle once it is no longer needed 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 \p handle immediately. After
- data invalidation, the first access to \p handle must be performed in
- ::STARPU_W mode. Accessing an invalidated data in ::STARPU_R mode
- results in undefined behaviour.
- \fn void starpu_data_invalidate_submit(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- Submit invalidation of the data \p 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
- Set the write-through mask of the data \p handle (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 nodes. 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 void starpu_data_set_name(starpu_data_handle_t handle, const char *name)
- \ingroup API_Data_Management
- Set the name of the data, to be shown in various profiling tools.
- \fn void starpu_data_set_coordinates_array(starpu_data_handle_t handle, int dimensions, int dims[])
- \ingroup API_Data_Management
- Set the coordinates of the data, to be shown in various profiling tools.
- \p dimensions is the size of the \p dims array
- This can be for instance the tile coordinates within a big matrix.
- \fn void starpu_data_set_coordinates(starpu_data_handle_t handle, unsigned dimensions, ...)
- \ingroup API_Data_Management
- Set the coordinates of the data, to be shown in various profiling tools.
- \p dimensions is the number of subsequent \c int parameters.
- This can be for instance the tile coordinates within a big matrix.
- \fn void starpu_data_set_ooc_flag(starpu_data_handle_t handle, unsigned flag)
- \ingroup API_Data_Management
- Set whether this data should be elligible to be evicted to disk storage (1) or
- not (0). The default is 1.
- \fn unsigned starpu_data_get_ooc_flag(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- Get whether this data was set to be elligible to be evicted to disk storage (1) or
- not (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 the data \p handle to \p 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 \p async 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 the data \p handle to \p node, i.e.
- requests that the data be replicated to \p node when there is room for it, so that it is
- available there for tasks. If \p async 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 the data \p handle to \p node, i.e.
- requests that the data be replicated to \p node, so that it is
- available there for tasks, but only when the bus is really idle. If \p async 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 unsigned starpu_data_is_on_node(starpu_data_handle_t handle, unsigned node)
- \ingroup API_Data_Management
- Check whether a valid copy of \p handle is currently available on memory node \p
- node .
- \fn void starpu_data_wont_use(starpu_data_handle_t handle)
- \ingroup API_Data_Management
- Advise StarPU that \p 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 \p 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
- Specify that the data \p handle 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
- Set 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
- Sset the field \c user_data 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 field \c user_data 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 \p handle 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 with \p mode. starpu_data_release() must
- be called once the application no longer needs to access the piece of
- data. 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 access \p mode, the \p
- callback function is executed. The application may access
- the requested data during the execution of \p callback. The \p callback
- function must call starpu_data_release() once the application no longer
- needs to access the piece of data. 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 access
- \p 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 no longer
- needs to access the piece of data. 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.
- \fn int starpu_data_acquire_try(starpu_data_handle_t handle, enum starpu_data_access_mode mode)
- \ingroup API_Data_Management
- The application can call this function instead of starpu_data_acquire() so as to
- acquire the data like starpu_data_acquire(), but only if all
- previously-submitted tasks have completed, in which case starpu_data_acquire_try()
- returns 0. StarPU will have ensured that the application will get an up-to-date
- copy of \p handle in main memory located where the data was originally
- registered. starpu_data_release() must be called once the application no longer
- needs to access the piece of data.
- If not all previously-submitted tasks have completed, starpu_data_acquire_try
- returns -EAGAIN, and starpu_data_release() must not be called.
- \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.
- \fn int starpu_data_acquire_on_node_cb_sequential_consistency_sync_jobids(starpu_data_handle_t handle, int node, enum starpu_data_access_mode mode, void (*callback)(void *), void *arg, int sequential_consistency, int quick, long *pre_sync_jobid, long *post_sync_jobid)
- \ingroup API_Data_Management
- This is the same as starpu_data_acquire_on_node_cb_sequential_consistency(),
- except that the \e pre_sync_jobid and \e post_sync_jobid parameters can be used
- to retrieve the jobid of the synchronization tasks. \e pre_sync_jobid happens
- just before the acquisition, and \e post_sync_jobid happens just after the
- release.
- \fn int starpu_data_acquire_on_node_try(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_try(), 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
- Release 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 \c
- starpu_data_acquire_on_node* call.
- \fn starpu_arbiter_t starpu_arbiter_create(void)
- \ingroup API_Data_Management
- Create 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
- Make access to \p handle managed by \p arbiter
- \fn void starpu_arbiter_destroy(starpu_arbiter_t arbiter)
- \ingroup API_Data_Management
- Destroy the \p arbiter . This must only be called after all data
- assigned to it have been unregistered.
- */
|