#ifdef __CIVL_MPI__ #else #define __CIVL_MPI__ #include #include #include #include #include /* Completed definition for mpi-common.h */ struct MPI_Request{ int id; }; struct MPI_Comm { $comm p2p; // point-to-point communication $comm col; // collective communication $barrier barrier; __MPI_Sys_status__ status; }; /********************************** State *****************************************/ /* The number of times the MPI_Wtime function has been called */ int CMPI_time_count = 0; /************************** MPI LIB Implementations *******************************/ double MPI_Wtime() { double result = CMPI_time(CMPI_time_count); CMPI_time_count++; return result; } int MPI_Comm_size(MPI_Comm comm, int *size) { $assert comm.status == __INIT : "MPI_Comm_size() cannot be invoked without MPI_Init() being called before.\n"; *size = $comm_size(comm.p2p); return 0; } int MPI_Comm_rank(MPI_Comm comm, int *rank) { $assert comm.status == __INIT : "MPI_Comm_rank() cannot be invoked without MPI_Init() being called before.\n"; *rank = $comm_place(comm.p2p); return 0; } int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) { $assert comm.status == __INIT : "MPI_Send() cannot be invoked without MPI_Init() being called before.\n"; return CMPI_Send(buf, count, datatype, dest, tag, comm.p2p); } int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status) { $assert comm.status == __INIT : "MPI_Recv() cannot be invoked without " "MPI_Init() being called before.\n"; return CMPI_Recv(buf, count, datatype, source, tag, comm.p2p, status); } int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count) { *count = status->size/sizeofDatatype(datatype); return 0; } int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status *status) { $assert comm.status == __INIT : "MPI_Sendrecv() cannot be invoked " "without MPI_Init() being called before.\n"; // not correct for checking potential deadlock...rewrite: MPI_Send(sendbuf, sendcount, sendtype, dest, sendtag, comm); MPI_Recv(recvbuf, recvcount, recvtype, source, recvtag, comm, status); return 0; } /******************************** Collective ***********************************/ /* Broadcasts a message from root to everyone else. * Need to use a differnt comm. */ int MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm) { $assert comm.status == __INIT : "MPI_Bcast() cannot be invoked without MPI_Init() " "being called before.\n"; if ($comm_place(comm.col) == root) { int nprocs = $comm_size(comm.col); for (int i=0; i(root==rank) int real_recvcount; MPI_Recv(recvbuf, recvcount, recvtype, root, SCATTER_TAG, comm, &status); MPI_Get_count(&status, recvtype, &real_recvcount); $assert real_recvcount == recvcount : "MPI_Gather() asks for equality between" " the amount of data sent and the " "amount of data received."; } } #endif