void ExchangeBuffer::Unpack( DataArray3D<double> & data ) { const size_t sAElements = data.GetSize(0); const size_t sBElements = data.GetSize(1); const size_t sRElements = data.GetSize(2); // Index for halo elements along boundary int ixBoundaryBegin; int ixBoundaryEnd; int ixABoundaryBegin; int ixABoundaryEnd; int ixBBoundaryBegin; int ixBBoundaryEnd; // Unpack data from right if (m_dir == Direction_Right) { ixBoundaryBegin = sAElements - m_sHaloElements; ixBoundaryEnd = sAElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixBoundaryEnd - ixBoundaryBegin) * (m_ixSecond - m_ixFirst); if (m_ixRecvBuffer + nTotalValues > m_dRecvBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in RecvBuffer for operation."); } // Unpack data for (int i = ixBoundaryEnd-1; i >= ixBoundaryBegin; i--) { for (int j = m_ixFirst; j < m_ixSecond; j++) { #pragma simd for (int k = 0; k < sRElements; k++) { data(i,j,k) = m_dRecvBuffer[m_ixRecvBuffer + k]; } m_ixRecvBuffer += sRElements; } } // Unpack data from top } else if (m_dir == Direction_Top) { ixBoundaryBegin = sBElements - m_sHaloElements; ixBoundaryEnd = sBElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixBoundaryEnd - ixBoundaryBegin) * (m_ixSecond - m_ixFirst); if (m_ixRecvBuffer + nTotalValues > m_dRecvBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in RecvBuffer for operation."); } // Unpack data for (int j = ixBoundaryEnd-1; j >= ixBoundaryBegin; j--) { for (int i = m_ixFirst; i < m_ixSecond; i++) { #pragma simd for (int k = 0; k < sRElements; k++) { data(i,j,k) = m_dRecvBuffer[m_ixRecvBuffer + k]; } m_ixRecvBuffer += sRElements; } } // Unpack data from left } else if (m_dir == Direction_Left) { ixBoundaryBegin = 0; ixBoundaryEnd = m_sHaloElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixBoundaryEnd - ixBoundaryBegin) * (m_ixSecond - m_ixFirst); if (m_ixRecvBuffer + nTotalValues > m_dRecvBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in RecvBuffer for operation."); } // Unpack data for (int i = ixBoundaryBegin; i < ixBoundaryEnd; i++) { for (int j = m_ixFirst; j < m_ixSecond; j++) { #pragma simd for (int k = 0; k < sRElements; k++) { data(i,j,k) = m_dRecvBuffer[m_ixRecvBuffer + k]; } m_ixRecvBuffer += sRElements; } } // Unpack data from bottom } else if (m_dir == Direction_Bottom) { ixBoundaryBegin = 0; ixBoundaryEnd = m_sHaloElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixBoundaryEnd - ixBoundaryBegin) * (m_ixSecond - m_ixFirst); if (m_ixRecvBuffer + nTotalValues > m_dRecvBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in RecvBuffer for operation."); } // Unpack data for (int j = ixBoundaryBegin; j < ixBoundaryEnd; j++) { for (int i = m_ixFirst; i < m_ixSecond; i++) { #pragma simd for (int k = 0; k < sRElements; k++) { data(i,j,k) = m_dRecvBuffer[m_ixRecvBuffer + k]; } m_ixRecvBuffer += sRElements; } } // Unpack data from top-right } else if (m_dir == Direction_TopRight) { ixABoundaryBegin = m_ixFirst + 1; ixABoundaryEnd = m_ixFirst + m_sHaloElements + 1; ixBBoundaryBegin = m_ixSecond + 1; ixBBoundaryEnd = m_ixSecond + m_sHaloElements + 1; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixABoundaryEnd - ixABoundaryBegin) * (ixBBoundaryEnd - ixBBoundaryBegin); if (m_ixRecvBuffer + nTotalValues > m_dRecvBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in RecvBuffer for operation."); } // Unpack data for (int j = ixBBoundaryEnd-1; j >= ixBBoundaryBegin; j--) { for (int i = ixABoundaryEnd-1; i >= ixABoundaryBegin; i--) { #pragma simd for (int k = 0; k < sRElements; k++) { data(i,j,k) = m_dRecvBuffer[m_ixRecvBuffer + k]; } m_ixRecvBuffer += sRElements; } } // Unpack data from top-left } else if (m_dir == Direction_TopLeft) { ixABoundaryBegin = m_ixFirst - m_sHaloElements; ixABoundaryEnd = m_ixFirst; ixBBoundaryBegin = m_ixSecond + 1; ixBBoundaryEnd = m_ixSecond + m_sHaloElements + 1; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixABoundaryEnd - ixABoundaryBegin) * (ixBBoundaryEnd - ixBBoundaryBegin); if (m_ixRecvBuffer + nTotalValues > m_dRecvBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in RecvBuffer for operation."); } // Unpack data for (int j = ixBBoundaryEnd-1; j >= ixBBoundaryBegin; j--) { for (int i = ixABoundaryBegin; i < ixABoundaryEnd; i++) { #pragma simd for (int k = 0; k < sRElements; k++) { data(i,j,k) = m_dRecvBuffer[m_ixRecvBuffer + k]; } m_ixRecvBuffer += sRElements; } } // Unpack data from bottom-left } else if (m_dir == Direction_BottomLeft) { ixABoundaryBegin = m_ixFirst - m_sHaloElements; ixABoundaryEnd = m_ixFirst; ixBBoundaryBegin = m_ixSecond - m_sHaloElements; ixBBoundaryEnd = m_ixSecond; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixABoundaryEnd - ixABoundaryBegin) * (ixBBoundaryEnd - ixBBoundaryBegin); if (m_ixRecvBuffer + nTotalValues > m_dRecvBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in RecvBuffer for operation."); } // Unpack data for (int j = ixBBoundaryBegin; j < ixBBoundaryEnd; j++) { for (int i = ixABoundaryBegin; i < ixABoundaryEnd; i++) { #pragma simd for (int k = 0; k < sRElements; k++) { data(i,j,k) = m_dRecvBuffer[m_ixRecvBuffer + k]; } m_ixRecvBuffer += sRElements; } } // Unpack data from bottom-right } else if (m_dir == Direction_BottomRight) { ixABoundaryBegin = m_ixFirst + 1; ixABoundaryEnd = m_ixFirst + m_sHaloElements + 1; ixBBoundaryBegin = m_ixSecond - m_sHaloElements; ixBBoundaryEnd = m_ixSecond; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixABoundaryEnd - ixABoundaryBegin) * (ixBBoundaryEnd - ixBBoundaryBegin); if (m_ixRecvBuffer + nTotalValues > m_dRecvBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in RecvBuffer for operation."); } // Unpack data for (int j = ixBBoundaryBegin; j < ixBBoundaryEnd; j++) { for (int i = ixABoundaryEnd-1; i >= ixABoundaryBegin; i--) { #pragma simd for (int k = 0; k < sRElements; k++) { data(i,j,k) = m_dRecvBuffer[m_ixRecvBuffer + k]; } m_ixRecvBuffer += sRElements; } } // Invalid direction } else { _EXCEPTIONT("Invalid direction"); } }
void ExchangeBuffer::Pack( const DataArray3D<double> & data ) { const size_t sAElements = data.GetSize(0); const size_t sBElements = data.GetSize(1); const size_t sRElements = data.GetSize(2); // Check matrix bounds if (((m_dir == Direction_Right) || (m_dir == Direction_Left)) && (m_ixSecond > sBElements) ) { _EXCEPTIONT("GridData / ExteriorNeighbor inconsistency."); } if (((m_dir == Direction_Top) || (m_dir == Direction_Bottom)) && (m_ixSecond > sAElements) ) { _EXCEPTIONT("GridData / ExteriorNeighbor inconsistency."); } // Index for halo elements along boundary int ixBoundaryBegin; int ixBoundaryEnd; int ixABoundaryBegin; int ixABoundaryEnd; int ixBBoundaryBegin; int ixBBoundaryEnd; // Maximum index for radial elements int nVarRElements; // Pack data to send right if (m_dir == Direction_Right) { ixBoundaryBegin = sAElements - 2 * m_sHaloElements; ixBoundaryEnd = sAElements - m_sHaloElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixBoundaryEnd - ixBoundaryBegin) * (m_ixSecond - m_ixFirst); if (m_ixSendBuffer + nTotalValues > m_dSendBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in SendBuffer for operation."); } // Pack the SendBuffer if (m_fReverseDirection) { for (int i = ixBoundaryBegin; i < ixBoundaryEnd; i++) { for (int j = m_ixSecond-1; j >= m_ixFirst; j--) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } else { for (int i = ixBoundaryBegin; i < ixBoundaryEnd; i++) { for (int j = m_ixFirst; j < m_ixSecond; j++) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } // Pack data to send topward } else if (m_dir == Direction_Top) { ixBoundaryBegin = sBElements - 2 * m_sHaloElements; ixBoundaryEnd = sBElements - m_sHaloElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixBoundaryEnd - ixBoundaryBegin) * (m_ixSecond - m_ixFirst); if (m_ixSendBuffer + nTotalValues > m_dSendBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in SendBuffer for operation."); } // Pack the SendBuffer if (m_fReverseDirection) { for (int j = ixBoundaryBegin; j < ixBoundaryEnd; j++) { for (int i = m_ixSecond-1; i >= m_ixFirst; i--) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } else { for (int j = ixBoundaryBegin; j < ixBoundaryEnd; j++) { for (int i = m_ixFirst; i < m_ixSecond; i++) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } // Pack data to send left } else if (m_dir == Direction_Left) { ixBoundaryBegin = m_sHaloElements; ixBoundaryEnd = 2 * m_sHaloElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixBoundaryEnd - ixBoundaryBegin) * (m_ixSecond - m_ixFirst); if (m_ixSendBuffer + nTotalValues > m_dSendBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in SendBuffer for operation."); } // Pack the SendBuffer if (m_fReverseDirection) { for (int i = ixBoundaryEnd-1; i >= ixBoundaryBegin; i--) { for (int j = m_ixSecond-1; j >= m_ixFirst; j--) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } else { for (int i = ixBoundaryEnd-1; i >= ixBoundaryBegin; i--) { for (int j = m_ixFirst; j < m_ixSecond; j++) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } // Pack data to send bottomward } else if (m_dir == Direction_Bottom) { ixBoundaryBegin = m_sHaloElements; ixBoundaryEnd = 2 * m_sHaloElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixBoundaryEnd - ixBoundaryBegin) * (m_ixSecond - m_ixFirst); if (m_ixSendBuffer + nTotalValues > m_dSendBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in SendBuffer for operation."); } // Pack the SendBuffer if (m_fReverseDirection) { for (int j = ixBoundaryEnd-1; j >= ixBoundaryBegin; j--) { for (int i = m_ixSecond-1; i >= m_ixFirst; i--) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } else { for (int j = ixBoundaryEnd-1; j >= ixBoundaryBegin; j--) { for (int i = m_ixFirst; i < m_ixSecond; i++) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } // Pack data to send toprightward } else if (m_dir == Direction_TopRight) { ixABoundaryBegin = m_ixFirst - m_sHaloElements + 1; ixABoundaryEnd = m_ixFirst + 1; ixBBoundaryBegin = m_ixSecond - m_sHaloElements + 1; ixBBoundaryEnd = m_ixSecond + 1; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixABoundaryEnd - ixABoundaryBegin) * (ixBBoundaryEnd - ixBBoundaryBegin); if (m_ixSendBuffer + nTotalValues > m_dSendBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in SendBuffer for operation."); } // Pack the SendBuffer if (m_fReverseDirection) { for (int i = ixABoundaryBegin; i < ixABoundaryEnd; i++) { for (int j = ixBBoundaryBegin; j < ixBBoundaryEnd; j++) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } else { for (int j = ixBBoundaryBegin; j < ixBBoundaryEnd; j++) { for (int i = ixABoundaryBegin; i < ixABoundaryEnd; i++) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } // Pack data to send topleftward } else if (m_dir == Direction_TopLeft) { ixABoundaryBegin = m_ixFirst; ixABoundaryEnd = m_ixFirst + m_sHaloElements; ixBBoundaryBegin = m_ixSecond - m_sHaloElements + 1; ixBBoundaryEnd = m_ixSecond + 1; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixABoundaryEnd - ixABoundaryBegin) * (ixBBoundaryEnd - ixBBoundaryBegin); if (m_ixSendBuffer + nTotalValues > m_dSendBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in SendBuffer for operation."); } // Pack the SendBuffer if (m_fReverseDirection) { for (int i = ixABoundaryEnd-1; i >= ixABoundaryBegin; i--) { for (int j = ixBBoundaryBegin; j < ixBBoundaryEnd; j++) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } else { for (int j = ixBBoundaryBegin; j < ixBBoundaryEnd; j++) { for (int i = ixABoundaryEnd-1; i >= ixABoundaryBegin; i--) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } // Pack data to send bottomleftward } else if (m_dir == Direction_BottomLeft) { ixABoundaryBegin = m_ixFirst; ixABoundaryEnd = m_ixFirst + m_sHaloElements; ixBBoundaryBegin = m_ixSecond; ixBBoundaryEnd = m_ixSecond + m_sHaloElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixABoundaryEnd - ixABoundaryBegin) * (ixBBoundaryEnd - ixBBoundaryBegin); if (m_ixSendBuffer + nTotalValues > m_dSendBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in SendBuffer for operation."); } // Pack the SendBuffer if (m_fReverseDirection) { for (int i = ixABoundaryEnd-1; i >= ixABoundaryBegin; i--) { for (int j = ixBBoundaryEnd-1; j >= ixBBoundaryBegin; j--) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } else { for (int j = ixBBoundaryEnd-1; j >= ixBBoundaryBegin; j--) { for (int i = ixABoundaryEnd-1; i >= ixABoundaryBegin; i--) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } // Pack data to send bottomrightward } else if (m_dir == Direction_BottomRight) { ixABoundaryBegin = m_ixFirst - m_sHaloElements + 1; ixABoundaryEnd = m_ixFirst + 1; ixBBoundaryBegin = m_ixSecond; ixBBoundaryEnd = m_ixSecond + m_sHaloElements; // Check that sufficient data remains in send buffer int nTotalValues = sRElements * (ixABoundaryEnd - ixABoundaryBegin) * (ixBBoundaryEnd - ixBBoundaryBegin); if (m_ixSendBuffer + nTotalValues > m_dSendBuffer.GetRows()) { _EXCEPTIONT("Insufficient space in SendBuffer for operation."); } // Pack the SendBuffer if (m_fReverseDirection) { for (int i = ixABoundaryBegin; i < ixABoundaryEnd; i++) { for (int j = ixBBoundaryEnd-1; j >= ixBBoundaryBegin; j--) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } else { for (int j = ixBBoundaryEnd-1; j >= ixBBoundaryBegin; j--) { for (int i = ixABoundaryBegin; i < ixABoundaryEnd; i++) { #pragma simd for (int k = 0; k < sRElements; k++) { m_dSendBuffer[m_ixSendBuffer + k] = data(i,j,k); } m_ixSendBuffer += sRElements; } } } // Invalid direction } else { _EXCEPTIONT("Invalid direction"); } }