public void AlltoallFlattened()

in MPI/Intracommunicator.cs [637:698]


        public void AlltoallFlattened<T>(T[] inValues, int[] sendCounts, int[] recvCounts, ref T[] outValues)
        {
            if (sendCounts.Length != Size)
                throw new ArgumentException($"sendCounts.Length ({sendCounts.Length}) != Communicator.Size ({Size})");
            if (recvCounts.Length != Size)
                throw new ArgumentException($"recvCounts.Length ({recvCounts.Length}) != Communicator.Size ({Size})");
            if (Size == 1)
            {
                outValues = inValues;
                return;
            }

            SpanTimer.Enter("AlltoallFlattened");
            int totalCounts = 0;
            for (int i = 0; i < recvCounts.Length; i++) checked
            {
                totalCounts += recvCounts[i];
            }
            // Make sure the outgoing array is the right size
            if (outValues == null || outValues.Length < totalCounts)
                outValues = new T[totalCounts];

            MPI_Datatype datatype = FastDatatypeCache<T>.datatype;
            if (datatype == Unsafe.MPI_DATATYPE_NULL)
            {
                // There is no associated MPI datatype for this type, so we will
                // need to serialize the value for transmission.
                if (SplitLargeObjects)
                    Serialization.AlltoallFlattened(this, inValues, sendCounts, recvCounts, outValues);
                else
                    AlltoallFlattened_serialized(inValues, sendCounts, recvCounts, outValues);
            }
            else
            {
                int[] sendDispls = new int[sendCounts.Length];
                int[] recvDispls = new int[recvCounts.Length];
                sendDispls[0] = 0;
                recvDispls[0] = 0;
                for (int i = 1; i < sendDispls.Length; i++) checked
                {
                    sendDispls[i] = sendDispls[i - 1] + sendCounts[i - 1];
                    recvDispls[i] = recvDispls[i - 1] + recvCounts[i - 1];
                }
                int lastIndex = sendCounts.Length - 1;
                int totalSendCount = checked(sendDispls[lastIndex] + sendCounts[lastIndex]);
                if (totalSendCount > inValues.Length)
                {
                    throw new ArgumentException($"Sum of sendCounts ({totalSendCount}) > inValues.Length ({inValues.Length})");
                }

                GCHandle inHandle = GCHandle.Alloc(inValues, GCHandleType.Pinned);
                GCHandle outHandle = GCHandle.Alloc(outValues, GCHandleType.Pinned);
                int errorCode = Unsafe.MPI_Alltoallv(inHandle.AddrOfPinnedObject(), sendCounts, sendDispls, datatype,
                                                    outHandle.AddrOfPinnedObject(), recvCounts, recvDispls, datatype, comm);
                inHandle.Free();
                outHandle.Free();

                if (errorCode != Unsafe.MPI_SUCCESS)
                    throw Environment.TranslateErrorIntoException(errorCode);
            }
            SpanTimer.Leave("AlltoallFlattened");
        }