/// <summary> /// Accumulates the catchment results from all processes involved in calculating that catchment. /// The root process in each catchment communicator will contain the accumulated result for that catchment. /// </summary> /// <param name="partialCatchmentResults"> The partial catchment results from the current process. </param> /// <param name="sysConfig"> The sys config. </param> /// <returns> The array of final catchment results for the current process. There will be one element for each catchment /// for which the current process is the catchment coordinator. /// </returns> private MpiObjectiveScores[] AccumulateCatchmentResultsInCatchmentCoordinator( Dictionary <string, List <SerializableDictionary <string, MpiTimeSeries> > > partialCatchmentResults, MpiSysConfig sysConfig) { MpiObjectiveScores[] finalCatchmentResults = new MpiObjectiveScores[CatchmentCoordinatorCount]; int finalResultIndex = 0; foreach (CatchmentDefinition catchment in MyWork.Catchments) { // Note that Gather is blocking but not synchronous. This means that I can't cause deadlock by having processes // call Gather on the communicators in different sequences. My local call to gather will return even if the other // participants in the gather have not joined in yet. Intracommunicator catchmentComm = communicatorsByCatchmentId[catchment.Id]; Log.DebugFormat("Rank {0}: Catchment '{1}' rank {2}: Sending {3} cell results", WorldRank, catchment.Id, catchmentComm.Rank, partialCatchmentResults[catchment.Id].Count); if (catchmentComm.Rank == 0) { SerializableDictionary <string, MpiTimeSeries>[] completeCatchmentResults = catchmentComm.GatherFlattened( partialCatchmentResults[catchment.Id].ToArray(), CatchmentResultCountPerCatchmentCommunicator[catchment.Id], 0); // catchmentResults contains all the gridded results for the current catchment Log.DebugFormat("Rank {0}: Catchment '{1}': Accumulating {2} results from {3} cells", WorldRank, catchment.Id, completeCatchmentResults.Length, catchment.Cells.Count); Debug.Assert(catchment.Cells.Count == completeCatchmentResults.Length); MpiObjectiveScores finalCatchmentResult = CalculateCatchmentScores(catchment, completeCatchmentResults, sysConfig, catchment.Cells.Count); finalCatchmentResults[finalResultIndex] = finalCatchmentResult; finalResultIndex++; } else { catchmentComm.GatherFlattened(partialCatchmentResults[catchment.Id].ToArray(), 0); } } return(finalCatchmentResults); }