diff --git a/src/mpi/c/allgather.c b/src/mpi/c/allgather.c index 66ecc2a8c1..e5c37f25c2 100644 --- a/src/mpi/c/allgather.c +++ b/src/mpi/c/allgather.c @@ -7,6 +7,8 @@ #include "mpi.h" #include "mpi/c/bindings.h" +#include "mca/coll/coll.h" +#include "communicator/communicator.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Allgather = PMPI_Allgather @@ -16,10 +18,42 @@ #include "mpi/c/profile/defines.h" #endif +static char FUNC_NAME[] = "MPI_Allgather"; int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype, - void *recvbuf, int recvcount, MPI_Datatype recvtype, - MPI_Comm comm) { - return MPI_SUCCESS; + void *recvbuf, int recvcount, MPI_Datatype recvtype, + MPI_Comm comm) +{ + int err; + mca_coll_base_allgather_fn_t func; + + if (MPI_PARAM_CHECK) { + if (MPI_COMM_NULL == comm) { + return LAM_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, + FUNC_NAME); + } + + if ((MPI_DATATYPE_NULL == sendtype) + || (MPI_DATATYPE_NULL == recvtype)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME); + } + + if ((sendcount < 0) || (recvcount < 0)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME); + } + } + + func = comm->c_coll.coll_allgather_intra; + + if (NULL == func) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_OTHER, FUNC_NAME); + } + + /* Call the coll SSI to actually perform the allgather */ + + err = func(sendbuf, sendcount, sendtype, recvbuf, recvcount, + recvtype, comm); + + LAM_ERRHANDLER_RETURN(err, comm, MPI_ERR_UNKNOWN, FUNC_NAME); } diff --git a/src/mpi/c/alltoall.c b/src/mpi/c/alltoall.c index 8807680982..3557f83e48 100644 --- a/src/mpi/c/alltoall.c +++ b/src/mpi/c/alltoall.c @@ -7,6 +7,8 @@ #include "mpi.h" #include "mpi/c/bindings.h" +#include "mca/coll/coll.h" +#include "communicator/communicator.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Alltoall = PMPI_Alltoall @@ -16,9 +18,47 @@ #include "mpi/c/profile/defines.h" #endif +static char FUNC_NAME[] = "MPI_Alltoall"; + + int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype, - void *recvbuf, int recvcount, - MPI_Datatype recvtype, MPI_Comm comm) { - return MPI_SUCCESS; + void *recvbuf, int recvcount, + MPI_Datatype recvtype, MPI_Comm comm) +{ + int err; + mca_coll_base_alltoall_fn_t func; + + if (MPI_PARAM_CHECK) { + if (MPI_COMM_NULL == comm) { + return LAM_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, + FUNC_NAME); + } + + if ((NULL == sendbuf) || (NULL == recvbuf)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME); + } + + if ((MPI_DATATYPE_NULL == sendtype) || (MPI_DATATYPE_NULL == recvtype)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME); + } + + if ((sendcount < 0) || (recvcount < 0)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME); + } + } + + /* VPS: Need to change this to another pointer, because we wont have + two pointers - intra and inter - cached in the new design */ + func = comm->c_coll.coll_alltoall_intra; + + if (NULL == func) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_OTHER, FUNC_NAME); + } + + err = func(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, + comm); + + LAM_ERRHANDLER_RETURN((err != MPI_SUCCESS), comm, MPI_ERR_UNKNOWN, + FUNC_NAME); } diff --git a/src/mpi/c/barrier.c b/src/mpi/c/barrier.c index 47ade0057d..6d81026907 100644 --- a/src/mpi/c/barrier.c +++ b/src/mpi/c/barrier.c @@ -6,6 +6,9 @@ #include "mpi.h" #include "mpi/c/bindings.h" +#include "mca/coll/coll.h" +#include "errhandler/errhandler.h" +#include "communicator/communicator.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Barrier = PMPI_Barrier @@ -15,6 +18,36 @@ #include "mpi/c/profile/defines.h" #endif -int MPI_Barrier(MPI_Comm comm) { - return MPI_SUCCESS; +static char FUNC_NAME[] = "MPI_Barrier"; + + +int MPI_Barrier(MPI_Comm comm) +{ + int err; + mca_coll_base_barrier_fn_t func; + + if (MPI_PARAM_CHECK) { + if (MPI_COMM_NULL == comm) { + return LAM_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, + FUNC_NAME); + } + } + + /* Obvious case */ + + if (lam_comm_size(comm) <= 1) { + return MPI_SUCCESS; + } + + /* VPS: Need to change this to another pointer, because we wont have + two pointers - intra and inter - cached in the new design */ + func = comm->c_coll.coll_barrier_intra; + + if (NULL == func) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_OTHER, FUNC_NAME); + } + + err = func(comm); + + LAM_ERRHANDLER_RETURN(err, comm, MPI_ERR_UNKNOWN, FUNC_NAME); } diff --git a/src/mpi/c/bcast.c b/src/mpi/c/bcast.c index d193fecb06..838e8e0191 100644 --- a/src/mpi/c/bcast.c +++ b/src/mpi/c/bcast.c @@ -6,6 +6,8 @@ #include "mpi.h" #include "mpi/c/bindings.h" +#include "mca/coll/coll.h" +#include "communicator/communicator.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Bcast = PMPI_Bcast @@ -15,7 +17,64 @@ #include "mpi/c/profile/defines.h" #endif +static char FUNC_NAME[] = "MPI_Bcast"; + + int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, - int root, MPI_Comm comm) { - return MPI_SUCCESS; + int root, MPI_Comm comm) +{ + int size, err; + mca_coll_base_bcast_fn_t func; + + if (MPI_PARAM_CHECK) { + if (MPI_COMM_NULL == comm) { + return LAM_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, + FUNC_NAME); + } + + if (NULL == buffer) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME); + } + + if (MPI_DATATYPE_NULL == datatype) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME); + } + + if (count < 0) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME); + } + } + + if (LAM_COMM_IS_INTRA(comm)) { + MPI_Comm_size(comm, &size); + if ((root >= size) || (root < 0)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ROOT, FUNC_NAME); + } + if (count == 0 && comm->c_coll.coll_bcast_optimization) { + return(MPI_SUCCESS); + } + + /* If there's only one node, we're done */ + + else if (size <= 1) { + return(MPI_SUCCESS); + } + } else { + MPI_Comm_remote_size(comm, &size); + if (!(((root < size) && (root >= 0)) + || (root == MPI_ROOT) || (root == MPI_PROC_NULL))) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ROOT, FUNC_NAME); + } + } + + /* VPS: Need to change this to another pointer, because we wont have + two pointers - intra and inter - cached in the new design */ + func = comm->c_coll.coll_bcast_intra; + + if (NULL == func) + return MPI_ERR_OTHER; + + err = func(buffer, count, datatype, root, comm); + + LAM_ERRHANDLER_RETURN(err, comm, MPI_ERR_UNKNOWN, FUNC_NAME); } diff --git a/src/mpi/c/gather.c b/src/mpi/c/gather.c index 30ced9d773..19a9537cf1 100644 --- a/src/mpi/c/gather.c +++ b/src/mpi/c/gather.c @@ -6,6 +6,8 @@ #include "mpi.h" #include "mpi/c/bindings.h" +#include "mca/coll/coll.h" +#include "communicator/communicator.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Gather = PMPI_Gather @@ -15,8 +17,62 @@ #include "mpi/c/profile/defines.h" #endif +static char FUNC_NAME[] = "MPI_Gather"; + int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, - int root, MPI_Comm comm) { - return MPI_SUCCESS; + int root, MPI_Comm comm) +{ + int rank; + int size; + int err; + mca_coll_base_gather_fn_t func; + + if (MPI_PARAM_CHECK) { + if (MPI_COMM_NULL == comm) { + return LAM_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, + FUNC_NAME); + } + } + + func = comm->c_coll.coll_gather_intra; + + if (LAM_COMM_IS_INTRA(comm)) { + /* conditions for intracomm */ + MPI_Comm_size(comm, &size); + MPI_Comm_rank(comm, &rank); + if ((root >= size) || (root < 0)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ROOT, FUNC_NAME); + } + if ((sendcount < 0) || (rank == root && recvcount < 0)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME); + } + if ((sendtype == MPI_DATATYPE_NULL) || + (rank == root && recvtype == MPI_DATATYPE_NULL)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME); + } + } else { + /* Conditions for intercomm */ + MPI_Comm_remote_size(comm, &size); + if (((root != MPI_PROC_NULL) && (sendtype == MPI_DATATYPE_NULL)) || + (root == MPI_ROOT && recvtype == MPI_DATATYPE_NULL)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME); + } + if (!(((root < size) && (root >= 0)) + || (root == MPI_ROOT) || (root == MPI_PROC_NULL))) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ROOT, FUNC_NAME); + } + } + + if (func == NULL) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_OTHER, FUNC_NAME); + } + + + /* Call the coll SSI to actually perform the bcast */ + + err = func(sendbuf, sendcount, sendtype, recvbuf, + recvcount, recvtype, root, comm); + + LAM_ERRHANDLER_RETURN(err, comm, MPI_ERR_UNKNOWN, FUNC_NAME); } diff --git a/src/mpi/c/group_excl.c b/src/mpi/c/group_excl.c index 24b689dfe7..252c700777 100644 --- a/src/mpi/c/group_excl.c +++ b/src/mpi/c/group_excl.c @@ -58,7 +58,7 @@ int MPI_Group_excl(MPI_Group group, int n, int *ranks, /* put group elements in the list */ cnt=0; - for (proc = 0; proc < n; proc++) { + for (proc = 0; proc < group_pointer->grp_proc_count; proc++) { found=0; /* check to see if this proc is in the exclusion list */ for( i_excl=0 ; i_excl < n ; ++i_excl ) { diff --git a/src/mpi/c/pack.c b/src/mpi/c/pack.c index bd1ed09eb1..d1cf736454 100644 --- a/src/mpi/c/pack.c +++ b/src/mpi/c/pack.c @@ -6,6 +6,10 @@ #include "mpi.h" #include "mpi/c/bindings.h" +#include "datatype/datatype.h" +#include "errhandler/errhandler.h" +#include "communicator/communicator.h" +#include "lfc/lam_object.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Pack = PMPI_Pack @@ -15,7 +19,68 @@ #include "mpi/c/profile/defines.h" #endif +/* VPS: Just for now, to be removed later */ +extern lam_convertor_t *lam_convertor; + +static char FUNC_NAME[] = "MPI_Pack"; + + int MPI_Pack(void *inbuf, int incount, MPI_Datatype datatype, - void *outbuf, int outsize, int *position, MPI_Comm comm) { - return MPI_SUCCESS; + void *outbuf, int outsize, int *position, MPI_Comm comm) +{ + int size, rc; + lam_convertor_t *local_convertor; + struct iovec invec; + + if (MPI_PARAM_CHECK) { + if (MPI_COMM_NULL == comm) { + return LAM_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, FUNC_NAME); + } + + if ((NULL == inbuf) || (NULL == outbuf) || (NULL == position)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME); + } +#if 0 + if (count < 0) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME); + } +#endif + + if (outsize < 0) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME); + } + + if (MPI_DATATYPE_NULL == datatype) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME); + } + } + + local_convertor = lam_convertor_get_copy(lam_convertor); + lam_convertor_init_for_send(local_convertor, 0, datatype, incount, + inbuf, 0); + + /* how long is the data ? Can we put it in the user buffer */ + lam_convertor_get_packed_size(local_convertor, &size); + if( (outsize - (*position)) < size) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME); + } + + /* Prepare the iovec withh all informations */ + invec.iov_base = (char*)outbuf + (*position); + + /* If the position is not ZERO we already start + * the packing for this datatype. + */ + invec.iov_len = outsize - (*position); + + /* Do the actual packing */ + rc = lam_convertor_pack(local_convertor, &invec, 1); + *position += local_convertor->bConverted; + + /* Release the convertor. For Open MPI you should simply use + * OBJ_RELEASE. + */ + OBJ_RELEASE(local_convertor); + + LAM_ERRHANDLER_RETURN(rc, comm, MPI_ERR_UNKNOWN, FUNC_NAME); } diff --git a/src/mpi/c/pack_size.c b/src/mpi/c/pack_size.c index 7034bd1f11..f6adb27c58 100644 --- a/src/mpi/c/pack_size.c +++ b/src/mpi/c/pack_size.c @@ -6,6 +6,10 @@ #include "mpi.h" #include "mpi/c/bindings.h" +#include "lfc/lam_object.h" +#include "errhandler/errhandler.h" +#include "communicator/communicator.h" +#include "datatype/datatype.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Pack_size = PMPI_Pack_size @@ -15,7 +19,32 @@ #include "mpi/c/profile/defines.h" #endif +static char FUNC_NAME[] = "MPI_Pack_size"; + int MPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, - int *size) { - return MPI_SUCCESS; + int *size) +{ + int ret; + lam_convertor_t *local_convertor; + + if (MPI_PARAM_CHECK) { + if (MPI_COMM_NULL == comm) { + return LAM_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, FUNC_NAME); + } + + if (NULL == size) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME); + } + + if (MPI_DATATYPE_NULL == datatype) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME); + } + } + + lam_convertor_init_for_send(local_convertor, 0, datatype, + incount, 0, NULL); + ret = lam_convertor_get_packed_size(local_convertor, size); + OBJ_RELEASE(local_convertor); + + LAM_ERRHANDLER_RETURN((ret >= 0), comm, MPI_ERR_UNKNOWN, FUNC_NAME); } diff --git a/src/mpi/c/unpack.c b/src/mpi/c/unpack.c index 24d5ebe4c6..4f00d471ca 100644 --- a/src/mpi/c/unpack.c +++ b/src/mpi/c/unpack.c @@ -6,6 +6,10 @@ #include "mpi.h" #include "mpi/c/bindings.h" +#include "datatype/datatype.h" +#include "errhandler/errhandler.h" +#include "communicator/communicator.h" +#include "lfc/lam_object.h" #if LAM_HAVE_WEAK_SYMBOLS && LAM_PROFILING_DEFINES #pragma weak MPI_Unpack = PMPI_Unpack @@ -15,8 +19,62 @@ #include "mpi/c/profile/defines.h" #endif +static char FUNC_NAME[] = "MPI_Unpack"; + + int MPI_Unpack(void *inbuf, int insize, int *position, void *outbuf, int outcount, MPI_Datatype datatype, - MPI_Comm comm) { - return MPI_SUCCESS; + MPI_Comm comm) +{ + int size, rc; + lam_convertor_t *local_convertor; + struct iovec outvec; + + if (MPI_PARAM_CHECK) { + if (MPI_COMM_NULL == comm) { + return LAM_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COMM, + "MPI_Unpack"); + } + + if ((NULL == inbuf) || (NULL == outbuf) || (NULL == position)) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME); + } + + if (outcount < 0) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME); + } + + if (MPI_DATATYPE_NULL == datatype) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME); + } + } + + local_convertor = lam_convertor_get_copy(local_convertor); + lam_convertor_init_for_recv(local_convertor, 0, datatype, outcount, + inbuf, 0); + + /* how long is the data ? Can we put it in the user buffer */ + lam_convertor_get_packed_size(local_convertor, &size); + if ((outcount - (*position)) < size) { + return LAM_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME); + } + + /* Prepare the iovec withh all informations */ + outvec.iov_base = (char*) inbuf + (*position); + + /* If the position is not ZERO we already start + * the packing for this datatype. + */ + outvec.iov_len = insize - (*position); + + /* Do the actual unpacking */ + rc = lam_convertor_unpack(local_convertor, &outvec, 1); + *position += local_convertor->bConverted; + + /* Release the convertor. For Open MPI you should simply use + * OBJ_RELEASE. + */ + OBJ_RELEASE(local_convertor); + + LAM_ERRHANDLER_RETURN(rc, comm, MPI_ERR_UNKNOWN, FUNC_NAME); }