public static void Initialize(int numThreads) { lock (_lockObject) { if (NumThreads == 0) { Contracts.Assert(numThreads > 0); Contracts.Assert(NumThreads == 0); NumThreads = numThreads; BlockingThreadPool.Initialize(numThreads); } } }
public double ComputeDominationLoss(double[] scores) { int chunkSize = 1 + Dataset.NumQueries / BlockingThreadPool.NumThreads; // Minimizes the number of repeat computations in sparse array to have each thread take as big a chunk as possible double totalOutput = 0.0; var _lock = new Object(); for (int queryBegin = 0; queryBegin < Dataset.NumQueries; queryBegin += chunkSize) { BlockingThreadPool.RunOrBlock(delegate(int startQuery, int endQuery) { double output = 0.0; for (int query = startQuery; query <= endQuery; query++) { int begin = Dataset.Boundaries[query]; int end = Dataset.Boundaries[query + 1]; if (end - begin <= 1) { continue; } int bestDoc = _bestDocsPerQuery.BestDocs[query]; int secondBestDoc = _bestDocsPerQuery.SecondBestDocs[query]; double bestDocScore = scores[bestDoc]; double secondBestDocScore = scores[secondBestDoc]; // find max score double max = double.NegativeInfinity; double maxNotBest = double.NegativeInfinity; for (int d = begin; d < end; ++d) { if (max < scores[d]) { max = scores[d]; } if (d != bestDoc && maxNotBest < scores[d]) { maxNotBest = scores[d]; } } // sum of exponents and sum of all but best double sum = 0.0; double sumAllButBest = 0.0; for (int d = begin; d < end; ++d) { sum += Math.Exp(scores[d] - max); if (d != bestDoc) { sumAllButBest += Math.Exp(scores[d] - maxNotBest); } } output += max - bestDocScore + Math.Log(sum) + 0.5 * (maxNotBest - secondBestDocScore + Math.Log(sumAllButBest)); } lock (_lock) { totalOutput += output; } }, queryBegin, Math.Min(queryBegin + chunkSize - 1, Dataset.NumQueries - 1)); } BlockingThreadPool.BlockUntilAllWorkItemsFinish(); return(totalOutput); }