Simpatico  v1.10
Buffer.h
1 #ifndef DDMD_BUFFER_H
2 #define DDMD_BUFFER_H
3 
4 /*
5 * Simpatico - Simulation Package for Polymeric and Molecular Liquids
6 *
7 * Copyright 2010 - 2017, The Regents of the University of Minnesota
8 * Distributed under the terms of the GNU General Public License.
9 */
10 
11 #include <util/param/ParamComposite.h> // base class
12 #include <util/misc/Setable.h> // member
13 #include <util/global.h>
14 
15 namespace DdMd
16 {
17 
18  using namespace Util;
19 
20  template <int N> class Group;
21 
217  class Buffer: public ParamComposite
218  {
219 
220  public:
221 
225  enum BlockDataType {NONE, ATOM, GHOST, UPDATE, FORCE,
226  GROUP2, GROUP3, GROUP4, SPECIAL};
227 
231  Buffer();
232 
236  virtual ~Buffer();
237 
243  void readParameters(std::istream& in);
244 
250  virtual void loadParameters(Serializable::IArchive &ar);
251 
257  virtual void save(Serializable::OArchive &ar);
258 
270  void allocate(int atomCapacity, int ghostCapacity);
271 
274 
278  void clearSendBuffer();
279 
287  void beginSendBlock(int sendType);
288 
300  template <typename T>
301  void pack(const T& data);
302 
306  void incrementSendSize();
307 
322  void endSendBlock(bool isComplete = true);
323 
327 
337  bool beginRecvBlock();
338 
350  template <typename T>
351  void unpack(T& data);
352 
356  void decrementRecvSize();
357 
366  void endRecvBlock();
367 
369  #ifdef UTIL_MPI
370 
372 
387  void sendRecv(MPI::Intracomm& comm, int source, int dest);
388 
398  void send(MPI::Intracomm& comm, int dest);
399 
406  void recv(MPI::Intracomm& comm, int source);
407 
414  void bcast(MPI::Intracomm& comm, int source);
415 
417  #endif
418 
420 
428  #ifdef UTIL_MPI
429  virtual void computeStatistics(MPI::Intracomm& comm);
430  #else
431  virtual void computeStatistics();
432  #endif
433 
441  void outputStatistics(std::ostream& out);
442 
446  void clearStatistics();
447 
449 
451 
455  int sendSize() const;
456 
460  int recvSize() const;
461 
465  bool isAllocated() const;
466 
470  bool isInitialized() const;
471 
475  int atomCapacity() const;
476 
480  int ghostCapacity() const;
481 
485  template <int N>
486  int groupCapacity() const;
487 
489 
490  private:
491 
493  char* sendBufferBegin_;
494 
496  char* recvBufferBegin_;
497 
499  char* sendBufferEnd_;
500 
502  char* recvBufferEnd_;
503 
505  char* sendBlockBegin_;
506 
508  char* recvBlockBegin_;
509 
511  char* recvBlockEnd_;
512 
514  char* sendPtr_;
515 
517  char* recvPtr_;
518 
520  int bufferCapacity_;
521 
523  int dataCapacity_;
524 
526  int sendSize_;
527 
529  int recvSize_;
530 
532  int sendType_;
533 
535  int recvType_;
536 
538  int atomCapacity_;
539 
541  int ghostCapacity_;
542 
544  int maxSendLocal_;
545 
547  Setable<int> maxSend_;
548 
550  bool isInitialized_;
551 
552  /*
553  * Allocate send and recv buffers, using preset capacities.
554  */
555  void allocate();
556 
557  };
558 
559  /*
560  * Pack an object of type T into send buffer.
561  */
562  template <typename T>
563  inline void Buffer::pack(const T& data)
564  {
565  if (sendPtr_ + sizeof(data) > sendBufferEnd_) {
566  UTIL_THROW("Attempted write past end of send buffer");
567  }
568  T* ptr = (T *)sendPtr_;
569  *ptr = data;
570  ++ptr;
571  sendPtr_ = (char *)ptr;
572  }
573 
574  /*
575  * Unpack an object of type T from recvBuffer.
576  */
577  template <typename T>
578  inline void Buffer::unpack(T& data)
579  {
580  if (recvPtr_ + sizeof(data) > recvBufferEnd_) {
581  UTIL_THROW("Attempted read past end of recv buffer");
582  }
583  T* ptr = (T *)recvPtr_;
584  data = *ptr;
585  ++ptr;
586  recvPtr_ = (char *)ptr;
587  }
588 
589  /*
590  * Maximum number of Group<N> objects that can fit buffer.
591  */
592  template <int N>
594  {
595  if (dataCapacity_ <= 0) {
596  UTIL_THROW("Buffer not allocated");
597  }
598  return (dataCapacity_/Group<N>::packedSize());
599  }
600 
601  /*
602  * Increment sendSize counter after packing an item.
603  */
605  { ++sendSize_; }
606 
607  /*
608  * Decrement sendSize counter after receiving an item.
609  */
611  { --recvSize_; }
612 
613 }
614 #endif
int groupCapacity() const
Maximum number of group<N> objects for which space is available.
Definition: Buffer.h:593
void recv(MPI::Comm &comm, T &data, int source, int tag)
Receive a single T value.
Definition: MpiSendRecv.h:116
File containing preprocessor macros for error handling.
Parallel domain decomposition (DD) MD simulation.
void send(MPI::Comm &comm, T &data, int dest, int tag)
Send a single T value.
Definition: MpiSendRecv.h:97
void unpack(T &data)
Function template unpacking one variable from the receive buffer.
Definition: Buffer.h:578
BlockDataType
Enumeration of types of data to be sent in blocks.
Definition: Buffer.h:225
Saving / output archive for binary ostream.
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
void bcast(MPI::Intracomm &comm, T &data, int root)
Broadcast a single T value.
Definition: MpiSendRecv.h:134
void incrementSendSize()
Increment sendSize counter after packing an item (an Atom or Group).
Definition: Buffer.h:604
Utility classes for scientific computation.
Definition: accumulators.mod:1
Buffer for interprocessor communication.
Definition: Buffer.h:217
Saving archive for binary istream.
void decrementRecvSize()
Decrement recvSize counter after completely unpacking an item.
Definition: Buffer.h:610
void pack(const T &data)
Function template for packing one variable into the send buffer.
Definition: Buffer.h:563
A group of covalently interacting atoms.
An object that can read multiple parameters from file.