/// <summary> /// creates a non-shallow copy of this object. /// </summary> /// <returns></returns> public Partitioning CloneAs() { MPICollectiveWatchDog.Watch(csMPI.Raw._COMM.WORLD); Partitioning ret = new Partitioning(); ret.m_i0Offset = (int[])this.m_i0Offset.Clone(); ret.m_LocalLengths = (int[])this.m_LocalLengths.Clone(); ret.m_rank = this.m_rank; ret.m_size = this.m_size; ret.m_comm = this.m_comm; return(ret); }
private void ConstructorCommon(int FrameBlockSize, int[][] _Subblk_i0, int[][] _SubblkLen, int[] _BlockType, MPI_Comm MpiComm) { MPICollectiveWatchDog.Watch(MpiComm); int LocalLength = base.LocalLength; // =============== // check arguments // =============== if (_Subblk_i0.Length != _SubblkLen.Length) { throw new ArgumentException(); } for (int i = _Subblk_i0.Length - 1; i >= 0; i--) { if (_Subblk_i0[i].Length != _SubblkLen[i].Length) { throw new ArgumentException(); } int i0min = 0; for (int iSblk = 0; iSblk < _Subblk_i0[i].Length; iSblk++) { if (_Subblk_i0[i][iSblk] < i0min) { throw new ArgumentException("Potential sub-block overlapping."); } i0min += _SubblkLen[i][iSblk]; } } this.m_Subblk_i0 = _Subblk_i0; this.m_SubblkLen = _SubblkLen; if (FrameBlockSize >= 1) { for (int BlockType = 0; BlockType < _Subblk_i0.Length; BlockType++) { int NoOfSubblocks = _Subblk_i0[BlockType].Length; int BlockLen = _Subblk_i0[BlockType][NoOfSubblocks - 1] + _SubblkLen[BlockType][NoOfSubblocks - 1]; if (BlockLen > FrameBlockSize) { throw new ArgumentException(); } } if (LocalLength % FrameBlockSize != 0) { throw new ArgumentException("'FrameBlockSize', if specified, must be a divider of 'LocalLength'."); } if (_BlockType != null) { if (_BlockType.Length != LocalLength / FrameBlockSize) { throw new ArgumentException("Mismatch between number of blocks specified by '_BlockType' and 'LocalLength/FrameBlockSize'."); } } } #if DEBUG if (_BlockType != null) { for (int j = 0; j < _BlockType.Length; j++) { if (_BlockType[j] < 0 || _BlockType[j] > _Subblk_i0.Length) { throw new ArgumentException(); } } } #endif // ==================== // set internal members // ==================== int LocalNoOfBlocks; if (_BlockType != null) { LocalNoOfBlocks = _BlockType.Length; if (FrameBlockSize > 0) { //throw new ArgumentException("If no BlockTape is given, the FrameBlockSize must be specified."); if (LocalLength / FrameBlockSize != _BlockType.Length) { throw new ArgumentException("FrameBlockSize does not match _BlockType."); } } } else { if (FrameBlockSize <= 0) { throw new ArgumentException("If no BlockTape is given, the FrameBlockSize must be specified."); } LocalNoOfBlocks = LocalLength / FrameBlockSize; } m_BlocksPartition = new Partitioning(LocalNoOfBlocks, MpiComm); if (_Subblk_i0.Length > 1) { this.m_BlockType = _BlockType; } else { this.m_BlockType = null; } int J = _BlockType.Length; #if DEBUG { var fbMin = FrameBlockSize.MPIMin(MpiComm); var fbMax = FrameBlockSize.MPIMax(MpiComm); if (fbMin != FrameBlockSize || fbMin != FrameBlockSize) { throw new ApplicationException("MPI bug: different FrameBlockSize among processors."); } } #endif if (FrameBlockSize == 0) { throw new ArgumentException(); } else if (FrameBlockSize < 0) { int[] BlockI0 = new int[J + 1]; BlockI0[0] = base.i0; int FrameBlockSizeMaybe = -1; for (int j = 0; j < J; j++) { int bT = _BlockType[j]; int B = _Subblk_i0[bT].Length; int BlockLen = _Subblk_i0[bT][B - 1] + _SubblkLen[bT][B - 1]; BlockI0[j + 1] = BlockI0[j] + BlockLen; if (j == 0) { FrameBlockSizeMaybe = BlockLen; } else { if (FrameBlockSizeMaybe != BlockLen) { FrameBlockSizeMaybe = -1; } } } Debug.Assert(BlockI0[J] == base.LocalLength + base.i0); int FrameBlockSizeMaybeMin = FrameBlockSizeMaybe.MPIMin(MpiComm); int FrameBlockSizeMaybeMax = FrameBlockSizeMaybe.MPIMax(MpiComm); if (FrameBlockSizeMaybeMin > 0 && FrameBlockSizeMaybe == FrameBlockSizeMaybeMin && FrameBlockSizeMaybe == FrameBlockSizeMaybeMax) { // constant blocking, although the stupid caller told us different m_FrameBlockSize = FrameBlockSizeMaybe; m_Block_i0 = null; } else { m_Block_i0 = BlockI0; m_FrameBlockSize = -1; } } else { Debug.Assert(FrameBlockSize >= 1); m_FrameBlockSize = FrameBlockSize; } }