From c73f2fe7c4b3dc6deeae12389ae22387928f0872 Mon Sep 17 00:00:00 2001 From: genaud Date: Tue, 23 Mar 2010 12:59:10 +0000 Subject: [PATCH] - implemented MPI_MAXLOC & MPI_MINLOC in operations - added fields _count and _cancelled to MPI_Status struct - implemented MPI_Get_count() git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7314 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- src/smpi/private.h | 1 + src/smpi/smpi_base.c | 11 +++++++ src/smpi/smpi_mpi.c | 27 +++++++++++++++-- src/smpi/smpi_mpi_dt.c | 69 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/smpi/private.h b/src/smpi/private.h index fd22172117..bc1580e55c 100644 --- a/src/smpi/private.h +++ b/src/smpi/private.h @@ -68,6 +68,7 @@ void smpi_mpi_send(void* buf, int count, MPI_Datatype datatype, int src, int tag void smpi_mpi_sendrecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf, int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status* status); int smpi_mpi_test(MPI_Request* request, MPI_Status* status); int smpi_mpi_testany(int count, MPI_Request requests[], int* index, MPI_Status* status); +void smpi_mpi_get_count(MPI_Status *status, MPI_Datatype datatype, int *count); void smpi_mpi_wait(MPI_Request* request, MPI_Status* status); int smpi_mpi_waitany(int count, MPI_Request requests[], MPI_Status* status); void smpi_mpi_waitall(int count, MPI_Request requests[], MPI_Status status[]); diff --git a/src/smpi/smpi_base.c b/src/smpi/smpi_base.c index 05a391a4b2..a48592d841 100644 --- a/src/smpi/smpi_base.c +++ b/src/smpi/smpi_base.c @@ -105,6 +105,8 @@ static void finish_wait(MPI_Request* request, MPI_Status* status) { status->MPI_SOURCE = (*request)->src; status->MPI_TAG = (*request)->tag; status->MPI_ERROR = MPI_SUCCESS; + status->_count = (*request)->size; // size in bytes + status->_cancelled = 0; // FIXME: cancellation of requests not handled yet } DEBUG3("finishing wait for %p [data = %p, complete = %d]", *request, data, data->complete); // data == *request if sender is first to finish its wait @@ -160,6 +162,15 @@ int smpi_mpi_testany(int count, MPI_Request requests[], int* index, MPI_Status* return flag; } + +void smpi_mpi_get_count(MPI_Status *status, MPI_Datatype datatype, int *count) { + int size = smpi_datatype_size(datatype); + *count = (int)(status->_count / size); + if ( (int)((*count) * size) != status->_count ) + *count = MPI_UNDEFINED; +} + + void smpi_mpi_wait(MPI_Request* request, MPI_Status* status) { MPI_Request data = (*request)->data; diff --git a/src/smpi/smpi_mpi.c b/src/smpi/smpi_mpi.c index 7bb89d2505..3dda18f396 100644 --- a/src/smpi/smpi_mpi.c +++ b/src/smpi/smpi_mpi.c @@ -732,6 +732,30 @@ int MPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, i return retval; } +int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count) { + int retval; +/* + * Returns the number of entries received. (Again, we count entries, each of type datatype, not bytes.) + * The datatype argument should match the argument provided by the receive call that set the status variable. + * If the size of the datatype is zero, this routine will return a count of zero. + * If the amount of data in status is not an exact multiple of the size of datatype + * (so that count would not be integral), a count of MPI_UNDEFINED is returned instead. + * + */ + smpi_bench_end(-1, NULL); //FIXME + + if( 0==smpi_datatype_size(datatype)) { + // also check that the type is 'committed' when we have MPI_Type_commit (s.g. 23/03/21010) + retval = MPI_ERR_TYPE; + } else { + smpi_mpi_get_count(status, datatype, count); + retval = MPI_SUCCESS; + } + smpi_bench_begin(-1, NULL); + return retval; +} + + int MPI_Test(MPI_Request* request, int* flag, MPI_Status* status) { int retval; int rank = request && (*request)->comm != MPI_COMM_NULL @@ -1072,8 +1096,7 @@ int MPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype s int MPI_Get_processor_name( char *name, int *resultlen ) { int retval = MPI_SUCCESS; smpi_bench_end(-1, NULL); - strcpy( name , SIMIX_host_get_name(SIMIX_host_self())); - name[MPI_MAX_PROCESSOR_NAME-1]='\0'; + strncpy( name , SIMIX_host_get_name(SIMIX_host_self()), MPI_MAX_PROCESSOR_NAME-1); *resultlen= strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name); smpi_bench_begin(-1, NULL); diff --git a/src/smpi/smpi_mpi_dt.c b/src/smpi/smpi_mpi_dt.c index 30575b5e17..672a5f8fba 100644 --- a/src/smpi/smpi_mpi_dt.c +++ b/src/smpi/smpi_mpi_dt.c @@ -37,6 +37,15 @@ typedef struct s_smpi_mpi_datatype { }; \ MPI_Datatype name = &mpi_##name; + +//The following are datatypes for the MPI functions MPI_MAXLOC and MPI_MINLOC. +typedef struct { float value; int index;} float_int; +typedef struct { long value; int index;} long_int ; +typedef struct { double value; int index;} double_int; +typedef struct { short value; int index;} short_int; +typedef struct { int value; int index;} int_int; +typedef struct { long double value; int index;} long_double_int; + // Predefined data types CREATE_MPI_DATATYPE(MPI_CHAR, char); CREATE_MPI_DATATYPE(MPI_SHORT, short); @@ -68,6 +77,9 @@ CREATE_MPI_DATATYPE(MPI_C_LONG_DOUBLE_COMPLEX, long double _Complex); CREATE_MPI_DATATYPE(MPI_AINT, MPI_Aint); CREATE_MPI_DATATYPE(MPI_OFFSET, MPI_Offset); +CREATE_MPI_DATATYPE(MPI_FLOAT_INT, float_int); + + size_t smpi_datatype_size(MPI_Datatype datatype) { return datatype->size; } @@ -129,6 +141,8 @@ typedef struct s_smpi_mpi_op { #define BAND_OP(a, b) (b) &= (a) #define BOR_OP(a, b) (b) |= (a) #define BXOR_OP(a, b) (b) ^= (a) +#define MAXLOC_OP(a, b) (b) = (a.value) < (b.value) ? (b) : (a) +#define MINLOC_OP(a, b) (b) = (a.value) < (b.value) ? (a) : (b) //TODO : MINLOC & MAXLOC #define APPLY_FUNC(a, b, length, type, func) \ @@ -349,20 +363,55 @@ static void bxor_func(void* a, void* b, int* length, MPI_Datatype* datatype) { } } +static void minloc_func(void* a, void* b, int* length, MPI_Datatype* datatype) { + if(*datatype == MPI_FLOAT_INT) { + APPLY_FUNC(a, b, length, float_int, MINLOC_OP); + } else if(*datatype == MPI_LONG_INT) { + APPLY_FUNC(a, b, length, long_int, MINLOC_OP); + } else if(*datatype == MPI_DOUBLE_INT) { + APPLY_FUNC(a, b, length, double_int, MINLOC_OP); + } else if(*datatype == MPI_SHORT_INT) { + APPLY_FUNC(a, b, length, short_int, MINLOC_OP); + } else if(*datatype == MPI_2INT) { + APPLY_FUNC(a, b, length, int_int, MINLOC_OP); + } else if(*datatype == MPI_LONG_DOUBLE_INT) { + APPLY_FUNC(a, b, length, long_double_int, MINLOC_OP); + } +} + +static void maxloc_func(void* a, void* b, int* length, MPI_Datatype* datatype) { + if(*datatype == MPI_FLOAT_INT) { + APPLY_FUNC(a, b, length, float_int, MAXLOC_OP); + } else if(*datatype == MPI_LONG_INT) { + APPLY_FUNC(a, b, length, long_int, MAXLOC_OP); + } else if(*datatype == MPI_DOUBLE_INT) { + APPLY_FUNC(a, b, length, double_int, MAXLOC_OP); + } else if(*datatype == MPI_SHORT_INT) { + APPLY_FUNC(a, b, length, short_int, MAXLOC_OP); + } else if(*datatype == MPI_2INT) { + APPLY_FUNC(a, b, length, int_int, MAXLOC_OP); + } else if(*datatype == MPI_LONG_DOUBLE_INT) { + APPLY_FUNC(a, b, length, long_double_int, MAXLOC_OP); + } +} + + #define CREATE_MPI_OP(name, func) \ static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */ }; \ MPI_Op name = &mpi_##name; -CREATE_MPI_OP(MPI_MAX, max_func); -CREATE_MPI_OP(MPI_MIN, min_func); -CREATE_MPI_OP(MPI_SUM, sum_func); -CREATE_MPI_OP(MPI_PROD, prod_func); -CREATE_MPI_OP(MPI_LAND, land_func); -CREATE_MPI_OP(MPI_LOR, lor_func); -CREATE_MPI_OP(MPI_LXOR, lxor_func); -CREATE_MPI_OP(MPI_BAND, band_func); -CREATE_MPI_OP(MPI_BOR, bor_func); -CREATE_MPI_OP(MPI_BXOR, bxor_func); +CREATE_MPI_OP(MPI_MAX, max_func); +CREATE_MPI_OP(MPI_MIN, min_func); +CREATE_MPI_OP(MPI_SUM, sum_func); +CREATE_MPI_OP(MPI_PROD, prod_func); +CREATE_MPI_OP(MPI_LAND, land_func); +CREATE_MPI_OP(MPI_LOR, lor_func); +CREATE_MPI_OP(MPI_LXOR, lxor_func); +CREATE_MPI_OP(MPI_BAND, band_func); +CREATE_MPI_OP(MPI_BOR, bor_func); +CREATE_MPI_OP(MPI_BXOR, bxor_func); +CREATE_MPI_OP(MPI_MAXLOC, maxloc_func); +CREATE_MPI_OP(MPI_MINLOC, minloc_func); MPI_Op smpi_op_new(MPI_User_function* function, int commute) { MPI_Op op; -- 2.20.1