Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        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;
            }
        }