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
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
00113 int mixedCounts[2];
00114
00115
00116 MPI::Aint mixedDisplacements[2];
00117
00118 friend class MPIInputBufferVector;
00119
00120 };
00121
00122
00124
00125
00126
00127
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