common/ompio: use allocator to manage temporary buffers
use an allocator to manage temporary buffers when copying unmanaged data from GPU buffer to host. This is necessary, since the buffers have to be pinned for better performance, which is an expensive operation. Signed-off-by: Edgar Gabriel <egabriel@central.uh.edu>
Этот коммит содержится в:
родитель
ac79e576ef
Коммит
3c10ed4ed1
@ -23,10 +23,21 @@
|
||||
#include "opal/datatype/opal_datatype_cuda.h"
|
||||
#include "opal/mca/common/cuda/common_cuda.h"
|
||||
|
||||
#include "ompi/mca/io/ompio/io_ompio.h"
|
||||
#include "opal/mca/allocator/allocator.h"
|
||||
#include "opal/mca/allocator/base/base.h"
|
||||
#include "common_ompio.h"
|
||||
#include "common_ompio_cuda.h"
|
||||
|
||||
|
||||
static opal_mutex_t mca_common_ompio_cuda_mutex; /* lock for thread safety */
|
||||
static mca_allocator_base_component_t* mca_common_ompio_allocator_component=NULL;
|
||||
static mca_allocator_base_module_t* mca_common_ompio_allocator=NULL;
|
||||
|
||||
static int32_t mca_common_ompio_cuda_init = 0;
|
||||
static int32_t mca_common_ompio_pagesize=4096;
|
||||
static void* mca_common_ompio_cuda_alloc_seg ( void *ctx, size_t *size );
|
||||
static void mca_common_ompio_cuda_free_seg ( void *ctx, void *buf );
|
||||
|
||||
void mca_common_ompio_check_gpu_buf ( ompio_file_t *fh, const void *buf, int *is_gpu,
|
||||
int *is_managed)
|
||||
{
|
||||
@ -46,24 +57,111 @@ void mca_common_ompio_check_gpu_buf ( ompio_file_t *fh, const void *buf, int *is
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void mca_common_ompio_register_buf ( ompio_file_t *fh, const void *buf,
|
||||
size_t bufsize )
|
||||
static void* mca_common_ompio_cuda_alloc_seg ( void*ctx, size_t *size )
|
||||
{
|
||||
mca_common_cuda_register ( ( char *)buf, bufsize, (char *) fh->f_filename );
|
||||
char *buf=NULL;
|
||||
size_t realsize, numpages, rest;
|
||||
|
||||
numpages = *size / mca_common_ompio_pagesize;
|
||||
rest = *size % mca_common_ompio_pagesize;
|
||||
if ( rest ) {
|
||||
numpages++;
|
||||
}
|
||||
realsize = numpages * mca_common_ompio_pagesize;
|
||||
|
||||
buf = malloc ( realsize);
|
||||
if ( NULL != buf ) {
|
||||
mca_common_cuda_register ( ( char *)buf, realsize, NULL );
|
||||
}
|
||||
*size = realsize;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void mca_common_ompio_cuda_free_seg ( void *ctx, void *buf )
|
||||
{
|
||||
if ( NULL != buf ) {
|
||||
mca_common_cuda_unregister ( (char *) buf, NULL );
|
||||
}
|
||||
free ( buf );
|
||||
return;
|
||||
}
|
||||
|
||||
void mca_common_ompio_unregister_buf ( ompio_file_t *fh, void *buf )
|
||||
int mca_common_ompio_cuda_alloc_init ( void )
|
||||
{
|
||||
if ( NULL != fh ) {
|
||||
mca_common_cuda_unregister ( (char *)buf, (char *)fh->f_filename);
|
||||
bool thread_safe=true;
|
||||
|
||||
if(OPAL_THREAD_ADD_FETCH32(&mca_common_ompio_cuda_init, 1) > 1)
|
||||
return OMPI_SUCCESS;
|
||||
|
||||
/* initialize static objects */
|
||||
OBJ_CONSTRUCT(&mca_common_ompio_cuda_mutex, opal_mutex_t);
|
||||
|
||||
OPAL_THREAD_LOCK (&mca_common_ompio_cuda_mutex );
|
||||
/* lookup name of the allocator to use */
|
||||
if(NULL == (mca_common_ompio_allocator_component = mca_allocator_component_lookup("basic"))) {
|
||||
OPAL_THREAD_UNLOCK(&mca_common_ompio_cuda_mutex);
|
||||
return OMPI_ERR_BUFFER;
|
||||
}
|
||||
else {
|
||||
char dummy_filename[]="dummy_ompio_filename";
|
||||
mca_common_cuda_unregister ( (char *)buf, (char *)dummy_filename);
|
||||
|
||||
/* create an instance of the allocator */
|
||||
mca_common_ompio_allocator = mca_common_ompio_allocator_component->allocator_init(thread_safe,
|
||||
mca_common_ompio_cuda_alloc_seg,
|
||||
mca_common_ompio_cuda_free_seg,
|
||||
NULL);
|
||||
if(NULL == mca_common_ompio_allocator) {
|
||||
OPAL_THREAD_UNLOCK(&mca_common_ompio_cuda_mutex);
|
||||
return OMPI_ERR_BUFFER;
|
||||
}
|
||||
free (buf);
|
||||
|
||||
mca_common_ompio_pagesize = sysconf(_SC_PAGESIZE);
|
||||
|
||||
OPAL_THREAD_UNLOCK(&mca_common_ompio_cuda_mutex);
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
int mca_common_ompio_cuda_alloc_fini ( void )
|
||||
{
|
||||
if ( NULL != mca_common_ompio_allocator ) {
|
||||
OPAL_THREAD_LOCK (&mca_common_ompio_cuda_mutex);
|
||||
mca_common_ompio_allocator->alc_finalize(mca_common_ompio_allocator);
|
||||
mca_common_ompio_allocator=NULL;
|
||||
OPAL_THREAD_UNLOCK (&mca_common_ompio_cuda_mutex);
|
||||
OBJ_DESTRUCT (&mca_common_ompio_cuda_mutex);
|
||||
}
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
void *mca_common_ompio_alloc_buf ( ompio_file_t *fh, size_t bufsize )
|
||||
{
|
||||
char *tmp=NULL;
|
||||
|
||||
if ( !mca_common_ompio_cuda_init ){
|
||||
mca_common_ompio_cuda_alloc_init ();
|
||||
}
|
||||
|
||||
OPAL_THREAD_LOCK (&mca_common_ompio_cuda_mutex);
|
||||
tmp = mca_common_ompio_allocator->alc_alloc (mca_common_ompio_allocator,
|
||||
bufsize, 0 );
|
||||
OPAL_THREAD_UNLOCK (&mca_common_ompio_cuda_mutex);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void mca_common_ompio_release_buf ( ompio_file_t *fh, void *buf )
|
||||
{
|
||||
|
||||
if ( !mca_common_ompio_cuda_init ){
|
||||
/* Should not happen. You can not release a buf without
|
||||
** having it allocated first.
|
||||
*/
|
||||
opal_output (1, "error in mca_common_ompio_release_buf: allocator not initialized\n");
|
||||
}
|
||||
|
||||
OPAL_THREAD_LOCK (&mca_common_ompio_cuda_mutex);
|
||||
mca_common_ompio_allocator->alc_free (mca_common_ompio_allocator,
|
||||
buf);
|
||||
OPAL_THREAD_UNLOCK (&mca_common_ompio_cuda_mutex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -26,12 +26,7 @@
|
||||
opal_convertor_clone ( _fh->f_convertor, _convertor, 0); \
|
||||
opal_convertor_prepare_for_send ( _convertor, &(_datatype->super), _count, _buf );\
|
||||
opal_convertor_get_packed_size( _convertor, &_max_data ); \
|
||||
_tbuf = (char *) malloc ( _max_data ); \
|
||||
if ( NULL == _tbuf ) { \
|
||||
opal_output(1, "common_ompio: could not allocate memory.\n"); \
|
||||
return OMPI_ERR_OUT_OF_RESOURCE; \
|
||||
} \
|
||||
mca_common_ompio_register_buf (_fh, _tbuf, _max_data); \
|
||||
_tbuf = mca_common_ompio_alloc_buf (_fh, _max_data); \
|
||||
_decoded_iov = (struct iovec *) malloc ( sizeof ( struct iovec )); \
|
||||
if ( NULL == _decoded_iov ) { \
|
||||
opal_output(1, "common_ompio: could not allocate memory.\n"); \
|
||||
@ -44,8 +39,11 @@
|
||||
|
||||
void mca_common_ompio_check_gpu_buf ( ompio_file_t *fh, const void *buf,
|
||||
int *is_gpu, int *is_managed);
|
||||
void mca_common_ompio_register_buf ( ompio_file_t *fh, const void *buf,
|
||||
size_t bufsize);
|
||||
void mca_common_ompio_unregister_buf ( ompio_file_t *fh, void *buf );
|
||||
int mca_common_ompio_cuda_alloc_init ( void );
|
||||
int mca_common_ompio_cuda_alloc_fini ( void );
|
||||
|
||||
|
||||
void* mca_common_ompio_alloc_buf ( ompio_file_t *fh, size_t bufsize);
|
||||
void mca_common_ompio_release_buf ( ompio_file_t *fh, void *buf );
|
||||
|
||||
#endif
|
||||
|
@ -167,7 +167,7 @@ int mca_common_ompio_file_read (ompio_file_t *fh,
|
||||
|
||||
opal_convertor_unpack (&convertor, decoded_iov, &iov_count, &pos );
|
||||
opal_convertor_cleanup (&convertor);
|
||||
mca_common_ompio_unregister_buf (fh, decoded_iov->iov_base);
|
||||
mca_common_ompio_release_buf (fh, decoded_iov->iov_base);
|
||||
}
|
||||
#endif
|
||||
if (NULL != decoded_iov) {
|
||||
|
@ -137,7 +137,7 @@ int mca_common_ompio_file_write (ompio_file_t *fh,
|
||||
}
|
||||
#if OPAL_CUDA_SUPPORT
|
||||
if ( is_gpu && !is_managed ) {
|
||||
mca_common_ompio_unregister_buf (fh, decoded_iov->iov_base);
|
||||
mca_common_ompio_release_buf (fh, decoded_iov->iov_base);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -48,7 +48,7 @@ static int mca_common_ompio_request_free ( struct ompi_request_t **req)
|
||||
decoded_iov.iov_len = ompio_req->req_size;
|
||||
opal_convertor_unpack (&ompio_req->req_convertor, &decoded_iov, &iov_count, &pos );
|
||||
}
|
||||
mca_common_ompio_unregister_buf ( NULL, ompio_req->req_tbuf );
|
||||
mca_common_ompio_release_buf ( NULL, ompio_req->req_tbuf );
|
||||
}
|
||||
#endif
|
||||
if ( NULL != ompio_req->req_free_fn ) {
|
||||
|
@ -34,6 +34,10 @@
|
||||
#include "io_ompio.h"
|
||||
#include "ompi/mca/common/ompio/common_ompio_request.h"
|
||||
|
||||
#if OPAL_CUDA_SUPPORT
|
||||
#include "ompi/mca/common/ompio/common_ompio_cuda.h"
|
||||
#endif
|
||||
|
||||
int mca_io_ompio_cycle_buffer_size = OMPIO_DEFAULT_CYCLE_BUF_SIZE;
|
||||
int mca_io_ompio_bytes_per_agg = OMPIO_PREALLOC_MAX_BUF_SIZE;
|
||||
int mca_io_ompio_num_aggregators = -1;
|
||||
@ -272,6 +276,10 @@ static int close_component(void)
|
||||
{
|
||||
mca_common_ompio_request_fini ();
|
||||
|
||||
#if OPAL_CUDA_SUPPORT
|
||||
mca_common_ompio_cuda_alloc_fini();
|
||||
#endif
|
||||
|
||||
OBJ_DESTRUCT(&mca_io_ompio_mutex);
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user