diff --git a/compute/CMakeLists.txt b/compute/CMakeLists.txt index 815eb60bf947d77c444e078598ea6894c521fd9b..e42f0917b0af8a3d213cfb6a8235a92158a29af2 100644 --- a/compute/CMakeLists.txt +++ b/compute/CMakeLists.txt @@ -38,6 +38,7 @@ set(CHAMELEON_CONTROL ../control/control.c ../control/descriptor.c ../control/descriptor_rec.c + ../control/descriptor_helpers.c ../control/workspace.c ../control/tile.c ../control/chameleon_f77.c diff --git a/control/descriptor.c b/control/descriptor.c index 7e4e6117b9549a106f63ddb4eeb71c58749cfb82..09130a5c374f87d68ed712f20368fc8c6182fe8f 100644 --- a/control/descriptor.c +++ b/control/descriptor.c @@ -113,27 +113,6 @@ void chameleon_desc_init_tiles( CHAM_desc_t *desc, blkrankof_fct_t rankof ) } } -/** - * Internal function to return MPI rank of element A(m,n) with m,n = block indices - */ -int chameleon_getrankof_2d( const CHAM_desc_t *A, int m, int n ) -{ - int mm = m + A->i / A->mb; - int nn = n + A->j / A->nb; - return (mm % A->p) * A->q + (nn % A->q); -} - -/** - * Internal function to return MPI rank of element DIAG(m,0) with m,n = block indices - */ -int chameleon_getrankof_2d_diag( const CHAM_desc_t *A, int m, int n ) -{ - int mm = m + A->i / A->mb; - assert( m == n ); - (void)n; - return (mm % A->p) * A->q + (mm % A->q); -} - /** ****************************************************************************** * diff --git a/control/descriptor.h b/control/descriptor.h index 1e0d883f61db4ff6365fbeaf76e4323124f48240..50eb614b6d9b890dadd69d764e49f5107f9a4dd7 100644 --- a/control/descriptor.h +++ b/control/descriptor.h @@ -37,20 +37,6 @@ extern "C" { /** * Internal routines */ -inline static void* chameleon_geteltaddr(const CHAM_desc_t *A, int m, int n, int eltsize); -inline static void* chameleon_getaddr_cm (const CHAM_desc_t *A, int m, int n); -inline static void* chameleon_getaddr_ccrb (const CHAM_desc_t *A, int m, int n); -inline static void* chameleon_getaddr_null (const CHAM_desc_t *A, int m, int n); -inline static void* chameleon_getaddr_diag (const CHAM_desc_t *A, int m, int n); -inline static int chameleon_getblkldd_cm (const CHAM_desc_t *A, int m); -inline static int chameleon_getblkldd_ccrb(const CHAM_desc_t *A, int m); - -/** - * Data distributions - */ -int chameleon_getrankof_2d(const CHAM_desc_t *desc, int m, int n); -int chameleon_getrankof_2d_diag(const CHAM_desc_t *desc, int m, int n); - static inline int chameleon_getrankof_tile(const CHAM_desc_t *desc, int m, int n) { CHAM_tile_t *tile = desc->get_blktile( desc, m, n ); assert( tile != NULL ); @@ -87,78 +73,6 @@ CHAM_desc_t* chameleon_desc_submatrix( CHAM_desc_t *descA, int i, int j, int m, void chameleon_desc_destroy ( CHAM_desc_t *desc ); int chameleon_desc_check ( const CHAM_desc_t *desc ); -/** - * Internal function to return address of block (m,n) with m,n = block indices - */ -inline static void* chameleon_getaddr_ccrb(const CHAM_desc_t *A, int m, int n) -{ - size_t mm = m + A->i / A->mb; - size_t nn = n + A->j / A->nb; - size_t eltsize = CHAMELEON_Element_Size(A->dtyp); - size_t offset = 0; - -#if defined(CHAMELEON_USE_MPI) - assert( A->myrank == A->get_rankof( A, mm, nn) ); - mm = mm / A->p; - nn = nn / A->q; -#endif - - if (mm < (size_t)(A->llm1)) { - if (nn < (size_t)(A->lln1)) - offset = (size_t)(A->bsiz) * (mm + (size_t)(A->llm1) * nn); - else - offset = A->A12 + ((size_t)(A->mb * (A->lln%A->nb)) * mm); - } - else { - if (nn < (size_t)(A->lln1)) - offset = A->A21 + ((size_t)((A->llm%A->mb) * A->nb) * nn); - else - offset = A->A22; - } - - return (void*)((intptr_t)A->mat + (offset*eltsize) ); -} - -/** - * Internal function to return address of block (m,n) with m,n = block indices - */ -inline static void *chameleon_getaddr_cm(const CHAM_desc_t *A, int m, int n) -{ - size_t mm = m + A->i / A->mb; - size_t nn = n + A->j / A->nb; - size_t eltsize = CHAMELEON_Element_Size(A->dtyp); - size_t offset = 0; - -#if defined(CHAMELEON_USE_MPI) - assert( A->myrank == A->get_rankof( A, mm, nn) ); - mm = mm / A->p; - nn = nn / A->q; -#endif - - offset = (size_t)(A->llm * A->nb) * nn + (size_t)(A->mb) * mm; - return (void*)((intptr_t)A->mat + (offset*eltsize) ); -} - -/** - * Internal function to return address of block (m,n) with m,n = block indices - */ -inline static void *chameleon_getaddr_diag( const CHAM_desc_t *A, int m, int n ) -{ - assert( m == n ); - (void)n; - return chameleon_getaddr_ccrb( A, m, 0 ); -} - -/** - * Internal function to return address of block (m,n) with m,n = block indices - * This version lets the runtime allocate on-demand. - */ -inline static void *chameleon_getaddr_null(const CHAM_desc_t *A, int m, int n) -{ - (void)A; (void)m; (void)n; - return NULL; -} - /** * Internal function to return address of block (m,n) with m,n = block indices */ @@ -204,20 +118,6 @@ inline static void* chameleon_geteltaddr(const CHAM_desc_t *A, int m, int n, int return (void*)((intptr_t)A->mat + (offset*eltsize) ); } -/** - * Internal function to return the leading dimension of element A(m,*) with m,n = block indices - */ -inline static int chameleon_getblkldd_ccrb(const CHAM_desc_t *A, int m) -{ - int mm = m + A->i / A->mb; - return ( ((mm+1) == A->lmt) && ((A->lm % A->mb) != 0)) ? A->lm % A->mb : A->mb; -} - -inline static int chameleon_getblkldd_cm(const CHAM_desc_t *A, int m) { - (void)m; - return A->llm; -} - /** * Detect if the tile is local or not */ diff --git a/control/descriptor_helpers.c b/control/descriptor_helpers.c new file mode 100644 index 0000000000000000000000000000000000000000..36a7023ce0386b79a7ed944c63965bc7d7740a88 --- /dev/null +++ b/control/descriptor_helpers.c @@ -0,0 +1,263 @@ +/** + * + * @file descriptor_helpers.c + * + * @copyright 2009-2014 The University of Tennessee and The University of + * Tennessee Research Foundation. All rights reserved. + * @copyright 2012-2022 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, + * Univ. Bordeaux. All rights reserved. + * + *** + * + * @brief Chameleon descriptors routines + * + * @version 1.2.0 + * @author Mathieu Faverge + * @author Cedric Castagnede + * @author Florent Pruvost + * @author Guillaume Sylvand + * @author Raphael Boucherie + * @author Samuel Thibault + * @date 2022-02-22 + * + *** + * + * @defgroup Descriptor + * @brief Group descriptor routines exposed to users + * + */ +#define _GNU_SOURCE 1 +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include "control/common.h" +#include "control/descriptor.h" +#include "chameleon/runtime.h" + +/** + * @brief Return the rank of the tile A( m, n ) in a classic 2D Block Cyclic + * distribution PxQ. + * + * @param[in] A + * The matrix descriptor in which to find the tile. + * + * @param[in] m + * The row index of the tile. + * + * @param[in] n + * The column index of the tile. + * + * @return The rank of the tile A( m, n ) + * + */ +int chameleon_getrankof_2d( const CHAM_desc_t *A, int m, int n ) +{ + int mm = m + A->i / A->mb; + int nn = n + A->j / A->nb; + return (mm % A->p) * A->q + (nn % A->q); +} + +/** + * @brief Return the rank associated to the diagonal tile ( m, m ) of a classic + * 2D Block Cyclic distribution PxQ. + * + * @param[in] A + * A specific matrix descriptor that holds only diagonal tiles. Thus, n is never used. + * + * @param[in] m + * The row and column index of the tile. + * + * @param[in] n + * Unused + * + * @return The rank of the tile A( m, m ) + * + */ +int chameleon_getrankof_2d_diag( const CHAM_desc_t *A, int m, int n ) +{ + int mm = m + A->i / A->mb; + (void)n; + return (mm % A->p) * A->q + (mm % A->q); +} + +/** + * @brief Return the address of the tile A( m, n ) in a tile storage. + * + * @WARNING The only mapping valid with this data storage is the 2D block cyclic + * storage as soon as multiple nodes are involved (see chameleon_getrankof_2d()). + * + * @param[in] A + * The matrix descriptor in which to find the tile. + * + * @param[in] m + * The row index of the tile. + * + * @param[in] n + * The column index of the tile. + * + * @return The address of the tile A( m, n ) + * + */ +void* chameleon_getaddr_ccrb( const CHAM_desc_t *A, int m, int n ) +{ + size_t mm = m + A->i / A->mb; + size_t nn = n + A->j / A->nb; + size_t eltsize = CHAMELEON_Element_Size(A->dtyp); + size_t offset = 0; + +#if defined(CHAMELEON_USE_MPI) + assert( A->myrank == A->get_rankof( A, mm, nn ) ); + mm = mm / A->p; + nn = nn / A->q; +#endif + + if (mm < (size_t)(A->llm1)) { + if (nn < (size_t)(A->lln1)) + offset = (size_t)(A->bsiz) * (mm + (size_t)(A->llm1) * nn ); + else + offset = A->A12 + ((size_t)(A->mb * (A->lln%A->nb)) * mm ); + } + else { + if (nn < (size_t)(A->lln1)) + offset = A->A21 + ((size_t)((A->llm%A->mb) * A->nb) * nn ); + else + offset = A->A22; + } + + return (void*)((intptr_t)A->mat + (offset*eltsize) ); +} + +/** + * @brief Return the address of the tile A( m, n ) in a column major storage. + * + * @WARNING The only mapping valid with this data storage is the 2D block cyclic + * storage as soon as multiple nodes are involved (see chameleon_getrankof_2d()). + * + * @param[in] A + * The matrix descriptor in which to find the tile. + * + * @param[in] m + * The row index of the tile. + * + * @param[in] n + * The column index of the tile. + * + * @return The address of the tile A( m, n ) + * + */ +void *chameleon_getaddr_cm( const CHAM_desc_t *A, int m, int n ) +{ + size_t mm = m + A->i / A->mb; + size_t nn = n + A->j / A->nb; + size_t eltsize = CHAMELEON_Element_Size(A->dtyp); + size_t offset = 0; + +#if defined(CHAMELEON_USE_MPI) + assert( A->myrank == A->get_rankof( A, mm, nn ) ); + mm = mm / A->p; + nn = nn / A->q; +#endif + + offset = (size_t)(A->llm * A->nb) * nn + (size_t)(A->mb) * mm; + return (void*)((intptr_t)A->mat + (offset*eltsize) ); +} + +/** + * @brief Return the address of the tile A( m, m ) in a tile storage. + * + * @WARNING The only mapping valid with this data storage is the diagonal 2D block cyclic + * storage as soon as multiple nodes are involved (see chameleon_getrankof_2d_diag()). + * + * @param[in] A + * The matrix descriptor in which to find the tile. + * + * @param[in] m + * The row and column index of the tile. + * + * @param[in] n + * Unused. + * + * @return The address of the tile A( m, n ) + * + */ +void *chameleon_getaddr_diag( const CHAM_desc_t *A, int m, int n ) +{ + (void)n; + return chameleon_getaddr_ccrb( A, m, 0 ); +} + +/** + * @brief Return the address of the tile A( m, m ) in a dynamic storage. + * + * Template that returns a NULL address for all tiles. This is used jointly with + * the StarPU runtime system to allocate data on the fly and it can be used with + * any data mapping. + * + * @param[in] A + * The matrix descriptor in which to find the tile (unused). + * + * @param[in] m + * The row index of the tile (unused). + * + * @param[in] n + * The column index of the tile (unused). + * + * @return A null pointer + * + */ +void *chameleon_getaddr_null( const CHAM_desc_t *A, int m, int n ) +{ + (void)A; (void)m; (void)n; + return NULL; +} + +/** + * @brief Return the leading dimension of the tile A( m, m ) stored in a tiled storage. + * + * This functions returns the leading dimension of the tile A( m, n ) and since + * the tiled storage is compatible with any mapping strategy, this function is + * also valid for any mapping. + * + * @param[in] A + * The matrix descriptor in which to find the tile. + * + * @param[in] m + * The row index of the tile. + * + * @param[in] n + * The column index of the tile. + * + * @return The leading dimension of the tile A( m, n ). + * + */ +int chameleon_getblkldd_ccrb( const CHAM_desc_t *A, int m ) +{ + int mm = m + A->i / A->mb; + return ( ((mm+1) == A->lmt) && ((A->lm % A->mb) != 0)) ? A->lm % A->mb : A->mb; +} + +/** + * @brief Return the leading dimension of the tile A( m, m ) stored in a column major storage. + * + * This functions returns the leading dimension of the tile A( m, n ) gfor + * column major storage. It can be only be used jointly with + * chameleon_getaddr_cm() and chameleon_getrankof_2d(). + * + * @param[in] A + * The matrix descriptor in which to find the tile. + * + * @param[in] m + * The row index of the tile. + * + * @param[in] n + * The column index of the tile. + * + * @return The leading dimension of the tile A( m, n ). + * + */ +int chameleon_getblkldd_cm( const CHAM_desc_t *A, int m ) +{ + (void)m; + return A->llm; +} diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 19dce38527e59cc76d83a3a1a23588429fbd547c..da47c6e21722c9acaf99a785540e92b2c2a25171 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -58,6 +58,7 @@ set(CHAMELEON_HDRS chameleon/timer.h chameleon/types.h chameleon/flops.h + chameleon/descriptor_helpers.h ) # Add generated headers diff --git a/include/chameleon.h b/include/chameleon.h index 175cb73f7d18148bffea2c780a24f26c9a14fbea..2dd55582aa680933212a0ae1d90d2e5881609348 100644 --- a/include/chameleon.h +++ b/include/chameleon.h @@ -30,6 +30,7 @@ #include "chameleon/constants.h" #include "chameleon/types.h" #include "chameleon/struct.h" +#include "chameleon/descriptor_helpers.h" /* **************************************************************************** * CHAMELEON runtime common API diff --git a/include/chameleon/descriptor_helpers.h b/include/chameleon/descriptor_helpers.h new file mode 100644 index 0000000000000000000000000000000000000000..575ed18a3afba3994512177c680a7fdedbd683d8 --- /dev/null +++ b/include/chameleon/descriptor_helpers.h @@ -0,0 +1,74 @@ +/** + * + * @file descriptor_helpers.h + * + * @copyright 2009-2014 The University of Tennessee and The University of + * Tennessee Research Foundation. All rights reserved. + * @copyright 2012-2021 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, + * Univ. Bordeaux. All rights reserved. + * + *** + * + * @brief Set of functions to help the user to declare matrix descriptors (allocation, mapping... ) + * + * @version 1.0.0 + * @author Jakub Kurzak + * @author Mathieu Faverge + * @author Cedric Castagnede + * @author Florent Pruvost + * @author Guillaume Sylvand + * @author Raphael Boucherie + * @author Samuel Thibault + * @date 2020-03-03 + * + * @addtogroup chameleon_descriptors + * @{ + * @brief Set of predefined functions to produce standard matrix mappings + * + * This module provides the set of functions to produce standard mapping of + * the matrix tiles among processors, as well as associated function to: get a + * tile address within a specific storage, get a tile leading dimension, ... + * + */ +#ifndef _chameleon_descriptor_helpers_h_ +#define _chameleon_descriptor_helpers_h_ + +#include <chameleon/struct.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Mapping functions + * @{ + */ +int chameleon_getrankof_2d ( const CHAM_desc_t *A, int m, int n ); +int chameleon_getrankof_2d_diag ( const CHAM_desc_t *A, int m, int n ); + +/** + * @} + * @name Block address functions + * @{ + */ +void* chameleon_getaddr_cm ( const CHAM_desc_t *A, int m, int n ); +void* chameleon_getaddr_ccrb( const CHAM_desc_t *A, int m, int n ); +void* chameleon_getaddr_null( const CHAM_desc_t *A, int m, int n ); +void* chameleon_getaddr_diag( const CHAM_desc_t *A, int m, int n ); + +/** + * @} + * @name Leading dimension functions + * @{ + */ +int chameleon_getblkldd_cm ( const CHAM_desc_t *A, int m ); +int chameleon_getblkldd_ccrb( const CHAM_desc_t *A, int m ); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _chameleon_descriptor_helpers_h_ */ diff --git a/testing/testing_zprint.c b/testing/testing_zprint.c index 46ae4f9838de05fa32c061032e4931863bba6e8d..ccc9c7fa0a2ec6aab08bdb901b4dfb19728fc32c 100644 --- a/testing/testing_zprint.c +++ b/testing/testing_zprint.c @@ -22,34 +22,6 @@ #include "testing_zcheck.h" #include <chameleon/flops.h> -/** - * Internal function to return address of block (m,n) with m,n = block indices - */ -inline static void * -chameleon_getaddr_cm( const CHAM_desc_t *A, int m, int n ) -{ - size_t mm = m + A->i / A->mb; - size_t nn = n + A->j / A->nb; - size_t eltsize = CHAMELEON_Element_Size( A->dtyp ); - size_t offset = 0; - -#if defined(CHAMELEON_USE_MPI) - assert( A->myrank == A->get_rankof( A, mm, nn ) ); - mm = mm / A->p; - nn = nn / A->q; -#endif - - offset = (size_t)( A->llm * A->nb ) * nn + (size_t)( A->mb ) * mm; - return (void *)( (intptr_t)A->mat + ( offset * eltsize ) ); -} - -inline static int -chameleon_getblkldd_cm( const CHAM_desc_t *A, int m ) -{ - (void)m; - return A->llm; -} - int testing_zprint_desc( run_arg_list_t *args, int check ) {