MPIInputBuffer.h

Go to the documentation of this file.
00001 #ifndef MPIINPUTBUFFER_H_
00002 #define MPIINPUTBUFFER_H_
00003 
00004 #include <mpi.h>
00005 
00006 #include <vector>
00007 #include <numeric>
00008 
00009 using std::vector;
00010 using std::accumulate;
00011 using std::partial_sum;
00012 
00013 #include <iostream>
00014 
00015 using std::cerr;
00016 using std::cout;
00017 using std::endl;
00018 
00019 
00020 #include "MPIInputSpikeBuffer.h"
00021 #include "MPIBufferSlicer.h"
00022 #include "MPIExchangeBlocksInfo.h"
00023 
00024 class MPIInputBufferVector;
00025 
00026 class MPIInputBuffer
00027 {
00028 public:
00029     MPIInputBuffer(int nEngines = 1);
00030     virtual ~MPIInputBuffer();
00031 
00032     double *getAnalogBuffer()
00033     {
00034         return (double *)analog_buf;
00035     }
00036 
00037     unsigned & getAnalogMsgCounter(engineid_t eng = 0)
00038     {
00039         return analogMsgCounters[eng];
00040     }
00041 
00042     void calculateTotalAnalogMsgCounter()
00043     {
00044         totalAnalogMsgCounter = accumulate(analogMsgCounters.begin(), analogMsgCounters.end(), 0);
00045         partial_sum(analogMsgCounters.begin(), analogMsgCounters.end(), analogMsgCounters.begin());
00046     }
00047 
00048     void startNewMPIExchange();
00049 
00050     bool hasNextBufferSlice();
00051 
00052     MPIMessageSpec & prepareNextBufferSlice();
00053 
00054     void setHasNewContent(bool contentIndicator)
00055     {
00056         mpiInputSpikeBuffer.setHasNewContent(contentIndicator);
00057     };
00058 
00059     // These methods are for testing purposes only
00060     int getMixedCounts(int idx) const
00061     {
00062         return mixedCounts[idx];
00063     }
00064 
00065     int getMixedDispl(int idx) const
00066     {
00067         return mixedDisplacements[idx];
00068     }
00069     
00070     MPIInputSpikeBuffer<> & spikeBuf()
00071     {
00072         return mpiInputSpikeBuffer;     
00073     }
00074     
00075     MPIMessageSpec::ContentType_t & getContentType()
00076     {
00077         return currentMsgInfo.content_type;     
00078     }
00079 
00080 protected:
00081     bool initialized;
00082 
00083     void *spike_buf;
00084 
00085     void *analog_buf;
00086     
00087     MPI::Datatype mixedMPIDataType;
00088 
00089     MPI::Datatype spikingMPIDatatype;
00090 
00091     MPI::Datatype analogMPIDatatype;
00092 
00093     MPIMessageSpec currentMsgInfo;
00094     
00095     void *baseBufferPtr;
00096     
00097     size_t spike_buffer_size_elements;
00098 
00099     vector<unsigned> analogMsgCounters;
00100 
00101     unsigned totalAnalogMsgCounter;
00102     
00103     int mixedMsgAbsoluteDisplacement;
00104 
00105     void initialize(MPIMessageSpec msgSpec, size_t spikeBufferSize, size_t maxMPIMsgSize,
00106                     void *baseBufferPtr, void *analogBuffer, void *spikeBuffer);
00107 
00108     MPIInputSpikeBuffer<> mpiInputSpikeBuffer;
00109 
00110     MPIBufferSlicer slicer;
00111     
00112     // counts for the mixed type, used only for testing.
00113     int mixedCounts[2];
00114 
00115     // displacements for the mixed type, used only for testing.
00116     MPI::Aint mixedDisplacements[2];
00117     
00118     friend class MPIInputBufferVector;
00119 
00120 };
00121 
00122 
00124 /*
00125  * Vector of all mpi input buffers. 
00126  * Simplifies the initialization procedure 
00127  * by performing memory allocation and setup of buffers. 
00128  * 
00129  */
00130 
00131 class MPIInputBufferVector
00132 {
00133 public:
00134 
00136 
00140     MPIInputBufferVector(vector< vector< gl_engineid_t > > &glengineids, int numBuffers) ;
00141 
00142     virtual ~MPIInputBufferVector()
00143     {
00144         if (initialized)
00145                 delete [] memoryPool;
00146     }
00147 
00149     MPIInputBuffer & operator[](int idx)
00150     {
00151         return _buffers[idx];
00152     }
00153 
00155     void *getBaseBufferPtr()
00156     {
00157         return memoryPool;
00158     }
00159 
00161     unsigned int size()
00162     {
00163         return nNodes;
00164     }
00165 
00167     void initialize(int minDelay, size_t maxMPIMessageSize = 0, size_t spikeBufferSize = MPIBUFFER_BLOCK_SIZE);
00168     
00169     
00170     void startNewMPIExchange()
00171     {
00172         vector<MPIInputBuffer>::iterator it;
00173         for (it = _buffers.begin(); it != _buffers.end(); ++it)
00174                 it->startNewMPIExchange();              
00175     }
00176     
00177     void prepareNextBufferSlices()
00178     {
00179         vector<MPIInputBuffer>::iterator it;
00180         for (it = _buffers.begin(); it != _buffers.end(); ++it)
00181                 it->prepareNextBufferSlice();   
00182     }
00183     
00184         MPIExchangeBlocksInfo & getMPIExchangeBlocksInfo();    
00185 
00186 protected:
00187         bool initialized ;
00188         
00190     int nNodes;
00191 
00193     size_t spike_buffer_size;
00194 
00196 
00201     size_t max_mpi_msg_size;
00202 
00204     vector<MPIInputBuffer> _buffers;
00205 
00207     char * memoryPool;
00208     
00209     MPIExchangeBlocksInfo mpiExchBlocksInfo;
00210 
00211 };
00212 
00213 
00214 
00215 #endif /*MPIINPUTBUFFER_H_*/

Generated on Wed Jul 9 16:34:37 2008 for PCSIM by  doxygen 1.5.5