initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / Pstream / mpi / OPwrite.C
blob230a366ebdfa948a742d2b9ef95177ce8579a88a
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software; you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation; either version 2 of the License, or (at your
14     option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM; if not, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Description
26     Write primitive and binary block from OPstream
28 \*---------------------------------------------------------------------------*/
30 #include "mpi.h"
32 #include "OPstream.H"
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 // Outstanding non-blocking operations.
37 //! @cond fileScope
38 Foam::DynamicList<MPI_Request> OPstream_outstandingRequests_;
39 //! @endcond fileScope
41 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
43 Foam::OPstream::~OPstream()
45     if
46     (
47        !write
48         (
49             commsType_,
50             toProcNo_,
51             buf_.begin(),
52             bufPosition_
53         )
54     )
55     {
56         FatalErrorIn("OPstream::~OPstream()")
57             << "MPI_Bsend cannot send outgoing message"
58             << Foam::abort(FatalError);
59     }
63 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
65 bool Foam::OPstream::write
67     const commsTypes commsType,
68     const int toProcNo,
69     const char* buf,
70     const std::streamsize bufSize
73     bool transferFailed = true;
75     if (commsType == blocking)
76     {
77         transferFailed = MPI_Bsend
78         (
79             const_cast<char*>(buf),
80             bufSize,
81             MPI_PACKED,
82             procID(toProcNo),
83             msgType(),
84             MPI_COMM_WORLD
85         );
86     }
87     else if (commsType == scheduled)
88     {
89         transferFailed = MPI_Send
90         (
91             const_cast<char*>(buf),
92             bufSize,
93             MPI_PACKED,
94             procID(toProcNo),
95             msgType(),
96             MPI_COMM_WORLD
97         );
98     }
99     else if (commsType == nonBlocking)
100     {
101         MPI_Request request;
103         transferFailed = MPI_Isend
104         (
105             const_cast<char*>(buf),
106             bufSize,
107             MPI_PACKED,
108             procID(toProcNo),
109             msgType(),
110             MPI_COMM_WORLD,
111             &request
112         );
114         OPstream_outstandingRequests_.append(request);
115     }
116     else
117     {
118         FatalErrorIn
119         (
120             "OPstream::write"
121             "(const int fromProcNo, char* buf, std::streamsize bufSize)"
122         )   << "Unsupported communications type " << commsType
123             << Foam::abort(FatalError);
124     }
126     return !transferFailed;
130 void Foam::OPstream::waitRequests()
132     if (OPstream_outstandingRequests_.size())
133     {
134         if
135         (
136             MPI_Waitall
137             (
138                 OPstream_outstandingRequests_.size(),
139                 OPstream_outstandingRequests_.begin(),
140                 MPI_STATUSES_IGNORE
141             )
142         )
143         {
144             FatalErrorIn
145             (
146                 "OPstream::waitRequests()"
147             )   << "MPI_Waitall returned with error" << Foam::endl;
148         }
150         OPstream_outstandingRequests_.clear();
151     }
155 bool Foam::OPstream::finishedRequest(const label i)
157     if (i >= OPstream_outstandingRequests_.size())
158     {
159         FatalErrorIn
160         (
161             "OPstream::finishedRequest(const label)"
162         )   << "There are " << OPstream_outstandingRequests_.size()
163             << " outstanding send requests and you are asking for i=" << i
164             << nl
165             << "Maybe you are mixing blocking/non-blocking comms?"
166             << Foam::abort(FatalError);
167     }
169     int flag;
170     MPI_Test(&OPstream_outstandingRequests_[i], &flag, MPI_STATUS_IGNORE);
172     return flag != 0;
176 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
178 // ************************************************************************* //