porting changes
[OpenFOAM-1.5.x.git] / src / Pstream / mpi / OPwrite.C
blob86d9c998ab6360bb37f5ec08ea2ecdc7ced1ecdf
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 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() > 0)
133     {
134         List<MPI_Status> status(OPstream_outstandingRequests_.size());
136         if
137         (
138             MPI_Waitall
139             (
140                 OPstream_outstandingRequests_.size(),
141                 OPstream_outstandingRequests_.begin(),
142                 status.begin()
143             )
144         )
145         {
146             FatalErrorIn
147             (
148                 "OPstream::waitRequests()"
149             )   << "MPI_Waitall returned with error" << Foam::endl;
150         }
152         OPstream_outstandingRequests_.clear();
153     }
157 bool Foam::OPstream::finishedRequest(const label i)
159     if (i >= OPstream_outstandingRequests_.size())
160     {
161         FatalErrorIn
162         (
163             "OPstream::finishedRequest(const label)"
164         )   << "There are " << OPstream_outstandingRequests_.size()
165             << " outstanding send requests and you are asking for i=" << i
166             << nl
167             << "Maybe you are mixing blocking/non-blocking comms?"
168             << Foam::abort(FatalError);
169     }
171     int flag;
172     MPI_Status status;
174     MPI_Test(&OPstream_outstandingRequests_[i], &flag, &status);
176     return flag != 0;
180 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
182 // ************************************************************************* //