Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "mpi.h"
00030
00031 #include "mpiOPstreamImpl.H"
00032 #include "mpiPstreamGlobals.H"
00033 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00034 #include <OpenFOAM/Pstream.H>
00035
00036
00037
00038 namespace Foam
00039 {
00040
00041 defineTypeNameAndDebug(mpiOPstreamImpl, 0);
00042 addToRunTimeSelectionTable(OPstreamImpl, mpiOPstreamImpl, dictionary);
00043
00044 }
00045
00046
00047
00048 void Foam::mpiOPstreamImpl::flush
00049 (
00050 const PstreamImpl::commsTypes commsType,
00051 const int toProcNo,
00052 const char* buf,
00053 const int bufPosition
00054 )
00055 {
00056 if
00057 (
00058 !write
00059 (
00060 commsType,
00061 toProcNo,
00062 buf,
00063 bufPosition
00064 )
00065 )
00066 {
00067 FatalErrorIn("mpiOPstreamImpl::flush(const PstreamImpl::commsTypes, "
00068 "const int, const char*, const int)")
00069 << "MPI_Bsend cannot send outgoing message"
00070 << Foam::abort(FatalError);
00071 }
00072 }
00073
00074
00075
00076 bool Foam::mpiOPstreamImpl::write
00077 (
00078 const PstreamImpl::commsTypes commsType,
00079 const int toProcNo,
00080 const char* buf,
00081 const std::streamsize bufSize
00082 )
00083 {
00084 bool transferFailed = true;
00085
00086 if (commsType == PstreamImpl::blocking)
00087 {
00088 transferFailed = MPI_Bsend
00089 (
00090 const_cast<char*>(buf),
00091 bufSize,
00092 MPI_PACKED,
00093 Pstream::procID(toProcNo),
00094 Pstream::msgType(),
00095 MPI_COMM_WORLD
00096 );
00097 }
00098 else if (commsType == PstreamImpl::scheduled)
00099 {
00100 transferFailed = MPI_Send
00101 (
00102 const_cast<char*>(buf),
00103 bufSize,
00104 MPI_PACKED,
00105 Pstream::procID(toProcNo),
00106 Pstream::msgType(),
00107 MPI_COMM_WORLD
00108 );
00109 }
00110 else if (commsType == PstreamImpl::nonBlocking)
00111 {
00112 MPI_Request request;
00113
00114 transferFailed = MPI_Isend
00115 (
00116 const_cast<char*>(buf),
00117 bufSize,
00118 MPI_PACKED,
00119 Pstream::procID(toProcNo),
00120 Pstream::msgType(),
00121 MPI_COMM_WORLD,
00122 &request
00123 );
00124
00125 PstreamGlobals::OPstream_outstandingRequests_.append(request);
00126 }
00127 else
00128 {
00129 FatalErrorIn
00130 (
00131 "mpiOPstreamImpl::write"
00132 "(const int fromProcNo, char* buf, std::streamsize bufSize)"
00133 ) << "Unsupported communications type " << commsType
00134 << Foam::abort(FatalError);
00135 }
00136
00137 return !transferFailed;
00138 }
00139
00140
00141 void Foam::mpiOPstreamImpl::waitRequests()
00142 {
00143 if (PstreamGlobals::OPstream_outstandingRequests_.size())
00144 {
00145 if
00146 (
00147 MPI_Waitall
00148 (
00149 PstreamGlobals::OPstream_outstandingRequests_.size(),
00150 PstreamGlobals::OPstream_outstandingRequests_.begin(),
00151 MPI_STATUSES_IGNORE
00152 )
00153 )
00154 {
00155 FatalErrorIn
00156 (
00157 "mpiOPstreamImpl::waitRequests()"
00158 ) << "MPI_Waitall returned with error" << Foam::endl;
00159 }
00160
00161 PstreamGlobals::OPstream_outstandingRequests_.clear();
00162 }
00163 }
00164
00165
00166 bool Foam::mpiOPstreamImpl::finishedRequest(const label i)
00167 {
00168 if (i >= PstreamGlobals::OPstream_outstandingRequests_.size())
00169 {
00170 FatalErrorIn
00171 (
00172 "OPstream::finishedRequest(const label)"
00173 "mpiOPstreamImpl::finishedRequest(const label)"
00174 ) << "There are "
00175 << PstreamGlobals::OPstream_outstandingRequests_.size()
00176 << " outstanding send requests and you are asking for i=" << i
00177 << nl
00178 << "Maybe you are mixing blocking/non-blocking comms?"
00179 << Foam::abort(FatalError);
00180 }
00181
00182 int flag;
00183 MPI_Test
00184 (
00185 &PstreamGlobals::OPstream_outstandingRequests_[i],
00186 &flag,
00187 MPI_STATUS_IGNORE
00188 );
00189
00190 return flag != 0;
00191 }
00192
00193
00194
00195
00196