📄 comm_inln.h
字号:
const MPI::Datatype & recvtype, int root) const{ (void)MPI_Scatterv(const_cast<void *>(sendbuf), const_cast<int *>(sendcounts), const_cast<int *>(displs), sendtype, recvbuf, recvcount, recvtype, root, mpi_comm);}inline voidMPI::Comm::Allgather(const void *sendbuf, int sendcount, const MPI::Datatype & sendtype, void *recvbuf, int recvcount, const MPI::Datatype & recvtype) const { (void)MPI_Allgather(const_cast<void *>(sendbuf), sendcount, sendtype, recvbuf, recvcount, recvtype, mpi_comm);}inline voidMPI::Comm::Allgatherv(const void *sendbuf, int sendcount, const MPI::Datatype & sendtype, void *recvbuf, const int recvcounts[], const int displs[], const MPI::Datatype & recvtype) const{ (void)MPI_Allgatherv(const_cast<void *>(sendbuf), sendcount, sendtype, recvbuf, const_cast<int *>(recvcounts), const_cast<int *>(displs), recvtype, mpi_comm);}inline voidMPI::Comm::Alltoall(const void *sendbuf, int sendcount, const MPI::Datatype & sendtype, void *recvbuf, int recvcount, const MPI::Datatype & recvtype) const{ (void)MPI_Alltoall(const_cast<void *>(sendbuf), sendcount, sendtype, recvbuf, recvcount, recvtype, mpi_comm);}inline voidMPI::Comm::Alltoallv(const void *sendbuf, const int sendcounts[], const int sdispls[], const MPI::Datatype & sendtype, void *recvbuf, const int recvcounts[], const int rdispls[], const MPI::Datatype & recvtype) const { (void)MPI_Alltoallv(const_cast<void *>(sendbuf), const_cast<int *>(sendcounts), const_cast<int *>(sdispls), sendtype, recvbuf, const_cast<int *>(recvcounts), const_cast<int *>(rdispls), recvtype,mpi_comm);}inline voidMPI::Comm::Alltoallw(const void *sendbuf, const int sendcounts[], const int sdispls[], const MPI::Datatype sendtypes[], void *recvbuf, const int recvcounts[], const int rdispls[], const MPI::Datatype recvtypes[]) const{ const int comm_size = Get_size(); MPI_Datatype *const data_type_tbl = new MPI_Datatype [2*comm_size]; // This must be done because MPI::Datatype arrays cannot be // converted directly into MPI_Datatype arrays. for (int i_rank=0; i_rank < comm_size; i_rank++) { data_type_tbl[i_rank] = sendtypes[i_rank]; data_type_tbl[i_rank + comm_size] = recvtypes[i_rank]; } (void)MPI_Alltoallw(const_cast<void *>(sendbuf), const_cast<int *>(sendcounts), const_cast<int *>(sdispls), data_type_tbl, recvbuf, const_cast<int *>(recvcounts), const_cast<int *>(rdispls), &data_type_tbl[comm_size], mpi_comm); delete[] data_type_tbl;}inline voidMPI::Comm::Reduce(const void *sendbuf, void *recvbuf, int count, const MPI::Datatype & datatype, const MPI::Op& op, int root) const{ (void)MPI_Reduce(const_cast<void *>(sendbuf), recvbuf, count, datatype, op, root, mpi_comm);}inline voidMPI::Comm::Allreduce(const void *sendbuf, void *recvbuf, int count, const MPI::Datatype & datatype, const MPI::Op& op) const{ (void)MPI_Allreduce (const_cast<void *>(sendbuf), recvbuf, count, datatype, op, mpi_comm);}inline voidMPI::Comm::Reduce_scatter(const void *sendbuf, void *recvbuf, int recvcounts[], const MPI::Datatype & datatype, const MPI::Op& op) const{ (void)MPI_Reduce_scatter(const_cast<void *>(sendbuf), recvbuf, recvcounts, datatype, op, mpi_comm);}//// Process Creation and Managemnt//inline voidMPI::Comm::Disconnect(){ (void) MPI_Comm_disconnect(&mpi_comm);}inline MPI::IntercommMPI::Comm::Get_parent(){ MPI_Comm parent; MPI_Comm_get_parent(&parent); return parent;}inline MPI::IntercommMPI::Comm::Join(const int fd) { MPI_Comm newcomm; (void) MPI_Comm_join((int) fd, &newcomm); return newcomm;}//// External Interfaces//inline voidMPI::Comm::Get_name(char* comm_name, int& resultlen) const{ (void) MPI_Comm_get_name(mpi_comm, comm_name, &resultlen);}inline voidMPI::Comm::Set_name(const char* comm_name) { (void) MPI_Comm_set_name(mpi_comm, const_cast<char *>(comm_name));} ////Process Topologies//inline intMPI::Comm::Get_topology() const { int status; (void)MPI_Topo_test(mpi_comm, &status); return status;} //// Environmental Inquiry//inline voidMPI::Comm::Abort(int errorcode) { (void)MPI_Abort(mpi_comm, errorcode);}//// These C++ bindings are for MPI-2.// The MPI-1.2 functions called below are all// going to be deprecated and replaced in MPI-2.//inline MPI::ErrhandlerMPI::Comm::Get_errhandler() const{ return *my_errhandler;}inline MPI::ErrhandlerMPI::Comm::Create_errhandler(MPI::Comm::_MPI2CPP_ERRHANDLERFN_* function){ MPI_Errhandler errhandler; // $%%@#%# AIX/POE 2.3.0.0 makes us put in this cast here (void)MPI_Comm_create_errhandler((MPI_Handler_function*) ompi_mpi_cxx_comm_errhandler_intercept, &errhandler); MPI::Errhandler temp(errhandler); temp.comm_handler_fn = (void(*)(MPI::Comm&, int*, ...))function; return temp;}// 1) original Create_keyval that takes the first 2 arguments as C++// functionsinline intMPI::Comm::Create_keyval(MPI::Comm::Copy_attr_function* comm_copy_attr_fn, MPI::Comm::Delete_attr_function* comm_delete_attr_fn, void* extra_state){ // Back-end function does the heavy lifting return do_create_keyval(NULL, NULL, comm_copy_attr_fn, comm_delete_attr_fn, extra_state);}// 2) overload Create_keyval to take the first 2 arguments as C// functionsinline intMPI::Comm::Create_keyval(MPI_Comm_copy_attr_function* comm_copy_attr_fn, MPI_Comm_delete_attr_function* comm_delete_attr_fn, void* extra_state){ // Back-end function does the heavy lifting return do_create_keyval(comm_copy_attr_fn, comm_delete_attr_fn, NULL, NULL, extra_state);}// 3) overload Create_keyval to take the first 2 arguments as C++ & C// functionsinline intMPI::Comm::Create_keyval(MPI::Comm::Copy_attr_function* comm_copy_attr_fn, MPI_Comm_delete_attr_function* comm_delete_attr_fn, void* extra_state){ // Back-end function does the heavy lifting return do_create_keyval(NULL, comm_delete_attr_fn, comm_copy_attr_fn, NULL, extra_state);}// 4) overload Create_keyval to take the first 2 arguments as C & C++// functionsinline intMPI::Comm::Create_keyval(MPI_Comm_copy_attr_function* comm_copy_attr_fn, MPI::Comm::Delete_attr_function* comm_delete_attr_fn, void* extra_state){ // Back-end function does the heavy lifting return do_create_keyval(comm_copy_attr_fn, NULL, NULL, comm_delete_attr_fn, extra_state);}inline voidMPI::Comm::Free_keyval(int& comm_keyval){ (void) MPI_Keyval_free(&comm_keyval);}inline voidMPI::Comm::Set_attr(int comm_keyval, const void* attribute_val) const{ (void)MPI_Attr_put(mpi_comm, comm_keyval, (void*) attribute_val);}inline boolMPI::Comm::Get_attr(int comm_keyval, void* attribute_val) const{ int flag; (void)MPI_Attr_get(mpi_comm, comm_keyval, attribute_val, &flag); return OPAL_INT_TO_BOOL(flag);}inline voidMPI::Comm::Delete_attr(int comm_keyval){ (void)MPI_Attr_delete(mpi_comm, comm_keyval);}inline intMPI::Comm::NULL_COPY_FN(const MPI::Comm& oldcomm, int comm_keyval, void* extra_state, void* attribute_val_in, void* attribute_val_out, bool& flag){#if SIZEOF_BOOL != SIZEOF_INT int f = (int)flag; int ret; if (MPI_NULL_COPY_FN != 0) { // Portland pgCC 5.0-2 has a bug that we have to workaround here. // MPI_NULL_COPY_FN is actually a #define for ((MPI_Copy_function // *) 0). If we try to invoke it, such as: // ret = MPI_NULL_COPY_FN(...); // the preprocessor will resolve this to: // ret = ((MPI_Copy_function *) 0)(...); // which should be fine. But unfortunately, pgCC 5.0-2 makes this // into a real symbol that will refuse to link. The workaround is // to assign this into a temp variable and then invoke through the // function pointer. This shouldn't be necessary. :-( MPI_Copy_function *stupid_compiler = MPI_NULL_COPY_FN; ret = stupid_compiler(oldcomm, comm_keyval, extra_state, attribute_val_in, attribute_val_out, &f); flag = OPAL_INT_TO_BOOL(f); } else { ret = MPI_SUCCESS; flag = true; } return ret;#else if (MPI_NULL_COPY_FN != 0) { // See note above. MPI_Copy_function *stupid_compiler = MPI_NULL_COPY_FN; return stupid_compiler(oldcomm, comm_keyval, extra_state, attribute_val_in, attribute_val_out, (int*)&flag); } else return MPI_SUCCESS;#endif}inline intMPI::Comm::DUP_FN(const MPI::Comm& oldcomm, int comm_keyval, void* extra_state, void* attribute_val_in, void* attribute_val_out, bool& flag){#if SIZEOF_BOOL != SIZEOF_INT int f = (int)flag; int ret; ret = MPI_DUP_FN(oldcomm, comm_keyval, extra_state, attribute_val_in, attribute_val_out, &f); flag = OPAL_INT_TO_BOOL(f); return ret;#else return MPI_DUP_FN(oldcomm, comm_keyval, extra_state, attribute_val_in, attribute_val_out, (int*)&flag);#endif}inline intMPI::Comm::NULL_DELETE_FN(MPI::Comm& comm, int comm_keyval, void* attribute_val, void* extra_state){ if (MPI_NULL_DELETE_FN != 0) { // See note in MPI_NULL_COPY_FN. MPI_Delete_function *stupid_compiler = MPI_NULL_DELETE_FN; return stupid_compiler(comm, comm_keyval, attribute_val, extra_state); } else return MPI_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -