11#ifndef _tipsy_H
22#define _tipsy_H
33
4+ // For MPI awareness
5+ //
6+ #include < localmpi.H>
7+
8+
49// Forward declare PR::Tipsy so it can friend TipsyFile
510//
611namespace PR {
@@ -157,24 +162,59 @@ namespace TipsyReader
157162 return header.nbodies ;
158163 }
159164
165+ // ! Generate stream position for parallel read
166+ // ! \param nsize The number of particles to read
167+ // ! \param ssize The size of each particle structure in bytes
168+ unsigned xdr_psize (int nsize, int ssize)
169+ {
170+ // Number of particles per process
171+ int psize = nsize/numprocs;
172+
173+ // Get current stream position
174+ auto pos = xdr_getpos (&xdrs);
175+
176+ // Move the stream position to the start of this process' data
177+ pos += psize * myid * ssize;
178+ if (xdr_setpos (&xdrs, pos) == 0 ) {
179+ throw std::runtime_error (" TipsyFile: xdr_setpos failed" );
180+ }
181+
182+ // If this is the last process, read the remainder
183+ if (myid == numprocs-1 ) psize = nsize - (numprocs-1 )*psize;
184+
185+ return psize;
186+ }
187+
160188 int xdr_read ()
161189 {
162190 int N=0 ;
163191
164192 if (header.nsph != 0 ) {
165- gas_particles.resize (header.nsph );
193+ // Get the number of gas particles for this process
194+ auto psize = xdr_psize (header.nsph , sizeof (gas_particle));
195+
196+ // Do the read
197+ gas_particles.resize (psize);
166198 read_gas ();
167199 N++;
168200 }
169201
170202 if (header.ndark != 0 ) {
171- dark_particles.resize (header.ndark );
203+ // Get the number of dark particles for this process
204+ auto psize = xdr_psize (header.ndark , sizeof (dark_particle));
205+
206+ // Do the read
207+ dark_particles.resize (psize);
172208 read_dark ();
173209 N++;
174210 }
175211
176212 if (header.nstar != 0 ) {
177- star_particles.resize (header.nstar );
213+ // Get the number of star particles for this process
214+ auto psize = xdr_psize (header.nstar , sizeof (star_particle));
215+
216+ // Do the read
217+ star_particles.resize (psize);
178218 read_star ();
179219 N++;
180220 }
@@ -186,7 +226,7 @@ namespace TipsyReader
186226 {
187227 if (sizeof (Real) == sizeof (float )) {
188228 xdr_vector (&xdrs, (char *) &gas_particles[0 ],
189- header. nsph *(sizeof (gas_particle)/sizeof (Real)),
229+ gas_particles. size () *(sizeof (gas_particle)/sizeof (Real)),
190230 sizeof (Real), (xdrproc_t ) xdr_float);
191231 }
192232 }
@@ -195,7 +235,7 @@ namespace TipsyReader
195235 {
196236 if (sizeof (Real) == sizeof (float )) {
197237 xdr_vector (&xdrs, (char *) &dark_particles[0 ],
198- header. ndark *(sizeof (dark_particle)/sizeof (Real)),
238+ dark_particles. size () *(sizeof (dark_particle)/sizeof (Real)),
199239 sizeof (Real), (xdrproc_t ) xdr_float);
200240 }
201241 }
@@ -204,7 +244,7 @@ namespace TipsyReader
204244 {
205245 if (sizeof (Real) == sizeof (float )) {
206246 xdr_vector (&xdrs, (char *) &star_particles[0 ],
207- header. nstar *(sizeof (star_particle)/sizeof (Real)),
247+ star_particles. size () *(sizeof (star_particle)/sizeof (Real)),
208248 sizeof (Real), (xdrproc_t ) xdr_float);
209249 }
210250 }
@@ -247,8 +287,9 @@ namespace TipsyReader
247287 try {
248288 input.read ((char *)&header, sizeof (header));
249289 } catch (std::exception& e) {
250- std::cerr << " TipsyFile native_header error: " << e.what () << std::endl;
251- throw ;
290+ std::ostringstream s;
291+ s << " TipsyFile native error reading header: " << e.what ();
292+ throw std::runtime_error (s.str ());
252293 }
253294 return 1 ;
254295 }
@@ -259,9 +300,10 @@ namespace TipsyReader
259300 input.open (filename);
260301 input.exceptions (ifstream::eofbit | ifstream::failbit | ifstream::badbit);
261302 } catch (std::exception& e) {
262- std::cerr << " TipsyFile native error opening file <" << filename << " >, "
263- << e.what () << std::endl;
264- throw ;
303+ std::ostringstream s;
304+ s << " TipsyFile native error opening file <" << filename << " >: "
305+ << e.what ();
306+ throw std::runtime_error (s.str ());
265307 }
266308
267309 if (native_header () != 1 ) {
@@ -271,24 +313,60 @@ namespace TipsyReader
271313 return header.nbodies ;
272314 }
273315
316+ // ! Generate stream position for parallel read
317+ // ! \param nsize The number of particles to read
318+ // ! \param ssize The size of each particle structure in bytes
319+ unsigned ios_psize (int nsize, int ssize)
320+ {
321+ // Number of particles per process
322+ int psize = nsize/numprocs;
323+
324+ // Get current stream position
325+ auto pos = input.tellg ();
326+
327+ // Move the stream position to the start of this process' data
328+ pos += psize * myid * ssize;
329+ input.seekg (pos);
330+ if (input.fail ()) {
331+ throw std::runtime_error (" TipsyFile: seekg failed" );
332+ }
333+
334+ // If this is the last process, read the remainder
335+ if (myid == numprocs-1 ) psize = nsize - (numprocs-1 )*psize;
336+
337+ return psize;
338+ }
339+
274340 int native_read ()
275341 {
276342 int N=0 ;
277343
278344 if (header.nsph != 0 ) {
279- gas_particles.resize (header.nsph );
345+ // Get the number of gas particles for this process
346+ auto psize = ios_psize (header.nsph , sizeof (gas_particle));
347+
348+ // Do the read
349+ gas_particles.resize (psize);
280350 read_gas ();
281351 N++;
282352 }
283353
284354 if (header.ndark != 0 ) {
285- dark_particles.resize (header.ndark );
355+ // Get the number of dark particles for this process
356+ auto psize = ios_psize (header.ndark , sizeof (dark_particle));
357+
358+ // Do the read
359+ dark_particles.resize (psize);
286360 read_dark ();
287361 N++;
288362 }
289363
290364 if (header.nstar != 0 ) {
291- star_particles.resize (header.nstar );
365+ // Get the number of star particles for this process
366+ int psize = ios_psize (header.nstar , sizeof (star_particle));
367+
368+ // Do the read
369+ star_particles.resize (psize);
292370 read_star ();
293371 N++;
294372 }
@@ -300,38 +378,38 @@ namespace TipsyReader
300378 {
301379 try {
302380 input.read ((char *) &gas_particles[0 ],
303- header. nsph *sizeof (gas_particle));
381+ gas_particles. size () *sizeof (gas_particle));
304382 }
305383 catch (std::exception& e) {
306- std::cerr << " TipsyFile native error reading sph particles: "
307- << e.what () << std::endl ;
308- throw ;
384+ std::ostringstream s;
385+ s << " TipsyFile native error reading gas particles: " << e.what ();
386+ throw std::runtime_error (s. str ()) ;
309387 }
310388 }
311389
312390 void read_dark ()
313391 {
314392 try {
315393 input.read ((char *) &dark_particles[0 ],
316- header. ndark *sizeof (dark_particle));
394+ dark_particles. size () *sizeof (dark_particle));
317395 }
318396 catch (std::exception& e) {
319- std::cerr << " TipsyFile native error reading dark particles: "
320- << e.what () << std::endl ;
321- throw ;
397+ std::ostringstream s;
398+ s << " TipsyFile native error reading dark particles: " << e.what ();
399+ throw std::runtime_error (s. str ()) ;
322400 }
323401 }
324402
325403 void read_star ()
326404 {
327405 try {
328406 input.read ((char *) &star_particles[0 ],
329- header. nstar *sizeof (star_particle));
407+ star_particles. size () *sizeof (star_particle));
330408 }
331409 catch (std::exception& e) {
332- std::cerr << " TipsyFile native error reading star particles: "
333- << e.what () << std::endl ;
334- throw ;
410+ std::ostringstream s;
411+ s << " TipsyFile native error reading star particles: " << e.what ();
412+ throw std::runtime_error (s. str ()) ;
335413 }
336414 }
337415
0 commit comments