33 |
|
#ifndef IO_IFSTRSTREAM_HPP |
34 |
|
#define IO_IFSTRSTREAM_HPP |
35 |
|
|
36 |
+ |
#include <cstring> |
37 |
|
#include <fstream> |
38 |
|
#include <sstream> |
39 |
|
|
40 |
+ |
#ifdef IS_MPI |
41 |
+ |
#include <mpi.h> |
42 |
+ |
#endif |
43 |
+ |
|
44 |
|
namespace oopse { |
45 |
|
using namespace std; |
46 |
|
/** |
55 |
|
* char buffer[MAXLEN]; |
56 |
|
* ifstrstream in; |
57 |
|
* in.open("Shapes.frc"); |
58 |
< |
* if (in.is_open) { |
58 |
> |
* if (in.is_open()) { |
59 |
|
* in.getline(buffer, MAXLEN); |
60 |
|
* } |
61 |
|
* in.close(); |
107 |
|
/** |
108 |
|
* Explicit constructor |
109 |
|
* @filename String containing the name of the file to be opened |
110 |
< |
* @mode Flags describing the requested i/o mode for the file, default value is ios_base::in |
110 |
> |
* @mode Flags describing the requested i/o mode for the file, default value is ios_base::in |
111 |
> |
* @checkFilename Flags indicating checking the file name in parallel |
112 |
|
*/ |
113 |
< |
explicit basic_ifstrstream(const char* filename, ios_base::openmode mode = ios_base::in) |
113 |
> |
explicit basic_ifstrstream(const char* filename, ios_base::openmode mode = ios_base::in, bool checkFilename = false) |
114 |
|
: basic_ios<_CharT, _Traits>(), basic_istream<_CharT, _Traits>(0), |
115 |
|
internalBuf_(NULL), isRead(false) { |
116 |
|
|
117 |
< |
isRead = internalOpen(filename, mode | ios_base::in); |
117 |
> |
isRead = internalOpen(filename, mode | ios_base::in, checkFilename); |
118 |
|
} |
119 |
|
|
120 |
|
/** |
121 |
< |
* |
121 |
> |
* virtual destructor will close the file(in single mode) and clear the stream buffer |
122 |
|
*/ |
123 |
|
~basic_ifstrstream(){ |
124 |
|
close(); |
132 |
|
* brocasting, every nodes fall back to stringstream (parallel mode). |
133 |
|
* @filename String containing the name of the file to be opened |
134 |
|
* @mode Flags describing the requested i/o mode for the file |
135 |
+ |
* @checkFilename Flags indicating checking the file name in parallel |
136 |
|
*/ |
137 |
< |
void open(const char* filename, ios_base::openmode mode = ios_base::in){ |
137 |
> |
void open(const char* filename, ios_base::openmode mode = ios_base::in, bool checkFilename = false){ |
138 |
|
|
139 |
|
if (!isRead ) { |
140 |
< |
isRead = internalOpen(); |
140 |
> |
isRead = internalOpen(filename, mode, checkFilename); |
141 |
|
} |
142 |
|
} |
143 |
|
|
188 |
|
* @mode Flags describing the requested i/o mode for the file |
189 |
|
* @todo use try - catch syntax to make the program more readable |
190 |
|
*/ |
191 |
< |
bool internalOpen(const char* filename, ios_base::openmode mode){ |
191 |
> |
bool internalOpen(const char* filename, ios_base::openmode mode, bool checkFilename){ |
192 |
|
|
193 |
|
#ifdef IS_MPI |
194 |
|
int commStatus; |
197 |
|
int filenameLen; |
198 |
|
int diffFilename; |
199 |
|
int error; |
200 |
+ |
int myRank; |
201 |
+ |
int masterNode; |
202 |
|
|
203 |
< |
if (worldRank == masterNode) { |
203 |
> |
commStatus = MPI_Comm_rank(MPI_COMM_WORLD, &myRank); |
204 |
> |
masterNode = 0; |
205 |
> |
|
206 |
> |
if (myRank == masterNode) { |
207 |
|
|
208 |
< |
//check the filename is the same |
197 |
< |
filenameLen = strlen(filename); |
198 |
< |
commStatus = MPI_Bcast(filenameLen, 1, MPI_INT, masterNode, MPI_COMM_WORLD); |
199 |
< |
commStatus = MPI_Bcast(filename, filenameLen, MPI_CHAR, masterNode, MPI_COMM_WORLD); |
208 |
> |
if (checkFilename) { |
209 |
|
|
210 |
< |
diffFilename = 0; |
211 |
< |
commStatus = MPI_Allreduce(sameFilename, error, 1, MPI_INT, MPI_COMM_WORLD); |
210 |
> |
//check the filename is the same |
211 |
> |
filenameLen = strlen(filename); |
212 |
> |
commStatus = MPI_Bcast(filenameLen, 1, MPI_INT, masterNode, MPI_COMM_WORLD); |
213 |
> |
commStatus = MPI_Bcast(filename, filenameLen, MPI_CHAR, masterNode, MPI_COMM_WORLD); |
214 |
|
|
215 |
< |
//if file names are different just return false |
216 |
< |
if (error > 0) |
215 |
> |
diffFilename = 0; |
216 |
> |
commStatus = MPI_Allreduce(diffFilename, error, 1, MPI_INT, MPI_COMM_WORLD); |
217 |
> |
|
218 |
> |
//if file names are different just return false |
219 |
> |
if (error > 0) |
220 |
|
return false; |
221 |
+ |
} |
222 |
|
|
223 |
< |
ifstream fin(filename, mod); |
223 |
> |
ifstream fin(filename, mode); |
224 |
|
basic_stringbuf<_CharT, _Traits, _Alloc>* sbuf; |
225 |
|
|
226 |
|
if (fin.is_open()) { |
271 |
|
|
272 |
|
} else{ |
273 |
|
//check file name |
274 |
< |
commStatus = MPI_Bcast(filenameLen, 1, MPI_INT, masterNode, MPI_COMM_WORLD); |
274 |
> |
if (checkFilename) { |
275 |
> |
commStatus = MPI_Bcast(filenameLen, 1, MPI_INT, masterNode, MPI_COMM_WORLD); |
276 |
|
|
277 |
< |
char * masterFilename = new char[filenameLen]; |
278 |
< |
commStatus = MPI_Bcast(masterFilename, filenameLen, MPI_CHAR, masterNode, MPI_COMM_WORLD); |
279 |
< |
|
280 |
< |
if( strcmp(masterFilename, filename) == 0) |
281 |
< |
diffFilename = 0; |
282 |
< |
else |
283 |
< |
diffFilename = 1; |
277 |
> |
char * masterFilename = new char[filenameLen]; |
278 |
> |
commStatus = MPI_Bcast(masterFilename, filenameLen, MPI_CHAR, masterNode, MPI_COMM_WORLD); |
279 |
> |
|
280 |
> |
if( strcmp(masterFilename, filename) == 0) |
281 |
> |
diffFilename = 0; |
282 |
> |
else |
283 |
> |
diffFilename = 1; |
284 |
|
|
285 |
< |
delete masterFilename; |
286 |
< |
|
287 |
< |
commStatus = MPI_Allreduce(sameFilename, error, 1, MPI_INT, MPI_COMM_WORLD); |
285 |
> |
delete masterFilename; |
286 |
> |
|
287 |
> |
commStatus = MPI_Allreduce(diffFilename, error, 1, MPI_INT, MPI_COMM_WORLD); |
288 |
|
|
289 |
< |
if (error > 0) |
290 |
< |
return false; |
291 |
< |
|
289 |
> |
if (error > 0) |
290 |
> |
return false; |
291 |
> |
} |
292 |
|
//get file size |
293 |
|
commStatus = MPI_Bcast(&fileSize, 1, MPI_LONG, masterNode, MPI_COMM_WORLD); |
294 |
|
|