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