public static void AlltoallSubarrays <T>(ICommunicator comm, IReadOnlyList <T> inputArray, ICollection <int>[] indicesToSend, IList <T> outputArray, ICollection <int>[] indicesToReceive) { var sendCounts = indicesToSend.Select(indices => indices.Count).ToArray(); var sendTotalCount = sendCounts.Sum(); T[] subarrayToSend = new T[sendTotalCount]; int position = 0; for (int recipient = 0; recipient < indicesToSend.Length; recipient++) { foreach (int index in indicesToSend[recipient]) { //if (comm.Rank == 0 && recipient == 1) // Trace.WriteLine($"sending {inputArray[index]}"); subarrayToSend[position++] = inputArray[index]; } } var recvCounts = indicesToReceive.Select(indices => indices.Count).ToArray(); var recvTotalCount = recvCounts.Sum(); AlltoallSubarraysItemsTransmitted += sendTotalCount + recvTotalCount; T[] subarrayReceived = comm.AlltoallFlattened(subarrayToSend, sendCounts, recvCounts); int recvPosition = 0; for (int source = 0; source < comm.Size; source++) { var indicesOfSubarray = indicesToReceive[source]; foreach (int index in indicesOfSubarray) { outputArray[index] = subarrayReceived[recvPosition++]; //Trace.WriteLine($"process {comm.Rank} from {source} received {outputArray[index]} for local index {index} recvPosition = {recvPosition}"); } } }