public void ScatterFromFlattened()

in MPI/Intercommunicator.cs [1821:1902]


        public void ScatterFromFlattened<T>(T[] inValues, int[] counts, int root, ref T[] outValues)
        {
            MPI_Datatype datatype = FastDatatypeCache<T>.datatype;
            if (datatype == Unsafe.MPI_DATATYPE_NULL)
            {
                if (Root == root)
                {
                    T[][] tempIn = new T[RemoteSize][];
                    int inLocation = 0;
                    for (int i = 0; i < RemoteSize; i++) checked
                    {
                        tempIn[i] = new T[counts[i]];
                        Array.Copy(inValues, inLocation, tempIn[i], 0, counts[i]);
                        inLocation += counts[i];
                    }
                    Scatter<T[]>(tempIn);

                }
                else if (Null == root)
                    Scatter<T[]>();
                else
                    outValues = Scatter<T[]>(root);
            }
            else
            {
                if (root != Null && root != Root)
                {
                    if (outValues == null || outValues.Length != counts[Rank])
                        outValues = new T[counts[Rank]];
                }

                if (Root == root)
                {
                    int[] displs = new int[counts.Length];
                    displs[0] = 0;
                    for (int i = 1; i < counts.Length; i++) checked
                    {
                        displs[i] = displs[i - 1] + counts[i - 1];
                    }

                    // Pin the array while we are scattering it.
                    GCHandle inHandle = GCHandle.Alloc(inValues, GCHandleType.Pinned);
                    int errorCode;
                    unsafe
                    {
                        errorCode = Unsafe.MPI_Scatterv(Marshal.UnsafeAddrOfPinnedArrayElement(inValues, 0), counts, displs, datatype,
                                          new IntPtr(0), 0, datatype, root, comm);
                    }
                    inHandle.Free();

                    if (errorCode != Unsafe.MPI_SUCCESS)
                        throw Environment.TranslateErrorIntoException(errorCode);
                }
                else if (Null == root)
                {
                    int errorCode;
                    unsafe
                    {
                        errorCode = Unsafe.MPI_Scatterv(new IntPtr(0), counts, new int[0], datatype,
                                          new IntPtr(0), 0, datatype, root, comm);
                    }

                    if (errorCode != Unsafe.MPI_SUCCESS)
                        throw Environment.TranslateErrorIntoException(errorCode);
                }
                else
                {
                    // Pin the array while we are scattering it.
                    GCHandle outHandle = GCHandle.Alloc(outValues, GCHandleType.Pinned);
                    int errorCode;
                    unsafe
                    {
                        errorCode = Unsafe.MPI_Scatterv(new IntPtr(0), counts, new int[0], datatype,
                                          Marshal.UnsafeAddrOfPinnedArrayElement(outValues, 0), counts[Rank], datatype, root, comm);
                    }
                    outHandle.Free();

                    if (errorCode != Unsafe.MPI_SUCCESS)
                        throw Environment.TranslateErrorIntoException(errorCode);
                }
            }
        }