| 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 |
|
|