mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			148 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| /*
 | |
|  *  This file is part of the X10 project (http://x10-lang.org).
 | |
|  *
 | |
|  *  This file is licensed to You under the Eclipse Public License (EPL);
 | |
|  *  You may not use this file except in compliance with the License.
 | |
|  *  You may obtain a copy of the License at
 | |
|  *      http://www.opensource.org/licenses/eclipse-1.0.php
 | |
|  *
 | |
|  *  (C) Copyright IBM Corporation 2006-2014.
 | |
|  */
 | |
| 
 | |
| import x10.array.*;
 | |
| import x10.io.Console;
 | |
| import x10.util.Random;
 | |
| 
 | |
| /**
 | |
|  * A low performance formulation of distributed KMeans using fine-grained asyncs.
 | |
|  *
 | |
|  * For a highly optimized and scalable, version of this benchmark see
 | |
|  * KMeans.x10 in the X10 Benchmarks (separate download from x10-lang.org)
 | |
|  */
 | |
| public class KMeansDist {
 | |
| 
 | |
|     static val DIM=2;
 | |
|     static val CLUSTERS=4;
 | |
|     static val POINTS=2000;
 | |
|     static val ITERATIONS=50;
 | |
| 
 | |
|     public static def main (Rail[String]) {
 | |
|         val world = Place.places();
 | |
|         val local_curr_clusters = 
 | |
|             PlaceLocalHandle.make[Array_2[Float]](world, () => new Array_2[Float](CLUSTERS, DIM));
 | |
|         val local_new_clusters = 
 | |
|             PlaceLocalHandle.make[Array_2[Float]](world, () =>  new Array_2[Float](CLUSTERS, DIM));
 | |
|         val local_cluster_counts = 
 | |
|             PlaceLocalHandle.make[Rail[Int]](world, ()=> new Rail[Int](CLUSTERS));
 | |
| 
 | |
|         val rnd = PlaceLocalHandle.make[Random](world, () => new Random(0));
 | |
|         val points = new DistArray_Block_2[Float](POINTS, DIM, world, (Long,Long)=>rnd().nextFloat());
 | |
| 
 | |
|         val central_clusters = new Array_2[Float](CLUSTERS, DIM, (i:Long, j:Long) => {
 | |
|             at (points.place(i,j)) points(i,j)
 | |
|         });
 | |
| 
 | |
| 	val old_central_clusters = new Array_2[Float](CLUSTERS, DIM);
 | |
| 
 | |
|         val central_cluster_counts = new Rail[Int](CLUSTERS);
 | |
| 
 | |
|         for (iter in 1..ITERATIONS) {
 | |
| 
 | |
|             Console.OUT.println("Iteration: "+iter);
 | |
| 
 | |
|             finish {
 | |
|                 // reset state
 | |
|                 for (d in world) at (d) async {
 | |
|                     for ([i,j] in central_clusters.indices()) {
 | |
|                         local_curr_clusters()(i, j) = central_clusters(i, j);
 | |
|                         local_new_clusters()(i, j) = 0f;
 | |
|                     }
 | |
|             
 | |
|                     local_cluster_counts().clear();
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             finish {
 | |
|                 // compute new clusters and counters
 | |
|                 for (p in 0..(POINTS-1)) {
 | |
|                     at (points.place(p,0)) async {
 | |
|                         var closest:Long = -1;
 | |
|                         var closest_dist:Float = Float.MAX_VALUE;
 | |
|                         for (k in 0..(CLUSTERS-1)) { 
 | |
|                             var dist : Float = 0;
 | |
|                             for (d in 0..(DIM-1)) { 
 | |
|                                 val tmp = points(p,d) - local_curr_clusters()(k, d);
 | |
|                                 dist += tmp * tmp;
 | |
|                             }
 | |
|                             if (dist < closest_dist) {
 | |
|                                 closest_dist = dist;
 | |
|                                 closest = k;
 | |
|                             }
 | |
|                         }
 | |
| 			atomic {
 | |
|                             for (d in 0..(DIM-1)) { 
 | |
|                                 local_new_clusters()(closest,d) += points(p,d);
 | |
|                             }
 | |
|                             local_cluster_counts()(closest)++;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             for ([i,j] in old_central_clusters.indices()) {
 | |
|                 old_central_clusters(i, j) = central_clusters(i, j);
 | |
|                 central_clusters(i, j) = 0f;
 | |
|             }
 | |
|            
 | |
|             central_cluster_counts.clear();
 | |
| 
 | |
|             finish {
 | |
|                 val central_clusters_gr = GlobalRef(central_clusters);
 | |
|                 val central_cluster_counts_gr = GlobalRef(central_cluster_counts);
 | |
|                 val there = here;
 | |
|                 for (d in world) at (d) async {
 | |
|                     // access PlaceLocalHandles 'here' and then data will be captured by at and transfered to 'there' for accumulation
 | |
|                     val tmp_new_clusters = local_new_clusters();
 | |
|                     val tmp_cluster_counts = local_cluster_counts();
 | |
|                     at (there) atomic {
 | |
|                         for ([i,j] in tmp_new_clusters.indices()) {
 | |
|                             central_clusters_gr()(i,j) += tmp_new_clusters(i,j);
 | |
|                         }
 | |
|                         for (j in 0..(CLUSTERS-1)) {
 | |
|                             central_cluster_counts_gr()(j) += tmp_cluster_counts(j);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             for (k in 0..(CLUSTERS-1)) { 
 | |
|                 for (d in 0..(DIM-1)) { 
 | |
|                     central_clusters(k, d) /= central_cluster_counts(k);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // TEST FOR CONVERGENCE
 | |
|             var b:Boolean = true;
 | |
|             for ([i,j] in old_central_clusters.indices()) { 
 | |
|                 if (Math.abs(old_central_clusters(i, j)-central_clusters(i, j))>0.0001) {
 | |
|                     b = false;
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
|             if (b) break;
 | |
| 
 | |
|         }
 | |
| 
 | |
|         for (d in 0..(DIM-1)) { 
 | |
|             for (k in 0..(CLUSTERS-1)) { 
 | |
|                 if (k>0)
 | |
|                     Console.OUT.print(" ");
 | |
|                 Console.OUT.print(central_clusters(k,d));
 | |
|             }
 | |
|             Console.OUT.println();
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| // vim: shiftwidth=4:tabstop=4:expandtab
 |