diff --git a/include/chameleon/struct.h b/include/chameleon/struct.h index e5df8fa6d030c831598cce505de55981bea35cca..289f4cad9c32e4602b1beda5503aa60ac72725ad 100644 --- a/include/chameleon/struct.h +++ b/include/chameleon/struct.h @@ -121,6 +121,7 @@ struct chameleon_desc_s { int register_mat; // 1 if we have to register mat - else 0 (handled by the application) int myrank; // MPI rank of the descriptor int ooc; // 1 if the matrix is not to fit in memory + int64_t mpitag; // First MPI tag used by the decriptor void *schedopt; // scheduler (QUARK|StarPU) specific structure }; diff --git a/runtime/starpu/CMakeLists.txt b/runtime/starpu/CMakeLists.txt index 0968de66d35b777f2efbbc2d75ebfdbc9ccdb475..c70669ba446ec0ef40cc53c3b3cd9721310ee942 100644 --- a/runtime/starpu/CMakeLists.txt +++ b/runtime/starpu/CMakeLists.txt @@ -222,6 +222,7 @@ set(RUNTIME_COMMON control/runtime_context.c control/runtime_control.c control/runtime_descriptor.c + control/runtime_tags.c control/runtime_options.c control/runtime_profiling.c control/runtime_workspace.c diff --git a/runtime/starpu/control/runtime_descriptor.c b/runtime/starpu/control/runtime_descriptor.c index 385adc0df81a1a87de81971fe3590853b5214287..46f3832a43596ccc44f36e0e3a38b6503579bb3e 100644 --- a/runtime/starpu/control/runtime_descriptor.c +++ b/runtime/starpu/control/runtime_descriptor.c @@ -30,57 +30,6 @@ */ #if defined(CHAMELEON_USE_MPI) -/* Take 24 bits for the tile id, and 7 bits for descriptor id. - These values can be changed through the call CHAMELEON_user_tag_size(int tag_width, int tag_sep) */ -#define TAG_WIDTH_MIN 20 -static int tag_width = 64; -static int tag_sep = 40; -static int _tag_mpi_initialized_ = 0; - -static inline int -chameleon_starpu_tag_init( int user_tag_width, - int user_tag_sep ) -{ - if (!_tag_mpi_initialized_) { - int ok = 0; - uintptr_t tag_ub; - - tag_width = user_tag_width; - tag_sep = user_tag_sep; - - void *tag_ub_p = NULL; -#if defined(HAVE_STARPU_MPI_COMM_GET_ATTR) - starpu_mpi_comm_get_attr(MPI_COMM_WORLD, STARPU_MPI_TAG_UB, &tag_ub_p, &ok); -#else - MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &tag_ub_p, &ok); -#endif - tag_ub = (uintptr_t)tag_ub_p; - - if ( !ok ) { - chameleon_error("RUNTIME_desc_create", "MPI_TAG_UB not known by StarPU"); - } - - while ( ((uintptr_t)((1UL<<tag_width) - 1) > tag_ub ) && - (tag_width >= TAG_WIDTH_MIN) ) - { - tag_width--; - tag_sep--; - } - - if ( tag_width < TAG_WIDTH_MIN ) { - chameleon_error("RUNTIME_desc_create", "MPI_TAG_UB too small to identify all the data"); - return CHAMELEON_ERR_OUT_OF_RESOURCES; - } - - _tag_mpi_initialized_ = 1; - return CHAMELEON_SUCCESS; - } - else { - return CHAMELEON_ERR_REINITIALIZED; - } -} - - #ifndef HAVE_STARPU_MPI_DATA_REGISTER #define starpu_mpi_data_register( handle_, tag_, owner_ ) \ do { \ @@ -221,23 +170,16 @@ void RUNTIME_desc_create( CHAM_desc_t *desc ) #if defined(CHAMELEON_USE_MPI) /* - * Check that we are not going over MPI tag limitations + * Book the number of tags required to describe this matrix */ { - chameleon_starpu_tag_init( tag_width, tag_sep ); + chameleon_starpu_tag_init(); + desc->mpitag = chameleon_starpu_tag_book( (int64_t)lnt * (int64_t)lmt ); - /* Check that we won't create overflow in tags used */ - if ( ((uintptr_t)(lnt*lmt)) > ((uintptr_t)(1UL<<tag_sep)) ) { - chameleon_fatal_error("RUNTIME_desc_create", "Too many tiles in the descriptor for MPI tags"); + if ( desc->mpitag == -1 ) { + chameleon_fatal_error("RUNTIME_desc_create", "Can't pursue computation since no more tags are available"); return; } - assert( ((uintptr_t)(lnt*lmt)) <= ((uintptr_t)(1UL<<tag_sep)) ); - - if ( ((uintptr_t)desc->id) >= (uintptr_t)(1UL<<(tag_width-tag_sep)) ) { - chameleon_fatal_error("RUNTIME_desc_create", "Number of descriptor available in MPI mode out of stock"); - return; - } - assert( ((uintptr_t)desc->id) < (uintptr_t)(1UL<<(tag_width-tag_sep)) ); } #endif } @@ -284,8 +226,9 @@ void RUNTIME_desc_destroy( CHAM_desc_t *desc ) } #endif #endif + chameleon_starpu_tag_release( desc->mpitag ); - free(desc->schedopt); + free( desc->schedopt ); } } @@ -505,10 +448,14 @@ void *RUNTIME_data_getaddr( const CHAM_desc_t *A, int m, int n ) #if defined(CHAMELEON_USE_MPI) { int64_t block_ind = A->lmt * nn + mm; - starpu_mpi_data_register(*ptrtile, (((int64_t)A->id) << tag_sep) | block_ind, owner); + starpu_mpi_data_register( *ptrtile, A->mpitag + block_ind, owner ); } #endif /* defined(CHAMELEON_USE_MPI) */ +#if defined(CHAMELEON_KERNELS_TRACE) + fprintf( stderr, "%s - %p registered with tag %ld\n", + tile->name, *ptrtile, A->mpitag + A->lmt * nn + mm ); +#endif assert( *ptrtile ); return *ptrtile; } diff --git a/runtime/starpu/control/runtime_tags.c b/runtime/starpu/control/runtime_tags.c new file mode 100644 index 0000000000000000000000000000000000000000..32c481a0d11a0970bd502bfc5800f0de4a6ead1d --- /dev/null +++ b/runtime/starpu/control/runtime_tags.c @@ -0,0 +1,261 @@ +/** + * + * @file starpu/runtime_tags.c + * + * @copyright 2017-2023 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, + * Univ. Bordeaux. All rights reserved. + * + * @version 1.3.0 + * @author Pierre Ramet + * @author Mathieu Faverge + * @date 2021-10-04 + * + * Functions to manage the MPI data tags with StarPU (originated from PaStiX). + * + * @addtogroup chameleon_starpu + * @{ + * + **/ +#include "chameleon_starpu.h" + +#if defined(CHAMELEON_USE_MPI) + +/** + * @brief Structure Chameleon StarPU tag + * + * List structure to manage the set of available tags. + */ +struct cst_range_; +typedef struct cst_range_ cst_range_t; + +struct cst_range_ { + int64_t min; /**< Minimal value in the range */ + int64_t max; /**< Maximal value in the range */ + cst_range_t *next; /**< Pointer to the following range */ +}; + +/** + * @brief Pointer to the first set or registered tags + */ +static cst_range_t *cst_first = NULL; + +/** + * @brief StarPU tag upper bound + */ +static int64_t starpu_tag_ub = 0; + +/** + ******************************************************************************* + * + * @brief Initialize the StarPU tags manager. + * + ******************************************************************************* + * + * @retval TODO + * + ******************************************************************************/ +int +chameleon_starpu_tag_init( void ) +{ + if (!starpu_tag_ub) { + int ok = 0; + void *tag_ub_p = NULL; + + starpu_mpi_comm_get_attr( MPI_COMM_WORLD, STARPU_MPI_TAG_UB, &tag_ub_p, &ok ); + starpu_tag_ub = (uint64_t)((intptr_t)tag_ub_p); + + if ( !ok ) { + chameleon_error("chameleon_starpu_tag_init", "MPI_TAG_UB not known by StarPU\n"); + } + + return CHAMELEON_SUCCESS; + } + else { + return CHAMELEON_ERR_REINITIALIZED; + } +} + +/** + ******************************************************************************* + * + * @brief Book a range of StarPU unique tags of size nbtags. + * + * This function returns the minimal tag value available to allow the + * registration of nbtags data in a continuous range. + * + * Note that this function must be called exactly the same way on all nodes to + * make sure the tags are identical from one node to another. + * + ******************************************************************************* + * + * @param[in] nbtags + * The number of tags required to register the sparse matrix or right + * hand side. + * + ******************************************************************************* + * + * @return V, the minimal tag value to use. The range [V:V+nbtags-1] is booked. + * + ********************************************************************************/ +int64_t +chameleon_starpu_tag_book( int64_t nbtags ) +{ + cst_range_t *new; + cst_range_t *prev = NULL; + cst_range_t *current = cst_first; + int64_t min = 0; + int64_t max = ( current == NULL ) ? starpu_tag_ub : current->min; + + if ( nbtags == 0 ) { + return -1; + } + assert( starpu_tag_ub != 0 ); /* StarPU tag must be initialized */ + + while ( ((max - min) < nbtags) && (current != NULL) ) { + min = current->max; + prev = current; + current = current->next; + max = ( current == NULL ) ? starpu_tag_ub : current->min; + } + + if ( (max - min) < nbtags ) { + /* chameleon_error( "chameleon_starpu_tag_book: No space left in tags (looking for %ld tags)\n", */ + /* nbtags ); */ + return -1; + } + + new = malloc( sizeof( cst_range_t ) ); + new->min = min; + new->max = min + nbtags; + new->next = current; + if ( prev == NULL ) { + cst_first = new; + } + else { + assert( prev->next == current ); + prev->next = new; + } + +#if defined(CHAMELEON_DEBUG_STARPU) + fprintf( stderr, "chameleon_starpu_tag: Book %ld - %ld\n", + min, min + nbtags ); +#endif + + assert( cst_first != NULL ); + return new->min; +} + +/** + ******************************************************************************* + * + * @brief Release the set of tags starting by min. + * + * This function releases the range of tags that starts by the min value. + * + ******************************************************************************* + * + * @param[in] min + * The initial value in the range + * + ******************************************************************************/ +void +chameleon_starpu_tag_release( int64_t min ) +{ + cst_range_t *prev = NULL; + cst_range_t *current = cst_first; + + assert( cst_first != NULL ); /* At least one range must be registered */ + + while ( (current != NULL) && (current->min < min) ) { + prev = current; + current = current->next; + } + + assert( current != NULL ); + assert( current->min == min ); + + if ( prev ) { + prev->next = current->next; + } + else { + assert( current == cst_first ); + cst_first = current->next; + } + +#if defined(CHAMELEON_DEBUG_STARPU) + fprintf( stderr, "chameleon_starpu_tag: Release %ld - %ld\n", + current->min, current->max ); +#endif + + free( current ); + + return; +} + +#else /* defined(CHAMELEON_USE_MPI) */ + +/** + ******************************************************************************* + * + * @brief Initialize the StarPU tags manager. + * + ******************************************************************************* + * + * @retval TODO + * + ******************************************************************************/ +int +chameleon_starpu_tag_init( ) { + return CHAMELEON_SUCCESS; +} + +/** + ******************************************************************************* + * + * @brief Book a range of StarPU unique tags of size nbtags. + * + * This function returns the minimal tag value available to allow the + * registration of nbtags data in a continuous range. + * + * Note that this function must be called exactly the same way on all nodes to + * make sure the tags are identical from one node to another. + * + ******************************************************************************* + * + * @param[in] nbtags + * The number of tags required to register the sparse matrix or right + * hand side. + * + ******************************************************************************* + * + * @return V, the minimal tag value to use. The range [V:V+nbtags-1] is booked. + * + ********************************************************************************/ +int64_t +chameleon_starpu_tag_book( __attribute__((unused)) int64_t nbtags ) { + return 0; +} + +/** + ******************************************************************************* + * + * @brief Release the set of tags starting by min. + * + * This function releases the range of tags that starts by the min value. + * + ******************************************************************************* + * + * @param[in] min + * The initial value in the range + * + ******************************************************************************/ +void +chameleon_starpu_tag_release( __attribute__((unused)) int64_t min ) { + return; +} + +#endif + +/** + * @} + */ diff --git a/runtime/starpu/include/chameleon_starpu.h.in b/runtime/starpu/include/chameleon_starpu.h.in index e92e23387f1f20912e3d28f910047c2d9629dfd4..d967fac54efab35815205367f4b65fe082b48366 100644 --- a/runtime/starpu/include/chameleon_starpu.h.in +++ b/runtime/starpu/include/chameleon_starpu.h.in @@ -149,6 +149,13 @@ typedef struct starpu_option_request_s { #define CHAMELEON_CODELETS_HAVE_NAME #endif +/** + * MPI tag management + */ +int chameleon_starpu_tag_init( ); +int64_t chameleon_starpu_tag_book( int64_t nbtags ); +void chameleon_starpu_tag_release( int64_t min ); + /** * Access to block pointer and leading dimension */