MPIBufferSlicer.cpp

Go to the documentation of this file.
00001 #include "MPIBufferSlicer.h"
00002 #include "MPIInputSpikeBuffer.h"
00003 #include "PCSIMException.h"
00004 
00005 #include <cassert>
00006 #include <numeric>
00007 
00008 using std::min;
00009 
00010 MPIBufferSlicer::MPIBufferSlicer(MPIBufferType bufferType)
00011         : buffer_type(bufferType)
00012 {}
00013 
00014 void MPIBufferSlicer::initialize(size_t analogBufferSize,
00015                                  size_t maxMPIMsgSize ,
00016                                  size_t spikeBufferSize)
00017 {
00018     if (maxMPIMsgSize % 8) {
00019         throw PCSIM::Exception("MPIBufferSlicer::initialize", "Maximum mpi msg size must be divisible by 8");
00020     }
00021 
00022     max_mpi_msg_size = maxMPIMsgSize;
00023     spike_buffer_size_bytes = spikeBufferSize ;
00024     analog_buffer_size_elements = analogBufferSize;
00025     analog_buffer_size_bytes = analog_buffer_size_elements * sizeof(double);
00026     spike_buffer_size_elements = spike_buffer_size_bytes / sizeof(MPIInputSpikeBuffer<>::coding_element_type);
00027 
00028     // Decide if there will be mixed (analog and spiking) mpi data types during transfer
00029     if ( analog_buffer_size_bytes == 0 )
00030         thereIsMixedDataType = false;
00031     else
00032         if ( max_mpi_msg_size == 0 )
00033             thereIsMixedDataType = true;
00034         else
00035             if (analog_buffer_size_bytes % max_mpi_msg_size == 0 ||
00036                     max_mpi_msg_size - analog_buffer_size_bytes % max_mpi_msg_size < MIN_MPI_SPIKE_BUFFER_SIZE)
00037                 thereIsMixedDataType = false;
00038             else
00039                 thereIsMixedDataType = true;
00040 }
00041 
00042 void MPIBufferSlicer::reset()
00043 {
00044     currentSliceType = sliceUndefined;
00045 }
00046 
00047 void MPIBufferSlicer::calcNextBufferSliceDimensions()
00048 {
00049     switch(currentSliceType) {
00050     case sliceUndefined:
00051         if (!analog_buffer_size_elements) {
00052             // no analog data so start transfering the spiking slices
00053             currentSliceType = sliceSpiking;
00054             currentSlicePos = analog_buffer_size_bytes;
00055             allowedSpikeSliceSize = spike_buffer_size_bytes;
00056         } else {
00057             if (thereIsMixedDataType) {
00058                 if (max_mpi_msg_size == 0) {
00059                     currentSliceType = sliceMixed;
00060                     currentSlicePos = 0;
00061                     currentAnalogSliceSize = analog_buffer_size_bytes;
00062                     allowedSpikeSliceSize = spike_buffer_size_bytes;
00063                 } else {
00064                     if (max_mpi_msg_size > analog_buffer_size_bytes) {
00065                         // first message should be mixed
00066                         currentSliceType = sliceMixed;
00067                         currentSlicePos = 0;
00068                         currentAnalogSliceSize = analog_buffer_size_bytes;
00069                         allowedSpikeSliceSize = min(max_mpi_msg_size - analog_buffer_size_bytes,
00070                                                     spike_buffer_size_bytes);
00071                     } else {
00072                         // first message is analog since there is analog data, and the first message is not mixed
00073                         currentSliceType = sliceAnalog;
00074                         currentSlicePos = 0;
00075                         currentAnalogSliceSize = max_mpi_msg_size;
00076                     }
00077                 }
00078             } else {
00079                 // there isn't a mixed data type, and there is analog data, so the first message should be analog
00080                 currentSliceType = sliceAnalog;
00081                 currentSlicePos = 0;
00082                 currentAnalogSliceSize= min(max_mpi_msg_size, analog_buffer_size_bytes) ;
00083             }
00084         }
00085         break;
00086     case sliceAnalog:
00087         currentSlicePos += currentAnalogSliceSize;
00088         if (currentSlicePos == analog_buffer_size_bytes) {
00089             currentSliceType = sliceSpiking;
00090             allowedSpikeSliceSize = spike_buffer_size_bytes;
00091         } else {
00092             if (currentSlicePos + max_mpi_msg_size > analog_buffer_size_bytes) {
00093                 if (thereIsMixedDataType) {
00094                     currentSliceType = sliceMixed;
00095                     currentAnalogSliceSize = analog_buffer_size_bytes - currentSlicePos ;
00096                     allowedSpikeSliceSize = min( currentSlicePos + max_mpi_msg_size - analog_buffer_size_bytes,
00097                                                  spike_buffer_size_bytes) ;
00098                 } else {
00099                     currentSliceType = sliceAnalog;
00100                     currentAnalogSliceSize = analog_buffer_size_bytes - currentSlicePos;
00101                 }
00102             } else {
00103                 currentSliceType = sliceAnalog;
00104                 currentAnalogSliceSize = max_mpi_msg_size;
00105             }
00106         }
00107         break;
00108     case sliceMixed:
00109     case sliceSpiking:
00110         currentSliceType = sliceSpiking;
00111         currentSlicePos = analog_buffer_size_bytes;
00112         allowedSpikeSliceSize = spike_buffer_size_bytes;
00113     }
00114 }
00115 
00116 
00117 

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