public void CorrectMeans()
        {
            const int numScores     = 4;
            const int numObjectives = 3;

            MpiObjectiveScores[] scores        = new MpiObjectiveScores[numScores];
            double[]             expectedMeans = new double[numObjectives];

            for (int i = 0; i < numScores; i++)
            {
                IObjectiveScore[] objectives = new IObjectiveScore[numObjectives];
                for (int j = 0; j < numObjectives; j++)
                {
                    double fs = FakeScore(i + j);
                    expectedMeans[j] += fs;
                    objectives[j]     = new DoubleObjectiveScore(String.Format("{0}-{1}", i, j), fs, true);
                }

                scores[i] = new MpiObjectiveScores(objectives, config);
            }

            for (int i = 0; i < numObjectives; i++)
            {
                expectedMeans[i] /= numScores;
            }

            var result = ObjectiveScoresHelper.Mean(scores, config);

            for (int i = 0; i < numObjectives; i++)
            {
                Assert.That((double)result.GetObjective(i).ValueComparable, Is.EqualTo(expectedMeans[i]).Within(1e-8));
            }
        }
        private MpiObjectiveScores CalculateCatchmentScores(CatchmentDefinition catchment, SerializableDictionary <string, MpiTimeSeries> catchmentTimeSeries, MpiSysConfig sysConfig)
        {
            // convert back to the Time.Data.TimeSeries objects for use by the statistics objects.
            SerializableDictionary <string, TimeSeries> convertedCatchmentTimeSeries = new SerializableDictionary <string, TimeSeries>();

            foreach (KeyValuePair <string, MpiTimeSeries> keyValuePair in catchmentTimeSeries)
            {
                MpiTimeSeries value = keyValuePair.Value;
                convertedCatchmentTimeSeries.Add(keyValuePair.Key, new TimeSeries(value.Start, value.TimeStep, value.TimeSeries));
            }

            // make the pre-calculated time series look like a point time series model so it can be used by the statistics evaluator
            PointTimeSeriesSimulationDictionaryAdapter catchmentTimeSeriesAdapter = new PointTimeSeriesSimulationDictionaryAdapter(convertedCatchmentTimeSeries);

            catchmentTimeSeriesAdapter.SetPeriod(catchment.Cells[0].ModelRunDefinition.StartDate, catchment.Cells[0].ModelRunDefinition.EndDate);

            // retrieve the statistics evaluator for this catchment
            Log.DebugFormat("Rank {0}: Catchment '{1}' creating score evaluator", WorldRank, catchment.Id);
            var catchmentScoreEvaluator = GetCatchmentStatisticsEvaluator(catchment, catchmentTimeSeriesAdapter);

            catchmentScoreEvaluator.SetModelRunner(catchmentTimeSeriesAdapter);
            Log.DebugFormat("Rank {0}: Catchment '{1}' evaluating score", WorldRank, catchment.Id);
            MpiObjectiveScores calculateCatchmentScores = new MpiObjectiveScores(catchmentScoreEvaluator.EvaluateScore(catchmentTimeSeriesAdapter, sysConfig), catchment.Id);

            return(calculateCatchmentScores);
        }
        /// <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>
        protected MpiObjectiveScores[] AccumulateCatchmentResultsInCatchmentCoordinator(
            Dictionary <string, 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.
                var catchmentComm = communicatorsByCatchmentId[catchment.Id];

                var groupRank = catchmentComm.GetRank(this.WorldRank);
                if (groupRank == 0) //Catchment coordinator
                {
                    SerializableDictionary <string, MpiTimeSeries>[] completeCatchmentResults = catchmentComm.Gather(partialCatchmentResults[catchment.Id], 0, groupRank);
                    Log.DebugFormat("Rank {0}: Catchment '{1}': Accumulating {2} results from {3} processes", WorldRank, catchment.Id, completeCatchmentResults.Length, catchmentComm.Size);
                    Debug.Assert(completeCatchmentResults.Length == catchmentComm.Size); // we expect one result from each process

                    // completeCatchmentResults contains the weighted summed scores from every process involved in calculating this catchment
                    // We now need to condense the array of scores to a single weighted sum, using the first partial result as the destination buffer
                    SerializableDictionary <string, MpiTimeSeries> finalResult = null;
                    foreach (SerializableDictionary <string, MpiTimeSeries> partialResult in completeCatchmentResults)
                    {
                        if (finalResult == null)
                        {
                            finalResult = partialResult;
                        }
                        else
                        {
                            foreach (var partialResultPairs in partialResult)
                            {
                                finalResult[partialResultPairs.Key].InplaceAdd(partialResultPairs.Value);
                            }
                        }
                    }

                    MpiObjectiveScores finalCatchmentResult = CalculateCatchmentScores(catchment, finalResult, sysConfig);
                    finalCatchmentResults[finalResultIndex] = finalCatchmentResult;
                    finalResultIndex++;
                }
                else
                {
                    Log.DebugFormat("Rank {0}: Catchment '{1}' rank {2}: Sending {3} cell results", WorldRank, catchment.Id, catchmentComm.GetRank(this.WorldRank), partialCatchmentResults[catchment.Id].Count);
                    catchmentComm.Gather(partialCatchmentResults[catchment.Id], 0, groupRank);
                }
            }

            return(finalCatchmentResults);
        }
        private MpiObjectiveScores[] CreateRandomScores(int numScores, int objectivesPerScore)
        {
            MpiObjectiveScores[] scores = new MpiObjectiveScores[numScores];

            for (int i = 0; i < numScores; i++)
            {
                IObjectiveScore[] objectives = new IObjectiveScore[objectivesPerScore];
                for (int j = 0; j < objectivesPerScore; j++)
                {
                    objectives[j] = new DoubleObjectiveScore(String.Format("{0}-{1}", i, j), FakeScore(i + j), true);
                }

                scores[i] = new MpiObjectiveScores(objectives, config);
            }

            return(scores);
        }
Пример #5
0
        public static IObjectiveScores[] CreateTestScores(int objectivesPerScore, MpiSysConfig[] configs)
        {
            int numScores = configs.Length;

            IObjectiveScores[] scores = new IObjectiveScores[numScores];
            for (int i = 0; i < numScores; i++)
            {
                IObjectiveScore[] objectives = new IObjectiveScore[objectivesPerScore];
                for (int j = 0; j < objectivesPerScore; j++)
                {
                    objectives[j] = new DoubleObjectiveScore(String.Format("Score:{0}-{1}", i, j), FakeScore(i + j), true);
                }

                scores[i] = new MpiObjectiveScores(objectives, configs[i]);
            }

            return(scores);
        }
        /// <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);
        }