1
1

Correct some minor bugs with the datatype.

Add the set_args and get_args function in the dt_args file and add their prototypes in datatype.h.

This commit was SVN r1012.
Этот коммит содержится в:
George Bosilca 2004-04-05 21:02:03 +00:00
родитель 69ddfa4e52
Коммит a08ea36900
5 изменённых файлов: 309 добавлений и 72 удалений

Просмотреть файл

@ -15,7 +15,7 @@ libdatatype_la_SOURCES = \
$(headers) \
dt_add.c dt_create.c dt_create_array.c dt_create_dup.c dt_create_indexed.c \
dt_create_struct.c dt_create_vector.c dt_destroy.c dt_module.c \
dt_optimize.c dt_pack.c dt_unpack.c fake_stack.c
dt_optimize.c dt_pack.c dt_unpack.c fake_stack.c dt_args.c
# Conditionally install the header files

Просмотреть файл

@ -185,5 +185,16 @@ int lam_convertor_get_unpacked_size( lam_convertor_t* pConv, int* pSize );
int lam_create_stack_with_pos( lam_convertor_t* pConv,
int local_starting_point,
int* local_sizes );
/* temporary function prototypes. They should move in other place later. */
int lam_ddt_get_args( dt_desc_t* pData, int which,
int * ci, int * i,
int * ca, MPI_Aint * a,
int * cd, MPI_Datatype * d, int * type);
int lam_ddt_set_args( dt_desc_t* pData,
int ci, int ** i,
int ca, MPI_Aint* a,
int cd, MPI_Datatype* d,int type);
#endif /* DATATYPE_H_HAS_BEEN_INCLUDED */

205
src/datatype/dt_args.c Обычный файл
Просмотреть файл

@ -0,0 +1,205 @@
#include <lam_config.h>
#include <mpi.h>
#include <datatype.h>
#include <datatype_internal.h>
typedef struct __dt_args {
int create_type;
int ci;
int ca;
int cd;
int* i;
MPI_Aint* a;
MPI_Datatype* d;
} lam_ddt_args_t;
#define ALLOC_ARGS(PDATA, IC, AC, DC) \
do { \
int length = sizeof(lam_ddt_args_t) + (IC) * sizeof(int) + (AC) * sizeof(MPI_Aint) + (DC) * sizeof(MPI_Datatype); \
char* buf = (char*)malloc( length ); \
lam_ddt_args_t* pArgs = (lam_ddt_args_t*)buf; \
pArgs->ci = (IC); \
pArgs->ca = (AC); \
pArgs->cd = (DC); \
buf += sizeof(lam_ddt_args_t); \
if( pArgs->ci == 0 ) pArgs->i = NULL; \
else { \
pArgs->i = (int*)buf; \
buf += pArgs->ci * sizeof(int); \
} \
if( pArgs->ca == 0 ) pArgs->a = NULL; \
else { \
pArgs->a = (MPI_Aint*)buf; \
buf += pArgs->ca * sizeof(MPI_Aint); \
} \
if( pArgs->cd == 0 ) pArgs->d = NULL; \
else pArgs->d = (MPI_Datatype*)buf; \
(PDATA)->args = (void*)pArgs; \
} while(0)
#define FREE_ARGS(PDATA) \
if( (PDATA)->args != NULL ) free( (PDATA)->args );
int lam_ddt_set_args( lam_datatype_t* pData,
int ci, int ** i,
int ca, MPI_Aint* a,
int cd, MPI_Datatype* d,int type)
{
int pos;
lam_ddt_args_t* pArgs;
FREE_ARGS( pData );
ALLOC_ARGS( pData, ci, ca, cd );
pArgs = (lam_ddt_args_t*)pData->args;
pArgs->create_type = type;
switch(type){
/******************************************************************/
case MPI_COMBINER_DUP:
break;
/******************************************************************/
case MPI_COMBINER_CONTIGUOUS:
pArgs->i[0] = i[0][0];
break;
/******************************************************************/
case MPI_COMBINER_VECTOR:
pArgs->i[0] = i[0][0];
pArgs->i[1] = i[1][0];
pArgs->i[2] = i[2][0];
break;
/******************************************************************/
case MPI_COMBINER_HVECTOR_INTEGER:
case MPI_COMBINER_HVECTOR:
pArgs->i[0] = i[0][0];
pArgs->i[1] = i[1][0];
break;
/******************************************************************/
case MPI_COMBINER_INDEXED:
pos = 1;
pArgs->i[0] = i[0][0];
memcpy( pArgs->i + pos, i[1], i[0][0] * sizeof(int) );
pos += i[0][0];
memcpy( pArgs->i + pos, i[2], i[0][0] * sizeof(int) );
break;
/******************************************************************/
case MPI_COMBINER_HINDEXED_INTEGER:
case MPI_COMBINER_HINDEXED:
pArgs->i[0] = i[0][0];
memcpy( pArgs->i + 1, i, i[0][0] * sizeof(int) );
break;
/******************************************************************/
case MPI_COMBINER_INDEXED_BLOCK:
pArgs->i[0] = i[0][0];
pArgs->i[1] = i[1][0];
memcpy( pArgs->i + 2, i[2], i[0][0] * sizeof(int) );
break;
/******************************************************************/
case MPI_COMBINER_STRUCT_INTEGER:
case MPI_COMBINER_STRUCT:
pArgs->i[0] = i[0][0];
memcpy( pArgs->i + 1, i[1], i[0][0] * sizeof(int) );
break;
/******************************************************************/
case MPI_COMBINER_SUBARRAY:
pos = 1;
pArgs->i[0] = i[0][0];
memcpy( pArgs->i + pos, i[1], pArgs->i[0] * sizeof(int) );
pos += pArgs->i[0];
memcpy( pArgs->i + pos, i[2], pArgs->i[0] * sizeof(int) );
pos += pArgs->i[0];
memcpy( pArgs->i + pos, i[3], pArgs->i[0] * sizeof(int) );
pos += pArgs->i[0];
pArgs->i[pos] = i[4][0];
break;
/******************************************************************/
case MPI_COMBINER_DARRAY:
pos = 3;
pArgs->i[0] = i[0][0];
pArgs->i[1] = i[1][0];
pArgs->i[2] = i[2][0];
memcpy( pArgs->i + pos, i[3], i[2][0] * sizeof(int) );
pos += i[2][0];
memcpy( pArgs->i + pos, i[4], i[2][0] * sizeof(int) );
pos += i[2][0];
memcpy( pArgs->i + pos, i[5], i[2][0] * sizeof(int) );
pos += i[2][0];
memcpy( pArgs->i + pos, i[6], i[2][0] * sizeof(int) );
pos += i[2][0];
pArgs->i[pos] = i[7][0];
break;
/******************************************************************/
case MPI_COMBINER_F90_REAL:
case MPI_COMBINER_F90_COMPLEX:
pArgs->i[0] = i[0][0];
pArgs->i[1] = i[1][0];
break;
/******************************************************************/
case MPI_COMBINER_F90_INTEGER:
pArgs->i[0] = i[0][0];
break;
/******************************************************************/
case MPI_COMBINER_RESIZED:
break;
/******************************************************************/
default:
break;
}
/* copy the array of MPI_Aint */
if( pArgs->a != NULL )
memcpy( pArgs->a, a, ca * sizeof(MPI_Aint) );
/* copy the array of types */
if( pArgs->d != NULL )
memcpy( pArgs->d, d, cd * sizeof(MPI_Datatype) );
return MPI_SUCCESS;
}
int lam_ddt_get_args( lam_datatype_t* pData, int which,
int * ci, int * i,
int * ca, MPI_Aint * a,
int * cd, MPI_Datatype * d, int * type)
{
lam_ddt_args_t* pArgs = pData->args;
if( (pData->flags & DT_FLAG_BASIC) == DT_FLAG_BASIC ) {
switch(which){
case 0:
*ci = 0;
*ca = 0;
*cd = 0;
*type = MPI_COMBINER_NAMED;
break;
default:
return MPI_ERR_INTERN;
}
return(MPI_SUCCESS);
}
if( pArgs == NULL ) return MPI_ERR_INTERN;
switch(which){
case 0: /* GET THE LENGTHS */
*ci = pArgs->ci;
*ca = pArgs->ca;
*cd = pArgs->cd;
*type = pArgs->create_type;
break;
case 1: /* GET THE ARGUMENTS */
if(*ci < pArgs->ci || *ca < pArgs->ca || *cd < pArgs->cd)
return MPI_ERR_ARG;
if( pArgs->i != NULL )
memcpy( i, pArgs->i, pArgs->ci * sizeof(int) );
if( pArgs->a != NULL )
memcpy( a, pArgs->a, pArgs->ca * sizeof(MPI_Aint) );
if( pArgs->d != NULL )
memcpy( d, pArgs->d, pArgs->cd * sizeof(MPI_Datatype) );
break;
default:
return MPI_ERR_INTERN;
}
return MPI_SUCCESS;
}

Просмотреть файл

@ -10,7 +10,8 @@
#endif
#include <stdlib.h>
static int convertor_pack_general( lam_convertor_t* pConvertor, struct iovec* out, unsigned int outCount )
static int lam_convertor_pack_general( lam_convertor_t* pConvertor,
struct iovec* out, unsigned int outCount )
{
dt_stack_t* pStack; /* pointer to the position on the stack */
int pos_desc; /* actual position in the description of the derived datatype */
@ -134,8 +135,8 @@ static int convertor_pack_general( lam_convertor_t* pConvertor, struct iovec* ou
/* We suppose here that we work with an already optimized version of the data
*/
static int convertor_pack_homogeneous( lam_convertor_t* pConv,
struct iovec* iov, unsigned int out_size )
static int lam_convertor_pack_homogeneous( lam_convertor_t* pConv,
struct iovec* iov, unsigned int out_size )
{
dt_stack_t* pStack; /* pointer to the position on the stack */
int pos_desc; /* actual position in the description of the derived datatype */
@ -272,6 +273,30 @@ static int convertor_pack_homogeneous( lam_convertor_t* pConv,
return 0;
}
static int lam_convertor_pack_homogeneous_contig( lam_convertor_t* pConv,
struct iovec* out, unsigned int out_size )
{
lam_datatype_t* pData = pConv->pDesc;
char* pSrc = pConv->pBaseBuf + pData->true_lb + pConv->bConverted;
size_t length = pData->size * pConv->count;
long extent;
if( pData->size == (extent = (pData->ub - pData->lb)) ) {
if( out[0].iov_base == NULL ) {
out[0].iov_base = pSrc;
if( (pConv->bConverted + out[0].iov_len) > length )
out[0].iov_len = length - pConv->bConverted;
} else {
/* contiguous data just memcpy the smallest data in the user buffer */
out[0].iov_len = IMIN( out[0].iov_len, length );
MEMCPY( out[0].iov_base, pSrc, out[0].iov_len);
}
pConv->bConverted += out[0].iov_len;
return (pConv->bConverted == length);
}
return -1; /* not yet implemented */
}
/* The pack routines should do 2 things:
* - first if the provided iovec contains NULL pointers then they should provide
* buffer space. If the data is contiguous the it should provide directly pointers
@ -288,35 +313,17 @@ static int convertor_pack_homogeneous( lam_convertor_t* pConv,
int lam_convertor_pack( lam_convertor_t* pConv, struct iovec* out, unsigned int out_size )
{
dt_desc_t* pData = pConv->pDesc;
int extent;
if( pConv->count == 0 ) return 1; /* nothing to do */
if( pData->flags & DT_FLAG_CONTIGUOUS ) {
if( pData->size == (extent = (pData->ub - pData->lb)) ) {
size_t length = pData->size * pConv->count;
char* pSrc = pConv->pBaseBuf + pData->true_lb + pConv->bConverted;
if( out[0].iov_base == NULL ) {
out[0].iov_base = pSrc;
if( (pConv->bConverted + out[0].iov_len) > length )
out[0].iov_len = length - pConv->bConverted;
} else {
/* contiguous data just memcpy the smallest data in the user buffer */
out[0].iov_len = IMIN( out[0].iov_len, pData->size * pConv->count );
MEMCPY( out[0].iov_base, pSrc, out[0].iov_len);
}
pConv->bConverted += out[0].iov_len;
return (pConv->bConverted == length);
} else { /* datatype is contiguous but there are gap inbetween elements */
if( out[0].iov_base != NULL ) {
return -1;
}
}
if( pConv->bConverted == (pData->size * pConv->count) ) { /* conversion completed or nothing to do */
out[0].iov_len = 0;
return 1;
}
if( out[0].iov_base == NULL ) {
out[0].iov_len = pConv->count * pData->size;
out[0].iov_base = (void*)malloc( out[0].iov_len );
pConv->freebuf = out[0].iov_base;
if( !(pData->flags & DT_FLAG_CONTIGUOUS) ) { /* TODO REMOVE ME */
if( out[0].iov_base == NULL ) {
out[0].iov_len = pConv->count * pData->size;
out[0].iov_base = (void*)malloc( out[0].iov_len );
pConv->freebuf = out[0].iov_base;
}
}
return lam_convertor_progress( pConv, out, out_size );
}
@ -345,9 +352,14 @@ int lam_convertor_init_for_send( lam_convertor_t* pConv, unsigned int flags,
pConv->pFunctions = copy_functions;
pConv->converted = 0;
pConv->bConverted = 0;
if( (dt->flags & DT_FLAG_CONTIGUOUS) && (dt->size == (dt->ub - dt->lb)) )
if( dt->flags & DT_FLAG_CONTIGUOUS ) {
pConv->flags |= DT_FLAG_CONTIGUOUS;
pConv->fAdvance = convertor_pack_homogeneous;
pConv->fAdvance = lam_convertor_pack_homogeneous_contig;
} else {
/* TODO handle the sender convert case */
pConv->fAdvance = lam_convertor_pack_general;
pConv->fAdvance = lam_convertor_pack_homogeneous;
}
if( pConv->freebuf != NULL ) {
free( pConv->freebuf );
pConv->freebuf = NULL;
@ -361,7 +373,7 @@ lam_convertor_t* lam_convertor_create( int remote_arch, int mode )
pConv->pStack = NULL;
pConv->remoteArch = remote_arch;
pConv->fAdvance = convertor_pack_homogeneous;
pConv->fAdvance = NULL;
return pConv;
}
@ -384,6 +396,7 @@ inline int lam_convertor_copy( lam_convertor_t* pSrcConv, lam_convertor_t* pDest
pDestConv->count = 0;
pDestConv->converted = 0;
pDestConv->bConverted = 0;
pDestConv->fAdvance = NULL;
pDestConv->freebuf = NULL;
return LAM_SUCCESS;
}

Просмотреть файл

@ -10,10 +10,6 @@
#endif
#include <stdlib.h>
static int convertor_unpack_homogeneous( lam_convertor_t* pConv, struct iovec* iov, unsigned int out_size );
static int convertor_unpack_general( lam_convertor_t* pConvertor,
struct iovec* pInputv, unsigned int inputCount );
void dump_stack( dt_stack_t* pStack, int stack_pos, dt_elem_desc_t* pDesc, char* name )
{
printf( "\nStack %p stack_pos %d name %s\n", (void*)pStack, stack_pos, name );
@ -43,9 +39,8 @@ void dump_stack( dt_stack_t* pStack, int stack_pos, dt_elem_desc_t* pDesc, char*
* 1 if everything went fine and the data was completly converted
* -1 something wrong occurs.
*/
static int convertor_unpack_general( lam_convertor_t* pConvertor,
struct iovec* pInputv,
unsigned int inputCount )
static int lam_convertor_unpack_general( lam_convertor_t* pConvertor,
struct iovec* pInputv, unsigned int inputCount )
{
dt_stack_t* pStack; /* pointer to the position on the stack */
int pos_desc; /* actual position in the description of the derived datatype */
@ -165,11 +160,11 @@ static int convertor_unpack_general( lam_convertor_t* pConvertor,
return 0;
}
static int convertor_unpack_homogeneous( lam_convertor_t* pConv, struct iovec* iov, unsigned int out_size )
static int lam_convertor_unpack_homogeneous( lam_convertor_t* pConv,
struct iovec* iov, unsigned int out_size )
{
dt_stack_t* pStack; /* pointer to the position on the stack */
int pos_desc; /* actual position in the description of the derived datatype */
int type; /* type at current position */
int i; /* counter for basic datatype with extent */
int stack_pos = 0; /* position on the stack */
long lastDisp = 0, last_count = 0;
@ -183,31 +178,6 @@ static int convertor_unpack_homogeneous( lam_convertor_t* pConv, struct iovec* i
pSrcBuf = iov[0].iov_base;
if( pData->flags & DT_FLAG_CONTIGUOUS ) {
long extent = pData->ub - pData->lb;
char* pDstBuf = pConv->pBaseBuf + pData->true_lb + pConv->bConverted;
if( pData->size == extent ) {
long length = pConv->count * pData->size;
if( length > iov[0].iov_len )
length = iov[0].iov_len;
/* contiguous data or basic datatype with count */
MEMCPY( pDstBuf, pSrcBuf, length );
pConv->bConverted += length;
} else {
type = iov[0].iov_len;
for( pos_desc = 0; pos_desc < pConv->count; pos_desc++ ) {
MEMCPY( pDstBuf, pSrcBuf, pData->size );
pSrcBuf += pData->size;
pDstBuf += extent;
type -= pData->size;
}
pConv->bConverted += type;
}
return (pConv->bConverted == (pData->size * pConv->count));
}
if( pData->opt_desc.desc != NULL ) {
pElems = pData->opt_desc.desc;
end_desc = pData->opt_desc.used;
@ -305,6 +275,38 @@ static int convertor_unpack_homogeneous( lam_convertor_t* pConv, struct iovec* i
return 0;
}
static int lam_convertor_unpack_homogeneous_contig( lam_convertor_t* pConv,
struct iovec* iov, unsigned int out_size )
{
dt_desc_t *pData = pConv->pDesc;
char* pDstBuf = pConv->pBaseBuf + pData->true_lb + pConv->bConverted;
char* pSrcBuf = iov[0].iov_base;
long extent = pData->ub - pData->lb;
int length, i;
if( iov[0].iov_base != NULL ) {
if( pData->size == extent ) {
length = pConv->count * pData->size - pConv->bConverted;
if( length > iov[0].iov_len )
length = iov[0].iov_len;
/* contiguous data or basic datatype with count */
MEMCPY( pDstBuf, pSrcBuf, length );
} else {
length = iov[0].iov_len;
for( i = 0; i < pConv->count; i++ ) {
MEMCPY( pDstBuf, pSrcBuf, pData->size );
pSrcBuf += pData->size;
pDstBuf += extent;
length -= pData->size;
}
}
pConv->bConverted += length;
return (pConv->bConverted == (pData->size * pConv->count));
}
return (pConv->bConverted == (pData->size * pConv->count));
}
int lam_convertor_unpack( lam_convertor_t* pConvertor,
struct iovec* pInputv,
unsigned int inputCount )
@ -314,8 +316,10 @@ int lam_convertor_unpack( lam_convertor_t* pConvertor,
char* pInput = pInputv[0].iov_base;
int rc;
if( pConvertor->count == 0 ) return 1; /* nothing to do */
if( pConvertor->bConverted == (pData->size * pConvertor->count) ) {
pInputv[0].iov_len = 0;
return 1; /* completed */
}
if( pConvertor->flags & DT_FLAG_CONTIGUOUS ) {
if( pInputv[0].iov_base == NULL ) {
rc = pConvertor->count * pData->size;
@ -475,9 +479,13 @@ int lam_convertor_init_for_recv( lam_convertor_t* pConv, unsigned int flags,
pConv->pFunctions = copy_functions;
pConv->converted = 0;
pConv->bConverted = 0;
if( (pData->flags & DT_FLAG_CONTIGUOUS) && (pData->size == (pData->ub - pData->lb)) )
/* TODO: work only on homogeneous architectures */
if( pData->flags & DT_FLAG_CONTIGUOUS ) {
pConv->flags |= DT_FLAG_CONTIGUOUS;
pConv->fAdvance = convertor_unpack_homogeneous;
pConv->fAdvance = lam_convertor_unpack_homogeneous_contig;
} else {
pConv->fAdvance = lam_convertor_unpack_homogeneous;
}
return 0;
}