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);
}
}
}