///------------------------------------------------------------------------------------------------- /// <summary> Map partition. </summary> /// /// <remarks> Chris Rossbach ([email protected]), 8/7/2012. </remarks> /// /// <param name="partition"> The partition. </param> ///------------------------------------------------------------------------------------------------- public static void MapPartition( object oPartition ) { KMeansMapPartition partition = oPartition as KMeansMapPartition; while (!m_bMapPhasesComplete) { partition.m_newCenters = KMeansCalculator.CreateCenterAccumulatorList(partition.m_nCenters, partition.m_nRank); partition.m_newGroupCounts = KMeansCalculator.CreateGroupCountList(partition.m_nCenters, partition.m_nRank); partition.m_fDelta = 0.0f; partition.m_evtMapWorkAvailable.WaitOne(); if (!m_bMapPhasesComplete) { for (int i = partition.m_nStartIndex; i < partition.m_nPartitionSize; i++) { Vector vec = partition.m_vectors.ElementAt(i); int nIndex = FindNearestCenter(vec, partition.m_oldCenters); if (partition.m_clusterIds.ElementAt(i) != nIndex) { partition.m_fDelta += 1.0f; } partition.m_clusterIds[i] = nIndex; partition.m_newCenters[nIndex] += vec; partition.m_newGroupCounts[nIndex] += 1; } partition.m_barrier.SignalAndWait(); } } }
SelectInitialCenters( IEnumerable <Vector> attributes, int nMinClusters, int nRandomSeed ) { return(KMeansCalculator.SelectRandomCenters(attributes, nMinClusters, nRandomSeed)); }
///------------------------------------------------------------------------------------------------- /// <summary> Updates the centers. </summary> /// /// <remarks> Chris Rossbach ([email protected]), 8/7/2012. </remarks> /// /// <param name="update"> The update. </param> ///------------------------------------------------------------------------------------------------- public static void UpdateCenters( object oUpdate ) { KMeansUpdateCenters update = oUpdate as KMeansUpdateCenters; update.m_nIterations = 0; while (!m_bUpdatePhasesComplete) { update.m_sharedCenters = KMeansCalculator.CreateCenterAccumulatorList(update.m_nCenters, update.m_nRank); update.m_sharedGroupCounts = KMeansCalculator.CreateGroupCountList(update.m_nCenters, update.m_nRank); update.m_fDelta = 0.0f; update.m_evtMapWorkComplete.WaitOne(); if (m_bVerbose) { Console.WriteLine("update..."); } for (int w = 0; w < update.m_workers.Count(); w++) { KMeansMapPartition worker = update.m_workers[w]; update.m_fDelta += worker.m_fDelta; for (int i = 0; i < update.m_nCenters; i++) { update.m_sharedCenters[i] += worker.m_newCenters[i]; update.m_sharedGroupCounts[i] += worker.m_newGroupCounts[i]; } } for (int i = 0; i < update.m_nCenters; i++) { update.m_sharedCenters[i] /= update.m_sharedGroupCounts[i]; } update.m_fDelta /= update.m_nPoints; update.m_nIterations++; if (update.m_nIterations < update.m_options.m_nMaxIterations && update.m_fDelta >= update.m_options.m_fConvergenceThreshold) { for (int w = 0; w < update.m_workers.Count(); w++) { update.m_workers[w].m_oldCenters = update.m_sharedCenters; } update.m_evtMapWorkComplete.Reset(); update.m_evtMapWorkAvailable.Set(); } else { m_bMapPhasesComplete = true; m_bUpdatePhasesComplete = true; update.m_evtMapWorkAvailable.Set(); // shouldn't be needed, but harmless return; } } }
///------------------------------------------------------------------------------------------------- /// <summary> Main entry-point for this application. </summary> /// /// <remarks> crossbac, 8/6/2013. </remarks> /// /// <param name="args"> Array of command-line argument strings. </param> ///------------------------------------------------------------------------------------------------- static void Main(string[] args) { KMeansOptions options = KMeansOptions.getOptions(args); if (options == null) { return; } if (options.m_bGenerateData) { GenerateRandomInput(options.m_strFileName, options.m_nGenerateElems, options.m_nGenerateDims); return; } Vector[] attributes = options.m_bBinaryInput ? KMeansCalculator.ReadBinaryInput(options.m_strFileName) : KMeansCalculator.ReadTextInput(options.m_strFileName); ComparePerformance(options, attributes); }
///------------------------------------------------------------------------------------------------- /// <summary> Compare performance of several implementations. </summary> /// /// <remarks> Chris Rossbach ([email protected]), 8/7/2012. </remarks> /// /// <param name="options"> Options for controlling the operation. </param> /// <param name="attributes"> The attributes. </param> ///------------------------------------------------------------------------------------------------- static void ComparePerformance( KMeansOptions options, IEnumerable <Vector> attributes ) { List <String> runnableVersions = SelectVersionsToCompare(options); Dictionary <String, Sample[]> perfdata = new Dictionary <string, Sample[]>(); Dictionary <String, Performance> stats = new Dictionary <string, Performance>(); foreach (String version in runnableVersions) { Sample[] vdata = new Sample[options.m_nTotalRuns]; for (int i = 0; i < options.m_nTotalRuns; i++) { vdata[i] = new Sample(); } perfdata[version] = vdata; } IEnumerable <Vector> goldcenters = SelectInitialCenters(attributes, options.m_nClusters, options.m_nRandomSeed); for (int i = 0; i < options.m_nTotalRuns; i++) { long lReferenceImplTime = 0; IEnumerable <Vector> refnewcenters = null; if (options.m_bCheckResult) { Vector[] refcenters = DuplicateCenters(goldcenters); ReferenceKMeans refkmeans = new ReferenceKMeans(); refnewcenters = refkmeans.Compute(attributes, refcenters, options.m_nMaxIterations, true); lReferenceImplTime = refkmeans.RuntimeMilliseconds; } foreach (String sVersion in runnableVersions) { bool bAvoidLazyEval = true; int nMaxParallelism = 1; int[] rClusterIds = null; Vector[] newcenters = DuplicateCenters(goldcenters); KMeansCalculator kmeans = SelectImplementation(options, sVersion, out nMaxParallelism, out bAvoidLazyEval); int nIterations = kmeans.execute(options, attributes, ref newcenters, out rClusterIds, nMaxParallelism, bAvoidLazyEval); Sample isample = perfdata[sVersion][i]; isample.m_impltime = kmeans.RuntimeMilliseconds; isample.m_success = true; isample.m_reftime = 0; if (options.m_bCheckResult) { isample.m_reftime = lReferenceImplTime; isample.m_success = KMeansCalculator.CheckResult(options, newcenters, refnewcenters, options.m_bVerbose, options.m_bVerbose); if (!isample.m_success) { Console.WriteLine("FAILED"); return; } } } } Console.WriteLine("SUCCEEDED"); foreach (String v in perfdata.Keys) { Sample[] samples = perfdata[v]; Performance perf = new Performance(samples); Console.WriteLine("{0,-15}: {1}, avg={2}", v, perf.RawRuntimes(), perf.m_impltime.ToString("f1")); } }