Finally I get the time to implement a correct reference count for datatypes. The problem
was that some datatypes can be used in order to create additional datatypes. In such cases they should not get destroyed otherwise the user will not be able to retrieve how a datatype was created. So I decide to never increase the reference count for any predefined datatypes (as we already know they will never get destroyed, except on finalize). For the others, every time a datatype is user by another one I increase the reference count. When I destroy a datatype, I parse (the internal structure args) and release one ref count on all not predefined datatypes used by this one. Thus the datatypes get cleaned. The main problem with this approach is the recursivity as this function can trigger another call to itself (but I dont think it will be an issue). This commit was SVN r6450.
Этот коммит содержится в:
родитель
d7bdc46ac9
Коммит
02828d3c97
@ -193,6 +193,7 @@ OMPI_DECLSPEC int32_t ompi_ddt_set_args( ompi_datatype_t* pData,
|
||||
int32_t ci, int32_t ** i,
|
||||
int32_t ca, long* a,
|
||||
int32_t cd, ompi_datatype_t** d,int32_t type);
|
||||
OMPI_DECLSPEC int32_t ompi_ddt_release_args( ompi_datatype_t* pData );
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
|
@ -30,29 +30,30 @@ typedef struct __dt_args {
|
||||
MPI_Datatype* d;
|
||||
} ompi_ddt_args_t;
|
||||
|
||||
#define ALLOC_ARGS(PDATA, IC, AC, DC) \
|
||||
do { \
|
||||
int length = sizeof(ompi_ddt_args_t) + (IC) * sizeof(int) + (AC) * sizeof(MPI_Aint) + (DC) * sizeof(MPI_Datatype); \
|
||||
char* buf = (char*)malloc( length ); \
|
||||
ompi_ddt_args_t* pArgs = (ompi_ddt_args_t*)buf; \
|
||||
pArgs->ci = (IC); \
|
||||
pArgs->ca = (AC); \
|
||||
pArgs->cd = (DC); \
|
||||
buf += sizeof(ompi_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 ALLOC_ARGS(PDATA, IC, AC, DC) \
|
||||
do { \
|
||||
int length = sizeof(ompi_ddt_args_t) + (IC) * sizeof(int) + \
|
||||
(AC) * sizeof(MPI_Aint) + (DC) * sizeof(MPI_Datatype); \
|
||||
char* buf = (char*)malloc( length ); \
|
||||
ompi_ddt_args_t* pArgs = (ompi_ddt_args_t*)buf; \
|
||||
pArgs->ci = (IC); \
|
||||
pArgs->ca = (AC); \
|
||||
pArgs->cd = (DC); \
|
||||
buf += sizeof(ompi_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 );
|
||||
@ -62,116 +63,116 @@ int32_t ompi_ddt_set_args( ompi_datatype_t* pData,
|
||||
int32_t ca, MPI_Aint* a,
|
||||
int32_t cd, MPI_Datatype* d, int32_t type)
|
||||
{
|
||||
int pos;
|
||||
ompi_ddt_args_t* pArgs;
|
||||
int pos;
|
||||
ompi_ddt_args_t* pArgs;
|
||||
|
||||
FREE_ARGS( pData );
|
||||
ALLOC_ARGS( pData, ci, ca, cd );
|
||||
assert( NULL == pData->args );
|
||||
ALLOC_ARGS( pData, ci, ca, cd );
|
||||
|
||||
pArgs = (ompi_ddt_args_t*)pData->args;
|
||||
pArgs->create_type = type;
|
||||
pArgs = (ompi_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[1], 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];
|
||||
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[1], 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;
|
||||
}
|
||||
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) );
|
||||
/* 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;
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t ompi_ddt_get_args( const ompi_datatype_t* pData, int32_t which,
|
||||
@ -179,44 +180,63 @@ int32_t ompi_ddt_get_args( const ompi_datatype_t* pData, int32_t which,
|
||||
int32_t* ca, MPI_Aint* a,
|
||||
int32_t* cd, MPI_Datatype* d, int32_t* type)
|
||||
{
|
||||
ompi_ddt_args_t* pArgs = pData->args;
|
||||
ompi_ddt_args_t* pArgs = pData->args;
|
||||
|
||||
if( pData->flags & DT_FLAG_PREDEFINED ) {
|
||||
switch(which){
|
||||
case 0:
|
||||
*ci = 0;
|
||||
*ca = 0;
|
||||
*cd = 0;
|
||||
*type = MPI_COMBINER_NAMED;
|
||||
break;
|
||||
default:
|
||||
return MPI_ERR_INTERN;
|
||||
}
|
||||
return(MPI_SUCCESS);
|
||||
}
|
||||
if( pData->flags & DT_FLAG_PREDEFINED ) {
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
/* In the dt_add function we increase the reference count for all datatypes
|
||||
* (except for the predefined ones) that get added to another datatype. This
|
||||
* insure that they cannot get released until all the references to them
|
||||
* get removed.
|
||||
*/
|
||||
int32_t ompi_ddt_release_args( ompi_datatype_t* pData )
|
||||
{
|
||||
int i;
|
||||
ompi_ddt_args_t* pArgs = pData->args;
|
||||
|
||||
for( i = 0; i < pArgs->cd; i++ ) {
|
||||
if( !(pArgs->d[i]->flags & DT_FLAG_PREDEFINED) ) {
|
||||
OBJ_RELEASE( pArgs->d[i] );
|
||||
}
|
||||
}
|
||||
FREE_ARGS( pData );
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ static void __destroy_ddt_struct( ompi_datatype_t* pData )
|
||||
pData->opt_desc.desc = NULL;
|
||||
pData->opt_desc.length = 0;
|
||||
pData->opt_desc.used = 0;
|
||||
if( pData->args != NULL ) free( pData->args );
|
||||
if( pData->args != NULL ) ompi_ddt_release_args( pData );
|
||||
pData->args = NULL;
|
||||
if( NULL != ompi_pointer_array_get_item(ompi_datatype_f_to_c_table, pData->d_f_to_c_index) ){
|
||||
ompi_pointer_array_set_item( ompi_datatype_f_to_c_table, pData->d_f_to_c_index, NULL );
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user