10 #include <util/misc/Memory.h> 11 #include <ddMd/chemistry/Atom.h> 12 #include <ddMd/chemistry/Group.h> 13 #include <util/format/Int.h> 51 if (sendBufferBegin_) {
52 Memory::deallocate<char>(sendBufferBegin_, bufferCapacity_);
54 if (recvBufferBegin_) {
55 Memory::deallocate<char>(recvBufferBegin_, bufferCapacity_);
65 if (atomCapacity < 0) {
68 if (ghostCapacity < 0) {
80 isInitialized_ =
true;
90 read<int>(in,
"atomCapacity", atomCapacity_);
91 read<int>(in,
"ghostCapacity", ghostCapacity_);
94 if (atomCapacity_ < 0) {
97 if (ghostCapacity_ < 0) {
106 isInitialized_ =
true;
115 loadParameter<int>(ar,
"atomCapacity", atomCapacity_);
116 loadParameter<int>(ar,
"ghostCapacity", ghostCapacity_);
119 if (atomCapacity_ < 0) {
122 if (ghostCapacity_ < 0) {
131 isInitialized_ =
true;
140 ar << ghostCapacity_;
147 {
return atomCapacity_; }
153 {
return ghostCapacity_; }
159 {
return isInitialized_; }
169 void Buffer::allocate()
173 if (atomCapacity_ <= 0) {
176 if (ghostCapacity_ <= 0) {
177 UTIL_THROW(
"ghostCapacity_ must be positive");
187 if (atomDataSize > ghostDataSize) {
188 dataCapacity_ = atomDataSize;
191 dataCapacity_ = ghostDataSize;
196 bufferCapacity_ += dataCapacity_ + 4 *
sizeof(int);
199 Memory::allocate<char>(sendBufferBegin_, bufferCapacity_);
200 sendBufferEnd_ = sendBufferBegin_ + bufferCapacity_;
203 Memory::allocate<char>(recvBufferBegin_, bufferCapacity_);
204 recvBufferEnd_ = recvBufferBegin_ + bufferCapacity_;
206 recvPtr_ = recvBufferBegin_;
214 sendPtr_ = sendBufferBegin_;
225 if (sendSize_ != 0) {
226 UTIL_THROW(
"Error: previous send block not finalized");
233 sendType_ = sendType;
236 sendBlockBegin_ = sendPtr_;
239 int* sendBuffPtr = (
int *)sendPtr_;
241 sendPtr_ = (
char *)sendBuffPtr;
249 int sendBytes = (int)(sendPtr_ - sendBlockBegin_);
253 int* sendBuffPtr = (
int *)sendBlockBegin_;
254 *sendBuffPtr = sendSize_;
256 *sendBuffPtr = sendBytes;
258 *sendBuffPtr = sendType_;
260 *sendBuffPtr = (int) isComplete;
274 if (recvSize_ != 0) {
275 UTIL_THROW(
"Error: Previous receive block not completely unpacked");
279 recvBlockBegin_ = recvPtr_;
282 int* recvBuffPtr = (
int *)recvPtr_;
283 recvSize_ = *recvBuffPtr;
284 int recvBytes = *(recvBuffPtr + 1);
285 recvType_ = *(recvBuffPtr + 2);
286 bool isComplete = (bool) *(recvBuffPtr + 3);
289 recvBlockEnd_ = recvBlockBegin_ + recvBytes;
293 recvPtr_ = (
char *)recvBuffPtr;
303 if (recvSize_ != 0) {
304 UTIL_THROW(
"Error: Recv counter != 0 at end of block");
306 if (recvPtr_ != recvBlockEnd_) {
307 UTIL_THROW(
"Error: Inconsistent recv cursor at end of block");
322 MPI::Request request[2];
324 int myRank = comm.Get_rank();
325 int comm_size = comm.Get_size();
328 if (dest > comm_size - 1 || dest < 0) {
331 if (source > comm_size - 1 || source < 0) {
334 if (dest == myRank) {
335 UTIL_THROW(
"Destination and my rank are identical");
337 if (source == myRank) {
338 UTIL_THROW(
"Source and my rank are identical");
342 request[0] = comm.Irecv(recvBufferBegin_, bufferCapacity_ ,
343 MPI::CHAR, source, 5);
346 sendBytes = sendPtr_ - sendBufferBegin_;
347 request[1] = comm.Isend(sendBufferBegin_, sendBytes , MPI::CHAR, dest, 5);
351 recvPtr_ = recvBufferBegin_;
357 if (sendBytes > maxSendLocal_) {
358 maxSendLocal_ = sendBytes;
367 MPI::Request request;
369 int comm_size = comm.Get_size();
370 int myRank = comm.Get_rank();
373 if (dest > comm_size - 1 || dest < 0) {
376 if (dest == myRank) {
377 UTIL_THROW(
"Source and destination identical");
380 sendBytes = sendPtr_ - sendBufferBegin_;
381 request = comm.Isend(sendBufferBegin_, sendBytes, MPI::CHAR, dest, 5);
385 if (sendBytes > maxSendLocal_) {
386 maxSendLocal_ = sendBytes;
395 MPI::Request request;
396 int myRank = comm.Get_rank();
397 int comm_size = comm.Get_size();
400 if (source > comm_size - 1 || source < 0) {
403 if (source == myRank) {
404 UTIL_THROW(
"Source and destination identical");
407 request = comm.Irecv(recvBufferBegin_, bufferCapacity_,
408 MPI::CHAR, source, 5);
411 recvPtr_ = recvBufferBegin_;
419 int comm_size = comm.Get_size();
420 int myRank = comm.Get_rank();
421 if (source > comm_size - 1 || source < 0) {
426 if (myRank == source) {
427 sendBytes = sendPtr_ - sendBufferBegin_;
428 comm.Bcast(&sendBytes, 1, MPI::INT, source);
429 comm.Bcast(sendBufferBegin_, sendBytes, MPI::CHAR, source);
430 sendPtr_ = sendBufferBegin_;
433 comm.Bcast(&sendBytes, 1, MPI::INT, source);
434 comm.Bcast(recvBufferBegin_, sendBytes, MPI::CHAR, source);
435 recvPtr_ = recvBufferBegin_;
438 if (sendBytes > maxSendLocal_) {
439 maxSendLocal_ = sendBytes;
456 comm.Allreduce(&maxSendLocal_, &globalSendMax, 1, MPI::INT, MPI::MAX);
457 maxSend_.
set(globalSendMax);
459 maxSend_.
set(maxSendLocal_);
479 out <<
"Buffer" << std::endl;
480 out <<
"sendBytes: max, capacity " 482 <<
Int(bufferCapacity_, 10)
490 {
return sendSize_; }
496 {
return recvSize_; }
502 {
return (bufferCapacity_ > 0); }
bool beginRecvBlock()
Begin to receive a block from the recv buffer.
void sendRecv(MPI::Intracomm &comm, int source, int dest)
Receive from processor send and send to processor recv.
int ghostCapacity() const
Maximum number of ghost atoms for which space is available.
void readParameters(std::istream &in)
Read capacity and allocate buffers.
void outputStatistics(std::ostream &out)
Output statistics.
void set(const T &value)
Set the value and mark as set.
void beginSendBlock(int sendType)
Initialize a data block.
static int packedAtomSize()
Return max size of an atom packed for exchange, in bytes.
Parallel domain decomposition (DD) MD simulation.
void allocate(int atomCapacity, int ghostCapacity)
Allocate send and recv buffers.
Saving / output archive for binary ostream.
const T & value() const
Return value (if set).
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
virtual void save(Serializable::OArchive &ar)
Save internal state to an archive.
Utility classes for scientific computation.
Wrapper for an int, for formatted ostream output.
int recvSize() const
Number of unread items left in current recv block.
void unset()
Unset the value (mark as unknown).
void send(MPI::Intracomm &comm, int dest)
Send a complete buffer.
virtual void computeStatistics(MPI::Intracomm &comm)
Compute statistics (reduce from all processors).
void recv(MPI::Intracomm &comm, int source)
Receive a buffer.
Saving archive for binary istream.
void endSendBlock(bool isComplete=true)
Finalize a block in the send buffer.
void setClassName(const char *className)
Set class name string.
bool isInitialized() const
Has this Buffer been initialized?
void bcast(MPI::Intracomm &comm, int source)
Broadcast a buffer.
static int packedGhostSize()
Return size of ghost atom packed for communication, in bytes.
An object that can read multiple parameters from file.
void clearSendBuffer()
Clear the send buffer.
void endRecvBlock()
Finish processing a block in the recv buffer.
int atomCapacity() const
Maximum number of atoms for which space is available.
bool isAllocated() const
Has memory been allocated for this Buffer?
void clearStatistics()
Clear any accumulated usage statistics.
virtual ~Buffer()
Destructor.
int sendSize() const
Number of items in current send block.
virtual void loadParameters(Serializable::IArchive &ar)
Load internal state from an archive.