#ifdef __CIVL_CIVLMPI__ #else #define __CIVL_CIVLMPI__ #include #include #include #include #include #include /**************************** Duplicated Part *************************************/ /* Duplicated definition with the same struct in mpi.h. The reason of this duplication is to make civlmpi.cvl independent with mpi.cvl. */ typedef struct MPI_Comm { $comm p2p; // point-to-point communication $comm col; // collective communication $barrier barrier; __MPI_Sys_status__ status; }MPI_Comm; /* Definition of CMPI_Gcomm (CMPI_Gcomm has a type of __CMPI_Gcomm) and MPI_Comm */ struct CMPI_Gcomm { $gcomm p2p; // point-to-point communication $gcomm col; // collective communication $gbarrier gbarrier; }; /****************************** Helper Functions **********************************/ int sizeofDatatype(MPI_Datatype datatype) { switch (datatype) { case MPI_INT: return sizeof(int); case MPI_FLOAT: return sizeof(float); case MPI_DOUBLE: return sizeof(double); case MPI_CHAR: return sizeof(char); case MPI_BYTE: return sizeof(char); // char is always one byte ? case MPI_SHORT: return sizeof(short); case MPI_LONG: return sizeof(long); case MPI_LONG_DOUBLE: return sizeof(long double); case MPI_LONG_LONG_INT: return sizeof(long long int); case MPI_LONG_LONG: return sizeof(long long); case MPI_UNSIGNED_LONG_LONG: return sizeof(unsigned long long); default: $assert 0 : "Unreachable"; } } /************************** MPI LIB Implementations *******************************/ CMPI_Gcomm CMPI_Gcomm_create($scope scope, int size) { CMPI_Gcomm result; result.p2p = $gcomm_create(scope, size); result.col = $gcomm_create(scope, size); result.gbarrier = $gbarrier_create(scope, size); return result; } void CMPI_Gcomm_destroy(CMPI_Gcomm gc) { $gcomm_destroy(gc.p2p); $gcomm_destroy(gc.col); $gbarrier_destroy(gc.gbarrier); } MPI_Comm CMPI_Comm_create($scope scope, CMPI_Gcomm gc, int rank) { MPI_Comm result; result.p2p = $comm_create(scope, gc.p2p, rank); result.col = $comm_create(scope, gc.col, rank); result.barrier = $barrier_create(scope, gc.gbarrier, rank); result.status = __UNINIT; return result; } void CMPI_Comm_destroy(MPI_Comm comm) { $comm_destroy(comm.p2p); $comm_destroy(comm.col); $barrier_destroy(comm.barrier); } int __MPI_Init(MPI_Comm *comm) { comm->status = __INIT; return 0; } int __MPI_Finalize(MPI_Comm *comm) { comm->status = __FINALIZED; return 0; } int CMPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, $comm comm) { if (dest >= 0) { int size = count*sizeofDatatype(datatype); int place = $comm_place(comm); $message out = $message_pack(place, dest, tag, buf, size); $comm_enqueue(comm, out); } return 0; } int CMPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, $comm comm, MPI_Status *status) { if (source >= 0 || source == MPI_ANY_SOURCE) { $message in = $comm_dequeue(comm, source, tag); int size = count*sizeofDatatype(datatype); $message_unpack(in, buf, size); if (status != MPI_STATUS_IGNORE) { status->size = $message_size(in); status->MPI_SOURCE = $message_source(in); status->MPI_TAG = $message_tag(in); status->MPI_ERROR = 0; } } return 0; } #endif