private static double ParseGraphAndCollect(int nthread, List<PhrasalTree> treebank, LAPCFGrammar rules, Vocabulary vocab, TagSet tagSet, out int failed) { double llhd = 0; failed = 0; int xfail = 0; var handle = new object(); var rulelist = new List<LAPCFGrammar>(); rulelist.Add(rules); while (rulelist.Count < nthread) { rulelist.Add(rules.CloneWithSharedParameters()); } Parallel.For(0, nthread, threadid => { int fail = 0; double xllhd = 0; var parser = new HyperGraphParser(vocab, tagSet, rulelist [threadid]); for (int i = threadid; i < treebank.Count; i += nthread) { try { var graph = parser.BuildHyperGraph(treebank [i]); graph.SumForward(); graph.SumBackward(); if (double.IsInfinity(graph.RootScore) || double.IsNaN(graph.RootScore)) { fail += 1; continue; } graph.CollectExpectedCount(); xllhd += graph.RootScore; } catch { fail += 1; } } lock (handle) { xfail += fail; llhd += xllhd; } } ); for (int i = 1; i < rulelist.Count; ++i) { LAPCFGrammar.ApplyToRules((x, y) => x.Add(y), rules.tposteriorCounts, rulelist [i].tposteriorCounts); LAPCFGrammar.ApplyToRules((x, y) => x.Add(y), rules.uposteriorCounts, rulelist [i].uposteriorCounts); LAPCFGrammar.ApplyToRules((x, y) => x.Add(y), rules.bposteriorCounts, rulelist [i].bposteriorCounts); } failed = xfail; //Console.Error.WriteLine("fail: {0}\tllhd: {1}", failed, llhd); return llhd; }